/* ═══════════════════════════════════════════════════════════════════════════
   COMPAYTENCE DESIGN SYSTEM — v2
   Adopted 2026-08-03. Supersedes the v1 "playbook" stylesheet entirely.

   The five things that make it ours:
     1 · One blue ladder, seeded on the wordmark's PAY blue (#33A9FF at step
         50) and stepped by LIGHTNESS ONLY. Chroma is held and drops only
         where sRGB cannot hold it.
     2 · Warm ground at hue 65.6, the blue's EXACT complement, at tint-
         level chroma. Warm paper, cool accent. No third hue anywhere.
     3 · Figures are the signature: display serif, blue, tabular, aligned.
     4 · The card is the container everywhere, docs and web alike: hairline
         at rest, elevation only on hover (lift + bloom + tracked sheen).
     5 · Spacing derives from the 30px text baseline, not a geometric ratio.

   Fonts: Instrument Serif (display + ALL figures) · Archivo (body/UI) ·
   a mono for technical strings ONLY (never labels, never eyebrows).
   Load via <link> for local work; embed as base64 @font-face for any file
   that will be emailed or shared. See references/design-system.md § Fonts.
   ═══════════════════════════════════════════════════════════════════════════ */

:root{
  /* ── Type ───────────────────────────────────────────────────────────── */
  --face-display:'Instrument Serif', Georgia, serif;
  --face-text:'Archivo', system-ui, -apple-system, sans-serif;
  --face-code:'Spline Sans Mono', ui-monospace, SFMono-Regular, Menlo, monospace;

  /* 1.25 modular scale off a 17px base. Type is judged comparatively, so a
     slow ratio works here. Spacing uses a faster one — see below. */
  --t-xs:.68rem; --t-sm:.85rem; --t-base:1.0625rem; --t-md:1.328rem;
  --t-lg:1.66rem; --t-xl:2.075rem; --t-2xl:2.594rem; --t-3xl:3.243rem;
  --t-4xl:4.05rem;

  /* ── Rhythm ─────────────────────────────────────────────────────────
     Body is 17px on a 30px baseline, so one line is one unit. Every value
     is a fraction or a multiple of it, and every one is a whole pixel.

       RULE · space BETWEEN text blocks uses whole baselines (30/60/90)
            · padding INSIDE a component uses the fractions (6–24)          */
  --baseline:30px;
  --lh-body:1.765;                      /* = 30px at the 17px base */
  --s1:6px;  --s2:12px; --s3:18px; --s4:24px;
  --s5:30px; --s6:45px; --s7:60px; --s8:90px;
  --s9:135px;                           /* 4.5 baselines - page-level movement */

  /* ── Density ────────────────────────────────────────────────────────
     One ladder is a tell: a page whose every gap is the same four numbers
     reads as extruded, however tidy those numbers are. Space carries
     information only when its size tracks the size of the break. Three
     densities, chosen by what the section CONTAINS, not for variety:

       .sec--tight  dense and technical - spec tables, parameter lists
       .sec         the default
       .sec--open   one idea alone - a hero, a pull quote, a single figure

     Sections step 60 / 90 / 135 (2 / 3 / 4.5 baselines); the break inside
     them steps 30 / 45 / 60 (1 / 1.5 / 2). The paragraph gap is NOT in the
     ladder - body rhythm is one baseline in every mode, always.           */
  --sec-gap:var(--s8);
  --blk:var(--s6);

  /* The welded pair. An eyebrow belongs to its title, so its gap is set in
     em of the TITLE and scales with the clamp instead of drifting loose at
     display sizes. Only meaningful where trim is applied - see LINE BOX.   */
  --lock:.3em;

  /* ── Geometry ───────────────────────────────────────────────────────
     A two-step shape scale (adopted 2026-08-12). Containers hold the
     house 14px; standalone controls sit a step tighter at 8px so the
     page is not one uniform soft blob. All four corners, always. */
  --r-lg:14px;                          /* cards, tables, notes, panels */
  --r-ctl:8px;                          /* buttons, inputs, toggles     */
  --r-xs:4px;                           /* inline code, chips           */
  --hair:1px;                           /* one border weight, everywhere */

  --ease:cubic-bezier(.2,.7,.2,1);
  --ease-out:cubic-bezier(.16,1,.3,1);

  /* Two reveal durations, so motion encodes weight instead of decorating
     uniformly. Leads are section heads; subs are cards and grids. */
  --dur-lead:.7s;
  --dur-sub:.5s;

  /* ── The blue ladder ────────────────────────────────────────────────
     Hue 245.6°, seeded on #33A9FF at step 50. NEVER introduce another blue
     and never hand-pick a step: use the named token for the job.          */
  --blue-05:#edf6ff; --blue-10:#d8ecff; --blue-20:#b0daff; --blue-30:#81c5ff;
  --blue-40:#5fb7ff; --blue-50:#33a9ff; --blue-60:#0089d9; --blue-70:#0077bd;
  --blue-80:#005990; --blue-90:#004470; --blue-95:#002e4d;
}

