/*
  Guardeye app design system (job B). Every view uses these tokens and components; a view adds
  its own CSS only for layout that is truly its own. Component reference: docs/APP.md.

  Direction: the same as the command-center orbit redesign (build/cc-redesign) - a dark blueprint
  deck: near-black navy ground with a two-scale grid, flat boxes with corner ticks, monospace
  uppercase labels, one flat accent (--accent: links, the main action, focus, "in progress") and
  colour that only ever means a state that needs attention: amber waiting or warning, red failing,
  green only to confirm an action that just worked. Healthy is quiet: a solid neutral dot, idle a
  hollow one, no data a dashed one. No glow, no gradient ramp; a shadow only under what floats
  (the detail sheet). One primary number per screen ([data-primary]), the others smaller.
  A "blueprint paper" light theme. Enforced by ops/test-design-rules.mjs.
  That language was adapted from FounderOS-DEMO (MIT License, Copyright (c) 2026 FounderOS; see
  the command center's docs/THIRD-PARTY.md). No code, names or branding of theirs are used here.

  Rules: tokens only. Every colour, space, type size, radius, control height, duration and layer comes
  from the custom properties below, defined once; a component or a view never writes a raw value (a
  data-driven width or position set from script is the one exception). 4.5:1 text contrast in both
  themes, a visible focus ring on everything focusable, 44 px touch targets, and prefers-reduced-motion
  stops every animation. Every interactive component defines hover, focus, disabled and (where it can
  wait) loading; every list or panel that can be empty or fail has an empty and an error look.
*/

/* ── tokens ── */
:root{
  --ground:#04060B; --ground-2:#070A12; --surface:#090D17; --surface-2:#0E1422; --surface-3:#141C2D; --rail:#060910;
  --ink:#E6EAF3; --ink-2:#A3ACBF; --ink-3:#7B859B; --line:#18202F; --line-2:#26314A;
  --solid:#E6EAF3; --solid-ink:#04060B; --accent-ink:#03121C; --solid-soft:rgba(230,234,243,.07);
  --tick:rgba(150,180,235,.38);
  --grid:rgba(120,150,210,.055); --grid-major:rgba(120,150,210,.10);
  --good:#2FD98A; --good-soft:rgba(47,217,138,.12);
  --accent:#5EC9F8; --accent-soft:rgba(94,201,248,.12);
  --warn:#FFB020; --warn-soft:rgba(255,176,32,.12);
  --crit:#FF5D6C; --crit-soft:rgba(255,77,94,.12);
  --idle:#6A7490;
  --overlay:rgba(2,4,9,.6); --shadow-sheet:0 0 60px rgba(0,0,0,.35);
  /* shape */
  --r:3px; --r-2:6px; --r-3:10px;
  --bw:1px; --bw-mark:3px;
  /* space: one 4-based scale; nothing between the steps */
  --s0:2px; --s1:4px; --s2:8px; --s3:12px; --s4:16px; --s5:24px; --s6:32px; --s7:48px; --s8:64px;
  /* type: families, one size scale, weights, tracking, line height */
  --sans:"Inter Tight",system-ui,-apple-system,"Segoe UI",sans-serif;
  --mono:"JetBrains Mono","IBM Plex Mono",ui-monospace,Menlo,monospace;
  --fs-1:11px; --fs-2:12px; --fs-3:14px; --fs-4:16px; --fs-5:20px; --fs-6:28px; --fs-7:36px; --fs-8:44px;
  --fs-display:clamp(26px,3.2vw,38px); --fs-stat:var(--fs-5); --fs-big:clamp(var(--fs-7),8vw,var(--fs-8));
  --fw-regular:400; --fw-medium:500; --fw-semibold:600; --fw-bold:700;
  --ls-tight:-.025em; --ls-1:.08em; --ls-2:.12em; --ls-3:.16em;
  --lh-tight:1.1; --lh-snug:1.25; --lh-body:1.5;
  /* controls: one touch target, a small one on desktop only, a large one for the signing footer */
  --ctl:44px; --ctl-sm:32px; --ctl-lg:56px; --check:20px;
  /* focus, disabled, motion, layers, measures, skeleton heights */
  --ring:0 0 0 3px var(--accent-soft); --ring-solid:0 0 0 3px var(--solid-soft); --ring-crit:0 0 0 3px var(--crit-soft); --focus:2px solid var(--accent); --focus-offset:2px;
  --dim:.6;
  --dur-1:.15s; --dur-2:.25s; --dur-3:.35s; --ease:cubic-bezier(.2,.7,.2,1);
  --z-bar:3; --z-tip:5; --z-skip:50;
  --w-form:400px; --w-field:240px; --w-sm:760px; --w-md:980px; --w-lg:1240px; --w-sheet:460px;
  --h-1:48px; --h-2:80px; --h-3:128px;
  /* small fixed sizes */
  --dim-2:.85; --bw-spin:1.5px; --ls-4:.24em; --w-btn-end:84px; --w-step:96px; --w-col:420px; --w-gate-side:360px; --mark:30px; --dot-sm:6px; --lift:6px; --corner:9px;
  color-scheme:dark;
}
:root[data-theme="light"]{
  --ground:#EEF2F8; --ground-2:#E7ECF4; --surface:#FBFCFE; --surface-2:#F0F3F9; --surface-3:#E4E9F2; --rail:#F7F9FC;
  --ink:#0C1222; --ink-2:#3F4A62; --ink-3:#5A6479; --line:#D5DCE8; --line-2:#BCC6D8;
  --solid:#0C1222; --solid-ink:#FFFFFF; --accent-ink:#FFFFFF; --solid-soft:rgba(12,18,34,.06);
  --tick:rgba(30,70,150,.45);
  --grid:rgba(30,70,150,.06); --grid-major:rgba(30,70,150,.11);
  --good:#0B7A4B; --good-soft:rgba(14,138,85,.12);
  --accent:#0A68A6; --accent-soft:rgba(11,114,181,.11);
  --warn:#8F5800; --warn-soft:rgba(168,104,0,.12);
  --crit:#B8213A; --crit-soft:rgba(196,38,57,.10);
  --idle:#7A849A;
  color-scheme:light;
}

