/* ============================================================
   PALETTE v7 — semantic ground/type layer.
   Added alongside the legacy --cream/--deep/--fluoro literals, which the
   six unmigrated sections still use. New work uses the semantic tokens
   only. Migration is section by section, each one verified by eye.

   The fault this fixes: the old set had three tones but two usable
   pairings. Everything involving fluoro measured 3.0-3.5 in every
   direction, so fluoro could never carry type and became flat planes of
   low-contrast mush. Near-black ink #0D1633 unlocks it. Ink on fluoro is
   4.79, so fluoro is now a ground that holds copy.

   LIGHT ladder   paper -> deep -> fluoro -> paper -> ink -> paper -> cream
   Measured steps 12.08    3.50     3.45      16.51   16.51   1.28 (a settle)

   DARK is a re-anchor, not an inversion. Dark grounds compress: ink to
   deep is only 1.37, so a five-step dark ladder is not physically
   available. Dark mode therefore runs two grounds and lets fluoro carry
   the whole rhythm. Stated rather than faked.
   ============================================================ */
:root{
  /* palette — fixed values, never used directly in a rule */
  --p-paper:#F7F1E3; --p-cream:#E8D6A4; --p-fluoro:#E8251F;
  --p-deep:#173CA8;  --p-ink:#0D1633;   --p-fluoro-deep:var(--accent-type);
  --p-fluoro-lift:var(--accent-type); --p-paper-dim:#E6E0D2;

  /* semantic — what a rule may reference */
  --g:var(--p-paper);        /* section ground            */
  --g-inset:var(--p-cream);  /* card / inset on that ground */
  --t-inset:var(--p-deep);   /* type ON that inset. An inset that changes
                                ground must change its type with it, or a
                                card silently renders ink on ink. */
  --t:var(--p-deep);         /* primary type   12.08 on paper */
  --t-mute:#4A5578;          /* metadata        6.18 on paper */
  --t-accent:var(--p-fluoro-deep); /* small accent type 5.07 */
  --mark:var(--p-fluoro);    /* rules, marks, display type only */
  --rule:rgba(23,60,168,.22);
}
/* ground contexts. Put one of these on a section and the type follows. */
[class*="on-"]{background:var(--g);color:var(--t)}

/* DARK. Grounds re-anchor to ink; the two light grounds fold into the two
   darks. Fluoro is untouched, so the one violent moment survives the
   switch unchanged. Pure paper at 16.51 on ink is harsh at night, so
   dark-mode type is #E6E0D2 at 14.13. */
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]){
    --g:var(--p-ink); --g-inset:var(--p-deep); --t-inset:var(--p-paper-dim);
    --t:var(--p-paper-dim); --t-mute:#9AA2C0; --t-accent:var(--p-fluoro-lift);
    --rule:rgba(247,241,227,.18);
  }
  /* .on-fluoro deliberately unchanged */
}
/* manual override hook, so a toggle can be added later without a rewrite */
:root[data-theme="dark"]{ --g:var(--p-ink); --g-inset:var(--p-deep); --t-inset:var(--p-paper-dim);
  --t:var(--p-paper-dim); --t-mute:#9AA2C0; --t-accent:var(--p-fluoro-lift);
  --rule:rgba(247,241,227,.18) }/* Reading inset. The near-white column that body copy sits on. */


/* ---------- PROOF ----------
   The one fluoro plane. Fluoro carries no small type anywhere; on this ground
   the type colour is ink, measured 4.79.
   Kept deliberately short. Evidence read on the way past, not a destination. */

/* The figures count up with the scroll: see PROOF figures in home.js. They are
   never hidden; with no JS the markup already holds the final values. */



:root{
  /* palette, families, --pad and --max are defined in base.css */
  --ground:var(--cream); --text:var(--deep);
  --xs:var(--t-small); --sm:var(--t-small); --base:var(--t-body); --md:var(--t-h3);
  --lg:var(--t-h3); --xl:var(--t-h2); --xxl:var(--t-h1);
  --ease:cubic-bezier(.16,1,.3,1);
  --sec:clamp(var(--s-8),10vw,var(--s-10));
}
*{box-sizing:border-box}
html{scroll-behavior:smooth}
html,body{margin:0}
/* the grid moved to a fixed layer in base.css so its strength can be driven
   by the scroll; body only carries the ground colour now */
body{background:var(--ground);color:var(--text);font-family:var(--fb);font-size:var(--t-body);line-height:var(--lh-body);-webkit-font-smoothing:antialiased;overflow-x:hidden}
body::after{content:"";position:fixed;inset:0;pointer-events:none;z-index:80;opacity:.035;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E")}
.wrap{max-width:var(--max);margin:0 auto;padding:0 var(--pad)}
h1,h2,h3{font-family:var(--fd);font-weight:700;margin:0;line-height:.95;letter-spacing:var(--fd-track)}
p{margin:0 0 1rem}
a{color:inherit}
.mono{font-family:var(--fu);font-size:var(--xs);letter-spacing:.08em;text-transform:uppercase}
:focus-visible{outline:2px solid var(--fluoro);outline-offset:3px}

/* ---------- section head ----------
   One left edge (9 Oct, at his instruction). It used to be a two-column grid
   whose first column was sized `auto`, which meant the heading started wherever
   the label beside it happened to end: "03 / Ideas" and "How the work happens"
   are different lengths, so the same device landed on five different left edges
   across the site (measured: 132, 142, 160, 207 and 251px at 1280).
   Now the label, the heading, the sub and the body below all start at the
   content edge, which is what /work, /contact and the five case pages already
   did. The star keeps its place beside the label rather than above it, via
   :has(); where there is no star the label simply starts the row. */
.shead{display:grid;grid-template-columns:auto minmax(0,1fr);column-gap:.7rem;row-gap:.55rem;
  align-items:center;border-top:3px solid var(--deep);padding-top:1rem;margin-bottom:2.6rem}
.shead .no{grid-column:1 / -1;font-family:var(--fu);font-size:var(--xs);letter-spacing:.08em;
  opacity:.82;margin:0;font-weight:inherit}
.shead:has(.smark) .no{grid-column:2;grid-row:1}
.shead h2{grid-column:1 / -1;font-size:var(--xl);margin:0}
.shead .sub{grid-column:1 / -1;font-size:var(--base);opacity:.82;max-width:34em;margin-top:.7rem}

/* ---------- nav ---------- */
/* scoped to the island by id (12 Oct). As a bare element selector this
   caught the first other <nav> on the site, the Explore column in the sign
   off, and threw it to the top of the viewport as a second fixed bar. */
nav#nav{position:fixed;top:0;left:0;right:0;z-index:60;display:flex;justify-content:space-between;align-items:center;
  padding:1.1rem var(--pad);font-family:var(--fu);font-size:var(--xs);letter-spacing:.08em;text-transform:uppercase;
  transition:transform 320ms var(--ease),background 320ms var(--ease)}
nav#nav .sig{font-weight:600}
/* the logo in the island (Nav1, delivered 1 Oct). It is a single-colour mark,
   so it is inverted to the island's cream rather than recoloured per theme. */
nav#nav .sig{display:flex;align-items:center}
nav#nav .links{display:flex;gap:1.5rem}
nav#nav a{text-decoration:none;position:relative;padding:3px 0}
nav#nav .sig{background:none;border:0;padding:0;box-shadow:none}
@media(max-width:820px){nav .links{display:none}}

/* ============================================================
   HERO (rebuilt 21 Sep 2026). One block; it replaces three stacked
   patches that each re-set the same properties.

   A side-by-side split, after a reference Shrey chose.
     Take only: the colour field against the photograph, the photograph
     as a halftone print, one small caption.
     Ignore: the top/bottom stack (it broke the reading), their red, their
     handwriting and scribble. The cut-out name does the scribble's job,
     stuck across the foot of the print.
   Left, the artefact on a fluoro field. Right, the words in one column
   that reads straight down: category, the line, the idea, the sign-off,
   the two actions, the proof.
   ============================================================ */
.hero{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);min-height:100vh;min-height:100svh}

/* ---------- the artefact ---------- */
/* sized so print, name and caption fit one screen: the stack is ~1.5x the width */
/* a real halftone, rendered once from the photograph (dot size follows
   how dark the photo is) and printed in deep ink on cream paper */ /* a label on the print: small type never sits on red */

/* the name: cut-outs stuck across the foot of the print */
.hero-name{position:absolute;left:-7cqw;right:-5cqw;top:calc(125cqw - 26cqw);
  margin:0;font-size:inherit;line-height:normal;letter-spacing:normal}
.hero-name .l1{display:flex;flex-wrap:nowrap;align-items:flex-end;gap:2.5cqw}
.hero-name .l2{display:block;margin-top:1.5cqw}
.tile{display:block;will-change:transform;cursor:grab;user-select:none}
.tile img{display:block;width:100%;height:auto;pointer-events:none;filter:drop-shadow(3px 4px 0 rgba(13,22,51,.45))}
.t-hi{width:17cqw} .t-my{width:19cqw} .t-name{width:34cqw} .t-is{width:12cqw} .t-shrey{width:78cqw}

/* ---------- the words ---------- */
.hero-k{margin:0;font-family:var(--fu);font-size:var(--t-small);line-height:1.6;color:rgba(var(--deep-rgb),.8)}
.roll{display:inline-block;height:1.25em;overflow:hidden;vertical-align:bottom;margin-top:var(--s-1);
  background:var(--deep);color:var(--cream);padding:0 .3em;transform:rotate(-1.2deg)}
.hero-cta{display:flex;flex-wrap:wrap;align-items:center;gap:var(--s-4) var(--s-6);margin-top:var(--s-7)}
.hbtn{display:inline-flex;align-items:center;min-height:48px;padding:0 var(--s-5);background:var(--deep);color:var(--cream);
  font-size:var(--t-body);font-weight:600;text-decoration:none;transition:background-color var(--d-1) ease,color var(--d-1) ease}
.hbtn:hover,.hbtn:focus-visible{background:var(--deep);color:var(--cream)}


/* the words: one column, centred on the screen's height */

/* tablets and phones: the artefact on top, full width, then the words */
@media (max-width:900px){
  .hero{grid-template-columns:minmax(0,1fr);min-height:0}
  /* the name stays on the screen: it overhangs the print, never the edge */
  .hero-name{left:-4cqw;right:auto}
}

/* ---------- ticker ----------
   The transition between identity and proof. One job: other people vouch
   for him. Hierarchy, top to bottom: the quotes are evidence and must be
   READ, so they do not move. The places are recognition, not comprehension,
   so they are the thing that moves. The disciplines are metadata and sit
   still and small. Previously all three were identical marquees, which made
   the only third-party validation on the site the least legible thing on it. */
 /* the tape above is the divider; --sec here was dead air */

/* metadata. Smallest, mono, muted — the bottom of the hierarchy. */
/* ---------- worked with ----------
   A credits line, not a logo wall. Six equal cells ruled like a table, names
   muted until pointed at, when the cell inverts. Only real employers, events and
   projects sit here, with context where it was not a job; spec brands never do. */
/* The eight marks, cut from the board Shrey supplied (2 Oct). They are
   mixed lockups: two sit on their own dark or orange plate, the rest are
   free-standing, so each one is capped by height rather than width and the
   row aligns on the optical centre instead of the box. UN Youth and BCG keep
   their college-project line, per CONTENT. */
/* The marks are exported on one ink and pre-balanced by ink area (2 Oct),
   so a single height is correct for all eight: no per-logo nudging. */
/* Bigger, and on the red (6 Oct feedback): at this size the marks are
   graphics, not small type, so cape red clears the 3:1 that large graphics
   need on the ground. Full breadth of the row, one height for all eight. */
/* Each mark is trimmed to its own ink and sized by height, which is how a
   logo wall is normally set: a square device and a long wordmark then read
   as the same weight. Width follows. */
/* Bliss and Birch is drawn small inside its own lockup, so at a shared cap
   height it still reads light. One nudge, the way a logo wall is normally
   optically corrected. */


/* ---------- the cross ----------
   Two bands meet in an X, from the riyadesign reference (chosen by Shrey,
   17 Sep 2026). What he does runs one way on deep; what it moved runs the
   other way on cream, ruled so it reads where it crosses. Speed follows the
   scroll through Lenis: scrolling pushes the bands, scrolling back reverses
   them, pointing at a band slows it to a stop. The riso star is the separator. */


/* ---------- the strip of marks (13 Oct, at his instruction) ----------
   One comic ticker on this page and it is the quote tape. These are other
   people's marks and they are evidence, so they travel on a ruled line with no
   torn edge, no tilt and no stars between them.
   The whole strip is also a way into the metrics below it: home.js makes a
   click on it open that drawer, which is why it carries a pointer. */
.logo-strip{position:relative;overflow:hidden;cursor:pointer;
  border-top:2px solid var(--deep);border-bottom:2px solid var(--deep)}
/* the shared .xtrack rule went with the crossing bands; each track needs its
   own row now or the four repeat copies stack instead of running */
.logo-strip .xtrack{display:flex;width:max-content;will-change:transform}
.logo-strip:is(:hover,:focus-within){background:rgba(var(--deep-rgb),.04)}

/* ---------- the metrics, collapsed onto a pill ----------
   Closed on arrival. Shield yellow, because this is the one plane on the page
   that has to be found rather than read past, and it is the first time yellow
   carries a surface rather than a highlight. Ink on yellow is 14.73, so the
   type inside is ink and the red accent stays off it. */
.mv{margin-top:var(--s-6)}
.mv-pill{cursor:pointer;list-style:none;display:flex;align-items:center;gap:var(--s-4);
  background:var(--yellow);color:#0D1633;border:2px solid #0D1633;border-radius:999px;
  padding:clamp(.9rem,2vw,1.3rem) clamp(1.6rem,3.5vw,2.6rem);min-height:56px}
.mv-pill::-webkit-details-marker{display:none}
.mv-pill-k{font-family:var(--fd);font-weight:900;font-size:var(--t-h3);line-height:1.1;
  letter-spacing:var(--fd-track)}
.mv-pill-n{margin-left:auto;font-size:var(--xs);letter-spacing:.08em;text-transform:uppercase;opacity:.72}
.mv-chev{flex:none;width:14px;height:14px;border-right:3px solid #0D1633;border-bottom:3px solid #0D1633;
  transform:rotate(45deg) translate(-2px,-2px);transition:transform var(--d-2) var(--e-out)}
.mv[open] .mv-chev{transform:rotate(225deg) translate(-2px,-2px)}
.mv-pill:focus-visible{outline:3px solid var(--deep);outline-offset:3px}
@media (prefers-reduced-motion:reduce){.mv-chev{transition:none}}

/* the drawer sits under the pill on the page's own ground */
.mv .mv-grid{margin-top:var(--s-6)}
@media (max-width:640px){
  .mv-pill{border-radius:28px;flex-wrap:wrap;gap:var(--s-2) var(--s-3)}
  .mv-pill-n{margin-left:0;width:100%}
}

/* ---------- what I do, and what it moved ----------
   This replaces the crossing bands (7 Oct). The X said something true, that
   the disciplines and the results belong to each other, and it said it in
   motion, which is where the seven figures went to not be read. A scanning
   reader takes away "there are numbers" rather than any one of them, and
   these seven are the most persuasive content on the site.
   So the same two ideas, side by side and still. The figure leads at display
   size, the unit sits next to it, and the employer sits under it, because a
   number without a source is a claim and a number with one is evidence. */
.moved{padding:clamp(3rem,7vw,5rem) 0 clamp(2.5rem,6vw,4rem)}
/* align-items:start, or a closed drawer reclaims nothing: grid items stretch
   to the row by default, so the column kept its full height with the list
   hidden inside it and the collapse did nothing visible. */
.mv-grid{display:grid;grid-template-columns:minmax(0,.95fr) minmax(0,1.25fr);gap:clamp(2rem,5vw,4.5rem);
  align-items:start;border-top:2px solid var(--deep);padding-top:var(--s-6)}
/* Both columns are native <details> (9 Oct, at his instruction). Native,
   because it is keyboard operable, announced correctly, and works with the
   script switched off, none of which a div and a click handler gives you.
   Both carry `open`: the figures are the most persuasive content on the page
   and a closed drawer buries them. Collapsing is for the second read. */
/* the marker is drawn, so it can be the site’s own line work rather than a
   platform triangle: a rule that loses its upright when the drawer opens */
@media (prefers-reduced-motion:reduce){.mv-col > summary::after{transition:none}}
.mv-k{font-size:var(--xs);letter-spacing:.08em;text-transform:uppercase;opacity:.82;margin:0 0 var(--s-5)}
.mv-do{list-style:none;margin:0;padding:0;display:flex;flex-wrap:wrap;gap:var(--s-3) var(--s-4);line-height:1.5}
.mv-do li{font-family:var(--fu);font-size:var(--t-small);letter-spacing:.04em;text-transform:uppercase;
  color:var(--deep);white-space:nowrap}
.mv-do li::after{content:"·";margin-left:var(--s-4);opacity:.5}
.mv-do li:last-child::after{content:none}
.mv-figs{list-style:none;margin:0;padding:0;display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
  gap:var(--s-5) var(--s-6)}
.mv-figs li{display:grid;grid-template-columns:max-content minmax(0,1fr);align-items:baseline;
  column-gap:var(--s-3);border-top:1.5px solid rgba(var(--deep-rgb),.3);padding-top:var(--s-2)}
.mv-figs b{grid-row:span 2;font-family:var(--fd);font-weight:900;font-size:clamp(1.5rem,2.6vw,2.1rem);
  line-height:1;letter-spacing:var(--fd-track);color:var(--deep)}
.mv-what{font-family:var(--fb);font-size:var(--t-small);line-height:1.3;color:var(--deep)}
.mv-who{font-family:var(--fu);font-size:var(--xs);letter-spacing:.06em;text-transform:uppercase;
  color:var(--accent-type)}
@media (max-width:900px){
  .mv-grid{grid-template-columns:minmax(0,1fr);gap:var(--s-7)}
  .mv-figs{gap:var(--s-4) var(--s-5)}
}
@media (max-width:560px){.mv-figs{grid-template-columns:minmax(0,1fr)}}

/* ---------- what keeps me going: the artefacts float ----------
   Three objects he made, not three images in a row. Each carries its own slow
   loop with a different duration and delay, so they never line up and the
   group never reads as a grid. CSS keyframes on transform only, which the
   compositor handles and which cannot stack or lag the way the hero drift did.
   Under reduced motion they simply sit still, slightly rotated, which is what
   they look like at rest anyway. */
.mot{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:clamp(1rem,3vw,2.6rem);
  align-items:center;margin:var(--s-7) 0 0}