/* ── LIGHT — the default. Warm ground, cool accent. All neutrals sit at
      hue 65.6, the blue ladder's exact complement. ────────────────────── */
html.light{
  --paper:#fcf9f5; --paper-2:#f6f2ed; --wash:#ebe6e1;
  --rule-c:31,27,22;                    /* borders = rgba(var(--rule-c), a) */
  --graphite:#767069;                   /*  4.67:1 — muted text            */
  --ink-soft:#534d48;                   /*  7.86:1 — body                  */
  --ink:#1f1b16;                        /* 16.28:1 — headings              */

  --mark:var(--blue-70);                /*  4.57:1 — links, emphasis       */
  --mark-deep:var(--blue-80);           /*  7.05:1 — heavier emphasis      */
  --mark-solid:var(--blue-50);          /* the wordmark blue: FILL ONLY    */
  --mark-tint:var(--blue-05);
  --fig:var(--blue-60);                 /*  3.58:1 — display figures only  */
  --fig-inline:var(--blue-70);          /*  4.57:1 — figures in text       */

  --risk:#bc5146; --good:#17843f;       /* semantics — see § Semantics     */

  --card:rgba(255,254,252,.72);
  --card-hover:rgba(255,255,254,.9);
  --sheen:255,255,255;
  /* Cards carry NO shadow at rest (2026-08-12) — hairline only, elevation on
     hover. `--shadow` is therefore reserved for things that genuinely float
     above the page and are not cards: popovers, dropdowns, sticky bars.
     Never hand-roll a box-shadow; use one of these two. */
  --shadow:0 1px 2px rgba(44,32,21,.05), 0 10px 26px -14px rgba(44,32,21,.16);
  --shadow-lift:0 2px 4px rgba(44,32,21,.06), 0 26px 54px -20px rgba(44,32,21,.30);
  --halo-1:rgba(51,169,255,.10); --halo-2:rgba(189,183,174,.11);
  --grain-op:.26; --grain-blend:multiply;
  color-scheme:light;
}

/* ── DARK — co-equal, same complement hue so the family holds. ────────── */
html.dark{
  --paper:#120f0c; --paper-2:#1b1814; --wash:#28241f;
  --rule-c:233,230,225;
  --graphite:#96918c;                   /*  6.12:1 */
  --ink-soft:#eae6e1;                   /* 15.35:1 */
  --ink:#f9f6f3;                        /* 17.74:1 */

  --mark:var(--blue-30);                /* 10.34:1 */
  --mark-deep:var(--blue-20);
  --mark-solid:var(--blue-50);          /*  7.51:1 — readable as TEXT here */
  --mark-tint:var(--blue-95);
  --fig:var(--blue-40);                 /*  8.83:1 */
  --fig-inline:var(--blue-30);          /* 10.34:1 */

  --risk:#c65a4f; --good:#319751;

  --card:rgba(233,230,225,.05);
  --card-hover:rgba(233,230,225,.08);
  --sheen:255,255,255;
  --shadow:0 1px 2px rgba(0,0,0,.4), 0 12px 30px -16px rgba(0,0,0,.7);
  --shadow-lift:0 2px 6px rgba(0,0,0,.5), 0 30px 60px -22px rgba(0,0,0,.9);
  --halo-1:rgba(51,169,255,.15); --halo-2:rgba(189,183,174,.07);
  --grain-op:.19; --grain-blend:screen;
  color-scheme:dark;
}