/* Breakpoints (a media query cannot read a custom property, so they are written out; there are four):
   480 small phone (login art) · 640 phone (header: who and controls on their own line) · 860 header and page padding tighten · 1000 two columns fold to one. */

/* ── base ── */
*,*::before,*::after{box-sizing:border-box}
[hidden]{display:none!important}
html{-webkit-text-size-adjust:100%}
html,body{min-height:100%}
body{margin:0;background:var(--ground);color:var(--ink);font-family:var(--sans);font-size:var(--fs-3);line-height:var(--lh-body);-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility}
h1,h2,h3,p{margin:0}
h1,h2,h3{text-wrap:balance}
button,input,select,textarea{font:inherit;color:inherit}
a{color:var(--accent)}
a:hover{color:var(--ink)}
:focus-visible{outline:var(--focus);outline-offset:var(--focus-offset);border-radius:var(--s0)}
::selection{background:var(--accent-soft)}
.sr-only{position:absolute!important;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
.skip{position:absolute;left:var(--s4);top:-60px;z-index:var(--z-skip);background:var(--solid);color:var(--solid-ink);padding:var(--s2) var(--s4);border-radius:var(--r-2);font:var(--fw-semibold) var(--fs-2) var(--mono);text-decoration:none}
.skip:focus{top:var(--s4)}

/* type */
.display{font-family:var(--sans);font-weight:var(--fw-semibold);font-size:var(--fs-display);letter-spacing:var(--ls-tight);line-height:var(--lh-tight)}
.h1{font-family:var(--mono);font-size:var(--fs-3);font-weight:var(--fw-semibold);letter-spacing:var(--ls-3);text-transform:uppercase;line-height:var(--lh-snug)}
.h1::before{content:"// ";color:var(--ink-3)}
.h2{font-family:var(--mono);font-size:var(--fs-2);font-weight:var(--fw-semibold);letter-spacing:var(--ls-2);text-transform:uppercase}
.label{font-family:var(--mono);font-size:var(--fs-1);letter-spacing:var(--ls-2);text-transform:uppercase;color:var(--ink-3)}
.lede{color:var(--ink-2);max-width:68ch;font-size:var(--fs-3)}
.mono{font-family:var(--mono)}
.num{font-variant-numeric:tabular-nums}
.muted{color:var(--ink-2)}
.wrap-any{overflow-wrap:anywhere}
/* small print under a control or a list: .help (quiet) · .help.err (a failure) · .help.muted (a notch darker) */
.help{font-size:var(--fs-2);color:var(--ink-3)}
.help.muted{color:var(--ink-2)}
.help.err{color:var(--crit)}
/* "no data": always this, never a zero that is not real */
.nd{color:var(--ink-3);font-family:var(--mono);font-weight:var(--fw-medium);letter-spacing:var(--ls-1);font-size:var(--fs-2);text-transform:lowercase;font-style:normal}

/* ── layout helpers: the only way a view lays out a few children (no inline styles) ── */
.stack{display:flex;flex-direction:column;gap:var(--s3);min-width:0}
.stack.sm{gap:var(--s2)} .stack.xs{gap:var(--s1)} .stack.lg{gap:var(--s4)}
.cluster{display:flex;flex-wrap:wrap;align-items:center;gap:var(--s2)}
.cluster.sm{gap:var(--s1)} .cluster.lg{gap:var(--s3) var(--s4)}
.grow{flex:1 1 0;min-width:0}
.measure{max-width:var(--w-form)}
.plain-list{list-style:none;margin:0;padding:0}
.pt-0{padding-top:0} .mt-2{margin-top:var(--s2)} .mt-3{margin-top:var(--s3)} .ml-3{margin-left:var(--s3)} .m-0{margin:0}

/* blueprint ground: two-scale grid */
.blueprint{background-color:var(--ground);
  background-image:linear-gradient(var(--grid-major) 1px,transparent 1px),linear-gradient(90deg,var(--grid-major) 1px,transparent 1px),
    linear-gradient(var(--grid) 1px,transparent 1px),linear-gradient(90deg,var(--grid) 1px,transparent 1px);
  background-size:160px 160px,160px 160px,32px 32px,32px 32px;background-position:-1px -1px}

/* ── status dots: flat, no glow. Colour only for what needs attention (amber, red); the shape says the rest:
   good = solid and quiet · signal = in progress (the accent) · idle = hollow · nodata = dashed ── */
.dot{--c:var(--idle);display:inline-block;width:var(--s2);height:var(--s2);border-radius:50%;background:var(--c);flex:none;vertical-align:middle}
.dot.good{--c:var(--ink-2)} .dot.signal{--c:var(--accent)} .dot.warn{--c:var(--warn)} .dot.crit{--c:var(--crit)}
.dot.idle{background:transparent;border:1px solid var(--idle)}
.dot.nodata{background:transparent;border:1px dashed var(--ink-3)}
.dot.live{animation:pulse 2.4s ease-in-out infinite}
.state{display:inline-flex;align-items:center;gap:var(--s2);font-family:var(--mono);font-size:var(--fs-1);letter-spacing:var(--ls-1);text-transform:uppercase;color:var(--ink-2)}

/* ── buttons ──
   .btn (primary) · .btn.signal (the main action) · .btn.ghost · .btn.danger · .sm · .block
   hover: lifts a ring or a tint · focus: the shared ring · disabled: flat and inert ·
   loading: aria-busy="true" keeps the colours, shows the spinner, ignores clicks */
.btn{--bg:var(--solid);--fg:var(--solid-ink);--bd:var(--solid);
  display:inline-flex;align-items:center;justify-content:center;gap:var(--s2);min-height:var(--ctl);padding:0 var(--s4);border-radius:var(--r-2);
  background:var(--bg);color:var(--fg);border:var(--bw) solid var(--bd);font:var(--fw-semibold) var(--fs-2) var(--mono);letter-spacing:var(--ls-1);text-transform:uppercase;line-height:var(--lh-snug);
  cursor:pointer;text-decoration:none;white-space:nowrap;transition:background var(--dur-1),border-color var(--dur-1),color var(--dur-1),box-shadow var(--dur-1)}
.btn:hover:not(:disabled):not([aria-busy="true"]){box-shadow:var(--ring-solid);color:var(--fg)}
.btn:active:not(:disabled){filter:brightness(.94)}
.btn.ghost{--bg:transparent;--fg:var(--ink-2);--bd:var(--line-2)}
.btn.ghost:hover:not(:disabled){--fg:var(--ink);--bd:var(--ink-3);box-shadow:none}
.btn.signal{--bg:var(--accent);--fg:var(--accent-ink);--bd:var(--accent)}
.btn.signal:hover:not(:disabled):not([aria-busy="true"]){box-shadow:var(--ring)}
.btn.danger{--bg:transparent;--fg:var(--crit);--bd:color-mix(in srgb,var(--crit) 50%,transparent)}
.btn.danger:hover:not(:disabled){--bg:var(--crit-soft);--bd:var(--crit);box-shadow:none}
.btn:disabled,.btn[aria-disabled="true"]{--bg:var(--surface-3);--fg:var(--ink-3);--bd:var(--line-2);cursor:not-allowed;box-shadow:none;filter:none}
.btn[aria-busy="true"]{cursor:progress}
.btn.sm{min-height:var(--ctl-sm);padding:0 var(--s3);font-size:var(--fs-1)}
.btn.block{width:100%}
.btn .spin{width:var(--s3);height:var(--s3);border-radius:50%;border:var(--bw-spin) solid currentColor;border-right-color:transparent;animation:spin .8s linear infinite}
.seg{display:inline-flex;border:var(--bw) solid var(--line-2);border-radius:var(--r-2);overflow:hidden;background:var(--surface)}
.seg button{background:none;border:0;min-height:var(--ctl-sm);padding:0 var(--s3);font:var(--fw-medium) var(--fs-1) var(--mono);letter-spacing:var(--ls-1);text-transform:uppercase;color:var(--ink-2);cursor:pointer;transition:background var(--dur-1),color var(--dur-1)}
.seg button+button{border-left:var(--bw) solid var(--line-2)}
.seg button:hover:not(:disabled):not([aria-pressed="true"]){background:var(--solid-soft);color:var(--ink)}
.seg button[aria-pressed="true"]{background:var(--solid);color:var(--solid-ink)}
.seg button:disabled{color:var(--ink-3);cursor:not-allowed}
.seg button:focus-visible{outline-offset:calc(-1 * var(--focus-offset))}

/* ── inputs ──
   states: hover (darker edge) · focus (signal edge + ring) · invalid (aria-invalid, red edge) ·
   disabled / read-only (flat, dashed) */
.field{display:flex;flex-direction:column;gap:var(--s2);min-width:0}
.field > label,.field > .flabel{font:var(--fw-medium) var(--fs-1) var(--mono);letter-spacing:var(--ls-2);text-transform:uppercase;color:var(--ink-2)}
.input,.select,.textarea{width:100%;min-height:var(--ctl);padding:var(--s2) var(--s3);background:var(--surface);border:var(--bw) solid var(--line-2);border-radius:var(--r-2);color:var(--ink);font-size:var(--fs-4);line-height:var(--lh-snug);transition:border-color var(--dur-1),box-shadow var(--dur-1)}
.textarea{min-height:var(--h-2);resize:vertical}
.input::placeholder,.textarea::placeholder{color:var(--ink-3)}
.input:hover,.select:hover,.textarea:hover{border-color:var(--ink-3)}
.input:focus,.select:focus,.textarea:focus{outline:none;border-color:var(--accent);box-shadow:var(--ring)}
.input[aria-invalid="true"],.select[aria-invalid="true"],.textarea[aria-invalid="true"]{border-color:var(--crit)}
.input[aria-invalid="true"]:focus,.select[aria-invalid="true"]:focus,.textarea[aria-invalid="true"]:focus{box-shadow:var(--ring-crit)}
.input:disabled,.select:disabled,.textarea:disabled,.input[readonly],.textarea[readonly]{background:var(--surface-2);color:var(--ink-3);border-style:dashed;cursor:not-allowed}
.input[readonly],.textarea[readonly]{cursor:text}
.field .help{font-size:var(--fs-2);color:var(--ink-3)}
.field .err{font-size:var(--fs-2);color:var(--crit)}
.inputwrap{position:relative;display:flex}
.inputwrap .input{padding-right:var(--w-btn-end)}
.inputwrap .peek{position:absolute;right:var(--s1);top:50%;transform:translateY(-50%)}
.check{display:flex;gap:var(--s3);align-items:flex-start;min-height:var(--ctl);font-size:var(--fs-3);cursor:pointer}
.check input,.choice-box{width:var(--check);height:var(--check);margin:var(--s1) 0 0;accent-color:var(--accent);flex:none;cursor:pointer}
.check:has(input:disabled){color:var(--ink-3);cursor:not-allowed}
.check input:disabled{cursor:not-allowed}
.form{display:flex;flex-direction:column;gap:var(--s4)}
.formgrid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--s4)}
@media (max-width:640px){.formgrid{grid-template-columns:minmax(0,1fr)}}
/* alert: a message that interrupts. .alert.crit (failed) / .warn (look at this) / .good (what you just did worked: the one place green is used) */
.alert{display:flex;gap:var(--s3);align-items:flex-start;padding:var(--s3);border:var(--bw) solid var(--line-2);border-radius:var(--r-2);font-size:var(--fs-3);background:var(--surface-2)}
.alert.crit{border-color:color-mix(in srgb,var(--crit) 45%,transparent);background:var(--crit-soft)}
.alert.warn{border-color:color-mix(in srgb,var(--warn) 45%,transparent);background:var(--warn-soft)}
.alert.good{border-color:color-mix(in srgb,var(--good) 45%,transparent);background:var(--good-soft)}
.alert .dot{margin-top:var(--s2)}
.alert + .btn,.alert + .cluster{margin-top:var(--s3)}