.mot-item{margin:0}
.mot-item img{display:block;width:100%;height:auto}
.mot-item--1{animation:mot-a 7.5s ease-in-out infinite}
.mot-item--3{animation:mot-a 8.2s ease-in-out infinite 1.2s}
@keyframes mot-a{0%,100%{transform:translateY(0) rotate(-1.5deg)}50%{transform:translateY(-10px) rotate(.8deg)}}
@keyframes mot-b{0%,100%{transform:translateY(-6px) rotate(1.6deg)}50%{transform:translateY(6px) rotate(-1deg)}}
@media (prefers-reduced-motion:reduce){.mot-item{animation:none;transform:rotate(-1.2deg)}}
@media (max-width:760px){.mot{grid-template-columns:minmax(0,1fr);gap:var(--s-6)}}

/* ---------- the process: an orange band that runs ----------
   Its own ground, at his instruction, because every section should change
   colour. Orange is new to the palette and earns its place by being the only
   one: ink on it is 9.1, so the type is ink and nothing else sits here. */
.process{--orange:#F0792A;position:relative;overflow:hidden;background:var(--orange);
  border-top:3px solid #0D1633;border-bottom:3px solid #0D1633;margin:var(--s-6) 0 0}
.process .pr-band{position:relative;overflow:hidden}
.process .xtrack{display:flex;width:max-content;will-change:transform}
.pr-set{list-style:none;margin:0;padding:0;display:flex;align-items:stretch;flex:none}
/* An infographic, not a list of names (19 Oct, at his instruction). The band
   used to run the five step names and nothing else, which repeated the cards
   below it word for word and carried no information they did not. Each step
   now shows its mark, its number, its name and the one line that says what
   actually happens in it, so the band is the summary and the cards are the
   detail.
   The marks are his own hero artwork, matched to meaning rather than assigned
   to fill a slot: the record player listens, the pencil starts blank, the bulb
   is the research turning into something, the phone is the step that is a
   conversation, the star is the standard it becomes. */
.pr-step{flex:none;display:flex;align-items:center;gap:clamp(.7rem,1.3vw,1.1rem);
  padding:clamp(.85rem,1.5vw,1.15rem) clamp(1.1rem,2.4vw,2rem);white-space:nowrap;
  border-right:2px solid rgba(13,22,51,.28)}
.pr-ico{flex:none;display:block;width:clamp(48px,5.2vw,74px);height:clamp(48px,5.2vw,74px)}
.pr-ico img{display:block;width:100%;height:100%;object-fit:contain}
.pr-txt{display:grid;gap:2px;line-height:1.12}
.pr-txt b{font-family:var(--fu);font-weight:400;font-size:var(--xs);letter-spacing:.1em;color:#0D1633}
.pr-txt strong{font-family:var(--fd);font-weight:900;font-size:clamp(1rem,1.5vw,1.3rem);
  letter-spacing:var(--fd-track);color:#0D1633}
/* No opacity on type over the orange, ever. The step numbers were at .7 here
   and measured 3.98; this sub-line was at .72 and measured 4.16. Both were
   estimated rather than checked. Full ink is 9.1 and the hierarchy is carried
   by family and size, which costs nothing. */
.pr-txt i{font-family:var(--fb);font-style:normal;font-size:var(--t-small);
  color:#0D1633;white-space:normal;max-width:22ch}
@media (max-width:640px){
  .pr-txt i{display:none}
  .pr-ico{width:38px;height:38px}
}

/* ---------- work: pinned collage ----------
   Scroll and hover mechanics translated from alaris.studio (reference chosen by
   Shrey, 17 Sep 2026), measured from the live site rather than its source:
   - the section is 240vh (was 400vh; cut 22 Sep 2026 on "too much scroll") and its shell sticks for 100vh;
   - progress p runs 0..1 across the scroll; tile i lands over p = reveal..reveal+.13,
     rising 16vh and scaling .9 to 1, tilted;
   - ghost type slides along a curve, trailed by marks, drifting 5vh against the scroll;
   - hover crossfades the poster out in .25s onto footage that plays, and rewinds on leave.
   Differences on purpose: cream/deep/fluoro instead of black, our star as the trailing
   mark, no drop shadow on hover (veto list), no transition on the tile transform (it
   stacked a second ease on top of Lenis and made tiles lag the scroll), and below 760px
   the collage pins as a deck instead of stacking. Only reduced motion stacks. */
.work{--wk-ease:cubic-bezier(.2,.75,.2,1);background:var(--deep);color:var(--cream);position:relative;
  padding:clamp(4.5rem,12vw,6rem) var(--pad) clamp(4rem,10vw,5.5rem)}
.wk-shell{position:relative;max-width:var(--max);margin:0 auto}
.wk-eyebrow,.wk-note,.wk-label{font-family:var(--fu);text-transform:uppercase}
.wk-eyebrow{font-size:var(--xs);letter-spacing:.08em;opacity:.82;margin:0}
.wk-title{font-family:var(--fd);font-weight:700;font-size:var(--t-h2);line-height:.92;
  letter-spacing:var(--fd-track);max-width:9ch;margin:.8rem 0 0;color:var(--cream)}
.wk-sub{font-size:var(--base);line-height:1.5;opacity:.82;max-width:24em;margin:1.2rem 0 0}
.wk-ghost{display:none}

.wk-stage{display:grid;grid-template-columns:minmax(0,1fr);gap:2.6rem;margin-top:3rem}
.wk-tile{display:block;color:var(--cream);text-decoration:none;transform:rotate(var(--r,0deg))}
.wk-tile:focus-visible{outline:3px solid var(--fluoro);outline-offset:8px}
/* 16:10 again (12 Oct): the covers were portrait A-series when they arrived
   in October and the collage was retuned to match. He has supplied 1600x1000
   masters, so the slot goes back to the shape it was designed for. */
.wk-frame{position:relative;display:block;aspect-ratio:16/10;overflow:hidden;contain:paint;container-type:size;
  border:1px solid rgba(var(--cream-rgb),.22);background:var(--cream)}

/* poster: the still face. Typographic until real imagery exists. */
.wk-poster img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:center}
.wk-poster{position:absolute;inset:0;z-index:2;display:flex;flex-direction:column;justify-content:space-between;
  padding:5cqw 5.5cqw;transition:opacity .25s var(--wk-ease)}
.wk-poster::after{content:"";position:absolute;inset:0;pointer-events:none;opacity:.08;
  background-image:radial-gradient(circle at 1px 1px,currentColor 1px,transparent 1.2px);background-size:5px 5px}

/* inside: what the hover reveals. Scrolls once, like a recording of the page,
   and snaps back to the top when the pointer leaves, like a video rewinding. */

/* The caption is the only writing on a poster wall, so it is set to be read
   from across the room rather than squinted at: the name at display size on
   its own line, the state under it. It also sits on a paper plate, which is
   what makes it read as a sticker on the print rather than a caption floating
   on the blue. */
.wk-label{display:flex;flex-direction:column;align-items:flex-start;gap:2px;margin-top:14px;
  font-size:var(--t-small);letter-spacing:.08em;color:rgba(var(--cream-rgb),.72)}
.wk-label span:first-child{color:var(--cream);font-weight:600}
.wk-label span:last-child{text-align:right}

.wk-note{display:block;font-size:var(--xs);letter-spacing:.08em;line-height:1.55;color:rgba(var(--cream-rgb),.55);margin:2.4rem 0 0}
a.wk-note{display:inline-flex;align-items:center;gap:14px;padding:6px 0;color:var(--cream);text-decoration:none}
a.wk-note:focus-visible{outline:3px solid var(--fluoro);outline-offset:6px}
.wk-arrow{position:relative;display:inline-block;width:74px;height:1px;background:rgba(var(--cream-rgb),.45);
  transition:width .3s var(--wk-ease)}
.wk-arrow::after{content:"";position:absolute;right:0;top:50%;width:8px;height:8px;
  border-top:1px solid rgba(var(--cream-rgb),.6);border-right:1px solid rgba(var(--cream-rgb),.6);transform:translateY(-50%) rotate(45deg)}
a.wk-note:hover .wk-arrow,a.wk-note:focus-visible .wk-arrow{width:96px}

/* stacked mode: fade up as each tile enters */
/* ============================================================
   POP FROM THE WALL (6 Oct 2026, at his instruction)
   The cards used to slide up and pile on each other, which left the one
   underneath half visible and the label unreadable. Now each card comes
   OUT of the wall: it starts small, flat and clipped to a slot, then
   pushes forward into its own space. No two cards share a position, so
   nothing is ever read through anything else.
   --p is the per-card scroll progress the pin already computes, so the
   pop is scrubbed by the same scroll rather than fired by a timer.
   ============================================================ */
/* The clip is gone (13 Oct). Coming out of a slot was my idea and it fails
   in practice: --p spends most of its life between 0 and 1, so the card spends
   most of its life as a card with its top 20% and its bottom 5% sliced off,
   and a half-cut label does not read as an animation, it reads as a rendering
   bug. That is the choppiness he reported. Opacity, scale and lift have no
   intermediate value that looks broken, which is the property that matters
   for anything scrubbed by a scroll the reader controls.
   Opacity now resolves by --p .45, so the card is solid well before it is
   near enough to read. */
.work.wk-live .wk-tile{
  --p:0;
  opacity:calc(var(--p) * 2.2);
  transform:rotate(var(--r,0deg)) scale(calc(.84 + var(--p) * .16)) translateY(calc((1 - var(--p)) * 34px));
  transition:none;will-change:transform,opacity}
/* the slot it comes out of: a rule on the wall, behind the card */
.work.wk-live .wk-tile::before{content:"";position:absolute;z-index:-1;left:6%;right:6%;top:46%;height:2px;
  background:rgba(var(--cream-rgb),.5);opacity:calc(1 - var(--p));transform:scaleX(calc(.3 + var(--p) * .7))}
.work.wk-live .wk-tile.is-visible{opacity:1}
@media (prefers-reduced-motion:reduce){
  .work.wk-live .wk-tile{opacity:1;transform:rotate(var(--r,0deg));clip-path:none}
  .work.wk-live .wk-tile::before{display:none}
}
@media (min-width:640px) and (max-width:759px){.wk-stage{grid-template-columns:repeat(2,minmax(0,1fr))}}

/* pinned mode */
@media (min-width:760px) and (prefers-reduced-motion:no-preference){
  .work{height:240vh;padding:0;overflow:clip} /* was 400vh: 41% of the page for three projects (22 Sep 2026) */
  .wk-shell{position:sticky;top:0;height:100vh;max-width:none;overflow:hidden}
  .wk-copy{position:absolute;z-index:15;top:clamp(86px,11vh,118px);
    --wk-left:max(var(--pad),calc((100vw - var(--max)) / 2 + var(--pad)));
    left:var(--wk-left);max-width:calc(31vw - var(--wk-left) - 2rem)}
  .wk-title{font-size:var(--t-h2);max-width:none}
  .wk-sub{font-size:var(--sm)}
  /* the crosshair is gone for good (13 Oct): it followed no grid line and
     carried nothing. It was set to display:none at the top of this file and
     then switched back on here, which is why it kept coming back. */
  .wk-ghost{display:block;position:absolute;z-index:0;inset:-8vh -7vw -12vh -9vw;width:116vw;height:122vh;
    overflow:visible;pointer-events:none;transform:translate3d(0,calc((var(--wp,0) - .45) * -5vh),0)}
  .wk-ghost-text{font-family:var(--fd);font-weight:700;letter-spacing:var(--fd-track);fill:rgba(var(--cream-rgb),.12);dominant-baseline:middle}
  .wk-ghost [data-ghost-stars] path{fill:rgba(var(--cream-rgb),.12)}
  .wk-stage{position:absolute;inset:0;z-index:6;display:block;margin:0;pointer-events:none}
  .work .wk-tile,.work.wk-live .wk-tile{position:absolute;left:var(--x);top:var(--y);width:var(--w);pointer-events:auto;
    transform:translate3d(0,calc(16vh - var(--p,1) * 16vh),0) scale(calc(.9 + var(--p,1) * .1)) rotate(var(--r));
    transition:opacity .42s var(--wk-ease)}
  .work.wk-live .wk-tile{opacity:0}
  .work.wk-live .wk-tile.is-visible{opacity:1;
    transform:translate3d(0,calc(16vh - var(--p,1) * 16vh),0) scale(calc(.9 + var(--p,1) * .1)) rotate(var(--r))}
  .wk-tile:hover,.wk-tile:focus-visible{z-index:12}
  .wk-note{position:absolute;z-index:7;bottom:4.5vh;margin:0}
  .wk-note--left{left:max(var(--pad),calc((100vw - var(--max)) / 2 + var(--pad)))}
  .wk-note--right{left:40%;max-width:320px}
}
@media (min-width:760px) and (max-width:1200px) and (prefers-reduced-motion:no-preference){
  .wk-label{flex-direction:column;align-items:flex-start;gap:3px}
  .wk-label span:last-child{text-align:left}
}
/* pinned, narrow: the collage becomes a deck. Same scroll maths over 300vh,
   each tile landing on the one before, offset enough that the pile reads. */
@media (max-width:759px) and (prefers-reduced-motion:no-preference){
  .work{height:200vh;padding:0;overflow:clip} /* was 300vh */
  .wk-shell{position:sticky;top:0;height:100vh;height:100svh;max-width:none;overflow:hidden}
  .wk-copy{position:absolute;z-index:15;top:clamp(72px,10vh,96px);left:var(--pad);right:var(--pad)}
  .wk-title{font-size:var(--t-h2);max-width:12ch}
  .wk-sub{font-size:var(--sm);margin-top:.7rem}
  .wk-ghost{display:block;position:absolute;z-index:0;top:30vh;left:-30vw;width:170vw;height:60vh;
    overflow:visible;pointer-events:none;transform:translate3d(0,calc((var(--wp,0) - .45) * -5vh),0)}
  .wk-ghost-text{font-family:var(--fd);font-weight:700;letter-spacing:var(--fd-track);fill:rgba(var(--cream-rgb),.12);dominant-baseline:middle}
  .wk-ghost [data-ghost-stars] path{fill:rgba(var(--cream-rgb),.12)}
  .wk-stage{position:absolute;inset:0;z-index:6;display:block;margin:0;pointer-events:none}
  .work .wk-tile,.work.wk-live .wk-tile,.work.wk-live .wk-tile.is-visible{position:absolute;left:var(--dx);
    top:calc(var(--deck-top,43vh) + var(--dy));width:var(--deck-w,min(80vw,440px));pointer-events:auto;
    transform:translate3d(0,calc(16vh - var(--p,1) * 16vh),0) scale(calc(.9 + var(--p,1) * .1)) rotate(var(--r));
    transition:opacity .42s var(--wk-ease)}
  .work.wk-live .wk-tile{opacity:0}
  .work.wk-live .wk-tile.is-visible{opacity:1}
  /* the labels stay: hiding them until hover was what made the wall read as
     decoration rather than as three pieces of work */
  .wk-label{opacity:1}
  
  .wk-tile:nth-child(1){--dx:6vw;--dy:0vh}
  .wk-tile:nth-child(2){--dx:13vw;--dy:3vh}
  .wk-tile:nth-child(3){--dx:8vw;--dy:6vh}
  .wk-note{position:absolute;z-index:7;left:var(--pad);right:calc(var(--pad) + 64px);margin:0} /* clear the vinyl button */
  a.wk-note{right:auto}
  .wk-note--left{top:var(--link-top,auto);bottom:auto}
  .wk-note--right{bottom:4vh;letter-spacing:.08em}
}
@media (min-width:760px) and (prefers-reduced-motion:reduce){
  .wk-stage{grid-template-columns:repeat(3,minmax(0,1fr))}
}
@media (prefers-reduced-motion:reduce){
  .work.wk-live .wk-tile{opacity:1;transform:rotate(var(--r,0deg));transition:none}
}

/* ---------- brain dump (dark) ---------- */
.dump{background:var(--deep);color:var(--cream);padding:var(--sec) 0}
.steps{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--s-7) var(--s-6);margin-top:var(--s-4)}
.step{border-left:2px solid var(--fluoro);padding:0 0 0 1rem}
.step .n{font-family:var(--fd);font-weight:700;font-size:var(--t-h2);line-height:1;opacity:.82;display:block;margin-bottom:.5rem;letter-spacing:var(--fd-track)}
.step h3{font-size:var(--t-body);margin-bottom:.5rem}
.step p{font-size:var(--sm);line-height:1.5;opacity:.85;margin:0}
.step:hover .n{opacity:1;color:var(--fluoro)}
@media(max-width:1000px){.steps{grid-template-columns:repeat(2,1fr);gap:1.8rem}}
@media(max-width:600px){.steps{grid-template-columns:1fr}}

/* ---------- about ---------- */
/* The jump from the zine into Me was invisible: the same ground, the same
   eyebrow, no change of register (6 Oct feedback). This is the turn: a full
   bleed rule with the sentence that hands over, set in the annotation face so
   it reads as an aside rather than a heading. It is the only place on the
   page where a line of type sits on the rule itself. */
.me-turn{position:relative;margin:var(--s-9) 0 var(--s-8);display:grid;place-items:center}
.me-turn::before{content:"";position:absolute;left:50%;transform:translateX(-50%);width:100vw;height:3px;background:var(--deep)}
.me-turn span{position:relative;background:var(--cream);padding:0 var(--s-5);font-family:var(--fu);
  font-size:var(--t-small);letter-spacing:.14em;text-transform:uppercase;color:var(--deep)}
.shead--me{margin-top:var(--s-6)}
@media (max-width:640px){.me-turn{margin:var(--s-8) 0 var(--s-6)}.me-turn span{padding:0 var(--s-3)}}
.about{padding:var(--sec) 0}
.abody{display:grid;grid-template-columns:minmax(0,1.618fr) minmax(0,1fr);gap:3rem;align-items:start}
.abody .prose p:first-child{font-size:var(--md);line-height:1.3;font-weight:500}
/* tighter paragraph rhythm, at his request 13 Oct: the long version read as
   five separated blocks rather than as one piece of writing. The beats in the
   home monologue come in with it, or the two pages disagree. */
.abody .prose p{max-width:32em;margin-block:0 var(--s-4)}
.prose p{margin-block:0 var(--s-4)}
.beat + .beat{margin-top:var(--s-4)}
.skills h3{font-family:var(--fu);font-size:var(--xs);letter-spacing:.08em;text-transform:uppercase;
  margin:0 0 .8rem;padding-bottom:.4rem;border-bottom:2px solid var(--deep)}
.skills .grp{margin-bottom:1.8rem}
.skills .cat{font-family:var(--fu);font-size:var(--t-small);letter-spacing:.08em;text-transform:uppercase;opacity:.82;margin:0 0 .4rem}
.skills ul{list-style:none;margin:0 0 .9rem;padding:0;display:flex;flex-wrap:wrap;gap:.35rem}
.skills li{font-size:var(--sm);border-bottom:1px solid rgba(var(--deep-rgb),.35);padding:1px 0}
.skills li::after{content:"·";margin-left:.4rem;opacity:.4;border:0}
.skills li:last-child::after{content:""}
.skills .work-k li{opacity:.82}
@media(max-width:900px){.abody{grid-template-columns:1fr;gap:2.4rem}}

/* ---------- faq bento ---------- */
.faq{padding:var(--sec) 0}
.bento{display:grid;grid-template-columns:repeat(6,minmax(0,1fr));gap:.9rem;margin-top:.5rem;align-items:start}
.tile-q{grid-column:span 2;border:3px solid var(--deep);background:var(--cream);padding:1rem 1.1rem;
  cursor:pointer;text-align:left;font:inherit;color:inherit;display:block;width:100%;
  transition:background 200ms var(--ease),color 200ms var(--ease)}
.tile-q:nth-child(1){grid-column:span 3}
.tile-q:nth-child(2){grid-column:span 3}
.tile-q:nth-child(4){grid-column:span 2}
.tile-q:nth-child(5){grid-column:span 4}
.tile-q:nth-child(8){grid-column:span 4}
.tile-q:nth-child(9){grid-column:span 2}
.tile-q .qn{font-family:var(--fu);font-size:var(--t-small);letter-spacing:.08em;opacity:.82;display:block;margin-bottom:.4rem}
.tile-q .qt{font-family:var(--fb);font-weight:700;font-size:var(--t-body);line-height:1.25;display:flex;justify-content:space-between;gap:1rem}
.tile-q .pm{font-family:var(--fd);font-weight:700;flex:none;transition:transform 220ms var(--ease);letter-spacing:var(--fd-track)}
.tile-q[aria-expanded="true"]{background:var(--deep);color:var(--cream)}
.tile-q[aria-expanded="true"] .pm{transform:rotate(45deg)}
.tile-q .ans{display:block;max-height:0;overflow:hidden;transition:max-height 350ms var(--ease),margin 350ms var(--ease);
  font-size:var(--sm);line-height:1.55;font-weight:400;margin:0}
.tile-q[aria-expanded="true"] .ans{max-height:420px;margin-top:.8rem}
.tile-q:hover{box-shadow:5px 5px 0 var(--fluoro)}
@media(max-width:900px){.bento{grid-template-columns:1fr}.tile-q,.tile-q:nth-child(n){grid-column:span 1}}

/* ---------- contact ----------
   The close. The brief asks for a deliberate reduction in intensity, so this
   returns to the ground colour the page opened on - the site starts and ends
   on cream, and the brain dump is left as the single dark moment rather than
   one of two. Was: dark ground, --xxl headline, a decorative star and three
   links competing at the same weight. One accent appears here, on the one
   action that matters. */
.contact{background:var(--cream);color:var(--deep);
  padding:clamp(3rem,7vw,5rem) 0 2rem;position:relative;border-top:3px solid var(--deep)}
.contact .no{font-family:var(--fu);font-size:var(--xs);letter-spacing:.08em;
  text-transform:uppercase;opacity:.82;display:block;margin-bottom:2.4rem}
.cta{font-family:var(--fd);font-weight:700;font-size:var(--t-h1);line-height:.98;
  margin:0 0 2.8rem;max-width:13em;letter-spacing:var(--fd-track)}
.cta em{font-style:normal;color:var(--fluoro)}

/* the action. Typographic, and the largest interactive thing on the page. */
.reach{display:inline-block;text-decoration:none;font-family:var(--fd);font-weight:700;
  font-size:var(--t-h2);line-height:1.05;letter-spacing:var(--fd-track);
  border-bottom:4px solid var(--fluoro);padding-bottom:.2rem;
  transition:border-color 220ms var(--ease)}
.reach:hover,.reach:focus-visible{border-bottom-color:var(--deep)}

/* everything else here is secondary and looks it */
/* The end of the page says what to do and nothing else (6 Oct). Four ways
   out, each marked by its icon, all weighted the same: no one of them gets a
   special treatment, which was his note about the long-version link too. */

/* footer: the Made by Shrey mark (see its own block) and one line of
   metadata. Metadata is #4A5578-weight deep, measured above AA. */
.foot{margin-top:3.4rem;padding-top:1.5rem;border-top:1px solid rgba(var(--deep-rgb),.28);
  display:flex;justify-content:space-between;align-items:flex-end;gap:1.2rem 2rem;flex-wrap:wrap}
.sign{margin:0;display:flex;align-items:baseline;gap:0;color:var(--deep);
  font-family:var(--fd);font-weight:900;line-height:1;font-size:var(--t-body);letter-spacing:var(--fd-track)}
.sign .sw{white-space:nowrap}
.sign-mark{height:clamp(26px,4vw,46px);width:auto;margin:0 .12rem 0 .45rem;transform:translateY(.22em)}
.sign-star{height:clamp(15px,1.9vw,22px);width:auto;margin:0 .1rem 0 0;transform:translateY(-.55em) rotate(-9deg);
  transition:transform 220ms var(--ease)}
.sign:hover .sign-star{transform:translateY(-.55em) rotate(21deg)}
@media(prefers-reduced-motion:reduce){.sign .sign-star,.sign:hover .sign-star{transition:none}}
@media(max-width:640px){.sign-mark{margin-left:.34rem}}
.foot-meta{margin:0;font-family:var(--fu);font-size:var(--xs);letter-spacing:.08em;
  text-transform:uppercase;color:rgba(var(--deep-rgb),.78)}

@media(max-width:640px){.foot{align-items:flex-start}}

/* ---------- vinyl ----------
   Form from the riyadesign reference (chosen by Shrey, 17 Sep 2026): a record
   parked bottom-right with its title above. Ours is a deep record, not black,
   with the hero photograph on the label, a tonearm that drops when it plays,
   and a fluoro ring that tracks the song's position. The ring is the one
   informative use of the accent here. 33 1/3 rpm is 1.8s a turn. */
/* It parks small and opens when you reach for it (8 Oct). At 112px the record
   sat over the bottom-right corner of every screen for the whole page: over a
   figure in What it moved, over the zine, over the last line of Me. A floating
   control may cover the corner it lives in; it may not cover the content. So
   it rests at 64px, which is a control, and grows to 112px, which is a record,
   on hover, focus or while playing. It is anchored bottom-right, so the target
   only ever grows under the pointer.
   It also stands down over the hero, which it used to do and stopped doing when
   the hero was rebuilt: html.at-hero is still set by home.js and nothing was
   reading it. The Listening mark in the hero is the way in, so the player has
   no job until the visitor has passed it. */
:focus-within,.playing){--vd:112px}
/* On a phone there is no corner to spare: a 64px control sits on the body copy
   of whatever section you are reading. So it is not there until it is asked
   for. The Listening mark in the hero links to #vinyl, which makes it the
   target, and once it is playing it stays. Summoned, not parked. */
@media (max-width:640px){
}
:focus-within{opacity:1;transform:none;pointer-events:auto}
/* 24px minimum on the target (WCAG 2.5.8). It was 23, which the caption only
   exposed once the player started opening on hover. */
@keyframes vspin{to{transform:rotate(360deg)}}
/* the label is the sleeve he supplied now, so it is not screened or greyed:
   it is artwork, and the halftone treatment was there to make a photograph
   read as a record label */
/* the embed does the playing; it is rendered, never shown */
/* .vinyl-host and its iframe rule are gone with the Spotify embed (13 Oct).
   Checked against the markup AND the scripts before deleting, which is the
   rule this repo learnt the hard way with .rise. */
@media (max-width:640px){
}
@media (prefers-reduced-motion:reduce){
}

/* star scroll indicator */
.scrollstar{position:fixed;right:1.1rem;top:50%;transform:translateY(-50%);width:22px;z-index:60}
.scrollstar svg{display:block;width:100%}
@media(max-width:900px){.scrollstar{display:none}}


/* ---------- star marks ---------- */
.smark{grid-column:1;grid-row:1;justify-self:start;align-self:center;width:24px;height:24px;object-fit:contain}

/* dealt-card brain dump */
.step{opacity:0;transform:translateY(20px) rotate(4deg);transition:opacity 520ms var(--ease),transform 620ms var(--ease)}
.step.dealt{opacity:1;transform:none}

/* faq + about stagger */
.tile-q{opacity:0;transform:translateY(14px);transition:opacity 480ms var(--ease),transform 480ms var(--ease),background 200ms var(--ease),color 200ms var(--ease),box-shadow 200ms var(--ease)}
.tile-q.in{opacity:1;transform:none}
/* ---------- Me: the monologue and the deck (8 Oct) ----------
   His paragraph is unchanged to the word. What changed is where it breaks:
   each sentence is its own beat with air after it, which is how a line reads
   when it is spoken rather than printed. The opening beat is set larger
   because it is the thesis, and the closing one is set apart because it is
   the turn. The word-by-word ink still runs over the top; site.js walks text
   nodes, so the beats do not interrupt it. */
.beat{display:block;max-width:30em}
.beat + .beat{margin-top:var(--s-5)}
.beat--open{font-size:var(--md);line-height:1.25;font-weight:500;max-width:22em}
.beat--close{margin-top:var(--s-6);font-style:italic}

/* The right column was empty on every screen wider than 900px, which is the
   white space he asked to use. A deck: one card at a time, thrown left or
   right, with the next two showing behind it so it reads as a stack rather
   than as a box. Every card is real. Nothing here is a placeholder, which is
   why there are three and not five.
   Markup order is a plain ordered list and stays one: a screen reader reads
   all three in sequence and never has to drive the deck. JS adds .is-deck,
   and without JS the list simply stacks down the column. */
.vouch{position:relative}
.vouch-k{font-size:var(--xs);letter-spacing:.08em;text-transform:uppercase;opacity:.82;margin:0 0 var(--s-5)}
.vouch-list{list-style:none;margin:0;padding:0;display:grid;gap:var(--s-4)}
.vouch-card{background:var(--cream);border:2px solid var(--deep);padding:var(--s-5) var(--s-5) var(--s-4)}
.vc-big{margin:0;font-family:var(--fd);font-weight:900;font-size:clamp(1.35rem,2.1vw,1.75rem);
  line-height:1.05;letter-spacing:var(--fd-track);color:var(--deep)}
.vc-sub{margin:var(--s-3) 0 0;font-family:var(--fb);font-size:var(--t-small);line-height:1.45;color:var(--deep)}
.vc-who{margin:var(--s-4) 0 0;font-size:var(--xs);letter-spacing:.08em;text-transform:uppercase;
  color:var(--accent-type)}

/* the deck, once the script is in */
.vouch-list.is-deck{display:block;position:relative;min-height:16.5rem;touch-action:pan-y}
.is-deck .vouch-card{position:absolute;inset:0 0 auto;height:auto;min-height:15rem;
  transform-origin:50% 100%;will-change:transform;
  transition:transform var(--d-2) var(--e-out),opacity var(--d-2) ease}
.is-deck .vouch-card[data-at="0"]{z-index:3;transform:rotate(-1deg)}
.is-deck .vouch-card[data-at="1"]{z-index:2;transform:translateY(10px) scale(.965) rotate(1.4deg)}
.is-deck .vouch-card[data-at="2"]{z-index:1;transform:translateY(20px) scale(.93) rotate(-.6deg)}
.is-deck .vouch-card[data-at="0"]{cursor:grab}
.is-deck .vouch-card[data-at="0"].is-held{cursor:grabbing;transition:none}
.is-deck .vouch-card.is-gone{opacity:0}
.vouch-nav{display:flex;align-items:center;gap:var(--s-3);margin-top:var(--s-5)}
.vouch-nav button{min-width:44px;min-height:44px;display:inline-flex;align-items:center;justify-content:center;
  background:none;border:2px solid var(--deep);color:var(--deep);cursor:pointer;
  font-family:var(--fu);font-size:var(--t-small);transition:background var(--d-1) ease,color var(--d-1) ease}
.vouch-nav button:is(:hover,:focus-visible){background:var(--deep);color:var(--cream)}
.vouch-count{font-family:var(--fu);font-size:var(--xs);letter-spacing:.08em;text-transform:uppercase;opacity:.82}
@media (prefers-reduced-motion:reduce){.is-deck .vouch-card{transition:none}}
@media (max-width:900px){
  .vouch{margin-top:var(--s-7)}
  .vouch-list.is-deck{min-height:15rem}
}

.prose p{opacity:0;transform:translateY(12px);transition:opacity 520ms var(--ease),transform 520ms var(--ease)}
.prose p.in{opacity:1;transform:none}
.cta span.ln{display:block;opacity:0;transform:translateY(18px);transition:opacity 560ms var(--ease),transform 560ms var(--ease)}
.cta span.ln.in{opacity:1;transform:none}

/* reveals */
.rv{opacity:0;transform:translateY(14px);transition:opacity 560ms var(--ease),transform 560ms var(--ease)}
.rv.in{opacity:1;transform:none}.anim [data-t],.anim .bg{opacity:0}
.snap{animation:snap 180ms var(--ease) forwards}
@keyframes snap{from{opacity:0;transform:scale(1.06)}to{opacity:1;transform:scale(1)}}
/* .rise is applied by home.js at runtime, never written in the markup, which
   is why the dead-code sweep of 8 Oct removed it after checking only the HTML
   and left the hero claim and both calls to action invisible for four days:
   .anim [data-t] holds them at opacity 0 and this is what brings them back.
   Any class a script adds has to be grepped in assets/*.js too. */
.rise{animation:rise 560ms var(--ease) forwards}
@keyframes rise{from{opacity:0;transform:translateY(12px)}to{opacity:1;transform:translateY(0)}}
.fade{animation:fade 640ms var(--ease) forwards}
@keyframes fade{from{opacity:0}to{opacity:1}}

@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{animation-duration:1ms!important;animation-iteration-count:1!important;transition-duration:1ms!important}.anim [data-t],.anim .bg{opacity:1}
  .rv{opacity:1;transform:none}
  
}