/* ═══ BASE ═══════════════════════════════════════════════════════════════ */
*{box-sizing:border-box}
html{scroll-behavior:smooth}
body{margin:0;background:var(--paper);color:var(--ink-soft);
  font-family:var(--face-text);font-size:var(--t-base);line-height:var(--lh-body);
  -webkit-font-smoothing:antialiased;overflow-x:hidden;
  transition:background .5s var(--ease),color .5s var(--ease)}
h1,h2,h3,h4,p,ul,ol,figure,blockquote,dl,dd{margin:0}
ul{padding:0;list-style:none}
img{max-width:100%;height:auto}
a{color:var(--mark);text-underline-offset:3px;text-decoration-thickness:1px}
a:focus-visible,button:focus-visible,[tabindex]:focus-visible{
  outline:2px solid var(--mark);outline-offset:3px;border-radius:2px}
strong{color:var(--ink);font-weight:600}
code{font-family:var(--face-code);font-size:.86em;color:var(--ink);
  background:rgba(var(--rule-c),.06);border:var(--hair) solid rgba(var(--rule-c),.1);
  border-radius:var(--r-xs);padding:.08em .34em}

/* ═══ ATMOSPHERE — exactly two soft halos and a grain. Never a grid overlay,
      never a glow orb of ANY edge treatment, never an aurora or mesh field.
      Two halos is the entire atmospheric budget. ═══════════════════════════ */
.atmos{position:fixed;inset:0;z-index:0;pointer-events:none;overflow:hidden}
.atmos::before,.atmos::after{content:'';position:absolute;border-radius:50%;filter:blur(150px)}
.atmos::before{width:70vw;height:70vw;top:-32vw;right:-18vw;background:var(--halo-1)}
.atmos::after{width:60vw;height:60vw;bottom:-28vw;left:-16vw;background:var(--halo-2)}

/* Grain sits ABOVE everything, including the cards. Underneath, every card
   would erase it and the two would visibly fight. Over the top it behaves
   like film grain and unifies the surface instead. */
.grain{position:fixed;inset:0;z-index:9;pointer-events:none;
  opacity:var(--grain-op);mix-blend-mode:var(--grain-blend);
  background-image:url("data:image/svg+xml,<svg%20xmlns='http://www.w3.org/2000/svg'%20width='180'%20height='180'><filter%20id='g'><feTurbulence%20type='fractalNoise'%20baseFrequency='0.8'%20numOctaves='4'%20stitchTiles='stitch'/><feColorMatrix%20type='saturate'%20values='0'/></filter><rect%20width='180'%20height='180'%20filter='url(%23g)'/></svg>");
  background-size:180px 180px}

/* ═══ LAYOUT — a centered max-width column. Locked. ═══════════════════════ */
.wrap{position:relative;z-index:1;max-width:1000px;margin:0 auto;
  padding:var(--s6) var(--s6) var(--s8)}

/* ═══ MASTHEAD ═══════════════════════════════════════════════════════════ */
/* Folio: the running head. A record book knows which page it is. */
.folio{display:flex;justify-content:space-between;align-items:baseline;gap:var(--s3);
  padding-bottom:var(--s2);margin-bottom:var(--s6);
  border-bottom:var(--hair) solid rgba(var(--rule-c),.16);
  font-family:var(--face-display);font-size:.95rem;color:var(--graphite)}

.masthead{display:flex;justify-content:space-between;align-items:flex-start;
  gap:var(--s4);margin-bottom:var(--s6)}
/* The real wordmark, embedded base64, top-left of EVERY document. */
.logo{height:30px;width:auto;display:block}
.logo-dark{display:none}
html.dark .logo-light{display:none}
html.dark .logo-dark{display:block}

.toggle{font-family:var(--face-text);font-size:var(--t-xs);font-weight:600;
  letter-spacing:.08em;text-transform:uppercase;color:var(--graphite);
  background:transparent;border:var(--hair) solid rgba(var(--rule-c),.2);
  border-radius:var(--r-ctl);padding:0 var(--s3);min-height:44px;cursor:pointer;
  transition:.25s var(--ease)}