/* ── stepper (guided flows, e.g. client signing) ──
   <ol class="stepper"><li data-state="done|current|todo"><span class="n">01</span><span class="t">Business</span></li>…</ol>
   The current step also gets aria-current="step". */
.stepper{list-style:none;margin:0;padding:0;display:flex;gap:0;counter-reset:s;overflow-x:auto;scrollbar-width:none}
.stepper li{flex:1 1 0;min-width:var(--w-step);display:flex;flex-direction:column;gap:var(--s2);padding:var(--s3) var(--s3) 0 0;position:relative;color:var(--ink-3)}
.stepper li::before{content:"";height:var(--s0);background:var(--line-2);display:block;margin-bottom:var(--s1)}
.stepper .n{font:var(--fw-semibold) var(--fs-1) var(--mono);letter-spacing:var(--ls-1)}
.stepper .t{font-size:var(--fs-2);font-weight:var(--fw-medium);white-space:nowrap}
.stepper li[data-state="done"]{color:var(--ink-2)}
.stepper li[data-state="done"]::before{background:var(--ink-2)}
.stepper li[data-state="current"]{color:var(--ink)}
.stepper li[data-state="current"]::before{background:var(--accent)}
.stepper button{all:unset;cursor:pointer;display:contents}
.stepper li:has(button:focus-visible){outline:var(--focus);outline-offset:calc(-1 * var(--focus-offset))}
/* numeric stepper: [−] 3 [+] */
.counter{display:inline-flex;align-items:stretch;border:var(--bw) solid var(--line-2);border-radius:var(--r-2);overflow:hidden;background:var(--surface)}
.counter button{background:none;border:0;width:var(--ctl);min-height:var(--ctl);cursor:pointer;color:var(--ink-2);font:var(--fw-medium) var(--fs-4) var(--mono);transition:background var(--dur-1),color var(--dur-1)}
.counter button:hover:not(:disabled){background:var(--surface-2);color:var(--ink)}
.counter button:disabled{color:var(--ink-3);cursor:not-allowed}
.counter button:focus-visible{outline-offset:calc(-1 * var(--focus-offset))}
.counter input{width:var(--s8);text-align:center;border:0;border-inline:var(--bw) solid var(--line-2);background:transparent;font:var(--fw-semibold) var(--fs-4) var(--mono);font-variant-numeric:tabular-nums;min-height:var(--ctl)}

