/* ═══════════════════════════════════════════════════════════════════════
   Hominix — brand book, presentation layer
   Consumes ../tokens/hominix.tokens.css. Nothing here invents a value the
   token file doesn't already own; it only maps brand tokens onto page roles
   and sets the rhythm — light technical sheets punctuated by Void chapters.
   ═══════════════════════════════════════════════════════════════════════ */

:root{
  --bg:var(--hx-bg); --bg-r:var(--hx-bg-raised);
  --fg:var(--hx-fg); --fg-m:var(--hx-fg-muted); --fg-s:var(--hx-fg-subtle);
  --rule:var(--hx-rule); --rule-2:var(--hx-rule-strong);
  --acc:var(--hx-accent); --res:var(--hx-reserve);
  --tint:color-mix(in srgb, var(--acc) 8%, transparent);

  --sans:var(--hx-font-display);
  --mono:var(--hx-font-mono);

  /* Body steps stay at the token value — they are already readable at 320px.
     The five display steps are fluid: they hit the token value at 1440 and a
     floor at 320 that keeps every one of them under 12% of the viewport
     width. Fixed display px is what made the Φ.09 specimen render a 110px
     word inside a 323px column and break "Hominix" across two lines. This
     replaces per-breakpoint overrides entirely — there are none. */
  --t-2:var(--hx-text--2); --t-1:var(--hx-text--1); --t0:var(--hx-text-0);
  --t1:var(--hx-text-1);  --t2:var(--hx-text-2);  --t3:var(--hx-text-3);
  --t4:clamp(22px, 1.79vw + 16.3px,  42px);
  --t5:clamp(25px, 2.50vw + 17.0px,  53px);
  --t6:clamp(29px, 3.48vw + 17.9px,  68px);
  --t7:clamp(33px, 4.73vw + 17.9px,  86px);
  --t8:clamp(38px, 6.43vw + 17.4px, 110px);

  --s1:var(--hx-space-1); --s2:var(--hx-space-2); --s3:var(--hx-space-3);
  --s4:var(--hx-space-4); --s5:var(--hx-space-5); --s6:var(--hx-space-6);
  --s7:var(--hx-space-7); --s8:var(--hx-space-8); --s9:var(--hx-space-9);

  --d1:var(--hx-dur-1); --d2:var(--hx-dur-2); --d3:var(--hx-dur-3); --d4:var(--hx-dur-4);
  --ez:var(--hx-ease);

  --rail-w:240px;   /* fits the longest two-line label without wrapping */
  /* Document chrome only, never a brand surface. Same lightness as Vellum,
     hue rotated to the warm side, so rail and page separate by temperature
     rather than by brightness. Every text colour keeps its contrast on it. */
  --chrome:#F0EDE5;
  --pad:var(--s7);
  --measure:66ch;
}
@media (max-width:1180px){ :root{ --pad:var(--s5) } }
@media (prefers-color-scheme:dark){ :root{ --chrome:#191711 } }
:root[data-theme="dark"]{ --chrome:#191711 }
:root[data-theme="light"]{ --chrome:#F0EDE5 }

*{box-sizing:border-box}
/* the artifact host resets this; the standalone file must too, or the rail
   sits 8px off the left edge only when opened directly */
html,body{margin:0;padding:0}
/* overflow-x:clip (không phải hidden) chặn kéo ngang mà vẫn giữ position:sticky */
html{overflow-x:clip}
body{overflow-x:clip;overscroll-behavior-x:none}

.hx{
  background:var(--bg); color:var(--fg-m);
  font:var(--t0)/1.618 var(--sans);
  -webkit-font-smoothing:antialiased;
}
.hx :focus-visible{outline:2px solid var(--acc);outline-offset:3px}

/* Void chapters re-point the semantic tokens; components never know. */
.on-void{
  --bg:var(--hx-void); --bg-r:var(--hx-ink);
  --fg:var(--hx-vellum); --fg-m:var(--hx-ash); --fg-s:var(--hx-steel);
  --rule:#252A31; --rule-2:var(--hx-graphite);
  --acc:var(--hx-signal-lift); --res:var(--hx-ratio-lift);
  --chrome:#191711;
  background:var(--hx-void); color:var(--fg-m);
}

/* clip-based hiding: -9999px offsets push real boxes outside the viewport
   and let touch devices rubber-band sideways */
.skip{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);
  white-space:nowrap;background:var(--acc);color:#fff;
  padding:var(--s3) var(--s4);font:600 var(--t-1)/1 var(--mono);z-index:99}
.skip:focus{position:fixed;width:auto;height:auto;clip-path:none;left:var(--s4);top:var(--s4)}

/* ── type utilities ────────────────────────────────────────────────── */
.m{font-family:var(--mono);font-variant-numeric:tabular-nums}
/* Vietnamese stacks its diacritics above the cap line. line-height:1 gives
   them nowhere to go, so the moment a label wraps the marks on the second
   line collide with the first. Every label that can wrap gets 1.45. */
.lab{font:500 var(--t-2)/1.45 var(--mono);letter-spacing:.14em;text-transform:uppercase;
  color:var(--fg-s);font-variant-numeric:tabular-nums}
.lab--acc{color:var(--acc)}
.hx p{margin:0;max-width:var(--measure)}
.hx h3{font:500 var(--t1)/1.3 var(--sans);letter-spacing:-.012em;color:var(--fg);margin:0}
.hx strong{color:var(--fg);font-weight:600}
.hx em{font-style:italic;color:var(--fg)}
.lead{font:400 var(--t2)/1.34 var(--sans);letter-spacing:-.016em;color:var(--fg);
  max-width:24ch;text-wrap:balance}
.body-lead{font-size:var(--t1);line-height:1.5;color:var(--fg);letter-spacing:-.008em;max-width:56ch}
.xref{color:var(--acc);text-decoration:none;font-family:var(--mono);font-size:.92em;
  white-space:nowrap;border-bottom:1px solid color-mix(in srgb,var(--acc) 40%,transparent)}
.xref:hover{border-bottom-color:var(--acc)}

/* ── shell ─────────────────────────────────────────────────────────── */
.shell{display:flex;align-items:flex-start}
.doc{flex:1 1 auto;min-width:0;position:relative}
.wrap{max-width:1180px;margin-inline:auto;padding-inline:var(--pad)}

/* ── rail ──────────────────────────────────────────────────────────── */
.rail{
  position:sticky;top:0;flex:0 0 var(--rail-w);width:var(--rail-w);height:100vh;
  border-right:1px solid var(--rule);padding:var(--s6) 0 var(--s5) var(--s4);
  display:flex;flex-direction:column;gap:var(--s5);background:var(--chrome);z-index:20;
  transition:background var(--d3) var(--ez),border-color var(--d3) var(--ez);
}
/* the real horizontal lockup from Φ.05, not a hand-assembled pair — the old
   version bottom-aligned the word to the axis foot instead of centring it on
   the circle, and its cap height was nowhere near D/Φ² */
.rail__mk{display:block;color:var(--fg);text-decoration:none;padding-right:var(--s4)}
.rail__mk svg{height:38px;width:auto;display:block}
.rail__nav{display:flex;flex-direction:column;gap:1px;overflow-y:auto;flex:1;padding-right:var(--s4)}
.rail__a{
  display:grid;grid-template-columns:44px 1fr;gap:var(--s3);
  padding:var(--s2) var(--s2) var(--s2) var(--s3);text-decoration:none;color:var(--fg-s);
  border-left:2px solid transparent;
  transition:color var(--d1) var(--ez),border-color var(--d1) var(--ez);
}
.rail__a span:first-child{font:400 var(--t-2)/1 var(--mono);letter-spacing:.06em;
  font-variant-numeric:tabular-nums;padding-top:4px}
.rail__a b{display:block;font:400 var(--t-1)/1.25 var(--sans);letter-spacing:-.004em}
.rail__a i{display:block;font:400 var(--t-2)/1.3 var(--mono);font-style:normal;
  letter-spacing:.1em;text-transform:uppercase;color:var(--fg-s);opacity:.72;margin-top:2px}
.rail__a[aria-current="true"] i{opacity:1;color:var(--acc)}
.rail__a:hover{color:var(--fg)}
.rail__a[aria-current="true"]{color:var(--fg);border-left-color:var(--acc)}
.rail__a[aria-current="true"] span:first-child{color:var(--acc)}
.rail__ft{font:400 var(--t-2)/1.5 var(--mono);color:var(--fg-s);padding-right:var(--s4)}

/* ── sheets ────────────────────────────────────────────────────────── */
.sheet{position:relative;padding-block:var(--s8);scroll-margin-top:0}
.sheet--void{padding-block:var(--s9)}
.sheet--tight{padding-block:var(--s7)}

.sh__hd{display:flex;align-items:baseline;gap:var(--s4);flex-wrap:wrap;
  border-top:1.5px solid var(--fg);padding-top:var(--s3);margin-bottom:var(--s6)}
.sh__no{font:500 var(--t-1)/1 var(--mono);letter-spacing:.1em;color:var(--acc);
  font-variant-numeric:tabular-nums}
.sh__ti{font:500 var(--t3)/1.25 var(--sans);letter-spacing:-.018em;color:var(--fg);
  margin:0;text-wrap:balance}
.sh__en{font:400 var(--t-1)/1.4 var(--mono);color:var(--fg-s);margin-left:auto;
  text-align:right;max-width:34ch}

/* content column against a narrower notes column */
.split{display:grid;grid-template-columns:10fr 6fr;gap:var(--s7);align-items:start}
@media (max-width:980px){ .split{grid-template-columns:1fr;gap:var(--s6)} }
.col{min-width:0;display:flex;flex-direction:column;gap:var(--s5)}
.mg{min-width:0;display:flex;flex-direction:column;gap:var(--s5);
  border-top:1px solid var(--rule);padding-top:var(--s4)}
.mg p{margin:0;font-size:var(--t-1);line-height:1.6;color:var(--fg-s);max-width:none}
.mg .lab{margin-bottom:var(--s2);display:block}

/* ── hero ──────────────────────────────────────────────────────────── */
.hero{position:relative;height:100svh;min-height:600px;overflow:hidden;
  display:flex;flex-direction:column;justify-content:space-between}
.hero canvas{position:absolute;inset:0;width:100%;height:100%;display:block;z-index:0}
.hero__fb{position:absolute;inset:0;display:none;align-items:center;justify-content:center;z-index:0}
.hero.failed .hero__fb{display:flex}
.hero.failed canvas{display:none}
.hero__fb svg{width:min(28vw,190px);height:auto;color:var(--hx-vellum)}
.hero > .wrap{position:relative;z-index:2;width:100%}
.hero__top{padding-top:var(--s6)}
.hero__btm{padding-bottom:var(--s7)}
.hero h1{font:500 clamp(34px,10.4vw,164px)/.94 var(--sans);letter-spacing:-.042em;
  color:var(--hx-vellum);margin:0}
.hero__claim{display:flex;align-items:flex-end;justify-content:space-between;
  gap:var(--s6);flex-wrap:wrap;margin-top:var(--s5)}
.hero__claim p{font:400 var(--t1)/1.4 var(--sans);color:var(--hx-ash);
  letter-spacing:-.008em;max-width:34ch}
.hero__scroll{font:500 var(--t-2)/1 var(--mono);letter-spacing:.14em;text-transform:uppercase;
  color:var(--hx-steel);display:flex;align-items:center;gap:var(--s3);white-space:nowrap}
.hero__scroll i{display:block;width:42px;height:1px;background:currentColor;
  transform-origin:left;animation:sweep 2.6s var(--ez) infinite}
@keyframes sweep{0%,100%{transform:scaleX(.25)}50%{transform:scaleX(1)}}

@media (min-width:980px){
  .hero h1{max-width:58%}
  .hero__claim p{max-width:min(34ch,50%)}
  .hero .titleblock{max-width:60%}
}

.titleblock{display:grid;grid-template-columns:repeat(5,1fr);gap:var(--s4);
  border-block:1px solid var(--rule);padding-block:var(--s3)}
.titleblock div{display:flex;flex-direction:column;gap:var(--s1)}
.titleblock b{font:500 var(--t-1)/1.3 var(--mono);color:var(--fg);
  font-variant-numeric:tabular-nums;letter-spacing:.02em}
.titleblock--4{grid-template-columns:repeat(4,1fr)}
@media (max-width:760px){ .titleblock{grid-template-columns:repeat(2,1fr);gap:var(--s3)} }

/* ── datum marquee ─────────────────────────────────────────────────── */
.marquee{border-block:1px solid var(--rule);overflow:hidden;padding-block:var(--s3);
  display:flex;white-space:nowrap;user-select:none;contain:inline-size}
.marquee span{font:400 var(--t-1)/1 var(--mono);letter-spacing:.16em;color:var(--res);
  flex:none;padding-right:var(--s6);animation:slide 64s linear infinite}
@keyframes slide{from{transform:translateX(0)}to{transform:translateX(-100%)}}

/* ── statement band ────────────────────────────────────────────────── */
.band{padding-block:var(--s9)}
.band h2{font:500 clamp(34px,6.2vw,92px)/1.02 var(--sans);letter-spacing:-.034em;
  color:var(--fg);margin:0;max-width:16ch;text-wrap:balance}
.band p{margin-top:var(--s5);font-size:var(--t1);line-height:1.5;color:var(--fg-s);max-width:46ch}

.claim{border-left:2px solid var(--acc);padding-left:var(--s4);
  font:500 var(--t2)/1.3 var(--sans);letter-spacing:-.016em;color:var(--fg);max-width:34ch}
.claim small{display:block;font:400 var(--t-1)/1.5 var(--mono);color:var(--fg-s);
  margin-top:var(--s3);letter-spacing:0}

/* ── tables ────────────────────────────────────────────────────────── */
.tw{overflow-x:auto;border-top:1px solid var(--fg)}
table.d{width:100%;border-collapse:collapse;font-size:var(--t-1);
  font-variant-numeric:tabular-nums;min-width:440px}
table.d th{text-align:left;font:500 var(--t-2)/1.45 var(--mono);letter-spacing:.12em;
  text-transform:uppercase;color:var(--fg-s);padding:var(--s3) var(--s4) var(--s3) 0;
  border-bottom:1px solid var(--rule);white-space:nowrap;vertical-align:bottom}
table.d td{padding:var(--s3) var(--s4) var(--s3) 0;border-bottom:1px solid var(--rule);
  vertical-align:top;line-height:1.5}
table.d td:first-child{color:var(--fg);font-family:var(--mono);white-space:nowrap}
table.d .num{font-family:var(--mono);color:var(--fg);white-space:nowrap}
table.d .src{font-family:var(--mono);color:var(--acc);white-space:nowrap}
table.d tr:last-child td{border-bottom:0}
table.d tr[data-dim]{cursor:default;transition:background var(--d1) var(--ez)}
table.d tr[data-dim]:hover,table.d tr[data-dim].lit{background:var(--tint)}

/* ── interactive construction drawing ──────────────────────────────── */
/* drawing and its spec sit side by side — the hover link is useless if the
   table is a scroll away from the dimension it lights up */
.symsplit{display:grid;grid-template-columns:9fr 7fr;gap:var(--s6);align-items:start}
@media (max-width:980px){ .symsplit{grid-template-columns:1fr} }
.symspec{display:flex;flex-direction:column;gap:var(--s4);min-width:0}
.symspec p{font-size:var(--t-1);line-height:1.6;color:var(--fg-s)}
.symspec table.d{min-width:0}
.draw{border:1px solid var(--rule);background:var(--bg-r);padding:var(--s5) var(--s4);
  overflow-x:auto}
.draw svg{display:block;width:100%;height:auto;min-width:360px}
.draw .g-l{stroke:var(--rule);stroke-width:2;fill:none}
.draw .g-b{stroke:var(--rule-2);stroke-width:3;fill:none}
.draw .mk-f{fill:var(--fg);opacity:.13}
.draw .mk-o{fill:none;stroke:var(--fg);stroke-width:5}
.draw .cl{stroke:var(--fg-s);stroke-width:4;fill:none;stroke-dasharray:60 18 8 18}
.draw .cons{stroke:var(--fg-s);stroke-width:3.5;fill:none;stroke-dasharray:22 16;opacity:.75}
.draw .arw{fill:var(--acc)}
.draw g.dimset{opacity:.42;transition:opacity var(--d2) var(--ez)}
.draw g.dimset.lit{opacity:1}
.draw.armed g.dimset{opacity:1}
.draw .dim{stroke:var(--acc);stroke-width:4.5;fill:none;
  marker-start:url(#hxA);marker-end:url(#hxA)}
.draw .ext{stroke:var(--acc);stroke-width:3;fill:none;opacity:.5}
.draw .dl{fill:var(--acc);font:600 56px var(--mono);letter-spacing:1px}
.draw .dn{fill:var(--fg-s);font:400 44px var(--mono)}

/* ── the ratio toy ─────────────────────────────────────────────────── */
/* Φ is the subject of this sheet, so the readout is Ratio, not Signal —
   the rule stated in Φ.08. Re-pointing --acc recolours the ring, the chip,
   the slider and the ticks together. The mark itself stays flat white. */
.toy{display:grid;grid-template-columns:1fr .8fr;gap:var(--s7);align-items:center;
  --acc:var(--res)}
@media (max-width:840px){ .toy{grid-template-columns:1fr;gap:var(--s6)} }
.toy__st{border:1px solid var(--rule);background:var(--bg-r);aspect-ratio:1/1;
  display:flex;align-items:center;justify-content:center;padding:var(--s6);position:relative}
.toy__st svg{width:auto;height:100%;max-width:100%;display:block;color:var(--fg)}
.toy__st.locked{border-color:var(--acc)}
.toy__flash{position:absolute;inset:0;pointer-events:none;
  box-shadow:inset 0 0 0 0 var(--acc);transition:box-shadow var(--d3) var(--ez)}
.toy__st.locked .toy__flash{box-shadow:inset 0 0 0 2px var(--acc)}
.toy__panel{display:flex;flex-direction:column;gap:var(--s5)}
.toy__read{display:flex;align-items:baseline;gap:var(--s3);flex-wrap:wrap}
.toy__val{font:500 var(--t6)/1 var(--mono);color:var(--res);letter-spacing:-.02em;
  font-variant-numeric:tabular-nums}
@supports (-webkit-background-clip:text) or (background-clip:text){
  .toy__val{
    background:var(--hx-ratio-sheen);background-size:220% 100%;background-position:38% 0;
    -webkit-background-clip:text;background-clip:text;
    color:transparent;-webkit-text-fill-color:transparent;
  }
  /* one sweep on lock, then it holds — the system arrives, it does not shimmer */
  .toy__panel.locked .toy__val{animation:sheen 820ms var(--ez) 1}
}
@keyframes sheen{from{background-position:100% 0}to{background-position:38% 0}}
.toy__ticks span:nth-child(2){color:var(--res)}
.toy__tag{font:500 var(--t-2)/1.45 var(--mono);letter-spacing:.14em;padding:5px var(--s3);
  border:1px solid var(--rule-2);color:var(--fg-s);white-space:nowrap}
.toy__panel.locked .toy__tag{border-color:var(--acc);color:var(--acc)}
.toy__slider{-webkit-appearance:none;appearance:none;width:100%;height:26px;background:none;
  cursor:ew-resize;display:block}
.toy__slider::-webkit-slider-runnable-track{height:1px;background:var(--rule-2)}
.toy__slider::-moz-range-track{height:1px;background:var(--rule-2)}
.toy__slider::-webkit-slider-thumb{-webkit-appearance:none;width:3px;height:26px;
  background:var(--acc);border:0;margin-top:-13px;cursor:ew-resize}
.toy__slider::-moz-range-thumb{width:3px;height:26px;background:var(--acc);border:0;border-radius:0}
/* The thumb is a 26px bar filling the slider's 26px box, so its bottom edge is
   the slider's bottom edge. A negative margin here parks a label under it. */
.toy__ticks{display:flex;justify-content:space-between;font:400 var(--t-2)/1 var(--mono);
  color:var(--fg-s);letter-spacing:.06em;margin-top:var(--s3)}
.toy__verdict{font-size:var(--t-1);line-height:1.6;color:var(--fg-s);min-height:4.6em}
.toy__verdict b{color:var(--fg);display:block;margin-bottom:var(--s2)}

/* ── lockups ───────────────────────────────────────────────────────── */
.locks{display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));
  border:1px solid var(--rule);border-width:1px 0 0 1px}
.lock{background:var(--bg-r);padding:var(--s5);display:flex;flex-direction:column;gap:var(--s4);
  border:1px solid var(--rule);border-width:0 1px 1px 0}
.lock__st{display:flex;align-items:center;justify-content:center;min-height:148px;color:var(--fg)}
.lock__st svg{width:auto;max-width:100%;display:block}
.lock__t{display:flex;flex-direction:column;gap:var(--s2);border-top:1px solid var(--rule);
  padding-top:var(--s3)}
.lock__t b{font:600 var(--t-1)/1.3 var(--sans);color:var(--fg)}
.lock__t p{font-size:var(--t-1);line-height:1.55;color:var(--fg-s)}

/* ── clear space ───────────────────────────────────────────────────── */
/* diagram left, everything else right — the old stack let a 650px diagram
   own the major column while the minor one sat almost empty */
.csplit{display:grid;grid-template-columns:6fr 10fr;gap:var(--s6);align-items:start}
@media (max-width:980px){ .csplit{grid-template-columns:1fr} }
.cs{border:1px solid var(--rule);background:var(--bg-r);padding:var(--s5);
  display:flex;justify-content:center}
.cs svg{width:100%;max-width:300px;height:auto;display:block}
.cs .zone{fill:var(--tint);stroke:var(--acc);stroke-width:4;stroke-dasharray:20 14}
.cs .bx{fill:none;stroke:var(--fg-s);stroke-width:3;stroke-dasharray:12 10}
.cs .mk{fill:var(--fg)}
.cs .oz{fill:var(--acc);font:600 76px var(--mono)}

/* ── misuse ────────────────────────────────────────────────────────── */
.dont{display:grid;grid-template-columns:repeat(auto-fit,minmax(125px,1fr));
  border:1px solid var(--rule);border-width:1px 0 0 1px}
.dont figure{margin:0;background:var(--bg-r);padding:var(--s5) var(--s4) var(--s4);
  display:flex;flex-direction:column;gap:var(--s4);border:1px solid var(--rule);
  border-width:0 1px 1px 0}
/* Room first, then art. A 72px mark rotated 21 degrees needs an 88px box;
   sizing the tile to the artwork and hoping is how it kept getting sheared. */
.dont__st{position:relative;height:132px;padding:var(--s4);display:flex;
  align-items:center;justify-content:center;overflow:hidden}
/* the transformed variants below rotate and stretch the mark; at 92px their
   bounding boxes exceeded the 110px tile and got sheared off by overflow */
.dont__st > svg:not(.dont__x){height:72px;width:auto;display:block;color:var(--fg)}
.dont__st--busy{background:repeating-linear-gradient(48deg,var(--hx-ash) 0 9px,var(--hx-mist) 9px 18px)}
.dont__x{position:absolute;top:0;right:0;width:18px;height:18px;color:var(--acc)}
.dont figcaption{font-size:var(--t-1);line-height:1.5;color:var(--fg-s);
  border-top:1px solid var(--rule);padding-top:var(--s3)}
.dont figcaption b{display:block;color:var(--acc);font:500 var(--t-2)/1.45 var(--mono);
  letter-spacing:.12em;text-transform:uppercase;margin-bottom:var(--s2)}
.x-rot .dont__st > svg:not(.dont__x){transform:rotate(21deg)}
.x-str .dont__st > svg:not(.dont__x){transform:scaleX(1.75)}
.x-col .dont__st > svg:not(.dont__x){color:#2E6BE6}
.x-fx  .dont__st > svg:not(.dont__x){filter:drop-shadow(4px 6px 0 var(--hx-ash));opacity:.9}

/* ── colour ────────────────────────────────────────────────────────── */
.sw{display:grid;grid-template-columns:repeat(auto-fit,minmax(125px,1fr));
  border:1px solid var(--rule);border-width:1px 0 0 1px}
.sw button{all:unset;cursor:pointer;display:flex;flex-direction:column;
  background:var(--bg-r);font-family:var(--sans);
  border:1px solid var(--rule);border-width:0 1px 1px 0}
.sw__c{height:104px;width:100%;position:relative;border-bottom:1px solid var(--rule);
  color:#fff;transition:height var(--d3) var(--ez)}
.sw button:hover .sw__c{height:142px}
.sw__c::after{content:attr(data-flag);position:absolute;right:var(--s3);bottom:var(--s3);
  font:500 var(--t-2)/1.45 var(--mono);letter-spacing:.1em;color:inherit;opacity:.82}
.sw__i{padding:var(--s4);display:flex;flex-direction:column;gap:var(--s2)}
.sw__i b{font:600 var(--t-1)/1.2 var(--sans);color:var(--fg)}
.sw__i code{font:400 var(--t-1)/1.2 var(--mono);color:var(--fg-s);letter-spacing:.02em}
.sw__i small{font-size:var(--t-2);line-height:1.5;color:var(--fg-s);font-family:var(--mono)}
.sw button:hover .sw__i code{color:var(--acc)}
.sw button.copied .sw__i code::after{content:" ✓ đã chép";color:var(--acc)}

/* ══ Φ.08 · colour system ═══════════════════════════════════════════════
   Four tiers shown as four different objects, because they are not peers:
   a pair, a ramp, two restricted colours, and a separate product layer. */
.tiers td:first-child{color:var(--acc)}

.grounds{display:grid;grid-template-columns:1fr 1fr;gap:var(--s5)}
@media (max-width:720px){ .grounds{grid-template-columns:1fr} }
/* grid equalises the pair; aspect-ratio fought that and left them uneven */
.ground{min-height:250px;display:flex;flex-direction:column;justify-content:space-between;
  gap:var(--s6);padding:var(--s5);border:1px solid var(--rule);container-type:inline-size}
.ground svg{height:64px;width:auto;display:block}
/* direct children only — a nested <span class="m"> must stay inline */
.ground__m > b{display:block;font:600 var(--t0)/1.2 var(--sans)}
.ground__m > code{display:block;font:400 var(--t-1)/1.7 var(--mono);letter-spacing:.04em}
.ground__m > span{display:block;font:400 var(--t-1)/1.55 var(--sans);margin-top:var(--s2)}
.ground--void{background:#0B0D10}
.ground--void svg{color:#fff}
.ground--void b{color:#ECEDEF}.ground--void code{color:#A8AEB7}.ground--void span{color:#8C929B}
.ground--vellum{background:#ECEDEF}
.ground--vellum svg{color:#0B0D10}
.ground--vellum b{color:#0B0D10}.ground--vellum code{color:#5F6570}.ground--vellum span{color:#5F6570}

/* the neutrals are one scale, so they are drawn as one strip */
.ramp{display:grid;grid-template-columns:repeat(auto-fit,minmax(98px,1fr));
  border:1px solid var(--rule);border-width:1px 0 0 1px}
.ramp button{all:unset;cursor:pointer;display:flex;flex-direction:column;
  background:var(--bg-r);border:1px solid var(--rule);border-width:0 1px 1px 0}
.ramp i{display:block;height:84px;width:100%}
.ramp span{padding:var(--s3) var(--s3) var(--s4);display:flex;flex-direction:column;gap:3px}
.ramp b{font:600 var(--t-1)/1.2 var(--sans);color:var(--fg)}
.ramp code{font:400 var(--t-2)/1.4 var(--mono);color:var(--fg-s);letter-spacing:.03em}
.ramp small{font:400 var(--t-2)/1.45 var(--mono);color:var(--fg-s)}
.ramp button:hover code{color:var(--acc)}
.ramp button.copied code::after{content:" ✓";color:var(--acc)}

.fnc{display:grid;grid-template-columns:1fr 1fr;gap:var(--s5)}
@media (max-width:720px){ .fnc{grid-template-columns:1fr} }
.fnc__x{border:1px solid var(--rule);display:flex;flex-direction:column}
.fnc__pair{display:grid;grid-template-columns:1fr 1fr}
.fnc__pair div{height:88px;display:flex;align-items:flex-end;padding:var(--s3);
  font:500 var(--t-2)/1.45 var(--mono);letter-spacing:.1em}
.fnc__b{padding:var(--s5);display:flex;flex-direction:column;gap:var(--s3);flex:1}
.fnc__b h4{font:600 var(--t0)/1.3 var(--sans);color:var(--fg);margin:0}
.fnc__cap{font:500 var(--t-2)/1.45 var(--mono);letter-spacing:.12em;color:var(--acc);
  border:1px solid var(--acc);padding:4px var(--s3);align-self:flex-start}
.fnc__b p{font-size:var(--t-1);line-height:1.6;color:var(--fg-s)}

/* verdict chips in the contrast matrix */
.v{font:500 var(--t-2)/1 var(--mono);letter-spacing:.1em;padding:3px 6px;white-space:nowrap;
  display:inline-block}
.v--aaa{color:var(--fg);border:1px solid var(--rule-2)}
.v--aa{color:var(--fg-s);border:1px solid var(--rule)}
.v--lg{color:var(--res);border:1px solid color-mix(in srgb,var(--res) 50%,transparent)}
.v--no{color:var(--acc);border:1px solid color-mix(in srgb,var(--acc) 50%,transparent)}

/* grid fr distributes the remainder exactly; four flex items rounded up and
   spilled 3px, shearing half the 2% segment at the narrowest width */
.ratiobar{display:grid;grid-template-columns:80fr 13fr 5fr 2fr;
  height:44px;border:1px solid var(--rule);overflow:hidden}
.ratiobar i{display:block;position:relative;min-width:0}
.ratiobar i::after{content:attr(data-l);position:absolute;left:var(--s3);top:50%;
  transform:translateY(-50%);font:500 var(--t-2)/1 var(--mono);letter-spacing:.1em;
  white-space:nowrap;color:inherit}

/* ── typography ────────────────────────────────────────────────────── */
.spec{border-top:1px solid var(--fg)}
.spec__r{display:grid;grid-template-columns:104px 1fr;gap:var(--s4);align-items:baseline;
  padding:var(--s3) 0;border-bottom:1px solid var(--rule);overflow:hidden}
.spec__r b{font:400 var(--t-2)/1.4 var(--mono);color:var(--fg-s);letter-spacing:.08em;
  font-variant-numeric:tabular-nums}
.spec__r span{color:var(--fg);letter-spacing:-.02em;line-height:1.06;white-space:nowrap;
  display:block;font-weight:500;
  transform:translateX(-14px);opacity:0;
  transition:transform var(--d4) var(--ez),opacity var(--d4) var(--ez)}
.spec.armed .spec__r span{transform:none;opacity:1}
.spec.armed .spec__r:nth-child(2) span{transition-delay:60ms}
.spec.armed .spec__r:nth-child(3) span{transition-delay:120ms}
.spec.armed .spec__r:nth-child(4) span{transition-delay:180ms}
.spec.armed .spec__r:nth-child(5) span{transition-delay:240ms}
.spec.armed .spec__r:nth-child(6) span{transition-delay:300ms}
.spec.armed .spec__r:nth-child(7) span{transition-delay:360ms}

/* ══ Φ.09 · typography ══════════════════════════════════════════════════
   Samples are sized to fit their own step, so nothing is ever clipped —
   the old specimen forced one long string through every size and cut it. */
.faces{display:grid;grid-template-columns:1fr 1fr;border:1px solid var(--rule);
  border-width:1px 0 0 1px}
@media (max-width:720px){ .faces{grid-template-columns:1fr} }
.face{background:var(--bg-r);padding:var(--s5);display:flex;flex-direction:column;gap:var(--s4);
  border:1px solid var(--rule);border-width:0 1px 1px 0;min-width:0}
.face__aa{font:500 clamp(34px,8vw,104px)/.92 var(--sans);color:var(--fg);letter-spacing:-.042em}
.face--mono .face__aa{font-family:var(--mono);letter-spacing:-.02em}
.face__set{font:400 var(--t-1)/1.8 var(--mono);color:var(--fg-s);letter-spacing:.02em;
  overflow-wrap:anywhere}
.face p{font-size:var(--t-1);line-height:1.6;color:var(--fg-s)}

.scale{border-top:1px solid var(--fg)}
.scale__r{display:grid;grid-template-columns:132px 1fr;gap:var(--s5);align-items:baseline;
  padding:var(--s4) 0;border-bottom:1px solid var(--rule)}
@media (max-width:640px){ .scale__r{grid-template-columns:1fr;gap:var(--s2)} }
.scale__k{display:flex;flex-direction:column;gap:3px}
.scale__k b{font:400 var(--t-1)/1.2 var(--mono);color:var(--fg);font-variant-numeric:tabular-nums}
.scale__k span{font:400 var(--t-2)/1.35 var(--mono);color:var(--fg-s)}
.scale__s{color:var(--fg);font-weight:500;letter-spacing:-.026em;line-height:1.25;
  min-width:0;overflow-wrap:anywhere}

.wts{display:grid;grid-template-columns:repeat(3,1fr);
  border:1px solid var(--rule);border-width:1px 0 0 1px}
.wts div{background:var(--bg-r);padding:var(--s5);display:flex;flex-direction:column;gap:var(--s3);
  border:1px solid var(--rule);border-width:0 1px 1px 0}
.wts b{font-size:var(--t3);letter-spacing:-.026em;color:var(--fg);line-height:1.15}

.viet{border:1px solid var(--rule);background:var(--bg-r);padding:var(--s5);
  display:flex;flex-direction:column;gap:var(--s4)}
.viet p{color:var(--fg);margin:0;max-width:none}

.fig{display:grid;grid-template-columns:1fr 1fr;border:1px solid var(--rule);
  border-width:1px 0 0 1px}
@media (max-width:640px){ .fig{grid-template-columns:1fr} }
.fig > div{background:var(--bg-r);padding:var(--s5);display:flex;flex-direction:column;gap:var(--s4);
  border:1px solid var(--rule);border-width:0 1px 1px 0}
.fig table{width:100%;border-collapse:collapse;font-family:var(--mono);font-size:var(--t0)}
.fig td{padding:5px 0;color:var(--fg);border-bottom:1px solid var(--rule)}
.fig td:last-child{text-align:right}
.fig tr:last-child td{border-bottom:0}
.fig--prop table{font-variant-numeric:proportional-nums}
.fig--tab  table{font-variant-numeric:tabular-nums}

.pair{display:grid;grid-template-columns:1fr 1fr;border:1px solid var(--rule);
  border-width:1px 0 0 1px}
@media (max-width:640px){ .pair{grid-template-columns:1fr} }
.pair>div{background:var(--bg-r);padding:var(--s5);display:flex;flex-direction:column;
  gap:var(--s3);border:1px solid var(--rule);border-width:0 1px 1px 0}
.pair .sm{font:400 var(--t3)/1.1 var(--sans);color:var(--fg);letter-spacing:-.02em}
.pair .sm.mo{font-family:var(--mono);letter-spacing:-.01em}
.pair p{font-size:var(--t-1);color:var(--fg-s);line-height:1.6}

/* ── voice ─────────────────────────────────────────────────────────── */
.vo{display:grid;grid-template-columns:1fr 1fr;border:1px solid var(--rule);
  border-width:1px 0 0 1px}
@media (max-width:720px){ .vo{grid-template-columns:1fr} }
.vo>div{background:var(--bg-r);padding:var(--s5);display:flex;flex-direction:column;
  gap:var(--s4);border:1px solid var(--rule);border-width:0 1px 1px 0}
.vo ul{margin:0;padding:0;list-style:none;display:flex;flex-direction:column;gap:var(--s4)}
.vo li{font-size:var(--t-1);line-height:1.6;padding-left:var(--s5);position:relative;color:var(--fg-s)}
.vo li::before{position:absolute;left:0;top:0;font:500 var(--t-1)/1.6 var(--mono)}
.vo--y li::before{content:"+";color:var(--acc)}
.vo--n li::before{content:"−";color:var(--fg-s)}
.vo li q{display:block;color:var(--fg);font-style:normal;quotes:"“" "”";margin-top:2px}

/* ══ APPLICATION MOCKUPS ═══════════════════════════════════════════════ */
.grp{display:flex;align-items:baseline;gap:var(--s4);flex-wrap:wrap;
  border-top:1px solid var(--fg);padding-top:var(--s3);margin-top:var(--s4)}
.grp b{font:500 var(--t0)/1.2 var(--sans);color:var(--fg);letter-spacing:-.012em}
.grp span{font:400 var(--t-1)/1.4 var(--mono);color:var(--fg-s);margin-left:auto;text-align:right}

.app{display:grid;grid-template-columns:repeat(auto-fit,minmax(238px,1fr));gap:var(--s6) var(--s5)}
/* one plate per mockup so objects of different proportion still line up —
   the grid was ragged because each mockup sized itself */
.plate{aspect-ratio:1.2/1;display:flex;align-items:center;justify-content:center;
  padding:6%;background:var(--bg-r);border:1px solid var(--rule)}
.plate--l > *{width:100%;height:auto;flex:none}
.plate--p > *{height:100%;width:auto;flex:none}
.app figure{margin:0;display:flex;flex-direction:column;gap:var(--s3)}
@supports (grid-template-rows:subgrid){
  .app figure{display:grid;grid-row:span 2;grid-template-rows:subgrid;row-gap:var(--s3)}
  .app figure > :first-child{align-self:end}
}
.app figcaption{font-size:var(--t-1);line-height:1.5;color:var(--fg-s);
  border-top:1px solid var(--rule);padding-top:var(--s3)}
.app figcaption b{display:block;color:var(--fg);font-weight:600;margin-bottom:2px}

.mk{border:1px solid var(--rule);overflow:hidden;position:relative;
  container-type:inline-size;display:flex}
.mk svg{display:block}
.deb{filter:drop-shadow(0 -1.5px 0 rgba(0,0,0,.85)) drop-shadow(0 1.5px 0 rgba(255,255,255,.13))}

/* Business card, 89 × 55mm. Sized in cqw so the proportions survive at any
   render size — the old fixed-px version broke as soon as the tile shrank.
   The hairline sits on the 10:6 split from Φ.10, not at the halfway mark. */
.card{aspect-ratio:1.618/1;background:var(--hx-void);display:flex;flex-direction:column;
  padding:7.5% 8%;position:relative}
.card svg{height:13cqw;width:auto;color:#fff;display:block}
.card__rule{position:absolute;left:8%;right:8%;top:62.5%;height:1px;background:#252A32}
.card__ft{margin-top:auto;display:flex;align-items:flex-end;justify-content:space-between;gap:4cqw}
.card__id b{display:block;font:500 6.2cqw/1.08 var(--sans);color:var(--hx-vellum);letter-spacing:-.024em}
.card__id span{display:block;font:400 2.6cqw/1.45 var(--mono);color:var(--hx-ash);
  letter-spacing:.2em;margin-top:2.2cqw}
.card__co{display:flex;flex-direction:column;align-items:flex-end;gap:1.5cqw;flex:none}
.card__co span{font:400 2.6cqw/1 var(--mono);color:#7C838E;letter-spacing:.04em;white-space:nowrap}

/* Report cover — was riding on .card and fighting it. Its own class now. */
.rcover{aspect-ratio:1.618/1;background:var(--hx-void);display:flex;flex-direction:column;
  justify-content:flex-end;padding:8%}
.rcover span{display:block;font:400 2.6cqw/1.7 var(--mono);color:var(--hx-ash);
  letter-spacing:.12em;margin-bottom:4.5cqw}
.rcover b{display:block;font:500 7cqw/1.25 var(--sans);color:var(--hx-vellum);letter-spacing:-.026em}

/* Product family. The mark is identical on every icon — that constancy is
   the thesis, so the code in the foot is the only thing allowed to differ.
   No colour variant exists; recolouring the mark is misuse 02. */
.pico{aspect-ratio:1/1;border-radius:22.37%;
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  border:1px solid var(--rule);container-type:inline-size}
.pico svg{height:65.9cqw;width:auto;color:#fff;display:block}
/* Gradient grounds. The mark still never changes colour beyond Void/White
   (misuse 02); Living is light, so its mark is Void — not a new colour. */
.pico--core  {background:var(--hx-p-core-grad)}
.pico--care  {background:var(--hx-p-care-grad)}
.pico--data  {background:var(--hx-p-data-grad)}
.pico--safety{background:var(--hx-p-safety-grad)}
.pico--living{background:var(--hx-p-living-grad)}
.pico--living svg{color:var(--hx-void)}
/* Min column widths are derived from the 320px content box (268px), not
   picked. Anything above half of it collapses auto-fit to one column and
   the tile fills the phone — that is how five app icons became five
   full-screen squares. */
.picos{display:grid;grid-template-columns:repeat(auto-fit,minmax(105px,1fr));gap:var(--s5)}
.picos figure{margin:0;display:flex;flex-direction:column;gap:var(--s3)}
.picos figcaption{font:400 var(--t-1)/1.5 var(--sans);color:var(--fg-s);text-align:center}
.picos figcaption b{display:block;color:var(--fg);font-weight:600}
.picos figcaption code{display:block;font:400 var(--t-2)/1.6 var(--mono);color:var(--fg-s);letter-spacing:.04em}


.cardb{aspect-ratio:1.618/1;background:var(--hx-vellum);flex-direction:column;
  align-items:center;justify-content:center;padding:7.5% 8%;position:relative}
.cardb svg{height:24cqw;width:auto;color:var(--hx-void);display:block}
.cardb__num{position:absolute;left:0;right:0;bottom:7.5%;text-align:center;
  font:400 2.5cqw/1.45 var(--mono);color:var(--hx-ratio);letter-spacing:.14em}

.folder{aspect-ratio:1/1.414;background:var(--hx-void);flex-direction:column;
  justify-content:space-between;padding:13% 11% 10%}
.folder__mk{display:flex;flex-direction:column;align-items:center;gap:6cqw;color:#181B20}
.folder__mk svg{width:23cqw;height:auto}
.folder__mk b{font:500 5.4cqw/1 var(--sans);letter-spacing:-.02em}
.folder__ft{display:flex;justify-content:space-between;align-items:flex-end;gap:var(--s3)}
.folder__ft span{font:400 3.1cqw/1.7 var(--mono);color:#4A505A;letter-spacing:.1em}

.letter{aspect-ratio:1/1.414;background:var(--hx-vellum);flex-direction:column;
  justify-content:space-between;padding:8% 9%}
.letter__hd{display:flex;justify-content:space-between;align-items:flex-start;gap:var(--s3)}
.letter__hd svg{width:32cqw;height:auto;color:var(--hx-void)}
.letter__hd span{font:400 2.9cqw/1.7 var(--mono);color:#5F6570;text-align:right;letter-spacing:.06em}
.letter__body{flex:1;display:flex;flex-direction:column;gap:2.4cqw;padding:9% 0}
.letter__body i{display:block;height:1.6cqw;background:#D2D6DB}
.letter__ft{border-top:1px solid #C9CFD6;padding-top:3cqw;font:400 2.7cqw/1.6 var(--mono);
  color:#5F6570;letter-spacing:.06em}

.book{aspect-ratio:1/1.35;background:linear-gradient(95deg,#0E1114 0 6%,var(--hx-ink) 6% 100%);
  align-items:center;justify-content:center;color:#1A1E24}
.book svg{width:26cqw;height:auto}

.wall{aspect-ratio:1.618/1;background:linear-gradient(180deg,#F2F3F4,#E2E4E7);
  align-items:flex-end;justify-content:center;padding-bottom:5%;gap:9%}
.wall svg.wmk{width:11.4cqw;height:auto;color:var(--hx-void);align-self:center;
  filter:drop-shadow(2.2cqw 1.4cqw 1.8cqw rgba(11,13,16,.30))}
.wall svg.wfig{width:7cqw;height:auto;color:#B7BCC3}
.wall__dim{position:absolute;left:4%;top:32%;bottom:38%;width:1px;background:var(--hx-signal)}
.wall__dim::after{content:"1200 mm";position:absolute;left:6px;top:50%;transform:translateY(-50%);
  font:500 2.6cqw/1 var(--mono);color:var(--hx-signal);letter-spacing:.1em;white-space:nowrap}

.glass{aspect-ratio:1.618/1;
  background:linear-gradient(118deg,#DCE3E6 0 38%,#CFD8DC 38% 62%,#E3E9EB 62%);
  align-items:center;justify-content:center}
.glass__band{position:absolute;left:0;right:0;top:41%;height:18%;background:rgba(255,255,255,.62);
  display:flex;align-items:center;gap:9cqw;padding-left:6cqw;
  border-block:1px solid rgba(255,255,255,.9)}
.glass__band svg{width:4.4cqw;height:auto;color:#7C858E;flex:none}
.glass__jamb{position:absolute;left:47%;top:0;bottom:0;width:1.6cqw;background:#AEB6BC}

.dplate{aspect-ratio:1.618/1;background:var(--hx-void);align-items:center;
  justify-content:space-between;padding:0 8%;gap:5%}
.dplate svg{width:11cqw;height:auto;color:#fff;flex:none}
.dplate__t{display:flex;flex-direction:column;gap:1.4cqw;text-align:right;margin-left:auto}
.dplate__t b{font:500 6.4cqw/1 var(--sans);color:#fff;letter-spacing:-.02em}
.dplate__t span{font:400 3cqw/1.45 var(--mono);color:var(--hx-ash);letter-spacing:.14em}

.dir{aspect-ratio:1/1.2;background:var(--hx-void);flex-direction:column;padding:9% 8%;gap:4%}
.dir svg{width:13cqw;height:auto;color:#fff}
.dir__rows{display:flex;flex-direction:column;gap:3.4cqw;margin-top:2cqw}
.dir__r{display:flex;justify-content:space-between;gap:var(--s3);border-bottom:1px solid #262A31;
  padding-bottom:2.4cqw;font:400 3.6cqw/1.3 var(--mono);color:var(--hx-ash);letter-spacing:.04em}
.dir__r b{color:#fff;font-weight:500}

.tile{aspect-ratio:1/1;background:var(--hx-void);border-radius:22.37%;display:flex;
  align-items:center;justify-content:center;border:1px solid var(--rule)}
/* The artboard carries a W/2 bleed, and % resolves against the content box
   while the 0.618 rule is stated against the tile edge. 65.9 covers both:
   artboard 65.9% of content -> artwork exactly 61.8% of the tile. */
.tile svg{height:65.9%;width:auto;max-width:66%;color:#fff;display:block}

/* sized in container units — fixed px overflowed and got clipped once the
   plate narrowed this tile */
.ui{aspect-ratio:1.618/1;background:var(--hx-void);border:1px solid var(--rule);
  padding:5%;display:flex;flex-direction:column;gap:2.4%;overflow:hidden;
  container-type:inline-size}
.ui__h{display:flex;align-items:center;gap:2.4cqw;border-bottom:1px solid #252A31;
  padding-bottom:3cqw}
.ui__h svg{height:4.4cqw;width:auto;color:#fff;display:block}
.ui__h b{font:500 3cqw/1.45 var(--mono);letter-spacing:.14em;color:var(--hx-ash);
  text-transform:uppercase}
.ui__rows{display:flex;flex-direction:column;gap:2.4cqw;flex:1;justify-content:center}
.ui__r{display:flex;justify-content:space-between;align-items:baseline;gap:3cqw;
  font:400 3.4cqw/1.4 var(--mono);color:var(--hx-ash);font-variant-numeric:tabular-nums}
.ui__r b{color:var(--hx-vellum);font-weight:500}
.ui__r.hit b{color:var(--hx-signal-lift)}
.ui__out{border-top:1px solid #252A31;padding-top:3cqw;display:flex;
  justify-content:space-between;align-items:center;gap:3cqw}
.ui__tag{font:500 2.9cqw/1.45 var(--mono);letter-spacing:.12em;color:var(--hx-void);
  background:var(--hx-signal-lift);padding:1.6cqw 2.6cqw}
.ui__ts{font:400 2.9cqw/1 var(--mono);color:var(--hx-steel)}

.esig{aspect-ratio:1.9/1;background:var(--hx-vellum);align-items:center;padding:0 7%;gap:5%}
.esig svg{width:9cqw;height:auto;color:var(--hx-void);flex:none}
.esig__rule{width:1px;align-self:stretch;margin-block:22%;background:#C9CFD6;flex:none}
.esig__t{display:flex;flex-direction:column;gap:1.4cqw}
.esig__t b{font:600 4.4cqw/1.2 var(--sans);color:var(--hx-void);letter-spacing:-.014em}
.esig__t span{font:400 3cqw/1.6 var(--mono);color:#5F6570;letter-spacing:.04em}

.sign{aspect-ratio:1.618/1;background:var(--hx-vellum);align-items:center;justify-content:center}
.sign svg{height:44%;width:auto;max-width:72%;color:var(--hx-void);display:block}

.cloth{aspect-ratio:1.618/1;background:
  repeating-linear-gradient(90deg,rgba(255,255,255,.028) 0 1px,transparent 1px 3px),
  repeating-linear-gradient(0deg,rgba(255,255,255,.028) 0 1px,transparent 1px 3px),
  var(--hx-ink);
  align-items:center;justify-content:center;gap:var(--s3);flex-direction:column}
.cloth svg{height:46px;width:auto;color:#fff;filter:drop-shadow(0 1px 0 rgba(0,0,0,.6))}
.cloth b{font:500 var(--t-1)/1 var(--sans);color:#fff;letter-spacing:-.005em}

.tag{aspect-ratio:1.618/1;background:var(--hx-ink);align-items:center;justify-content:center}
.tag__t{width:34%;aspect-ratio:1/1;background:var(--hx-void);display:flex;align-items:center;
  justify-content:center;border:1px solid #22262C}
.tag__t svg{width:44%;height:auto;color:#fff}

.badge{aspect-ratio:1/1.5;background:var(--hx-vellum);flex-direction:column}
.badge__slot{height:7%;display:flex;align-items:center;justify-content:center;flex:none}
.badge__slot i{width:26%;height:26%;min-height:3px;background:#C9CFD6;border-radius:99px}
.badge__hd{background:var(--hx-void);padding:5% 8%;display:flex;align-items:center;
  gap:3.4cqw;flex:none}
.badge__hd svg{width:8cqw;height:auto;color:#fff}
.badge__hd span{font:500 3cqw/1.45 var(--mono);color:var(--hx-ash);letter-spacing:.16em}
.badge__b{flex:1;display:flex;flex-direction:column;justify-content:space-between;padding:7% 8%}
.badge__ph{width:46%;aspect-ratio:1/1.2;background:#D6DADF;border:1px solid #C2C8CF}
.badge__t b{display:block;font:600 5.6cqw/1.2 var(--sans);color:var(--hx-void);letter-spacing:-.016em}
.badge__t span{display:block;font:400 3.1cqw/1.7 var(--mono);color:#5F6570;letter-spacing:.06em;
  margin-top:1.6cqw}

/* ── the review seal ───────────────────────────────────────────────── */
.sealwrap{display:grid;grid-template-columns:1fr 1fr;gap:var(--s7);align-items:center}
@media (max-width:860px){ .sealwrap{grid-template-columns:1fr;gap:var(--s6)} }
.stamp{display:flex;flex-direction:column;align-items:center;gap:var(--s5);
  border:1px solid var(--rule);padding:var(--s7) var(--s5);background:var(--bg-r)}
/* faint before the press, solid after — an invisible seal reads as an empty box */
.stamp svg{width:min(60%,220px);height:auto;color:var(--fg);display:block;
  transform:scale(1.14);opacity:.1;
  transition:transform 220ms cubic-bezier(.2,.9,.3,1),opacity 140ms linear}
.stamp.pressed svg{transform:none;opacity:1}
.stamp__meta{font:400 var(--t-2)/1.9 var(--mono);color:var(--fg-s);letter-spacing:.1em;
  text-align:center;opacity:0;transition:opacity var(--d3) var(--ez) 180ms;min-height:3.8em}
.stamp.pressed .stamp__meta{opacity:1}
.stamp__btn{all:unset;cursor:pointer;font:500 var(--t-2)/1.45 var(--mono);letter-spacing:.14em;
  text-transform:uppercase;border:1px solid var(--rule-2);color:var(--fg-s);
  padding:var(--s3) var(--s5);transition:color var(--d1) var(--ez),border-color var(--d1) var(--ez)}
.stamp__btn:hover{color:var(--acc);border-color:var(--acc)}

.seals{display:grid;grid-template-columns:repeat(auto-fit,minmax(120px,1fr));
  border:1px solid var(--rule);border-width:1px 0 0 1px}
.seals figure{margin:0;background:var(--bg-r);padding:var(--s5) var(--s4);display:flex;
  flex-direction:column;gap:var(--s4);align-items:center;
  border:1px solid var(--rule);border-width:0 1px 1px 0}
.seals svg{width:100%;max-width:112px;height:auto;display:block}
.seals figcaption{font-size:var(--t-2);line-height:1.6;color:var(--fg-s);text-align:center;
  border-top:1px solid var(--rule);padding-top:var(--s3);width:100%;font-family:var(--mono)}
.seals figcaption b{display:block;color:var(--fg);font-weight:600;margin-bottom:2px;
  font-family:var(--sans);font-size:var(--t-1)}

/* ── dimensional stage ─────────────────────────────────────────────── */
.stage{border:1px solid var(--rule);position:relative;overflow:hidden;
  aspect-ratio:1.618/1;background:var(--bg-r);touch-action:pan-y}
.stage canvas{display:block;width:100%;height:100%}
.stage__hint{position:absolute;left:var(--s4);bottom:var(--s4);z-index:2;pointer-events:none;
  font:500 var(--t-2)/1 var(--mono);letter-spacing:.14em;text-transform:uppercase;
  color:var(--hx-steel);transition:opacity var(--d3) var(--ez)}
.stage.dragged .stage__hint{opacity:0}
.stage__fb{position:absolute;inset:0;display:none;align-items:center;justify-content:center;
  padding:var(--s6);text-align:center;font-size:var(--t-1);line-height:1.6;color:var(--fg-s)}
.stage.failed .stage__fb{display:flex}
.stage.failed canvas,.stage.failed .stage__hint{display:none}

.finishes{display:flex;border:1px solid var(--rule);border-width:1px 0 0 1px;flex-wrap:wrap}
.finishes button{all:unset;cursor:pointer;flex:1 1 150px;background:var(--bg-r);
  padding:var(--s4);font-family:var(--sans);display:flex;flex-direction:column;gap:var(--s2);
  border:1px solid var(--rule);border-width:0 1px 1px 0;
  transition:background var(--d1) var(--ez)}
.finishes button:hover{background:var(--bg)}
.finishes button b{font:600 var(--t-1)/1.2 var(--sans);color:var(--fg)}
.finishes button span{font:400 var(--t-2)/1.6 var(--mono);color:var(--fg-s);letter-spacing:.04em}
.finishes button[aria-pressed="true"]{background:var(--bg);box-shadow:inset 2px 0 0 var(--acc)}
.finishes button[aria-pressed="true"] b{color:var(--acc)}

.man td:first-child{color:var(--acc)}

/* ── 13-column overlay ─────────────────────────────────────────────── */
.grid{position:absolute;inset:0;pointer-events:none;opacity:0;z-index:9;
  transition:opacity var(--d3) var(--ez)}
.grid > div{max-width:1180px;margin-inline:auto;padding-inline:var(--pad);height:100%;
  display:grid;grid-template-columns:repeat(16,1fr);gap:var(--s5)}
.grid i{background:var(--tint);border-inline:1px solid color-mix(in srgb,var(--acc) 25%,transparent)}
.shell.grid-on .grid{opacity:1}

.gt{position:fixed;right:var(--s5);bottom:var(--s5);z-index:50;
  font:500 var(--t-2)/1 var(--mono);letter-spacing:.12em;text-transform:uppercase;
  background:var(--hx-bg);color:var(--hx-fg-subtle);border:1px solid var(--hx-rule-strong);
  padding:var(--s3) var(--s4);cursor:pointer;
  transition:color var(--d1) var(--ez),border-color var(--d1) var(--ez)}
.gt:hover{color:var(--hx-fg);border-color:var(--hx-fg-subtle)}
.gt[aria-pressed="true"]{color:var(--hx-accent);border-color:var(--hx-accent)}

/* ── mobile: rail out, top bar in ──────────────────────────────────── */
.topbar{display:none}
@media (max-width:900px){
  .shell{flex-direction:column}
  .doc{width:100%}
  .rail{display:none}
  .topbar{display:flex;align-items:center;gap:var(--s4);position:sticky;top:0;z-index:40;
    background:var(--chrome);border-bottom:1px solid var(--rule);
    padding:var(--s3) var(--s5);width:100%}
  .topbar__mk{display:block;color:var(--fg);text-decoration:none;flex:none}
  .topbar__mk svg{height:30px;width:auto;display:block}
  .navmenu{margin-left:auto;position:relative;min-width:0}
  .navmenu__btn{all:unset;box-sizing:border-box;cursor:pointer;display:flex;align-items:center;
    gap:var(--s3);border:1px solid var(--rule-2);padding:var(--s3) var(--s4);
    font-family:var(--mono);max-width:56vw;
    transition:border-color var(--d1) var(--ez)}
  .navmenu__btn:hover,.navmenu__btn[aria-expanded="true"]{border-color:var(--acc)}
  .navmenu__btn b{font:500 var(--t-2)/1 var(--mono);letter-spacing:.08em;color:var(--acc);flex:none}
  .navmenu__btn > span{font:400 var(--t-1)/1 var(--sans);color:var(--fg);
    overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}
  .navmenu__btn svg{width:10px;height:6px;flex:none;color:var(--fg-s);
    transition:transform var(--d2) var(--ez)}
  .navmenu__btn[aria-expanded="true"] svg{transform:rotate(180deg)}

  .navmenu__list{position:absolute;top:calc(100% + var(--s3));right:0;z-index:60;
    margin:0;padding:var(--s2) 0;list-style:none;min-width:230px;max-height:66vh;overflow-y:auto;
    background:var(--chrome);border:1px solid var(--rule-2);
    box-shadow:0 18px 44px -12px rgba(11,13,16,.34)}
  .navmenu__list[hidden]{display:none}
  .navmenu__list li{display:flex;align-items:baseline;gap:var(--s3);cursor:pointer;
    padding:var(--s3) var(--s4);border-left:2px solid transparent}
  .navmenu__list b{font:400 var(--t-2)/1 var(--mono);letter-spacing:.06em;color:var(--fg-s);
    flex:none;width:36px}
  .navmenu__list span{font:400 var(--t-1)/1.3 var(--sans);color:var(--fg)}
  .navmenu__list li:hover,.navmenu__list li.here{background:var(--bg-r)}
  .navmenu__list li[aria-selected="true"]{border-left-color:var(--acc)}
  .navmenu__list li[aria-selected="true"] b{color:var(--acc)}
  .sheet{scroll-margin-top:62px}
  /* Grid, not space-between: the middle row is a guaranteed band for the
     object. With flex, a short viewport let the type blocks eat everything
     and the mark collapsed to 4% of the hero. */
  .hero{height:92svh;min-height:560px;
    display:grid;grid-template-rows:auto minmax(clamp(140px,24svh,260px),1fr) auto}
  .hero__top{grid-row:1}
  .hero__btm{grid-row:3}
  .hero__top{padding-top:var(--s4)}
  /* the title block was eating 40% of the hero, leaving no band for the
     object between it and the wordmark */
  .titleblock{grid-template-columns:repeat(2,1fr);gap:var(--s2) var(--s4);
    padding-block:var(--s2)}
  .titleblock div{gap:1px}
  .titleblock b{font-size:var(--t-1);line-height:1.25}
  /* 15 gutters of 26px exceed the content box below ~500px, so the overlay
     overflowed even at opacity 0. Its toggle is hidden here anyway. */
  .gt,.grid{display:none}
}
/* short phones: shrink the type so the band above it survives */
@media (max-width:900px) and (max-height:740px){
  .hero__claim p{font-size:var(--t0);line-height:1.45}
  .hero__claim{margin-top:var(--s4)}
  .hero__btm{padding-bottom:var(--s5)}
  .hero__top{padding-top:var(--s3)}
  .titleblock b{font-size:var(--t-2)}
}

@media (max-width:640px){
  /* Wide spec tables scrolled sideways on a phone, which left every row as
     tall as its off-screen third column and mostly blank on screen. Stack
     them instead. Two tables opt out with .d--keep: their meaning IS the
     column each cell sits in, so they keep the scroll. */
  .tw:has(table.d:not(.d--keep)){overflow-x:visible;border-top-color:var(--fg)}
  table.d:not(.d--keep){min-width:0}
  table.d:not(.d--keep) thead{position:absolute;width:1px;height:1px;
    overflow:hidden;clip-path:inset(50%);white-space:nowrap}
  table.d:not(.d--keep) tbody,
  table.d:not(.d--keep) tr,
  table.d:not(.d--keep) td{display:block;width:auto}
  table.d:not(.d--keep) tr{border-bottom:1px solid var(--rule);padding:var(--s4) 0}
  table.d:not(.d--keep) tr:last-child{border-bottom:0}
  table.d:not(.d--keep) td{border:0;padding:0 0 var(--s2)}
  table.d:not(.d--keep) td:last-child{padding-bottom:0}
  table.d:not(.d--keep) td:first-child{color:var(--acc);font-weight:500;white-space:normal}
  .sh__en{margin-left:0;text-align:left;max-width:none}
  /* "5%" is wider than the 15px segment it labels at this width */
  .ratiobar i:nth-child(n+2)::after{content:none}
}
@media (max-width:560px){
  .sh__ti{font-size:var(--t2)}
  .lead{font-size:var(--t1)}
  .faces,.fig,.vo,.pair,.grounds,.fnc,.toy,.sealwrap,.csplit,.symsplit{grid-template-columns:1fr}
  .app{grid-template-columns:repeat(auto-fit,minmax(190px,1fr))}
  .wts{grid-template-columns:1fr}   /* three tiles, never an orphan row */
  .scale__r{grid-template-columns:1fr;gap:var(--s2)}
}

@media (prefers-reduced-motion:reduce){
  .hx *,.hx *::before,.hx *::after{
    animation-duration:1ms !important;animation-iteration-count:1 !important;
    transition-duration:1ms !important}
  .spec__r span{transform:none;opacity:1}
}

@media print{
  .rail,.gt,.grid,.hero canvas,.stage,.marquee{display:none}
  .hx{background:#fff;color:#000}
  .sheet{break-inside:avoid;padding-block:var(--s6)}
}