.toggle:hover{color:var(--ink);border-color:rgba(var(--rule-c),.4)}

.doc-title{font-family:var(--face-display);font-weight:400;color:var(--ink);
  font-size:clamp(2.8rem,7vw,var(--t-4xl));line-height:1;letter-spacing:-.02em;
  text-wrap:balance;margin-bottom:var(--s3)}
.doc-title em{font-style:italic;color:var(--mark)}
.standfirst{font-size:var(--t-md);line-height:1.5;color:var(--ink-soft);max-width:48ch}

/* Byline / metadata row */
.byline{display:flex;flex-wrap:wrap;gap:var(--s2) var(--s6);margin-top:var(--s4);
  padding-top:var(--s3);border-top:var(--hair) solid rgba(var(--rule-c),.14)}
.byline dt{font-family:var(--face-display);font-style:italic;font-size:.95rem;
  color:var(--graphite);margin-bottom:2px}
.byline dd{margin:0;color:var(--ink);font-weight:500;font-size:var(--t-sm)}

/* ═══ SECTIONS ═══════════════════════════════════════════════════════════
   The eyebrow carries the section's KIND; the numeral carries its POSITION.
   Two pieces of information, neither repeating the other. If an eyebrow
   would only restate the title, leave it out. ════════════════════════════ */
.sec{margin-top:var(--sec-gap);scroll-margin-top:var(--s4)}
.sec--tight{--sec-gap:var(--s7);--blk:var(--s5)}
.sec--open {--sec-gap:var(--s9);--blk:var(--s7)}
.eyebrow{display:flex;align-items:center;gap:var(--s2);margin-bottom:var(--s1);
  font-family:var(--face-display);font-style:italic;font-size:1rem;
  letter-spacing:0;text-transform:none;color:var(--graphite);font-weight:400}
.eyebrow::before{content:'';height:1px;width:26px;flex:none;
  background:currentColor;opacity:.45}
.sec-head{display:flex;align-items:baseline;gap:var(--s3);margin-bottom:var(--s4);
  font-size:clamp(1.9rem,4vw,var(--t-2xl))}
.sec-n{font-family:var(--face-display);font-size:var(--t-xl);color:var(--fig);
  line-height:1;flex:none;font-variant-numeric:lining-nums}
.sec-t{font-family:var(--face-display);font-weight:400;color:var(--ink);
  font-size:inherit;line-height:1.1;
  letter-spacing:-.015em;text-wrap:balance}
.lede{font-size:var(--t-md);line-height:1.55;color:var(--ink-soft);
  max-width:58ch;margin-bottom:var(--s4)}
p{max-width:64ch;margin-bottom:var(--s3)}
p:last-child{margin-bottom:0}

/* === LINE BOX - trim the leading so a gap means what it says =============
   Every text element ships with half-leading above the caps and below the
   baseline. It is invisible, it belongs to no spacing token, and it scales
   with font-size - so one 24px token renders near 32px under a 42px title
   and near 30px under body copy. The ladder drifts even though the numbers
   are clean, and it drifts the same way on every generated page on the web,
   which is a large part of why they all sit alike.

   Trimming deletes it. The box becomes the letters, the tokens become real
   optical space, and the gaps can then be tuned to carry information:

     eyebrow -> title   .3em   welded, scales with the title's clamp
     title   -> lede    24px   grouped, one explains the other
     lede    -> body    45px   a real break (--blk, moves with density)
     p       -> p       30px   one baseline, invariant in every mode

   The retuned values sit INSIDE @supports on purpose. Where trim is missing
   the page keeps today's 24/24/18, which already lands near this rhythm by
   way of the leading it still carries. Nothing regresses; the ladder just
   stops drifting wherever the browser can hold it still.

   Never add a flex or grid container to this list. Trim applies to block
   containers, and .eyebrow / .sec-head are flex - the declaration is silently
   inert on them. Trim the text child instead, which is what .sec-t does.
   ====================================================================== */