/* ── panels: flat blueprint boxes with corner ticks ── */
.panel,.tile,.pgtile{--c:var(--corner);
  background:
    linear-gradient(var(--tick),var(--tick)) top left/var(--c) 1px no-repeat,linear-gradient(var(--tick),var(--tick)) top left/1px var(--c) no-repeat,
    linear-gradient(var(--tick),var(--tick)) top right/var(--c) 1px no-repeat,linear-gradient(var(--tick),var(--tick)) top right/1px var(--c) no-repeat,
    linear-gradient(var(--tick),var(--tick)) bottom left/var(--c) 1px no-repeat,linear-gradient(var(--tick),var(--tick)) bottom left/1px var(--c) no-repeat,
    linear-gradient(var(--tick),var(--tick)) bottom right/var(--c) 1px no-repeat,linear-gradient(var(--tick),var(--tick)) bottom right/1px var(--c) no-repeat,
    color-mix(in srgb,var(--surface) 90%,transparent);
  border:var(--bw) solid var(--line);border-radius:var(--r);min-width:0}
.panel > header{display:flex;align-items:baseline;flex-wrap:wrap;gap:var(--s2) var(--s3);padding:var(--s4) var(--s4) 0}
.panel > header .label{margin-left:auto}
.panel > .body{padding:var(--s3) var(--s4) var(--s4)}
.panel.pad{padding:var(--s5)}
/* an entry in a list: a flat bordered group (staff members). Not .card: the click test treats .card as a control. */
.entry{border:var(--bw) solid var(--line);border-radius:var(--r-2);background:var(--surface);padding:var(--s4)}
.entry[data-active="false"]{opacity:var(--dim-2);border-style:dashed}

