/* =========================================================================
   SUPREMATIST PLATE — index.html only (appendix pages keep site.css)

   Gamma taken directly from Malevich, «Untitled», c. 1916 (Guggenheim
   76.2553.42): chalk-white ground with visible brushwork; muted ("глухой")
   pigments — viridian green, ultramarine, raspberry, dusty red, rust,
   mustard ochre, orange, faded pink, teal, silver grey, soft black.

   The register is an expensive coated art catalogue: generous margins,
   hairline rules, serif display, small-caps folios — with the painted
   forms doing the suprematism.
   ========================================================================= */

:root{
  /* ground */
  --paper:      #fffffe;
  --paper-hi:   #f6f5ef;
  --paper-lo:   #edebe3;
  --plate:      #ffffff;   /* the white of a printed plate */

  /* ink */
  --ink:        #26241f;
  --ink-strong: #191813;
  --ink-soft:   #4c4a42;
  --ink-faint:  #6f6c62;
  --hairline:   #d5d3c9;
  --hairline-soft: #e0ded5;

  /* pigments — each as a light/dark pair so every form can be painted */
  --green-1:  #45774f;  --green-2:  #2b5540;
  --black-1:  #34322c;  --black-2:  #16150f;
  --blue-1:   #3a55b0;  --blue-2:   #22398c;
  --rasp-1:   #a83048;  --rasp-2:   #832338;
  --red-1:    #a94136;  --red-2:    #8a2f26;
  --rust-1:   #a05a22;  --rust-2:   #7b4116;
  --ochre-1:  #cfa03a;  --ochre-2:  #ab7f23;
  --orange-1: #c96f2d;  --orange-2: #a85417;
  --pink-1:   #cf9297;  --pink-2:   #b97a80;
  --teal-1:   #337e7b;  --teal-2:   #23615e;
  --silver-1: #b3b4ae;  --silver-2: #91938c;
  --plum-1:   #7b4a86;  --plum-2:   #5d3465;
  --sand-1:   #9a8352;  --sand-2:   #7a663b;

  --display: "Fraunces", Georgia, serif;
  --body:    "Newsreader", Georgia, serif;
  --label:   "IBM Plex Mono", ui-monospace, Consolas, monospace;
  --mono:    "IBM Plex Mono", ui-monospace, Consolas, monospace;

  --maxw: 1060px;
  --colw: 66ch;

  /* one register for all running prose — everything that is not a title
     and not a decoded trace is set in exactly this size and leading */
  --prose-size: clamp(17px, 1.8vw, 20px);
  --prose-lh: 1.6;

  /* fine grain — the tooth of the paper / the dry brush */
  --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='240'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='1'/%3E%3C/svg%3E");
  /* broad strokes — the weave of the canvas */
  --weave: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='700' height='700'%3E%3Cfilter id='w'%3E%3CfeTurbulence type='turbulence' baseFrequency='0.012 0.02' numOctaves='2' seed='7' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0  0 0 0 0 0  0 0 0 0 0  0.6 0.6 0.6 0 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23w)'/%3E%3C/svg%3E");
}

*{box-sizing:border-box}
/* author display rules (.blockbtn etc.) must never override the hidden attr */
[hidden]{display:none !important}
html{scroll-behavior:smooth; scroll-padding-top:96px; -webkit-text-size-adjust:100%}
body{
  margin:0;
  position:relative;
  background:var(--paper);
  color:var(--ink);
  font-family:var(--body);
  font-size:17px;
  line-height:1.72;
  font-optical-sizing:auto;
  text-rendering:optimizeLegibility;
  -webkit-font-smoothing:antialiased;
}
/* paper tooth over everything, very quiet */
body::after{
  content:""; position:fixed; inset:0; z-index:9999; pointer-events:none;
  background-image:var(--grain);
  opacity:.055; mix-blend-mode:multiply;
}