@supports (text-box: trim-both cap alphabetic){
  .doc-title,.standfirst,.sec-t,.lede,p,.card-h,.card p,.quote{
    text-box:trim-both cap alphabetic}

  .eyebrow{margin-bottom:0}
  .eyebrow + .sec-head{margin-top:var(--lock)}

  .doc-title{margin-bottom:var(--s4)}
  .lede{margin-bottom:var(--blk)}
  p{margin-bottom:var(--s5)}
  p:last-child{margin-bottom:0}
  .card p:last-child{margin-bottom:0}
}

/* ═══ FIGURES — the signature. Serif, blue, tabular, aligned. ════════════ */
.fig-inline{font-family:var(--face-display);font-size:1.15em;color:var(--fig-inline);
  font-variant-numeric:tabular-nums lining-nums}

/* ═══ THE CARD — the container, documents and website alike ══════════════
   Two hover layers:
     1 · lift + shadow bloom — it becomes physically nearer
     2 · specular sheen tracks the pointer — expensive materials catch light
   A third layer (a blue rule wiping across the top) was tried and removed:
   with the sheen already carrying the accent it read as one signal too many.
   The sheen needs the pointermove handler in the starter scaffold. ═══════ */
.card{position:relative;overflow:hidden;isolation:isolate;
  background:var(--card);border:var(--hair) solid rgba(var(--rule-c),.14);
  border-radius:var(--r-lg);padding:var(--s4);
  backdrop-filter:blur(16px) saturate(1.25);-webkit-backdrop-filter:blur(16px) saturate(1.25);
  transition:transform .45s var(--ease-out), box-shadow .45s var(--ease-out),
             border-color .45s var(--ease), background-color .45s var(--ease);
  will-change:transform}
.card::after{content:'';position:absolute;inset:0;z-index:1;pointer-events:none;opacity:0;
  background:radial-gradient(320px circle at var(--mx,50%) var(--my,0%),
    rgba(var(--sheen),.20), rgba(var(--sheen),0) 62%);
  transition:opacity .4s var(--ease)}
.card:hover,.card:focus-within{transform:translateY(-3px);box-shadow:var(--shadow-lift);
  border-color:rgba(var(--rule-c),.24);background:var(--card-hover)}
.card:hover::after,.card:focus-within::after{opacity:1}
.card > *{position:relative;z-index:3}
.card-h{font-family:var(--face-text);font-size:var(--t-base);font-weight:600;
  color:var(--ink);margin-bottom:var(--s2)}
.card p{font-size:var(--t-sm);line-height:1.6;color:var(--ink-soft);max-width:none}

/* Card grids */
.grid{display:grid;gap:var(--s3);margin:var(--s4) 0}
.g2{grid-template-columns:repeat(auto-fit,minmax(250px,1fr))}
.g3{grid-template-columns:repeat(auto-fit,minmax(200px,1fr))}

/* Stat card — figure hangs large, hairline, then the label. Number is hero. */
.card-stat .stat-fig{font-family:var(--face-display);font-size:var(--t-3xl);
  color:var(--fig);line-height:.9;letter-spacing:-.01em;display:block;
  font-variant-numeric:tabular-nums lining-nums}
.card-stat .stat-unit{font-family:var(--face-text);font-size:var(--t-xs);
  color:var(--graphite);letter-spacing:.08em;text-transform:uppercase;margin-left:5px}
.card-stat .stat-rule{height:1px;background:rgba(var(--rule-c),.16);margin:var(--s2) 0}
.card-stat .stat-l{font-size:var(--t-sm);color:var(--ink);font-weight:500;display:block}
.card-stat .stat-d{font-size:var(--t-sm);color:var(--graphite);line-height:1.5;
  margin-top:2px;display:block}

/* Row card — label left, figure right. The ledger row, boxed. */
.card-row{display:grid;grid-template-columns:1fr auto;align-items:center;gap:var(--s3)}
.card-row .row-fig{font-family:var(--face-display);font-size:var(--t-xl);color:var(--fig);
  font-variant-numeric:tabular-nums lining-nums;text-align:right;line-height:1}

/* Total card — the DOUBLE RULE. A ledger never closes a column with one
   line, and no framework ships this. Use it only above a genuine total. */
.card-total .mini{display:grid;grid-template-columns:1fr auto;gap:var(--s3);
  font-size:var(--t-sm);padding:5px 0;color:var(--ink-soft)}