/* ── KPI tiles ──
   <div class="tile"><span class="k">Clients actifs</span><span class="v">12</span><span class="why">…</span></div>
   The number is the hero: no icon and no dot in a tile, a plain label that says what the number is.
   One number per screen carries data-primary on its .v and is the large one; every other number is --fs-stat.
   Red only on a number that needs attention (.tile.crit). No number yet → <span class="v"><i class="nd">no data</i></span>. Never a fake 0. */
.tiles{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:var(--s3)}
@media (max-width:1000px){.tiles{grid-template-columns:repeat(2,minmax(0,1fr))}}
.tile{padding:var(--s4);display:flex;flex-direction:column;gap:var(--s2);position:relative;overflow:hidden}
.tile .k{display:flex;align-items:center;gap:var(--s2);font-family:var(--mono);font-size:var(--fs-1);letter-spacing:var(--ls-1);text-transform:uppercase;color:var(--ink-2)}
.tile .v{font-family:var(--mono);font-size:var(--fs-stat);font-weight:var(--fw-medium);letter-spacing:var(--ls-tight);line-height:var(--lh-tight);font-variant-numeric:tabular-nums;min-height:var(--s6);display:flex;align-items:flex-end;overflow-wrap:anywhere}
.tile .v .nd{font-size:var(--fs-3);padding-bottom:var(--s1)}
.tile .why{font-size:var(--fs-2);color:var(--ink-3);overflow-wrap:anywhere;margin-top:auto}
.tile.big{grid-column:span 2}
.tile .v[data-primary]{font-size:var(--fs-big);font-weight:var(--fw-semibold);min-height:var(--h-1)}
.tile.crit .v{color:var(--crit)}

/* ── tables ── */
.tablewrap{overflow-x:auto;-webkit-overflow-scrolling:touch}
.table{border-collapse:collapse;width:100%;font-size:var(--fs-3)}
.table th{font:var(--fw-semibold) var(--fs-1) var(--mono);letter-spacing:var(--ls-2);text-transform:uppercase;color:var(--ink-3);text-align:left;padding:var(--s2) var(--s3);border-bottom:var(--bw) solid var(--line-2);white-space:nowrap}
.table td{padding:var(--s3);border-bottom:var(--bw) dashed var(--line);vertical-align:middle}
.table tr:last-child td{border-bottom:0}
.table .r{text-align:right;font-family:var(--mono);font-variant-numeric:tabular-nums}
.table th.r{font-family:var(--mono)}