::selection{background:#d9c9a8; color:var(--ink-strong)}

a{color:inherit}

/* =========================================================
   PAINTED FORMS — the shared recipe
   A form = pigment gradient + light falling from upper left
   + pigment pooling toward the lower edge + dry-brush grain.
   ========================================================= */
.pt{
  position:relative;
  background-image:
    radial-gradient(130% 100% at 28% 18%, rgba(255,255,255,.16), rgba(255,255,255,0) 55%),
    radial-gradient(150% 130% at 72% 88%, rgba(0,0,0,.22), rgba(0,0,0,0) 62%),
    linear-gradient(158deg, var(--p1), var(--p2));
}
.pt::after{
  content:""; position:absolute; inset:0; pointer-events:none;
  background-image:var(--grain);
  opacity:.28; mix-blend-mode:overlay;
}
.pt.brushy::after{
  background-image:var(--weave), var(--grain);
  opacity:.4;
}
.c-black.brushy::after{opacity:.22}

/* =========================================================
   TEXT-FORMS — the figure IS the text
   No border, no fill: a dense block of tiny bold monospace,
   broken per character, glyphs painted with the pigment
   gradient and cut to the figure's silhouette. Squint: a
   colored plane. Look closer: decoded reasoning.
   ========================================================= */
.tf{overflow:hidden}
.tf .fill{
  position:absolute; inset:0; display:block;
  font-family:var(--mono); font-weight:700;
  font-size:6.5px; line-height:.98; letter-spacing:-.05em;
  word-break:break-all; white-space:normal;
  background-image:
    radial-gradient(130% 100% at 28% 18%, rgba(255,255,255,.16), rgba(255,255,255,0) 55%),
    radial-gradient(150% 130% at 72% 88%, rgba(0,0,0,.34), rgba(0,0,0,0) 62%),
    linear-gradient(158deg, var(--p1), var(--p2));
  -webkit-background-clip:text; background-clip:text; color:transparent;
}
/* slanted figures: a float spacer pushes each line to follow the contour,
   so the text snakes along the shape instead of being cut flat */
.f-green .fill::before{
  content:""; float:left; width:100%; height:34%;
  shape-outside:polygon(0 0, 100% 0, 0 100%);
}
.f-rasp .fill::before{
  content:""; float:left; width:100%; height:50%;
  shape-outside:polygon(0 0, 100% 0, 0 100%);
}
.f-blue .fill::before{
  content:""; float:left; width:38%; height:100%;
  shape-outside:polygon(0 0, 100% 0, 0 100%);
}
.f-silver .fill::before{
  content:""; float:left; width:100%; height:24%;
  shape-outside:polygon(0 0, 100% 0, 0 100%);
}

/* =========================================================
   PEASANT GRADIENTS — after the late peasant cycle
   («Крестьянин в поле», 1928-32): a figure split down the
   middle, each half its own smooth vertical gradient. These
   sit in FRONT of the noisy text-forms — flat, silent, eerie.
   ========================================================= */
.pg{
  position:relative; overflow:hidden;
  background-image:
    linear-gradient(180deg, var(--ga1), var(--ga2)),
    linear-gradient(180deg, var(--gb1), var(--gb2));
  background-size:51% 100%, 50% 100%;
  background-position:0 0, 100% 0;
  background-repeat:no-repeat;
}
.pg::after{
  content:""; position:absolute; inset:0; pointer-events:none;
  background-image:var(--grain); opacity:.2; mix-blend-mode:overlay;
}
/* the same split gradient, but set in type: glyphs carry the two halves */
.tf.pgx .fill{
  background-image:
    linear-gradient(180deg, var(--ga1), var(--ga2)),
    linear-gradient(180deg, var(--gb1), var(--gb2));
  background-size:51% 100%, 50% 100%;
  background-position:0 0, 100% 0;
  background-repeat:no-repeat;
}
.pg-a{--ga1:#b23a30; --ga2:#1a1511; --gb1:#d9a13c; --gb2:#8a4a16}
.pg-b{--ga1:#4a7d54; --ga2:#101310; --gb1:#c2c3bd; --gb2:#3a3a34}
.pg-c{--ga1:#3f57ae; --ga2:#131b3a; --gb1:#a83048; --gb2:#20080e}
.pg-d{--ga1:#a83048; --ga2:#170408; --gb1:#cf9297; --gb2:#6e2c33}
.pg-e{--ga1:#b9bab4; --ga2:#3f403b; --gb1:#34322c; --gb2:#0d0c08}

/* the two peasants standing in the hero composition */
.f-peasant1{
  width:min(6.5vw,80px); height:min(24vw,300px);
  right:max(8.5%, calc(50% - 797px)); top:34%; z-index:2;
  transform:rotate(1.5deg);
}
.f-peasant2{
  width:min(4vw,48px); height:min(4vw,48px);
  right:max(12%, calc(50% - 730px)); top:10%;
  transform:rotate(-7deg);
}

/* the detonation: a clicked text-form bursts into flying letter-shards */
.shardbox{
  position:absolute; pointer-events:none; z-index:998;
}
.shard{
  position:absolute; display:block;
  font-family:var(--mono); font-weight:700;
  font-size:6.5px; line-height:1; letter-spacing:-.05em;
  white-space:nowrap;
  will-change:transform,opacity;
  transition:transform 1s cubic-bezier(.15,.8,.25,1), opacity 1s ease;
}

/* the long field: text-forms scattered down the page margins.
   Kept quiet (opacity) so the page breathes; a lifted one returns to full. */
.field{
  position:absolute; inset:0; overflow:hidden;
  pointer-events:none; z-index:0;
}
.field > *{position:absolute; scale:var(--s,1); opacity:.5; transition:opacity .3s ease}
.field > *.lifted{opacity:1}
/* the topmost LIVE primitive under the cursor floats up — driven by JS
   (stack-probing), so a form lifts even when it sits behind another */
.field .tf, .field .spiral, .comp .tf{
  transition:scale .3s cubic-bezier(.2,.8,.2,1), filter .3s ease;
}
.tf.lifted, .spiral.lifted{
  scale:calc(var(--s,1) * 1.16);
  filter:brightness(1.14) saturate(1.18);
  z-index:50;
}
/* The margin frame: these forms hang on the viewport edge and bleed off it —
   the edge is what cuts them, so they stay edge-pinned at every width.
   (Only whole shapes — the hero composition, the chevron heap, the posts and
   the strays below — are center-capped for big monitors.) */
.bg1{left:-46px; top:11%; width:210px; height:540px;
  clip-path:polygon(20% 0, 80% 2%, 100% 98%, 0 100%); transform:rotate(6deg)}
.bg2{right:-40px; top:20%; width:230px; height:230px;
  clip-path:polygon(0 50%, 100% 0, 100% 100%); transform:rotate(-8deg)}
.bg2 .fill::before{content:""; float:left; width:100%; height:50%;
  shape-outside:polygon(0 0, 100% 0, 0 100%)}
.bg3{left:-50px; top:33%; width:200px; height:460px;
  clip-path:polygon(30% 0, 75% 0, 100% 100%, 0 96%); transform:rotate(-4deg)}
.bg4{right:-56px; top:47%; width:260px; height:140px;
  clip-path:polygon(0 24%, 100% 0, 97% 100%, 2% 92%); transform:rotate(-12deg)}
.bg5{left:-30px; top:59%; width:180px; height:330px;
  clip-path:polygon(0 0, 100% 4%, 84% 100%, 10% 96%); transform:rotate(7deg)}
.bg6{right:-36px; top:71%; width:150px; height:420px;
  clip-path:polygon(26% 0, 70% 0, 100% 97%, 0 100%); transform:rotate(3deg)}
.bg7{left:-40px; top:86%; width:240px; height:110px;
  clip-path:polygon(0 30%, 100% 0, 96% 78%, 3% 100%); transform:rotate(-14deg)}
.bg8{right:-20px; top:15%; width:170px; height:44px;
  clip-path:polygon(0 20%, 100% 0, 98% 90%, 2% 100%); transform:rotate(9deg)}
.bg9{left:-24px; top:27%; width:150px; height:56px;
  clip-path:polygon(2% 0, 100% 10%, 96% 100%, 0 88%); transform:rotate(-6deg)}
.bg10{right:-18px; top:41%; width:60px; height:140px;
  clip-path:polygon(12% 0, 100% 4%, 88% 100%, 0 94%); transform:rotate(14deg)}
.bg11{left:-20px; top:52%; width:190px; height:36px;
  transform:rotate(-11deg)}
.bg12{right:-26px; top:64%; width:130px; height:52px;
  clip-path:polygon(0 0, 96% 12%, 100% 92%, 4% 100%); transform:rotate(5deg)}
/* elongated strays right of the prose column. The column is the full wrap
   (edge at 50% + 530px), so they start past it and never cross the text. */
.bg13{left:calc(50% + 545px); top:19%; width:400px; height:28px;
  clip-path:polygon(0 18%, 100% 0, 98% 84%, 1% 100%); transform:rotate(-3deg)}
.bg14{left:calc(50% + 575px); top:30%; width:34px; height:380px;
  clip-path:polygon(14% 0, 92% 2%, 100% 98%, 0 96%); transform:rotate(5deg)}
.bg15{left:calc(50% + 545px); top:47%; width:360px; height:24px;
  transform:rotate(2deg)}
.bg16{left:calc(50% + 605px); top:56%; width:300px; height:32px;
  clip-path:polygon(2% 0, 100% 12%, 97% 100%, 0 90%); transform:rotate(-7deg)}
.bg17{left:calc(50% + 555px); top:64%; width:30px; height:320px;
  transform:rotate(-4deg)}
.bg18{left:calc(50% + 565px); top:76%; width:440px; height:26px;
  clip-path:polygon(0 0, 99% 16%, 100% 90%, 2% 100%); transform:rotate(3deg)}
.bg19{left:calc(50% + 585px); top:83.5%; width:320px; height:22px;
  transform:rotate(-9deg)}
.bg20{left:max(26px, calc(50% - 934px)); top:44%; width:60px; height:280px; transform:rotate(4deg)}
.bg21{right:max(30px, calc(50% - 930px)); top:69%; width:50px; height:240px; transform:rotate(-3deg)}

/* the heap — checkmarks and trapezoids piled up, after ЖБ-1332 */
.chev{clip-path:polygon(0 0, 50% 55%, 100% 0, 100% 42%, 50% 100%, 0 42%)}
.bgH1{right:max(36px, calc(50% - 924px));  top:37%;   width:150px; height:110px; transform:rotate(-12deg)}
.bgH2{right:max(-12px, calc(50% - 972px)); top:38.3%; width:110px; height:82px;  transform:rotate(16deg)}
.bgH3{right:max(92px, calc(50% - 868px));  top:39.4%; width:96px;  height:62px;
  clip-path:polygon(16% 0, 84% 4%, 100% 100%, 0 92%); transform:rotate(-5deg)}
.bgH4{right:max(18px, calc(50% - 942px));  top:40.3%; width:130px; height:26px;  transform:rotate(8deg)}
.bgH5{right:max(64px, calc(50% - 896px));  top:41.2%; width:84px;  height:62px;  transform:rotate(-22deg)}

/* spirals — text entering the whirl from the rim, and escaping it */
.spiral{position:absolute; overflow:visible}
.spiral text{font-family:var(--mono); font-weight:700; font-size:8.5px}
.bgS1{left:calc(50% + 555px); top:21%; width:290px; height:290px; transform:rotate(8deg)}
.bgS2{left:calc(50% + 565px); top:59%; width:260px; height:260px; transform:rotate(-6deg)}

@media (prefers-reduced-motion: no-preference){
  .field > *{opacity:0; animation:settle 1s cubic-bezier(.22,.9,.24,1) forwards}
}
/* small screens: the forms don't leave — they drift further from the text */
@media (max-width:1280px){
  .bg13,.bg14,.bg15,.bg16,.bg17,.bg18,.bg19{left:auto; right:-150px}
  .bgS1,.bgS2{left:auto; right:-190px}
}
@media (max-width:1200px){
  .bg1,.bg3,.bg5,.bg7,.bg9,.bg11{left:-130px}
  .bg2,.bg4,.bg6,.bg8,.bg10,.bg12{right:-130px}
  .bg20{left:-70px}
  .bg21{right:-70px}
  .bgH1,.bgH2,.bgH3,.bgH4,.bgH5{right:-120px}
}

.c-green  {--p1:var(--green-1);  --p2:var(--green-2)}
.c-black  {--p1:var(--black-1);  --p2:var(--black-2)}
.c-blue   {--p1:var(--blue-1);   --p2:var(--blue-2)}
.c-rasp   {--p1:var(--rasp-1);   --p2:var(--rasp-2)}
.c-red    {--p1:var(--red-1);    --p2:var(--red-2)}
.c-rust   {--p1:var(--rust-1);   --p2:var(--rust-2)}
.c-ochre  {--p1:var(--ochre-1);  --p2:var(--ochre-2)}
.c-orange {--p1:var(--orange-1); --p2:var(--orange-2)}
.c-pink   {--p1:var(--pink-1);   --p2:var(--pink-2)}
.c-teal   {--p1:var(--teal-1);   --p2:var(--teal-2)}
.c-silver {--p1:var(--silver-1); --p2:var(--silver-2)}

/* =========================================================
   MASTHEAD
   ========================================================= */
nav{
  position:sticky; top:0; z-index:100;
  background:color-mix(in srgb, var(--paper) 88%, transparent);
  backdrop-filter:blur(10px); -webkit-backdrop-filter:blur(10px);
  border-bottom:1px solid var(--hairline);
}
nav .inner{
  max-width:1280px; margin:0 auto; padding:0 32px;
  display:flex; align-items:center; gap:18px;
  height:64px;
  overflow-x:auto; scrollbar-width:none;
}
nav .inner::-webkit-scrollbar{display:none}
.brand{
  display:flex; align-items:center; gap:11px;
  font-family:var(--body); font-weight:560; font-size:14.5px;
  letter-spacing:.1em; text-transform:uppercase;
  font-variation-settings:"opsz" 30;
  text-decoration:none; color:var(--ink-strong);
  white-space:nowrap; margin-right:auto;
}
.brand .mark{
  width:15px; height:15px; flex:none;
  transform:rotate(-8deg);
  /* sit on the cap line of the wordmark, not on its middle */
  position:relative; top:-2px;
}
.tab{
  font-family:var(--body); font-size:13px; font-weight:470;
  letter-spacing:.08em; text-transform:uppercase;
  font-variation-settings:"opsz" 30;
  text-decoration:none; color:var(--ink-soft);
  white-space:nowrap; padding:6px 2px 4px;
  border-bottom:3px solid transparent;
  transition:color .18s ease;
}
.tab:hover{color:var(--ink-strong)}
.tab.here{
  color:var(--ink-strong);
  border-image:linear-gradient(120deg, var(--ochre-1), var(--ochre-2)) 1;
  border-bottom:3px solid var(--ochre-2);
}
.tab.paper{
  color:var(--plate); padding:8px 14px 7px; border-bottom:none;
}
/* Contents — the whole page in one panel, so no finding is more than a click
   away. It hangs under the bar rather than pushing it, and closes on a choice. */
.toctoggle{
  border:1px solid var(--hairline); background:none; cursor:pointer;
  padding:6px 12px 5px; border-bottom:1px solid var(--hairline);
  font-family:inherit; color:var(--ink-soft);
}
.toctoggle::after{content:' ▾'; font-size:.85em; color:var(--ink-faint)}
.toctoggle[aria-expanded="true"]{color:var(--ink-strong); border-color:var(--ink-soft)}
.toctoggle[aria-expanded="true"]::after{content:' ▴'}
.toc{
  border-bottom:1px solid var(--hairline);
  background:color-mix(in srgb, var(--paper) 96%, transparent);
  backdrop-filter:blur(10px); -webkit-backdrop-filter:blur(10px);
}
.toc .inner{
  /* nav .inner is a 64px-tall row; this one is a panel and sets its own height */
  height:auto; overflow:visible;
  max-width:1280px; margin:0 auto; padding:14px 32px 18px;
  /* filled down each column rather than across, so a section and its
     sub-sections stay together instead of wrapping apart */
  display:grid; grid-auto-flow:column;
  grid-template-rows:repeat(4, auto); grid-template-columns:repeat(3, minmax(0, 1fr));
  gap:2px 26px;
}
.toc a{
  display:flex; align-items:baseline; gap:10px;
  padding:7px 2px; text-decoration:none;
  font-family:var(--body); font-size:15px; color:var(--ink);
  border-bottom:1px solid transparent;
}
.toc a:hover{color:var(--rasp-2); border-bottom-color:var(--hairline)}
.toc a b{
  font-family:var(--mono); font-size:11px; font-weight:600;
  color:var(--ink-faint); min-width:26px;
}
/* a sub-section is set in by its own numbering: 1.1 under 1, 4.1 under 4 */
.toc a.tocsub{margin-left:20px; color:var(--ink-soft); font-size:14.5px}
.toc a.tocsub:hover{color:var(--rasp-2)}
/* the three that are not sections keep the numbering column so the titles line
   up, and carry no number of their own */
.toc a.tocend{color:var(--ink-soft)}
.toc a.tocend:hover{color:var(--rasp-2)}
@media (max-width: 980px){
  .toc .inner{
    grid-auto-flow:row; grid-template-rows:none;
    grid-template-columns:repeat(2, minmax(0, 1fr));
  }
}
@media (max-width: 720px){
  .toc .inner{grid-template-columns:1fr; padding:10px 22px 14px; gap:0}
  .toc a{font-size:16px; padding:9px 2px}
}

/* =========================================================
   HERO — the plate itself
   ========================================================= */
.hero{
  position:relative;
  overflow:hidden;
  padding:96px 32px 28px;
}
.hero .wrap{
  position:relative; z-index:2;
  max-width:var(--maxw); margin:0 auto;
}

/* the composition — after Malevich, Untitled, c. 1916 */
.comp{position:absolute; inset:0; z-index:1; pointer-events:none}
.comp > *{position:absolute; display:block}
.comp a{
  pointer-events:auto; cursor:pointer;
  transition:scale .32s cubic-bezier(.2,.8,.2,1), filter .32s ease;
}
.comp a:focus-visible{outline:2px dashed var(--ink-strong); outline-offset:5px}

/* The composition keeps to the top-right of a canvas at most 1920px wide:
   past that, max() pins every form to the same center-relative spot it had
   at 1920, so the plate never drifts away from the title on big monitors. */
.f-green{
  width:min(30vw,380px); height:min(11.5vw,142px);
  right:max(1.5%, calc(50% - 931px)); top:14%;
  clip-path:polygon(0 34%, 97% 0, 100% 78%, 3% 100%);
  transform:rotate(-3deg);
}
.f-trunk{
  width:min(8vw,100px); height:min(34vw,420px);
  right:max(6%, calc(50% - 845px)); top:22%;
  clip-path:polygon(30% 0, 66% 0, 100% 96%, 90% 100%, 0 100%);
  transform:rotate(2deg);
}
.f-blue{
  width:min(9vw,110px); height:min(15.5vw,192px);
  right:max(4.5%, calc(50% - 874px)); top:3%;
  clip-path:polygon(38% 0, 78% 0, 100% 100%, 0 100%);
  transform:rotate(6deg);
}
.f-rasp{
  width:min(7vw,86px); height:min(7vw,86px);
  right:max(1%, calc(50% - 941px)); top:6%;
  clip-path:polygon(0 50%, 100% 0, 100% 100%);
}
.f-rust{
  width:min(14vw,176px); height:min(1.5vw,18px);
  right:max(5.5%, calc(50% - 854px)); top:1.5%;
  transform:rotate(38deg);
}
.f-redchip{
  display:none;
}
.f-silver{
  width:min(21vw,264px); height:min(4.2vw,52px);
  right:max(2%, calc(50% - 922px)); top:43%;
  clip-path:polygon(0 22%, 100% 0, 98% 100%, 2% 92%);
  transform:rotate(-4deg);
}
.f-teal{
  width:min(12vw,148px); height:min(1.2vw,14px);
  right:max(.5%, calc(50% - 950px)); top:52%;
  transform:rotate(-2deg);
}
.f-pink{
  width:min(10.5vw,130px); height:min(1vw,12px);
  right:max(9%, calc(50% - 787px)); top:47.5%;
  transform:rotate(-5deg);
}
.f-ochre-bar{
  width:min(12vw,148px); height:min(2.4vw,30px);
  right:max(20%, calc(50% - 576px)); top:58%;
  transform:rotate(28deg);
}
.f-orange{
  width:min(2.5vw,30px); height:min(4.6vw,56px);
  right:max(23.5%, calc(50% - 509px)); top:67%;
  transform:rotate(14deg);
}
.f-ochre-post{
  width:min(2.7vw,32px); height:min(13.5vw,164px);
  right:max(21.5%, calc(50% - 547px)); top:63%;
  transform:rotate(-6deg);
}
.f-redbar{
  width:min(9vw,112px); height:min(1.4vw,17px);
  right:max(23%, calc(50% - 518px)); top:38%;
  transform:rotate(-3deg);
}
.f-bluebar{
  width:min(11vw,136px); height:min(1.2vw,14px);
  right:max(13%, calc(50% - 710px)); bottom:5.5%;
  transform:rotate(-7deg);
}
.f-dash{
  display:none;
}

/* entrance — the forms settle onto the canvas once */
@media (prefers-reduced-motion: no-preference){
  .comp i{
    opacity:0;
    animation:settle 1.1s cubic-bezier(.22,.9,.24,1) forwards;
  }
  .comp > *:nth-child(1) {animation-delay:.05s}
  .comp > *:nth-child(2) {animation-delay:.16s}
  .comp > *:nth-child(3) {animation-delay:.24s}
  .comp > *:nth-child(4) {animation-delay:.32s}
  .comp > *:nth-child(5) {animation-delay:.40s}
  .comp > *:nth-child(6) {animation-delay:.46s}
  .comp > *:nth-child(7) {animation-delay:.52s}
  .comp > *:nth-child(8) {animation-delay:.58s}
  .comp > *:nth-child(9) {animation-delay:.64s}
  .comp > *:nth-child(10){animation-delay:.70s}
  .comp > *:nth-child(11){animation-delay:.76s}
  .comp > *:nth-child(12){animation-delay:.82s}
  .comp > *:nth-child(13){animation-delay:.88s}
  .comp > *:nth-child(14){animation-delay:.94s}
  .hero h1, .hero .authors, .hero .affil, .hero .equal,
  .hero .tldr, .hero .pills{
    opacity:0; animation:rise .9s cubic-bezier(.2,.8,.2,1) forwards;
  }
  .hero h1{animation-delay:.1s}
  .hero .authors{animation-delay:.3s}
  .hero .affil{animation-delay:.38s}
  .hero .equal{animation-delay:.44s}
  .hero .tldr{animation-delay:.52s}
  .hero .pills{animation-delay:.62s}
}
@keyframes settle{
  from{opacity:0; translate:0 -14px}
  to{opacity:1; translate:0 0}
}
@keyframes rise{
  from{opacity:0; translate:0 16px}
  to{opacity:1; translate:0 0}
}

.kicker{
  font-family:var(--label); font-size:11.5px; font-weight:600;
  letter-spacing:.3em; text-transform:uppercase; color:var(--ink-faint);
  margin:0 0 30px;
  display:flex; align-items:center; gap:16px;
}
.kicker::after{content:""; height:1px; width:72px; background:var(--ink-faint); opacity:.5}

.hero h1{
  font-family:var(--display);
  font-size:clamp(42px, 6.4vw, 84px);
  font-weight:430;
  line-height:1.02;
  letter-spacing:-.018em;
  margin:0 0 42px;
  max-width:11em;
  color:var(--ink-strong);
  font-variation-settings:"opsz" 90;
}
.hero h1 em{
  font-style:italic; font-weight:400;
  color:var(--rasp-2);
}

.authors{
  font-family:var(--body); font-size:20px; font-weight:500; line-height:1.75;
  margin:0 0 26px; max-width:60em; color:var(--ink-strong);
}
/* Each name leads to its Google Scholar page. A byline is a list of names
   before it is a list of links, so the rule stays off until the pointer is on
   one — then it draws under the name only, never under the affiliation marks. */
.authors .scholar{
  color:inherit; text-decoration:none;
  border-bottom:1px solid transparent;
  transition:color .14s ease, border-color .14s ease;
}
.authors .scholar:hover, .authors .scholar:focus-visible{
  color:var(--rasp-2); border-bottom-color:var(--rasp-2); outline:none;
}
.authors sup{font-size:.62em; color:var(--ink-faint)}
.authors sup b{font-weight:700}
.authors .a1{color:var(--red-2)}
.authors .a2{color:var(--blue-2)}
.authors .a3{color:var(--silver-2)}
.authors .a4{color:var(--green-2)}
.authors .a5{color:var(--ochre-2)}
.authors .a6{color:var(--rasp-2)}
.authors .a7{color:var(--teal-2)}
.authors .sup-mark{color:var(--ink-strong)}
/* affiliations as collage cuts: each institution a painted offcut,
   tilted, sized to its name — Max Planck a long bar, Snyk a chip */
.affil{
  display:flex; flex-wrap:wrap; align-items:center;
  gap:9px 8px; margin:0 0 56px; max-width:60em;
}
.affil-break{flex-basis:100%; height:0}
/* The shadow lives on the CONTAINER, not on each chip. A filter is applied
   BEFORE clip-path, so a drop-shadow set on a clipped chip is cut away by
   that chip's own silhouette — which is why only the one chip that never got
   a clip-path appeared to have one. Filtering the unclipped .affil instead
   casts a shadow off every chip's cut shape at once. */
.affil{filter:drop-shadow(4px 5px 0 rgba(25,24,19,.5))}
.chip{
  display:inline-flex; align-items:baseline; gap:5px;
  padding:8px 20px 7px;
  font-family:var(--label); font-size:11px; font-weight:500;
  letter-spacing:.02em; line-height:1.1;
  color:var(--plate); white-space:nowrap;
  position:relative;
  transition:translate .16s ease;
}
/* the chip slides off its own shadow — it reads as lifting off the paper.
   .lift is the same move, triggered by hovering the author it belongs to. */
.chip:hover, .chip.lift{translate:-2px -3px; z-index:9}
/* a name travels as one piece — surname and affiliation marks never wrap
   apart from it; lines break only between authors */
.authors .au{transition:color .16s ease; white-space:nowrap; margin-right:.6em}
.authors .au:hover{color:var(--rasp-2)}
.chip sup{font-size:.72em; opacity:.75; font-weight:600}
/* Each cut its own silhouette — trapezoids, slants, shaved corners, points.
   Child 4 is .affil-break, so the seven chips are children 1-3 and 5-8. */
.chip:nth-child(1){rotate:-1.6deg;              /* parallelogram → */
  clip-path:polygon(7% 0, 100% 0, 93% 100%, 0 100%)}
.chip:nth-child(2){rotate:1.1deg; padding-right:26px; /* right arrow-cut */
  clip-path:polygon(0 0, 92% 0, 100% 50%, 92% 100%, 0 100%)}
.chip:nth-child(3){rotate:-.6deg;               /* long trapezoid, both corners in */
  clip-path:polygon(2% 0, 98% 0, 100% 100%, 0 100%)}
.chip:nth-child(5){rotate:1.8deg;               /* trapezoid narrowing down */
  clip-path:polygon(0 0, 100% 0, 92% 100%, 8% 100%)}
.chip:nth-child(6){rotate:-1.2deg;              /* shaved top-left + bottom-right */
  clip-path:polygon(9% 0, 100% 0, 100% 62%, 91% 100%, 0 100%, 0 38%)}
.chip:nth-child(7){rotate:2.2deg; padding-bottom:13px; /* pennant point down */
  clip-path:polygon(0 0, 100% 0, 100% 66%, 50% 100%, 0 66%)}
.chip:nth-child(8){rotate:-.9deg;               /* parallelogram ← */
  clip-path:polygon(0 0, 93% 0, 100% 100%, 7% 100%)}
/* the silver cut needs dark ink to stay legible */
.chip.c-silver{color:var(--ink-strong)}
.chip.c-silver sup{opacity:.6}
/* the marks the author line carries have to be worth something: the note
   rides just under the affiliation cuts, so the chips give up their air to it */
.affil:has(+ .equal){margin-bottom:20px}
.equal{
  font-family:var(--body); font-style:italic; font-size:13.5px;
  color:var(--ink-faint); margin:0 0 44px;
}

/* the standfirst */
.tldr{
  position:relative;
  /* starts 22px left of the column; runs a touch past the widest
     affiliation chip so the block does not read as clipped short */
  max-width:820px;
  margin:0 -22px 44px;
  padding:20px 26px 22px 62px;
  font-family:var(--body);
  font-size:clamp(18px, 2vw, 22.5px);
  font-weight:380;
  line-height:1.52;
  color:var(--ink);
  font-variation-settings:"opsz" 30;
  text-align:justify; hyphens:auto;
  /* the same trick as .teaser-note: the decorative field runs underneath,
     so lift the block onto frosted paper — translucent with a blur, so a
     form passing below reads as a soft colored shadow instead of being
     hard-cut at the block's edge */
  z-index:2;
  background:color-mix(in srgb, var(--paper) 72%, transparent);
  backdrop-filter:blur(5px); -webkit-backdrop-filter:blur(5px);
}
.tldr b{
  display:block;
  font-family:var(--body); font-size:clamp(28px, 3vw, 40px);
  font-weight:600; letter-spacing:.03em;
  font-variation-settings:"opsz" 60;
  color:var(--rasp-2); margin:0 0 14px;
}
.tldr .tbar{
  position:absolute; left:22px; top:14px; bottom:14px; width:13px;
  transform:rotate(1.8deg);
  clip-path:polygon(22% 0, 100% 2%, 78% 100%, 0 98%);
}
/* the bar's shadow: a clipped element cannot cast its own (filter runs
   before clip-path), so the panel paints an offset copy underneath it */
.tldr::before{
  content:""; position:absolute; z-index:0;
  left:26px; top:19px; bottom:9px; width:13px;
  transform:rotate(1.8deg);
  clip-path:polygon(22% 0, 100% 2%, 78% 100%, 0 98%);
  background:rgba(25,24,19,.5);
}

.pills{display:flex; gap:18px; flex-wrap:wrap; margin:0 0 70px}
.blockbtn{
  display:inline-block; text-decoration:none; border:none; cursor:pointer;
  font-family:var(--body); font-size:14.5px; font-weight:520;
  letter-spacing:.15em; text-transform:uppercase;
  font-variation-settings:"opsz" 30;
  padding:16px 30px 15px;
  color:var(--plate);
  transition:translate .16s ease, box-shadow .16s ease;
}
.blockbtn:hover{
  translate:-2px -2px;
  box-shadow:5px 6px 0 rgba(168,48,72,.32);
}
.blockbtn.ghost{
  background:none; color:var(--ink-strong);
  outline:1.5px solid var(--ink-strong); outline-offset:-1.5px;
}
.blockbtn.ghost:hover{box-shadow:5px 6px 0 rgba(38,36,31,.16)}
.blockbtn.ghost::after{display:none}

/* =========================================================
   PLATES — figures framed like catalogue reproductions
   ========================================================= */
figure{margin:56px 0}
.plate-frame{
  background:var(--plate);
  border:1px solid var(--hairline);
  padding:clamp(18px, 3vw, 40px);
  box-shadow:0 1px 0 rgba(25,24,19,.05), 0 14px 40px -22px rgba(25,24,19,.28);
}
.plate-frame img{display:block; width:100%; height:auto}
/* The fidelity plate is three panels 4.7 times wider than they are tall. On a
   phone that is 110px per panel — the scatter reads as grey dust. The panels
   are cut apart and stacked instead, each one the full width of the screen:
   the same file, scaled up behind a window and slid sideways to the panel
   wanted. Only one version is in the flow at a time. */
.plate-panels{display:none}
@media (max-width: 720px){
  .plate-frame{display:none}
  .plate-panels{
    display:grid; gap:14px;
    background:var(--plate);
    border:1px solid var(--hairline);
    padding:14px;
    box-shadow:0 1px 0 rgba(25,24,19,.05), 0 14px 40px -22px rgba(25,24,19,.28);
  }
  .plate-cut{overflow:hidden; aspect-ratio:var(--ar)}
  .plate-cut img{display:block; width:var(--w); max-width:none; margin-left:var(--x)}
}
figcaption{
  margin-top:18px;
  padding-top:14px;
  border-top:1px solid var(--hairline);
  font-family:var(--body); font-size:clamp(15px,1.5vw,17px); line-height:1.5;
  font-weight:400; color:var(--ink-soft);
  font-variation-settings:"opsz" 30;
  max-width:72ch;
}
figcaption b{
  font-weight:500; color:var(--ink-strong);
}

.teaser{margin:0 0 32px}

/* the attack, side by side: source trace → injected → jailbroken trace */
.traces{
  display:grid; grid-template-columns:1fr 1fr; align-items:stretch;
  gap:clamp(10px,1.6vw,20px); margin:0;
  position:relative;
}
.trace{
  background:#faf9f4; border:1px solid var(--hairline);
  padding:16px 18px 18px; overflow-x:auto; min-width:0;
  box-shadow:0 10px 30px -22px rgba(25,24,19,.3);
}
.trace.src{transform:rotate(-.5deg)}
.trace.dst{transform:rotate(.5deg)}
.trace .cap{
  font-family:var(--label); font-size:10.5px; font-weight:600;
  letter-spacing:.1em; text-transform:uppercase; margin:0 0 12px;
  display:flex; align-items:center; gap:8px;
}
.trace.src .cap{color:var(--ink-soft)}
.trace.dst .cap{color:var(--rasp-2)}
.trace .cap::before{
  content:""; width:11px; height:11px; flex:none; transform:rotate(-8deg);
  background:linear-gradient(150deg, var(--silver-1), var(--silver-2));
}
.trace.dst .cap::before{background:linear-gradient(150deg, var(--rasp-1), var(--rasp-2))}
.trace pre{
  margin:0; font-family:var(--mono); font-size:11px; line-height:1.62;
  color:var(--ink); white-space:pre;
}
.trace .k{color:var(--blue-2); font-weight:500}
.trace .v{color:var(--green-2)}
.trace .dim{color:var(--ink-faint)}
.trace .sig{
  display:inline-block; padding:0 4px;
  background:linear-gradient(100deg, #f6dde2, #efc9d1);
  color:var(--rasp-2); font-weight:500;
}
/* the injection arrow runs straight from the source signature to the
   jailbroken signature — positioned by JS (both sit on the same row) */
.inject{
  position:absolute; height:0; z-index:4; pointer-events:none;
  display:flex; align-items:center; justify-content:center;
  translate:0 -50%;
}
.inject::before{               /* the shaft */
  content:""; position:absolute; left:0; right:0; top:0; height:2px;
  translate:0 -50%; background:var(--ink-strong);
}
.inject::after{                /* the arrowhead at the jailbroken end */
  content:""; position:absolute; right:0; top:0; translate:0 -50%;
  border:6px solid transparent; border-left-color:var(--ink-strong); border-right:0;
}
.inject span{
  position:relative; z-index:1;
  font-family:var(--display); font-size:9px; font-weight:520;
  letter-spacing:.08em; text-transform:uppercase; color:var(--plate);
  background:linear-gradient(120deg, var(--black-1), var(--black-2));
  padding:5px 10px 4px; white-space:nowrap;
}
@media (max-width:720px){
  .traces{grid-template-columns:1fr}
  .inject{display:none}
}

.teaser-note{
  margin:20px 0 0; max-width:none;   /* full .wrap width, same right edge as .teaser above */
  font-family:var(--body); font-size:var(--prose-size); font-weight:400;
  line-height:var(--prose-lh); color:var(--ink); font-variation-settings:"opsz" 30;
  text-align:justify; hyphens:auto;
  /* the background spirals run straight under this paragraph, so lift it
     onto frosted paper: translucent with a blur, so whatever crosses below
     stays present as a soft haze instead of being hard-cut at the edge.
     No side padding: the text spans exactly the column, so its justified
     edges sit flush with the trace boxes above. */
  position:relative; z-index:2;
  background:color-mix(in srgb, var(--paper) 72%, transparent);
  backdrop-filter:blur(5px); -webkit-backdrop-filter:blur(5px);
  padding:16px 0 18px;
}
@media (max-width:720px){
  .teaser-note{padding:14px 0 16px}
}
.teaser-note b{
  font-weight:560; color:var(--ink-strong);
}
/* <i> is spoken for by the decorative bars (.bar i, .tbar), so prose emphasis
   uses <em>, matching .hero h1 em. Italic only -- no weight bump, so it reads
   as emphasis rather than as a second kind of bold. */
.teaser-note em{
  font-style:italic; color:var(--ink-strong);
}

/* =========================================================
   GUESS THE MODEL — swaps in for the teaser figure
   ========================================================= */
.guessgame{margin:0 0 64px}
.gg-head{
  display:flex; align-items:flex-end; justify-content:space-between;
  gap:20px; flex-wrap:wrap; margin:0 0 6px;
}
.gg-q{
  font-family:var(--body); font-weight:520;
  font-size:clamp(24px, 3.4vw, 40px); letter-spacing:-.01em;
  line-height:1.05; margin:0; color:var(--ink-strong);
  font-variation-settings:"opsz" 60;
}
.gg-q span{color:var(--tint, var(--rasp-2)); font-style:italic}
/* each model keeps one locked colour, in the question and on the badges */
.gg-m-claude{--p1:var(--blue-1);   --p2:var(--blue-2);   --tint:var(--blue-2)}
.gg-m-gpt   {--p1:var(--ochre-1);  --p2:var(--ochre-2);  --tint:var(--ochre-2)}
.gg-m-kimi  {--p1:var(--teal-1);   --p2:var(--teal-2);   --tint:var(--teal-2)}
.gg-m-glm   {--p1:var(--orange-1); --p2:var(--orange-2); --tint:var(--orange-2)}
.gg-m-inkling {--p1:var(--silver-1); --p2:var(--silver-2); --tint:var(--silver-2)}
.gg-m-deepseek{--p1:var(--red-1);    --p2:var(--red-2);    --tint:var(--red-2)}
.gg-m-k2p6    {--p1:var(--green-1);  --p2:var(--green-2);  --tint:var(--green-2)}
.gg-m-gemini  {--p1:var(--plum-1);   --p2:var(--plum-2);   --tint:var(--plum-2)}
.gg-m-sonnet  {--p1:var(--sand-1);   --p2:var(--sand-2);   --tint:var(--sand-2)}
.gg-meta{display:flex; align-items:center; gap:18px; padding-bottom:6px}
.gg-score{
  font-family:var(--mono); font-size:13px; color:var(--ink-soft);
  font-variant-numeric:tabular-nums;
  background:var(--paper-hi); border:1px solid var(--hairline);
  padding:6px 14px;
}
.gg-score b{color:var(--ink-strong); font-weight:600}
.gg-x{
  border:none; background:none; cursor:pointer;
  font-family:var(--mono); font-size:11.5px; color:var(--ink-faint);
  padding:4px 0;
}
.gg-x:hover{color:var(--rasp-2)}
.gg-hint{
  font-family:var(--body); font-style:italic; font-size:14px;
  color:var(--ink-faint); margin:0 0 20px; max-width:64ch;
}
.gg-hint:empty{margin:0}

.gg-cols{
  display:grid; grid-template-columns:repeat(3, 1fr); gap:18px;
  align-items:start;
}
.gg-col{
  text-align:left; cursor:pointer; font:inherit;
  background:#f5f4ee; border:1px solid var(--hairline);
  padding:22px 22px 20px;
  display:flex; flex-direction:column; gap:12px;
  min-height:230px;
  transition:transform .28s cubic-bezier(.2,.8,.2,1), box-shadow .28s ease, border-color .2s ease;
}
.gg-col:nth-child(1){transform:rotate(-.7deg)}
.gg-col:nth-child(2){transform:rotate(.5deg)}
.gg-col:nth-child(3){transform:rotate(-.35deg)}
.gg-cols:not(.revealed) .gg-col:hover{
  transform:translateY(-5px) rotate(0deg);
  box-shadow:6px 9px 0 rgba(168,48,72,.14);
  border-color:var(--rasp-1);
}
.gg-tag{
  font-family:var(--mono); font-size:10px; font-weight:600;
  letter-spacing:.1em; text-transform:uppercase; color:var(--ink-faint);
}
.gg-trace{
  font-family:var(--mono); font-size:12px; line-height:1.7;
  color:var(--ink); overflow-wrap:anywhere; flex:1;
}
.gg-name{
  font-family:var(--body); font-weight:520; font-size:16px;
  color:var(--ink-strong); opacity:0; height:0; overflow:hidden;
  transition:opacity .35s ease;
  display:flex; align-items:center; gap:9px;
}
.gg-name::before{
  content:""; width:13px; height:13px; flex:none;
  background:linear-gradient(150deg, var(--p1,var(--silver-1)), var(--p2,var(--silver-2)));
  transform:rotate(-8deg);
}
.gg-cols.revealed .gg-name{opacity:1; height:auto}
.gg-cols.revealed .gg-col{cursor:default}
/* correctness lives on the column frame; the name badge keeps the model colour */
.gg-col.is-truth{border-color:var(--green-1); background:#eff4ee}
.gg-col.is-wrongpick{border-color:var(--rasp-1); background:#f8f0ec}
.gg-col.dim{opacity:.62}
.gg-foot{
  display:flex; align-items:center; justify-content:space-between;
  gap:16px 20px; flex-wrap:wrap; margin-top:24px;
}
.gg-foot-r{display:flex; align-items:center; gap:22px}
.gg-next{margin:0; border:none}

@media (max-width:720px){
  .gg-cols{grid-template-columns:1fr}
  .gg-col{min-height:0}
}

/* =========================================================
   SECTIONS
   ========================================================= */
section{padding:88px 32px 40px}

/* #fidelity lost its heading, so the 88px meant to sit above one is dead space:
   the lede now reads straight on from the hero's teaser note. An id beats the
   element selector, so this holds at every breakpoint. */
#fidelity{padding-top:0}
#cite{scroll-margin-top:84px}
#fidelity .wrap > p{max-width:none}
/* .teaser-note is justified; the section prose that continues from it was not,
   so the two read as different settings. */
section .wrap > p, .lede{text-align:justify; hyphens:auto}
/* The decorative field runs behind the whole page, and the TL;DR and the teaser
   note were the only prose lifted clear of it. Every section paragraph now sits
   on the same frosted paper: translucent with a blur, so a form crossing below
   reads as a soft haze rather than being hard-cut at the edge. The vertical
   padding is half the gap between paragraphs, so consecutive blocks meet and
   the passage reads as one sheet instead of a ladder of strips. No side
   padding: the justified edges must stay flush with the column. */
section .wrap > p, section .wrap > .lede{
  position:relative; z-index:2;
  background:color-mix(in srgb, var(--paper) 72%, transparent);
  backdrop-filter:blur(5px); -webkit-backdrop-filter:blur(5px);
  padding:13px 0;
  margin-top:-13px; margin-bottom:13px;
}
/* A paragraph beside a floated figure is only narrow line by line — the block
   itself still spans the column, so its frosted panel would be painted across
   the figure. The figures sit above it. */
section .wrap > figure, .chartfig{position:relative; z-index:3}
section .wrap{max-width:var(--maxw); margin:0 auto; position:relative; z-index:1}

.sect-head{
  display:grid;
  grid-template-columns:auto 1fr;
  gap:26px;
  align-items:start;
  margin-bottom:40px;
}
.sect-no{
  width:64px; height:64px; flex:none;
  display:flex; align-items:center; justify-content:center;
  font-family:var(--display); font-size:30px; font-weight:500;
  color:var(--plate);
  transform:rotate(-5deg);
  margin-top:6px;
}
.sect-no.tilt-r{transform:rotate(4deg)}
.sect-head .folio{
  font-family:var(--label); font-size:11px; font-weight:600;
  letter-spacing:.14em; text-transform:uppercase;
  color:var(--ink-faint);
  display:flex; align-items:center; gap:14px;
  margin:0 0 14px;
}
.sect-head .folio::after{content:""; height:1px; flex:1; background:var(--hairline)}
.sect-head h2{
  font-family:var(--display);
  font-size:clamp(28px, 3.6vw, 46px);
  font-weight:440; line-height:1.12; letter-spacing:-.014em;
  margin:0; max-width:20em; color:var(--ink-strong);
  font-variation-settings:"opsz" 60;
}

h3{
  font-family:var(--display); font-size:clamp(21px,2.4vw,27px);
  font-weight:480; letter-spacing:-.01em; line-height:1.25;
  margin:64px 0 16px; color:var(--ink-strong);
}
h4{
  font-family:var(--label); font-size:12px; font-weight:600;
  letter-spacing:.12em; text-transform:uppercase;
  margin:44px 0 14px; color:var(--rasp-2);
}

/* the lede reads as the first paragraph, not a size of its own */
.lede{
  font-family:var(--body); font-weight:400;
  font-size:var(--prose-size); line-height:var(--prose-lh);
  color:var(--ink); margin:0 0 26px;
}
section p{
  max-width:var(--colw);
  font-family:var(--body); font-size:var(--prose-size); font-weight:400; line-height:var(--prose-lh);
}
/* running prose sits directly in the wrap. It keeps a readable measure —
   ~72 characters to the line — set ragged-right; the plates and trace boxes
   deliberately run wider, as breakout figures do in a catalogue. */
section .wrap > p{
  max-width:72ch;
}
/* a paragraph that clears a floated figure and closes the passage: it runs the
   full column so its right edge lands under the figure's, instead of stopping
   short of it and leaving the corner ragged. */
section .wrap > p.wide{max-width:none; clear:right}
.folio, .tag, .coltag, .colmeta, .axis-title, .chart-foot{max-width:none !important}
/* `section p` sets a 66ch measure for prose. Card text is not prose — it fills
   its box, which is already the column. Without this the trace sat at 66ch
   inside a much wider card. */
.monobody, .serifbody, .col p, .blk .body, .trace pre{max-width:none}
section p a{
  color:var(--rasp-2);
  text-decoration-color:color-mix(in srgb, var(--rasp-1) 45%, transparent);
  text-underline-offset:3px;
}
section p a:hover{text-decoration-color:var(--rasp-1)}

strong{color:var(--ink-strong)}

/* painted highlight — at the jailbreak exhibit's strength everywhere:
   the paler mix melted into the pigment-washed card grounds */
mark{
  background:linear-gradient(104deg,
    color-mix(in srgb, var(--rasp-1) 34%, transparent),
    color-mix(in srgb, var(--rasp-2) 24%, transparent));
  box-decoration-break:clone; -webkit-box-decoration-break:clone;
  padding:.08em .22em; color:inherit;
}
/* the planted seed in the drift cards stays a pale mark, so the hover's
   shared-run highlight still reads clearly above it */
#drift-track mark:not(.lcs){
  background:linear-gradient(104deg,
    color-mix(in srgb, var(--rasp-1) 20%, transparent),
    color-mix(in srgb, var(--rasp-2) 14%, transparent));
}
.redact{
  display:inline-block; min-width:3.2em; height:.95em;
  vertical-align:text-bottom;
  background:linear-gradient(150deg, var(--black-1), var(--black-2));
  transform:rotate(-.4deg);
}
.redact.key{min-width:2.6em; height:.85em; margin-left:.1em; transform:rotate(-1.2deg)}

/* =========================================================
   EXAMPLE PANELS (prompt / decoded / answer)
   ========================================================= */
.ex{display:grid; grid-template-columns:1fr 1fr; gap:22px; margin:8px 0 4px; align-items:start}
@media (max-width:720px){.ex{grid-template-columns:1fr}}
.blk{
  background:var(--plate);
  padding:30px 34px 28px;
  max-width:56em;
  position:relative;
}
.blk .tag{
  display:inline-flex; align-items:center; gap:9px;
  font-family:var(--label); font-size:10.5px; font-weight:600;
  letter-spacing:.12em; text-transform:uppercase;
  color:var(--ink-soft); margin:0 0 14px;
}
.blk .tag::before{
  content:""; width:11px; height:11px;
  background:linear-gradient(150deg, var(--p1,var(--black-1)), var(--p2,var(--black-2)));
  transform:rotate(-8deg);
}
.blk .body{margin:0; max-width:none}
/* The sub-degree rotation is deliberate ink: rotating a block makes the
   browser resample its glyphs (subpixel AA turns off), and that faint
   softness reads as a printed magazine plate. Cheap offset lithography. */
.blk.prompt{
  transform:rotate(-.9deg); background:#f0f1f0;
  clip-path:polygon(.7% 3.2%, 100% 0, 99.2% 96.8%, 0 100%);
}
.blk.prompt .tag{--p1:var(--silver-1); --p2:var(--silver-2)}
.blk.reason{
  transform:rotate(-.8deg);
  background:#f9f0ec;
  clip-path:polygon(0 0, 99.4% 2.6%, 100% 100%, .8% 97.2%);
}
.blk.reason::before{
  content:""; position:absolute; top:0; left:0; right:0; height:7px;
  background:linear-gradient(100deg, var(--rasp-1), var(--rasp-2));
}
.blk.reason .tag{--p1:var(--rasp-1); --p2:var(--rasp-2); color:var(--rasp-2)}
.blk.reason .body{font-family:var(--mono); font-size:13px; line-height:1.75}
.blk.answer{
  transform:rotate(-.55deg); background:#f0f4ee;
  clip-path:polygon(1.1% 0, 99% 1.8%, 100% 98.2%, 0 100%);
}
.blk.answer .tag{--p1:var(--green-1); --p2:var(--green-2)}

/* =========================================================
   SIDE-BY-SIDE DECODED COLUMNS
   ========================================================= */
.sbs{display:grid; grid-template-columns:1fr 1fr; gap:22px}
/* every decoded-trace card wears the jailbreak exhibit's dress: paper washed
   with the card's own pigment (the way .blk.reason sits on rose and
   .blk.answer on green), a crooked cut, a tilt, and the coloured bar on top */
.col{
  position:relative;
  /* the jailbreak exhibit's paper, generalized: 5% pigment in this paper
     lands EXACTLY on its hand-picked rose (#f9f0ec) for rasp — and its
     .8deg lean is what prints the type with the soft offset-litho ink */
  background:color-mix(in srgb, var(--p1, var(--rasp-1)) 5%, #fdfaf5);
  padding:30px 32px 26px;
  min-width:0;
  transform:rotate(-.8deg);
  clip-path:polygon(0 0, 99.5% 2.4%, 100% 100%, .6% 97.6%);
}
.col::before{
  content:""; position:absolute; top:0; left:0; right:0; height:7px;
  background:linear-gradient(100deg, var(--p1,var(--rasp-1)), var(--p2,var(--rasp-2)));
}
.col.alt{
  background:color-mix(in srgb, var(--p1, var(--silver-1)) 4%, #fbfaf4);
  transform:rotate(.75deg);
  clip-path:polygon(.5% 2.4%, 100% 0, 99.4% 97.6%, 0 100%);
}
/* the pigment strip is cut by hand too: each end lies a touch off-true */
.col:nth-child(odd)::before{clip-path:polygon(0 0, 100% 22%, 100% 100%, 0 88%); height:8px}
.col:nth-child(even)::before{clip-path:polygon(0 14%, 100% 0, 99.6% 86%, .3% 100%); height:8px}
.coltag{
  font-family:var(--label); font-size:10.5px; font-weight:600;
  letter-spacing:.1em; text-transform:uppercase;
  color:var(--p2, var(--ink-strong)); margin:0 0 4px;
  display:flex; align-items:center; gap:9px;
}
/* silver ink alone is too faint for a label on pale ground */
.coltag.c-silver{color:color-mix(in srgb, var(--silver-2) 35%, var(--ink-strong))}
.coltag::before{
  content:""; width:11px; height:11px; flex:none;
  background:linear-gradient(150deg, var(--p1,var(--blue-1)), var(--p2,var(--blue-2)));
  transform:rotate(-8deg);
}
.colmeta{
  font-family:var(--mono); font-size:10.5px; color:var(--ink-faint);
  margin:0 0 14px; word-break:break-all;
}
/* the gallery cards carry a real title over the decoded text */
.coltitle{
  font-family:var(--body); font-size:21px; font-weight:460;
  letter-spacing:-.01em; line-height:1.24; color:var(--ink-strong);
  margin:0 0 12px; max-width:26em;
  font-variation-settings:"opsz" 40;
}
.monobody{
  font-family:var(--mono); font-size:13px; line-height:1.75; margin:0;
  overflow-wrap:anywhere;
}
/* A trace is written in lines — paragraph breaks, numbered steps, a table of
   assignments — and collapsing that ran every card together into one block of
   type. Only the cards poured in from the data files keep their breaks: the
   few panels typed into the page carry the source's own indentation, which
   would print as ragged gutters if it were honoured. */
.monobody.pre, .serifbody.pre{white-space:pre-wrap}
/* the cut: where a stretch of reasoning was taken out. it opens — click it
   and the missing reasoning is pasted back; click that text to fold it away */
.elide{
  display:block; margin:14px 0; padding:2px 0;
  border:none; background:none; text-align:left;
  color:var(--ink-faint); cursor:pointer;
  font-family:var(--mono); font-size:11px; letter-spacing:.35em;
  transition:color .14s ease, letter-spacing .14s ease;
}
.elide:hover, .elide:focus-visible{color:var(--rasp-1); letter-spacing:.5em; outline:none}
.elide.loading{opacity:.5}
/* the reasoning put back: the same voice, a shade quieter than the excerpt */
.uncut{
  color:var(--ink-faint); cursor:pointer;
  background:rgba(38,36,31,.045);
  box-decoration-break:clone; -webkit-box-decoration-break:clone;
  padding:.12em .24em; border-radius:1px;
  transition:color .14s ease, background .14s ease;
}
.uncut:hover{
  color:var(--ink);
  background:color-mix(in srgb, var(--rasp-1) 10%, transparent);
}
.serifbody{
  font-family:var(--body); font-size:15.5px; line-height:1.7; margin:0;
  color:var(--ink);
}

/* =========================================================
   THE CHART — painted bars, catalogue axis
   ========================================================= */
/* the chart floats right; the Results prose wraps down its left side */
.chartfig{
  float:right; width:min(46%, 440px);
  margin:4px 0 20px 36px;
}
.chartwrap{
  background:none; border:none; padding:0; box-shadow:none;
}
.chartbox{width:100%}
.clearfix{clear:both}

/* the heap: stolen traces of every shape, piled on the ground */
.heap{
  position:relative; overflow:hidden;
  min-height:min(74vh,660px);
  margin-top:0;
  background:linear-gradient(180deg, var(--paper) 0%, var(--paper-lo) 100%);
}
.heap .pile{position:absolute; inset:0}
.heap .pile > *{position:absolute; bottom:0}

/* =========================================================
   CAROUSEL — arrows + dots + swipe, one system for Privacy & Gallery
   ========================================================= */
.carousel{position:relative; margin:0}
.car-track{
  display:flex; align-items:flex-start; gap:20px; overflow-x:hidden; scroll-snap-type:none;
  scroll-behavior:smooth; touch-action:pan-y; overscroll-behavior-x:none; scrollbar-width:none;
  /* the cards ride tilted; the vertical padding keeps their lifted corners
     from being shaved off by the track's own scroll box */
  padding:14px 2px;
}
/* every card is a fixed-size window — short traces pad, long ones scroll,
   so paging never makes the box jump. drift slides stack several cells,
   so their cells get a smaller cap instead of a full fixed height. */
.car-track .monobody, .car-track .serifbody{max-height:400px; overflow-y:auto; scrollbar-width:thin}
/* A short leak hugs its text. A long one is cut at the window rather than
   scrolled inside it — the [ … ] under the card opens the rest, the same door
   the gallery cards use, so nothing is hidden behind a scrollbar the reader
   has to find. */
#privacy-track .monobody{height:auto; max-height:400px; overflow-y:auto; scrollbar-width:thin}
/* The gallery excerpts run from a few lines to a quarter of a million
   characters once a cut is opened. Left to their own height they made the
   card lurch by two thousand pixels between one arrow press and the next, so
   every window is capped: what does not fit scrolls inside the card. */
#gallery-track .monobody{height:auto; max-height:440px; overflow-y:auto; scrollbar-width:thin}
#gallery-track{align-items:center}
/* drift: trio cells are capped by .sbs.trio .col; the prompt band is capped
   here — its question and its planted seed are what differ from slide to slide */
#drift-track .monobody, #drift-track .serifbody{max-height:none}
#drift-track .driftprompt .serifbody{max-height:200px; overflow-y:auto; scrollbar-width:thin}
#drift-track .driftprompt .monobody{max-height:150px; overflow-y:auto; scrollbar-width:thin}
.car-track::-webkit-scrollbar{display:none}
.car-slide{flex:0 0 100%; min-width:0; scroll-snap-align:none}
/* Every slide of every carousel lives in the DOM at once — 113 of them,
   a quarter of a million characters of card text on 154 tilted, clipped
   layers. Laying all of it out costs ~150ms, which any invalidation
   (a hover repaint, a resize, an inner scroll) then has to pay again.
   content-visibility lets the browser skip layout and paint for slides
   nobody is looking at; the `auto` intrinsic size remembers each slide's
   real height once it has been rendered, so the fallback below only ever
   describes a slide the reader has not reached yet. Measured: 150ms -> 20ms. */
.car-slide{content-visibility:auto}
#drift-track   .car-slide{contain-intrinsic-size:auto 1400px}
#gallery-track .car-slide{contain-intrinsic-size:auto 900px}
#privacy-track .car-slide{contain-intrinsic-size:auto 520px}
/* the cards keep their collage tilt inside the carousel too — that crookedness
   is half the charm of the jailbreak exhibit */
.car-slide .col{width:100%}
/* gallery cards carry no .alt, so alternate the lean by slide instead */
#gallery-track .car-slide:nth-child(even) .col{
  transform:rotate(.75deg);
  clip-path:polygon(.5% 2.4%, 100% 0, 99.4% 97.6%, 0 100%);
}
/* gallery trace fills its card (same width as the privacy carousel above) */
#gallery-track .monobody{max-width:none}
#gallery-track .col{width:100%}
/* The arrows hold one place. Centring them on the track meant they rode its
   height, and the height is the card's — so every press slid the button out
   from under the cursor. They sit near the head of the card instead, where
   the reader's eye already is, and only a card too short to reach that far
   pulls them up to its own middle. */
.car-arrow{
  position:absolute; top:min(150px, calc(50% - 22px)); z-index:6;
  width:44px; height:44px; border:none; cursor:pointer; color:var(--plate);
  background:linear-gradient(150deg, var(--black-1), var(--black-2));
  font-family:var(--display); font-size:24px; line-height:1;
  display:flex; align-items:center; justify-content:center;
  box-shadow:0 8px 22px -12px rgba(25,24,19,.5);
  transition:translate .15s ease, opacity .15s ease;
}
.car-arrow.prev{left:-14px}
.car-arrow.next{right:-14px}
.car-arrow:hover{translate:0 -2px}
.car-arrow[disabled]{opacity:.22; cursor:default; translate:0 0}
/* a long run counts itself instead of laying out eighty diamonds */
.car-count{
  /* it is a caption, not prose — the column measure must not centre it
     against a 66ch box inside a much wider carousel */
  margin:18px 0 0; text-align:center; max-width:none;
  font-family:var(--label); font-size:11px; font-weight:600;
  letter-spacing:.18em; color:var(--ink-faint);
  font-variant-numeric:tabular-nums;
}
.car-count b{color:var(--rasp-2); font-weight:600}

/* The turn before the excerpt. Silver is already the site's colour for a
   prompt (see .blk.prompt), so the lead-in wears it too and never competes
   with the decoded reasoning underneath. Tall prompts scroll inside the card
   rather than pushing the reasoning off the bottom. */
.colctx{
  font-family:var(--mono); font-size:11.5px; line-height:1.62;
  color:var(--ink-strong); background:#f0f1f0;
  border-left:3px solid var(--ink-strong);
  padding:11px 14px 12px; margin:0 0 16px;
  white-space:pre-wrap; overflow-wrap:anywhere;
  max-height:11em; overflow-y:auto;
}
.colctx b{
  display:block; font-family:var(--label); font-size:9.5px; font-weight:600;
  letter-spacing:.12em; text-transform:uppercase; color:var(--ink-strong);
  margin:0 0 7px;
}

/* Gallery filter. Each button wears the pigment its cards are painted in, so
   the colour predicts what the carousel turns into; the little tilted square
   is the same mark the card tags carry. */
.galfilter{display:flex; flex-wrap:wrap; align-items:center; gap:9px; margin:0 0 26px}
/* Force the row to break after the fifth chip, so the bar reads as two rows —
   the five chat/self categories, then the three benchmarks — never one long run. */
.galbreak{flex-basis:100%; width:100%; height:0; margin:0; padding:0}
@media (max-width:640px){.galbreak{display:none}}
.galbtn{
  font-family:var(--label); font-size:10.5px; font-weight:600;
  letter-spacing:.1em; text-transform:uppercase;
  color:var(--ink-soft); background:var(--paper-hi);
  border:1px solid var(--hairline); cursor:pointer;
  padding:7px 12px 6px; display:flex; align-items:center; gap:8px;
  transition:color .18s ease, background .18s ease, border-color .18s ease, translate .15s ease;
}
.galbtn::before{
  content:""; width:9px; height:9px; flex:none;
  background:linear-gradient(150deg, var(--p1,var(--black-1)), var(--p2,var(--black-2)));
  transform:rotate(-8deg);
}
.galbtn:hover{color:var(--ink-strong); border-color:var(--ink-faint); translate:0 -1px}
.galbtn.on{
  color:var(--plate); border-color:transparent;
  background:linear-gradient(150deg, var(--p1,var(--black-1)), var(--p2,var(--black-2)));
}
.galbtn.on::before{background:var(--plate)}
.galbtn:focus-visible{outline:2px dashed var(--ink-strong); outline-offset:3px}
.galbtn[hidden]{display:none}
@media (max-width:640px){
  .galfilter{gap:7px}
  .galbtn{font-size:9.5px; padding:6px 9px 5px; gap:6px}
}
@media (max-width:640px){
  .car-arrow.prev{left:-6px} .car-arrow.next{right:-6px}
}
@media (max-width:720px){
  /* Unfloated, the chart's own margin is all that stands between the bars and
     the paragraph below — and the labels hang off the bottom of the bars on
     position:absolute, taking no space of their own. "Technical identifiers"
     wraps to two lines and landed on top of the prose. */
  .chartfig{float:none; width:100%; margin:22px 0 66px}
}
.axis-title{
  font-family:var(--body); font-size:20px; font-weight:600;
  color:var(--ink-strong); margin:0 0 22px;
  text-align:center;
  font-variation-settings:"opsz" 40;
}
.chart{
  display:flex; align-items:flex-end; gap:clamp(18px,3vw,40px);
  height:250px;
  border-bottom:2px solid var(--ink-strong);
  padding:0 8px;
}
.bar{
  flex:1; max-width:110px; height:100%;
  display:flex; flex-direction:column; align-items:center; justify-content:flex-end;
  position:relative;
}
.bar i{
  display:block; width:100%;
  background-image:
    radial-gradient(130% 100% at 30% 12%, rgba(255,255,255,.16), rgba(255,255,255,0) 55%),
    radial-gradient(150% 130% at 70% 95%, rgba(0,0,0,.2), rgba(0,0,0,0) 60%),
    linear-gradient(168deg, var(--p1), var(--p2));
}
.bar .val{
  font-family:var(--body); font-size:23px; font-weight:500;
  color:var(--ink-strong); margin-bottom:8px;
}
.bar .lab{
  position:absolute; top:100%; padding-top:12px;
  font-family:var(--body); font-size:16px; font-weight:440;
  color:var(--ink-soft); text-align:center; line-height:1.3;
  font-variation-settings:"opsz" 40;
}
.chart-foot{
  margin:56px 0 0; font-family:var(--body); font-style:italic;
  font-size:12.5px; color:var(--ink-faint);
}

.breakdown{
  list-style:none; margin:0; padding:0;
  font-size:14.5px;
}
.breakdown li{
  display:flex; justify-content:space-between; align-items:baseline;
  padding:8px 0; gap:12px;
  border-bottom:1px solid var(--hairline-soft);
}
.breakdown li:last-child{border-bottom:none}
.breakdown .c{
  font-family:var(--body); font-size:17px; font-weight:500;
  color:var(--rasp-2); font-variant-numeric:tabular-nums;
}

/* =========================================================
   MARGINALIA
   ========================================================= */
.note{
  position:relative;
  max-width:56em;
  margin:36px 0;
  padding:22px 28px 20px 34px;
  background:var(--paper-hi);
  border:1px solid var(--hairline);
  font-size:15.5px;
}
.note::before{
  content:""; position:absolute; left:-1px; top:-1px; bottom:-1px; width:7px;
  background:linear-gradient(170deg, var(--ochre-1), var(--ochre-2));
}
.note.alarm::before{background:linear-gradient(170deg, var(--rasp-1), var(--rasp-2))}
.note strong{
  font-weight:600; color:var(--ink-strong);
}

/* =========================================================
   MITIGATION CARDS
   ========================================================= */
.mit{
  display:grid; grid-template-columns:repeat(auto-fill, minmax(300px,1fr));
  gap:20px; margin:36px 0 8px;
}
.card{
  background:var(--plate); border:1px solid var(--hairline);
  padding:26px 26px 22px;
  position:relative;
  box-shadow:0 8px 26px -20px rgba(25,24,19,.3);
}
.card::before{
  content:""; position:absolute; top:16px; right:16px;
  width:13px; height:13px;
  background:linear-gradient(150deg, var(--p1,var(--silver-1)), var(--p2,var(--silver-2)));
  transform:rotate(-8deg);
}
.card:nth-child(6n+1)::before{--p1:var(--green-1);  --p2:var(--green-2)}
.card:nth-child(6n+2)::before{--p1:var(--blue-1);   --p2:var(--blue-2)}
.card:nth-child(6n+3)::before{--p1:var(--rasp-1);   --p2:var(--rasp-2)}
.card:nth-child(6n+4)::before{--p1:var(--ochre-1);  --p2:var(--ochre-2)}
.card:nth-child(6n+5)::before{--p1:var(--teal-1);   --p2:var(--teal-2)}
.card:nth-child(6n+6)::before{--p1:var(--rust-1);   --p2:var(--rust-2)}
.card h4{
  margin:0 34px 12px 0;
  font-size:11.5px; color:var(--ink-strong);
}
.card p{margin:0; font-size:14.5px; line-height:1.68; color:var(--ink-soft)}

/* =========================================================
   TABLES
   ========================================================= */
.scroll-x{overflow-x:auto; margin:32px 0}
.dt{
  border-collapse:collapse; width:100%; min-width:640px;
  background:var(--plate); border:1px solid var(--hairline);
  font-size:14.5px; line-height:1.6;
}
.dt caption{
  caption-side:top; text-align:left;
  font-family:var(--label); font-size:10.5px; font-weight:600;
  letter-spacing:.1em; text-transform:uppercase;
  color:var(--ink-faint); padding:0 0 12px;
}
.dt th{
  font-family:var(--label); font-size:10.5px; font-weight:600;
  letter-spacing:.08em; text-transform:uppercase; text-align:left;
  color:var(--plate);
  background:linear-gradient(150deg, var(--black-1), var(--black-2));
  padding:12px 18px;
}
.dt td{
  padding:16px 18px; vertical-align:top;
  border-top:1px solid var(--hairline-soft);
  color:var(--ink-soft);
}
.dt td.lab{
  font-family:var(--label); font-size:11px; font-weight:600;
  letter-spacing:.04em; text-transform:uppercase;
  color:var(--ink-strong); line-height:1.6;
}
.dt tr:nth-child(even) td{background:var(--paper-hi)}
code, .m{font-family:var(--mono); font-size:.86em}

/* formula */
.code{
  margin:32px 0; padding:26px 30px;
  background:linear-gradient(155deg, var(--black-1), var(--black-2));
  color:#e9e7de;
  position:relative;
  max-width:56em;
  transform:rotate(-.3deg);
  box-shadow:8px 9px 0 color-mix(in srgb, var(--rasp-2) 30%, transparent);
}
.code::after{
  content:""; position:absolute; inset:0; pointer-events:none;
  background-image:var(--grain); opacity:.2; mix-blend-mode:overlay;
}
.code pre{
  margin:0; font-family:var(--mono); font-size:14.5px; line-height:1.7;
  white-space:pre-wrap; word-break:break-word;
}

/* =========================================================
   FOOTER — the black square closes the page
   ========================================================= */
footer{
  margin-top:88px;
  position:relative;
  background:linear-gradient(160deg, var(--black-1) 0%, var(--black-2) 70%);
  color:#c9c6ba;
  padding:80px 32px 64px;
}
footer::after{
  content:""; position:absolute; inset:0; pointer-events:none;
  background-image:var(--weave), var(--grain); opacity:.14; mix-blend-mode:overlay;
}
footer .wrap{max-width:var(--maxw); margin:0 auto; position:relative; z-index:1}
footer p{max-width:78ch; font-size:14.5px; line-height:1.75}
footer strong{
  font-family:var(--label); font-size:11px; font-weight:600;
  letter-spacing:.1em; text-transform:uppercase; color:#f0eee4;
}
footer a{color:#e4d9a8; text-underline-offset:3px}
footer .fin{
  margin-top:40px; padding-top:26px;
  border-top:1px solid rgba(233,231,222,.18);
  color:#8d8a7e; font-style:italic;
}

.pagenav{
  display:grid; grid-template-columns:repeat(auto-fit, minmax(240px,1fr));
  gap:16px; margin:0 0 48px;
}
.pagenav a{
  display:block; text-decoration:none;
  font-family:var(--label); font-size:11.5px; font-weight:600;
  letter-spacing:.06em; text-transform:uppercase;
  color:#f0eee4; line-height:1.6;
  padding:18px 20px;
  border:1px solid rgba(233,231,222,.25);
  transition:border-color .16s ease, translate .16s ease, box-shadow .16s ease;
}
.pagenav a:hover{
  border-color:#e4d9a8;
  translate:-2px -2px;
  box-shadow:4px 5px 0 rgba(207,160,58,.35);
}
.pagenav a b{
  display:block; font-family:var(--body); font-weight:420;
  font-size:16px; letter-spacing:0; text-transform:none;
  margin-top:6px; color:#fbfaf7;
}

/* =========================================================
   RESPONSIVE
   ========================================================= */
@media (max-width: 900px){
  .hero{padding:64px 22px 20px}
  section{padding:64px 22px 28px}
  nav .inner{padding:0 22px; gap:18px}
  .comp{opacity:.5}
  .f-trunk{right:8%}
  .f-ochre-post,.f-orange,.f-ochre-bar,.f-redbar{display:none}
  .sbs{grid-template-columns:1fr}
  .chartwrap{grid-template-columns:1fr}
  .chart{height:210px}
  .sect-head{grid-template-columns:1fr; gap:18px}
  .sect-no{width:52px; height:52px; font-size:24px}
  .blk.reason{margin-left:0}
}
/* The eight tabs want 1,108px. Between there and the phone breakpoint they
   tighten rather than disappear — at 1,009px it was only BibTeX hanging off
   the end, and the scrollbar is hidden, so nothing said it was there. */
@media (max-width: 1180px){
  nav .inner{gap:14px}
  .tab{font-size:12px; letter-spacing:.06em}
  .tab.paper, .tab.citetab{padding:8px 11px 7px}
  .brand{font-size:13.5px; letter-spacing:.08em}
}
/* Below about a thousand pixels even the tightened row does not fit, and the
   tabs that fall off the end are the two that lead off the page — the paper
   and the citation. The section anchors go instead: a reader on a narrow
   screen scrolls the page rather than jumping around it. */
@media (max-width: 1000px){
  nav .inner{gap:14px}
  nav .inner > .tab:not(.paper):not(.citetab):not(.toctoggle){display:none}
  .brand{font-size:12.5px; letter-spacing:.07em; gap:8px}
}
@media (max-width: 560px){
  /* the brand shrinks to its mark so Contents, Paper and BibTeX all fit */
  .brand{font-size:0; gap:0}
  .brand .mark{width:18px; height:18px}
  .toctoggle{padding:6px 9px 5px}
}
@media (max-width: 560px){
  body{font-size:16px}
  .hero h1{font-size:clamp(36px,11vw,52px)}
  .comp{opacity:.32}
  .pills{gap:12px}
  .blockbtn{padding:14px 22px 13px}
}

/* Kimi drift exhibit: three columns like the paper's figure, stacked on narrow
   screens. The prompt sits above them as a full-width band. */
.sbs.trio{grid-template-columns:repeat(3,1fr); gap:14px; margin-top:14px}
@media (max-width:860px){ .sbs.trio{grid-template-columns:1fr} }
.driftprompt .monobody{margin-bottom:10px}
.driftprompt .colmeta{margin-top:12px}

/* Untruncated reasoning: the columns differ by up to 20x in length, so every
   box is the SAME size and scrolls inside itself. That size is a true square —
   the suprematist unit — so the exhibit reads as rows of three squares. */
.sbs.trio{align-items:start}
/* no vertical padding of its own — fixed padding zones let scrolled text
   peek out crisp above the header band and below the fade. The header
   carries the top air; the body's own bottom padding carries the ending,
   and it scrolls WITH the text, so the last line can ride clear of the
   fade at scroll end. */
.sbs.trio .col{aspect-ratio:1/1; height:auto; min-height:0; overflow-y:auto; scrollbar-width:thin; padding-top:0; padding-bottom:0}
.sbs.trio .col .monobody, .sbs.trio .col .serifbody{padding-bottom:32px}
/* the trace dissolves just above the square's lower edge instead of being
   guillotined by the scrollport; sticky, so it never scrolls away. The
   gradient goes fully solid 12px early: the card's crooked bottom cut runs
   through that solid zone, so the fade hugs the real slanted edge. */
.sbs.trio .col::after{
  content:""; position:sticky; bottom:0; display:block;
  height:34px; margin:-34px -32px 0; pointer-events:none;
  background:linear-gradient(to bottom, transparent,
    color-mix(in srgb, var(--p1, var(--rasp-1)) 5%, #fdfaf5) calc(100% - 12px));
}
.sbs.trio .col.alt::after{
  background:linear-gradient(to bottom, transparent,
    color-mix(in srgb, var(--p1, var(--silver-1)) 4%, #fbfaf4) calc(100% - 12px));
}
/* the card's header does not travel with the trace: chip and meta ride a
   sticky band at the top of the square, the text scrolls beneath them.
   The pigment strip moves onto that band (an absolutely-positioned strip
   would scroll away with the content). */
.sbs.trio .col::before{display:none}
.colhead{
  position:sticky; top:0; z-index:2;
  background:inherit;
  margin:0 -32px 12px; padding:28px 32px 9px;
}
.colhead::before{
  content:""; position:absolute; top:0; left:0; right:0; height:8px;
  background:linear-gradient(100deg, var(--p1,var(--rasp-1)), var(--p2,var(--rasp-2)));
  clip-path:polygon(0 0, 100% 22%, 100% 100%, 0 88%);
}
.colhead .colmeta{margin-bottom:0}
/* appliqué: no two squares are glued at exactly the same angle — but all
   stay in the .7–.85deg band where the printed-ink softness shows */
.sbs.trio .col:nth-child(1){transform:rotate(-.8deg)}
.sbs.trio .col:nth-child(2){transform:rotate(.7deg)}
.sbs.trio .col:nth-child(3){transform:rotate(-.75deg)}
.sbs.trio.answer-trio .col:nth-child(1){transform:rotate(.72deg)}
.sbs.trio.answer-trio .col:nth-child(2){transform:rotate(-.8deg)}
.sbs.trio.answer-trio .col:nth-child(3){transform:rotate(.78deg)}
/* the prompt band speaks in the same voice as the model answers */
.driftprompt .serifbody{font-size:var(--prose-size); line-height:1.6}

/* the Summary Unfaithfulness pair wears the jailbreak exhibit's rhythm:
   the same padding and the same generous air under the header (no meta
   line sits between tag and body here); lean and paper now come from the
   card base, which prints at the jailbreak angle everywhere */
#extras .sbs:not(.trio) .col{padding:30px 34px 28px}
#extras .sbs:not(.trio) .coltag{margin-bottom:14px}
@media (max-width:860px){
  /* stacked full-width cards: a square would be a huge scroll well on a
     phone, so reasonings go back to a fixed window and answers hug content */
  .sbs.trio .col{aspect-ratio:auto; height:440px}
  .sbs.trio.answer-trio .col{height:auto; max-height:360px}
}
.driftprompt{max-height:none; overflow:visible}

/* =========================================================
   SHARED WORDING — nothing is marked until the cursor asks.
   Pointing at a word grows the longest exact run of characters
   the neighbouring card also contains, and lights it in both.
   ========================================================= */
mark.lcs{
  background:linear-gradient(100deg, rgba(168,48,72,.34), rgba(131,35,56,.22));
  color:var(--ink-strong);
}

/* the game opens above the figure, so the figure slides down out of the way */
.guessgame{opacity:0; translate:0 -14px; transition:opacity .35s ease, translate .35s cubic-bezier(.2,.8,.2,1)}
.guessgame.in{opacity:1; translate:0 0}
.teaser{transition:translate .35s cubic-bezier(.2,.8,.2,1)}
/* the mode switch rides beside the question. It names the mode it takes you
   to, and wears that mode's dress once you are in it: outlined while you are
   reading stolen reasoning, painted green on the sanctioned output. */
.gg-mode{
  font-size:12px; letter-spacing:.13em; padding:12px 18px 11px;
  white-space:nowrap; align-self:flex-end; margin-bottom:7px;
}
/* what a model let you see is set in the reading face — the same rule the
   drift exhibit follows: mono is the machine's private voice, serif is public */
.gg-cols.answers .gg-trace{
  font-family:var(--body); font-size:14.5px; line-height:1.62;
  overflow-wrap:normal;
}


/* Provenance note under a carousel column tag: says where the sensitive-looking
   strings come from, so a synthetic benchmark fixture is not read as a leak. */
.colnote{
  margin:-2px 0 10px; font-size:12px; line-height:1.45;
  color:var(--ink-faint); font-style:italic;
}
.colnote code{
  font-family:var(--mono); font-style:normal; font-size:11px;
}


/* The citation block, cut from the same paper as the exhibit panels: pigment
   mixed into the cream, a hand-trimmed edge, and the gradient strip along the
   top. Not .col itself — that one is sized by the carousel that owns it. */
.citehd{
  font-family:var(--display); font-size:22px; font-weight:500;
  margin:0 0 20px; color:var(--ink-strong);
}
.bibwrap{
  position:relative; max-width:56em;
  background:color-mix(in srgb, var(--p1, var(--rasp-1)) 5%, #fdfaf5);
  padding:28px 32px 24px 36px;
  transform:rotate(-.55deg);
  clip-path:none;
}
/* the splinter, cut and leaning like the one beside TL;DR — a touch thinner */
.bibwrap .bbar{
  position:absolute; left:13px; top:16px; bottom:16px; width:10px; z-index:1;
  transform:rotate(1.8deg);
  clip-path:polygon(22% 0, 100% 2%, 78% 100%, 0 98%);
}
/* a clipped element cannot cast a shadow — filter runs before clip-path — so
   the panel paints an offset copy of the splinter underneath it */
.bibwrap::before{
  content:""; position:absolute; z-index:0;
  left:16px; top:20px; bottom:12px; width:10px;
  transform:rotate(1.8deg);
  clip-path:polygon(22% 0, 100% 2%, 78% 100%, 0 98%);
  background:rgba(25,24,19,.5);
}
/* BibTeX colouring, hand-rolled: entry type and key carry the panel's own
   pigment, field names go teal, braces and equals recede so the values read
   first. Copying is unaffected — the spans hold no text of their own. */
.bib .bt{color:var(--rasp-2); font-weight:600}
.bib .bk{color:var(--ink-strong); font-weight:600}
.bib .bf{color:var(--teal-2)}
.bib .bv{color:var(--ink)}
.bib .bp{color:var(--ink-faint)}
.bib{
  font-family:var(--mono); font-size:12px; line-height:1.7;
  white-space:pre-wrap; overflow-wrap:anywhere;
  margin:0; padding:0; border:none; background:none;
  color:var(--ink);
}
/* the page's own button, shrunk to sit in the corner: .blockbtn carries the
   face, the tracking and the hard offset shadow — only the scale changes */
.bibcopy{
  position:absolute; top:14px; right:18px;
  padding:9px 18px 8px;
  font-size:11.5px;
}
@media (max-width:640px){
  .bibwrap{padding:22px 18px 18px 26px; transform:none; clip-path:none}
  .bib{font-size:11px}
  .bibcopy{position:static; display:block; margin:0 0 12px}
}