/* ============================================================
   MULTI-PAGE SHELL — added when the site moved from one
   scrolling page to routed pages. Everything above is the
   original system and is unchanged.
   ============================================================ */

/* page header — the sub-page equivalent of .shead, with air
   above it so it clears the fixed nav */
.phead{padding:calc(var(--sec) + 3.2rem) 0 0}
.phead .wrap{display:block}
.phead .no{font-family:var(--fu);font-size:var(--xs);letter-spacing:.08em;opacity:.82;display:block;margin-bottom:.9rem}
.phead h1{font-size:var(--xxl);max-width:13em;margin:0 0 1.1rem}
.phead .stand{font-size:var(--md);line-height:1.3;font-weight:500;max-width:24em;margin:0}
.phead .rule{margin-top:2.4rem;border-top:3px solid var(--deep)}
.phead .star{width:34px;height:34px;object-fit:contain;display:block;margin-bottom:1.4rem}

/* back link — same grammar as the case studies */

/* page foot — where next, then the signature line */
.pfoot{border-top:1px solid rgba(var(--deep-rgb),.3);margin-top:var(--sec);padding:1.4rem 0 3.5rem;
  display:flex;justify-content:space-between;gap:1rem;flex-wrap:wrap;align-items:baseline}
.pfoot a{text-decoration:none;font-family:var(--fd);font-weight:700;font-size:var(--lg);line-height:1;letter-spacing:var(--fd-track)}
.pfoot a .arw{color:var(--fluoro)}
.pfoot .sig{font-family:var(--fu);font-size:var(--t-small);letter-spacing:.08em;text-transform:uppercase;opacity:.82}

/* home hub — section teaser that points at a full page */
/* The same call to action as every other one on the site (8 Oct, his note:
   no special treatment for just one). It carried a permanent red underline
   while the four at the end of the page carried none until hovered, so the
   one link that leads to a second page shouted and the ones that lead off the
   site whispered. Now it matches .ways a exactly: transparent rule, red on
   hover or focus, 44px of height to hit. */
.more{display:inline-flex;align-items:center;gap:var(--s-2);min-height:44px;margin-top:2.4rem;
  font-family:var(--fu);font-size:var(--t-small);letter-spacing:.06em;text-transform:uppercase;
  color:var(--deep);text-decoration:none;border-bottom:2px solid transparent;
  transition:border-color var(--d-1) ease}
.more:is(:hover,:focus-visible){border-bottom-color:var(--fluoro)}
.more .arw{transition:transform 220ms var(--ease)}
.more:hover .arw{transform:translateX(4px)}

.lede{font-size:var(--md);line-height:1.3;font-weight:500;max-width:20em;margin:0 0 1rem}

/* ideas — index list and the scrolling piece */

/* a single idea, read top to bottom */

/* progress rail for a long read */
.rail{position:fixed;left:0;top:0;height:3px;background:var(--fluoro);width:0;z-index:65}

/* ============================================================
   ROUTED HUBS — /work and /ideas indexes, and the shared
   filter grammar. Namespaced so nothing here can collide with
   the home-page .card / .face / .tag rules above.
   ============================================================ */

/* filter — text toggles, ruled not boxed */
.filter{display:flex;gap:1.4rem;flex-wrap:wrap;align-items:baseline;padding:1.6rem 0 0;
  border-bottom:1px solid rgba(var(--deep-rgb),.25)}
.filter .lab{font-family:var(--fu);font-size:var(--xs);letter-spacing:.08em;text-transform:uppercase;opacity:.82}
.fbtn{font-family:var(--fu);font-size:var(--xs);letter-spacing:.08em;text-transform:uppercase;background:none;
  border:0;color:inherit;cursor:pointer;padding:0 0 .55rem;border-bottom:2px solid transparent;opacity:.82;
  transition:opacity 200ms var(--ease),border-color 200ms var(--ease)}
.fbtn:hover{opacity:1}
.fbtn[aria-pressed="true"]{opacity:1;border-bottom-color:var(--fluoro)}
.fbtn .c{opacity:.5;margin-left:.35em}
.fempty{padding:2.5rem 0;font-family:var(--fu);font-size:var(--xs);letter-spacing:.08em;
  text-transform:uppercase;opacity:.82}

/* work index — an editorial contents page, one row per project */
.windex{border-top:3px solid var(--deep);margin-top:.5rem}
.wrow{display:grid;grid-template-columns:4.5rem minmax(0,1fr) 11rem;gap:1.5rem;align-items:start;
  padding:1.7rem 0;border-bottom:1px solid rgba(var(--deep-rgb),.25);text-decoration:none;position:relative;
  transition:padding-left 260ms var(--ease)}
a.wrow:hover,a.wrow:focus-visible{padding-left:.7rem}
a.wrow::before{content:"";position:absolute;left:0;top:0;bottom:-1px;width:3px;background:var(--fluoro);
  transform:scaleY(0);transform-origin:top;transition:transform 260ms var(--ease)}
a.wrow:hover::before,a.wrow:focus-visible::before{transform:scaleY(1)}
.wrow .n{font-family:var(--fu);font-size:var(--xs);letter-spacing:.08em;opacity:.82;padding-top:.45rem}
.wrow h2{font-family:var(--fd);font-weight:700;font-size:var(--t-h2);line-height:1;
  margin:0 0 .5rem;letter-spacing:var(--fd-track)}