/* pills, key/value, lists, empty */
.pill{display:inline-flex;align-items:center;gap:var(--s2);font:var(--fw-semibold) var(--fs-1) var(--mono);letter-spacing:var(--ls-1);text-transform:uppercase;padding:var(--s0) var(--s2);border-radius:var(--r);border:var(--bw) solid currentColor;white-space:nowrap}
.pill.good{background:var(--solid-soft);color:var(--ink-2)} .pill.warn{background:var(--warn-soft);color:var(--warn)}
.pill.crit{background:var(--crit-soft);color:var(--crit)} .pill.signal{background:var(--accent-soft);color:var(--accent)}
.pill.off{color:var(--ink-3)} .pill.acc{background:var(--solid-soft);color:var(--ink-2)}
.kv{display:flex;flex-direction:column}
.kv > div{display:flex;justify-content:space-between;gap:var(--s3);padding:var(--s2) 0;border-bottom:var(--bw) dashed var(--line);font-size:var(--fs-3)}
.kv > div:last-child{border-bottom:0}
.kv dt,.kv .k{color:var(--ink-2)}
.kv dd,.kv b{margin:0;font-family:var(--mono);font-weight:var(--fw-semibold);font-variant-numeric:tabular-nums;text-align:right;overflow-wrap:anywhere}
/* two-column definition list (client page, Google page) */
.dl{display:grid;grid-template-columns:minmax(0,max-content) minmax(0,1fr);gap:var(--s2) var(--s4);margin:0;font-size:var(--fs-3)}
.dl dt{font:var(--fw-medium) var(--fs-1) var(--mono);letter-spacing:var(--ls-1);text-transform:uppercase;color:var(--ink-3);padding-top:var(--s1)}
.dl dd{margin:0;overflow-wrap:anywhere}
/* empty: nothing here yet (dot + sentence). .empty.box = the same, centred in a dashed box */
.empty{display:flex;align-items:center;gap:var(--s3);color:var(--ink-3);font-size:var(--fs-3);padding:var(--s3) 0}
.empty.box{padding:var(--s5);border:var(--bw) dashed var(--line-2);border-radius:var(--r-2);justify-content:center;text-align:center}
.links{display:grid;gap:var(--s2)}
.linkcard{display:flex;align-items:center;gap:var(--s3);min-height:var(--ctl);padding:var(--s3) var(--s4);border:var(--bw) solid var(--line);border-radius:var(--r-2);background:var(--surface-2);text-decoration:none;color:var(--ink);cursor:pointer;width:100%;text-align:left;transition:border-color var(--dur-1),background var(--dur-1)}
.linkcard:hover{border-color:var(--line-2);background:var(--surface-3);color:var(--ink)}
.linkcard .arr{margin-left:auto;font-family:var(--mono);color:var(--ink-3)}
/* loading: a shimmering placeholder. Size it with .h-1 / .h-2 / .h-3 (48 / 80 / 128 px) or .line (one line of text) */
.skel{background:linear-gradient(90deg,var(--surface-2),var(--surface-3),var(--surface-2));background-size:200% 100%;animation:shimmer 1.4s linear infinite;border-radius:var(--r);min-height:var(--s4)}
.skel.h-1{height:var(--h-1)} .skel.h-2{height:var(--h-2)} .skel.h-3{height:var(--h-3)}
.skel.line{width:60%;height:var(--s5)}

/* ── shell ── */
.shell{display:flex;flex-direction:column;min-height:100vh;min-height:100dvh}
/* the header: one per screen. Brand, "Home / Page", then who, theme, language, sign out. No rail, no tabs. */
.pghead{display:flex;flex-wrap:wrap;align-items:center;gap:var(--s1) var(--s5);padding:var(--s2) max(var(--s6),calc((100% - var(--w-lg)) / 2));background:var(--rail);border-bottom:var(--bw) solid var(--line)}
.pghead .brand{min-height:var(--ctl);padding-inline:0}
.crumb{display:flex;align-items:center;gap:var(--s2);min-width:0;font:var(--fw-medium) var(--fs-2) var(--mono);letter-spacing:var(--ls-1);text-transform:uppercase}
.crumb-link{display:inline-flex;align-items:center;justify-content:center;min-height:var(--ctl);min-width:var(--ctl);padding-inline:var(--s1);color:var(--ink-2);text-decoration:none;transition:color var(--dur-1)}
.crumb-link:hover{color:var(--ink)}
.crumb-sep{color:var(--ink-3)}
.crumb-now{color:var(--ink)}
.brand{display:flex;gap:var(--s3);align-items:center;padding-inline:var(--s1);text-decoration:none;color:var(--ink)}
.brand b{font:var(--fw-bold) var(--fs-2) var(--mono);letter-spacing:var(--ls-3);text-transform:uppercase;display:block;line-height:var(--lh-snug)}
.brand small{font:var(--fw-medium) var(--fs-1) var(--mono);letter-spacing:var(--ls-2);text-transform:uppercase;color:var(--ink-3)}
.mark{width:var(--mark);height:var(--mark);flex:none;position:relative;display:grid;place-items:center}
.mark svg{width:var(--mark);height:var(--mark);overflow:visible}
.mark .ring{transform-origin:15px 15px;animation:spin 24s linear infinite}
.pghead .who{margin-left:auto;display:flex;flex-wrap:wrap;align-items:center;justify-content:flex-end;gap:var(--s1) var(--s4)}
.who .id{display:flex;align-items:center;gap:var(--s3);min-width:0}
.who .name{font-weight:var(--fw-semibold);font-size:var(--fs-3);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:var(--w-field)}
.who .email{display:none;font:var(--fw-regular) var(--fs-1) var(--mono);color:var(--ink-3);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:var(--w-field)}
.who .ctl{display:flex;flex-wrap:wrap;align-items:center;gap:var(--s2)}
main.stage{min-width:0;padding:var(--s6) var(--s6) var(--s8);position:relative;flex:1}

/* the homepage (tiles) and a page landing (links): one measure, the same as a view */
.pghome,.pgland{display:flex;flex-direction:column;gap:var(--s6);max-width:var(--w-lg);width:100%;margin-inline:auto;position:relative;isolation:isolate;animation:enter var(--dur-3) var(--ease) both}
.pgtiles{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,var(--w-field)),1fr));gap:var(--s4)}
.pgtile,.pgtile:hover{color:var(--ink);text-decoration:none}
.pgtile{--c:var(--corner);padding:var(--s5);display:flex;flex-direction:column;justify-content:flex-end;gap:var(--s2);min-height:var(--h-3);position:relative;overflow:hidden;cursor:pointer;
  transition:border-color var(--dur-1),background-color var(--dur-1),transform var(--dur-2) var(--ease)}
