@layer tokens, base, parts, places;

/* ------------------------------------------------------------------ tokens */
@layer tokens {
  /* Registered so the room's light interpolates when the page on the phone changes. */
  @property --glow { syntax: '<color>'; inherits: true; initial-value: #5b6672; }
  :root {
    /* Dark first: the room the phone sits in. Neutrals carry a few degrees of the
       product's green so state sits in the same family as the ground. There is no
       accent: green is live or granted, amber is staged, red is refused. */
    --ground: #0F1113;  --panel: #16191C;  --sunk: #1B1F22;
    --ink: #E9EBED;     --ink-2: #A0A7AF;  --ink-3: #767D85;
    --rule: #262A2E;    --rule-2: #1D2124;
    --live: #47C596;    --staged: #D9A23B; --refused: #E4796B;
    --device: #0B0C0E;
    --console: #0B0D0F; --console-2: #111417; --console-ink: #E9EBED; --console-dim: #767D85;
    --console-add: #47C596; --console-del: #E4796B;
    --ansi-0: #6B7075; --ansi-1: #E4796B; --ansi-2: #47C596; --ansi-3: #D9A23B; --ansi-4: #6CA8F0; --ansi-5: #C48AE0; --ansi-6: #5CC8D8; --ansi-7: #E9EBED;

    /* the light behind the phone: caused by the screen, coloured by the page it shows */
    --glow: #5b6672; --glow-a: .5; --glow-a-busy: .78;
    --presence: rgba(255, 255, 255, .72);

    /* Two faces. The host's own sans, because an instrument should be honest
       and a web font costs a request; Roboto is vendored on this origin for
       hosts that have no SF or Segoe. Mono is for values a machine produced. */
    --sans: -apple-system, "SF Pro Text", "Segoe UI", Roboto, system-ui, "Helvetica Neue", Helvetica, Arial, sans-serif;
    --mono: ui-monospace, "SF Mono", Menlo, Consolas, "DejaVu Sans Mono", monospace;

    --type-title: 600 28px/1.15 var(--sans);       --track-title: -0.02em;
    --type-section: 600 19px/1.30 var(--sans);     --track-section: -0.01em;
    --type-body: 400 15px/1.55 var(--sans);
    --type-interface: 400 13px/1.40 var(--sans);
    --type-interface-strong: 500 13px/1.40 var(--sans);
    --type-caption: 400 11.5px/1.40 var(--sans);
    --type-data: 400 12px/1.45 var(--mono);
    --type-label: 400 11px/1.40 var(--mono);       --track-label: 0.07em;

    --s-1: 4px; --s-2: 8px; --s-3: 12px; --s-4: 16px; --s-5: 24px; --s-6: 32px; --s-7: 48px;
    --h-control: 32px; --h-row: 38px; --h-header: 48px;
    --r-control: 4px; --r-panel: 8px; --r-sheet: 14px;
    --gutter: 24px;

    /* motion: one curve, three durations. Motion means an event occurred. */
    --ease: cubic-bezier(.32, .72, 0, 1);
    --t-press: 120ms; --t-move: 260ms; --t-settle: 420ms;

    --shadow-raised: 0 1px 2px rgba(0, 0, 0, .3), 0 6px 18px rgba(0, 0, 0, .35);
    --shadow-lifted: 0 2px 6px rgba(0, 0, 0, .4), 0 18px 44px rgba(0, 0, 0, .55);
    --focus-ring: color-mix(in srgb, var(--ink) 40%, transparent);

    /* the device gets the whole depth budget */
    --bezel: linear-gradient(160deg, color-mix(in srgb, #2A2D31 90%, var(--ground)) 0%, var(--device) 52%, #1A1D20 100%);
    --rim: rgba(255, 255, 255, .18);
    --contact-a: rgba(0, 0, 0, .6); --contact-b: rgba(0, 0, 0, .35);
    --screen-edge: rgba(0, 0, 0, .5);
    --glass-dark: #08090B;
    /* The screen before a page is on it: an OLED at power-on, black in either room, the mark in the product's white and green. */
    --boot-screen: #000; --boot-ink: #F6F6F3; --boot-eye: #47C596;

    color-scheme: dark;
  }
  :root[data-theme="light"] {
    --ground: #F6F6F3;  --panel: #FFFFFF;  --sunk: #F1F1EC;
    --ink: #14161A;     --ink-2: #565C64;  --ink-3: #727880;
    --rule: #E3E3DD;    --rule-2: #EFEFEA;
    --live: #1B6E52;    --staged: #8A5A00; --refused: #A32C21;
    --console: #0F1113; --console-2: #16191C;
    --glow: #c9cfd6; --glow-a: .35; --glow-a-busy: .55;
    --presence: rgba(20, 22, 26, .55);
    --shadow-raised: 0 1px 2px rgba(0, 0, 0, .05), 0 6px 18px rgba(0, 0, 0, .06);
    --shadow-lifted: 0 2px 6px rgba(0, 0, 0, .08), 0 18px 44px rgba(0, 0, 0, .14);
    --rim: rgba(255, 255, 255, .14);
    --contact-a: rgba(0, 0, 0, .18); --contact-b: rgba(0, 0, 0, .10);
    color-scheme: light;
  }
}

/* Roboto, vendored (Apache 2.0), from this origin, and only fetched on a host with neither SF nor Segoe. */
@font-face { font-family: 'Roboto'; src: url(./vendor/roboto/Roboto-latin.woff2) format('woff2'); font-weight: 100 900; font-style: normal; font-display: swap; }

/* -------------------------------------------------------------------- base */
@layer base {
  * { box-sizing: border-box; }
  [hidden] { display: none !important; }
  html { height: 100%; }
  body { margin: 0; min-height: 100%; background: var(--ground); color: var(--ink); font: var(--type-interface); -webkit-text-size-adjust: 100%; font-variant-numeric: tabular-nums; -webkit-font-smoothing: antialiased; }
  h1, h2, h3 { margin: 0; font: inherit; }
  p, blockquote, figure { margin: 0; }
  button { font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; text-align: left; }
  input, select { font: inherit; color: inherit; }
  a { color: var(--ink); }
  code { font: var(--type-data); }
  :focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
  * { scrollbar-width: thin; scrollbar-color: var(--rule) transparent; }
  ::selection { background: color-mix(in srgb, var(--live) 22%, transparent); }
  @media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation: none !important; transition: none !important; } }
}

/* ------------------------------------------------------------------- parts */
@layer parts {
  .mono { font-family: var(--mono); }
  .label { font: var(--type-label); letter-spacing: var(--track-label); text-transform: uppercase; color: var(--ink-3); }
  .fine { font: var(--type-caption); color: var(--ink-3); }
  .dot { display: inline-block; width: 6px; height: 6px; border-radius: 50%; background: var(--ink-3); flex: none; }
  .dot.hollow { background: transparent; border: 1px solid var(--ink-3); }

  /* button: 32 tall, radius 4, ground level. The one filled button on the
     page is the grant — ink ground, panel text — so the click reads as consequential. */
  .btn { display: inline-flex; align-items: center; justify-content: center; gap: var(--s-2); height: var(--h-control); padding: 0 var(--s-3); border: 1px solid var(--rule); border-radius: var(--r-control); background: var(--panel); color: var(--ink); font: var(--type-interface-strong); white-space: nowrap; transition: background var(--t-press), border-color var(--t-press), color var(--t-press), opacity var(--t-press); }
  .btn:hover { border-color: var(--ink-3); }
  .btn:active { background: var(--sunk); }
  .btn.primary { background: var(--ink); border-color: var(--ink); color: var(--panel); }
  .btn.primary:hover { background: color-mix(in srgb, var(--ink) 88%, var(--panel)); border-color: transparent; }
  .btn.primary:active { background: var(--ink); }
  .btn.danger { color: var(--refused); }
  .btn.danger:hover { border-color: var(--refused); }
  .btn.quiet { border-color: transparent; background: transparent; color: var(--ink-2); }
  .btn.quiet:hover { border-color: var(--rule); color: var(--ink); }
  .btn:disabled { opacity: .45; cursor: not-allowed; }
  .link { display: inline; color: var(--ink-2); text-decoration: underline; text-underline-offset: 3px; text-decoration-color: var(--rule); transition: color var(--t-press), text-decoration-color var(--t-press); }
  .link:hover { color: var(--ink); text-decoration-color: var(--ink-3); }

  /* switch: 32-tall segments, 12 horizontal padding, selected is panel over sunk, no shadow */
  .seg { display: inline-flex; height: var(--h-control); padding: 2px; border: 1px solid var(--rule); border-radius: var(--r-control); background: var(--sunk); }
  .seg button { height: 26px; padding: 0 var(--s-3); border-radius: 3px; color: var(--ink-2); font: var(--type-interface); white-space: nowrap; transition: background var(--t-press), color var(--t-press); }
  .seg button:hover { color: var(--ink); }
  .seg button[aria-checked="true"], .seg button[aria-selected="true"] { background: var(--panel); color: var(--ink); font-weight: 500; }
  .seg button:disabled { opacity: .35; cursor: not-allowed; }

  /* field: 32 tall, ground level */
  .field { display: flex; align-items: center; gap: var(--s-2); height: var(--h-control); padding: 0 var(--s-1) 0 var(--s-3); border: 1px solid var(--rule); border-radius: var(--r-control); background: var(--panel); transition: border-color var(--t-press); }
  .field:focus-within { border-color: var(--ink-3); }
  .field input { flex: 1 1 auto; min-width: 0; height: 100%; border: 0; background: transparent; padding: 0; outline: 0; font: var(--type-data); color: var(--ink); }
  .field input::placeholder { color: var(--ink-3); font-family: var(--sans); font-size: 13px; }
  .field svg { width: 14px; height: 14px; flex: none; stroke: var(--ink-3); fill: none; stroke-width: 1.5; stroke-linecap: round; }

  /* a plain select and an icon button, both 32 */
  .select { position: relative; display: inline-flex; align-items: center; height: var(--h-control); border: 1px solid var(--rule); border-radius: var(--r-control); background: var(--panel); transition: border-color var(--t-press); }
  .select:hover { border-color: var(--ink-3); }
  .select select { appearance: none; -webkit-appearance: none; height: 100%; width: 100%; border: 0; background: transparent; color: var(--ink); font: var(--type-interface-strong); padding: 0 var(--s-5) 0 var(--s-3); cursor: pointer; }
  .select::after { content: ""; position: absolute; right: var(--s-3); top: 50%; width: 6px; height: 6px; border-right: 1.5px solid var(--ink-3); border-bottom: 1.5px solid var(--ink-3); transform: translateY(-70%) rotate(45deg); pointer-events: none; }
  .ico { width: var(--h-control); height: var(--h-control); display: grid; place-items: center; border: 1px solid var(--rule); border-radius: var(--r-control); background: var(--panel); color: var(--ink-2); transition: border-color var(--t-press), color var(--t-press), background var(--t-press); }
  .ico svg { width: 15px; height: 15px; stroke: currentColor; fill: none; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
  .ico:hover { border-color: var(--ink-3); color: var(--ink); }
  .ico[aria-pressed="true"] { color: var(--ink); background: var(--sunk); }
  .tog { display: inline-flex; align-items: center; gap: 6px; height: var(--h-control); padding: 0 var(--s-3); border: 1px solid var(--rule); border-radius: var(--r-control); background: var(--panel); color: var(--ink-2); font: var(--type-interface); white-space: nowrap; transition: border-color var(--t-press), color var(--t-press); }
  .tog:hover { border-color: var(--ink-3); color: var(--ink); }
  .tog .v { color: var(--ink); }

  /* panel: ground elevation is a rule; raised and lifted are spent by role */
  .panel { background: var(--panel); border: 1px solid var(--rule); border-radius: var(--r-panel); }

  /* a strip: one 32-tall row that stays while a state is true. No wash — the text carries the colour. */
  .strip { display: flex; align-items: center; gap: var(--s-3); min-height: var(--h-control); padding: var(--s-1) 0; border-bottom: 1px solid var(--rule); font: var(--type-interface); }
  .strip strong { font-weight: 500; display: inline-flex; align-items: center; gap: var(--s-2); white-space: nowrap; }
  .strip .grow { flex: 1 1 auto; min-width: 0; color: var(--ink-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .strip .t { font: var(--type-data); color: var(--ink-3); }

  /* the load sequence: the page settles once, top to bottom */
  @keyframes settle { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }
  .settles { animation: settle var(--t-settle) var(--ease) both; }
}

/* ------------------------------------------------------------------ places */
@layer places {
  .page { height: 100vh; height: 100dvh; display: flex; flex-direction: column; padding: 0 clamp(16px, 2vw, 32px) 40px; position: relative; }
  .top, .stage { animation: settle var(--t-settle) var(--ease) both; }
  .stage { animation-delay: 60ms; }

  /* header: one line over the room, no rule. The count is the WebMCP number. */
  .top { display: flex; align-items: center; gap: var(--s-5); height: var(--h-header); flex: none; position: relative; z-index: 5; }
  .wordmark { font: var(--type-interface-strong); letter-spacing: -.01em; }
  .top .status { display: flex; align-items: center; gap: var(--s-3); min-width: 0; font: var(--type-caption); color: var(--ink-2); white-space: nowrap; }
  .top .status .st { display: inline-flex; align-items: center; gap: var(--s-2); white-space: nowrap; }
  .top .status .sep { color: var(--rule); }
  .st[data-state="local"] .dot, .st[data-state="direct"] .dot { background: var(--live); }
  .st[data-state="booting"] .dot, .st[data-state="unattested"] .dot { background: var(--staged); }
  .st[data-state="relayed"] .dot, .st[data-state="offline"] .dot { background: var(--refused); }
  .st[data-state="relayed"], .st[data-state="offline"] { color: var(--refused); }
  .st.tools .n { font: var(--type-data); font-size: 13px; color: var(--ink); min-width: 1.2em; text-align: right; transition: color var(--t-move); }
  .st.tools .split { color: var(--ink-3); }
  .st.tools[data-agent="none"] .dot { background: transparent; border: 1px solid var(--ink-3); }
  .st.tools[data-agent="yes"] .dot { background: var(--live); }
  .st.tools[data-delta="up"] .n { color: var(--live); }
  .st.tools[data-delta="down"] .n { color: var(--refused); }
  /* the one line of pitch: centred, and gone once the phone has something on it */
  .top .line { flex: 1 1 0; min-width: 0; text-align: center; font: var(--type-interface); color: var(--ink-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; padding: 0 var(--s-4); transition: opacity var(--t-settle) var(--ease); pointer-events: none; }
  body[data-loaded="true"] .top .line { opacity: 0; }
  body[data-bench="open"] .top .line { display: none; }
  .top .links { margin-left: auto; display: flex; align-items: center; gap: var(--s-4); font: var(--type-interface); }
  .top .links .fab { margin-left: var(--s-2); }
  .top .links .link { text-decoration: none; }
  .top .links .link:hover { text-decoration: underline; }
  .top .links .ico.quiet { border-color: transparent; background: transparent; }
  .top .links .ico.quiet:hover { border-color: var(--rule); }

  /* strips: standing access, a live warrant, no agent — one 32-tall row under the header */
  .strip { flex: none; position: relative; z-index: 5; border-bottom: 0; }
  #standing-banner strong { color: var(--staged); }
  #standing-banner strong::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: var(--staged); }
  #warrant-strip strong { color: var(--live); }
  #warrant-strip strong::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: var(--live); }
  .strip.notice { font: var(--type-caption); }
  .strip.notice strong { color: var(--staged); font-weight: 500; }
  .strip.notice strong::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: var(--staged); }

  /* ------------------------------------------------------------------ stage
     The room. The phone sits in it; the rail floats at the right edge. */
  .stage { flex: 1 1 0; min-height: 320px; display: grid; grid-template-columns: minmax(0, 1fr) clamp(280px, 24vw, 360px); gap: 0 var(--gutter); position: relative; }
  #devices { position: relative; display: flex; flex-direction: column; min-height: 0; min-width: 0; }
  body[data-focus="true"] .strip, body[data-focus="true"] .watch, body[data-focus="true"] .bench, body[data-focus="true"] .top .line { display: none; }
  body[data-focus="true"] .stage { grid-template-columns: minmax(0, 1fr); }
  body[data-focus="true"] .page { padding-bottom: 0; }

  /* the light behind the phone: caused by the screen, coloured by the page it shows,
     brighter while the agent's hands are on it. Blur lives on this pseudo alone. */
  .room { position: absolute; inset: 0; pointer-events: none; overflow: hidden; z-index: 0; }
  .room::before { content: ""; position: absolute; left: 50%; top: var(--glow-y, 46%); width: min(72vmin, 620px); height: min(72vmin, 620px); transform: translate(-50%, -50%) scale(var(--glow-s, 1)); border-radius: 50%;
    background: radial-gradient(closest-side, var(--glow) 0%, color-mix(in srgb, var(--glow) 70%, transparent) 38%, color-mix(in srgb, var(--glow) 25%, transparent) 70%, transparent 100%);
    filter: blur(48px); opacity: var(--glow-a); transition: opacity 700ms var(--ease), transform 700ms var(--ease), --glow 900ms linear; }
  .phone-stage[data-booted="false"] .room::before { opacity: 0; }
  #devices[data-busy="true"] { --glow-a: var(--glow-a-busy); }
  #devices[data-tap="true"] .room::before { transition-duration: 120ms; --glow-s: 1.04; }

  /* the boot: the kernel's own log over the dark, until the phone lands */
  .boot-log { position: absolute; left: 50%; top: 44%; transform: translate(-50%, -50%); width: min(60ch, 80%); margin: 0; font: var(--type-data); color: var(--ink-3); white-space: pre-wrap; word-break: break-all; text-align: left; pointer-events: none; z-index: 1;
    mask-image: linear-gradient(to bottom, transparent, #000 45%); -webkit-mask-image: linear-gradient(to bottom, transparent, #000 45%); transition: opacity var(--t-settle) var(--ease); }
  .phone-stage[data-booted="true"] .boot-log { opacity: 0; }
  .phone-row { flex: 1 1 auto; min-height: 0; display: grid; position: relative; z-index: 1; padding: var(--s-2) 0 calc(var(--deck-h, 96px) + var(--s-5)); }
  .phone-cell { position: relative; display: grid; grid-template-rows: minmax(0, 1fr) auto auto; justify-items: center; align-items: center; min-height: 0; gap: var(--s-2); transition: opacity var(--t-settle) var(--ease), transform var(--t-settle) var(--ease); }
  .phone-stage[data-booted="false"] .phone-cell { opacity: 0; transform: translateY(10px); }
  .phone-cell .device { width: 100%; height: 100%; min-height: 0; }
  /* The hint sits under the mark on the booting screen, in that screen's ink rather than the room's. */
  .empty-screen { position: absolute; left: 50%; top: 61%; transform: translate(-50%, -50%); width: 200px; text-align: center; font: var(--type-caption); color: color-mix(in srgb, var(--boot-ink) 46%, transparent); pointer-events: none; }
  .phone-stage[data-loaded="true"] .empty-screen { display: none; }
  /* what the agent is doing, in the present tense, under the glass */
  .now { font: var(--type-interface); color: var(--ink); text-align: center; min-height: 18px; display: inline-flex; align-items: center; gap: var(--s-2); }
  .now::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: var(--live); animation: pulse 1.6s ease-in-out infinite; }
  .now[data-tone="staged"] { color: var(--staged); } .now[data-tone="staged"]::before { background: var(--staged); animation: none; }
  .now[data-tone="refused"] { color: var(--refused); } .now[data-tone="refused"]::before { background: var(--refused); animation: none; }
  .now[data-tone="quiet"]::before { animation: none; background: var(--ink-3); }
  @keyframes now-in { from { opacity: 0; transform: translateY(2px); } }
  .now.swap { animation: now-in 160ms var(--ease); }
  @keyframes pulse { 0%, 100% { opacity: .35; transform: scale(.85); } 50% { opacity: 1; transform: scale(1); } }
  .phone-cap { font: var(--type-caption); color: var(--ink-3); text-align: center; }
  .phone-cap .cap-tog { color: var(--ink-2); text-decoration: underline; text-underline-offset: 3px; text-decoration-color: var(--rule); }
  .phone-cap .cap-tog:hover { color: var(--ink); text-decoration-color: var(--ink-3); }

  /* the deck: every control for the phone, floating under it, 32 rhythm; it dims while the pointer is still */
  .deck { position: absolute; left: 50%; bottom: var(--s-3); transform: translateX(-50%); width: min(100%, 1040px); z-index: 3; display: grid; gap: var(--s-2); padding: var(--s-2); border-radius: 10px; background: color-mix(in srgb, var(--panel) 94%, transparent); border: 1px solid var(--rule); box-shadow: var(--shadow-raised); transition: opacity var(--t-move) var(--ease); }
  .deck .row { display: flex; gap: var(--s-2); align-items: center; flex-wrap: nowrap; height: var(--h-control); min-width: 0; }
  .deck .select { width: 188px; flex: none; }
  .deck .seg, .deck .tog, .deck .ico, .deck select[data-role="nav"] { flex: none; }
  .deck .select select { max-width: 100%; overflow: hidden; text-overflow: ellipsis; }
  .deck select[data-role="nav"] { height: var(--h-control); padding: 0 var(--s-2); border: 1px solid var(--rule); border-radius: var(--r-control); background: var(--panel); color: var(--ink-2); }
  .deck .icons { display: inline-flex; gap: var(--s-1); }
  .deck .addr { flex: 1 1 260px; }
  .deck .addr .go { height: 24px; padding: 0 var(--s-3); border: 1px solid var(--rule); border-radius: 3px; background: var(--panel); color: var(--ink); font: var(--type-interface-strong); transition: border-color var(--t-press), background var(--t-press); }
  .deck .addr .go:hover { border-color: var(--ink-3); }
  .deck .addr .go:active { background: var(--sunk); }
  .deck .preview .dot { background: var(--staged); }
  .deck .preview[aria-pressed="true"] { border-color: var(--staged); color: var(--staged); }
  .deck .preview[aria-pressed="true"] .v { color: var(--staged); }
  .deck .via { position: relative; display: inline-flex; align-items: center; gap: var(--s-2); font: var(--type-caption); color: var(--ink-3); white-space: nowrap; flex: none; }
  .deck .via .dot { border: 1px solid var(--ink-3); background: transparent; }
  .deck .via .link { font: inherit; }
  /* The pill: the route in one word. Everything it stands for opens above it, on hover or a tap. */
  .deck .via .pill { display: inline-flex; align-items: center; gap: var(--s-2); height: 24px; padding: 0 var(--s-3) 0 var(--s-2); border: 1px solid var(--rule); border-radius: 999px; background: var(--panel); color: inherit; font: var(--type-caption); cursor: default; }
  .deck .via .pill:hover, .deck .via.open .pill { border-color: currentColor; }
  .deck .via .pill:focus-visible { outline: 2px solid var(--ink-3); outline-offset: 2px; }
  .deck .via .ledger { position: absolute; left: 0; bottom: calc(100% + var(--s-2)); width: min(440px, 80vw); display: none; padding: var(--s-3) var(--s-3) var(--s-2); border: 1px solid var(--rule); border-radius: var(--r-control); background: var(--panel); color: var(--ink-2); box-shadow: 0 8px 28px rgba(0,0,0,.28); white-space: normal; z-index: 6; }
  .deck .via:hover .ledger, .deck .via.open .ledger, .deck .via:focus-within .ledger { display: block; }
  .deck .via .ledger .vt { display: block; color: var(--ink); line-height: 1.4; }
  .deck .via .ledger .rl-turn { margin-top: var(--s-2); }
  .deck .via .ledger ol { list-style: none; margin: var(--s-3) 0 0; padding: var(--s-2) 0 0; border-top: 1px solid var(--rule); display: grid; gap: 6px; }
  .deck .via .ledger li { display: grid; grid-template-columns: 10px 1fr auto; gap: var(--s-2); align-items: baseline; font: var(--type-caption); color: var(--ink-3); }
  .deck .via .ledger li .h { color: var(--ink-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .deck .via .ledger li .t { font-variant-numeric: tabular-nums; }
  .deck .via .ledger li .dot { width: 8px; height: 8px; margin-top: 1px; }
  .deck .via .ledger li[data-via="sealed"] .dot { background: var(--ansi-4); border-color: var(--ansi-4); }
  .deck .via .ledger li[data-via="relay"] .dot { background: var(--staged); border-color: var(--staged); }
  .deck .via .ledger li[data-via="live"] .dot { background: var(--live); border-color: var(--live); }
  .deck .via .ledger li[data-via="workspace"] .dot, .deck .via .ledger li[data-via="direct"] .dot { background: var(--ink-3); }
  .deck .via .ledger .rl-empty { margin: var(--s-2) 0 0; color: var(--ink-3); }
  /* Row one: the address grows, the rest sits to the right. Row two: the icons hold the far edge. */
  .deck .netlify { margin-left: auto; }
  .deck .row:last-of-type .icons { margin-left: auto; }
  .deck .via[data-via="relay"] { color: var(--staged); }
  .deck .via[data-via="relay"] .dot { background: var(--staged); border-color: var(--staged); }
  .deck .via[data-via="sealed"] { color: var(--ansi-4); }
  .deck .via[data-via="sealed"] .dot { background: var(--ansi-4); border-color: var(--ansi-4); }
  .deck .via[data-via="live"], .deck .via[data-live="on"] { color: var(--live); }
  .deck .via[data-via="live"] .dot, .deck .via[data-live="on"] .dot { background: var(--live); border-color: var(--live); }
  .deck .via[data-via="workspace"] .dot, .deck .via[data-via="direct"] .dot { background: var(--ink-3); }
  .deck .netlify { margin-left: auto; display: inline-flex; align-items: center; gap: var(--s-3); font: var(--type-interface); white-space: nowrap; }
  .deck .netlify #netlify-who { color: var(--ink-3); }
  .deck .focus-btn { flex: none; }
  .site-list { max-height: 228px; overflow: auto; }
  .site-list button { display: grid; grid-template-columns: minmax(9rem, auto) 1fr auto; gap: 14px; align-items: baseline; width: 100%; height: var(--h-row); padding: 0 var(--s-3); border-bottom: 1px solid var(--rule-2); color: var(--ink); transition: background var(--t-press); }
  .site-list button:last-child { border-bottom: 0; }
  .site-list button:hover { background: var(--sunk); }
  .site-list .nm { font: var(--type-interface-strong); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .site-list .u { font: var(--type-data); color: var(--ink-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .site-list .st { font: var(--type-caption); color: var(--ink-3); white-space: nowrap; }
  .site-list .st.ok { color: var(--live); }
  .site-list .none { padding: var(--s-3); font: var(--type-interface); color: var(--ink-2); }

  /* the say menu: six lines, behind one button */
  .fab { position: relative; width: 40px; height: 40px; border-radius: 50%; display: grid; place-items: center; background: var(--panel); border: 1px solid var(--rule); color: var(--ink); box-shadow: var(--shadow-lifted); z-index: 45; transition: transform var(--t-press), border-color var(--t-press), background var(--t-press); }
  .fab:hover { transform: translateY(-1px); border-color: var(--ink-3); }
  .fab svg { width: 22px; height: 22px; stroke: currentColor; fill: none; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
  .fab .eye { fill: currentColor; stroke: none; }
  .fab::before { content: ""; position: absolute; inset: -1px; border-radius: 50%; border: 1.5px solid var(--live); opacity: 0; }
  body:has(#tools-badge[data-agent="none"]) .fab::before { animation: fab-pulse 2.6s var(--ease) infinite; }   /* pulsing while no agent is attached: an invitation, and the only time it moves */
  body:not(:has(#tools-badge[data-agent="none"])) .fab { border-color: var(--live); }
  body:has(#say:popover-open) .fab { background: var(--sunk); border-color: var(--ink-3); }
  @keyframes fab-pulse { 0% { transform: scale(1); opacity: .75; } 100% { transform: scale(1.6); opacity: 0; } }
  .say-menu { inset: auto; top: calc(var(--h-header) + 4px); right: clamp(16px, 2vw, 32px); margin: 0; width: min(680px, calc(100vw - 32px)); max-height: calc(100dvh - var(--h-header) - 24px); overflow: auto; padding: var(--s-4) var(--s-5) var(--s-5); border: 1px solid var(--rule); border-radius: var(--r-sheet); background: var(--panel); color: var(--ink); box-shadow: var(--shadow-lifted); }
  .say-menu::backdrop { background: transparent; }
  .say-menu .eyebrow { display: flex; align-items: baseline; gap: var(--s-3); margin-bottom: var(--s-3); }
  .say-menu .eyebrow span:first-child { font: var(--type-label); letter-spacing: var(--track-label); text-transform: uppercase; color: var(--ink-3); }
  .say-menu .eyebrow span:last-child { font: var(--type-caption); color: var(--ink-3); }
  .ask-head { display: flex; align-items: center; gap: var(--s-3); margin-bottom: var(--s-3); }
  .ask-head .link { margin-left: auto; align-self: flex-start; font: var(--type-interface); }
  .ask-head svg { width: 30px; height: 30px; flex: none; stroke: var(--ink); fill: none; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
  .ask-head .eye { fill: var(--ink); stroke: none; }
  .ask-title h2 { margin: 0; font: var(--type-interface-strong); font-size: 16px; }
  .ask-title p { margin: 2px 0 0; font: var(--type-caption); color: var(--ink-3); }
  .ask-title p[data-agent="yes"] { color: var(--live); }
  .ask-lede { margin: 0 0 var(--s-4); font: var(--type-body); color: var(--ink-2); max-width: 60ch; }
  .chips { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s-2); }
  .chips button { display: flex; flex-direction: column; gap: 3px; min-height: 68px; padding: var(--s-3); border: 1px solid var(--rule); border-radius: 8px; background: var(--sunk); text-align: left; font: var(--type-interface); transition: border-color var(--t-press), color var(--t-press), background var(--t-press); }
  .chips button { position: relative; padding-right: 34px; animation: edge 3.6s var(--ease) infinite; animation-delay: calc(var(--i, 0) * .45s); }
  .chips button::before, .chips button::after { content: ""; position: absolute; width: 9px; height: 9px; border: 1.2px solid var(--ink-3); border-radius: 2px; pointer-events: none; transition: border-color var(--t-press); }
  .chips button::before { top: 9px; right: 14px; }
  .chips button::after { top: 13px; right: 10px; background: var(--sunk); }
  .chips button:hover::before, .chips button:hover::after { border-color: var(--ink); }
  .chips button[data-copied="true"]::before, .chips button[data-copied="true"]::after { border-color: var(--live); }
  .chips button:hover { border-color: var(--ink-3); background: var(--panel); animation: none; }
  @keyframes edge { 0%, 100% { border-color: var(--rule); box-shadow: 0 0 0 0 transparent; } 50% { border-color: var(--ink-3); box-shadow: 0 0 0 3px color-mix(in srgb, var(--ink-3) 12%, transparent); } }
  .chips button b { font-weight: 500; }
  .chips button span { color: var(--ink-2); font: var(--type-caption); }
  .chips button[data-copied="true"] { border-color: var(--live); }
  .ask-eyebrow { display: flex; align-items: baseline; justify-content: space-between; gap: var(--s-3); margin: var(--s-5) 0 var(--s-2); }
  .ask-eyebrow span:first-child { font: var(--type-label); letter-spacing: var(--track-label); text-transform: uppercase; color: var(--ink-3); }
  .ask-eyebrow span:last-child { font: var(--type-caption); color: var(--ink-3); }
  .reach .row { display: grid; grid-template-columns: 64px minmax(0, 1fr); gap: var(--s-1) var(--s-3); align-items: baseline; padding: 7px 0; border-top: 1px solid var(--rule); }
  .reach .row:first-child { border-top: 0; }
  .reach .row .k { font: var(--type-label); letter-spacing: var(--track-label); text-transform: uppercase; color: var(--ink-2); }
  .reach .row .dots { display: flex; flex-wrap: wrap; gap: 4px; align-items: center; min-height: 10px; }
  .reach .row .dots i { width: 8px; height: 8px; border-radius: 50%; background: var(--live); animation: land var(--t-settle) var(--ease); }
  .reach .row .dots b { font: var(--type-data); color: var(--ink); margin-left: var(--s-1); }
  .reach .row .w { grid-column: 2; font: var(--type-caption); color: var(--ink-3); }
  .reach .row .w code { color: var(--ink-2); }
  .reach .row[data-n="0"] .k { color: var(--ink-3); }
  .ask-fine { margin: var(--s-3) 0 0; font: var(--type-caption); color: var(--ink-3); max-width: 64ch; }
  .flow { list-style: none; display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: var(--s-2); margin: var(--s-5) 0 0; padding: var(--s-3) 0 0; border-top: 1px solid var(--rule); counter-reset: step; }
  .flow li { display: grid; gap: 2px; font: var(--type-caption); color: var(--ink-3); min-width: 0; }
  .flow li::before { counter-increment: step; content: counter(step); font: var(--type-label); color: var(--ink-3); width: 18px; height: 18px; border: 1px solid var(--rule); border-radius: 50%; display: grid; place-items: center; margin-bottom: 4px; }
  .flow li b { font: var(--type-interface); font-weight: 500; color: var(--ink); }
  .chips button:hover b, .chips button:hover span, .chips button[data-copied="true"] b, .chips button[data-copied="true"] span { color: var(--live); }

  /* the rail: what the agent read, then what it did. Floats at the right edge of the room. */
  .watch { position: relative; z-index: 2; display: flex; flex-direction: column; min-height: 0; min-width: 0; padding: var(--s-3) 0 var(--s-3); }
  .watch h2 { font: var(--type-interface-strong); display: flex; align-items: baseline; gap: var(--s-3); color: var(--ink-2); }
  .watch .count { font: var(--type-data); color: var(--ink-3); }
  .read { flex: 0 1 auto; min-height: 0; display: flex; flex-direction: column; gap: var(--s-2); padding: 0 0 var(--s-3); border-bottom: 1px solid var(--rule); max-height: 46%; overflow: hidden; }
  .read .findings { font: var(--type-caption); }
  .read .findings:empty { display: none; }
  .phone-stage[data-findings]:not([data-findings="0"]) .findings { color: var(--refused); }
  .phone-stage[data-findings="0"] .findings { color: var(--live); }
  .ps-findings { flex: 0 1 auto; min-height: 0; overflow: auto; display: grid; gap: var(--s-2); align-content: start; font: var(--type-interface); color: var(--ink); }
  .ps-findings .f { padding-left: 14px; text-indent: -14px; cursor: default; transition: color var(--t-press); }
  .ps-findings .f::before { content: "▲"; display: inline-block; width: 14px; text-indent: 0; color: var(--refused); font-size: 8px; vertical-align: 2px; }
  .ps-findings .f[data-on="true"] { color: var(--ink); } .ps-findings .f:not([data-on="true"]) { color: var(--ink-2); }
  .ps-findings .f .fix { display: block; padding-left: 0; text-indent: 0; font: var(--type-data); color: var(--ink-3); margin-top: 2px; }
  .ps-findings .clean { color: var(--live); }
  .ps-findings .ps-empty { font: var(--type-caption); color: var(--ink-3); }
  .read h3 { font: var(--type-label); letter-spacing: var(--track-label); text-transform: uppercase; color: var(--ink-3); margin-top: var(--s-2); }
  .ps-log { flex: 1 1 auto; min-height: 0; overflow: auto; font: var(--type-data); color: var(--ink-3); display: grid; gap: 2px; align-content: start; }
  .ps-log .error { color: var(--refused); }
  .ps-log .warn { color: var(--staged); }
  .activity { flex: 1 1 0; min-height: 0; display: flex; flex-direction: column; }
  .side-head { display: flex; align-items: baseline; gap: var(--s-3); padding: var(--s-3) 0 var(--s-2); }
  .side-head .facts { margin-left: auto; font: var(--type-caption); color: var(--ink-3); text-align: right; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 55%; }
  ol.rail { list-style: none; margin: 0; padding: 0; flex: 1 1 auto; min-height: 0; overflow: auto; display: flex; flex-direction: column; }
  ol.rail li { position: relative; display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 6px; min-height: var(--h-row); padding: var(--s-2) 0 var(--s-2) 20px; font: var(--type-interface); border-bottom: 1px solid var(--rule-2); }
  ol.rail li::before { content: ""; position: absolute; left: 2px; top: 15px; width: 7px; height: 7px; border-radius: 50%; border: 1.5px solid var(--ink-3); background: var(--ink-3); }
  ol.rail li[data-running="true"]::before { border-color: var(--live); background: var(--live); animation: pulse 1.2s ease-in-out infinite; }
  ol.rail li .who { color: var(--ink-3); }
  ol.rail li .t { order: 9; margin-left: auto; padding-left: var(--s-2); font: var(--type-caption); color: var(--ink-3); }
  ol.rail li .name { color: var(--ink); }
  ol.rail li[data-kind="call"] .name { font: var(--type-data); }
  ol.rail li .arg { font: var(--type-data); color: var(--ink-2); overflow-wrap: anywhere; }
  ol.rail li .fx { order: 10; flex-basis: 100%; color: var(--ink-2); margin-top: 1px; }
  ol.rail li .fx .mono { font: var(--type-data); }
  ol.rail li[data-kind="human"]::before { background: var(--ink); border-color: var(--ink); }
  ol.rail li[data-kind="note"]::before, ol.rail li[data-kind="call"]::before { background: transparent; }
  ol.rail li[data-kind="call"][data-ok="false"]::before, ol.rail li[data-kind="refusal"]::before { border-color: var(--refused); background: transparent; }
  ol.rail li[data-kind="call"][data-ok="false"] .name, ol.rail li[data-kind="call"][data-ok="false"] .fx { color: var(--refused); }
  ol.rail li[data-kind="grant"]::before { background: var(--live); border-color: var(--live); }
  ol.rail li[data-kind="grant"] .name, ol.rail li[data-kind="grant"] b { color: var(--live); font-weight: 500; }
  ol.rail li[data-kind="revoke"]::before { background: var(--refused); border-color: var(--refused); }
  ol.rail li[data-kind="revoke"] .name { color: var(--refused); font-weight: 500; }
  ol.rail li[data-kind="refusal"] .name, ol.rail li[data-kind="refusal"] .fx { color: var(--refused); }
  ol.rail li[data-kind="run"]::before { background: var(--staged); border-color: var(--staged); }
  ol.rail li[data-kind="note"] .name { color: var(--ink-2); }
  @keyframes land { from { background: var(--sunk); } to { background: transparent; } }
  ol.rail li[data-fresh="true"] { animation: land var(--t-settle) var(--ease); }
  ol.rail .idle { display: block; padding: var(--s-2) 0 var(--s-3); font: var(--type-caption); color: var(--ink-3); border-bottom: 0; }
  ol.rail .idle::before { display: none; }
  .side-foot { display: flex; gap: var(--s-2); flex-wrap: wrap; padding: var(--s-2) 0 0; align-items: center; }

  /* the workbench: a sheet at the foot of the window; one line until it is wanted */
  .bench { position: fixed; left: 0; right: 0; bottom: 0; z-index: 40; display: flex; flex-direction: column; background: color-mix(in srgb, var(--ground) 92%, transparent); border-top: 1px solid var(--rule); }
  .bench[data-open="true"] { --bench-h: min(62vh, calc(100dvh - 120px)); height: var(--bench-h); background: var(--ground); box-shadow: var(--shadow-lifted); }
  .bench-bar { display: flex; align-items: center; gap: var(--s-4); height: 40px; min-width: 0; padding: 0 clamp(16px, 2vw, 32px); flex: none; }
  .bench-toggle { display: inline-flex; align-items: center; gap: var(--s-2); height: var(--h-control); font: var(--type-interface-strong); white-space: nowrap; }
  .bench-toggle::before { content: ""; width: 6px; height: 6px; border-right: 1.5px solid var(--ink-3); border-bottom: 1.5px solid var(--ink-3); transform: rotate(-135deg) translate(-1px, -1px); transition: transform var(--t-move) var(--ease); }
  .bench[data-open="true"] .bench-toggle::before { transform: rotate(45deg) translate(-1px, -1px); }
  .machine-label { font: var(--type-data); color: var(--ink-3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 34ch; }
  .tabs { display: inline-flex; height: var(--h-control); padding: 2px; border: 1px solid var(--rule); border-radius: var(--r-control); background: var(--sunk); }
  .tabs [role="tab"] { height: 26px; padding: 0 var(--s-3); border-radius: 3px; display: inline-flex; gap: 6px; align-items: center; color: var(--ink-2); white-space: nowrap; font: var(--type-interface); transition: background var(--t-press), color var(--t-press); }
  .tabs [role="tab"]:hover { color: var(--ink); }
  .bench[data-open="true"] .tabs [role="tab"][aria-selected="true"] { background: var(--panel); color: var(--ink); font-weight: 500; }
  .tabs .count { font: var(--type-data); color: var(--staged); }
  .tabs .count:empty { display: none; }
  .bench-bar .tail { flex: 1 1 auto; min-width: 0; font: var(--type-data); color: var(--ink-3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; direction: rtl; text-align: left; }
  .bench-bar .tail > span { direction: ltr; unicode-bidi: isolate; }
  .bench[data-open="true"] .tail { visibility: hidden; }
  .bench-bar .status { margin-left: auto; font: var(--type-caption); color: var(--ink-3); white-space: nowrap; display: inline-flex; align-items: center; gap: var(--s-2); }
  .bench-bar .status[data-live="true"] { color: var(--live); }
  .bench-bar .status[data-live="true"]::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: var(--live); }
  .bench-bar .sep { color: var(--rule); }
  .bench-bar .fact { font: var(--type-data); color: var(--ink-3); white-space: nowrap; }
  .bench-bar .link { font: var(--type-caption); white-space: nowrap; }
  #mode-badge { display: inline-flex; align-items: center; gap: var(--s-2); color: var(--ink-3); font: var(--type-caption); white-space: nowrap; }
  #mode-badge:hover { color: var(--ink); }
  #mode-badge[data-standing="true"] { color: var(--staged); font-weight: 500; }
  #mode-badge[data-standing="true"] .dot { background: var(--staged); }
  .view { display: none; flex: 1 1 auto; min-height: 0; position: relative; flex-direction: column; border-top: 1px solid var(--rule); overflow: hidden; background: var(--panel); }
  .bench[data-open="true"] .view { display: flex; animation: settle var(--t-move) var(--ease) both; }

  /* the log: the machine's serial console, shared with the agent */
  #terminal { flex: 1 1 auto; min-height: 0; background: var(--console); color: var(--console-ink); font: var(--type-data); padding: var(--s-3) clamp(16px, 2vw, 32px) var(--s-4); overflow: auto; white-space: pre-wrap; word-break: break-word; outline: none; cursor: text; }
  #terminal:focus-visible { box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--live) 60%, transparent); outline: none; }
  #terminal .term-gap { color: var(--staged); font-style: italic; }
  #terminal .term-notice { color: var(--console-dim); }
  #terminal { line-height: 1.55; font-variant-ligatures: none; }
  #terminal .ts { color: var(--console-dim); }
  #terminal .prompt { color: var(--console-add); font-weight: 600; }
  #terminal .trouble { color: color-mix(in srgb, var(--console-del) 82%, var(--console-ink)); }
  #terminal .b { font-weight: 600; } #terminal .d { opacity: .7; } #terminal .i { font-style: italic; } #terminal .u { text-decoration: underline; }
  #terminal .c0 { color: var(--ansi-0); } #terminal .c1 { color: var(--ansi-1); } #terminal .c2 { color: var(--ansi-2); } #terminal .c3 { color: var(--ansi-3); }
  #terminal .c4 { color: var(--ansi-4); } #terminal .c5 { color: var(--ansi-5); } #terminal .c6 { color: var(--ansi-6); } #terminal .c7 { color: var(--ansi-7); }
  #terminal .c8 { color: var(--console-dim); } #terminal .c9 { color: var(--ansi-1); } #terminal .c10 { color: var(--ansi-2); } #terminal .c11 { color: var(--ansi-3); }
  #terminal .c12 { color: var(--ansi-4); } #terminal .c13 { color: var(--ansi-5); } #terminal .c14 { color: var(--ansi-6); } #terminal .c15 { color: var(--ansi-7); }
  #terminal .cur::after { content: ""; display: inline-block; width: .58em; height: 1.05em; margin-left: 1px; vertical-align: text-bottom; background: var(--console-dim); opacity: .9; }
  #terminal[data-typing="true"] .cur::after { background: var(--live); animation: blink 1.1s steps(2, start) infinite; }
  @keyframes blink { to { visibility: hidden; } }
  .term-head { display: flex; align-items: center; gap: var(--s-2); padding: 7px clamp(16px, 2vw, 32px); background: var(--console-2); color: var(--console-dim); font: var(--type-label); letter-spacing: var(--track-label); text-transform: uppercase; border-bottom: 1px solid color-mix(in srgb, var(--console-ink) 8%, transparent); }
  .term-head::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: var(--live); flex: none; }
  .term-head .t { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .term-head .r { margin-left: auto; font-family: var(--mono); text-transform: none; letter-spacing: 0; }
  .term-input { position: absolute; left: 0; bottom: 0; width: 1px; height: 1px; opacity: 0; border: 0; padding: 0; margin: 0; resize: none; pointer-events: none; }
  .term-foot { display: flex; flex-wrap: wrap; gap: var(--s-2) var(--s-4); align-items: center; padding: var(--s-2) clamp(16px, 2vw, 32px); border-top: 1px solid var(--rule); font: var(--type-caption); color: var(--ink-3); background: var(--sunk); }
  .term-foot .k { font: var(--type-label); padding: 2px 6px; border: 1px solid var(--rule); border-radius: 3px; color: var(--ink-2); background: var(--panel); }
  .term-foot .hint { margin-left: auto; font-family: var(--mono); }

  /* files: a tree with a viewer beside it */
  #files { flex: 1 1 auto; min-height: 0; display: grid; grid-template-columns: minmax(200px, 300px) minmax(0, 1fr); background: var(--panel); }
  #files > .tree { overflow: auto; padding: var(--s-2) 0; border-right: 1px solid var(--rule); font: var(--type-data); }
  #files .tree ul { list-style: none; margin: 0; padding: 0; }
  #files .tree li { display: flex; align-items: baseline; gap: var(--s-2); min-height: 28px; padding: 4px var(--s-3) 4px 0; cursor: default; }
  #files .tree li .n { flex: 1 1 auto; overflow-wrap: anywhere; }
  #files .tree li .s { color: var(--ink-3); font: var(--type-label); }
  #files .tree li[data-type="dir"] .n { color: var(--ink-2); }
  #files .tree li[data-type="dir"] .n::before { content: "▾ "; color: var(--ink-3); font-size: 10px; }
  #files .tree li[data-type="dir"][data-collapsed="true"] .n::before { content: "▸ "; }
  #files .tree li[data-type="file"] { cursor: pointer; }
  #files .tree li[data-type="file"]:hover, #files .tree li[data-type="file"][data-open="true"] { background: var(--sunk); }
  #files .tree li[data-type="file"][data-open="true"] .n { color: var(--live); }
  #files .tree li[data-ghost="true"] .n::after { content: " ◐"; color: var(--staged); }
  #files .tree li[data-fresh="true"] { animation: land var(--t-settle) var(--ease); }
  #files > .viewer { min-width: 0; display: flex; flex-direction: column; }
  #files .viewer .vh { display: flex; align-items: center; gap: var(--s-3); min-height: var(--h-row); padding: 0 var(--s-3); border-bottom: 1px solid var(--rule); font: var(--type-caption); color: var(--ink-3); }
  #files .viewer .vh b { color: var(--ink); font: var(--type-data); font-weight: 500; }
  #files .viewer .vh .ghost-note { color: var(--staged); }
  #files .viewer .vh button { margin-left: auto; }
  #files .viewer pre { flex: 1 1 auto; min-height: 0; margin: 0; padding: var(--s-3) var(--s-4); overflow: auto; font: var(--type-data); background: var(--console); color: var(--console-ink); white-space: pre-wrap; word-break: break-word; }
  #files .viewer .empty { padding: var(--s-5); font: var(--type-body); color: var(--ink-3); max-width: 44ch; }
  #files .viewer .empty b { color: var(--ink); font-weight: 500; }

  /* changes: staged edits as diffs. Addition and removal colour the gutter and the text, never a fill. */
  #changes { flex: 1 1 auto; min-height: 0; overflow: auto; padding: var(--s-4) clamp(16px, 2vw, 32px); background: var(--panel); display: grid; gap: var(--s-4); align-content: start; }
  .empty-state { font: var(--type-body); color: var(--ink-3); max-width: 52ch; padding: var(--s-3) var(--s-1); }
  .empty-state b { color: var(--ink); font-weight: 500; }
  .ghost { border-left: 2px solid var(--staged); padding-left: var(--s-4); }
  .ghost h3 { font: var(--type-data); font-weight: 500; color: var(--ink); overflow-wrap: anywhere; display: flex; gap: var(--s-3); align-items: baseline; flex-wrap: wrap; }
  .ghost h3 .tag { font: var(--type-label); letter-spacing: var(--track-label); text-transform: uppercase; color: var(--staged); }
  .ghost .note { font: var(--type-caption); color: var(--ink-3); margin-top: 2px; }
  .ghost .intent { font: var(--type-interface); margin-top: var(--s-1); }
  .ghost pre { margin: var(--s-2) 0; max-height: 280px; overflow: auto; font: var(--type-data); white-space: pre-wrap; word-break: break-word; background: var(--console); color: var(--console-ink); padding: var(--s-3) var(--s-3); border-radius: var(--r-control); }
  .ghost pre .add { color: var(--console-add); display: block; }
  .ghost pre .add::before, .ghost pre .del::before { content: ""; display: inline-block; width: 2px; height: 1em; margin: 0 var(--s-2) -2px -12px; background: currentColor; }
  .ghost pre .del { color: var(--console-del); display: block; }
  .ghost pre .hunk { color: var(--console-dim); display: block; }
  .ghost .actions { display: flex; gap: var(--s-3); align-items: center; flex-wrap: wrap; font: var(--type-caption); color: var(--ink-3); }
  .ghost[data-fresh="true"] { animation: land var(--t-settle) var(--ease); }

  /* screen: the VGA console as a monitor */
  #screen { flex: 1 1 auto; min-height: 0; overflow: auto; padding: var(--s-4); background: var(--panel); display: flex; flex-direction: column; align-items: center; gap: var(--s-3); }
  #vga { background: var(--console); border: 10px solid var(--console-2); border-radius: var(--r-panel); padding: var(--s-3); box-shadow: var(--shadow-raised); max-width: 100%; overflow: auto; }
  #vga > div { white-space: pre; font: var(--type-data); line-height: 1.15; color: var(--console-ink); overflow: auto; }
  #vga > canvas { display: none; }
  #screen .cap { font: var(--type-caption); color: var(--ink-3); text-align: center; max-width: 60ch; }
  #screen .cap button { display: inline; }

  /* drawer: every explanation behind one click; lifted, non-modal, the machine keeps running */
  #drawer { position: fixed; top: 0; right: 0; bottom: 0; width: min(520px, 100%); z-index: 60; background: var(--panel); border-left: 1px solid var(--rule); box-shadow: var(--shadow-lifted); transform: translateX(104%); transition: transform var(--t-move) var(--ease); overflow: auto; padding: var(--s-5) var(--s-6) calc(var(--s-5) + env(safe-area-inset-bottom)); }
  #drawer[data-open="false"] { visibility: hidden; transition: transform var(--t-move) var(--ease), visibility 0s var(--t-move); }
  #drawer[data-open="true"] { transform: translateX(0); }
  #drawer .dh { display: flex; align-items: baseline; gap: var(--s-3); margin-bottom: var(--s-4); }
  #drawer .dh h2 { font: var(--type-section); letter-spacing: var(--track-section); }
  #drawer .dh button { margin-left: auto; }
  #drawer section { display: none; }
  #drawer[data-section="how"] section[data-section="how"], #drawer[data-section="phones"] section[data-section="phones"],
  #drawer[data-section="yours"] section[data-section="yours"], #drawer[data-section="archive"] section[data-section="archive"],
  #drawer[data-section="live"] section[data-section="live"], #drawer[data-section="cloudflare"] section[data-section="cloudflare"] { display: block; }
  #drawer h3 { font: var(--type-interface-strong); margin: var(--s-5) 0 var(--s-1); }
  #drawer p, #drawer li { font: var(--type-body); color: var(--ink-2); }
  #drawer p strong { color: var(--ink); font-weight: 500; }
  #drawer p + p { margin-top: var(--s-2); }
  #drawer ul, #drawer ol { margin: var(--s-2) 0 0; padding-left: 18px; }
  #drawer ol li + li { margin-top: var(--s-1); }
  #drawer pre { margin: var(--s-3) 0 0; background: var(--console); color: var(--console-ink); padding: var(--s-3) var(--s-4); border-radius: var(--r-control); overflow-x: auto; font: var(--type-data); }
  #drawer dl.kv { display: grid; grid-template-columns: auto 1fr; gap: var(--s-1) var(--s-4); font: var(--type-interface); margin: var(--s-2) 0 0; }
  #drawer dl.kv dt { color: var(--ink-3); }
  #drawer dl.kv dd { margin: 0; font: var(--type-data); overflow-wrap: anywhere; }
  #drawer .drop { display: block; margin-top: var(--s-3); padding: var(--s-5) var(--s-4); cursor: pointer; border: 1px dashed var(--rule); border-radius: var(--r-panel); text-align: center; color: var(--ink-2); font: var(--type-interface); transition: border-color var(--t-press), background var(--t-press); }
  #drawer .drop[data-over="true"], #drawer .drop:hover { border-color: var(--live); background: var(--sunk); }
  #drawer .drop input { display: none; }
  #drawer .drop .st { display: block; margin-top: var(--s-2); font: var(--type-data); color: var(--ink-3); }
  #drawer .row { display: flex; gap: var(--s-3); align-items: center; flex-wrap: wrap; margin-top: var(--s-3); }
  #drawer .fine, #drawer p.fine { font: var(--type-caption); color: var(--ink-3); }

  /* --------------------------------------------------------------- the sheets
     The warrant sheet is the most important object on the page. When it is up the
     room goes dark and the light behind the phone goes out: it is the one lit thing. */
  .scrim { position: fixed; inset: 0; z-index: 69; background: color-mix(in srgb, var(--device) 45%, transparent); opacity: 0; visibility: hidden; transition: opacity var(--t-move) var(--ease), visibility 0s var(--t-move); }
  .scrim[data-open="true"] { opacity: 1; visibility: visible; transition: opacity var(--t-move) var(--ease); }
  body[data-sheet="true"] .room::before { opacity: 0; }
  #sheet, #access-sheet { position: fixed; left: 50%; top: 50%; z-index: 70; width: min(420px, calc(100% - 32px)); max-height: calc(100dvh - 48px); overflow: auto; background: var(--panel); border: 1px solid var(--rule); border-radius: var(--r-sheet); box-shadow: var(--shadow-lifted); transform: translate(-50%, calc(-50% + 8px)); opacity: 0; transition: transform var(--t-move) var(--ease), opacity var(--t-move) var(--ease); }
  #sheet[data-open="false"], #access-sheet[data-open="false"] { visibility: hidden; transition: transform var(--t-move) var(--ease), opacity var(--t-move) var(--ease), visibility 0s var(--t-move); }
  #sheet[data-open="true"], #access-sheet[data-open="true"] { transform: translate(-50%, -50%); opacity: 1; }
  #sheet .inner, #access-sheet .inner { display: grid; gap: var(--s-4); padding: var(--s-5); }
  #sheet .head, #access-sheet .head { display: grid; gap: var(--s-2); }
  #sheet h2, #access-sheet h2 { font: var(--type-section); letter-spacing: var(--track-section); text-wrap: balance; }
  #sheet .reason { font: var(--type-body); color: var(--ink); padding-left: var(--s-3); border-left: 2px solid var(--staged); }
  #sheet .reason::before { content: "The agent says: "; color: var(--ink-3); }
  #sheet .reason:empty { display: none; }
  #access-sheet .reason { font: var(--type-body); color: var(--ink-2); }
  .caps { display: grid; border-top: 1px solid var(--rule); }
  .cap { display: grid; grid-template-columns: 16px 1fr auto; gap: 2px var(--s-3); align-items: center; min-height: var(--h-row); padding: var(--s-2) 0; border-bottom: 1px solid var(--rule-2); cursor: pointer; }
  .cap input { margin: 0; width: 16px; height: 16px; accent-color: var(--ink); grid-row: 1 / span 2; align-self: start; margin-top: 2px; }
  .cap .cl { font: var(--type-interface-strong); }
  .cap .why { grid-column: 2 / -1; grid-row: 2; font: var(--type-caption); color: var(--ink-2); }
  .cap .tool { grid-column: 3; grid-row: 1; font: var(--type-data); color: var(--ink-3); white-space: nowrap; transition: color var(--t-press); }
  .cap:has(input:checked) .tool { color: var(--live); }
  .cap:has(input:not(:checked)) .cl { color: var(--ink-3); }
  .cap > div { display: contents; }
  .tally { display: grid; grid-template-columns: 1fr auto; gap: var(--s-1) var(--s-4); align-items: baseline; }
  .tally .nums { grid-column: 2; grid-row: 1 / span 2; display: inline-flex; align-items: baseline; gap: var(--s-2); font: 500 28px/1.15 var(--mono); letter-spacing: -.02em; }
  .tally .nums .n { min-width: 1.25ch; text-align: right; }
  .tally .nums .arrow { color: var(--ink-3); font-size: 20px; }
  .tally .nums .after { color: var(--live); transition: color var(--t-move); }
  .tally .fine { grid-column: 1; font: var(--type-caption); color: var(--ink-2); }
  .sheet-actions { display: flex; gap: var(--s-2); flex-wrap: wrap; align-items: center; }
  #access-sheet { width: min(580px, calc(100% - 32px)); }
  .presets { display: inline-flex; justify-self: start; padding: 2px; border: 1px solid var(--rule); border-radius: var(--r-control); background: var(--sunk); }
  .presets button { height: 28px; padding: 0 var(--s-3); border-radius: 3px; font: var(--type-interface); color: var(--ink-2); transition: background var(--t-press), color var(--t-press); }
  .presets button:hover:not(:disabled) { color: var(--ink); }
  .presets button[aria-checked="true"] { background: var(--panel); color: var(--ink); font-weight: 500; }
  .presets button:disabled { opacity: .55; cursor: default; }
  .perm-head { display: flex; justify-content: space-between; padding-bottom: var(--s-1); border-bottom: 1px solid var(--rule); font: var(--type-label); letter-spacing: var(--track-label); text-transform: uppercase; color: var(--ink-3); }
  .perms { display: grid; }
  .perm { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 2px var(--s-3); align-items: center; padding: var(--s-2) 0; border-bottom: 1px solid var(--rule-2); }
  .perm .cl { font: var(--type-interface-strong); }
  .perm .why { grid-column: 1; font: var(--type-caption); color: var(--ink-2); }
  .perm[data-mode="deny"] .cl { color: var(--ink-3); text-decoration: line-through; text-decoration-color: var(--refused); }
  .perm[data-mode="allow"] .cl::after { content: ""; display: inline-block; width: 6px; height: 6px; border-radius: 50%; background: var(--live); margin-left: 8px; vertical-align: middle; }
  .seg3 { grid-column: 2; grid-row: 1 / span 2; display: inline-flex; padding: 2px; border: 1px solid var(--rule); border-radius: var(--r-control); background: var(--sunk); }
  .seg3 button { height: 26px; min-width: 50px; padding: 0 var(--s-2); border-radius: 3px; font: var(--type-interface); color: var(--ink-3); text-transform: capitalize; transition: background var(--t-press), color var(--t-press); }
  .seg3 button:hover { color: var(--ink); }
  .seg3 button[aria-checked="true"] { background: var(--panel); color: var(--ink); font-weight: 500; }
  .seg3 button[aria-checked="true"][data-mode="allow"] { color: var(--live); }
  .seg3 button[aria-checked="true"][data-mode="deny"] { color: var(--refused); }
  .perm.toggle { cursor: pointer; border-bottom: 0; }
  .perm.toggle input { grid-column: 2; grid-row: 1 / span 2; appearance: none; width: 34px; height: 20px; margin: 0; border-radius: 10px; background: var(--sunk); border: 1px solid var(--rule); position: relative; cursor: pointer; }
  .perm.toggle input::after { content: ""; position: absolute; top: 2px; left: 2px; width: 14px; height: 14px; border-radius: 50%; background: var(--ink-3); transition: transform var(--t-press), background var(--t-press); }
  .perm.toggle input:checked { background: color-mix(in srgb, var(--live) 28%, var(--sunk)); border-color: var(--live); }
  .perm.toggle input:checked::after { transform: translateX(14px); background: var(--live); }
  .perm-foot { display: flex; align-items: center; gap: var(--s-3); flex-wrap: wrap; font: var(--type-caption); color: var(--ink-2); }
  .perm-foot .spacer { margin-left: auto; }
  .perm-foot .hold { display: inline-flex; align-items: center; gap: var(--s-2); }
  .perm-foot .hold select { font: var(--type-interface); color: var(--ink); background: var(--panel); border: 1px solid var(--rule); border-radius: var(--r-control); height: 28px; padding: 0 var(--s-2); }
  .sheet-actions .spacer { margin-left: auto; }
  #sheet .foot-note, #access-sheet .foot-note { font: var(--type-caption); color: var(--ink-3); }
  #grant:active { transform: translateY(1px); }

  /* -------------------------------------------------------------- responsive */
  .top .links .link, .top .links .btn { white-space: nowrap; }
  @media (max-width: 1280px) { .top .line { display: none; } .top .status .sep, .top .status #attest-badge { display: none; } }
  @media (max-width: 900px) { .top .links [data-drawer="phones"], .top .links [data-drawer="yours"] { display: none; } }
  @media (max-width: 1100px) {
    .page { height: auto; min-height: 100dvh; }
    .deck .row { flex-wrap: wrap; height: auto; }
    .stage { flex: none; grid-template-columns: 1fr; gap: var(--s-4); min-height: 0; }
    #devices { height: 78vh; min-height: 520px; }
    .watch { display: block; padding-bottom: var(--s-6); }
    .read { max-height: none; }
    .activity { display: block; }
    ol.rail { max-height: 320px; }
    body[data-focus="true"] #devices { height: calc(100dvh - 60px); }
  }
  /* A tablet held upright: the workbench bar keeps its tabs and state, and drops the facts that need a wide bar. */
  @media (max-width: 960px) {
    .bench-bar { gap: var(--s-3); }
    .bench-bar .tail, .bench-bar .fact, .bench-bar .sep, .bench-bar .link, .machine-label { display: none; }
  }
  /* Any touch screen, whatever its width: controls a finger can hit. */
  @media (pointer: coarse) {
    :root { --h-control: 40px; }
    .seg button, .tabs [role="tab"] { height: 34px; }
    .deck .addr .go { height: 32px; }
  }
  @media (max-width: 720px) {
    .page { padding: 0 var(--s-3) 40px; }
    .top { height: auto; flex-wrap: wrap; gap: var(--s-2) var(--s-3); padding: var(--s-3) 0; }
    .top .links { margin-left: 0; flex-wrap: wrap; }
    #devices { height: 86vh; min-height: 480px; }
    .deck .row { flex-wrap: wrap; height: auto; }
    .deck .select { width: 100%; }
    .deck .netlify { margin-left: 0; }
    .bench-bar { gap: var(--s-3); }
    .bench-bar .tail, .bench-bar .fact, .bench-bar .sep, .bench-bar .link, .machine-label { display: none; }
    #files { grid-template-columns: 1fr; grid-template-rows: minmax(0, 40%) minmax(0, 60%); }
    #files > .tree { border-right: 0; border-bottom: 1px solid var(--rule); }
  }

  /* A phone holding the page. Touch-sized controls, fields that never zoom the page, nothing to scroll sideways:
     the bar the product itself measures other people's apps against. */
  @media (max-width: 720px) {
    :root { --h-control: 40px; }
    html, body { overflow-x: clip; }
    .page { padding-left: max(var(--s-3), env(safe-area-inset-left)); padding-right: max(var(--s-3), env(safe-area-inset-right)); padding-bottom: calc(64px + env(safe-area-inset-bottom)); }
    .seg button, .tabs [role="tab"] { height: 34px; }
    .field input, .field input::placeholder, .select select, .deck select[data-role="nav"] { font-size: 16px; }   /* under 16px Safari zooms the page on focus */
    .strip.notice { display: block; padding: var(--s-2) 0; line-height: 1.4; }   /* the notice reads as one paragraph on a phone */
    .strip.notice strong, .strip.notice .grow { display: inline; white-space: normal; }
    .strip.notice strong::before { display: inline-block; margin-right: var(--s-2); vertical-align: middle; }
    .strip.notice .grow { margin-left: var(--s-2); }
    .strip:not(.notice) { flex-wrap: wrap; height: auto; }
    /* The deck sits under the phone in the flow, so a short screen gives its height to the phone, not to a reservation. */
    #devices { height: auto; }
    .phone-row { height: min(70svh, 640px); padding-bottom: var(--s-2); }
    .deck { position: static; transform: none; width: 100%; margin-top: var(--s-2); }
    .deck .addr { flex: 1 1 100%; }
    .deck .addr .go { height: 32px; }
    .deck .focus-btn { display: none; }
    .deck .via { flex: none; }
    .deck .via .ledger { left: auto; right: 0; width: min(440px, calc(100vw - 2 * var(--s-3))); }
    .deck .netlify { margin-left: 0; }
    .deck .seg { display: flex; flex: 1 1 100%; }
    .deck .seg button { flex: 1 1 0; padding: 0 var(--s-2); }
    .deck .seg[data-role="layout"] { flex: 1 1 auto; }
    .bench { padding-bottom: env(safe-area-inset-bottom); }
    .bench-bar { height: 48px; gap: var(--s-2); padding: 0 var(--s-3); }
    .tabs { flex: 1 1 auto; display: flex; }
    .tabs [role="tab"] { flex: 1 1 0; justify-content: center; padding: 0 var(--s-1); }
    .bench-bar .status { font-size: 0; gap: 0; }
    .bench-bar .status::before { content: ""; width: 8px; height: 8px; border-radius: 50%; background: var(--ink-3); }
    .bench-bar .status[data-live="true"]::before { background: var(--live); }
    #mode-badge #mode-text { display: none; }
    .chips { grid-template-columns: 1fr 1fr; }
    .chips button { min-height: 0; }
    .say-menu { width: calc(100vw - 24px); right: 12px; top: 56px; max-height: calc(100dvh - 72px); }
    .top { padding-right: 52px; }
    .fab { position: absolute; right: 0; top: var(--s-3); }
    .flow { grid-template-columns: 1fr 1fr; }
    .ask-eyebrow { flex-direction: column; align-items: flex-start; gap: 2px; }
    .term-foot { display: none; }   /* the phone has no keys to name; the tap hint is the title line's job */
  }
}

/* ------------------------------------------------------------- the device
   A part, and the one object on the page pretending to be physical, so it
   takes the whole depth budget. Colours drawn on the browser's own chrome —
   Safari's glass, Chrome's bars, the keyboard — are measurements off a real
   phone, not design tokens, and stay literal here on purpose. */
@layer parts {
  .device { --scale: 0.5; display: grid; place-items: center; min-height: 0; }
  /* --pw/--ph the frame box, --ix/--iy where the viewport sits, --vw/--vh its size. Two SVG layers, the page's iframe between them. */
  .phone { width: calc(var(--pw) * var(--scale)); height: calc(var(--ph) * var(--scale)); position: relative; transition: width var(--t-move) var(--ease), height var(--t-move) var(--ease); transform-origin: 50% 50%; }
  /* A turn: the phone takes its new box at once, then the transform carries it from where it was, a quarter turned, into place. */
  .phone.turning { transition: transform var(--t-turn, 900ms) cubic-bezier(.45, 0, .18, 1); }
  .phone.turning.jump { transition: none; }
  /* The body. Its own element under the drawing: a filter on the scaled container
     would rasterise the iframe and both SVG layers into one bitmap and blur them.
     The bezel picks up a little of the room (the ground is mixed into its highlight);
     the rim is the machined edge catching light; the contact shadow is wider and
     softer than the object, and the same size on screen whatever the scale. */
  .phone .shadow { position: absolute; top: 0; left: 0; width: var(--pw); height: var(--ph); transform: scale(var(--scale)); transform-origin: top left; border-radius: var(--body-rx);
    background: var(--bezel);
    box-shadow: inset 0 0 0 calc(.5px / var(--scale)) var(--rim),
                0 calc(24px / var(--scale)) calc(60px / var(--scale)) var(--contact-a),
                0 calc(4px / var(--scale)) calc(10px / var(--scale)) var(--contact-b);
    pointer-events: none; transition: width var(--t-move) var(--ease), height var(--t-move) var(--ease), transform var(--t-move) var(--ease), border-radius var(--t-move) var(--ease); }
  .phone .screen { position: absolute; top: 0; left: 0; width: var(--pw); height: var(--ph); transform: scale(var(--scale)); transform-origin: top left; will-change: transform; transition: width var(--t-move) var(--ease), height var(--t-move) var(--ease), transform var(--t-move) var(--ease), opacity var(--t-press) var(--ease); }
  .device[data-swap="out"] .phone .screen { opacity: 0; transition: opacity 180ms ease-out; }
  @keyframes screen-in { from { opacity: 0; } }
  .device[data-swap="in"] .phone .screen { animation: screen-in var(--t-move) var(--ease); }
  .phone .screen iframe { transform: translateZ(0); transform-origin: 0 0; transition: transform var(--t-move) var(--ease); }
  .phone .layer { position: absolute; inset: 0; }
  .phone .layer.under [data-role="addr"] { cursor: text; }
  .phone .layer svg { display: block; width: 100%; height: 100%; }
  .phone .layer.over, .phone .layer.hw, .phone .layer.float { pointer-events: none; }
  /* the kit's titanium band is replaced by the body above; the buttons stay */
  .phone .under .shell { fill: none; stroke: none; }
  .phone .under .buttons rect { fill: #26292E; }
  .phone .under .glass { fill: #fff; }
  .phone[data-theme="dark"] .under .glass { fill: var(--glass-dark); }
  /* Retracting moves the bar. Apple's own curve for this is a long ease-out;
     260ms matches the phone closely enough that the two are hard to tell apart. */
  .phone .float .piece, .phone .float .wash {
    transition: left var(--t-move) var(--ease), top var(--t-move) var(--ease),
                width var(--t-move) var(--ease), height var(--t-move) var(--ease),
                border-radius var(--t-move) var(--ease), opacity 160ms linear, transform var(--t-move) var(--ease);
  }
  .phone .float .piece.coming { opacity: 0; transform: scale(.86); }
  .phone .float .piece.going { opacity: 0; transform: scale(.86); pointer-events: none; transition-duration: .2s, .2s, .2s, .2s, .2s, .1s, .2s; }
  @media (prefers-reduced-motion: reduce) {
    .phone .float .piece, .phone .float .wash, .phone .page-clip, .phone .page-clip iframe { transition: none !important; }
  }
  /* The status bar is the same glass as the bar at the bottom: the page runs under it and shows through. */
  /* No z-index: the clip makes no stacking context of its own, so one here would lift the frost above the status bar's glyphs. */
  .phone .topfrost { position: absolute; left: 0; top: 0; pointer-events: none;
    background: color-mix(in srgb, var(--page-bg-top, #f1f1f1) 62%, transparent);
    -webkit-backdrop-filter: blur(22px) saturate(1.6); backdrop-filter: blur(22px) saturate(1.6); }
  /* The minimised address strip's pill, on the frost: a 150×34 pill in the page's material, the host trimmed from the left. */
  .phone .topfrost .pill { position: absolute; left: 50%; width: 150px; height: 34px; margin-left: -75px; border-radius: 17px; box-sizing: border-box; padding: 0 14px;
    background: var(--page-mat-top, rgba(255,255,255,.62)); color: var(--page-ink-top, #111); font: 400 15px/34px Roboto, -apple-system, system-ui, sans-serif; text-align: center;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis; direction: rtl; unicode-bidi: plaintext; box-shadow: 0 0 0 .5px rgba(0,0,0,.06); }
  .phone .float .piece { position: absolute; background: rgba(241,241,241,.7); -webkit-backdrop-filter: blur(12px) saturate(1.7); backdrop-filter: blur(12px) saturate(1.7); box-shadow: 0 6px 20px rgba(0,0,0,.16), 0 1px 3px rgba(0,0,0,.06), 0 0.5px 0 rgba(255,255,255,.9) inset; }
  .phone[data-theme="dark"] .float .piece { background: rgba(22,22,24,.82); box-shadow: 0 4px 16px rgba(0,0,0,.4), 0 0.5px 0 rgba(255,255,255,.12) inset, 0 0 0 .5px rgba(255,255,255,.08); }
  /* Glass over a dark page goes dark and stays see-through: the page's colour comes through the blur, as on the phone. */
  .phone[data-glass="dark"] .float .piece { background: rgba(18,18,22,.58); box-shadow: 0 4px 16px rgba(0,0,0,.35), 0 0.5px 0 rgba(255,255,255,.09) inset, 0 0 0 .5px rgba(255,255,255,.05); }
  .phone .float .piece svg { display: block; color: var(--page-ink, #111); fill: var(--page-ink, #111); }
  .phone .float .wash { position: absolute; border-radius: 0 0 var(--corner) var(--corner); background: linear-gradient(to bottom, rgba(250,250,250,0), rgba(250,250,250,.34) 68%); -webkit-mask-image: linear-gradient(to bottom, transparent, #000 40%); mask-image: linear-gradient(to bottom, transparent, #000 40%); }
  .phone[data-foot="dark"] .float .wash { background: linear-gradient(to bottom, rgba(0,0,0,0), rgba(0,0,0,.34) 68%); }
  .phone[data-foot="light"] .float .wash { background: linear-gradient(to bottom, rgba(250,250,250,0), rgba(250,250,250,.34) 68%); }
  /* Safari's edge extension: the zone under the top layout's toolbar takes the page's own colour, not the browser's */
  .phone .under .band.edge .bar { fill: var(--page-bg, #fff); }
  .phone .under .band.edge .mat { fill: var(--page-mat, rgba(255,255,255,.62)); }
  .phone .under .band.edge { filter: drop-shadow(0 1px 2px rgba(0, 0, 0, .10)); }
  /* The glyphs over an edge-painted band take the ink the page's colour there calls for: white on a dark page. */
  .phone .under .band.edge > g { color: var(--page-ink, #111); fill: var(--page-ink, #111); }
  .phone .under .band.edge.chrome-top .bar { fill: var(--page-bg-top, #fff); }
  .phone .under .band.edge.chrome-top .mat { fill: var(--page-mat-top, rgba(255,255,255,.62)); }
  .phone .under .band.edge.chrome-top > g { color: var(--page-ink-top, #111); fill: var(--page-ink-top, #111); }
  .phone[data-glass="dark"] .under .band.edge .mat, .phone[data-glass-top="dark"] .under .band.edge.chrome-top .mat { stroke: rgba(255,255,255,.14); }
  .phone[data-edge-top="true"] .under .status-bg { fill: var(--page-bg-top, #fff); }
  /* The status bar over a page-tinted zone reads in that zone's ink: white over GitHub's dark grey, as on the phone. */
  .phone[data-edge-top="true"] .over .status { color: var(--page-ink-top, #111); fill: var(--page-ink-top, #111); }
  .phone[data-edge-top="true"][data-status-ink="light"] .status .battery { fill: #111; }
  .phone[data-edge-top="true"][data-status-ink="dark"] .status .battery { fill: #fff; }
  /* Safari 26's compact layout draws no home indicator over its bar zone (four screenshots of a real iPhone 17). */
  .phone[data-browser="safari"][data-layout="compact"] .over .nav.home-indicator { display: none; }
  .phone[data-edge-bottom="true"] .over .nav.home-indicator,
  .phone[data-edge-bottom="true"] .over .nav.home-indicator * { fill: var(--nav-ink, rgba(0,0,0,.28)); stroke: none; }
  /* The clip is the screen's rounded rectangle and nothing more: the page's own
     colour lives on the page-clip inside it, so the browser bands drawn under it
     (Chrome's address bar, Safari 18's top bar) show through where the page is not. */
  .phone .viewport-clip { background: transparent; position: absolute; top: var(--sy); left: var(--sx); width: var(--sw); height: var(--sh); border-radius: var(--corner); overflow: hidden; }
  /* the glass has an edge: a thin dark fall at the top of the screen only */
  .phone .viewport-clip::after { content: ""; position: absolute; inset: 0; z-index: 6; border-radius: var(--corner); box-shadow: inset 0 1px 3px var(--screen-edge); pointer-events: none; }
  /* Safari's Smart App Banner, measured on a real iPhone at 3 px/pt: 68 tall, a 40 icon inset 19. */
  /* It sits in Safari's page-tinted zone and takes that colour, its title in the zone's ink (the user's iPhone, GitHub, 2026-09-04). */
  .phone .app-banner { position: absolute; display: flex; align-items: center; gap: 12px; padding: 0 19px; box-sizing: border-box; color: var(--page-ink-top, #111);
    background: var(--page-bg-top, #fff); border-bottom: 1px solid color-mix(in srgb, var(--page-ink-top, #111) 14%, transparent); font-family: var(--sans); }
  .phone .app-banner img, .phone .app-banner i { width: 40px; height: 40px; border-radius: 9px; flex: none; object-fit: cover; background: #f0f0f2; border: 1px solid color-mix(in srgb, var(--page-ink-top, #111) 12%, transparent); box-sizing: border-box; }
  .phone .app-banner .t { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
  .phone .app-banner b { font: 600 15px/1.2 var(--sans); color: var(--page-ink-top, #111); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .phone .app-banner span { font: 13px/1.25 var(--sans); color: color-mix(in srgb, var(--page-ink-top, #111) 58%, transparent); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  /* The button says OPEN in capitals; on a dark ground its blue is the lighter one (the user's phone, 2026-09-04). */
  .phone .app-banner u { flex: none; text-decoration: none; height: 32px; padding: 0 18px; border-radius: 16px; background: #0a84ff; color: #fff; font: 700 14px/32px var(--sans); text-transform: uppercase; letter-spacing: .03em; }
  .phone .app-banner s { flex: none; text-decoration: none; width: 28px; height: 28px; border-radius: 14px; background: color-mix(in srgb, var(--page-ink-top, #111) 12%, transparent); color: #0a84ff; font: 400 17px/28px var(--sans); text-align: center; }
  .phone[data-status-ink="light"] .app-banner u { background: #4c9fff; }
  .phone[data-status-ink="light"] .app-banner s { background: color-mix(in srgb, var(--page-ink-top, #fff) 18%, transparent); color: #6db2ff; }
  /* Safari's menu, measured on a real iPhone: 248 across, its right edge 34 in from the screen and its foot just above the bar. */
  .phone .browser-menu { position: absolute; right: 34px; bottom: 104px; width: 248px; z-index: 4;
    background: rgba(249,249,249,.94); -webkit-backdrop-filter: blur(24px) saturate(1.8); backdrop-filter: blur(24px) saturate(1.8);
    border-radius: 15px; box-shadow: 0 12px 40px rgba(0,0,0,.22), 0 0 0 .5px rgba(0,0,0,.06);
    overflow: hidden; font-family: var(--sans); }
  .phone .browser-menu button { display: flex; align-items: center; gap: 14px; width: 100%; padding: 13px 16px; border: 0; background: none;
    font: 16px/1.2 var(--sans); color: #111; text-align: left; cursor: pointer; }
  .phone .browser-menu button:hover { background: rgba(0,0,0,.05); }
  .phone .browser-menu svg { width: 21px; height: 21px; flex: none; color: #111; }
  .phone .browser-menu hr { border: 0; border-top: .5px solid rgba(0,0,0,.16); margin: 0; }
  .phone .browser-menu .pair { display: flex; border-top: .5px solid rgba(0,0,0,.16); }
  .phone .browser-menu .pair button { justify-content: center; font-size: 13px; padding: 12px 6px; }
  .phone .float .piece[data-piece="back"], .phone .float .piece[data-piece="more"] { pointer-events: auto; cursor: pointer; }
  /* The finger. A pad rather than a point: 26 across is about what a fingertip covers, and it presses in when it is down. */
  /* Two tones, so it reads on a dark page and a light one alike: a pale pad with a dark rim and a light halo outside it. */
  /* The finger's own layer covers the whole screen, bars and glass included, and is cut to the screen's rounded rectangle. The
     real cursor is hidden over all of it, since the finger is the pointer here. */
  .phone .layer.touch { pointer-events: none; clip-path: inset(var(--sy) var(--sx) var(--sy) var(--sx) round var(--corner)); }
  .phone .screen, .phone .screen * { cursor: none !important; }
  .phone .layer.touch .finger { position: absolute; z-index: 3; width: 28px; height: 28px; margin: -14px 0 0 -14px; border-radius: 50%;
    background: rgba(255,255,255,.42); box-shadow: 0 0 0 2px rgba(0,0,0,.62), 0 0 0 4px rgba(255,255,255,.85), 0 3px 10px rgba(0,0,0,.45);
    pointer-events: none; transition: transform var(--t-press) ease, background var(--t-press) ease; }
  .phone .layer.touch .finger.down { transform: scale(.82); background: rgba(255,255,255,.62); }
  /* The screen before a page has landed: black edge to edge, and the mark strikes on the way an OLED does, then holds a
     low neon flicker until the page arrives. Over the bars and the glass, under the finger and the hardware, cut to the
     screen's rounded rectangle. The base state is the settled mark, so a room that asks for no motion just shows it. */
  .phone .layer.boot { z-index: 6; pointer-events: none; background: var(--boot-screen); clip-path: inset(var(--sy) var(--sx) var(--sy) var(--sx) round var(--corner));
    display: grid; place-items: center; opacity: 0; visibility: hidden; transition: opacity .34s ease, visibility 0s linear .34s; }
  .phone[data-boot="on"] .layer.boot { opacity: 1; visibility: visible; transition: opacity 0s, visibility 0s; }
  .phone .boot .mark { display: grid; justify-items: center; gap: 22px; color: var(--boot-ink); transform: translateY(-4%); }
  .phone .boot .mark svg { width: 124px; height: 124px; display: block; overflow: visible; }
  .phone .boot .mark .b { fill: none; stroke: currentColor; stroke-width: 10; stroke-linecap: round; stroke-linejoin: round; }
  .phone .boot .mark .name { font: 500 15px/1 var(--sans); letter-spacing: .34em; text-indent: .34em; text-transform: lowercase; color: var(--boot-ink); opacity: .82; }
  /* The current: sparks of the product's green running round the letter's edge and through its counters, each a dash
     pattern that never divides the path evenly, so the run does not repeat where the eye can catch it. One sharp, one
     soft and wide for the glow, one for the inside. They flicker on their own clock, out of step with the tube. */
  .phone .boot .mark .arc { fill: none; stroke: var(--boot-eye); stroke-linecap: round; filter: drop-shadow(0 0 2px var(--boot-eye)) drop-shadow(0 0 6px var(--boot-eye)); }
  .phone .boot .mark .a1 { stroke-width: 2.8; stroke-dasharray: 4 38 10 57 3 26 7 44; }
  .phone .boot .mark .a2 { stroke-width: 7; stroke-dasharray: 2 29 6 47 12 71; opacity: .55; filter: blur(2.5px); }
  .phone .boot .mark .a3 { stroke-width: 2.2; stroke-dasharray: 3 23 8 41 2 19; }
  /* the sweep: one hairline of light crossing the mark on the strike, the way a tube fills */
  .phone .boot .mark .sweep { fill: url(#boot-sweep); opacity: 0; }
  .phone[data-boot="on"] .boot .mark { animation: boot-strike 1.35s steps(1, end) .25s both, boot-neon 3.7s linear 1.6s infinite; }
  .phone[data-boot="on"] .boot .mark svg { animation: boot-jitter 1.35s steps(1, end) .25s both; }
  .phone[data-boot="on"] .boot .mark .sweep { animation: boot-sweep 1.1s cubic-bezier(.2, .7, .3, 1) .8s both; }
  .phone[data-boot="on"] .boot .mark .a1 { animation: arc-run-1 1.4s linear infinite, arc-flick .74s steps(1, end) infinite; }
  .phone[data-boot="on"] .boot .mark .a2 { animation: arc-run-2 2.1s linear infinite, arc-flick 1.1s steps(1, end) .3s infinite; }
  .phone[data-boot="on"] .boot .mark .a3 { animation: arc-run-3 1.7s linear infinite, arc-flick .62s steps(1, end) .17s infinite; }
  /* The phone is hidden behind the tab machine's kernel log until the machine is up; the strike waits for the phone to show. */
  .phone-stage[data-booted="false"] .boot .mark, .phone-stage[data-booted="false"] .boot .mark * { animation: none; }
  /* Nothing to look at, and why. The same layer the mark waits on: the screen is
     the right place to say it, because the screen is where the person is looking. */
  .phone[data-boot="notice"] .layer.boot { opacity: 1; visibility: visible; transition: opacity .2s ease; }
  .phone[data-boot="notice"] .boot .mark { display: none; }
  .phone .boot .notice { max-width: 78%; text-align: center; display: grid; gap: 10px; justify-items: center; }
  .phone .boot .notice b { font: 600 17px/1.35 var(--sans); color: var(--boot-ink); letter-spacing: -.01em; }
  .phone .boot .notice span { font: 400 13.5px/1.5 var(--sans); color: color-mix(in srgb, var(--boot-ink) 62%, transparent); }
  .phone .boot .notice::before { content: ""; width: 34px; height: 34px; border-radius: 50%; margin-bottom: 4px;
    border: 1.5px solid color-mix(in srgb, var(--boot-eye) 55%, transparent); box-shadow: 0 0 14px color-mix(in srgb, var(--boot-eye) 30%, transparent) inset; }
  /* the strike: dark, a first flash that does not hold, a stutter, then on */
  @keyframes boot-strike { 0% { opacity: 0; } 9% { opacity: .9; } 12% { opacity: .08; } 19% { opacity: .55; } 22% { opacity: 0; } 34% { opacity: 1; } 38% { opacity: .18; } 41% { opacity: 1; } 47% { opacity: .62; } 50% { opacity: 1; } 71% { opacity: 1; } 73% { opacity: .3; } 75% { opacity: 1; } 100% { opacity: 1; } }
  /* the tube settles a hair off true on each flash, the way a cold one does */
  @keyframes boot-jitter { 0%, 22% { transform: translate(0, 0) scale(1.012); } 34% { transform: translate(-1px, 0) scale(1.004); } 41% { transform: translate(1px, 0) scale(1); } 50%, 100% { transform: none; } }
  /* the hold: mostly on, with the small dips a neon has, on a loop long enough not to read as a beat */
  @keyframes boot-neon { 0%, 100% { opacity: 1; } 13% { opacity: .96; } 14% { opacity: .78; } 15% { opacity: 1; } 43% { opacity: 1; } 44% { opacity: .86; } 45% { opacity: 1; } 47% { opacity: .92; } 48% { opacity: 1; } 79% { opacity: 1; } 80% { opacity: .7; } 81% { opacity: 1; } }
  @keyframes boot-sweep { 0% { opacity: 0; transform: translateX(-120px); } 15% { opacity: .9; } 100% { opacity: 0; transform: translateX(120px); } }
  /* the sparks run by a whole pattern each loop, so the loop has no seam; the wide one runs the other way */
  @keyframes arc-run-1 { to { stroke-dashoffset: -189; } }
  @keyframes arc-run-2 { to { stroke-dashoffset: 167; } }
  @keyframes arc-run-3 { to { stroke-dashoffset: -96; } }
  @keyframes arc-flick { 0% { opacity: 1; } 11% { opacity: .5; } 19% { opacity: .95; } 27% { opacity: .25; } 33% { opacity: 1; } 52% { opacity: .7; } 58% { opacity: 1; } 71% { opacity: .35; } 76% { opacity: .9; } 88% { opacity: .6; } 100% { opacity: 1; } }
  /* A page lands whole: blank while its viewport, banner and edge colour come in, then on in one piece. */
  .phone .page-clip iframe { transition: opacity .16s ease; }
  .phone .page-clip.landing iframe, .phone .page-clip.landing ~ .app-banner { opacity: 0; }
  .phone .app-banner { transition: background-color .3s linear, opacity .16s ease; }
  .phone .under .band .bar, .phone .under .band .mat, .phone .under .status-bg { transition: fill .3s linear; }
  .phone .page-clip { transition: height var(--t-move) var(--ease), top var(--t-move) var(--ease), background .3s linear; position: absolute; top: var(--iy); left: 0; width: var(--vw); height: var(--vclip, var(--vh)); overflow: hidden; background: var(--page-bg, #fff); border-radius: 0 0 var(--page-rb, 0) var(--page-rb, 0); }
  /* An installed app laid out under the status bar: the zone above the page is the page's own top colour, as iOS paints it. */
  .phone[data-browser="pwa"] .page-clip { background: linear-gradient(to bottom, var(--page-bg-top, var(--page-bg, #fff)) 0, var(--page-bg-top, var(--page-bg, #fff)) var(--inset-top, 0px), var(--page-bg, #fff) var(--inset-top, 0px)); }
  .phone .screen iframe { position: absolute; top: 0; left: 0; display: block; border: 0; background: #fff; width: var(--vw); height: var(--vh); }
  /* the keyboard: over the page, under the home indicator; the keys take presses, the rest lets them through */
  /* The keys never leave the glass: the layer is clipped to the screen's rectangle and the rise happens on a wrapper inside it, so nothing spills past the phone's box, and nothing reflows or refits around it. */
  .phone .layer.keys { pointer-events: none; overflow: hidden; clip-path: inset(var(--sy) var(--sx) var(--sy) var(--sx) round var(--corner)); }
  .phone .layer.keys .kb-motion { position: absolute; inset: 0; }
  .phone .keys .kb { position: absolute; border-radius: 0 0 var(--corner) var(--corner); overflow: hidden; }
  .phone .keys .kb svg { display: block; }
  .phone .keys .kb.glass { -webkit-backdrop-filter: blur(28px) saturate(1.4); backdrop-filter: blur(28px) saturate(1.4); }
  .phone .keys .kb-piece { position: absolute; pointer-events: auto; background: rgba(255,255,255,.86); -webkit-backdrop-filter: blur(18px) saturate(1.6); backdrop-filter: blur(18px) saturate(1.6); box-shadow: 0 6px 20px rgba(0,0,0,.16), 0 1px 3px rgba(0,0,0,.06), 0 0.5px 0 rgba(255,255,255,.9) inset; }
  .phone .keys .kb-piece[data-tint="dark"] { background: rgba(52,54,56,.9); box-shadow: 0 4px 16px rgba(0,0,0,.4), 0 0.5px 0 rgba(255,255,255,.12) inset, 0 0 0 .5px rgba(255,255,255,.1); }
  .phone .keys .kb-piece[data-tint="light"] { background: rgba(250,250,250,.94); }
  .phone[data-keyboard="open"] .under .chrome-bottom { visibility: hidden; }
  .phone[data-keyboard="open"] .under .glass { fill: var(--page-bg, #fff); }
  .phone .keys .kb-piece svg { display: block; }
  .phone .keys .picker svg { width: 16px; height: 16px; flex: none; }
  .phone .keys .picker .key:active { filter: brightness(.92); }
  .phone .keys .addr-mini { display: flex; align-items: center; justify-content: center; font: 400 15px/1 system-ui, sans-serif; color: #111; }
  .phone .keys .key { pointer-events: auto; cursor: pointer; }
  .phone .keys .key:active rect:first-child, .phone .keys .key[data-pressed] rect:first-child { filter: brightness(.82); }
  @keyframes kb-rise { from { transform: translateY(var(--kb-rise, 340px)); } to { transform: none; } }
  @keyframes kb-fall { from { transform: none; } to { transform: translateY(var(--kb-rise, 340px)); } }
  .phone .layer.keys[data-motion="rise"] .kb-motion { animation: kb-rise .32s cubic-bezier(.2, .8, .2, 1) both; }
  .phone .layer.keys[data-motion="fall"] .kb-motion { animation: kb-fall .24s cubic-bezier(.4, 0, .8, .4) both; pointer-events: none; }
  .phone[data-keyboard="open"] .float { visibility: hidden; }
  .phone .float .piece[data-role="addr"] { pointer-events: auto; cursor: text; }
  .phone .keys .addr-edit { position: absolute; pointer-events: auto; display: flex; align-items: center; gap: 8px; padding: 0 12px 0 18px; box-sizing: border-box; background: rgba(255,255,255,.96); box-shadow: 0 6px 20px rgba(0,0,0,.16), 0 1px 3px rgba(0,0,0,.06); }
  .phone[data-theme="dark"] .keys .addr-edit { background: rgba(44,44,48,.94); }
  .phone .keys .omni { flex: 1 1 auto; min-width: 0; border: 0; outline: 0; background: transparent; font: 400 17px/1 system-ui, sans-serif; color: #111; }
  .phone[data-theme="dark"] .keys .omni { color: #f2f2f2; }
  .phone .keys .omni-cancel { position: absolute; pointer-events: auto; border: 0; border-radius: 50%; background: rgba(255,255,255,.96); box-shadow: 0 6px 20px rgba(0,0,0,.16), 0 1px 3px rgba(0,0,0,.06); display: grid; place-items: center; cursor: pointer; padding: 0; }
  .phone .keys .omni-cancel svg { width: 18px; height: 18px; }
  .phone .keys .clear { flex: 0 0 auto; width: 22px; height: 22px; border-radius: 50%; border: 0; background: rgba(120,120,128,.55); padding: 0; cursor: pointer; display: grid; place-items: center; }
  .phone .keys .clear svg { width: 10px; height: 10px; }
  .phone .over .status text, .phone .over .nav rect { paint-order: stroke; }