.card-total .mini span:last-child{font-family:var(--face-display);color:var(--fig-inline);
  font-size:1.15em;font-variant-numeric:tabular-nums lining-nums}
.card-total .total-line{position:relative;margin-top:var(--s3);padding-top:var(--s3);
  border-top:var(--hair) solid rgba(var(--rule-c),.45);
  display:grid;grid-template-columns:1fr auto;align-items:baseline;gap:var(--s3)}
.card-total .total-line::before{content:'';position:absolute;left:0;right:0;top:-4px;
  border-top:var(--hair) solid rgba(var(--rule-c),.45)}
.card-total .total-l{font-weight:600;color:var(--ink);font-size:var(--t-sm)}
.card-total .total-fig{font-family:var(--face-display);font-size:var(--t-xl);color:var(--fig);
  font-variant-numeric:tabular-nums lining-nums;line-height:1}

/* Feature card — the website shape. The arrow travels with the card. */
.card-link{display:inline-flex;align-items:center;gap:6px;margin-top:var(--s1);
  min-height:44px;font-size:var(--t-sm);font-weight:600;color:var(--mark);
  text-decoration:none}
.card-link .arrow{transition:transform .45s var(--ease-out)}
.card:hover .card-link .arrow{transform:translateX(4px)}

/* Tag — a small italic qualifier above a card title (status, priority). */
.tag{display:inline-block;font-family:var(--face-display);font-style:italic;
  font-size:.9rem;color:var(--graphite);margin-bottom:var(--s1)}

/* Points list — the workhorse inside cards. A short rule, never a bullet. */
.pts{display:flex;flex-direction:column;gap:var(--s1);margin-top:var(--s2)}
.pts li{position:relative;padding-left:var(--s3);font-size:var(--t-sm);
  line-height:1.55;color:var(--ink-soft)}
.pts li::before{content:'';position:absolute;left:0;top:.62em;width:6px;height:1px;
  background:var(--mark);opacity:.75}

/* ═══ TABLE — in a card-like container, figures right and tabular ════════ */
.tw{overflow-x:auto;border:var(--hair) solid rgba(var(--rule-c),.14);
  border-radius:var(--r-lg);margin:var(--s4) 0;background:var(--card);
  backdrop-filter:blur(16px) saturate(1.25);-webkit-backdrop-filter:blur(16px) saturate(1.25)}
table{width:100%;border-collapse:collapse;font-size:var(--t-sm);
  font-variant-numeric:tabular-nums lining-nums}
table th{text-align:left;font-family:var(--face-text);font-size:var(--t-xs);font-weight:600;
  letter-spacing:.09em;text-transform:uppercase;color:var(--graphite);
  padding:var(--s2) var(--s3);white-space:nowrap;
  border-bottom:var(--hair) solid rgba(var(--rule-c),.3)}
table td{padding:var(--s2) var(--s3);vertical-align:top;line-height:1.55;
  border-bottom:var(--hair) solid rgba(var(--rule-c),.09)}
table tr:last-child td{border-bottom:none}
table td:first-child{color:var(--ink)}
th.n,td.n{text-align:right}
.num{font-family:var(--face-display);color:var(--fig-inline);font-size:1.15em;
  font-variant-numeric:tabular-nums lining-nums}

/* ═══ NOTE — the callout. Accent by default. ═════════════════════════════
   SEMANTICS: only two, risk and good. There is deliberately no amber
   "warning" — amber sits at hue ~70 and collides with the warm ground at
   75, which is exactly the mistake the retired brass accent made. Anything
   that would have been a warning is either a risk or a plain note. ═══════ */
.note{border-left:2px solid var(--mark);padding:var(--s1) 0 var(--s1) var(--s3);
  margin:var(--s5) 0;max-width:62ch}
.note-l{font-family:var(--face-display);font-style:italic;font-size:1rem;
  color:var(--mark);margin-bottom:2px}
.note--risk{border-left-color:var(--risk)}
.note--risk .note-l{color:var(--risk)}
.note--good{border-left-color:var(--good)}
.note--good .note-l{color:var(--good)}

/* ═══ PULL-QUOTE ═════════════════════════════════════════════════════════ */
.quote{font-family:var(--face-display);font-style:italic;font-size:var(--t-lg);
  line-height:1.32;color:var(--ink);max-width:28ch;margin:var(--s7) 0;
  padding-left:var(--s4);border-left:var(--hair) solid rgba(var(--rule-c),.22)}