.pgtile:hover{border-color:var(--line-2);background-color:var(--surface-2);transform:translateY(calc(-1 * var(--s0)))}
.pgtile-name{font:var(--fw-semibold) var(--fs-6)/var(--lh-tight) var(--sans);letter-spacing:var(--ls-tight)}
.pgtile-sub{color:var(--ink-2);font-size:var(--fs-3);max-width:34ch;padding-right:var(--s6)}
.pgtile .arr{position:absolute;right:var(--s5);bottom:var(--s5);font:var(--fw-medium) var(--fs-5) var(--mono);color:var(--ink-3);transition:transform var(--dur-2) var(--ease),color var(--dur-1)}
.pgtile:hover .arr{color:var(--accent);transform:translateX(var(--s1))}
.pagelist{display:grid;grid-template-columns:repeat(auto-fill,minmax(min(100%,var(--w-col)),1fr));gap:var(--s3)}
.pagelist .linkcard{min-height:var(--h-1);padding:var(--s4)}
.lc-text{display:flex;flex-direction:column;gap:var(--s0);min-width:0}
.lc-text small{color:var(--ink-3);font-size:var(--fs-2)}
.view{display:flex;flex-direction:column;gap:var(--s5);max-width:var(--w-lg);margin-inline:auto;animation:enter var(--dur-3) var(--ease) both}
.vhead{display:flex;flex-wrap:wrap;align-items:flex-end;gap:var(--s3) var(--s4)}
.vhead .right{margin-left:auto;display:flex;gap:var(--s2);align-items:center}

@media (min-width:1000px){
  .who .email{display:block}
}
@media (max-width:860px){
  .pghead{padding:var(--s2) var(--s4);gap:var(--s1) var(--s4)}
  main.stage{padding:var(--s5) var(--s4) var(--s7)}
}
@media (max-width:640px){
  .pghead .who{margin-left:0;width:100%;display:grid;grid-template-columns:minmax(0,1fr) auto;grid-template-areas:"id out" "ctl ctl";align-items:center;gap:var(--s1) var(--s3)}
  .who .id{grid-area:id}
  .who .ctl{grid-area:ctl}
  .who .signout{grid-area:out}
  .pghead .brand small{display:none}
  .pgtile{padding:var(--s4);min-height:var(--h-3)}
  .pgtile .arr{right:var(--s4);bottom:var(--s4)}
}

/* ── login: the orbit ── */
.gate{min-height:100vh;min-height:100dvh;display:grid;grid-template-columns:minmax(0,1.1fr) minmax(var(--w-gate-side),.9fr);position:relative;overflow:hidden}
.gate .art{position:relative;display:grid;place-items:center;border-right:var(--bw) solid var(--line);overflow:hidden}
.gate .art svg{width:min(78%,620px);height:auto;overflow:visible}
.gate .art .caption{position:absolute;left:var(--s6);bottom:var(--s5);right:var(--s6);display:flex;justify-content:space-between;gap:var(--s3);flex-wrap:wrap}
.gate .art .topline{position:absolute;left:var(--s6);top:var(--s5);right:var(--s6);display:flex;justify-content:space-between;gap:var(--s3)}
.orbit .rings circle{fill:none;stroke:var(--line-2);vector-effect:non-scaling-stroke}
.orbit circle,.orbit line{vector-effect:non-scaling-stroke}
.orbit .rings .dash{stroke:var(--tick);stroke-dasharray:2 6}
.orbit .ticks line{stroke:var(--tick)}
.orbit .spin-a{transform-origin:300px 300px;animation:spin 90s linear infinite}
.orbit .spin-b{transform-origin:300px 300px;animation:spin 140s linear infinite reverse}
.orbit .spin-a,.orbit .spin-b{--c:var(--tick)} .orbit .node.signal{--c:var(--accent)}
.orbit .node{fill:var(--c,var(--idle))}
.orbit .core{fill:var(--surface);stroke:var(--line-2)}
.orbit text{font-family:var(--mono);font-size:10px;letter-spacing:var(--ls-2);fill:var(--ink-3);text-transform:uppercase}
.orbit .coretext{font-size:15px;font-weight:var(--fw-bold);letter-spacing:var(--ls-4);fill:var(--ink)}
.gate .side{display:flex;flex-direction:column;justify-content:center;padding:var(--s7) clamp(var(--s5),5vw,72px);gap:var(--s5);background:color-mix(in srgb,var(--rail) 82%,transparent);position:relative}
.gate .side .top{position:absolute;top:var(--s5);left:clamp(var(--s5),5vw,72px);right:clamp(var(--s5),5vw,72px);display:flex;justify-content:space-between;align-items:center;gap:var(--s3)}
.gate form{max-width:var(--w-form);width:100%}
.gate .foot{font:var(--fw-regular) var(--fs-1) var(--mono);color:var(--ink-3);letter-spacing:var(--ls-1);display:flex;align-items:flex-start;gap:var(--s2)}
.gate .foot .dot{margin-top:var(--s1)}
@media (max-width:860px){
  .gate{grid-template-columns:minmax(0,1fr);grid-template-rows:auto 1fr}
  .gate .art{border-right:0;border-bottom:var(--bw) solid var(--line);height:230px}
  .gate .art svg{width:auto;height:300px}
  .gate .art .caption{display:none}
  .gate .side{padding:var(--s5) var(--s4) var(--s7);justify-content:flex-start}
  .gate .side .top{position:static;order:-1}
}
@media (max-width:480px){.gate .side .top .brand small{display:none}.gate .side .top .brand{display:none}.gate .side .top{justify-content:flex-end}}

