@font-face{font-family:'Inter Tight';font-style:normal;font-weight:300;font-display:swap;
  src:url('../font/inter-tight-latin-300-normal.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;}
@font-face{font-family:'Inter Tight';font-style:normal;font-weight:400;font-display:swap;
  src:url('../font/inter-tight-latin-400-normal.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;}
@font-face{font-family:'Inter Tight';font-style:normal;font-weight:500;font-display:swap;
  src:url('../font/inter-tight-latin-500-normal.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;}
@font-face{font-family:'Inter Tight';font-style:normal;font-weight:600;font-display:swap;
  src:url('../font/inter-tight-latin-600-normal.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;}
@font-face{font-family:'JetBrains Mono';font-style:normal;font-weight:400;font-display:swap;
  src:url('../font/jetbrains-mono-latin-400-normal.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;}
@font-face{font-family:'JetBrains Mono';font-style:normal;font-weight:500;font-display:swap;
  src:url('../font/jetbrains-mono-latin-500-normal.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;}

/* ═══════════════════════════════════════════════════════════════
   NA:EUM — smart ring platform
   The page has no brand colour. Every hue on it is a light source
   that exists on the product: the indicator LED, and nothing else.
   ═══════════════════════════════════════════════════════════════ */

:root {
  --ink:      #06070A;
  --ink-1:    #0B0D12;
  --ink-2:    #131721;
  --pap:      #E9EBEF;
  --pap-1:    #F4F5F7;
  --pap-2:    #DBDEE4;

  --led:      #3CE08A;
  --led-amber:#F2A14B;
  /* --led is the LED's own colour and only ever sits on the dark ground,
     where it reads at 11.7:1. The film crosses to a light ground mid-scroll
     and the same green falls to 1.4:1 — invisible. --acc is the accent that
     follows the ground it lands on: 5.3:1 on the light half. */
  --acc:      var(--led);

  --fg:       #EEF0F4;
  --fg-2:     #A3ABB8;
  --fg-3:     #7C8492;
  --line:     rgb(255 255 255 / .11);
  --line-2:   rgb(255 255 255 / .055);
  --bg:       var(--ink);
  --surface:  #0E1117;

  --sans: 'Inter Tight', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --mono: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;

  --pad: clamp(1.25rem, 4.4vw, 4.5rem);
  --measure: 34ch;
  --e: cubic-bezier(.22,.61,.36,1);
  --mast-h: 66px;
}

[data-tone="light"] {
  --acc:    #0C6E40;
  --fg:     #0B0D12;
  --fg-2:   #545C69;
  --fg-3:   #5E6675;
  --line:   rgb(6 7 10 / .16);
  --line-2: rgb(6 7 10 / .08);
  --bg:     var(--pap);
}

/* ── reset ─────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background: var(--ink);
  color: var(--fg);
  font-family: var(--sans);
  font-size: clamp(.95rem, .35vw + .86rem, 1.06rem);
  line-height: 1.62;
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: clip;
}

h1, h2, h3 {
  text-wrap: balance; margin: 0; font-weight: 400; letter-spacing: -.035em; line-height: 1.03; }
h1 { font-size: clamp(2.35rem, 5.1vw, 4.5rem); }
h2 { font-size: clamp(1.75rem, 3.4vw, 2.75rem); }
h3 { font-size: clamp(1.05rem, 1.3vw, 1.22rem); letter-spacing: -.015em; }
p  { margin: 0; }
img, svg, canvas { display: block; max-width: 100%; }
.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }

::selection { background: var(--led); color: #04150C; }

:focus-visible {
  outline: 2px solid var(--acc);
  outline-offset: 3px;
  border-radius: 2px;
}

.skip {
  position: fixed; z-index: 200; top: .55rem; left: .55rem;
  padding: .65rem 1rem; background: var(--fg); color: var(--ink);
  font-size: .85rem; text-decoration: none; border-radius: 3px;
  transform: translateY(-160%);
  transition: transform .2s var(--e);
}
.skip:focus-visible { transform: none; }

/* ── shared bits ───────────────────────────────────────────── */
.eyebrow {
  font-family: var(--mono);
  font-size: .69rem;
  letter-spacing: .17em;
  text-transform: uppercase;
  color: var(--fg-3);
  margin-bottom: 1.1rem;
}
.eyebrow i, .mark__wd i, .foot__mark i { font-style: normal; opacity: .45; }

.btn {
  --btn-fg: var(--fg); --btn-bg: transparent; --btn-bd: var(--line);
  display: inline-flex; align-items: center; gap: .55rem;
  padding: .58rem 1.05rem;
  font: 500 .87rem/1 var(--sans);
  letter-spacing: -.005em;
  color: var(--btn-fg); background: var(--btn-bg);
  border: 1px solid var(--btn-bd); border-radius: 2px;
  text-decoration: none; cursor: pointer;
  transition: background .18s var(--e), color .18s var(--e), border-color .18s var(--e);
}
.btn--solid { --btn-fg: var(--ink); --btn-bg: var(--fg); --btn-bd: var(--fg); }
[data-tone="light"] .btn--solid { --btn-fg: var(--pap-1); }
.btn--solid:hover { --btn-bg: var(--led); --btn-bd: var(--led); --btn-fg: #04150C; }
.btn--lg { padding: .82rem 1.5rem; font-size: .95rem; }

/* ── masthead ──────────────────────────────────────────────── */
.mast {
  position: fixed; inset: 0 0 auto; z-index: 100;
  height: var(--mast-h);
  backdrop-filter: blur(14px) saturate(1.3);
  background: color-mix(in oklab, var(--bg) 72%, transparent);
  border-bottom: 1px solid var(--line-2);
  transition: background .5s linear, border-color .5s linear;
}
.mast__in {
  height: 100%; padding-inline: var(--pad);
  display: flex; align-items: center; gap: clamp(1rem, 3vw, 2.5rem);
}
.mark {
  display: inline-flex; align-items: center; gap: .62rem;
  color: var(--fg); text-decoration: none;
  font: 500 .95rem/1 var(--sans); letter-spacing: .01em;
}
.mark__glyph { width: 26px; height: 26px; flex: none; }
.nav { margin-left: auto; display: flex; gap: clamp(.9rem, 2.2vw, 2rem); }
.nav a {
  position: relative; color: var(--fg-2); text-decoration: none;
  font-size: .87rem; padding-block: .3rem;
  transition: color .18s var(--e);
}
.nav a::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: 0;
  height: 1px; background: currentColor;
  transform: scaleX(0); transform-origin: left;
  transition: transform .26s var(--e);
}
.nav a:hover { color: var(--fg); }
.nav a:hover::after { transform: none; }
/* language switch — a pair of pills that borrow the masthead's tone, so it
   stays legible over both halves of the film */
.lang {
  display: inline-flex; align-items: center; gap: 2px;
  padding: 2px; border-radius: 999px; border: 1px solid var(--line); }
.lang button {
  appearance: none; background: none; border: 0; cursor: pointer;
  padding: .32rem .6rem; border-radius: 999px; color: var(--fg-3);
  font-family: var(--mono); font-size: .64rem; letter-spacing: .12em;
  transition: color .18s var(--e), background-color .18s var(--e); }
@media (hover: hover) { .lang button:hover { color: var(--fg); } }
.lang button[aria-pressed="true"] {
  background: color-mix(in oklab, var(--fg) 13%, transparent); color: var(--fg); }
.lang button:focus-visible { outline: 2px solid var(--acc); outline-offset: 2px; }

@media (max-width: 720px) {
  .nav { display: none; }
  .lang { margin-left: auto; }
  .mast .btn { margin-left: .55rem; }
}
@media (max-width: 460px) {
  .lang button { padding: .3rem .45rem; font-size: .6rem; letter-spacing: .08em; }
}

/* ═══════════════════ THE FILM ═══════════════════ */
#film {
  position: relative;
  height: 780vh;
  background: var(--bg);
  transition: background .55s linear;
}
.film__vp {
  position: sticky; top: 0;
  height: 100svh;
  overflow: clip;
}
#stage-canvas {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  opacity: 0;
  transition: opacity .9s var(--e);
}
.stage-ready #stage-canvas { opacity: 1; }
/* No WebGL: the film becomes an ordinary stacked page. The copy is the
   same copy — it is never conditional on the 3D running. */
.no-3d #film { height: auto; }
.no-3d .film__vp { position: static; height: auto; overflow: visible; }
.no-3d #stage-canvas,
.no-3d #labels,
.no-3d .film__rail,
.no-3d .load,
.no-3d .film__copy::before { display: none; }
.no-3d .film__copy { position: static; }
.no-3d .act {
  position: static; opacity: 1; transform: none;
  width: auto; max-width: 46rem;
  padding: clamp(3rem, 8vw, 6rem) var(--pad) 0;
  text-align: left;
}
.no-3d .act--hero { padding-top: clamp(5rem, 14vh, 9rem); }
.no-3d .act p { margin-left: 0; }
.no-3d .hint { display: none; }
.no-3d .fallback { margin-top: clamp(3rem, 8vw, 6rem); }

/* copy layer */
.film__copy { position: absolute; inset: 0; pointer-events: none; }
/* a whisper of the page's own colour from the reading edge, so the copy
   never has to compete with a specular highlight for contrast */
.film__copy::before {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(to right, var(--bg), transparent 52%);
  opacity: .72;
  transition: opacity .4s var(--e);
}
@media (max-width: 860px) {
  /* portrait: the copy sits at the foot, so the scrim rises from the bottom */
  .film__copy::before {
    background: linear-gradient(to top, var(--bg) 6%, color-mix(in oklab, var(--bg) 62%, transparent) 34%, transparent 62%);
    opacity: 1;
  }
}
.act {
  position: absolute;
  color: var(--fg);
  width: min(36rem, 84vw);
  opacity: 0;
  transform: translateY(16px);
  transition: opacity .5s var(--e), transform .62s var(--e);
  will-change: opacity, transform;
}
.act.is-live { opacity: 1; transform: none; }
.act p:not(.eyebrow):not(.hint):not(.flag) {
  margin-top: 1.15rem; max-width: var(--measure);
  color: var(--fg-2); font-size: .98rem; line-height: 1.66;
  /* `pretty` costs a little layout time and buys no line ending on a single
     orphaned word — which is the failure you actually notice in a 34ch
     column set over a product shot. */
  text-wrap: pretty;
}
/* a second paragraph is a second thought, so it gets air rather than a gap
   the same size as a line */
.act p + p:not(.flag):not(.hint) { margin-top: .85rem; }
.act h1 span { color: var(--fg-2); }

/* ── finish picker ────────────────────────────────────────────────
   The one control in the film. It lives in the charging scene because
   that is where the case fills the frame, and it has to be clickable —
   the copy layer above the canvas is pointer-events:none, so this puts
   them back on just this control. */
.finish {
  margin: clamp(1.6rem, 4vh, 2.4rem) 0 0; padding: 0; border: 0;
  display: flex; flex-wrap: wrap; gap: .4rem;
  pointer-events: auto;
}
.finish legend {
  padding: 0; margin-bottom: .7rem; float: left; width: 100%;
  font-family: var(--mono); font-size: .63rem;
  letter-spacing: .16em; text-transform: uppercase; color: var(--fg-3);
}
.finish label {
  position: relative;              /* keeps the hidden input inside its own chip */
  display: flex; align-items: center; gap: .5rem;
  padding: .38rem .7rem .38rem .45rem;
  border: 1px solid var(--line); border-radius: 999px;
  cursor: pointer; user-select: none;
  font-family: var(--mono); font-size: .63rem;
  letter-spacing: .1em; text-transform: uppercase; color: var(--fg-3);
  transition: border-color .18s var(--e), color .18s var(--e);
}
/* Visually hidden but still in its chip, so focus lands where the eye is
   and a click anywhere on the chip reaches the control. */
.finish input {
  position: absolute; inset: 0; width: 100%; height: 100%;
  margin: 0; opacity: 0; cursor: pointer; appearance: none;
}
.finish i {
  width: 13px; height: 13px; border-radius: 50%; flex: none;
  background: var(--sw);
  /* every swatch needs an edge: midnight vanishes on the dark ground and
     champagne all but vanishes on the light one */
  box-shadow: inset 0 0 0 1px rgb(255 255 255 / .22), 0 0 0 1px rgb(0 0 0 / .28);
}
@media (hover: hover) {
  .finish label:hover { border-color: var(--fg-3); color: var(--fg-2); }
}
.finish label:has(input:checked) { border-color: var(--fg-2); color: var(--fg); }
.finish label:has(input:focus-visible) { outline: 2px solid var(--acc); outline-offset: 2px; }
@media (max-width: 620px) { .finish label span { font-size: .6rem; } }
/* With no WebGL there is no cradle to recolour, so the control would be a
   dead end — it goes away rather than sitting there doing nothing. */
.no-3d .finish { display: none; }

.act--hero { left: var(--pad); bottom: clamp(3rem, 11vh, 7rem); width: min(45rem, 88vw); }
.act--hero .lede { font-size: clamp(1rem, 1.1vw, 1.15rem); color: var(--fg-2); max-width: 40ch; }
.act--l { left: var(--pad); top: 50%; transform: translateY(calc(-50% + 16px)); }
.act--l.is-live { transform: translateY(-50%); }
.act--r { right: var(--pad); top: 50%; transform: translateY(calc(-50% + 16px)); text-align: right; }
.act--r.is-live { transform: translateY(-50%); }
.act--r p { margin-left: auto; }

.hint {
  margin-top: clamp(1.6rem, 4vh, 2.6rem);
  display: flex; align-items: center; gap: .8rem;
  font-family: var(--mono); font-size: .7rem; letter-spacing: .04em;
  color: var(--fg-3);
}
.hint__rule {
  width: 44px; height: 1px; background: var(--fg-3); flex: none;
  transform-origin: left; animation: sweep 3.4s var(--e) infinite;
}
@keyframes sweep { 0%,100% { transform: scaleX(.4); opacity: .45; } 50% { transform: scaleX(1); opacity: 1; } }

.flag {
  margin-top: 1.4rem; display: flex; gap: .6rem; align-items: baseline;
  font-family: var(--mono); font-size: .69rem; line-height: 1.5;
  letter-spacing: .01em; color: var(--fg-3); max-width: 40ch;
}
.flag__d {
  width: 6px; height: 6px; border-radius: 50%; flex: none;
  background: var(--led-amber); translate: 0 -1px;
}

/* What the sensor reads, listed beside the product rather than wired to it */
.reads {
  margin: 1.35rem 0 0; padding: 0; list-style: none;
  display: flex; flex-wrap: wrap; gap: .45rem 1.35rem;
  font-family: var(--mono); font-size: .68rem;
  letter-spacing: .13em; text-transform: uppercase; color: var(--fg-2);
}

/* The assistant's three words are not a list, they are a sequence: the ring
   senses, a baseline forms, insight comes back. All three carry equal weight —
   each is a claim in its own right — and the arrows, set well back, do the
   work of showing the order. Only the last word takes the accent. */
.reads--flow { gap: .45rem .7rem; align-items: center; }
.reads--flow li { color: var(--fg); }
.reads--flow li:last-child { color: var(--acc); }
.reads--flow li:not(:last-child)::after {
  content: '→'; margin-left: .7rem; color: var(--fg-3); opacity: .7;
  font-size: 1.05em;
}


/* progress rail */
.film__rail {
  position: absolute; right: calc(var(--pad) * .42); top: 22vh; bottom: 22vh;
  width: 1px; background: var(--line);
}
.film__rail-fill {
  position: absolute; inset: 0 0 auto; height: 0;
  background: var(--fg-2);
}
@media (max-width: 900px) { .film__rail { display: none; } }

/* loading */
.load {
  position: absolute; left: var(--pad); bottom: clamp(3rem, 12vh, 8rem);
  display: flex; align-items: center; gap: .8rem;
  font-family: var(--mono); font-size: .7rem; letter-spacing: .08em;
  text-transform: uppercase; color: var(--fg-3);
  transition: opacity .5s var(--e);
}
.load__bar { width: 96px; height: 1px; background: var(--line); display: block; }
.load__bar i { display: block; height: 100%; width: calc(var(--p, 0) * 100%); background: var(--fg-2); transition: width .2s linear; }
.load.is-done { opacity: 0; }

/* The label layer is gone — see main.js. Nothing is drawn over the product
   any more, so the only rule left is the one that reserves the space. */
#labels { display: none; }

/* fallback stills */
.fallback { display: none; }
.no-3d .fallback {
  display: grid; gap: 1px; background: var(--line-2);
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
}
.no-3d .fallback img { width: 100%; height: auto; }

/* ═══════════════════ LEDGER ═══════════════════ */
.ledger {
  border-block: 1px solid var(--line-2);
  padding: clamp(2.4rem, 6vw, 4.4rem) var(--pad);
  background: var(--ink-1);
}
.ledger dl {
  margin: 0; display: grid; gap: clamp(1.6rem, 3vw, 2.5rem);
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
}
.ledger dt {
  font-family: var(--mono); font-size: .68rem; letter-spacing: .13em;
  text-transform: uppercase; color: var(--fg-3);
}
.ledger dd {
  margin: .5rem 0 0; font-size: clamp(2rem, 4vw, 3rem);
  letter-spacing: -.045em; font-weight: 300; font-variant-numeric: tabular-nums;
}
.ledger dd i { font-style: normal; font-size: .34em; margin-left: .35em; color: var(--fg-3); letter-spacing: 0; }
/* A number with no explanation under it is a number nobody can use. */
.ledger dl p {
  margin: .5rem 0 0; font-size: .84rem; line-height: 1.55;
  color: var(--fg-3); max-width: 26ch;
}
/* the asterisk on the battery figure has to lead somewhere */
.ledger__fn {
  margin: clamp(1.8rem, 4vw, 2.6rem) 0 0;
  font-family: var(--mono); font-size: .66rem; line-height: 1.7;
  color: var(--fg-3); max-width: 74ch;
}

/* ═══════════════════ WHAT IT DOES ═══════════════════ */
.grp {
  margin: clamp(2rem, 5vw, 3rem) 0 1.1rem;
  font-family: var(--mono); font-size: .69rem;
  letter-spacing: .15em; text-transform: uppercase; color: var(--fg-3);
  display: flex; align-items: center; gap: .8rem;
}
.grp::after { content: ''; flex: 1; height: 1px; background: var(--line-2); }
.grp--key { color: var(--led); }
.grp--key::after { background: color-mix(in oklab, var(--led) 30%, transparent); }

.feat {
  list-style: none; margin: 0; padding: 0;
  display: grid; gap: 1px; background: var(--line-2);
  border-block: 1px solid var(--line-2);
  grid-template-columns: 1fr;
}
.feat li {
  background: var(--bg); padding: 1.15rem clamp(.9rem, 1.6vw, 1.35rem);
  display: grid; gap: .34rem; align-content: start;
  transition: background .2s var(--e);
}
.feat b { font-weight: 400; font-size: 1rem; letter-spacing: -.012em; color: var(--fg); }
.feat em { font-style: normal; font-size: .855rem; line-height: 1.58; color: var(--fg-3); }
.feat em i { display: block; margin-top: .45rem; font-style: normal; color: var(--led-amber); font-size: .96em; }

/* Core sensing — ten cards, five across, no gaps left in the grid.
   The icon is a reading aid, not a picture: it sits inline with the title at
   roughly cap height, so the eye still lands on the word first. */
/* Ten cards, so the column count has to divide ten or the grid ends with a
   hole: 2 and 5, never 3 or 4. */
.feat--core { grid-template-columns: repeat(2, 1fr); }
@media (min-width: 1080px) { .feat--core { grid-template-columns: repeat(5, 1fr); } }
.feat__t {
  /* the icon rides the first line of the title, so a title that wraps to two
     lines does not drag the glyph down into the gap between them */
  display: flex; align-items: flex-start; gap: .55rem;
  margin: 0 0 .06rem;
}
.ico {
  width: 18px; height: 18px; flex: none;
  color: rgb(255 255 255 / .72);
  translate: 0 2px;                 /* optical: sit on the cap line, not the box */
  transition: color .2s var(--e);
}
@media (max-width: 620px) { .ico { width: 16px; height: 16px; } }

/* the four that carry the argument — typography first, no icons */
.feat--key { grid-template-columns: 1fr; }
@media (min-width: 700px)  { .feat--key { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1080px) { .feat--key { grid-template-columns: repeat(4, 1fr); } }
.feat--key { border-color: color-mix(in oklab, var(--led) 26%, transparent); }
.feat--key li { border-left: 2px solid var(--led); padding-left: calc(clamp(.9rem, 1.6vw, 1.35rem) - 2px); }
.feat--key em { color: var(--fg-2); }

/* Hover is a nudge, not an event: the icon takes the accent and the card
   lifts by a couple of per cent. Nothing moves. */
@media (hover: hover) {
  .feat li:hover { background: color-mix(in oklab, var(--fg) 3%, var(--bg)); }
  .feat--core li:hover .ico { color: var(--led); }
}

/* ═══════════════════ SHEETS ═══════════════════ */
.sheet { padding: clamp(4rem, 11vw, 8.5rem) var(--pad); border-bottom: 1px solid var(--line-2); }
.sheet__hd { max-width: 62ch; margin-bottom: clamp(2.4rem, 6vw, 4rem); }
.sheet__lede { margin-top: 1.3rem; color: var(--fg-2); max-width: 56ch; }
.sheet__fn { margin-top: 1.8rem; font-family: var(--mono); font-size: .69rem; color: var(--fg-3); max-width: 60ch; line-height: 1.7; }

.parts { list-style: none; margin: 0; padding: 0; counter-reset: p; border-top: 1px solid var(--line-2); }
.parts li {
  counter-increment: p;
  display: grid; align-items: baseline;
  grid-template-columns: 2.6rem minmax(9rem, 12rem) 1fr auto;
  gap: 0 1.2rem;
  padding: .95rem 0;
  border-bottom: 1px solid var(--line-2);
  transition: background .2s var(--e);
}
.parts li::before {
  content: counter(p, decimal-leading-zero);
  font-family: var(--mono); font-size: .72rem; color: var(--fg-3);
}
.parts li:hover { background: color-mix(in oklab, var(--fg) 3.5%, transparent); }
.parts b { font-weight: 500; }
.parts em { font-style: normal; color: var(--fg-2); font-size: .92rem; }
.parts span { font-family: var(--mono); font-size: .76rem; color: var(--fg-3); text-align: right; white-space: nowrap; }
@media (max-width: 780px) {
  .parts li { grid-template-columns: 2.2rem 1fr; }
  .parts em { grid-column: 2; }
  .parts span { grid-column: 2; text-align: left; margin-top: .2rem; }
}

/* specs */
.split { display: grid; gap: clamp(2rem, 4vw, 3.5rem); grid-template-columns: repeat(auto-fit, minmax(min(100%, 22rem), 1fr)); }
.spec h3 { display: flex; flex-wrap: wrap; align-items: center; gap: .7rem; margin-bottom: 1.4rem; }
.tag {
  font-family: var(--mono); font-size: .62rem; letter-spacing: .12em; text-transform: uppercase;
  padding: .3em .62em; border: 1px solid currentColor; border-radius: 2px; line-height: 1;
}
.tag--ok { color: var(--led); }
/* A figure we have not confirmed is shown as missing, never as a guess. */
td.pend { color: var(--led-amber); font-family: var(--mono); font-size: .82em;
  letter-spacing: .06em; text-transform: uppercase; }
.sheet__fn--warn { color: var(--fg-2); border-left: 2px solid var(--led-amber);
  padding-left: .9rem; font-family: var(--sans); font-size: .88rem; }
.tag--wip { color: var(--led-amber); }
.spec table { width: 100%; border-collapse: collapse; }
.spec tr { border-top: 1px solid var(--line-2); }
.spec tr:last-child { border-bottom: 1px solid var(--line-2); }
.spec th, .spec td { text-align: left; padding: .78rem 0; font-weight: 400; vertical-align: baseline; }
.spec td { padding-right: .4rem; }
.spec th { color: var(--fg-3); font-size: .87rem; width: 46%; padding-right: 1rem; }
.spec td { font-family: var(--mono); font-size: .82rem; font-variant-numeric: tabular-nums; }
.spec td i { font-style: normal; color: var(--fg-3); }
.spec--soft table { opacity: .92; }
.spec__note { margin-top: 1.3rem; font-size: .85rem; color: var(--fg-3); max-width: 44ch; line-height: 1.7; }

/* ═══════════════════ CONTACT ═══════════════════ */
.contact {
  padding: clamp(4rem, 11vw, 8.5rem) var(--pad);
  display: grid; gap: clamp(2.5rem, 6vw, 5rem);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 24rem), 1fr));
  background: var(--ink-1);
}
.contact__hd p:not(.eyebrow) { margin-top: 1.4rem; color: var(--fg-2); max-width: 46ch; }
.form { display: grid; gap: 1.15rem 1.2rem; grid-template-columns: 1fr 1fr; align-content: start; }
.field { display: grid; gap: .45rem; }
.field--wide, .form__err, .form .btn, .form__alt { grid-column: 1 / -1; }
.field label { font-family: var(--mono); font-size: .68rem; letter-spacing: .12em; text-transform: uppercase; color: var(--fg-3); }
.field input, .field textarea, .field select {
  font: 400 .95rem/1.5 var(--sans);
  color: var(--fg); background: transparent;
  border: 1px solid var(--line); border-radius: 2px;
  padding: .7rem .8rem; width: 100%;
  transition: border-color .18s var(--e);
}
.field select {
  appearance: none; cursor: pointer;
  /* the caret is drawn rather than fetched — one less asset */
  background-image: linear-gradient(45deg, transparent 50%, var(--fg-3) 50%),
                    linear-gradient(135deg, var(--fg-3) 50%, transparent 50%);
  background-position: calc(100% - 1.05rem) 55%, calc(100% - .75rem) 55%;
  background-size: 5px 5px, 5px 5px; background-repeat: no-repeat;
  padding-right: 2.2rem;
}
.field select option { background: var(--ink-1); color: var(--fg); }
.field input:hover, .field textarea:hover, .field select:hover { border-color: var(--fg-3); }
.field textarea { resize: vertical; min-height: 6.5rem; }
.form .btn { justify-self: start; }
.form__err { font-family: var(--mono); font-size: .74rem; color: var(--led-amber); }
.form__note { grid-column: 1 / -1; font-size: .85rem; line-height: 1.7; color: var(--fg-2); }
.form__note a { color: var(--fg); }
.form__alt { font-size: .85rem; color: var(--fg-3); }
.form__alt a { color: var(--fg-2); }
@media (max-width: 560px) { .form { grid-template-columns: 1fr; } }

/* ═══════════════════ FOOT ═══════════════════ */
.foot { padding: clamp(3rem, 7vw, 5rem) var(--pad); border-top: 1px solid var(--line-2); }
/* The footer spans the full padded width so the bottom bar can put the
   social marks against the right edge; the reading measure is capped on the
   paragraph that needs it rather than on the whole column. */
.foot__in { display: grid; gap: 1.6rem; }
.foot__mark { display: flex; align-items: center; gap: .6rem; font-size: .9rem; }
.foot__mark svg { width: 22px; height: 22px; flex: none; }
/* the company particulars a Korean site is expected to carry, set as a
   definition list so the label and the value stay bound together */
.foot__co { display: flex; flex-wrap: wrap; gap: .5rem 1.6rem; margin: 0; }
.foot__co div { display: flex; align-items: baseline; gap: .55rem; }
.foot__co dt {
  font-family: var(--mono); font-size: .66rem; letter-spacing: .12em;
  text-transform: uppercase; color: var(--fg-3); white-space: nowrap; }
.foot__co dd { margin: 0; font-size: .82rem; color: var(--fg-2); }
@media (max-width: 560px) { .foot__co div { flex-direction: column; gap: .15rem; } }

.foot__legal { font-size: .82rem; line-height: 1.75; color: var(--fg-2); max-width: 72ch; }
.foot__bar {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: 1.2rem 2rem; justify-content: space-between; }
.foot__meta { display: flex; flex-wrap: wrap; gap: 1.2rem; font-family: var(--mono); font-size: .7rem; color: var(--fg-3); }

/* social — solid glyphs rather than the page's line icons, because that is
   how these marks are read; they sit at the footer's own weight until the
   pointer arrives */
.foot__social { list-style: none; margin: 0; padding: 0; display: flex; gap: .4rem; }
.foot__social a {
  display: grid; place-items: center; width: 2.7rem; height: 2.7rem;
  border-radius: 50%; color: var(--fg-3);
  transition: color .18s var(--e), background-color .18s var(--e); }
.foot__social svg { width: 1.4rem; height: 1.4rem; }
@media (hover: hover) {
  .foot__social a:hover { color: var(--fg); background: color-mix(in oklab, var(--fg) 9%, transparent); }
}
.foot__social a:focus-visible { outline: 2px solid var(--acc); outline-offset: 2px; }
/* until a profile exists the icon is present but inert, rather than a link
   that goes nowhere */
.foot__social a[data-pending] { opacity: .5; cursor: not-allowed; }
@media (hover: hover) { .foot__social a[data-pending]:hover { color: var(--fg-3); background: none; } }
.foot__meta a { color: var(--fg-2); }
/* the privacy policy has no URL yet — the slot is visible but inert, so it
   cannot ship as a link that goes nowhere without someone noticing */
.foot__meta a[data-pending] { color: var(--fg-3); text-decoration-style: dotted; cursor: not-allowed; }
.foot__meta a[data-pending]::after { content: ' (pending)'; font-size: .9em; opacity: .7; }

/* ═══════════════════ narrow ═══════════════════ */
@media (max-width: 860px) {
  #film { height: 700vh; }
  .act--l, .act--r {
    left: var(--pad); right: var(--pad); width: auto;
    top: auto; bottom: clamp(2.5rem, 9vh, 5rem);
    text-align: left; transform: translateY(16px);
  }
  .act--l.is-live, .act--r.is-live { transform: none; }
  .act--r p { margin-left: 0; }
  .act--hero { bottom: clamp(2.5rem, 9vh, 5rem); }

}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important; animation-iteration-count: 1 !important;
    transition-duration: .12s !important;
  }
}

@media (prefers-contrast: more) {
  :root { --fg-2: #D2D7DE; --fg-3: #AEB6C1; --line: rgb(255 255 255 / .3); --line-2: rgb(255 255 255 / .18); }
  [data-tone="light"] { --fg-2: #262C36; --fg-3: #3C4450; --line: rgb(6 7 10 / .4); --line-2: rgb(6 7 10 / .22); }
}

/* ── scroll reveals (added by ui.js) ─────────────────────────── */
.rise { opacity: 0; transform: translateY(14px); }
.rise.in {
  opacity: 1; transform: none;
  transition: opacity .55s var(--e) var(--d, 0ms), transform .68s var(--e) var(--d, 0ms);
}
@media (prefers-reduced-motion: reduce) { .rise { opacity: 1; transform: none; } }

.form__ok { font-size: 1rem; color: var(--fg); max-width: 40ch; line-height: 1.7; }

/* the masthead borrows the film's tone while the film is behind it */
.mast[data-tone="light"] {
  --fg: #0B0D12; --fg-2: #545C69; --fg-3: #5E6675;
  --line-2: rgb(6 7 10 / .1);
  background: color-mix(in oklab, var(--pap) 72%, transparent);
  color: var(--fg);
}
.mast[data-tone="light"] .btn--solid { --btn-fg: var(--pap-1); --btn-bg: #0B0D12; --btn-bd: #0B0D12; }

/* ══════════════════════════ THE APP ══════════════════════════
   Concept UI, drawn rather than photographed. Every screen below is HTML,
   CSS and one SVG path on the page's own tokens — so it stays sharp at any
   size, keeps the site's palette, and can be corrected in a text editor
   when the shipping interface settles. Nothing here is a screenshot.       */

.app__stage {
  display: grid;
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: center;
  margin-bottom: clamp(3.5rem, 9vw, 7rem);
}
@media (min-width: 900px) { .app__stage { grid-template-columns: auto 1fr; } }
.app__say { max-width: 46ch; }
.app__say p { margin-top: 1.25rem; color: var(--fg-2); }
.app__say .reads { margin-top: 1.7rem; }

.app__cards { display: grid; gap: clamp(2.4rem, 5vw, 3.4rem); }
@media (min-width: 760px) { .app__cards { grid-template-columns: repeat(3, 1fr); } }
.app__card { display: grid; gap: 1.6rem; justify-items: start; }
.app__cap b {
  display: block; font-weight: 400; font-size: 1rem;
  letter-spacing: -.012em; color: var(--fg); margin-bottom: .4rem; }
.app__cap em { font-style: normal; font-size: .855rem; line-height: 1.58; color: var(--fg-3); }
.app__cap .k {
  display: block; margin-bottom: .65rem;
  font-family: var(--mono); font-size: .69rem; letter-spacing: .17em;
  text-transform: uppercase; color: var(--fg-3); }

/* ── the handset ───────────────────────────────────────────── */
.phone {
  --w: 232px;
  width: var(--w); aspect-ratio: 9 / 19; flex: none;
  padding: calc(var(--w) * .026);
  border-radius: calc(var(--w) * .162);
  background: linear-gradient(152deg, #39404C 0%, #191D25 26%, #0B0D12 68%, #2B313B 100%);
  box-shadow: 0 0 0 1px rgb(255 255 255 / .06), 0 34px 68px -34px rgb(0 0 0 / .9);
}
.app__stage .phone { --w: clamp(212px, 21vw, 250px); }
.app__card .phone { --w: clamp(200px, 20vw, 228px); }

.phone__scr {
  position: relative; height: 100%; overflow: hidden;
  border-radius: calc(var(--w) * .138);
  background: #090B10;
  display: flex; flex-direction: column; gap: .85em;
  padding: calc(var(--w) * .075) calc(var(--w) * .058) calc(var(--w) * .052);
  font-size: calc(var(--w) * .0455);
  line-height: 1.45; color: var(--fg);
}
.phone__isl {
  position: absolute; top: calc(var(--w) * .03); left: 50%; transform: translateX(-50%);
  width: 27%; height: calc(var(--w) * .05); border-radius: 99px; background: #040507; }
.phone__bar {
  display: flex; justify-content: space-between; align-items: center;
  font-family: var(--mono); font-size: .74em; letter-spacing: .04em; color: var(--fg-3); }
.phone__bat {
  display: inline-block; width: 1.55em; height: .78em; border-radius: .18em;
  border: 1px solid currentColor; padding: .1em; }
.phone__bat i { display: block; height: 100%; width: 72%; background: currentColor; border-radius: .06em; }

.scr { display: flex; flex-direction: column; flex: 1; min-height: 0; }
.scr__k {
  font-family: var(--mono); font-size: .72em; letter-spacing: .14em;
  text-transform: uppercase; color: var(--fg-3); }
.scr__k--warn { color: var(--led-amber); }

/* live measurement ------------------------------------------- */
.scr--live { gap: .55em; }
.scr__hr { display: flex; align-items: flex-end; gap: .4em; margin-top: .05em; }
.scr__hr i { font-style: normal; font-family: var(--mono); font-size: .8em; color: var(--fg-3);
  padding-bottom: .35em; }
.scr__k--mt { margin-top: .35em; }
.reel { display: block; overflow: hidden; font-size: 2.4em; height: 1em; }
.reel span { display: block; animation: reel 9s var(--e) infinite; }
.reel b {
  display: block; height: 1em; line-height: 1; font-weight: 300;
  letter-spacing: -.04em; font-variant-numeric: tabular-nums; }
@keyframes reel {
  0%,  20% { transform: translateY(0) }
  25%, 45% { transform: translateY(-1em) }
  50%, 70% { transform: translateY(-2em) }
  75%, 95% { transform: translateY(-3em) }
  100%     { transform: translateY(-4em) }
}
.wave { width: 100%; height: auto; overflow: visible; }
.wave__b { fill: none; stroke: var(--fg-3); stroke-width: 1.3; opacity: .32; }
.wave__h {
  fill: none; stroke: var(--led); stroke-width: 2.3; stroke-linecap: round;
  stroke-dasharray: 120 1000;
  filter: drop-shadow(0 0 3px rgb(60 224 138 / .55));
  animation: sweep 3.2s linear infinite; }
@keyframes sweep { from { stroke-dashoffset: 1120 } to { stroke-dashoffset: 0 } }

.scr__mini { list-style: none; margin: 0; padding: 0; display: flex; gap: .9em; }
.scr__mini li { flex: 1; }
.scr__mini b {
  display: block; font-weight: 400; font-size: 1.35em; letter-spacing: -.03em;
  font-variant-numeric: tabular-nums; }
.scr__mini em {
  font-style: normal; font-family: var(--mono); font-size: .68em;
  letter-spacing: .08em; text-transform: uppercase; color: var(--fg-3); }
.scr__run { height: 2px; border-radius: 2px; background: rgb(255 255 255 / .08); overflow: hidden; }
.scr__run i { display: block; height: 100%; width: 38%; border-radius: 2px;
  background: var(--led); animation: run 2.8s var(--e) infinite; }
@keyframes run { 0% { transform: translateX(-105%) } 100% { transform: translateX(275%) } }
.scr__note { font-family: var(--mono); font-size: .7em; color: var(--fg-3); }
.scr__sp { flex: 1; min-height: .4em; }

/* notifications ---------------------------------------------- */
.scr--lock { gap: .5em; }
.scr__time { font-size: 3.1em; font-weight: 300; letter-spacing: -.045em; line-height: 1; }
.scr__date { font-size: .92em; color: var(--fg-2); }
.note {
  border-radius: .85em; padding: .8em .85em;
  background: rgb(255 255 255 / .075);
  border: 1px solid rgb(255 255 255 / .06); }
.note + .note { margin-top: .5em; }
/* The older notice recedes by weight rather than by veiling: dimming the
   whole card with opacity took its text under 3:1, and it is still text. */
.note--2 { background: rgb(255 255 255 / .04); border-color: rgb(255 255 255 / .045); }
.note--2 .note__t { color: var(--fg-2); }
.note__hd {
  display: flex; align-items: center; gap: .45em;
  font-family: var(--mono); font-size: .68em; letter-spacing: .12em;
  text-transform: uppercase; color: var(--fg-2); margin-bottom: .5em; }
.note__hd svg { width: 1.1em; height: 1.1em; flex: none; color: var(--fg-2); }
.note__hd i { font-style: normal; margin-left: auto; letter-spacing: .06em; }
.note__t { font-size: 1.02em; letter-spacing: -.015em; }
.note__b { font-size: .88em; color: var(--fg-2); margin-top: .3em; }

/* fall detection --------------------------------------------- */
.scr--sos { gap: .5em; text-align: center; align-items: center; }
/* the alert state colours the whole screen, not just a badge */
.scr--sos::before {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(112% 62% at 50% 34%, rgb(242 161 75 / .13), transparent 72%); }
.scr--sos > * { position: relative; }
.sos__mark { position: relative; width: 6.2em; height: 6.2em; margin: 0 0 .55em; }
.sos__mark span, .sos__mark svg { position: absolute; inset: 0; }
.sos__mark span {
  border-radius: 50%; border: 1px solid var(--led-amber); opacity: .5;
  animation: sos 2.4s var(--e) infinite; }
.sos__mark span:nth-child(2) { animation-delay: .8s }
@keyframes sos {
  0%   { transform: scale(.62); opacity: .65 }
  100% { transform: scale(1.05); opacity: 0 }
}
.sos__mark svg { width: 100%; height: 100%; color: var(--led-amber); padding: 1.15em; }
.sos__t { font-size: 1.5em; letter-spacing: -.03em; line-height: 1.15; }
.sos__b { font-size: .9em; color: var(--fg-2); }
.sos__count {
  font-family: var(--mono); font-size: .74em; letter-spacing: .1em;
  text-transform: uppercase; color: var(--led-amber); margin-top: .2em; }
.sos__btns { display: grid; gap: .45em; width: 100%; margin-top: .5em; }
.sos__btn {
  display: block; padding: .68em; border-radius: .7em; font-size: .95em;
  border: 1px solid rgb(255 255 255 / .16); color: var(--fg); }
.sos__btn--go { background: var(--led-amber); border-color: var(--led-amber); color: #1B1204; }

/* report ------------------------------------------------------ */
.scr--rep { gap: .6em; }
.seg {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 2px; padding: 2px;
  border-radius: .55em; background: rgb(255 255 255 / .06);
  font-family: var(--mono); font-size: .66em; letter-spacing: .1em; text-transform: uppercase; }
.seg span { padding: .5em 0; text-align: center; border-radius: .42em; color: var(--fg-3); }
.seg .is-on { background: rgb(255 255 255 / .1); color: var(--fg); }
.rep__t { font-size: 1.12em; letter-spacing: -.02em; line-height: 1.3; }
.bars { display: flex; align-items: flex-end; gap: .38em; height: 4.6em; margin-top: .15em; }
.bars i {
  flex: 1; display: block; height: var(--h); border-radius: .18em;
  background: rgb(255 255 255 / .17);
  transform-origin: bottom;
  animation: grow .75s var(--e) both; }
.bars .low { background: var(--led-amber); }
@keyframes grow { from { transform: scaleY(0) } to { transform: scaleY(1) } }
.rep__days {
  display: flex; justify-content: space-between;
  font-family: var(--mono); font-size: .64em; letter-spacing: .06em; color: var(--fg-3); }
.rep__rows { list-style: none; margin: .3em 0 0; padding: 0; }
.rep__rows li {
  display: flex; justify-content: space-between; gap: 1em;
  padding: .55em 0; border-top: 1px solid rgb(255 255 255 / .07);
  font-size: .9em; }
.rep__rows em { font-style: normal; color: var(--fg-3); }
.rep__rows b { font-weight: 400; font-family: var(--mono); font-size: .92em; font-variant-numeric: tabular-nums; }
.rep__rows .up { color: var(--led-amber); }
.rep__rows .dn { color: var(--led-amber); }

/* the screens only animate while the section is on-screen; the gate is
   added by ui.js, so without JS everything simply runs */
.app.is-gated .phone *  { animation-play-state: paused; }
.app.is-gated.is-on .phone * { animation-play-state: running; }
@media (prefers-reduced-motion: reduce) {
  .app .phone * { animation: none !important; }
}
/* on a narrow screen the handset is the picture, so it centres and grows;
   the caption stays full width and left aligned under it */
@media (max-width: 899px) {
  .app__stage .phone { justify-self: center; --w: min(258px, 66vw); }
}
@media (max-width: 759px) {
  .app__card { justify-items: stretch; }
  .app__card .phone { justify-self: center; --w: min(258px, 66vw); }
}

/* the app's own tab bar — the home glyph is the ring itself */
.tabs {
  display: flex; gap: .2em; margin-top: .75em; padding-top: .7em;
  border-top: 1px solid rgb(255 255 255 / .07); }
.tabs span {
  flex: 1; display: grid; justify-items: center; gap: .35em;
  font-family: var(--mono); font-size: .6em; letter-spacing: .09em;
  text-transform: uppercase; color: var(--fg-3); }
.tabs svg { width: 2.1em; height: 2.1em; }
.tabs .is-on { color: var(--fg); }

/* ── the laptop, and the dashboard inside it ─────────────────
   Same rule as the handset: the chassis is CSS, the page inside it is
   markup on the site's own tokens. Everything within the screen is sized
   against the shell's own width — container query units, not a custom
   property, because a percentage inside a font-size calc() resolves
   against the inherited font size and collapsed the whole screen to a
   fraction of a pixel. */
.lap { container-type: inline-size; width: 100%; max-width: 860px; }
.lap__lid {
  padding: 1.2cqw 1.2cqw 1.9cqw;
  border-radius: 1.7cqw 1.7cqw .5cqw .5cqw;
  background: linear-gradient(152deg, #39404C 0%, #1A1E26 24%, #0C0E13 70%, #2B313B 100%);
  box-shadow: 0 0 0 1px rgb(255 255 255 / .06), 0 40px 70px -40px rgb(0 0 0 / .9); }
.lap__scr {
  aspect-ratio: 16 / 10; overflow: hidden;
  border-radius: .6cqw;
  background: #090B10;
  display: flex; flex-direction: column;
  padding: 2.6cqw 2.8cqw;
  font-size: 1.62cqw; line-height: 1.4; color: var(--fg); }
.lap__base {
  display: block; position: relative;
  width: 107%; margin-left: -3.5%;
  height: 1.25cqw;
  border-radius: 0 0 1cqw 1cqw;
  background: linear-gradient(180deg, #262B35, #14171E 58%, #0A0C10); }
.lap__base i {
  position: absolute; top: 0; left: 50%; transform: translateX(-50%);
  width: 12%; height: 42%;
  border-radius: 0 0 .6cqw .6cqw;
  background: rgb(0 0 0 / .5); }

/* the console screen — a grid of cards, all of it markup and SVG */
.con { display: flex; gap: 1.5em; flex: 1; min-height: 0; }

.con__side { width: 7.2em; flex: none; display: flex; flex-direction: column; }
.con__brand { display: flex; align-items: center; gap: .5em; margin-bottom: 1.9em; }
.con__brand svg { width: 1.35em; height: 1.35em; color: var(--fg); flex: none; }
.con__brand span { font-size: .92em; letter-spacing: -.01em; }
.con__side ul { list-style: none; margin: 0; padding: 0; display: grid; gap: .35em; }
.con__side li {
  display: flex; align-items: center; gap: .6em;
  padding: .5em .6em; border-radius: .45em;
  font-family: var(--mono); font-size: .72em; letter-spacing: .07em;
  text-transform: uppercase; color: var(--fg-3); }
.con__side li svg { width: 1.5em; height: 1.5em; flex: none; }
.con__side .is-on { background: rgb(255 255 255 / .075); color: var(--fg); }
.con__ver {
  margin-top: auto; font-family: var(--mono); font-size: .66em;
  letter-spacing: .1em; color: var(--fg-3); }

.con__main { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.con__bar { display: flex; align-items: center; gap: .7em; }
.con__bar b { font-weight: 400; font-size: 1.12em; letter-spacing: -.02em; margin-right: .3em; }
.con__chip {
  padding: .3em .65em; border-radius: .4em;
  border: 1px solid rgb(255 255 255 / .11);
  font-family: var(--mono); font-size: .68em; letter-spacing: .07em; color: var(--fg-2); }
.con__bar em {
  margin-left: auto; display: flex; align-items: center; gap: .5em;
  font-style: normal; font-family: var(--mono); font-size: .68em;
  letter-spacing: .15em; text-transform: uppercase; color: var(--fg-2); }
.con__bar em::before {
  content: ''; width: .5em; height: .5em; border-radius: 50%;
  background: var(--led); animation: blip 2.2s var(--e) infinite; }
@keyframes blip { 0%, 100% { opacity: 1 } 50% { opacity: .25 } }

.con__kpi {
  list-style: none; margin: 1em 0; padding: 0;
  display: grid; grid-template-columns: repeat(4, 1fr); gap: .8em; }
.con__kpi li {
  padding: .7em .8em; border-radius: .5em;
  background: rgb(255 255 255 / .04);
  border: 1px solid rgb(255 255 255 / .055);
  display: grid; gap: .18em; }
.con__kpi span {
  font-family: var(--mono); font-size: .66em; letter-spacing: .1em;
  text-transform: uppercase; color: var(--fg-3); }
.con__kpi b { font-weight: 400; font-size: 1.5em; letter-spacing: -.035em; }
.con__kpi u {
  text-decoration: none; font-family: var(--mono); font-size: .42em;
  letter-spacing: .06em; color: var(--fg-3); margin-left: .45em; }
.con__kpi i { font-style: normal; font-size: .72em; color: var(--fg-3); }
.con__kpi .warn { color: var(--led-amber); }

/* one row, capped at the space the screen actually has, so a card can never
   spill past the bezel */
.con__body { flex: 1; min-height: 0; display: grid;
  grid-template-columns: 8.6em 1.55fr 1.15fr;
  grid-template-rows: minmax(0, 1fr); gap: .8em; }
.con__col { display: grid; gap: .8em; align-content: start; min-height: 0; }
.con__card {
  padding: .75em .85em .8em; border-radius: .5em;
  background: rgb(255 255 255 / .03);
  border: 1px solid rgb(255 255 255 / .055); }
.con__ck {
  display: flex; align-items: baseline; gap: .5em; white-space: nowrap;
  font-family: var(--mono); font-size: .66em; letter-spacing: .12em;
  text-transform: uppercase; color: var(--fg-2); margin-bottom: .55em; }
.con__ck span { color: var(--fg-3); overflow: hidden; text-overflow: ellipsis; }
.con__ck b { margin-left: auto; font-weight: 400; color: var(--fg); letter-spacing: .06em; }

.con__strip, .con__ch { width: 100%; height: auto; display: block; }
.con__sb { fill: none; stroke: var(--fg-3); stroke-width: 1.4; opacity: .3; }
.con__sh {
  fill: none; stroke: var(--led); stroke-width: 2.1; stroke-linecap: round;
  stroke-dasharray: 130 1000;
  filter: drop-shadow(0 0 3px rgb(60 224 138 / .5));
  animation: sweep 3.4s linear infinite; }
.con__night { fill: rgb(255 255 255 / .035); }
.con__g { stroke: rgb(255 255 255 / .07); stroke-width: 1; }
.con__band { fill: color-mix(in oklab, var(--led) 20%, transparent); }
.con__line { fill: none; stroke: var(--led); stroke-width: 1.6; stroke-linejoin: round; }
.con__band--b { fill: rgb(255 255 255 / .1); }
.con__line--b { stroke: var(--fg-2); }
.con__ax {
  display: flex; justify-content: space-between; margin-top: .3em;
  font-family: var(--mono); font-size: .64em; letter-spacing: .08em; color: var(--fg-3); }

.con__tbl { width: 100%; border-collapse: collapse; font-size: .74em; }
.con__tbl th {
  text-align: left; font-weight: 400; padding: 0 0 .5em;
  font-family: var(--mono); font-size: .88em; letter-spacing: .08em;
  text-transform: uppercase; color: var(--fg-3); }
.con__tbl td {
  padding: .4em 0; border-top: 1px solid rgb(255 255 255 / .06);
  font-family: var(--mono); font-variant-numeric: tabular-nums; color: var(--fg-2); }
.con__tbl td:first-child, .con__tbl th:first-child { width: 34%; }
.con__tbl td:last-child, .con__tbl th:last-child { text-align: right; }
.con__tbl .warn { color: var(--led-amber); }
.con__tbl .dim { color: var(--fg-3); }

/* three columns only once there is genuinely room for them; below that the
   laptop takes a row of its own rather than squeezing the copy */
/* the caption belongs to the laptop, so it keeps the laptop's measure
   rather than running the width of the column */
.app__dash { display: grid; gap: 1.6rem; justify-items: start; }
.app__dash .app__cap { max-width: min(860px, 62ch); }

/* Three columns only where the third one is wide enough for the console to
   stay readable — below that the laptop takes a row of its own and uses the
   full measure rather than shrinking its type into illegibility. */
@media (min-width: 1660px) {
  .app__stage { grid-template-columns: auto minmax(30ch, 42ch) minmax(0, 1fr); }
  .lap { max-width: 900px; }
}
@media (max-width: 1659px) {
  .app__dash { grid-column: 1 / -1; }
  .lap { max-width: 1000px; }
}
/* Below this the console cannot shrink further and stay readable, so the
   panel scrolls sideways within its own column instead of setting six-pixel
   type. The page itself never scrolls horizontally. */
.lap-wrap { width: 100%; max-width: 100%; }
@media (max-width: 719px) {
  .lap-wrap { overflow-x: auto; overscroll-behavior-x: contain; padding-bottom: .5rem; }
  .lap { width: 620px; max-width: none; }
}

/* ── the participant panel ─────────────────────────────────── */
.con__prof { display: flex; flex-direction: column; gap: .55em; }
.con__av {
  width: 2.9em; height: 2.9em; border-radius: 50%;
  display: grid; place-items: center;
  background: rgb(255 255 255 / .07);
  font-family: var(--mono); font-size: .82em; letter-spacing: .08em; color: var(--fg-2); }
.con__nm { font-size: 1.02em; letter-spacing: -.015em; line-height: 1.2; }
.con__id {
  font-family: var(--mono); font-size: .64em; letter-spacing: .07em;
  color: var(--fg-3); margin-bottom: .35em; }
.con__dl { margin: 0; display: grid; gap: .05em; }
.con__dl div {
  display: flex; justify-content: space-between; gap: .6em;
  padding: .3em 0; border-top: 1px solid rgb(255 255 255 / .06); }
.con__dl dt {
  font-family: var(--mono); font-size: .64em; letter-spacing: .08em;
  text-transform: uppercase; color: var(--fg-3); }
.con__dl dd {
  margin: 0; font-family: var(--mono); font-size: .68em;
  font-variant-numeric: tabular-nums; color: var(--fg-2); }
.con__state {
  margin-top: auto; padding: .4em .6em; border-radius: .35em;
  background: color-mix(in oklab, var(--led) 14%, transparent);
  font-family: var(--mono); font-size: .62em; letter-spacing: .12em;
  text-transform: uppercase; color: var(--led); text-align: center; }

.con__chip--demo { border-style: dashed; color: var(--fg-3); }
.con__g--base { stroke: rgb(255 255 255 / .16); stroke-dasharray: 3 4; }
.con__meal { stroke: rgb(255 255 255 / .10); stroke-width: 1; stroke-dasharray: 2 3; }
.con__line--hi { stroke: var(--led-amber); }
.con__line--lo { stroke: var(--fg-3); }
.con__line--me { stroke: var(--led); }
.con__fn {
  margin-top: .45em; font-family: var(--mono); font-size: .58em;
  line-height: 1.5; color: var(--fg-3); }

.con__bars { display: flex; align-items: flex-end; gap: .28em; height: 2.6em; margin-top: .25em; }
.con__bars i { flex: 1; height: var(--h); border-radius: 1.5px; background: rgb(255 255 255 / .17); }
.con__bars .on { background: var(--led); }

/* ── the assistant screens ───────────────────────────────────
   One shape repeated three times: the subject, the shape of the data, one
   sentence about it, and the smallest thing worth trying. The estimate line
   at the foot is not decoration — it is what keeps a trend a trend. */
.app__mid {
  max-width: 62ch;
  margin: clamp(3.5rem, 9vw, 6.5rem) 0 clamp(2.2rem, 5vw, 3.4rem); }
.app__mid p:not(.eyebrow) { margin-top: 1.25rem; color: var(--fg-2); max-width: 56ch; }

.scr--ai { gap: .5em; }
.ai__topic {
  display: flex; gap: .45em; align-items: baseline;
  font-size: 1.02em; letter-spacing: -.015em; }
.ai__topic i {
  font-style: normal; font-family: var(--mono); font-size: .66em;
  letter-spacing: .08em; color: var(--fg-3); }
.ai__ch { width: 100%; height: auto; display: block; margin: .15em 0 .1em; }
.ai__ch .con__line { stroke-width: 2.4; }

.ai__msg {
  border-radius: .85em; padding: .8em .85em;
  background: rgb(255 255 255 / .065);
  border: 1px solid rgb(255 255 255 / .06); }
.ai__from {
  display: flex; align-items: center; gap: .45em;
  font-family: var(--mono); font-size: .68em; letter-spacing: .12em;
  text-transform: uppercase; color: var(--fg-2); }
.ai__from svg { width: 1.1em; height: 1.1em; flex: none; }
.ai__t { margin-top: .55em; font-size: 1.02em; letter-spacing: -.015em; line-height: 1.32; }
.ai__b { margin-top: .4em; font-size: .87em; color: var(--fg-2); }

.ai__acts { display: grid; gap: .4em; margin-top: .15em; }
.ai__acts span {
  padding: .58em .75em; border-radius: .6em;
  border: 1px solid rgb(255 255 255 / .13);
  font-size: .9em; color: var(--fg); }
.ai__acts span:first-child { background: rgb(255 255 255 / .075); }
.ai__src {
  display: grid; gap: .28em; margin-top: .4em;
  font-family: var(--mono); font-size: .64em; letter-spacing: .12em;
  text-transform: uppercase; color: var(--fg-3); }
.ai__src i {
  font-style: normal; text-transform: none; letter-spacing: .05em;
  font-size: 1.06em; color: var(--fg-2); }

/* ── Korean typography ───────────────────────────────────────
   The Latin settings do not transfer. Tracking meant for small Latin caps
   opens gaps between syllable blocks; the display tightening crowds them;
   and without keep-all the browser will break a Korean word in half at the
   end of a line, which is how 없이 ended up as 없 / 이. */
:root[lang="ko"] { word-break: keep-all; }
:root[lang="ko"] h1,
:root[lang="ko"] h2,
:root[lang="ko"] h3 { letter-spacing: -.012em; line-height: 1.2; }
:root[lang="ko"] .eyebrow,
:root[lang="ko"] .grp,
:root[lang="ko"] .hint,
:root[lang="ko"] .reads,
:root[lang="ko"] .flag,
:root[lang="ko"] .app__cap .k,
:root[lang="ko"] .ledger dt,
:root[lang="ko"] .field label,
:root[lang="ko"] .foot__meta,
:root[lang="ko"] .finish legend,
:root[lang="ko"] .finish label span,
:root[lang="ko"] .tag { letter-spacing: .04em; }
/* JetBrains Mono carries no Hangul, so these fall back mid-string anyway —
   set the fallback deliberately rather than letting it happen by accident */
:root[lang="ko"] .spec td,
:root[lang="ko"] .ledger dl p { font-family: var(--sans); font-size: .88rem; }

/* ── the policy pages ────────────────────────────────────────
   Same shell, no film: one column at a reading measure, sections numbered
   by their own headings rather than by decoration. */
.doc-page { padding-top: var(--mast-h); }
.doc { padding: clamp(3rem, 8vw, 6rem) var(--pad) clamp(4rem, 10vw, 7rem); }
.doc__hd { max-width: 62ch; margin-bottom: clamp(2.4rem, 6vw, 3.6rem); }
.doc__hd h1 { font-size: clamp(2rem, 4vw, 3rem); margin-top: .3rem; }
.doc__lede { margin-top: 1.4rem; color: var(--fg-2); max-width: 58ch; }
.doc__meta {
  margin-top: 1.6rem; font-family: var(--mono); font-size: .69rem;
  letter-spacing: .12em; text-transform: uppercase; color: var(--fg-3); }
.doc__body { max-width: 68ch; display: grid; gap: clamp(1.8rem, 4vw, 2.6rem); }
.doc__s { display: grid; gap: .8rem; }
.doc__s h2 {
  font-size: clamp(1.02rem, 1.2vw, 1.16rem); letter-spacing: -.012em;
  color: var(--fg); }
.doc__s p { color: var(--fg-2); font-size: .95rem; line-height: 1.75; }
.doc__s a { color: var(--fg); }