/* ═══ COLOR RAMP — for design docs that show the ladder ═════════════════ */
.ramp{display:flex;border-radius:var(--r-ctl);overflow:hidden;
  border:var(--hair) solid rgba(var(--rule-c),.14);margin-top:var(--s2)}
.ramp span{flex:1;height:52px;display:block}
.ramp-l{display:flex;justify-content:space-between;font-family:var(--face-code);
  font-size:var(--t-xs);color:var(--graphite);margin-top:6px}

/* ═══ FOOT ═══════════════════════════════════════════════════════════════ */
.foot{margin-top:var(--s8);padding-top:var(--s3);
  border-top:var(--hair) solid rgba(var(--rule-c),.16);
  font-family:var(--face-display);font-size:.95rem;color:var(--graphite);
  display:flex;justify-content:space-between;flex-wrap:wrap;gap:var(--s2)}

/* ═══ MOTION ═════════════════════════════════════════════════════════════
   Scroll reveal. The starter's script reveals everything immediately if
   IntersectionObserver is missing, the tab is hidden, or reduced-motion is
   set — content must NEVER depend on a frame that may not arrive.

   TWO DURATIONS, BY WEIGHT (adopted 2026-08-12). One uniform reveal on
   everything is decoration; varying it by importance makes motion mean
   something. `.rise` is the lead — section heads and anything that opens a
   block. `.rise-sub` is the follower — cards, grids, tables — and travels a
   shorter distance in less time. Small elements get no reveal at all.
   Do NOT add a third duration. ══════════════════════════════════════════ */
.rise{opacity:0;transform:translateY(18px);
  transition:opacity var(--dur-lead) var(--ease-out),transform var(--dur-lead) var(--ease-out)}
.rise-sub{opacity:0;transform:translateY(10px);
  transition:opacity var(--dur-sub) var(--ease-out),transform var(--dur-sub) var(--ease-out)}
.rise.in,.rise-sub.in,.no-motion .rise,.no-motion .rise-sub{opacity:1;transform:none}

@media (prefers-reduced-motion: reduce){
  html{scroll-behavior:auto}
  *{transition:none!important;animation:none!important}
  .rise,.rise-sub{opacity:1;transform:none}
  .card:hover{transform:none;box-shadow:var(--shadow-lift)}
  .card::after{display:none}
}
/* Touch: no pointer to track, and a hover state would simply stick. */
@media (hover:none){
  .card::after{display:none}
  .card:hover{transform:none;box-shadow:var(--shadow-lift)}
}

/* ═══ RESPONSIVE ═════════════════════════════════════════════════════════ */
@media (max-width:820px){
  .wrap{padding:var(--s5) var(--s4) var(--s7)}
  /* Compress the ladder by one step; do NOT flatten it to a single value.
     This block used to hardcode `.sec{margin-top:var(--s7)}`, which erased
     the density system on every phone and left one gap everywhere - the
     exact sameness the rhythm section exists to avoid. Retune the tokens
     instead, and keep --blk at or above one baseline in every mode so the
     block break never falls below the paragraph gap. */
  :root       {--sec-gap:var(--s7);--blk:var(--s5)}
  .sec--tight {--sec-gap:var(--s6);--blk:var(--s5)}
  .sec--open  {--sec-gap:var(--s8);--blk:var(--s6)}
}
@media (max-width:560px){
  .wrap{padding:var(--s4) var(--s3) var(--s6)}
  .masthead{flex-wrap:wrap}
  .logo{height:24px}            /* the wordmark is ~11:1; 30px overflows 375 */
  .folio{flex-wrap:wrap;gap:4px}
  table{min-width:460px}
}

/* ═══ PRINT ══════════════════════════════════════════════════════════════ */
@media print{
  .atmos,.grain,.toggle{display:none!important}
  .rise{opacity:1!important;transform:none!important}
  body{background:#fff}
  .card,.tw{box-shadow:none;background:#fff;backdrop-filter:none;break-inside:avoid}
  .sec{break-inside:avoid-page}
}