.wrow .teaser{margin:0 0 .7rem;max-width:34em;opacity:.82;font-size:var(--t-small);line-height:1.45}
.wrow .tags{display:flex;gap:.4rem;flex-wrap:wrap}
.wrow .tags span{font-family:var(--fu);font-size:var(--t-small);letter-spacing:.06em;text-transform:uppercase;
  border:1px solid var(--deep);padding:2px 6px}
/* audience reads first, the way the market sorts case studies */
.tags .aud{background:var(--deep);color:var(--cream);border-color:var(--deep);font-weight:600}
.wrow .tags span.on{background:var(--deep);color:var(--cream)}
.wrow .tags span.dev{border-style:dashed;opacity:.82}
.wrow .aside{display:grid;gap:.35rem;justify-items:end;text-align:right;padding-top:.4rem}
.wrow .aside .t{font-family:var(--fu);font-size:var(--xs);letter-spacing:.08em;text-transform:uppercase;opacity:.82}
.wrow .go{font-family:var(--fd);font-weight:700;font-size:var(--t-body);letter-spacing:var(--fd-track)}
a.wrow .go::after{content:" \2192";transition:padding-left 260ms var(--ease)}
a.wrow:hover .go::after{padding-left:.25em}
.wrow.soon .go{font-family:var(--fu);font-size:var(--xs);letter-spacing:.08em;text-transform:uppercase;font-weight:400}
.wrow[hidden]{display:none}
.wrow.rv:not(.in){opacity:0}
.wrow.soon.rv.in{opacity:.82}
@media(max-width:760px){
  .wrow{grid-template-columns:3rem minmax(0,1fr);gap:.9rem}
  .wrow .aside{grid-column:2;justify-items:start;text-align:left;padding-top:.6rem;
    grid-auto-flow:column;justify-content:start;gap:1.2rem;align-items:baseline}
}

/* contact page */
.cblock{display:grid;grid-template-columns:minmax(0,1.618fr) minmax(0,1fr);gap:3rem;align-items:start;padding:0 0 var(--sec)}
@media(max-width:900px){.cblock{grid-template-columns:1fr;gap:2rem}}
.creach{display:grid;gap:0;border-top:2px solid var(--deep)}
.creach a{display:flex;justify-content:space-between;align-items:baseline;gap:1rem;padding:1rem 0;
  border-bottom:1px solid rgba(var(--deep-rgb),.3);text-decoration:none;transition:padding 240ms var(--ease)}
.creach a:hover,.creach a:focus-visible{padding-left:.7rem}
.creach .k{font-family:var(--fu);font-size:var(--xs);letter-spacing:.08em;text-transform:uppercase;opacity:.82}
.creach .v{font-family:var(--fd);font-weight:700;font-size:var(--t-h3);line-height:1;letter-spacing:var(--fd-track)}

/* project / idea cross-navigation on a light page */


/* ============================================================
   WORK PLATES — the visual slot for each project.
   Today they are typographic compositions; the markup is a slot,
   so a real artefact image replaces .pw without touching layout
   or the reveal mechanism. Each plate differs in COMPOSITION,
   not merely ground colour — per the section brief.
   ============================================================ */
.plate{position:relative;overflow:hidden;aspect-ratio:16/10;background:var(--deep);
  border:2px solid var(--deep);display:grid;isolation:isolate}
.plate img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:center;z-index:1}
.plate .pw{font-family:var(--fd);font-weight:700;text-transform:uppercase;
  color:var(--cream);line-height:.8;letter-spacing:var(--fd-track);margin:0;z-index:1;
  font-size:var(--t-h2)}
.plate .pm{position:absolute;z-index:2;font-family:var(--fu);font-size:var(--t-small);
  letter-spacing:.08em;text-transform:uppercase;opacity:.82}
/* The halftone belonged to the typographic stand-ins. Real artwork is the
   evidence, so nothing is screened over it: the dots now only dress a plate
   that has no image in it (1 Oct 2025, when the posters arrived). */