.grid2{display:grid;grid-template-columns:minmax(0,1.4fr) minmax(0,1fr);gap:var(--s3)}
@media (max-width:1000px){.grid2{grid-template-columns:minmax(0,1fr)}}
/* two columns that fold to one when they would get narrower than 420 px */
.cols{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,var(--w-col)),1fr));gap:var(--s4);align-items:start}

.boot{min-height:100vh;display:grid;place-items:center;gap:var(--s3);align-content:center;color:var(--ink-3);font:var(--fw-medium) var(--fs-1) var(--mono);letter-spacing:var(--ls-2);text-transform:uppercase}
.boot.plain{text-transform:none;letter-spacing:0;font:inherit;padding:var(--s5)}

/* ── motion ── */
@keyframes spin{to{transform:rotate(360deg)}}
@keyframes pulse{0%,100%{opacity:1}50%{opacity:.45}}
@keyframes shimmer{to{background-position:-200% 0}}
@keyframes enter{from{opacity:0;transform:translateY(var(--lift))}to{opacity:1;transform:none}}
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation:none!important;transition:none!important;scroll-behavior:auto!important}
}

/* environment label (shell): which database this page talks to */
.pill.env{cursor:default}

/* ── things that open: tiles, rows and marks with more behind them ── */
.tile[data-open],tr[data-open],.card[data-open]{cursor:pointer;transition:border-color var(--dur-1),background-color var(--dur-1)}
.tile[data-open]:hover{border-color:var(--line-2);background-color:var(--surface-2)}
.tile[data-open] .k{padding-right:var(--s5)}
.tile[data-open]::after{content:"→";position:absolute;right:var(--s3);top:var(--s3);font:var(--fw-medium) var(--fs-2) var(--mono);color:var(--ink-3)}
.tile[data-open]:hover::after{color:var(--ink)}
tr[data-open]:hover td{background:var(--solid-soft)}
tr[data-open] td:last-child{white-space:nowrap}
[data-open]:focus-visible{outline:var(--focus);outline-offset:var(--focus-offset)}

/* ── the detail panel: one dialog, a sheet from the right (from the bottom on a phone) ── */
dialog.sheet{margin:0 0 0 auto;padding:0;border:0;border-left:var(--bw) solid var(--line-2);width:min(var(--w-sheet),100vw);max-width:100vw;height:100vh;height:100dvh;max-height:100dvh;
  background:var(--surface);color:var(--ink);box-shadow:calc(-1 * var(--s5)) var(--shadow-sheet)}
dialog.sheet::backdrop{background:var(--overlay)}
dialog.sheet[open]{display:flex;flex-direction:column;animation:enter var(--dur-2) var(--ease) both}
.sheet > header{display:flex;align-items:flex-start;justify-content:space-between;gap:var(--s3);padding:var(--s4) var(--s4) var(--s3);border-bottom:var(--bw) dashed var(--line)}
.sheet-head{display:flex;flex-direction:column;gap:var(--s2);min-width:0}
.sheet-title{overflow-wrap:anywhere}
.sheet-title::before{content:""}
.sheet-body{padding:var(--s4) var(--s4) var(--s5);display:flex;flex-direction:column;gap:var(--s4);overflow-y:auto;flex:1}
.sheet-value{font:var(--fw-semibold) var(--fs-6) var(--mono);letter-spacing:var(--ls-tight);line-height:var(--lh-tight);margin:0;overflow-wrap:anywhere}
.sheet-sec{display:flex;flex-direction:column;gap:var(--s2)}
.sheet-sec p{color:var(--ink-2);font-size:var(--fs-3);max-width:62ch}
.sheet-list{list-style:none;margin:0;padding:0;display:grid;gap:var(--s2)}
.sheet-li{display:flex;flex-direction:column;gap:var(--s0);min-width:0}
.sheet-li small{color:var(--ink-3);font-size:var(--fs-2)}
.sheet-actions{display:flex;gap:var(--s2);flex-wrap:wrap}
@media (max-width:640px){
  dialog.sheet{margin:auto 0 0;width:100vw;height:auto;max-height:88dvh;border-left:0;border-top:var(--bw) solid var(--line-2);box-shadow:0 calc(-1 * var(--s5)) var(--shadow-sheet)}
}

/* ── phone and touch: 44 px targets everywhere (WCAG 2.5.8 asks 24; Apple and Google ask 44) ──
   Desktop with a mouse keeps the small button and segment at 32 px; on a phone, or on any
   coarse pointer (a tablet in landscape), they all reach --ctl. */
@media (max-width:860px),(pointer:coarse){
  .btn.sm,.seg button,.counter button{min-height:var(--ctl)}
  .btn.sm,.seg button{min-width:var(--ctl)}
  .peek{min-height:var(--ctl)}
  summary{min-height:var(--ctl);display:flex;align-items:center;cursor:pointer}
  .linkcard{min-height:var(--h-1)}
  a.link,.kv a,.dl a{display:inline-flex;align-items:center;min-height:var(--ctl)}
}
tr[data-open] td{height:var(--ctl)}
summary{cursor:pointer}
details>summary:hover{color:var(--ink)}