.plate:not(:has(img))::after{content:"";position:absolute;inset:0;z-index:2;opacity:.09;pointer-events:none;
  background-image:radial-gradient(circle at 1px 1px,#000 1px,transparent 1.15px);background-size:5px 5px}

/* 01 — the V is the hanger rail. Centred, oversized initial. */
.p-vastr{background:var(--deep)}
.p-vastr .pw{align-self:center;justify-self:center;text-align:center}
.p-vastr .pw b{font-size:2.1em;line-height:.7;display:block;font-weight:700}
.p-vastr .pm{left:.6rem;bottom:.5rem;color:var(--cream)}

/* 02 — the campaign is about leaving the feed, so the words walk off it. */
.p-noise{background:var(--fluoro)}
.p-noise .pw{align-self:center;padding-left:.7rem;text-align:left;color:var(--cream)}
.p-noise .pw span{display:block}
.p-noise .pw span:nth-child(2){padding-left:1.2em}
.p-noise .pw span:nth-child(3){padding-left:2.4em;opacity:.45}
.p-noise .pm{right:.6rem;top:.5rem;color:var(--cream)}

/* 03 — a voice print: the same word, three times, decaying. */
.p-voice{background:var(--cream)}
.p-voice .pw{align-self:center;justify-self:center;text-align:center;color:var(--deep);position:relative}
.p-voice .pw span{display:block}
.p-voice .pw span:nth-child(2){opacity:.32;transform:translateX(.18em)}
.p-voice .pw span:nth-child(3){opacity:.14;transform:translateX(.36em)}
.p-voice .pm{left:.6rem;bottom:.5rem;color:var(--deep)}

/* 04 — a shipping plate. Small mark, big rule, industrial. */
.p-vrl{background:var(--deep);grid-template-rows:1fr auto}
.p-vrl .pw{align-self:end;padding:0 .7rem;font-size:var(--t-h1)}
.p-vrl .pm{left:.7rem;top:.5rem;color:var(--cream)}

/* 05 — one word, broken where the name breaks. */
.p-abs{background:var(--fluoro)}
.p-abs .pw{align-self:center;justify-self:center;text-align:center;color:var(--cream);
  font-size:var(--t-h3)}
.p-abs .pm{right:.6rem;bottom:.5rem;color:var(--cream)}

/* 06/07 — not built yet. The plate says so rather than pretending. */
.p-soon{background:transparent;border:2px dashed rgba(var(--deep-rgb),.4);place-items:center}
.p-soon .pw{color:var(--deep);opacity:.82;font-size:var(--t-body);
  letter-spacing:.06em;font-family:var(--fu);font-weight:400;text-align:center;padding:0 .8rem}
.p-soon::after{display:none}

/* row gains a plate column */
.wrow{grid-template-columns:3.2rem 15rem minmax(0,1fr) 8.5rem}
@media(max-width:1040px){.wrow{grid-template-columns:3.2rem 11rem minmax(0,1fr)}
  .wrow .aside{grid-column:3;justify-items:start;text-align:left;padding-top:.6rem;
    grid-auto-flow:column;justify-content:start;gap:1.2rem;align-items:baseline}}
@media(max-width:760px){.wrow{grid-template-columns:3rem minmax(0,1fr)}
  .wrow > :not(.n){grid-column:2} /* everything but the number in the wide column */
  .wrow .plate{grid-column:2;margin-bottom:.9rem}
  .wrow .aside{grid-column:2}}

/* The wipe. Start state applies only when JS will drive it, and the
   transition runs on the compositor so it does not need rAF. */
.js-wipe .plate{clip-path:inset(0 100% 0 0);
  transition:clip-path 780ms cubic-bezier(.16,1,.3,1)}
.js-wipe .plate .pw{transform:translateX(10%);
  transition:transform 900ms cubic-bezier(.16,1,.3,1)}
.js-wipe .plate.wiped{clip-path:inset(0 0% 0 0)}
.js-wipe .plate.wiped .pw{transform:translateX(0)}
@media (prefers-reduced-motion:reduce){
  .js-wipe .plate{clip-path:none;transition:none}
  .js-wipe .plate .pw{transform:none;transition:none}
}


/* ---------- dark mode, for the cream / deep / fluoro system ----------
   Driven by <html data-theme> (set by assets/theme.js when the visitor picks)
   and otherwise by prefers-color-scheme, the same contract the Proof section
   and the case pages already use. Skin-quiet pages carry their own dark rules
   and are excluded here.

   Light sections flip: cream becomes the ink ground, deep becomes the type.
   Sections that are deep by design (Selected work, Brain dump, the record)
   keep their light-mode values, so dark mode still has two grounds and a
   rhythm instead of one flat night. Fluoro does not change. Ink and the
   type tone are the v7 values, so Proof and these sections agree. */
/* ---------- phones: headers stack, nothing outgrows the screen ----------
   Section labels grew from 10px to the 14px floor, so the side-label column
   squeezed long headlines past the edge. Under 640px the label sits above
   the headline instead. The email steps down one size and may break at any
   character rather than push the page sideways. */
@media (max-width:640px){
  .shead{grid-template-columns:minmax(0,1fr);row-gap:var(--s-3)}
  .shead .smark,.shead .no,.shead h2,.shead .sub{grid-column:1;grid-row:auto}
  .shead .no{white-space:normal}
  .shead h2{min-width:0}
  .reach{font-size:var(--t-h3);overflow-wrap:anywhere}
}


/* ---------- scale pass: fixes found by looking, 18 Sep ---------- */
/* the record: the song leads, the artist line follows, sentence case at 14 */
/* work tiles: names in sentence case so 14px labels fit the tile, not the page */
.wk-label{text-transform:none;letter-spacing:.02em;
  background:var(--cream);color:var(--deep);padding:.5rem .8rem .55rem;
  border:2px solid var(--deep);transform:rotate(-1deg);align-self:flex-start;max-width:100%}
.wk-label span:first-child{font-family:var(--fd);font-weight:900;font-size:var(--t-h3);
  line-height:1.05;letter-spacing:var(--fd-track);color:var(--deep)}
.wk-label span:last-child{font-family:var(--fu);font-size:var(--t-small);
  letter-spacing:.04em;color:var(--accent-type);text-align:left}
.wk-tile:is(:hover,:focus-visible) .wk-label{background:var(--yellow)}
.wk-tile:is(:hover,:focus-visible) .wk-label span:first-child{color:#0D1633}
.wk-note{letter-spacing:.04em}
.work .wk-tile[href*="vrl"]{--y:44vh}
@media (min-width:760px){.wk-note--right{max-width:26rem}}
/* proof: the lede is a sentence to read, so body size */
/* brain dump: steps are body copy (18), so five columns become three then two */
.step p{font-size:var(--t-body);line-height:var(--lh-body)}

/* contrast at 14px: small labels were muted with low opacity, which was
   tolerable at 10px as texture but fails AA now they are reading text.
   Metadata stays quieter than body, at .8, which clears 4.5:1 on cream and
   deep; on the fluoro ground it takes the ink tone, the only one that passes
   there. Small accent text on deep uses the lifted fluoro. */.contact .no,.shead .no{opacity:.82}
.wk-note{color:rgba(var(--cream-rgb),.82)}

/* ---------- work covers: static, with a state change on hover ----------
   Decided 18 Sep 2026: no screen recordings. The cover stays; a bar rises
   into it naming the action, and the label below lifts to full strength.
   Keyboard focus gets the same. */
.wk-open{position:absolute;left:0;right:0;bottom:0;z-index:1;display:flex;justify-content:space-between;
  align-items:center;padding:var(--s-3) var(--s-4);background:var(--deep);color:var(--cream);
  font-family:var(--fu);font-size:var(--t-small);letter-spacing:.04em;
  transition:color var(--d-1) ease}
.wk-open span{transition:transform var(--d-2) var(--e-spring)}
/* the cover lifts to uncover the bar beneath it, so nothing on the cover is hidden */
.wk-poster{transition:opacity .25s var(--wk-ease),transform var(--d-2) var(--e-out)}
.wk-tile:is(:hover,:focus-visible) .wk-poster{transform:translateY(-2.9rem)}
.wk-tile:is(:hover,:focus-visible) .wk-open span{transform:translateX(4px)}
.wk-label span{transition:color var(--d-1) ease}
.wk-tile:is(:hover,:focus-visible) .wk-label span:first-child{color:var(--accent-type)}

@media (prefers-reduced-motion:reduce){.wk-open,.wk-open span,.wk-poster{transition:none}}
/* labels: name and status each stay on one line; status drops below if short of room */
.wk-label{flex-wrap:wrap;row-gap:2px}
.wk-label span{white-space:nowrap}

/* ---------- about: direction and beliefs ----------
   Direction is what he wants next, stated plainly for a recruiter routing
   him to a req. Beliefs are his lines, verbatim, numbered because the last
   one undercuts the other four and the order is the joke. */
.skills .grp-say{font-size:var(--t-small);line-height:1.5;margin:0 0 var(--s-4);max-width:28em;opacity:.85}
.stance{padding:var(--sec) 0 0}
.stance-body{display:grid;gap:var(--s-5);max-width:40em;margin:var(--s-6) 0 0}
.stance-body p{margin:0;font-size:var(--t-body);line-height:var(--lh-body)}
.stance-body .stance-lede{font-family:var(--fd);font-weight:500;font-size:var(--t-h3);line-height:1.25;letter-spacing:var(--fd-track)}


/* ============================================================
   IDEAS: the magazine (built 18 Sep 2026)
   The hero is the base kit: cream ground, deep ink, the cut-out SHREY
   tile, a two-ink photograph, the riso star. Each page is that kit in a
   different setting, the way each home section is. The accent is spent
   once, on the Process page. Pages are 3:4, a spread is 3:2.
   Wide screens: magazine.js binds the pages into leaves on a spine.
   Phones: a swipe track, one page at a time. No JS: pages stack.
   ============================================================ */
.mag{position:relative;margin:var(--s-6) auto 0}
.mag-book{position:relative;display:grid;gap:var(--s-6)}

/* ---------- a page ---------- */
.mag-page{position:relative;container-type:inline-size;overflow:hidden;background:var(--cream);color:var(--deep);
  aspect-ratio:3/4;padding:var(--s-7) var(--s-7) var(--s-8);display:flex;flex-direction:column;border:1px solid var(--deep)}
.pg-kick{font-size:var(--t-small);letter-spacing:.08em;text-transform:uppercase;opacity:.82;margin:0 0 var(--s-3)}
.pg-title{font-family:var(--fd);font-weight:700;font-size:clamp(1.75rem,8.4cqw,var(--t-h2));line-height:1.02;
  letter-spacing:var(--fd-track);margin:0 0 var(--s-5);max-width:14ch}
.pg-body{font-size:var(--t-body);line-height:var(--lh-body);max-width:24em;margin:0 0 var(--s-5)}
.pg-folio{position:absolute;bottom:var(--s-5);right:var(--s-7);font-size:var(--t-small);opacity:.82}
.pg-link{margin-top:auto;align-self:flex-start;font-family:var(--fu);font-size:var(--t-small);letter-spacing:.04em;
  color:inherit;text-decoration:none;border-bottom:2px solid currentColor;padding:var(--s-2) 0 2px}
.pg-link span{display:inline-block;transition:transform var(--d-2) var(--e-spring)}
.pg-link:hover span,.pg-link:focus-visible span{transform:translateX(4px)}

/* 1. cover: masthead over the photograph, the hero's overlap move */
/* The cover is Shrey's own artwork now (delivered 1 Oct), so the page is a
   frame for it and nothing is composed on top. It fills the leaf and is
   cropped from the top if the leaf is squarer than the art. */
.cv-art{display:block;width:100%;height:100%;object-fit:cover;object-position:top center}
.pg-cover{padding:0;background:var(--cream)}
/* the orange duotone predates the retro palette: set it back to one ink and
   print it red, the way a two-colour newsstand cover would */
.pg-cover{isolation:isolate}
/* The red multiply wash over the cover is gone (13 Oct). It was left from
   the composed cover his artwork replaced, and it was repainting the blue
   half of his own cover red. Never screen delivered artwork. */

/* 2. contents: the inversion */
.pg-contents{background:var(--deep);color:var(--cream);border-color:var(--deep)}
.toc{list-style:none;margin:0;padding:0;border-top:1px solid rgba(var(--cream-rgb),.4)}
.toc a{display:grid;grid-template-columns:2.6rem minmax(0,1fr);grid-template-areas:"n t" ". k";column-gap:var(--s-3);
  padding:var(--s-3) 0;border-bottom:1px solid rgba(var(--cream-rgb),.4);color:inherit;text-decoration:none;
  transition:padding var(--d-2) var(--e-out),background var(--d-1) ease}
.toc-n{grid-area:n;font-size:var(--t-small);opacity:.82;padding-top:.3em}
.toc-t{grid-area:t;font-family:var(--fd);font-weight:700;font-size:clamp(1rem,4.6cqw,1.375rem);line-height:1.15;letter-spacing:var(--fd-track)}
.toc-k{grid-area:k;font-size:var(--t-small);letter-spacing:.06em;text-transform:uppercase;opacity:.82}
.toc a:hover,.toc a:focus-visible{padding-left:var(--s-3);background:rgba(var(--cream-rgb),.08)}

/* 3. manifesto */

/* 4. projects */
.briefs{list-style:none;margin:0;padding:0;border-top:1px solid var(--deep)}
.briefs li{border-bottom:1px solid rgba(var(--deep-rgb),.3)}
.briefs a,.briefs .bf-soon{display:flex;justify-content:space-between;align-items:baseline;gap:var(--s-3);flex-wrap:wrap;
  padding:var(--s-2) 0;color:inherit;text-decoration:none}
.briefs .bf-soon{padding:var(--s-2) 0}
.bf-t{font-family:var(--fd);font-weight:700;font-size:clamp(.95rem,4cqw,1.25rem);line-height:1.15;letter-spacing:var(--fd-track)}
.bf-m{font-size:var(--t-small);opacity:.82;white-space:nowrap}
.briefs a{transition:color var(--d-1) ease,padding var(--d-2) var(--e-out)}
.briefs a:hover,.briefs a:focus-visible{color:var(--accent-type);padding-left:var(--s-2)}
.briefs .bf-soon .bf-t{opacity:.82}

/* 5. process: the accent plane, ink type (4.8:1; cream would be 3.0:1) */
.pg-process{background:var(--fluoro);color:#0D1633;border-color:#0D1633}
.pg-process .pg-kick,.pg-process .pg-folio{opacity:1}

/* 7. letters: deep, the locked CTA at display size */
.pg-letters{background:var(--deep);color:var(--cream);border-color:var(--deep)}
.lt-cta{font-family:var(--fd);font-weight:700;font-size:clamp(1.8rem,10cqw,3.4rem);line-height:.98;letter-spacing:var(--fd-track);margin:0 0 var(--s-6)}
.lt-mail{font-family:var(--fd);font-weight:700;font-size:clamp(1rem,4.8cqw,1.5rem);color:inherit;
  text-decoration:none;border-bottom:3px solid var(--fluoro);align-self:flex-start;overflow-wrap:anywhere;letter-spacing:var(--fd-track)}
.pg-letters .pg-link{margin-top:auto}

/* 8. back cover */
.pg-back{background:var(--deep);color:var(--cream);align-items:center;justify-content:center;gap:var(--s-5);border-color:var(--deep)}
.bk-star{width:34cqw;height:auto;transform:rotate(-8deg)}
.bk-sign{margin:0}.bk-sign img{width:44cqw;height:auto;display:block}
.bk-meta{font-size:var(--t-small);letter-spacing:.08em;text-transform:uppercase;opacity:.82;margin:0}

/* ---------- controls ---------- */
.mag-bar{display:none;justify-content:space-between;align-items:center;gap:var(--s-4);margin:var(--s-5) auto 0}
.mag.is-bound .mag-bar,.mag.is-track .mag-bar{display:flex}
.mag-btn{white-space:nowrap;font-family:var(--fu);font-size:var(--t-small);letter-spacing:.04em;color:var(--deep);background:none;
  border:1px solid var(--deep);padding:var(--s-3) var(--s-4);min-height:44px;cursor:pointer;
  transition:background var(--d-1) ease,color var(--d-1) ease,opacity var(--d-1) ease}
.mag-btn:hover:not(:disabled),.mag-btn:focus-visible{background:var(--deep);color:var(--cream)}
.mag-btn:disabled{color:color-mix(in srgb,var(--deep) 88%,var(--cream));border-style:dashed;
  border-color:color-mix(in srgb,var(--deep) 45%,var(--cream));cursor:default}
.mag-count{margin:0;font-size:var(--t-small);letter-spacing:.06em;text-transform:uppercase;opacity:.82;text-align:center}

/* ---------- bound: leaves on a spine ---------- */
.mag.is-bound{width:min(100%,1120px,calc((100svh - 230px) * 1.5));perspective:2600px}
.mag.is-bound .mag-book{display:block;aspect-ratio:3/2;gap:0;transform:translateX(var(--shift,0));
  transition:transform var(--d-3) var(--e-out)}
.mag-leaf{position:absolute;top:0;left:50%;width:50%;height:100%;transform-style:preserve-3d;transform-origin:0 50%;
  transition:transform 850ms cubic-bezier(.45,.05,.25,1);cursor:pointer}
.mag-leaf.is-flipped{transform:rotateY(-180deg)}
.mag-leaf > .mag-page{position:absolute;inset:0;aspect-ratio:auto;backface-visibility:hidden;-webkit-backface-visibility:hidden}
.mag-leaf > .mag-page.is-back{transform:rotateY(180deg)}
.mag-leaf a,.mag-leaf button{cursor:pointer}
.mag.is-bound .mag-bar{width:min(100%,640px)}

/* ---------- phones: a swipe track ---------- */
.mag.is-track .mag-book{display:flex;gap:var(--s-4);overflow-x:auto;scroll-snap-type:x mandatory;
  overscroll-behavior-x:contain;scrollbar-width:none;padding-bottom:var(--s-1)}
.mag.is-track .mag-book::-webkit-scrollbar{display:none}
.mag.is-track .mag-page{flex:0 0 100%;scroll-snap-align:start;aspect-ratio:auto;min-height:min(132vw,620px)}
.mag.is-track .pg-cover{min-height:min(133vw,620px)}

@media (prefers-reduced-motion:reduce){
  .mag-leaf,.mag.is-bound .mag-book,.toc a,.briefs a,.pg-link span{transition:none}
}



@media (max-width:899px){.mag-page{padding:var(--s-6) var(--s-5) var(--s-8)}.pg-folio{right:var(--s-5)}}

/* ============================================================
   HOME IDEAS: the desk (18 Sep 2026)
   The real issue, set in the home page itself, lying on the same
   cream as the hero with the hero's cut-outs scattered round it. Props
   sit at their own parallax depth (--py from home.js) and never take
   pointer events. Sticker slots stay hidden until tool icons arrive.
   ============================================================ */
.desk{padding:var(--sec) 0 0}
.desk-surface{position:relative;max-width:1400px;margin:var(--s-5) auto 0;padding:var(--s-7) var(--pad) var(--sec)}
.desk-props{position:absolute;inset:0;pointer-events:none;z-index:1}
.prop{position:absolute;display:block;height:auto;
  transform:translate3d(0,var(--py,0px),0) rotate(var(--rot,0deg));will-change:transform}
.sticker:empty{display:none}
.sticker{width:clamp(40px,4vw,56px)}
.sticker img{display:block;width:100%;height:auto}
.s1{left:14%;top:44%;--rot:-12deg}.s2{right:15%;top:38%;--rot:9deg}.s3{left:22%;bottom:4%;--rot:6deg}
.desk-mag{position:relative;z-index:2}
.desk-mag .mag{margin-top:0}
@media (min-width:900px){.desk-mag .mag.is-bound{width:min(78%,1000px,calc((100svh - 230px) * 1.5))}}
/* before the issue arrives, and if it never does: the cover as a link */
@media (max-width:899px){
  .desk-surface{padding:var(--s-5) var(--pad) var(--sec)}
  .sticker{display:none}
}
@media (prefers-reduced-motion:reduce){.prop{transform:rotate(var(--rot,0deg))}}
.mag-count{white-space:nowrap}





/* ---------- the magazine, as a magazine (21 Sep 2026) ----------
   Newsstand furniture, all of it doing a job a real cover does: the volume
   line and cover price say "periodical", the starburst says "new", the
   barcode says "printed". Inside, a running head and a shade at the spine.
   Clash, marked: the veto list bans badges. The burst is a cover convention,
   not a UI chip; picked on relevance to a magazine, and it appears once. */
/* running head on every inside page */
.mag-page:not(.pg-cover):not(.pg-back)::before{content:"Ideas \00B7  Issue 01";position:absolute;top:var(--s-5);right:var(--s-7);
  font-family:var(--fu);font-size:var(--t-small);letter-spacing:.06em;text-transform:uppercase;opacity:.7;pointer-events:none}
/* the spine: each page darkens a touch toward the binding */
.mag.is-bound .mag-leaf > .mag-page:not(.is-back){box-shadow:inset 22px 0 26px -20px rgba(13,22,51,.35)}
.mag.is-bound .mag-leaf > .mag-page.is-back{box-shadow:inset -22px 0 26px -20px rgba(13,22,51,.35)}
@media (max-width:899px){.mag-page:not(.pg-cover):not(.pg-back)::before{right:var(--s-5)}}

/* ============================================================
   HOME: EVERY SECTION ITS OWN PERSONALITY (21 Sep 2026)
   Shrey: "the homepage sections should differ by personality". Each one
   gets a different device, so scrolling reads as turning to a new page
   rather than more of the same:
     hero      assembly: the cut-outs snap on, the print sits still
     quotes    a hand-drawn tape between the hero and the page, scroll-driven
     bands     scroll velocity drives the crossing tapes
     proof     a blue comic panel on Ben-Day dots, figures roll up in yellow
     work      pinned collage, scrubbed by scroll
     ideas     the magazine: pages turn on a spine
     me        the paragraph inks in word by word as you read it
     contact   the ask, with a highlighter pulled under "always"
   ============================================================ */

/* ---------- proof: the comic panel ----------
   Yellow, not blue: the work section below is already a blue ground, and two
   blue panels in a row would read as one. Blue Ben-Day dots, ink type (10.6),
   blue figures (6.2). Figures are set wholly in Geist: the trial heading
   face has no digits, and mixing faces inside a number misaligns it. */

/* ---------- me: the paragraph inks in as you read ---------- */
[data-scrub] .w{opacity:.42;transition:opacity 160ms linear}
[data-scrub] .w.on{opacity:1}
@media (prefers-reduced-motion:reduce){[data-scrub] .w{opacity:1}}

/* ---------- contact: a highlighter under "always" ---------- */.contact .cta em{font-style:normal;background:linear-gradient(var(--yellow),var(--yellow)) 0 88% / 0% 34% no-repeat;
  transition:background-size 900ms var(--e-out) 400ms}.contact .cta.lit em{background-size:100% 34%}

/* icons: Phosphor (MIT, phosphoricons.com), bold weight, inlined so they take
   the text colour. Sources in assets/icons/. They sit on the text baseline at
   the text's own size, and only where they add meaning: direction, medium. */
.ico{display:inline-block;width:1em;height:1em;vertical-align:-.14em;flex:none}
.hbtn .ico{margin-left:var(--s-2);transition:transform var(--d-1) var(--e-out)}
.hbtn:hover .ico,.hbtn:focus-visible .ico{transform:translate(2px,2px)}
@media (prefers-reduced-motion:reduce){.hbtn .ico{transition:none}}
/* the cover furniture must never crowd the cover lines: the barcode sits
   top-left under the masthead on small covers, and the dateline stays on one row */
@container (max-width:520px){
}

/* ---------- the quote tape (21 Sep 2026) ----------
   A strip of yellow tape, cut by hand and stuck on at an angle across the
   seam between the hero and the rest of the page. Its edges are drawn, not
   ruled: a wobbly ink line top and bottom. Quotes are set in the display face
   in ink (11.0 on yellow), separated by hand-drawn stars. */


/* ---------- readability pass (21 Sep 2026) ----------
   Muted text is now opacity .82 everywhere, the lowest that holds 4.5:1 on
   cream and on ink; nothing smaller than 14px; no small type straight on a
   photograph or on red. */
@container (max-width:520px){}
/* the dateline wraps on small covers rather than shrinking below 14px */

@container (max-width:520px){}
/* an in-development row is marked by its dashed tag and "Writing", not by
   fading the whole row: fading twice put its text at 3.6:1 */
.wrow.soon.rv.in{opacity:1}
/* plate labels sit on a cream tab, never straight on red or blue */
.plate .pm{opacity:1;background:var(--cream);color:var(--ink);padding:2px 6px}
/* the last belief is the red one; on ink it takes the lifted red (6.4) */

/* ticker pause: small, plain, next to the thing it stops */

/* ---------- loader ----------
   A cold open, not a spinner. Mono leader in the corners, the artefact
   revealed through a widening letterbox, then the star punches and the
   whole thing wipes up into the hero. It also covers the hero image
   decode, so it is doing work as well as setting a tone.
   Restored 22 Sep 2026 at Shrey's request; now plays on every load. */
.loader{position:fixed;inset:0;z-index:120;background:var(--cream);
  display:grid;place-items:center;transition:clip-path 620ms var(--ease)}
.loader.gone{clip-path:inset(0 0 100% 0);pointer-events:none}

.lgrid{position:relative;width:min(88vw,var(--max));height:min(72vh,620px);
  display:grid;grid-template-columns:1fr auto;grid-template-rows:auto 1fr auto;gap:1rem}
.lmeta{font-family:var(--fu);font-size:var(--xs);letter-spacing:.16em;text-transform:uppercase;
  color:var(--deep);opacity:0;transition:opacity 420ms var(--ease)}
.lmeta.in{opacity:.82}
.lmeta.tl{grid-row:1;grid-column:1}
.lmeta.tr{grid-row:1;grid-column:2;text-align:right}
.lmeta.bl{grid-row:3;grid-column:1;align-self:end}
.lmeta.br{grid-row:3;grid-column:2;align-self:end;text-align:right}

/* the letterbox: a slit that opens to reveal the photograph.
   shares the centre cell with the rule, so the rule appears to part */

/* a hairline that draws across before the band opens */
.lrule{grid-row:2;grid-column:1/-1;align-self:center;height:2px;background:var(--deep);
  width:0;transition:width 620ms var(--ease);position:relative;z-index:2;justify-self:start}
.lrule.draw{width:100%}
.lrule.part{opacity:0;transition:opacity 300ms var(--ease)}

@media(max-width:900px){.lgrid{height:60vh}}
@media (prefers-reduced-motion:reduce){.loader{display:none}}

/* ---------- recruiter hooks (22 Sep 2026) ----------
   Copy written by Claude, flagged for Shrey's review (HARD RULE 6): a fast
   lane in the hero, a one-line value claim over each proof stint, and the
   roles he wants, stated once, above the ask. Every claim sits on a verified
   figure; nothing here adds a number. */

/* ============================================================
   FLOATING NAVIGATION MARKS, head start (22 Sep 2026)
   Five floating cut-out marks are the primary navigation, drifting in the
   hero; a label snaps in on hover or focus; the island nav stays as the
   always-visible text menu. Phones hide the marks.
   Clash, marked: the veto list bans offset shadows. The brief asks for a
   hard 3px offset on the cut-out marks, the same surface as the name tiles;
   picked on relevance. It stays on these marks and their labels only.
   ============================================================ */
.hero{position:relative}
/* where each one floats: the red panel's free edges and the cream margin, never over the copy */
/* the marks: paper, ink, one colour each. Fixed colours, so they stay paper in dark mode */
/* the label: a cut-out word that snaps in on intent */


/* the camera date stamp, printed on the picture */

 /* no drift, no hover on touch: the island menu is the navigation */

/* the loader, shortened: a fast rule, a fast wipe */
.loader{transition:clip-path 380ms var(--e-out)}
.lrule{transition:width 340ms var(--e-out)}
.lmeta{transition:opacity 200ms ease}

/* ---------- yellow is an accent, never a plane (Shrey, 22 Sep 2026) ----------
   It marks things (the highlighter, the stars on the tape, the cover
   starburst); it no longer fills a band. The quote tape is paper now. */
/* positions for the full hero: the red panel's free strips either side of the
   print, and the cream corner above the copy */
/* below 1180px the strips beside the print are too narrow to hold the marks
   clear of it; the island nav carries navigation there, as on phones */



/* ============================================================
   REFERENCE BOOK BUILD (23 Sep 2026). Rows marked Take, built here.
   ============================================================ */
/* 01 Hero: the icon slots hold the marks' size and drift; Hero6 is new */

/* 03 Work: covers wait in their frames; cards pick up on hover */
.plate{transition:transform 260ms var(--e-spring),box-shadow 260ms var(--e-out)}
/* the pick-up: lift, a small turn, and the hard 3px offset the cut-outs use
   (veto-list clash, marked: kept to this one hover) */
a.wrow:is(:hover,:focus-visible) .plate{transform:translateY(-6px) rotate(-1.6deg);box-shadow:3px 3px 0 #0D1633}
/* The hover lift moved to motion.js (13 Oct): it is now a three-part move
   on one timeline (the tile straightens, the poster pushes, the red band
   wipes up) and CSS cannot keep those in step. Nothing here drives .wk-frame
   any more, so the two systems cannot fight over its transform. */
@media (prefers-reduced-motion:reduce){.plate,.wk-tile .wk-frame{transition:none}a.wrow:is(:hover,:focus-visible) .plate,.wk-tile:is(:hover,:focus-visible) .wk-frame{transform:none}}

/* 05 Ideas: the magazine sits on its clipboard */
.desk-mag{position:relative}
.ph-clip{position:absolute;z-index:0;left:50%;top:50%;width:min(94%,760px);height:calc(100% + 96px);transform:translate(-50%,-50%) rotate(-2deg);pointer-events:none}
.desk-mag > .mag{position:relative;z-index:1}

/* ============================================================
   CONTACT, the references replicated in full (24 Sep 2026)
   Row 02, up.com.au: the hover that reveals a dark graphic. Row 00, Riya:
   the connect section's double hover, and the scribble. Row 09, the sky pin:
   the section stands on a hill rather than sitting above a band of one.
   One hover, three answers: the address inverts into a plane, the scribble
   draws under it, and the graphic comes up beside it. That is the "double
   hover" take, held to the letter, and it is all one gesture so it does not
   read as three effects competing.
   ============================================================ */
.reach{position:relative;z-index:1;padding:.05em .16em .2rem}
.reach{transition:border-color 220ms var(--ease),background 220ms var(--ease),color 220ms var(--ease)}

/* the scribble: drawn, not decorative. It underlines the one thing on the
   page a visitor is meant to do. */
.scribble{position:absolute;left:-.1em;right:-.1em;bottom:-.95rem;width:auto;height:clamp(14px,1.6vw,22px);
  overflow:visible;pointer-events:none;z-index:2}
.scribble path{fill:none;stroke:var(--fluoro);stroke-width:3.5;stroke-linecap:round;
  stroke-dasharray:440;stroke-dashoffset:440;transition:stroke-dashoffset 620ms var(--e-out)}
.scribble .s2{stroke-width:2.5;opacity:.75;transition-delay:90ms}

/* the dark graphic, row 02. It comes up beside the address, not over it. */

/* the hill, row 09: the section stands on it, full bleed and behind the
   content, with the footer line sitting on it rather than after it. */
/* a third of the height it was: the pill carries the copy, so the section is
   the pill, the sign-off line and the ground. */
.contact{position:relative;overflow:hidden;padding-bottom:clamp(96px,12vw,150px)}
.contact .wrap{position:relative;z-index:1}
/* ============================================================
   THE SIGN OFF (12 Oct 2026, from the sitraaart reference)
   Taken: a page that ends on purpose, three short columns, a giant
   wordmark cropped by the bottom edge, one oversized shape rising behind.
   Left: the near-black ground and the rounded blob. Ours stays on the
   off-white and the shape is our own star, so the ending is written in
   this alphabet rather than borrowed whole from theirs.
   The star is the ground (the Contact2 slot) AND the wordmark's full
   stop. The wordmark is cropped on purpose: a name too big for the page
   is the oldest poster move there is, and it is the one place on the
   site where type is allowed to run off the edge.
   ============================================================ */
.contact{isolation:isolate}
/* its own grid layer, because the section paints an opaque ground over the
   fixed one and would otherwise hide it */
.contact::before{content:"";position:absolute;inset:0;z-index:0;pointer-events:none;
  background-image:var(--paper);background-size:var(--paper-size);opacity:calc(.25 + var(--paper-in) * .75)}

/* The ending sits on a coloured pill (12 Oct, at his instruction). The veto
   list bans pills, and it means the small metadata capsule, not this: a plane
   big enough to be a room rather than a label. Same job as the reference's
   rounded blob, in our own colour.
   Cape blue and not red, because the block carries small type and red only
   carries type above 24px. Cream on deep is 8.50.
   The hover rule inside turns yellow rather than red: red on blue is unusable,
   and this is the one place yellow gets to be the interactive colour. */
.sign-off{position:relative;z-index:2;display:grid;gap:var(--s-6) var(--s-6);
  grid-template-columns:minmax(0,1.35fr) minmax(0,.6fr) minmax(0,.85fr) auto;
  align-items:start;margin-top:clamp(3.5rem,7vw,5.5rem);
  /* the pill is cape blue in BOTH themes: it is a plane, not a surface that
     follows the UI, and --deep becomes the light cream in dark mode, which put
     the yellow "always" on cream at 1.06. Same trap as the polaroid card.
     Cream on this blue is 8.50 and yellow on it is 8.70. */
  background:#173CA8;color:#F7F4EC;border-radius:999px;
  padding:clamp(3rem,6vw,5rem) clamp(2.4rem,6vw,6rem);align-items:center}
.sign-off .so-cta,.sign-off .so-mail,.sign-off .so-col a,.sign-off .so-k{color:#F7F4EC}
.sign-off .so-mail:is(:hover,:focus-visible),
.sign-off .so-col a:is(:hover,:focus-visible){border-bottom-color:var(--yellow)}
.sign-off :focus-visible{outline-color:var(--yellow)}
/* the pill is a plane, so the grid's own paper does not show through it and
   the star behind must not either */
.sign-off{isolation:isolate}
/* the call to action lives in the pill now and is the biggest thing in it */
.so-cta{margin:0;font-family:var(--fd);font-weight:700;font-size:clamp(1.9rem,3.6vw,3rem);line-height:1;
  letter-spacing:var(--fd-track);color:var(--cream);max-width:9em;text-wrap:balance}
.so-cta em{font-style:normal;color:var(--yellow)}
.so-mail{font-size:var(--t-body);letter-spacing:.01em;text-transform:none}
.so-mail{display:inline-flex;align-items:center;gap:var(--s-2);min-height:44px;margin-top:var(--s-4);
  font-family:var(--fu);font-size:var(--t-small);letter-spacing:.06em;text-transform:uppercase;
  color:var(--deep);text-decoration:none;border-bottom:2px solid transparent;
  transition:border-color var(--d-1) ease}
.so-mail:is(:hover,:focus-visible){border-bottom-color:var(--fluoro)}
.so-k{margin:0 0 var(--s-4);font-size:var(--xs);letter-spacing:.08em;text-transform:uppercase;opacity:.82}
.so-col ul{list-style:none;margin:0;padding:0;display:grid;gap:var(--s-1)}
.so-col a{display:inline-flex;align-items:center;gap:var(--s-2);min-height:36px;min-width:44px;
  font-family:var(--fu);font-size:var(--t-small);color:var(--deep);text-decoration:none;
  border-bottom:2px solid transparent;transition:border-color var(--d-1) ease}
.so-col a:is(:hover,:focus-visible){border-bottom-color:var(--fluoro)}
.so-ico{width:17px;height:17px;flex:none}
.so-social a{letter-spacing:.01em}

/* his own marks, fanned the way a hand of cards sits. Three, not six: the
   ring in the hero already shows all of them and this is a sign-off, not a
   second navigation. */
.so-fan{position:relative;width:clamp(150px,15vw,214px);height:clamp(118px,12vw,168px);justify-self:end}
.so-card{position:absolute;top:0;width:clamp(88px,8.6vw,124px);height:auto;
  transform-origin:50% 100%;transition:transform var(--d-2) var(--e-out)}
.so-card--1{left:0;transform:rotate(-13deg)}
.so-card--2{left:22%;transform:rotate(-1deg) translateY(-6px);z-index:2}
.so-card--3{left:44%;transform:rotate(12deg)}
.so-fan:hover .so-card--1{transform:rotate(-20deg) translateY(-4px)}
.so-fan:hover .so-card--3{transform:rotate(19deg) translateY(-4px)}
@media (prefers-reduced-motion:reduce){.so-card{transition:none}}

/* the wordmark, cropped by the section's own overflow */
.bigmark{position:absolute;z-index:1;left:50%;bottom:0;transform:translate(-50%,22%);
  margin:0;width:100vw;text-align:center;pointer-events:none;user-select:none;
  font-family:var(--fd);font-weight:900;font-size:clamp(3.2rem,15.5vw,15rem);line-height:.78;
  letter-spacing:-.045em;color:var(--deep);white-space:nowrap}

/* the ground: the star, rising, cropped. It is the full stop of the
   wordmark and the hill the section stands on at the same time. */
/* A whole star, most of it below the fold. Cropping it with slice showed
   only the top 30 per cent of the shape, which is one point and reads as an
   arrow; the arms start at about 45 per cent down. So the star keeps its
   proportions and the section edge does the cutting. */
/* The star settles in as you reach it (13 Oct, at his instruction). --star-in
   runs 0 to 1 while the contact section comes up the screen, written by
   home.js on a rAF tick. At 0 it sits lower and turned further; at 1 it is
   home. Transform only, so the compositor does all of it. */
.ground-star{position:absolute;z-index:0;left:50%;bottom:0;
  width:clamp(440px,68vw,1120px);aspect-ratio:1;height:auto;transform-origin:50% 100%;
  transform:translate(-50%,calc(50% + (1 - var(--star-in,1)) * 26%))
            rotate(calc(-4deg + (1 - var(--star-in,1)) * -16deg))
            scale(calc(.88 + var(--star-in,1) * .12));
  fill:var(--fluoro);opacity:calc(.25 + var(--star-in,1) * .67);pointer-events:none}
@media (prefers-reduced-motion:reduce){.ground-star{transform:translate(-50%,50%) rotate(-4deg);opacity:.92}}

@media (max-width:1100px){
  .sign-off{grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:var(--s-6);
    border-radius:clamp(28px,6vw,72px);padding:clamp(2.2rem,5vw,3rem) clamp(1.6rem,4vw,2.6rem)}
  .so-fan{justify-self:start}
}
@media (max-width:640px){
  .sign-off{grid-template-columns:minmax(0,1fr)}
  .bigmark{font-size:clamp(3.4rem,21vw,6rem);transform:translate(-50%,26%)}
}

/* the /contact/ list: the same gesture, one step quieter. No second copy of
   the Contact1 graphic, because one idea per surface. */
.creach .reach-row{position:relative}
.creach .reach-row .v{position:relative;display:inline-block;padding:.02em .14em;transition:background 220ms var(--ease),color 220ms var(--ease)}
.creach .reach-row:is(:hover,:focus-visible) .v{background:var(--deep);color:var(--cream)}
.creach .reach-row .scribble{bottom:-.5rem;height:14px}
.creach .reach-row:is(:hover,:focus-visible) .scribble path{stroke-dashoffset:0}
@media (prefers-reduced-motion:reduce){.scribble path{transition:none;stroke-dashoffset:0}}



/* 06 Me: the floating head, and the globe at the end of the story */
.phead{position:relative}
.me-head{position:absolute;right:max(var(--pad),4vw);top:var(--s-6);width:clamp(140px,18vw,240px);aspect-ratio:1;
  animation:mebob 1.4s var(--e-out) 3 alternate}
/* the floating head is a cut-out with its own transparent margin, so it is
   contained rather than cropped and the slot stops being square-bound */
.me-head{aspect-ratio:auto}
.me-head img{display:block;width:100%;height:auto;object-fit:contain}
@keyframes mebob{to{transform:translateY(-10px) rotate(-3deg)}}
@media (prefers-reduced-motion:reduce){.me-head{animation:none}}
/* it is a <span>, so the stacked branch has to give it a box: inline elements
   ignore width, height and aspect-ratio, which collapsed the slot to a 62px
   band across the column under 900px (found 7 Oct). */
@media (max-width:900px){.me-head{display:block;position:relative;right:auto;top:auto;margin:var(--s-5) 0 0}}
/* ---------- what keeps me going (12 Oct, at his instruction) ----------
   Replaces the globe and the list of places. A polaroid rather than a framed
   image: white card, a deep lip under the picture where a polaroid's chemistry
   sits, and pinned a degree or two off square so it reads as placed by hand
   rather than laid out. It is the only white object on a page of off-white,
   which is what makes it read as a print on a desk. */
.keeps{padding:var(--sec) 0}
/* The card is white in BOTH themes, because a polaroid is white paper and
   not a surface that follows the UI. That means the caption cannot use --deep,
   which becomes the light cream in dark mode: it was 1.26 on the card. Ink and
   the rule are fixed values here for the same reason. This is the --card trap
   from 24 Sep in a new place: anything hard-coded light needs hard-coded ink. */

/* The head that rides the giant star in the sign off. It sits in front of the
   star and behind the wordmark, which is the whole point: the three layers
   overlap the way a collage does rather than clearing each other. */
.star-head{position:absolute;z-index:1;left:50%;bottom:0;
  width:clamp(120px,15vw,250px);height:auto;
  transform:translate(-50%,-38%) rotate(3deg);pointer-events:none;user-select:none}
@media (max-width:640px){.star-head{width:clamp(96px,26vw,150px);transform:translate(-50%,-30%) rotate(3deg)}}
/* ============================================================
   THE HERO STAGE (23 Sep 2026, Reference Book rows 00-02)
   Taken: Balint Horvath's centre-piece with labelled objects floating
   around it, draggable, each one a place to go. Left: his sky wallpaper
   and the XP desktop language (taskbar, system-message window, .exe file
   names) - it reads as someone else's site, and it buried the photograph.
   The ground is cream, blue does the type and line work, red is the one
   accent plane, yellow only marks a hover. The photograph is the
   centre-piece and does not move.
   ============================================================ */
/* The hero ground is lifted towards white (Shrey, 24 Sep 2026): the same
   cream, mixed with paper, so the token relationship holds and dark mode
   still flips. Everything else on the page stays on --cream. */
.stage-hero{--card:color-mix(in srgb,var(--cream) 58%,#fff 42%);position:relative;display:block;min-height:100vh;min-height:100svh;overflow:hidden;
  padding:calc(var(--s-10) + var(--s-4)) 0 var(--s-9);background:var(--cream);color:var(--deep);isolation:isolate}
/* on the dark ground the mount has to go darker, not grey: mixing the dark
   cream towards white lands in the middle and takes the caption with it */
html[data-theme="dark"] .stage-hero{--card:color-mix(in srgb,var(--cream) 90%,#fff 10%)}
.stage-ground{position:absolute;inset:0;z-index:0;background-image:var(--paper);background-size:var(--paper-size);opacity:calc(.25 + var(--paper-in) * .75)}

.stage{position:relative;z-index:2;min-height:calc(100svh - var(--s-10) - var(--s-9));display:grid;place-items:center}

.print{margin:0;width:clamp(168px,17vw,228px);transform:rotate(-2.4deg)}
.print-mount{display:block;position:relative;background:var(--card);border:2px solid var(--deep);padding:10px 10px 0}
/* ============================================================
   THE BRUSH (6 Oct 2026, Shrey, after the Up bank reveal cursor)
   The photograph is printed black and white. The cursor paints the colour
   back in: a soft round mask follows the pointer over a colour copy of the
   same frame, so moving across it feels like wiping a window rather than
   toggling a state. The mask is a CSS mask driven by two custom properties,
   so the paint costs nothing per frame beyond two variable writes.
   Touch and keyboard get the whole thing revealed on focus, because there
   is no pointer to paint with. Reduced motion skips the transition, not the
   reveal: the colour is information, not decoration.
   ============================================================ */
.print-mount{position:relative}
.print-colour{position:absolute;inset:10px 10px 0;display:block;pointer-events:none;
  /* the path is stylesheet-relative on purpose: a url() inside a custom
     property is resolved against this file by the browser, not against the
     page, so an inline override from the markup resolves wrong */
  background-image:url("img/delhi-colour.webp");
  background-size:cover;background-position:center;
  /* the source is the colour original now, not the same halftone pushed, so
     the saturation boost that was faking colour comes off (12 Oct) */
  filter:saturate(1.06);
  -webkit-mask-image:radial-gradient(circle var(--brush,118px) at var(--bx,-999px) var(--by,-999px),#000 42%,rgba(0,0,0,.55) 62%,transparent 78%);
  mask-image:radial-gradient(circle var(--brush,118px) at var(--bx,-999px) var(--by,-999px),#000 42%,rgba(0,0,0,.55) 62%,transparent 78%);
  transition:-webkit-mask-image 120ms linear,mask-image 120ms linear}
.print-mount:is(:focus-within) .print-colour{-webkit-mask-image:none;mask-image:none}
@media (hover:none){.print-colour{-webkit-mask-image:none;mask-image:none;opacity:.001}}
.print-mount img{display:block;width:100%;height:auto;aspect-ratio:4/5;object-fit:cover;filter:grayscale(1) contrast(1.12)}
.print-stamp{position:absolute;right:-14px;top:-14px;display:grid;place-items:center;width:52px;height:52px;
  background:var(--card);border:2px solid var(--fluoro);color:var(--accent-type);border-radius:50%;font-family:var(--fd);font-weight:900;font-size:15px;
  letter-spacing:.02em;transform:rotate(9deg)}
.print figcaption{padding:var(--s-2) 10px var(--s-3);background:var(--card);border:2px solid var(--deep);border-top:0;
  font-family:var(--fu);font-size:13px;line-height:1.38;color:var(--deep)}
.print figcaption b{display:block;font-family:var(--fu);font-weight:400;text-transform:uppercase;letter-spacing:.08em;font-size:12px;opacity:.82}

.stage-copy{display:grid;justify-items:start}
.stage-copy .claim{margin:0 0 var(--s-1);font-family:var(--fd);font-weight:900;font-size:clamp(1.5rem,2.45vw,2rem);line-height:1.03;
  letter-spacing:var(--fd-track);color:var(--deep);max-width:13em;text-wrap:balance}
.stage-copy .roll{font-family:var(--fd);font-weight:900;font-size:var(--t-body);background:var(--deep);color:var(--cream)}
.stage-copy .hero-k{margin:var(--s-2) 0 0;font-family:var(--fu);font-size:var(--t-small);color:var(--deep);opacity:.82}
/* one row, so the hero stops being two stacked blocks of furniture */
.stage-copy .hero-cta{margin-top:var(--s-4);display:flex;flex-wrap:wrap;align-items:center;gap:var(--s-3) var(--s-5)}
@media (max-width:560px){.stage-copy .hero-cta{gap:var(--s-3)}}



.fl a{display:grid;justify-items:center;gap:var(--s-2);text-decoration:none;color:var(--deep);cursor:pointer}
.fl-icon{display:block;width:var(--fl-w);height:var(--fl-w);transition:transform 220ms var(--e-spring)}
.fl-icon img{display:block;width:100%;height:100%;object-fit:contain}
.fl-icon .ph{width:100%;height:100%;padding:4px;font-size:9px;gap:2px;background:var(--card)}
.fl-icon .ph b{font-size:14px}.fl-icon .ph i{display:none}
.fl-name{margin-top:-18px;position:relative;z-index:2;padding:3px 8px;background:var(--card);
  border:1.5px solid var(--deep);font-family:var(--fu);font-size:var(--t-small);line-height:1.25;
  text-align:center;color:var(--deep);overflow-wrap:anywhere}
.fl a:hover .fl-name,.fl a:focus-visible .fl-name{background:var(--yellow);color:#0D1633}
.fl a:hover .fl-icon,.fl a:focus-visible .fl-icon{transform:rotate(-2deg) scale(1.06)}
.fl a:focus-visible{outline:none}
.fl a:focus-visible .fl-icon{outline:3px solid var(--fluoro);outline-offset:3px}






/* ============================================================
   FINALISED HERO (6 Oct 2026). Appended last so it wins by order.

   Three changes from the previous hero, all of them subtractions except
   the panel:
   1. The cut-out name moves off the cream and onto a red halftone panel
      with the photograph, so the left column is one object instead of two.
   2. The separate rolling line is gone. Its word now rides inside the
      claim, which removes the second headline that was diluting the first.
   3. Both calls to action render as buttons. Square, hard-edged, 2px rule:
      a button in this system is a plane with a border, never a pill.
   ============================================================ */

/* --- the panel --------------------------------------------------- */
/* The tile sizes used to live under .stage-copy. The name has moved out of
   that scope, so without these the five cut-outs render at natural size, the
   grid column takes its minimum from them, and the panel blows out to 1289px
   with the photograph following it. Measured, not guessed: that is exactly
   what happened on the first build of this panel. */
/* The cut-out letters are a percentage of the panel rather than of the
   viewport, so the whole lockup scales as one object when the panel gives way.
   The percentages are the sizes they already had at a 330px panel. */

/* --- the claim ---------------------------------------------------- */
/* It is the largest type in the hero now that the second line is gone. */
.stage-copy .claim{font-size:clamp(1.75rem,3.1vw,2.6rem);line-height:1.06;max-width:15em;
  margin:0}
/* The roller. A clipped frame one line tall; the stack inside is moved by
   home.js. Spans, not list items: see the markup note. */
/* 1.25em is not a taste value. home.js moves the stack by i * 1.25em, so the
   frame and every row have to be exactly that or the words land between
   lines. They were 1.1em on the first pass and the roller settled 25px off. */
.stage-copy .roll{display:inline-block;height:1.25em;overflow:hidden;vertical-align:bottom;
  padding:0 .22em;background:var(--deep);color:var(--cream);box-sizing:content-box;
  font-family:var(--fd);font-weight:900;font-size:1em;line-height:1.25;
  transition:width 420ms var(--ease)}
@media (prefers-reduced-motion:reduce){.stage-copy .roll{transition:none}}
.stage-copy .roll .rollstack{display:block;transition:transform 420ms var(--ease)}
/* width:max-content so each word keeps its own measured width. Without it a
   block child fills the frame, and re-measuring after the webfont loads
   returns the frame width instead of the word width. */
.stage-copy .roll .rollstack>span{display:block;width:max-content;height:1.25em;line-height:1.25em;white-space:nowrap}
.vh{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;
  clip-path:inset(50%);white-space:nowrap;border:0}

.stage-copy .hero-k{margin:var(--s-3) 0 0;opacity:1;color:var(--deep)}

/* --- both actions are buttons ------------------------------------- */
/* The brief asked for buttons rather than bare text. Square and ruled, so
   the pill veto still holds. The second one is the outline variant: equal
   size, lower weight, which is how two actions sit together without the
   secondary one disappearing. */
.stage-copy .hero-cta .hbtn{min-height:48px;padding:0 var(--s-4);border:2px solid var(--deep);
  font-family:var(--fu);font-size:var(--t-small);letter-spacing:.04em;text-transform:uppercase;
  transition:background-color var(--d-1) ease,color var(--d-1) ease}
.stage-copy .hero-cta .hbtn-alt{background:transparent;color:var(--deep);text-transform:none;
  letter-spacing:0;font-family:var(--fb);font-weight:600;font-size:var(--t-small)}
.stage-copy .hero-cta .hbtn-alt:hover,.stage-copy .hero-cta .hbtn-alt:focus-visible{
  background:var(--yellow);color:#0D1633}
.stage-copy .hero-cta .hbtn:not(.hbtn-alt):hover,
.stage-copy .hero-cta .hbtn:not(.hbtn-alt):focus-visible{background:var(--yellow);color:#0D1633}

/* --- nav marks: the snap-in label --------------------------------- */
/* The short name is always there so the mark is never a mystery. The long
   label snaps in on hover and focus: a cut-out strip, held off-angle, no
   fade. A fade would read as a tooltip; a snap reads as a label being
   slapped on. Hidden from assistive tech because the link already carries
   its destination, and it is never the only way to know where a mark goes. */
.fl a{position:relative}
.fl-hint{position:absolute;left:50%;top:calc(100% + 6px);z-index:5;
  width:max-content;max-width:min(230px,42vw);padding:4px 9px;
  background:var(--yellow);color:#0D1633;border:2px solid var(--deep);
  font-family:var(--fu);font-size:11px;line-height:1.3;text-align:left;
  transform:translate(-50%,0) rotate(-1.6deg) scale(.86);
  opacity:0;visibility:hidden;pointer-events:none;
  transition:opacity 90ms linear,transform 140ms var(--e-spring),visibility 0s linear 140ms}
.fl a:hover .fl-hint,.fl a:focus-visible .fl-hint{
  opacity:1;visibility:visible;transform:translate(-50%,0) rotate(-1.6deg) scale(1);
  transition:opacity 90ms linear,transform 140ms var(--e-spring),visibility 0s}
@media (prefers-reduced-motion:reduce){
  .fl-hint{transition:opacity 90ms linear,visibility 0s linear 90ms;
    transform:translate(-50%,0) rotate(-1.6deg)}
  .fl a:hover .fl-hint,.fl a:focus-visible .fl-hint{transform:translate(-50%,0) rotate(-1.6deg)}
}
@media (hover:none){.fl-hint{display:none}}

/* ============================================================
   HERO v4 — THE CARD (13 Oct 2026, at his instruction)
   The name, the photograph and the copy are one object now: a licence
   card. Head strip, portrait, detail, actions, which is the order every
   ID card uses and the reason it reads clean instead of arranged.
   It sits left. The six marks have the rest of the field and float on
   their own CSS loops: no pointer, no ticker, no JS. Each has its own
   duration and delay so they never beat together, and because each one
   only moves a few pixels around a fixed position they cannot collide
   and cannot lag.
   ============================================================ */
.stage-centre{display:block;width:min(1180px,calc(100% - 2 * var(--pad)))}

.idcard{position:relative;z-index:3;width:min(540px,100%);
  background:#FFFDF7;color:#0D1633;border:2px solid #0D1633;
  padding:clamp(1.1rem,2vw,1.5rem);display:grid;gap:clamp(.9rem,1.6vw,1.2rem);
  transform:rotate(-1.2deg)}

/* head: the cut-out name, and the number every licence carries */
.id-head{display:flex;align-items:flex-end;justify-content:space-between;gap:var(--s-4);
  border-bottom:2px solid #0D1633;padding-bottom:clamp(.7rem,1.4vw,1rem)}
.id-head .hero-name{position:static;display:grid;justify-items:start;gap:3px;margin:0;
  width:auto;max-width:100%}
.id-head .hero-name .l1{display:flex;flex-wrap:wrap;align-items:flex-end;gap:5px}
.id-head .hero-name .l2{display:block;margin-top:2px}
.id-head .tile{display:block}
.id-head .tile img{display:block;width:100%;height:auto}
.id-head .t-hi{width:clamp(26px,3vw,34px)}
.id-head .t-my{width:clamp(31px,3.5vw,40px)}
.id-head .t-name{width:clamp(55px,6vw,70px)}
.id-head .t-is{width:clamp(18px,2vw,24px)}
.id-head .t-shrey{width:clamp(118px,13vw,158px)}
.id-stamp{flex:none;font-size:var(--xs);letter-spacing:.1em;text-transform:uppercase;
  color:var(--accent-type);padding-bottom:.2rem}

/* body: portrait beside the detail */
.id-body{display:grid;grid-template-columns:minmax(0,auto) minmax(0,1fr);
  gap:clamp(1rem,2vw,1.4rem);align-items:start}
.idcard .hero-pola{width:clamp(136px,16vw,188px);transform:none;margin:0}
.id-detail{min-width:0;display:grid;gap:var(--s-3)}
.idcard .stage-copy{max-width:none}
.idcard .claim{font-size:clamp(1.25rem,2.1vw,1.7rem);line-height:1.08;max-width:12em}
.idcard .hero-k{font-size:var(--t-small)}
.idcard .hero-cta{margin-top:var(--s-2);gap:var(--s-2) var(--s-3)}

/* the card is a printed object, so it does not follow the theme */
.idcard .claim,.idcard .hero-k,.idcard figcaption{color:#0D1633}
.idcard .roll{background:#173CA8;color:#FFFDF7}

/* ---- the marks: placed, and floating on their own loops ---- */
.floats{position:absolute;inset:0;width:auto;height:auto;transform:none;border-radius:0;
  z-index:4;pointer-events:none;list-style:none;margin:0;padding:0;
  --fl-w:clamp(112px,12vw,184px)}
.fl{position:absolute;width:calc(var(--fl-w) + 28px);pointer-events:auto;
  offset-path:none;will-change:transform}
.fl-icon{width:var(--fl-w);height:var(--fl-w)}
.fl-work{right:33vw;top:10%;animation:fl-a 7s ease-in-out infinite}
.fl-ideas{right:11vw;top:20%;animation:fl-b 8.4s ease-in-out infinite .4s}
.fl-me{right:25vw;top:40%;animation:fl-a 9.2s ease-in-out infinite .9s}
.fl-faq{right:5vw;top:56%;animation:fl-b 7.8s ease-in-out infinite 1.4s}
.fl-contact{right:36vw;top:62%;animation:fl-a 8.6s ease-in-out infinite .2s}
.fl-listen{right:16vw;top:74%;animation:fl-b 9.6s ease-in-out infinite 1.1s}
@keyframes fl-a{0%,100%{transform:translate3d(0,0,0) rotate(-2deg)}50%{transform:translate3d(6px,-12px,0) rotate(2deg)}}
@keyframes fl-b{0%,100%{transform:translate3d(0,-8px,0) rotate(2.5deg)}50%{transform:translate3d(-7px,8px,0) rotate(-1.5deg)}}
.fl a:is(:hover,:focus-visible) .fl-icon{transform:scale(1.07)}
@media (prefers-reduced-motion:reduce){.fl{animation:none}}

@media (max-width:1100px){
  .floats{--fl-w:clamp(84px,9.5vw,124px)}
  .fl-work{right:2vw;top:4%}.fl-ideas{right:20vw;top:16%}.fl-me{right:3vw;top:40%}
  .fl-faq{right:22vw;top:56%}.fl-contact{right:4vw;top:72%}.fl-listen{right:24vw;top:86%}
}
@media (max-width:860px){
  .idcard{width:100%;transform:none}
  .floats{position:relative;inset:auto;display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
    gap:var(--s-4);margin:var(--s-7) auto 0;max-width:560px;pointer-events:auto}
  .fl{position:static;width:auto;animation:none}
  .fl-work,.fl-ideas,.fl-me,.fl-faq,.fl-contact,.fl-listen{right:auto;top:auto;animation:none}
  .fl-icon{width:100%;height:auto;aspect-ratio:1}
}
@media (max-width:560px){
  .id-body{grid-template-columns:minmax(0,1fr)}
  .idcard .hero-pola{width:min(220px,62%)}
}


/* ---------- the card is printed, so it ignores the theme ----------
   The fourth time this trap has been walked into, and it is always the same
   one: a surface that is conceptually a PRINTED OBJECT cannot be built from
   --cream and --deep, because those two swap in dark mode. The card is white
   paper with blue ink on it in both themes, which is also why the hero ground
   does not darken. Every value below is a literal for that reason. Caught by
   the harness at 1.25, 1.29 and 1.34 in dark, not by reading the file. */
.idcard .print-mount{background:#FFFDF7;border-color:#0D1633}
.idcard .print figcaption{background:#FFFDF7;border-color:#0D1633;color:#0D1633}
.idcard .print-stamp{background:#FFFDF7;border-color:#E8251F;color:#B8141A}
.idcard .id-stamp{color:#B8141A}
.idcard .hero-cta .hbtn{background:#173CA8;color:#FFFDF7;border-color:#173CA8}
.idcard .hero-cta .hbtn-alt{background:transparent;color:#173CA8}
.idcard .hero-cta .hbtn:hover,.idcard .hero-cta .hbtn:focus-visible,
.idcard .hero-cta .hbtn-alt:hover,.idcard .hero-cta .hbtn-alt:focus-visible{
  background:#FFED10;color:#0D1633;border-color:#0D1633}
/* the marks sit on the same light ground in both themes, so their labels do too */
.floats .fl-name{background:#FFFDF7;border-color:#173CA8;color:#173CA8}
.floats .fl a:hover .fl-name,.floats .fl a:focus-visible .fl-name{background:#FFED10;color:#0D1633}

/* ============================================================
   THE STAR-HEAD STRIP (13 Oct 2026, at his instruction, after Rishabh)
   His face, four cuts of it, running between the five things he believes.
   It replaces a plain <ol> of the same five lines, which was the weakest
   presentation of the strongest personal copy on the site.

   It travels sideways as the page scrolls DOWN rather than running itself.
   That is the whole point of the device here: home already carries one
   self-starting loop, he has said twice that motion must not cost the
   content, and a scroll-linked strip is controlled by the reader, cannot be
   missed, and stops the moment they stop. Driven by ScrollTrigger in
   about.js; with the script off, or under reduced motion, the strip simply
   sits still and scrolls horizontally by hand like any overflow list.
   ============================================================ */
.hstrip{position:relative;margin:var(--s-9) 0;padding:var(--s-6) 0;
  border-top:2px solid var(--deep);border-bottom:2px solid var(--deep);
  background:var(--yellow);overflow:hidden}
.hs-view{overflow-x:auto;overflow-y:hidden;scrollbar-width:none;-ms-overflow-style:none}
.hs-view::-webkit-scrollbar{display:none}
.hs-track{display:flex;align-items:center;gap:clamp(1.4rem,3vw,2.6rem);
  margin:0;padding:0 var(--pad);list-style:none;width:max-content}
/* ink on shield yellow is 14.73, which is the one pairing that lets display
   type sit on a yellow plane at all */
.hs-say{flex:none;max-width:22ch;font-family:var(--fd);font-weight:900;
  font-size:clamp(1.15rem,2.1vw,1.9rem);line-height:1.08;
  letter-spacing:var(--fd-track);color:#0D1633}
.hs-say span{display:block}
.hs-face{flex:none;width:clamp(96px,11vw,164px)}
.hs-face img{display:block;width:100%;height:auto}
/* the faces alternate their tilt, so four cut-outs in a row read as a strip
   of frames rather than a row of stickers set at one angle */
.hs-face:nth-of-type(odd) img{transform:rotate(-3deg)}
.hs-face:nth-of-type(even) img{transform:rotate(2.5deg)}
@media (max-width:640px){
  .hstrip{margin:var(--s-8) 0;padding:var(--s-5) 0}
  .hs-say{max-width:18ch}
}

/* ---------- the choppiness pass (13 Oct 2026) ----------
   Three things he reported as "overlaps and unnecessary gaps", all of them
   found by screenshotting the scroll rather than by reading the file. */

/* The notes that stood here described the quote tape and the logo strip
   clearances. Both sections came off home at his instruction, so the fixes
   and their reasoning went with them. The seam they were protecting is now
   the hero meeting the numbers block directly. */

/* 3. The dashed slot behind the zine read as a broken frame rather than as a
      waiting image: it is a large empty dashed rectangle with nothing in it,
      which is the one placeholder treatment this site had already decided
      against everywhere else. It comes back when the clipboard art lands. */
.ph-clip{display:none}

/* ---------- the card carries the name properly (13 Oct 2026) ----------
   The first build of the card shrank the cut-out name to a 150px thumbnail in
   a head strip. That inverts the hierarchy the whole system is built on: the
   name is the identity, the identity is the idea, and the idea is the largest
   thing in the block. It also threw away the one device that is unmistakably
   his, the ransom lettering, by setting it at a size where you cannot read
   that the letters are cut from different sources.

   So the name is the headline now and the card is sized around it. */
.idcard{width:min(620px,100%)}
.id-head{display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:start;
  gap:var(--s-3);padding-bottom:clamp(.9rem,1.8vw,1.2rem);
  /* red, not blue: the hero had no cape red in it at all except a 52px stamp,
     on a site whose system is three colours. One rule is enough to fix that. */
  border-bottom:3px solid var(--fluoro)}
.id-head .hero-name .l1{gap:8px}
.id-head .t-hi{width:clamp(38px,4.4vw,52px)}
.id-head .t-my{width:clamp(45px,5.2vw,61px)}
.id-head .t-name{width:clamp(80px,9.1vw,107px)}
.id-head .t-is{width:clamp(26px,3vw,36px)}
.id-head .t-shrey{width:clamp(186px,21vw,248px)}
.id-stamp{align-self:end}

/* the claim grows with it, so the card reads as one object rather than a
   large name with small print under it */
.idcard .claim{font-size:clamp(1.4rem,2.5vw,2rem);max-width:13em}
.idcard .hero-pola{width:clamp(150px,17vw,205px)}

/* A registration edge, not a shadow. Offset printing lays one plate slightly
   off another and leaves a hard colour edge; a drop shadow fakes depth. The
   veto list bans the second and this is the first: no blur, no transparency,
   a flat plane of cape red showing along two sides of the card. */
/* The registration edge. Third build, and the first honest one.
   Attempts one and two put the red on a pseudo-element behind the card and
   it painted over the whole card instead. The cause was never the z-index:
   .idcard carried transform:rotate(), and a transform creates a stacking
   context by itself, so a z-index:-1 child can never get behind its parent's
   background whatever the index says.

   Attempt three moved the paper onto a pseudo-element too, which worked
   visually and then lied: with no background on .idcard itself, the contrast
   harness walked up to the body and read the claim at 1.01 in dark mode on a
   card that is plainly white. A check that cannot see the real ground is
   worse than no check, because the next session trusts the zero.

   So the ROTATION moves up to .stage-centre, which holds nothing but the
   card. .idcard then has no transform and no stacking context, keeps its real
   background where anything reading this file would expect it, and the red
   plane sits behind it on a plain negative index. No blur, no transparency:
   one plate printed slightly off another, which is not what the veto list
   means by an offset shadow. */
.stage-centre{transform:rotate(-1.2deg)}
.idcard{transform:none;z-index:auto;background:#FFFDF7;border:2px solid #0D1633;
  padding:clamp(1.1rem,2vw,1.5rem)}
.idcard::before{content:"";position:absolute;z-index:-1;inset:12px -12px -12px 12px;
  background:var(--fluoro)}

@media (max-width:560px){
  .id-head{grid-template-columns:minmax(0,1fr)}
  .id-stamp{align-self:start}
  .idcard::before{inset:7px -7px -7px 7px}
}

/* The deck says so when the file will not play, rather than leaving a button
   that silently does nothing. Set by motion-free code in home.js on the audio
   element's own error event, so it can only appear when the load really failed. */

/* ============================================================
   HOME IS SCHEDULED IN BLOCKS (13 Oct 2026, at his instruction)
   "The home is still not scheduled on different blocks and the grid
   background seems very overdone."

   Both halves of that are the same problem. Every section except Work sat on
   one continuous cream with one continuous grid behind it, so the page read
   as a single sheet eight screens long, and the only way to feel progress was
   the headings. Giving six sections six grounds is what makes a scroll feel
   like a sequence of rooms rather than a long corridor.

   The schedule, and the reason for each:
     1  HERO       paper + grid     the texture is the hero's signature
     2  NUMBERS    flat cream       a clean plain break (his Akriti note)
     3  WORK       cape blue        the one colour block, torn at both edges
     4  IDEAS      flat warm white  a clean sheet, so the zine art carries it
     5  ME         paper + grid     the texture returns, so it reads as a motif
     6  CONTACT    cream + star     unchanged

   Textured, plain, colour, plain, textured, colour. Nothing new is invented:
   every ground is a token already locked, and the two flat blocks are simply
   the grid not showing through.
   ============================================================ */

/* --- 2. THE PROOF BLOCK: quotes, the logo wall, the numbers ---------------
   Three sections that answer one question (who says so) and read as one band.
   The flat ground is an opaque cream painted over the fixed grid layer, which
   is why no grid shows here: there is nothing to switch off. */
/* The tape and the logo wall came off home at his instruction, so this block
   is now the numbers alone: what he does, and what it moved. It is still the
   plain break between the hero and the work, and it is still the only thing
   between them, which is the point he was making. */
.moved{background:var(--cream);border-top:2px solid var(--deep)}
/* no bottom rule: the work block tears away from this one, and a ruled edge
   12px above a torn one reads as a mistake rather than as two devices. */

/* --- 3. WORK: the blue block is torn, not cut -----------------------------
   A full-bleed colour band with two razor edges is a <div>. The same band
   torn along both edges is a strip of paper laid on the page, which is the
   collage language the rest of the site is built in. The wobble is the quote
   tape's own edge, reused rather than redrawn, so the two devices are
   recognisably the same hand. */
.work{position:relative}
.work::before,.work::after{content:"";position:absolute;left:0;right:0;height:12px;z-index:20;
  pointer-events:none;
  background:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='12' viewBox='0 0 240 12'%3E%3Cpath d='M0 0h240v4c-14 3-26-2-40 0s-24 4-38 1-30-3-44 0-22 3-36 1-26-4-42-1-26 2-40-1z' fill='%23F7F4EC'/%3E%3C/svg%3E") repeat-x 0 0/240px 12px}
.work::before{top:-1px}
.work::after{bottom:-1px;transform:scaleY(-1)}
/* dark mode: the torn edge has to be the colour of the page it tears away
   from, and that colour flips. Hard-coding it would leave a cream scar on an
   ink page, which is the plane trap in its other direction. */
:root[data-theme="dark"] .work::before,:root[data-theme="dark"] .work::after{
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='12' viewBox='0 0 240 12'%3E%3Cpath d='M0 0h240v4c-14 3-26-2-40 0s-24 4-38 1-30-3-44 0-22 3-36 1-26-4-42-1-26 2-40-1z' fill='%230D1633'/%3E%3C/svg%3E")}

/* --- 4. IDEAS: a clean sheet ---------------------------------------------
   The zine cover is his artwork and it is busy. A grid behind busy artwork is
   two textures competing, and the artwork loses. Warm white rather than cream
   so the sheet reads as a different stock from the proof block above it. */
.ideas{background:#FFFDF7;position:relative}
/* bottom only, for the same reason: the work block above already tears into
   this one. */
.ideas::before{content:"";position:absolute;inset:0;z-index:0;pointer-events:none;
  border-bottom:2px solid var(--deep)}
:root[data-theme="dark"] .ideas{background:color-mix(in srgb,var(--cream) 94%,#000)}

/* --- 5. ME: the texture returns ------------------------------------------
   Nothing to declare: .about has no background, so the fixed grid shows
   through again. Stated here only so the schedule above is complete and the
   next session does not "fix" the gap by giving it one. */

/* ---------- Who I do it for (13 Oct 2026, his title) ----------
   The camera holds the whole family and the Taj frame still on its screen, so
   it is the picture that explains the other two. It sits in the middle at his
   instruction, and it is wider than the polaroid stacks either side of it
   (820x486 against 820x960), so a straight three-column grid would leave it
   floating in a tall cell. The centre column takes the extra width instead. */
.mot{grid-template-columns:minmax(0,.82fr) minmax(0,1.36fr) minmax(0,.82fr);
  align-items:center}
.mot-item--cam{animation:mot-b 9s ease-in-out infinite .6s}
@media (prefers-reduced-motion:reduce){.mot-item--cam{animation:none;transform:rotate(-1.2deg)}}
@media (max-width:760px){.mot{grid-template-columns:minmax(0,1fr)}}

/* the orange band on /about/ sits between the heading and the five cards, so
   it needs air on both sides rather than the flush bleed it has on home */
.dump .process{margin:var(--s-6) 0 var(--s-7)}

/* ---------- the manifesto spread carries one line, big ----------
   The five beliefs are the star-head strip on /about/ now, so printing all
   five here as a numbered list was the same copy twice. A zine that prints
   its loudest line at full size is behaving like a zine; a zine that prints
   a bulleted list is behaving like a slide. The other four are one click away
   and the page says so. */
.mani-one{margin:0;border:0;padding:0}
.mani-one p{margin:0;font-family:var(--fd);font-weight:900;
  font-size:clamp(1.75rem,3.2vw,3.1rem);line-height:1.02;
  letter-spacing:var(--fd-track);color:var(--deep);text-wrap:balance}
.mani-more{margin:var(--s-5) 0 0;font-family:var(--fu);font-size:var(--t-small)}
.mani-more a{display:inline-flex;align-items:center;min-height:24px;padding:2px 0}
.mani-more a{color:var(--accent-type);text-decoration:none;border-bottom:1.5px solid currentColor}
.mani-more a:is(:hover,:focus-visible){background:var(--yellow);color:#0D1633;border-color:#0D1633}

/* ---------- the star, with him in the middle of it (13 Oct 2026) ----------
   From the same delivery as the bobbleheads, found in 3.pdf of that zip. It is
   the best picture of him on the site: he is in it, he took it himself, and
   the star is the site's own mark drawn by hand rather than the vector one.
   It replaces the small floating head in the /about/ header, which was a
   decoration where this is a feature.
   Bigger than the head it replaces, because a 900x975 artefact at 240px reads
   as a sticker. Loaded eagerly: it is above the fold on this page, and a lazy
   image in the header pops in after the heading has already settled. */
.me-head--star{width:clamp(200px,26vw,360px);aspect-ratio:auto;
  top:calc(var(--s-9) + var(--s-4));right:max(var(--pad),6vw)}
.me-head--star img{width:100%;height:auto}
@media (max-width:900px){
  .me-head--star{width:min(300px,70%);margin-inline:auto}
}

/* ============================================================
   THE WORK WALL READS AS A SEQUENCE (19 Oct 2026, at his instruction)
   "The work stuff has to be remade in a way that actually follows the flow
   of readability."

   It was three posters at three hand-placed positions, accumulating as you
   scrolled. At any given moment you saw one, two or three of them scattered
   across a blue field with a few hundred pixels of nothing under them, and
   there was no order for the eye to follow: nothing said which to read first
   or that there were three.

   Each project now holds the stage alone, in one slot, at a size you can
   actually read, and hands it to the next. The pin earns its height because
   something changes the whole way down it, and the dead space is gone
   because there is only ever one object on the stage.
   ============================================================ */
@media (min-width:760px) and (prefers-reduced-motion:no-preference){
  .work .wk-tile,.work.wk-live .wk-tile,.work.wk-live .wk-tile.is-visible{
    /* one slot, right of the copy column, vertically centred */
    left:auto;right:max(var(--pad),7vw);top:50%;width:min(38vw,520px);
    /* enter from below, sit, leave upward. --p drives the arrival and --q the
       exit, so the two are independent and neither can strand a tile on
       screen when the scroll is thrown rather than dragged. */
    transform:translate3d(0,calc(-50% + (1 - var(--p,1)) * 26vh - var(--q,0) * 30vh),0)
      scale(calc(.92 + var(--p,1) * .08))
      rotate(calc(var(--r) * (1 - var(--q,0))));
    opacity:calc(var(--p,1) * 2.2 * (1 - var(--q,0)));
    transition:none}
  /* the number is the reading order, stated rather than implied */
  /* above the tile, not beside it: the poster is rotated, so a counter in
     the left margin sits under its corner at two of the three angles. */
  .wk-tile::after{content:attr(data-n);position:absolute;left:.2rem;top:-1.9rem;
    font-family:var(--fu);font-size:var(--t-small);letter-spacing:.1em;
    color:rgba(var(--cream-rgb),.62)}
  .wk-label{font-size:var(--t-small)}
  .wk-label span:first-child{font-family:var(--fd);font-weight:900;font-size:var(--t-h3);
    letter-spacing:var(--fd-track)}
}

/* The easter-egg head is GONE (20 Oct, at his instruction). A floating head
   at the end of the page was explicitly cut on 13 Oct and I put one back as
   the scroll reward, which reinstated the exact overlap he had removed. The
   egg needs a different form and that is his call, not another guess. */
/* ============================================================
   ONE TRANSITION LANGUAGE (19 Oct 2026, at his instruction)
   "The current pages are either bound by unwanted breaks, or transitions
   that do not create a huge difference between sections."

   Both halves were true and they were the same inconsistency. Some seams
   were a hard 2px rule, which cuts the page without saying anything. Others
   were nothing at all, so two different grounds met with no event between
   them. Only the work block had a real transition.

   The rule now: wherever two DIFFERENT grounds meet, the upper block tears
   away in its own colour. Wherever two blocks share a ground, a rule is the
   honest signal and stays. One device, applied by the same test every time,
   instead of three treatments chosen ad hoc.
   ============================================================ */

/* the tear is one shape, declared once, and each use only sets its colour */
.work::before,.work::after,.ideas::after{
  content:"";position:absolute;left:0;right:0;height:12px;z-index:20;pointer-events:none;
  background-repeat:repeat-x;background-position:0 0;background-size:240px 12px}

/* work tears UP into the numbers block, which is cream */
.work::before{top:-1px;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='12' viewBox='0 0 240 12'%3E%3Cpath d='M0 0h240v4c-14 3-26-2-40 0s-24 4-38 1-30-3-44 0-22 3-36 1-26-4-42-1-26 2-40-1z' fill='%23F7F4EC'/%3E%3C/svg%3E")}

/* work tears DOWN into ideas, which is warm white, not cream. It was cream
   here and the 6-point difference showed as a pale line along the seam. */
.work::after{bottom:-1px;transform:scaleY(-1);
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='12' viewBox='0 0 240 12'%3E%3Cpath d='M0 0h240v4c-14 3-26-2-40 0s-24 4-38 1-30-3-44 0-22 3-36 1-26-4-42-1-26 2-40-1z' fill='%23FFFDF7'/%3E%3C/svg%3E")}

/* ideas tears into Me, which is the grid ground returning. This boundary had
   a plain rule and was the one seam on the page you could scroll past
   without noticing the ground had changed. */
.ideas{position:relative}
.ideas::after{bottom:-1px;transform:scaleY(-1);
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='12' viewBox='0 0 240 12'%3E%3Cpath d='M0 0h240v4c-14 3-26-2-40 0s-24 4-38 1-30-3-44 0-22 3-36 1-26-4-42-1-26 2-40-1z' fill='%23F7F4EC'/%3E%3C/svg%3E")}
/* the rule it replaces: a tear and a rule at the same seam is two devices
   doing one job, which is the inconsistency this block exists to end */
.ideas::before{border-bottom:0}

/* dark: a tear has to be the colour of the page it tears away from, and that
   colour flips. Hard-coding light values leaves a pale scar on an ink page. */
:root[data-theme="dark"] .work::before,
:root[data-theme="dark"] .work::after,
:root[data-theme="dark"] .ideas::after{
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='12' viewBox='0 0 240 12'%3E%3Cpath d='M0 0h240v4c-14 3-26-2-40 0s-24 4-38 1-30-3-44 0-22 3-36 1-26-4-42-1-26 2-40-1z' fill='%230D1633'/%3E%3C/svg%3E")}

/* ---------- why the marks are NOT beside the figures (20 Oct 2026) ----------
   Tried and reverted, recorded so it is not tried again. The idea was to let
   each client mark cite the number it produced, turning an assertion into
   evidence with a source attached. It was built, looked at, and it was wrong
   for two reasons:

   1. The figure ALREADY names its source in words. A small mark beside the
      word "Tickertape" says Tickertape a second time. Nobody trusts +310%
      more because a logo sits next to it; the line had already said so.
   2. Half of the eight are plate lockups rather than wordmarks. iSelect is
      white knocked out of a red rounded rectangle. Tinted to one ink it is a
      grey box, and at the 16px a citation allows it is mud either way.

   The marks are information where the question "who has he worked with" is
   actually being asked, which is /about/, not next to a number that has
   already answered it. That is where they live now. */

/* ---------- Worked with, on /about/ (20 Oct 2026) ----------
   The eight marks finally earn a place. They came off the top of home at his
   instruction and he was right: a row of other people's logos before a
   visitor has seen anything he made is an interruption. On the page that is
   about his background it is the opposite, it is the fastest answer on the
   site to a question a recruiter is actually asking.

   STATIC, not a loop. They ran as a marquee on home until 13 Oct and the
   motion was part of the problem: eight names moving become a texture you
   scan past. Eight names held still are read in one glance.

   Each mark keeps its own colour. Four of the eight are plate lockups rather
   than wordmarks (iSelect is white knocked out of red), and tinting those to
   one ink turns them into grey boxes. That was learnt by doing it. */
.worked-at{margin:0 0 var(--s-7)}
.worked-at h3{margin:0 0 .2rem}
.wa-marks{display:flex;flex-wrap:wrap;align-items:center;gap:var(--s-4) var(--s-5);
  margin:var(--s-4) 0 0;padding:0;list-style:none}
.wa-marks li{display:flex;align-items:center}
/* sized by HEIGHT, never by a shared box: a square device in the same box as
   a wide wordmark reads half the size. This was settled on 6 Oct and the
   reasoning is worth keeping. */
.wa-marks img{display:block;width:auto;max-width:none;height:clamp(20px,2.4vw,30px)}
/* two exceptions, both devices drawn small inside their own lockup rather
   than wordmarks, so a shared cap height leaves them looking like holes */
.wa-marks li:nth-child(6) img,
.wa-marks li:nth-child(7) img{height:clamp(30px,3.6vw,44px)}
@media (max-width:640px){.wa-marks{gap:var(--s-3) var(--s-4)}}

/* ---------- the alphabet page (20 Oct 2026) ----------
   The sheet every cut-out letter in the hero was lifted from. It is the one
   artefact on the site that shows a system behind a device rather than the
   device on its own, which is why it is a page rather than a background.
   Contained, never cropped: the value is seeing all 26 with their three
   variants, so it fits the page rather than filling it. */
.pg-alpha{display:flex;flex-direction:column}
.pg-alpha-art{display:block;flex:1 1 auto;min-height:0;width:100%;height:100%;
  object-fit:contain;object-position:center top;margin:var(--s-4) 0 0;
  border:2px solid var(--deep);background:#fff}

/* ---------- the figures group by capability (20 Oct 2026, his call) ----------
   Seven figures in a flat list read as seven things that happened. Fourteen
   under five capability headings read as five things he can do, each with
   evidence under it. That is the difference between a CV line and a claim a
   hiring manager can test, and it is why the group heading is the loudest
   thing in each block after the number itself. */
.mv-group{margin:0 0 var(--s-6)}
.mv-group:last-child{margin-bottom:0}
.mv-gk{margin:0 0 var(--s-3);padding-bottom:.35rem;
  font-family:var(--fu);font-size:var(--xs);letter-spacing:.1em;text-transform:uppercase;
  color:var(--deep);border-bottom:1.5px solid color-mix(in srgb,var(--deep) 32%,transparent)}

/* the pill carries two real figures instead of a count of skills. Shut, it is
   now the only place on the first two screens where a number appears, which
   is the whole reason for the change. */
.mv-pill-n b{font-family:var(--fd);font-weight:900;font-size:1.15em;letter-spacing:var(--fd-track)}
.mv-pill-n i{font-style:normal;opacity:.5;margin:0 .25em}
@media (max-width:760px){
  /* the two figures survive, the "12 more" does not: it is the first thing
     that can go when the row runs out of width */
  .mv-pill-n{font-size:var(--xs)}
}

/* ---------- the playlist, hanging off the deck (20 Oct 2026) ----------
   The mp3 stays: he asked for the file, and the embed gives anyone not
   signed in a thirty second preview. This is a second thing, not a
   replacement. It opens upward from the deck because the deck lives in the
   bottom-right corner and there is no room below it. */
/* ---------- the one record, in Me (20 Oct 2026, at his instruction) ----------
   Split from the deck: the deck is the playlist, this is the single track.
   It sits in Me because a favourite record is a fact about him rather than a
   utility in the corner of every screen, and it is the only audio on the
   site that plays a file he owns rather than an embed. */
/* pause: two bars, drawn from the same span so there is no second element */
:focus-visible){background:#FFED10}
:focus-visible) span{border-left-color:#0D1633}
:focus-visible) span{
  background:linear-gradient(to right,#0D1633 0 34%,transparent 34% 66%,#0D1633 66% 100%)}



/* ---------- /work reads, instead of competing with itself (20 Oct) ----------
   His note: the work pages read cluttered and the background impairs
   reading. Both were true and they were separate problems.

   THE GROUND. The drawn grid is the texture of the paper sections. /work is
   a dense index: eleven rows of cover, heading, teaser and tags, and a grid
   running under all of it is a second pattern competing with the first. The
   page gets a flat ground, which is the same decision the case pages got on
   19 Oct for the same reason.
   THE TAGS. Every row carried its state twice: once on the plate corner
   (01 · SPEC) and again as a tag. Vastr carried six tags, which reads as a
   tag cloud rather than a project. The state tag is gone; the plate keeps
   it, because that is where the eye lands first. */
body:has(.wlist),body:has(.wrow){background:var(--cream)}
body:has(.wrow)::before{display:none}
/* the rows get air: 11 of them at the old rhythm is a wall */
.wrow{padding-block:clamp(1.1rem,2vw,1.6rem)}
.wrow .tags{gap:.45rem}

/* ---------- the process cards, his own deck (20 Oct) ----------
   The five steps were retyped into five text cards, which threw away the
   deck he designed and left the section reading as a wall of body copy. The
   cards are the artefact; they run on the same ticker engine as the band
   above so the section is one device rather than two. */
.proccards{position:relative;overflow:hidden;margin:var(--s-6) 0 0;
  padding:var(--s-5) 0;border-top:2px solid rgba(var(--cream-rgb),.35);
  border-bottom:2px solid rgba(var(--cream-rgb),.35)}
.proccards .pc-band{position:relative;overflow:hidden}
.proccards .xtrack{display:flex;width:max-content;will-change:transform}
.pc-set{display:flex;align-items:stretch;gap:var(--s-5);margin:0;padding:0 calc(var(--s-5)/2);list-style:none;flex:none}
.pc-set li{flex:none}
.pc-set img{display:block;width:auto;max-width:none;height:clamp(190px,24vh,270px);
  border:2px solid #0D1633}
@media (max-width:640px){.pc-set img{height:170px}.pc-set{gap:var(--s-4)}}

/* ---------- TWO OBJECTS, not one box (20 Oct, his third correction) ----------
   "MP4 is a disc player on site and the spotify playlist is a music list on
   the site - you have merged these two."

   He was right and I kept missing it. Putting them in one bordered box is
   still a merge even when the contents are separate. A record player is a
   thing you OPERATE; a playlist is a thing you READ. They share a section
   and nothing else: no common frame, no common border, different shapes. */
.listening{display:grid;gap:var(--s-5);margin:var(--s-6) 0 0}
@media (min-width:900px){.listening{grid-template-columns:auto minmax(0,1fr);align-items:start;gap:var(--s-6)}}

/* 1. the disc player: an object, round, with a platter and an arm */
.disc{margin:0;display:grid;justify-items:center;gap:var(--s-3)}
.disc-deck{position:relative;width:clamp(140px,17vw,180px);aspect-ratio:1;
  border-radius:50%;background:#0D1633;display:grid;place-items:center;
  border:3px solid #0D1633}
.disc-platter{display:block;width:62%;aspect-ratio:1;border-radius:50%;overflow:hidden;
  border:2px solid #FFFDF7}
.disc-platter img{display:block;width:100%;height:100%;object-fit:cover}
/* it only turns while sound is actually coming out */
.disc.spinning .disc-platter{animation:disc-spin 3.2s linear infinite}
@keyframes disc-spin{to{transform:rotate(360deg)}}
@media (prefers-reduced-motion:reduce){.disc.spinning .disc-platter{animation:none}}
.disc-arm{position:absolute;right:4%;top:2%;width:26%;height:auto;
  transform-origin:76% 9%;transform:rotate(-12deg);transition:transform 420ms var(--e-spring)}
.disc.spinning .disc-arm{transform:rotate(10deg)}
.disc-arm .arm-rod{fill:none;stroke:#FFFDF7;stroke-width:3;stroke-linecap:round}
.disc-arm .arm-head{fill:#E8251F}
.disc-arm .arm-pivot{fill:#FFFDF7}
.disc-btn{position:absolute;left:50%;top:50%;width:40px;height:40px;margin:-20px 0 0 -20px;
  border-radius:50%;border:2px solid #0D1633;background:#FFED10;cursor:pointer;
  display:grid;place-items:center;padding:0}
.disc-btn span{display:block;width:0;height:0;margin-left:3px;
  border-left:12px solid #0D1633;border-top:8px solid transparent;border-bottom:8px solid transparent}
.disc.spinning .disc-btn span{width:12px;height:14px;margin:0;border:0;
  background:linear-gradient(to right,#0D1633 0 34%,transparent 34% 66%,#0D1633 66% 100%)}
.disc-btn:focus-visible{outline:3px solid var(--fluoro);outline-offset:3px}
.disc.dead .disc-btn{opacity:.5;cursor:not-allowed}
.disc-meta{display:grid;justify-items:center;gap:1px;text-align:center}
.disc-k{font-size:var(--xs);letter-spacing:.1em;text-transform:uppercase;color:var(--accent-type)}
.disc-title{font-family:var(--fd);font-weight:900;font-size:var(--t-body);
  letter-spacing:var(--fd-track);color:var(--deep)}
.disc-by{font-family:var(--fu);font-size:var(--t-small);color:var(--deep);opacity:.78}
.disc-audio{display:none}

/* 2. the music list: rows, not a machine. No border, no card. */
.mlist{min-width:0}
.mlist-k{display:flex;flex-wrap:wrap;gap:.3rem .7rem;align-items:baseline;margin:0 0 var(--s-2);
  font-size:var(--xs);letter-spacing:.1em;text-transform:uppercase;color:var(--deep)}
.mlist-k a{color:var(--accent-type);text-decoration:none;border-bottom:1px solid currentColor;
  text-transform:none;letter-spacing:.02em}
.mlist-k a:is(:hover,:focus-visible){background:var(--yellow);color:#0D1633}
.mlist-frame{display:block;width:100%;height:352px;border:0;border-radius:10px}
@media (max-width:560px){.mlist-frame{height:252px}}
