/* tokens.css: the only file where a raw value may appear (design/README.md).
   Light is the bare set. Dark redefines tokens only, three ways: the visitor's OS when
   no theme is chosen, an explicit data-theme on <html>, and the scoped classes public
   pages use to follow their builder's setting instead of the dashboard's cookie. */

:root,
.theme-light,
.theme-visitor {
  /* A near-white page, black type. Panels are told apart by a hairline and a faint resting
     shadow (--rest) in the app, and by a tone step on the site. The page is a hair off white,
     1.03:1 against a white panel and under the threshold of reading as a tint, so a white panel
     has somewhere to rise to. Dark keeps its own ground. */
  --ground: #fcfcfd;
  --surface: #ffffff;
  --sunk: #f3f4f6;
  --raised: #f8f9fb;
  --ink: #0b0c0e;
  --ink-2: #3f4550;
  --ink-3: #5d6470;
  --edge: #8a919d;
  --line: #e4e6eb;
  --line-strong: #d3d7de;
  --on-ink: #ffffff;
  /* Where you are in the rail: a neutral step past hover's --sunk, never the accent. Where you are
     is wayfinding, not a choice made in the content (design/README.md, principle 1). */
  --current: #eaecf0;

  /* Cobalt is the brand: every primary action, link, selection and focus ring. Never a state.
     Its tints keep its own hue (OKLCH about 268°), so a wash reads blue, not lavender. */
  --accent: #1f2de6;
  --accent-hover: #1823c4;
  --accent-text: #1f2de6;
  --on-accent: #ffffff;
  --accent-wash: #eaf0ff;

  /* Status colours mean one thing each and appear nowhere else. */
  --up: #12a150;
  --warn: #c27a00;
  --down: #cc1f1f;
  --paused: #8a919d;

  --wash-up: #e7f6ec;
  /* A healthy day on an uptime bar: a tint, so the days that weren't healthy are what you see. */
  --bar-up: #8fd4ab;
  --wash-warn: #fdf3e1;
  --wash-down: #fdecec;
  --wash-info: #eaf0ff;

  --chart-p50: #1f2de6;
  --chart-p95: #a3a9b4;
  --chart-grid: #eceef1;
  --chart-band: #fdecec;

  /* Whole-section fields on the site. */
  --field-dark: #0b0c0e;
  --field-dark-surface: #1a1c21;
  --field-dark-ink: #ffffff;
  --field-dark-ink-2: #b4bac4;
  --field-dark-line: #2c2f36;
  --field-accent: #1f2de6;
  --field-accent-ink: #ffffff;
  --field-accent-ink-2: #d5d8fc;
  --field-tone: #f3f4f6;

  --scrim: rgba(11, 12, 14, 0.5);
  --lift: 0 12px 40px rgba(11, 12, 14, 0.14);
  /* A panel at rest: one faint step of depth under its hairline, light only. Dark already
     separates a panel by tone, the surface on the ground. */
  --rest: 0 1px 2px rgba(11, 12, 14, 0.06);
  color-scheme: light;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]),
  .theme-visitor {
    --ground: #0b0c0e;
    --surface: #121418;
    --sunk: #1a1d22;
    --raised: #16191d;
    --ink: #f2f3f5;
    --ink-2: #c4c8d0;
    --ink-3: #9aa1ad;
    --edge: #6b7280;
    --line: #262a31;
    --line-strong: #353a43;
    --on-ink: #0b0c0e;
    --current: #20242b;

    --accent: #3d5cff;
    --accent-hover: #2f4ce0;
    --accent-text: #8fa6ff;
    --on-accent: #ffffff;
    --accent-wash: #15204a;

    --up: #34c46e;
    --warn: #f0a92e;
    --down: #f2665f;
    --paused: #7d8590;

    --wash-up: #0f2a1b;

    --bar-up: #1f6a42;
    --wash-warn: #2e2410;
    --wash-down: #3a1716;
    --wash-info: #15204a;

    --chart-p50: #8fa6ff;
    --chart-p95: #5d6470;
    --chart-grid: #1f2228;
    --chart-band: #3a1716;

    --field-dark: #000000;
    --field-dark-surface: #16181c;
    --field-dark-line: #2a2d33;
    --field-accent: #2733d9;
    --field-tone: #121418;

    --scrim: rgba(0, 0, 0, 0.6);
    --lift: 0 12px 40px rgba(0, 0, 0, 0.5);
    --rest: none;
    color-scheme: dark;
  }
}

:root[data-theme="dark"],
.theme-dark {
  --ground: #0b0c0e;
  --surface: #121418;
  --sunk: #1a1d22;
  --raised: #16191d;
  --ink: #f2f3f5;
  --ink-2: #c4c8d0;
  --ink-3: #9aa1ad;
  --edge: #6b7280;
  --line: #262a31;
  --line-strong: #353a43;
  --on-ink: #0b0c0e;
  --current: #20242b;

  --accent: #3d5cff;
  --accent-hover: #2f4ce0;
  --accent-text: #8fa6ff;
  --on-accent: #ffffff;
  --accent-wash: #15204a;

  --up: #34c46e;
  --warn: #f0a92e;
  --down: #f2665f;
  --paused: #7d8590;

  --wash-up: #0f2a1b;

  --bar-up: #1f6a42;
  --wash-warn: #2e2410;
  --wash-down: #3a1716;
  --wash-info: #15204a;

  --chart-p50: #8fa6ff;
  --chart-p95: #5d6470;
  --chart-grid: #1f2228;
  --chart-band: #3a1716;

  --field-dark: #000000;
  --field-dark-surface: #16181c;
  --field-dark-line: #2a2d33;
  --field-accent: #2733d9;
  --field-tone: #121418;

  --scrim: rgba(0, 0, 0, 0.6);
  --lift: 0 12px 40px rgba(0, 0, 0, 0.5);
  --rest: none;
  color-scheme: dark;
}

/* Public pages (status page, sample host app) wear the builder's neutrals and accent, not
   Staygreen's cobalt. Status colours stay: they mean the same thing everywhere.
   The accent tokens are the builder's colour, shaded per theme to read on these grounds
   (`src/lib/accents.ts`). The page sets the `--page-*` values on its own element; without them,
   as on a page with no builder, the controls wear the page's ink. */
.public-neutral {
  --ground: #ffffff;
  --surface: #ffffff;
  --sunk: #f4f4f5;
  --raised: #fafafa;
  --ink: #111113;
  --ink-2: #46464d;
  --ink-3: #5f5f68;
  --edge: #8b8b94;
  --line: #e6e6ea;
  --on-ink: #ffffff;

  --accent: var(--page-accent-light, var(--ink));
  --accent-hover: var(--page-accent-hover-light, var(--ink-2));
  --accent-text: var(--page-accent-text-light, var(--ink));
  --on-accent: var(--page-on-accent-light, var(--on-ink));
}

.public-neutral.theme-dark {
  --ground: #0f0f11;
  --surface: #17171a;
  --sunk: #1f1f23;
  --raised: #1b1b1f;
  --ink: #f1f1f3;
  --ink-2: #c3c3ca;
  --ink-3: #9b9ba5;
  --edge: #6c6c76;
  --line: #2a2a30;
  --on-ink: #0f0f11;

  --accent: var(--page-accent-dark, var(--ink));
  --accent-hover: var(--page-accent-hover-dark, var(--ink-2));
  --accent-text: var(--page-accent-text-dark, var(--ink));
  --on-accent: var(--page-on-accent-dark, var(--on-ink));
}

@media (prefers-color-scheme: dark) {
  .public-neutral.theme-visitor {
    --ground: #0f0f11;
    --surface: #17171a;
    --sunk: #1f1f23;
    --raised: #1b1b1f;
    --ink: #f1f1f3;
    --ink-2: #c3c3ca;
    --ink-3: #9b9ba5;
    --edge: #6c6c76;
    --line: #2a2a30;
    --on-ink: #0f0f11;

    --accent: var(--page-accent-dark, var(--ink));
    --accent-hover: var(--page-accent-hover-dark, var(--ink-2));
    --accent-text: var(--page-accent-text-dark, var(--ink));
    --on-accent: var(--page-on-accent-dark, var(--on-ink));
  }
}

:root {
  --f-sans: var(--font-switzer), "Switzer", system-ui, -apple-system, "Segoe UI", sans-serif;
  --f-mono: "JetBrains Mono Variable", "JetBrains Mono", ui-monospace, "Cascadia Mono", Consolas, monospace;

  /* App and site share the first four. The site adds two display sizes. */
  --t-1: 13px;
  --t-2: 15px;
  --t-3: 18px;
  --t-4: 28px;
  --t-h2: clamp(36px, 4.4vw, 64px);
  --t-5: clamp(52px, 7.6vw, 120px);

  --lh-tight: 0.95;
  --lh-h2: 1;
  --lh-head: 1.2;
  --lh-body: 1.5;

  --track-display: -0.045em;
  --track-h2: -0.035em;
  --track-title: -0.02em;

  --w-regular: 400;
  --w-medium: 500;
  --w-bold: 600;
  --w-black: 700;

  --s-1: 4px;
  --s-2: 8px;
  --s-3: 12px;
  --s-4: 16px;
  --s-5: 24px;
  --s-6: 32px;
  --s-7: 48px;
  --s-8: 72px;
  --s-9: 112px;
  --s-10: 168px;

  --r-1: 6px;
  --r-2: 10px;
  --r-3: 16px;
  --r-pill: 999px;
  /* A button's and a segmented control's corner inside the app (`.shell`); the site, status
     pages and tags keep pills (the owner, 2026-10-22). */
  --r-control: 8px;

  --hair: 1px;
  --rule: 2px;

  --target: 44px;
  --control: 40px;
  --control-sm: 32px;

  --w-read: 68ch;
  --w-site: 1280px;
  --w-app: 1200px;
  --w-rail: 240px;

  --d-1: 120ms;
  --d-2: 220ms;
  --d-3: 480ms;
  --ease: cubic-bezier(0.2, 0.7, 0.2, 1);

  --z-sticky: 10;
  --z-drawer: 40;
  --z-toast: 60;
}

/* AskOne's brand, worn by the sample host app at /demo/askone (status.css maps it onto the tokens). */
.host-askone {
  --askone-bg: #0b0b0d;
  --askone-sunk: #060607;
  --askone-surface: #151518;
  --askone-raised: #1c1c21;
  --askone-line: #29292f;
  --askone-edge: #5d5a56;
  --askone-text: #f3f1ec;
  --askone-text-2: #b5b1aa;
  --askone-text-3: #95918a;
  --askone-amber: #f5a524;
  --askone-on-amber: #1a1206;
}

/* kit.css: primitives built from tokens only. `npm run check:kit` refuses colour literals here.
   Resets sit inside :where() so any single kit class outranks them. */

/* ---------- reset ---------- */
:where(*, *::before, *::after) { box-sizing: border-box; }
:where(html) { -webkit-text-size-adjust: 100%; }
:where(body) {
  margin: 0;
  background: var(--ground);
  color: var(--ink);
  font-family: var(--f-sans);
  font-size: var(--t-2);
  line-height: var(--lh-body);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
:where(h1, h2, h3, h4, p, ul, ol, dl, dd, figure, blockquote) { margin: 0; }
:where(ul, ol) { padding: 0; list-style: none; }
:where(fieldset) { border: 0; padding: 0; margin: 0; min-width: 0; }
:where(legend) { padding: 0; }
:where(h1, h2, h3, h4) { font-weight: var(--w-bold); line-height: var(--lh-head); text-wrap: balance; letter-spacing: var(--track-title); }
:where(a) { color: inherit; text-decoration-thickness: var(--hair); text-underline-offset: 0.2em; }
:where(button, input, select, textarea) { font: inherit; color: inherit; }
:where(button) { cursor: pointer; }
:where(img, svg) { display: block; max-width: 100%; }
:where(code, kbd, pre, samp) { font-family: var(--f-mono); font-size: 0.92em; font-variant-ligatures: none; }
:where(table) { border-collapse: collapse; }
:where(:focus-visible) { outline: var(--rule) solid var(--accent); outline-offset: var(--rule); }
:where([hidden]) { display: none !important; }

@media (prefers-reduced-motion: reduce) {
  :where(*, *::before, *::after) { animation-duration: 1ms !important; animation-iteration-count: 1 !important; transition-duration: 1ms !important; scroll-behavior: auto !important; }
}

/* ---------- type ---------- */
.t-display { font-size: var(--t-5); line-height: var(--lh-tight); letter-spacing: var(--track-display); font-weight: var(--w-bold); text-wrap: balance; }
.t-title { font-size: var(--t-4); line-height: var(--lh-head); letter-spacing: var(--track-title); font-weight: var(--w-bold); }
.t-section { font-size: var(--t-3); line-height: var(--lh-head); font-weight: var(--w-bold); }
.t-lead { font-size: var(--t-3); line-height: var(--lh-body); color: var(--ink-2); max-width: var(--w-read); }
.t-body { font-size: var(--t-2); }
.t-meta { font-size: var(--t-1); color: var(--ink-3); }
.t-2 { color: var(--ink-2); }
.t-3 { color: var(--ink-3); }
.t-strong { font-weight: var(--w-bold); }
.t-down { color: var(--down); }
.prose { max-width: var(--w-read); }
.prose > * + * { margin-top: var(--s-3); }
/* A long document read top to bottom: the terms and the privacy policy. Sections open with more
   room than the paragraphs inside them, lists keep their bullets (the reset takes them), and an
   address, an email or a URL wraps rather than widening a phone's page. Links are underlined at
   rest: cobalt against body text is 2.4:1 in light and 2.1:1 in dark, under the 3:1 a link needs
   to be told from the words around it by colour alone. */
.prose-doc { overflow-wrap: anywhere; }
.prose-doc > h2 { margin-top: var(--s-6); font-size: var(--t-3); }
.prose-doc ul { padding-left: var(--s-5); list-style: disc; }
.prose-doc li + li { margin-top: var(--s-2); }
.prose-doc li::marker { color: var(--ink-3); }
.prose-doc a { color: var(--accent-text); text-decoration: underline; text-decoration-thickness: var(--hair); }
.prose-doc a:hover { text-decoration-thickness: var(--rule); }

/* Numbers and addresses are tokens, never prose. */
.num { white-space: nowrap; flex: none; font-variant-numeric: tabular-nums; text-transform: none; }
.code { font-family: var(--f-mono); font-size: 0.86em; background: var(--sunk); border-radius: 4px; padding: 0.12em 0.4em; white-space: nowrap; text-transform: none; }
.addr { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; text-transform: none; }
.wrap-anywhere { overflow-wrap: anywhere; white-space: normal; }

pre.snippet {
  margin: 0;
  background: var(--sunk);
  border-radius: var(--r-2);
  padding: var(--s-3) var(--s-4);
  font-size: var(--t-1);
  line-height: 1.6;
  overflow-x: auto;
  white-space: pre;
}
pre.snippet.wrap { white-space: pre-wrap; overflow-wrap: anywhere; }

/* ---------- layout ---------- */
.stack { display: flex; flex-direction: column; gap: var(--s-4); }
.stack-sm { display: flex; flex-direction: column; gap: var(--s-2); }
.stack-lg { display: flex; flex-direction: column; gap: var(--s-6); }
.row { display: flex; align-items: center; gap: var(--s-3); min-width: 0; }
.row-top { display: flex; align-items: flex-start; gap: var(--s-3); min-width: 0; }
.cluster { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-2); }
.spread { display: flex; align-items: center; justify-content: space-between; gap: var(--s-3); flex-wrap: wrap; min-width: 0; }
.grow { flex: 1 1 auto; min-width: 0; }
.grid-2 { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr)); gap: var(--s-4); }
.grid-3 { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 240px), 1fr)); gap: var(--s-4); }
.grid-4 { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 170px), 1fr)); gap: var(--s-3); }
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
/* position: relative keeps an .sr-only table head inside the clip, so it can't widen the page. */
.scroll-x { overflow-x: auto; min-width: 0; position: relative; }

/* ---------- surfaces ---------- */
.panel { background: var(--surface); border: var(--hair) solid var(--line); border-radius: var(--r-2); padding: var(--s-5); min-width: 0; box-shadow: var(--rest); }
.panel-tight { padding: var(--s-4); }
.panel-flush { padding: 0; overflow: hidden; }
.well { background: var(--sunk); border-radius: var(--r-2); padding: var(--s-4); min-width: 0; }
.panel-head { display: flex; align-items: center; justify-content: space-between; gap: var(--s-3); flex-wrap: wrap; margin-bottom: var(--s-4); }
.divider { height: var(--hair); background: var(--line); border: 0; margin: 0; }
/* A card of settings, one per section (`.panel.panel-flush`): a row per setting, what it is and
   what it does on the left, its control on the right, rows split by hairlines. A row with nothing
   to set yet is its words alone. On a phone the control drops under its words. */
.set-row { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: var(--s-3) var(--s-6); padding: var(--s-4) var(--s-5); min-width: 0; }
.set-row + .set-row { border-top: var(--hair) solid var(--line); }
.set-row-text { display: flex; flex-direction: column; gap: var(--s-1); min-width: 0; }
.set-row-control { display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: var(--s-2); min-width: 0; }
.set-row-wide { grid-column: 1 / -1; }
@media (max-width: 640px) {
  .set-row { grid-template-columns: minmax(0, 1fr); padding: var(--s-4); }
  .set-row-control { justify-content: flex-start; }
}

/* ---------- buttons ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s-2);
  min-height: var(--control); padding: 0 var(--s-4);
  border-radius: var(--btn-r, var(--r-pill)); border: var(--hair) solid var(--line-strong);
  background: var(--surface); color: var(--ink);
  font-size: var(--t-2); font-weight: var(--w-medium); line-height: 1.2;
  text-decoration: none; white-space: nowrap; cursor: pointer;
  transition: background var(--d-1) var(--ease), border-color var(--d-1) var(--ease), transform var(--d-1) var(--ease);
}
.btn:hover { background: var(--sunk); border-color: var(--edge); }
.btn:active { transform: translateY(1px); }
.btn:disabled, .btn[aria-disabled="true"] { opacity: 0.5; cursor: not-allowed; transform: none; }
.btn svg { width: 18px; height: 18px; flex: none; }
.btn-primary { background: var(--accent); color: var(--on-accent); border-color: var(--accent); }
.btn-primary:hover { background: var(--accent-hover); border-color: var(--accent-hover); }
.btn-ink { background: var(--ink); color: var(--on-ink); border-color: var(--ink); }
.btn-ink:hover { background: var(--ink-2); border-color: var(--ink-2); }
.btn-quiet { background: transparent; border-color: transparent; }
.btn-quiet:hover { background: var(--sunk); border-color: transparent; }
.btn-danger { color: var(--down); border-color: var(--down); background: var(--surface); }
.btn-danger:hover { background: var(--wash-down); }
.btn-sm { min-height: var(--control-sm); padding: 0 var(--s-3); font-size: var(--t-1); }
.btn-lg { min-height: 52px; padding: 0 var(--s-5); font-size: var(--t-3); }
.btn-block { width: 100%; }
.btn-icon { width: var(--control); padding: 0; }
.btn-icon.btn-sm { width: var(--control-sm); }
.link { color: var(--accent-text); text-decoration: underline; text-decoration-color: transparent; background: none; border: 0; padding: 0; font: inherit; cursor: pointer; }
.link:hover { text-decoration-color: currentColor; }
@media (pointer: coarse) {
  .btn, .btn-sm { min-height: var(--target); }
  .btn-icon, .btn-icon.btn-sm { width: var(--target); }
}

/* ---------- forms ---------- */
.field { display: flex; flex-direction: column; gap: var(--s-1); min-width: 0; }
.label { font-size: var(--t-1); font-weight: var(--w-bold); color: var(--ink); display: flex; align-items: center; gap: var(--s-2); flex-wrap: wrap; }
.hint { font-size: var(--t-1); color: var(--ink-3); }
.error { font-size: var(--t-1); color: var(--down); font-weight: var(--w-medium); }
.input, .select, .textarea {
  width: 100%; min-height: var(--control);
  background: var(--surface); color: var(--ink);
  border: var(--hair) solid var(--edge); border-radius: var(--r-1);
  padding: var(--s-2) var(--s-3); font-size: var(--t-2);
}
.input.mono, .textarea.mono { font-family: var(--f-mono); font-size: var(--t-1); }
.textarea { min-height: 112px; resize: vertical; line-height: var(--lh-body); }
.input[aria-invalid="true"] { border-color: var(--down); }
.input:disabled, .select:disabled, .textarea:disabled { background: var(--sunk); color: var(--ink-3); opacity: 0.6; cursor: not-allowed; }
.input-group { display: flex; min-width: 0; }
.input-group > .input { border-radius: var(--r-1) 0 0 var(--r-1); }
.input-group > .btn { border-radius: 0 var(--r-1) var(--r-1) 0; border-left: 0; }
@media (pointer: coarse) { .input, .select { min-height: var(--target); } }

.check { display: inline-flex; align-items: center; gap: var(--s-2); font-size: var(--t-2); cursor: pointer; min-height: var(--control-sm); }
.check input { width: 18px; height: 18px; accent-color: var(--accent); margin: 0; }

/* Switch: a checkbox with role="switch". */
.switch { display: inline-flex; align-items: center; gap: var(--s-3); cursor: pointer; min-height: var(--control-sm); }
.switch input { appearance: none; margin: 0; flex: none; width: 40px; height: 24px; border-radius: var(--r-pill); background: var(--sunk); border: var(--hair) solid var(--edge); position: relative; cursor: pointer; transition: background var(--d-1) var(--ease); }
.switch input::after { content: ""; position: absolute; top: 3px; left: 3px; width: 16px; height: 16px; border-radius: var(--r-pill); background: var(--ink-3); transition: transform var(--d-2) var(--ease), background var(--d-1) var(--ease); }
.switch input:checked { background: var(--accent); border-color: var(--accent); }
.switch input:checked::after { transform: translateX(16px); background: var(--on-accent); }
.switch input:disabled { opacity: 0.5; cursor: not-allowed; }

/* Inside the app, buttons and segmented controls take the control corner; elsewhere they stay pills. */
.shell { --btn-r: var(--r-control); }

/* Segmented control: radios in a row. */
.seg { display: inline-flex; background: var(--sunk); border-radius: var(--btn-r, var(--r-pill)); padding: 3px; gap: 2px; flex-wrap: wrap; }
.seg label { position: relative; display: inline-flex; }
.seg input { position: absolute; opacity: 0; inset: 0; margin: 0; cursor: pointer; }
.seg span { display: inline-flex; align-items: center; gap: var(--s-1); min-height: var(--control-sm); padding: 0 var(--s-3); border-radius: calc(var(--btn-r, var(--r-pill)) - 3px); font-size: var(--t-1); font-weight: var(--w-medium); color: var(--ink-2); white-space: nowrap; }
.seg input:checked + span { background: var(--surface); color: var(--ink); box-shadow: 0 1px 2px var(--scrim); }
.seg input:focus-visible + span { outline: var(--rule) solid var(--accent); outline-offset: 1px; }
.seg input:disabled + span { opacity: 0.5; }

/* ---------- tables ---------- */
.table { width: 100%; font-size: var(--t-2); font-variant-numeric: tabular-nums; }
.table th { text-align: left; font-size: var(--t-1); font-weight: var(--w-medium); color: var(--ink-3); padding: var(--s-2) var(--s-3); background: var(--raised); border-bottom: var(--hair) solid var(--line); white-space: nowrap; }
.table td { padding: var(--s-3); border-top: var(--hair) solid var(--line); vertical-align: middle; }
.table tr:first-child td { border-top: 0; }
.table td.r, .table th.r { text-align: right; }
.table tbody tr.clickable { cursor: pointer; }
.table tbody tr.clickable:hover td { background: var(--raised); }
.table a.row-link { text-decoration: none; font-weight: var(--w-bold); color: var(--ink); }
.table a.row-link:hover { text-decoration: underline; }

/* ---------- labels and states ---------- */
.tag { display: inline-flex; align-items: center; gap: 5px; min-height: 22px; padding: 0 var(--s-2); border-radius: var(--r-pill); font-size: var(--t-1); font-weight: var(--w-medium); background: var(--sunk); color: var(--ink-2); white-space: nowrap; line-height: 1; }
.tag svg { width: 12px; height: 12px; flex: none; }
/* The Builder mark (`design/README.md`, principle 8): cobalt, because pressing it opens what
   Builder adds; never amber, which means degraded. On a gated control the crown takes the
   control's own ink, so a primary button keeps its white label. */
.builder-mark { width: 14px; height: 14px; flex: none; color: var(--accent-text); }
.btn .builder-mark { width: 16px; height: 16px; }
.btn-primary .builder-mark, .btn-ink .builder-mark { color: currentColor; }
.tag-builder, .tag-builder-static { background: var(--accent-wash); color: var(--accent-text); }
button.tag-builder { border: 0; font-family: inherit; cursor: pointer; }
button.tag-builder:hover { text-decoration: underline; }
.tag-accent { background: var(--accent-wash); color: var(--accent-text); }
.tag-soon { background: transparent; border: var(--hair) dashed var(--edge); color: var(--ink-2); }
.tag-info { background: var(--wash-info); color: var(--accent-text); }

.state { display: inline-flex; align-items: center; gap: 6px; font-weight: var(--w-medium); white-space: nowrap; }
.state.degraded, .state.down { padding: 2px 10px 2px 8px; border-radius: var(--r-pill); }
.state.degraded { background: var(--wash-warn); }
.state.down { background: var(--wash-down); }
.state.paused, .state.unchecked { color: var(--ink-3); }
.state-icon { flex: none; }
.state-icon.up { color: var(--up); }
.state-icon.degraded { color: var(--warn); }
.state-icon.down { color: var(--down); }
.state-icon.paused { color: var(--paused); }
.state-icon.unchecked { color: var(--edge); }

/* ---------- callouts ---------- */
.callout { display: flex; gap: var(--s-3); align-items: flex-start; padding: var(--s-3) var(--s-4); border-radius: var(--r-2); background: var(--sunk); font-size: var(--t-2); min-width: 0; }
.callout > svg { flex: none; margin-top: 2px; width: 18px; height: 18px; }
.callout-down { background: var(--wash-down); }
.callout-down > svg { color: var(--down); }
.callout-warn { background: var(--wash-warn); }
.callout-warn > svg { color: var(--warn); }
.callout-up { background: var(--wash-up); }
.callout-up > svg { color: var(--up); }
/* Information is neither an action nor a state, so it is neutral: the base callout's grey, and an
   icon in secondary ink. The screen's one cobalt thing stays its primary button. */
.callout-info { background: var(--sunk); }
.callout-info > svg { color: var(--ink-2); }

/* ---------- stat tiles ---------- */
.stat { display: flex; flex-direction: column; gap: var(--s-1); min-width: 0; }
.stat-label { font-size: var(--t-1); color: var(--ink-2); }
.stat-value { font-size: var(--t-4); font-weight: var(--w-bold); letter-spacing: var(--track-title); line-height: 1.1; white-space: nowrap; font-variant-numeric: tabular-nums; }
.stat-value small { font-size: var(--t-2); font-weight: var(--w-medium); color: var(--ink-2); letter-spacing: 0; }
/* A phrase in a number's place (a schedule, "Cloudflare and Google") wraps between its words in a
   narrow cell; the number beside a unit never parts from it. An address keeps `.addr`. */
.stat-value small:not(.addr) { white-space: normal; }
.stat-delta { font-size: var(--t-1); color: var(--ink-3); }

/* ---------- meter ---------- */
.meter { height: 6px; border-radius: var(--r-pill); background: var(--sunk); overflow: hidden; }
.meter > span { display: block; height: 100%; background: var(--accent); border-radius: var(--r-pill); }
.meter.full > span { background: var(--warn); }

/* ---------- tabs ---------- */
.tabs { display: flex; gap: var(--s-1); border-bottom: var(--hair) solid var(--line); overflow-x: auto; }
.tabs a, .tabs button { display: inline-flex; align-items: center; gap: var(--s-2); min-height: var(--control); padding: 0 var(--s-3); border: 0; background: none; font-weight: var(--w-medium); color: var(--ink-2); text-decoration: none; white-space: nowrap; border-bottom: var(--rule) solid transparent; margin-bottom: -1px; }
.tabs [aria-selected="true"], .tabs [aria-current="page"] { color: var(--ink); border-bottom-color: var(--accent); }

/* ---------- dialog and popover ---------- */
dialog.dialog { border: 0; border-radius: var(--r-2); background: var(--surface); color: var(--ink); padding: 0; width: min(560px, calc(100vw - 32px)); max-height: calc(100dvh - 48px); }
dialog.dialog::backdrop { background: var(--scrim); }
.dialog-body { padding: var(--s-5); display: flex; flex-direction: column; gap: var(--s-4); }
.dialog-foot { display: flex; justify-content: flex-end; gap: var(--s-2); padding: var(--s-4) var(--s-5); background: var(--sunk); flex-wrap: wrap; }
[popover].pop { border: var(--hair) solid var(--line); border-radius: var(--r-2); background: var(--surface); color: var(--ink); padding: var(--s-4); box-shadow: var(--lift); max-width: min(360px, calc(100vw - 32px)); }
[popover].builder-offer { position: fixed; inset: auto; margin: 0; display: none; flex-direction: column; align-items: flex-start; gap: var(--s-3); text-align: left; white-space: normal; font-size: var(--t-2); font-weight: var(--w-regular); letter-spacing: normal; text-transform: none; line-height: 1.45; }
[popover].builder-offer:popover-open { display: flex; }
.builder-offer-title { font-size: var(--t-3); font-weight: var(--w-bold); }

/* ---------- toasts ---------- */
.toasts { position: fixed; z-index: var(--z-toast); right: max(16px, env(safe-area-inset-right, 0px)); bottom: calc(76px + env(safe-area-inset-bottom, 0px)); display: flex; flex-direction: column; gap: var(--s-2); width: min(380px, calc(100vw - 32px)); pointer-events: none; }
.toast { pointer-events: auto; display: flex; gap: var(--s-3); align-items: flex-start; background: var(--ink); color: var(--on-ink); border-radius: var(--r-2); padding: var(--s-3) var(--s-4); font-size: var(--t-2); animation: toast-in var(--d-2) var(--ease); }
.toast svg { flex: none; width: 18px; height: 18px; margin-top: 2px; }
.toast .t-meta { color: inherit; opacity: 0.75; }
@keyframes toast-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }

/* ---------- empty ---------- */
.empty { padding: var(--s-6) var(--s-5); text-align: left; display: flex; flex-direction: column; gap: var(--s-3); align-items: flex-start; }

/* ---------- key/value list ---------- */
.kv { display: grid; grid-template-columns: minmax(120px, max-content) 1fr; gap: var(--s-2) var(--s-5); font-size: var(--t-2); }
.kv dt { color: var(--ink-2); }
.kv dd { min-width: 0; }
@media (max-width: 520px) { .kv { grid-template-columns: 1fr; gap: 2px; } .kv dd { margin-bottom: var(--s-2); } }

/* ---------- live pulse (the one ambient motion: a check just ran) ---------- */
.pulse { animation: pulse var(--d-3) var(--ease); }
@keyframes pulse { from { opacity: 0.35; } to { opacity: 1; } }

@media (max-width: 640px) { .hide-sm { display: none; } }

/* ---------- plan table ---------- */
.plan-table .table th[scope="row"] { font-weight: var(--w-regular); background: transparent; color: var(--ink); white-space: normal; padding: var(--s-3); border-top: var(--hair) solid var(--line); font-size: var(--t-2); }
.plan-table .table td { width: 30%; }
.plan-table .plan-group th { background: transparent; color: var(--ink); font-size: var(--t-2); padding-top: var(--s-5); }
.plan-table thead th[aria-current="true"] { color: var(--ink); box-shadow: inset 0 -2px 0 var(--accent); }
.plan-yes svg, .plan-no svg { width: 18px; height: 18px; }
.plan-yes { color: var(--accent-text); }
.plan-no { color: var(--ink-3); }

/* A disclosure says it opens: its label, then on the same line a chevron, turned while open
   (`src/components/Disclosure.tsx`). A JSON tree keeps the browser's triangle in front, as trees do. */
.disclosure > summary { display: inline-flex; align-items: center; gap: var(--s-1); min-height: var(--control-sm); cursor: pointer; list-style: none; font-weight: var(--w-medium); color: var(--ink-2); border-radius: var(--r-1); }
.disclosure > summary::-webkit-details-marker { display: none; }
.disclosure > summary:hover, .disclosure[open] > summary { color: var(--ink); }
.disclosure-chev { flex: none; width: 16px; height: 16px; transition: transform var(--d-1) var(--ease); }
.disclosure[open] > summary > .disclosure-chev { transform: rotate(180deg); }
.disclosure > :not(summary) { margin-top: var(--s-2); }
@media (prefers-reduced-motion: reduce) { .disclosure-chev { transition: none; } }

/* app.css: the dashboard's layout. Tokens only. */

.logo { display: inline-flex; align-items: center; gap: var(--s-2); text-decoration: none; }
.logo-word { font-weight: var(--w-bold); font-size: var(--t-3); letter-spacing: var(--track-title); color: var(--ink); }

.skip { position: absolute; left: var(--s-3); top: -60px; z-index: var(--z-toast); background: var(--ink); color: var(--on-ink); padding: var(--s-2) var(--s-3); border-radius: var(--r-1); }
.skip:focus { top: var(--s-3); }

/* ---------- shell ---------- */
.shell { display: grid; grid-template-columns: var(--w-rail) minmax(0, 1fr); min-height: 100dvh; }
.rail { position: sticky; top: 0; height: 100dvh; overflow-y: auto; background: var(--raised); border-right: var(--hair) solid var(--line); }
.rail-inner { display: flex; flex-direction: column; gap: var(--s-5); padding: var(--s-5) var(--s-3) var(--s-4); min-height: 100%; }
.rail-top { display: flex; flex-direction: column; gap: var(--s-2); padding: 0 var(--s-2); }
.rail-brand { text-decoration: none; display: inline-flex; }
.rail-sum { display: inline-flex; align-items: center; gap: 6px; font-size: var(--t-1); font-weight: var(--w-medium); color: var(--ink-2); }
/* The app row under the logo: the app's name, or the switcher with two or more, then its state
   and what is wrong in the other apps. */
.rail-app { display: flex; flex-direction: column; gap: var(--s-2); min-width: 0; }
.rail-app-one { display: flex; align-items: center; gap: var(--s-2); padding: 0 var(--s-2); min-width: 0; }
.rail-app-name { font-weight: var(--w-bold); overflow-wrap: anywhere; min-width: 0; }
.rail-app-status { display: flex; flex-direction: column; align-items: flex-start; gap: var(--s-1); padding: 0 var(--s-2); }
.rail-group ul { display: flex; flex-direction: column; gap: 1px; }
.rail-link { display: flex; align-items: center; gap: var(--s-2); min-height: 36px; padding: 0 var(--s-2); border-radius: var(--r-1); text-decoration: none; color: var(--ink-2); font-weight: var(--w-medium); }
.rail-link:hover { background: var(--sunk); color: var(--ink); }
.rail-switcher { min-width: 0; }
.rail-switch { width: 100%; text-align: left; justify-content: space-between; white-space: normal; }
.rail-switch .grow, .rail-app-option .grow { min-width: 0; overflow-wrap: anywhere; }
[popover].rail-app-menu { position: fixed; inset: auto; margin: 0; padding: var(--s-1); overflow-y: auto; }
.rail-app-option { display: flex; align-items: center; gap: var(--s-2); width: 100%; min-height: var(--control); padding: var(--s-2); border: 0; border-radius: var(--r-1); background: none; color: var(--ink); text-align: left; text-decoration: none; font-weight: var(--w-medium); }
.rail-app-option:hover { background: var(--sunk); }
.rail-app-option svg { flex: none; width: var(--s-4); height: var(--s-4); }
.rail-app-add { border-top: var(--hair) solid var(--line); border-radius: 0; margin-top: var(--s-1); }
/* Five places to ping from are wider than a phone; wrapped, none hides past the edge. */
.hb-places .tabs { flex-wrap: wrap; }
.rail-link svg { width: 18px; height: 18px; flex: none; }
/* Where you are is wayfinding, not a choice, so it is neutral: a grey step past hover, never the
   accent, which stays for what you can press and what you chose in the content (principle 1). In
   forced colours the background is dropped, so the current section keeps a Highlight outline; a
   focused link shows its focus ring instead. */
.rail-link[aria-current="page"] { background: var(--current); color: var(--ink); }
@media (forced-colors: active) {
  .rail-link[aria-current="page"]:not(:focus-visible) { outline: var(--hair) solid Highlight; outline-offset: calc(-1 * var(--hair)); }
}
.rail-count { font-size: var(--t-1); color: var(--on-accent); background: var(--down); font-weight: var(--w-bold); border-radius: var(--r-pill); padding: 1px 8px; }
.rail-foot { margin-top: auto; display: flex; flex-direction: column; gap: var(--s-3); }
.plan-box { display: flex; flex-direction: column; gap: var(--s-2); padding: var(--s-3); border-radius: var(--r-2); background: var(--surface); border: var(--hair) solid var(--line); box-shadow: var(--rest); text-decoration: none; }
.rail-org { flex: 1; min-width: 0; }
.rail-org .cl-rootBox, .rail-org .cl-organizationSwitcherTrigger { max-width: 100%; }
.rail-user { display: flex; align-items: center; gap: var(--s-2); padding: 0 var(--s-2); min-height: var(--control); }

.topbar { display: none; }
.drawer { border: 0; padding: 0; margin: 0 auto 0 0; height: 100dvh; max-height: 100dvh; width: min(300px, 86vw); overflow: visible; background: var(--surface); color: var(--ink); }
.drawer-scroll { height: 100%; overflow-y: auto; }
.drawer::backdrop { background: var(--scrim); }
.drawer-x { position: absolute; right: var(--s-2); top: var(--s-3); }

.main { padding: var(--s-6) max(var(--s-6), env(safe-area-inset-right, 0px)) var(--s-9) var(--s-6); min-width: 0; width: 100%; max-width: calc(var(--w-app) + 2 * var(--s-6)); }
.loading { padding: var(--s-7) 0; }
/* A click on a dashboard link, until its screen is there (`usePendingPath`, `Shell.tsx`): after a
   beat the screen being left fades back, so a slow answer is seen to be coming and a quick one
   never flickers. Only on the way out: the new screen arrives at full strength at once. Under
   reduced motion the fade becomes a step after the same beat (`design/kit.css`). */
.main[aria-busy="true"] { opacity: 0.6; transition: opacity var(--d-2) var(--ease) var(--d-1); }

@media (max-width: 900px) {
  .rail-switch, .rail-app-option { min-height: var(--target); }
  /* Rows sized to their content: on a page shorter than the screen the grid's spare height would
     otherwise be shared out, and the top bar grew to a quarter of the phone. */
  .shell { grid-template-columns: minmax(0, 1fr); align-content: start; }
  .rail { display: none; }
  .topbar { display: flex; align-items: center; gap: var(--s-3); position: sticky; top: env(safe-area-inset-top, 0px); z-index: var(--z-sticky); background: var(--surface); border-bottom: var(--hair) solid var(--line); padding: var(--s-2) max(16px, env(safe-area-inset-right, 0px)) var(--s-2) max(16px, env(safe-area-inset-left, 0px)); }
  .topbar > a { text-decoration: none; }
  /* A long app name wraps rather than losing its tail; the bar grows a line. */
  .topbar-app { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
  .topbar-app-name { font-size: var(--t-1); font-weight: var(--w-bold); overflow-wrap: anywhere; }
  .topbar-app .rail-app-status { padding: 0; gap: 0; }
  .topbar .btn-icon { margin-left: auto; }
  .main { padding: var(--s-5) max(16px, env(safe-area-inset-right, 0px)) var(--s-9) max(16px, env(safe-area-inset-left, 0px)); }
}

/* ---------- page head ---------- */
.page-head { display: flex; flex-direction: column; gap: var(--s-2); margin-bottom: var(--s-5); }
.page-head-row { align-items: flex-end; }
/* A page title led by a 24px mark (the overview's state), held to its first line when it wraps. */
.head-mark { display: flex; align-items: flex-start; gap: var(--s-3); }
.head-mark > svg { flex: none; margin-top: calc((1lh - 24px) / 2); }
.back { font-size: var(--t-1); color: var(--ink-2); text-decoration: none; display: inline-flex; align-items: center; gap: var(--s-1); width: fit-content; }
.back::before { content: "‹"; font-size: 1.2em; line-height: 1; }
.back:hover { color: var(--ink); text-decoration: underline; }

.section { display: flex; flex-direction: column; gap: var(--s-3); }
.section + .section { margin-top: var(--s-6); }
.section-head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--s-3); flex-wrap: wrap; }

/* ---------- overview ---------- */
/* Every panel-like surface in the app sits on the resting shadow (`--rest`, light only) under its
   hairline, so all of them read as one material. */
.app-block { background: var(--surface); border: var(--hair) solid var(--line); border-radius: var(--r-2); overflow: hidden; box-shadow: var(--rest); }
.app-block-head { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: var(--s-3) var(--s-5); padding: var(--s-4) var(--s-5); }
.app-block-head h2 { font-size: var(--t-3); display: flex; align-items: center; gap: var(--s-3); flex-wrap: wrap; }
.app-block-bars { grid-column: 1 / -1; display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: var(--s-4); }
@media (max-width: 640px) { .app-block-head { grid-template-columns: minmax(0, 1fr); } .app-block-bars { grid-template-columns: minmax(0, 1fr); gap: var(--s-1); } }

.kpis { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--s-3); margin-bottom: var(--s-5); }
.kpi { display: flex; flex-direction: column; gap: var(--s-1); padding: var(--s-4) var(--s-5); border-radius: var(--r-2); border: var(--hair) solid var(--line); background: var(--surface); box-shadow: var(--rest); text-decoration: none; color: var(--ink); min-width: 0; }
a.kpi:hover { border-color: var(--line-strong); }
.kpi-n { font-size: 40px; line-height: 1; font-weight: var(--w-bold); letter-spacing: var(--track-title); font-variant-numeric: tabular-nums; }
.kpi-l { display: inline-flex; align-items: center; gap: var(--s-2); font-weight: var(--w-medium); color: var(--ink-2); }
.kpi.degraded { background: var(--wash-warn); border-color: transparent; }
.kpi.down { background: var(--wash-down); border-color: transparent; }
/* A zero is quiet: its number and its shape go grey, so a healthy day shows no amber or red. */
.kpi.zero .kpi-n { color: var(--ink-3); }
.kpi.zero .state-icon { color: var(--edge); }
/* On a phone the four counts are one strip of four split by hairlines, one short row instead of
   a two-by-two block of 40px numbers: each cell's shape beside its number, its word under them. */
@media (max-width: 760px) {
  .kpis { gap: 0; border: var(--hair) solid var(--line); border-radius: var(--r-2); overflow: hidden; background: var(--surface); box-shadow: var(--rest); }
  .kpi { display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: center; align-content: start; gap: 2px var(--s-2); border: 0; border-radius: 0; padding: var(--s-3) var(--s-2); box-shadow: none; }
  .kpi + .kpi { border-left: var(--hair) solid var(--line); }
  .kpi-n { font-size: 24px; }
  .kpi-l { display: contents; font-size: var(--t-1); }
  .kpi-word { grid-column: 1 / -1; line-height: 1.3; }
  a.kpi:hover .kpi-word { color: var(--ink); text-decoration: underline; }
}
.app-block .table td:first-child, .app-block .table th:first-child { padding-left: var(--s-5); }
.app-block .table td:last-child, .app-block .table th:last-child { padding-right: var(--s-5); }
/* The severity bar is a straight strip clipped by the corners, not an inset shadow, which follows
   the radius and bends at both ends. */
.alarm { position: relative; overflow: hidden; display: flex; gap: var(--s-4); align-items: flex-start; padding: var(--s-4) var(--s-5); border-radius: var(--r-2); background: var(--wash-down); flex-wrap: wrap; }
.alarm::before { content: ""; position: absolute; inset: 0 auto 0 0; width: 4px; background: var(--down); }
.alarm.warn { background: var(--wash-warn); }
.alarm.warn::before { background: var(--warn); }
.alarm-body > strong { font-size: var(--t-3); line-height: var(--lh-head); }
.alarm-body { flex: 1 1 280px; min-width: 0; display: flex; flex-direction: column; gap: var(--s-1); }

/* ---------- monitor rows ---------- */
.mon-name { display: flex; align-items: center; gap: var(--s-2); min-width: 0; }
.mon-name > svg { color: var(--ink-3); flex: none; }
.mon-name a { font-weight: var(--w-bold); text-decoration: none; color: var(--ink); }
.mon-name a:hover { text-decoration: underline; }
.mon-target { display: block; color: var(--ink-3); max-width: 340px; font-size: var(--t-1); }
/* On a phone the table keeps the name, the state and the day's uptime: the address gives way
   first, cut to whatever width the name leaves it, so a state like Not checked yet stays on one
   line. */
@media (max-width: 640px) { .mon-target { width: 0; min-width: 100%; max-width: none; } }
.filters { display: flex; flex-wrap: wrap; gap: var(--s-2); align-items: center; }
.filters .select { width: auto; min-width: 140px; }
.filters .input { width: min(260px, 100%); }

/* ---------- monitor detail ---------- */
.hero-state { display: flex; align-items: center; gap: var(--s-3); flex-wrap: wrap; font-size: var(--t-3); }
.hero-state .state { font-weight: var(--w-bold); }
/* A monitor's numbers: one panel split by hairlines, not a tile each. The cells flow onto as many
   rows as the width allows and every row fills, so a fifth number never sits alone beside an
   empty slot; the panel's line colour shows through the 1px gaps as the hairlines between. */
.stat-strip { display: flex; flex-wrap: wrap; gap: var(--hair); background: var(--line); border: var(--hair) solid var(--line); border-radius: var(--r-2); overflow: hidden; box-shadow: var(--rest); }
.stat-strip > .stat { flex: 1 1 150px; background: var(--surface); padding: var(--s-4) var(--s-5); }
@media (max-width: 640px) { .stat-strip > .stat { padding: var(--s-3) var(--s-4); } }
/* Where checks come from: one panel, a row per location split by hairlines. The city leads with
   its flag; the state, or the Builder tag, sits at the row's far end, away from the flags' red. */
.locs { background: var(--surface); border: var(--hair) solid var(--line); border-radius: var(--r-2); box-shadow: var(--rest); }
.loc { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--s-3); padding: var(--s-3) var(--s-4); min-width: 0; }
.loc + .loc { border-top: var(--hair) solid var(--line); }
.loc-body { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.loc.off .loc-place strong { color: var(--ink-2); }
/* A location's flag (`Flag`): 16 by 12, no larger than a state icon, before its city. The hairline
   keeps the white of the Canadian and US flags from dissolving into the panel. */
.loc-place { display: inline-flex; align-items: center; gap: var(--s-2); min-width: 0; }
.flag { flex: none; width: 16px; height: 12px; border-radius: 2px; outline: var(--hair) solid var(--line-strong); outline-offset: calc(-1 * var(--hair)); }
.assert-row { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: var(--s-3); align-items: center; padding: var(--s-3) 0; border-top: var(--hair) solid var(--line); }
.assert-row:first-child { border-top: 0; }
.events { display: flex; flex-direction: column; }
.event { display: grid; grid-template-columns: 92px 18px minmax(0, 1fr); gap: var(--s-3); padding: var(--s-3) 0; border-top: var(--hair) solid var(--line); align-items: start; }
.event:first-child { border-top: 0; }
.event > time { font-size: var(--t-1); color: var(--ink-3); padding-top: 2px; }
.event-dot { width: 10px; height: 10px; border-radius: var(--r-pill); margin-top: 6px; background: var(--edge); }
.event-dot.fail, .event-dot.down { background: var(--down); border-radius: 2px; }
.event-dot.degraded { background: var(--warn); }
.event-dot.recovered, .event-dot.pass, .event-dot.ping { background: var(--up); }
.event-dot.paused { background: var(--paused); }
.detail-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 340px); gap: var(--s-4); align-items: start; }
@media (max-width: 1080px) { .detail-grid { grid-template-columns: minmax(0, 1fr); } }

/* ---------- charts ---------- */
.chart { margin: 0; display: flex; flex-direction: column; gap: var(--s-3); }
.chart-head { display: flex; justify-content: space-between; align-items: center; gap: var(--s-3); flex-wrap: wrap; }
.legend { display: flex; flex-wrap: wrap; gap: var(--s-4); font-size: var(--t-1); color: var(--ink-2); }
.legend li { display: inline-flex; align-items: center; gap: 6px; }
.swatch { width: 14px; height: 3px; border-radius: var(--r-pill); display: inline-block; }
.swatch-band { height: 10px; width: 10px; border-radius: 2px; background: var(--chart-band); box-shadow: inset 2px 0 0 var(--down); }
.chart-plot { position: relative; width: 100%; }
.chart-plot svg { overflow: visible; }
.axis { font-size: 11px; fill: var(--ink-3); font-family: var(--f-sans); }
.chart-table { max-height: 320px; overflow-y: auto; }
.tip { position: absolute; transform: translateX(-50%); background: var(--ink); color: var(--on-ink); border-radius: var(--r-1); padding: var(--s-2) var(--s-3); font-size: var(--t-1); display: flex; flex-direction: column; gap: 1px; pointer-events: none; white-space: nowrap; z-index: 2; }
.tip .t-down { color: var(--on-ink); font-weight: var(--w-bold); }
.tip .t-meta { color: var(--on-ink); opacity: 0.8; }

.bars-wrap { display: flex; flex-direction: column; gap: var(--s-2); min-width: 0; }
.bars { position: relative; display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); gap: 2px; align-items: stretch; }
.bar { border-radius: 2px; background: var(--bar-up); min-width: 1px; }
.bar.dip { background: var(--warn); }
.bar.down { background: var(--down); }
.bar.none { background: var(--sunk); }
.bar:hover, .bar:focus-visible { opacity: 0.7; outline-offset: 1px; }
.tip-bar { top: calc(100% + 6px); }
.bars-foot { display: flex; justify-content: space-between; gap: var(--s-3); }
.spark { flex: none; }

/* ---------- add monitor ---------- */
.type-groups { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr)); gap: var(--s-4); }
.type-group legend { font-size: var(--t-1); color: var(--ink-2); font-weight: var(--w-bold); margin-bottom: var(--s-2); }
.type-list { display: flex; flex-direction: column; gap: 2px; background: var(--surface); border: var(--hair) solid var(--line); border-radius: var(--r-2); box-shadow: var(--rest); padding: var(--s-1); }
/* One of eight is a radio (`AddMonitorScreen`): the chosen card wears a full cobalt border and a
   filled radio, never a left bar, which means "you are here" or "how bad" and bent at the corners.
   The radio sits last; a Coming soon tag sits before it. */
.type-opt { display: grid; grid-template-columns: 32px minmax(0, 1fr) auto; gap: var(--s-3); align-items: center; width: 100%; padding: var(--s-3); border: var(--hair) solid transparent; border-radius: var(--r-1); background: transparent; color: var(--ink); min-height: var(--target); cursor: pointer; }
.type-opt:hover { background: var(--sunk); }
.type-opt:has(input:checked) { background: var(--accent-wash); border-color: var(--accent); box-shadow: inset 0 0 0 var(--hair) var(--accent); }
.type-opt input { grid-column: -2; width: 18px; height: 18px; margin: 0; accent-color: var(--accent); cursor: pointer; }
.type-opt input:focus-visible { outline: 0; }
.type-opt:has(input:focus-visible) { outline: var(--rule) solid var(--accent); outline-offset: var(--rule); }
.type-opt-text { min-width: 0; }
/* A Coming soon tag sits beside the name, wrapping under it in a narrow column, never squeezing the hint. */
.type-opt-name { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-1) var(--s-2); }
.type-opt small { display: block; color: var(--ink-3); font-size: var(--t-1); }
/* Forced colours drop the wash and the shadow: the chosen card keeps a Highlight border and the
   system's filled radio; the others' transparent borders would otherwise show. */
@media (forced-colors: active) {
  .type-opt { border-color: Canvas; }
  .type-opt:has(input:checked) { border: var(--rule) solid Highlight; padding: calc(var(--s-3) - var(--hair)); }
}
/* An icon in a small bordered square, as the type picker shows its types. */
.icon-tile { flex: none; width: 32px; height: 32px; display: grid; place-items: center; border: var(--hair) solid var(--line); border-radius: var(--r-1); background: var(--surface); color: var(--ink-2); }
.icon-tile svg { width: 18px; height: 18px; }
.form-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 220px), 1fr)); gap: var(--s-4); }
.form-grid .span-all { grid-column: 1 / -1; }
.assert-edit { display: grid; grid-template-columns: minmax(0, 1.4fr) 110px minmax(0, 1fr) auto auto; gap: var(--s-2); align-items: center; }
@media (max-width: 640px) { .assert-edit { grid-template-columns: 1fr 1fr; } .assert-edit > :first-child { grid-column: 1 / -1; } }
.live-check { display: flex; flex-direction: column; gap: var(--s-2); }
.live-line { display: flex; gap: var(--s-2); align-items: center; font-size: var(--t-2); }
.live-line > svg { flex: none; }
.add-layout { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 360px); gap: var(--s-5); align-items: start; }
@media (max-width: 1080px) { .add-layout { grid-template-columns: minmax(0, 1fr); } }
.sticky-side { position: sticky; top: var(--s-5); }

/* ---------- incidents ---------- */
/* An empty list that reassures: the up mark, or before any check the hollow ring, then one quiet
   line of evidence. Healthy is quiet, so nothing in it is bold. */
.calm { display: flex; gap: var(--s-3); align-items: flex-start; padding: var(--s-4) var(--s-5); border: var(--hair) solid var(--line); border-radius: var(--r-2); background: var(--surface); box-shadow: var(--rest); min-width: 0; }
.calm > svg { flex: none; margin-top: 1px; }
.calm strong { display: block; font-weight: var(--w-medium); }
.calm p > span { font-size: var(--t-1); color: var(--ink-3); }
.timeline { display: flex; flex-direction: column; }
.timeline li { display: grid; grid-template-columns: 92px minmax(0, 1fr); gap: var(--s-3); padding: var(--s-2) 0; border-top: var(--hair) solid var(--line); }
.timeline li:first-child { border-top: 0; }
.note { display: flex; flex-direction: column; gap: var(--s-2); padding: var(--s-4); border-radius: var(--r-2); background: var(--sunk); }
.note.draft { background: transparent; border: var(--hair) dashed var(--edge); }
.note-head { display: flex; gap: var(--s-2); align-items: center; flex-wrap: wrap; font-size: var(--t-1); color: var(--ink-2); }
.note-head strong { color: var(--ink); text-transform: none; }

/* ---------- alerts ---------- */
.channel-row { display: grid; grid-template-columns: 36px minmax(0, 1fr) auto; gap: var(--s-3); align-items: center; padding: var(--s-4) var(--s-5); border-top: var(--hair) solid var(--line); }
.channel-row:first-child { border-top: 0; }
.channel-icon { width: 36px; height: 36px; border-radius: var(--r-2); background: var(--sunk); display: grid; place-items: center; }
.channel-icon svg { width: 18px; height: 18px; }
.preview-phone { background: var(--sunk); border-radius: var(--r-2); padding: var(--s-4); display: flex; flex-direction: column; gap: var(--s-3); }
.msg { background: var(--surface); border-radius: var(--r-2); padding: var(--s-3) var(--s-4); display: flex; flex-direction: column; gap: var(--s-2); max-width: 440px; font-size: var(--t-2); }
.msg-from { font-size: var(--t-1); font-weight: var(--w-bold); }
.msg-buttons { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s-1); }
.msg-buttons .btn { min-height: var(--control-sm); font-size: var(--t-1); padding: 0 var(--s-2); }

/* ---------- status page editor ---------- */
.editor { display: grid; grid-template-columns: minmax(0, 400px) minmax(0, 1fr); gap: var(--s-5); align-items: start; }
@media (max-width: 1080px) { .editor { grid-template-columns: minmax(0, 1fr); } }
.preview-frame { background: var(--sunk); border-radius: var(--r-2); padding: var(--s-4); position: sticky; top: var(--s-5); display: flex; flex-direction: column; gap: var(--s-3); }
.preview-viewport { border-radius: var(--r-2); overflow: hidden; background: var(--ground); margin: 0 auto; width: 100%; max-height: 72vh; overflow-y: auto; }
.preview-viewport.phone { width: 375px; max-width: 100%; }
.preview-url { font-size: var(--t-1); color: var(--ink-2); display: flex; align-items: center; gap: var(--s-2); min-width: 0; }
.steps { display: flex; flex-direction: column; gap: var(--s-3); counter-reset: step; }
.step { display: grid; grid-template-columns: 26px minmax(0, 1fr); gap: var(--s-3); align-items: start; }
.step-n { width: 26px; height: 26px; border-radius: var(--r-pill); display: grid; place-items: center; font-size: var(--t-1); font-weight: var(--w-bold); background: var(--sunk); color: var(--ink-2); }
.step.done .step-n { background: var(--up); color: var(--on-ink); }
.step.now .step-n { background: var(--accent); color: var(--on-accent); }
.comp-row { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: var(--s-3); align-items: center; padding: var(--s-3) 0; border-top: var(--hair) solid var(--line); }
.comp-row:first-child { border-top: 0; }
.swatches { display: flex; gap: var(--s-2); flex-wrap: wrap; align-items: center; }
.swatch-btn { width: 32px; height: 32px; border-radius: var(--r-pill); border: var(--rule) solid transparent; cursor: pointer; padding: 0; }
.swatch-btn[aria-pressed="true"] { border-color: var(--accent); box-shadow: inset 0 0 0 2px var(--surface); }

/* ---------- widget ---------- */
.host-frame { border-radius: var(--r-2); overflow: hidden; }

/* ---------- agents ---------- */
.terminal { background: var(--field-dark); color: var(--field-dark-ink-2); border-radius: var(--r-2); padding: var(--s-4) var(--s-5); font-family: var(--f-mono); font-size: var(--t-1); line-height: 1.7; overflow-x: auto; white-space: pre-wrap; overflow-wrap: anywhere; }
.terminal .you { color: var(--field-dark-ink); font-weight: var(--w-bold); }
.terminal .tool { color: var(--field-dark-ink-2); opacity: 0.8; }
.terminal .ok { color: var(--up); }

/* ---------- toasts ---------- */
.toast-x { background: none; border: 0; color: inherit; opacity: 0.8; padding: 2px; display: grid; place-items: center; min-width: 28px; min-height: 28px; }
.toast-link { color: inherit; font-weight: var(--w-bold); font-size: var(--t-1); }

/* Adding an app: name, optional address, one button. */
.add-app { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr) auto; gap: var(--s-3); align-items: end; }
.add-app .span-all { grid-column: 1 / -1; }
@media (max-width: 640px) { .add-app { grid-template-columns: minmax(0, 1fr); } }
.add-app-block { margin-top: var(--s-5); }

/* An app's logo beside its name (`AppLogo`): its image, or its first letter on a neutral square.
   Never a state colour and never the accent. */
.app-logo { flex: none; border-radius: var(--r-1); object-fit: contain; }
.app-logo-none { display: inline-grid; place-items: center; background: var(--sunk); color: var(--ink-2); font-weight: var(--w-bold); line-height: 1; }

/* Settings: an app's row, and its editor and suggested checks under it. */
.app-row { border-top: var(--hair) solid var(--line); }
.app-row:first-child { border-top: 0; }
.app-row > .channel-row { border-top: 0; }
.app-edit { padding: 0 var(--s-5) var(--s-5) calc(var(--s-5) + 36px + var(--s-3)); }
/* On a phone an app's row follows the settings rows: its words keep the width, its Edit and Delete
   drop under them. */
@media (max-width: 640px) {
  .app-row > .channel-row { grid-template-columns: 36px minmax(0, 1fr); padding: var(--s-4); }
  .app-row-actions { grid-column: 2; }
  .app-edit { padding: 0 var(--s-4) var(--s-4); }
}

/* Suggested checks (`SuggestedChecks`): each a tick, what it checks, and what it got. */
.sg { display: flex; flex-direction: column; gap: var(--s-4); min-width: 0; }
.sg-list { border: 0; margin: 0; padding: 0; min-width: 0; display: flex; flex-direction: column; }
.sg-row { align-items: flex-start; padding: var(--s-3) 0; border-top: var(--hair) solid var(--line); min-width: 0; }
.sg-row:first-of-type { border-top: 0; padding-top: 0; }
.sg-row input { margin-top: 2px; flex: none; }
.sg-row:has(input:disabled) { cursor: default; }
.sg-body { display: flex; flex-direction: column; gap: var(--s-1); min-width: 0; }
.sg-name { font-weight: var(--w-medium); display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--s-2); min-width: 0; }
.sg-name .code { white-space: normal; }
.sg-result { display: flex; align-items: flex-start; gap: var(--s-2); color: var(--ink-2); min-width: 0; }
.sg-result .state-icon { flex: none; margin-top: 3px; }
.sg-found { display: flex; align-items: baseline; gap: var(--s-2); min-width: 0; }
.sg-swatch { flex: none; width: 12px; height: 12px; border-radius: var(--r-pill); box-shadow: inset 0 0 0 var(--hair) var(--line); align-self: center; }

/* status.css: public surfaces. The status page, the widget pieces and the sample host app.
   Tokens only. The sample host app wears AskOne's own palette (its raw values sit in tokens.css),
   because the person looking at it is AskOne's user, not the builder. */

/* ---------- AskOne, the sample host app (pair with .theme-dark for the status colours) ---------- */
.host-askone {
  --ground: var(--askone-bg);
  --surface: var(--askone-surface);
  --sunk: var(--askone-sunk);
  --raised: var(--askone-raised);
  --ink: var(--askone-text);
  --ink-2: var(--askone-text-2);
  --ink-3: var(--askone-text-3);
  --edge: var(--askone-edge);
  --line: var(--askone-line);
  --on-ink: var(--askone-bg);
  --brand: var(--askone-amber);
  --on-brand: var(--askone-on-amber);
  background: var(--ground);
  color: var(--ink);
}

/* ---------- status page ---------- */
.sp {
  min-height: 100dvh;
  background: var(--ground);
  color: var(--ink);
  container-type: inline-size;
  overflow-x: clip;
}
.sp-embedded { min-height: 0; }
.sp-inner {
  width: 100%;
  max-width: 760px;
  margin: 0 auto;
  padding: var(--s-6) max(var(--s-5), env(safe-area-inset-right, 0px)) var(--s-7) max(var(--s-5), env(safe-area-inset-left, 0px));
  display: flex;
  flex-direction: column;
  gap: var(--s-6);
}
.sp-plain { padding-top: var(--s-8); max-width: 560px; }

.sp-head { display: flex; align-items: center; justify-content: space-between; gap: var(--s-2) var(--s-4); flex-wrap: wrap; }
.sp-brand { display: inline-flex; align-items: center; gap: var(--s-2); min-height: var(--target); font-size: var(--t-3); font-weight: var(--w-black); letter-spacing: var(--track-title); color: var(--ink); text-decoration: none; }
.sp-mark { flex: none; }
/* The page's own links wear the builder's accent, shaded to read on this theme (`tokens.css`). */
.sp-home { display: inline-flex; align-items: center; gap: 0.35em; min-height: var(--target); color: var(--accent-text); text-decoration: underline; min-width: 0; }
.sp-home:hover { text-decoration-thickness: var(--rule); }

.sp-overall { display: flex; align-items: center; gap: var(--s-4); padding: var(--s-5) var(--s-6); border-radius: var(--r-3); background: var(--surface); }
.sp-overall.up { background: var(--wash-up); }
.sp-overall.degraded { background: var(--wash-warn); }
.sp-overall.down { background: var(--wash-down); }
.sp-overall.unchecked, .sp-overall.paused { background: var(--sunk); }
.sp-overall > svg { flex: none; }
.sp-overall-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.sp-overall-text h1, .sp-overall-text h2 { font-size: var(--t-4); line-height: 1.15; letter-spacing: var(--track-title); }
.sp-overall-text p { color: var(--ink-2); }

.sp-active { background: var(--surface); border-radius: var(--r-2); padding: var(--s-4) var(--s-5); display: flex; flex-direction: column; gap: var(--s-3); }
.sp-active-title { font-size: var(--t-3); }

.sp-section { display: flex; flex-direction: column; gap: var(--s-3); }
.sp-section-head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--s-1) var(--s-3); flex-wrap: wrap; }
.sp-section-head h2, .sp-sub h2 { font-size: var(--t-3); }

.sp-comps { background: var(--surface); border-radius: var(--r-2); }
.sp-comp { display: flex; flex-direction: column; gap: var(--s-2); padding: var(--s-4) var(--s-5); border-top: var(--hair) solid var(--line); min-width: 0; }
.sp-comp:first-child { border-top: 0; }
.sp-comp-head { display: flex; align-items: center; justify-content: space-between; gap: var(--s-1) var(--s-3); flex-wrap: wrap; }
.sp-comp-name { font-weight: var(--w-bold); min-width: 0; }

.sp-notes { display: flex; flex-direction: column; gap: var(--s-3); }
.sp-notes > li { display: grid; grid-template-columns: 112px minmax(0, 1fr); gap: 2px var(--s-4); }
.sp-notes > li > strong { grid-row: span 2; }
.sp-notes > li > p, .sp-notes > li > time { grid-column: 2; }

.sp-history { display: flex; flex-direction: column; }
.sp-incident { display: flex; flex-direction: column; gap: var(--s-3); padding: var(--s-4) 0; border-top: var(--hair) solid var(--line); }
.sp-incident:first-child { border-top: 0; padding-top: 0; }
.sp-incident-head { display: flex; flex-direction: column; gap: 2px; }
.sp-incident h3 { font-size: var(--t-2); }

.sp-sub { background: var(--surface); border-radius: var(--r-2); padding: var(--s-4) var(--s-5); }
.sp-sub-row { display: flex; flex-wrap: wrap; gap: var(--s-2); }
.sp-sub-row .input { flex: 1 1 220px; width: auto; }
.sp .input, .sp .btn { min-height: var(--target); }

.sp-foot { display: flex; align-items: center; justify-content: space-between; gap: var(--s-2) var(--s-4); flex-wrap: wrap; padding-top: var(--s-3); border-top: var(--hair) solid var(--line); }
.sp-foot-link { display: inline-flex; align-items: center; min-height: var(--target); color: var(--ink-2); font-size: var(--t-1); text-decoration-color: var(--edge); }
.sp-foot-link:hover { color: var(--ink); }

@container (max-width: 560px) {
  .sp-inner { padding: var(--s-4) max(16px, env(safe-area-inset-right, 0px)) var(--s-6) max(16px, env(safe-area-inset-left, 0px)); gap: var(--s-5); }
  .sp-plain { padding-top: var(--s-7); }
  .sp-overall, .sp-active, .sp-comp, .sp-sub { padding-left: var(--s-4); padding-right: var(--s-4); }
  .sp-overall-text h1, .sp-overall-text h2 { font-size: var(--t-3); }
  .sp-notes > li { grid-template-columns: minmax(0, 1fr); }
  .sp-notes > li > strong { grid-row: auto; }
  .sp-notes > li > p, .sp-notes > li > time { grid-column: 1; }
  .sp-sub-row .btn { flex: 1 1 100%; }
}

/* ---------- widget pieces ---------- */
.sg-pill { display: inline-flex; align-items: center; gap: var(--s-2); min-height: var(--target); padding: 0 var(--s-4); border-radius: var(--r-pill); border: var(--hair) solid var(--line); background: var(--surface); color: var(--ink); font-size: var(--t-1); font-weight: var(--w-medium); text-decoration: none; white-space: nowrap; }
.sg-pill:hover { border-color: var(--edge); }

.sg-banner { display: flex; align-items: flex-start; gap: var(--s-3); padding: var(--s-3) max(var(--s-4), env(safe-area-inset-right, 0px)) var(--s-3) max(var(--s-4), env(safe-area-inset-left, 0px)); background: var(--wash-warn); color: var(--ink); }
.sg-banner.down { background: var(--wash-down); }
.sg-banner > svg { flex: none; margin-top: 3px; }
.sg-banner-body { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.sg-banner-body p { overflow-wrap: anywhere; }
.sg-banner-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 0 var(--s-4); }
.sg-banner-link { display: inline-flex; align-items: center; min-height: var(--target); margin-block: -10px; color: var(--ink); font-size: var(--t-1); font-weight: var(--w-bold); }
.sg-banner-x { flex: none; display: grid; place-items: center; width: var(--target); height: var(--target); margin: -10px -10px -10px 0; border: 0; border-radius: var(--r-1); background: transparent; color: var(--ink-2); }
.sg-banner-x:hover { color: var(--ink); background: var(--surface); }
.sg-banner-x svg { width: 18px; height: 18px; }


/* The README badge is an image with its own fixed colours (`src/lib/badge.ts`); a long name shrinks it rather than widening the page. */
.sg-badge { display: block; flex: none; max-width: 100%; height: auto; }

/* ---------- the sample host app ---------- */
.ha { min-height: 100dvh; display: flex; flex-direction: column; }

/* The frame strip is Staygreen's, not AskOne's: it uses the dashboard's tokens on purpose. */
.ha-strip { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 0 var(--s-4); padding: var(--s-1) max(16px, env(safe-area-inset-right, 0px)) var(--s-1) max(16px, env(safe-area-inset-left, 0px)); background: var(--surface); color: var(--ink); border-bottom: var(--rule) solid var(--ink); font-size: var(--t-1); }
.ha-strip-label { display: inline-flex; align-items: center; gap: var(--s-2); font-weight: var(--w-bold); min-height: var(--target); }
.ha-strip-label svg { width: 16px; height: 16px; flex: none; }
.ha-strip-hint { color: var(--ink-2); flex: 1 1 280px; min-width: 0; padding-block: var(--s-1); }
.ha-strip a { display: inline-flex; align-items: center; min-height: var(--target); }

.ha-app { flex: 1 0 auto; display: flex; flex-direction: column; }
.ha-head { display: flex; align-items: center; justify-content: space-between; gap: var(--s-3); padding: var(--s-2) max(var(--s-5), env(safe-area-inset-right, 0px)) var(--s-2) max(var(--s-5), env(safe-area-inset-left, 0px)); border-bottom: var(--hair) solid var(--line); min-height: 64px; }
.ha-logo { display: inline-flex; align-items: center; gap: var(--s-2); font-size: var(--t-3); font-weight: var(--w-black); letter-spacing: var(--track-title); }
.ha-live { display: inline-flex; align-items: center; gap: 6px; min-height: 28px; padding: 0 var(--s-3); border-radius: var(--r-pill); border: var(--hair) solid var(--brand); color: var(--brand); font-size: var(--t-1); font-weight: var(--w-bold); }
.ha-head-right { display: flex; align-items: center; gap: var(--s-3); color: var(--ink-2); font-size: var(--t-1); }

.ha-main { width: 100%; max-width: 760px; margin: 0 auto; padding: var(--s-5) max(var(--s-5), env(safe-area-inset-right, 0px)) var(--s-7) max(var(--s-5), env(safe-area-inset-left, 0px)); display: flex; flex-direction: column; gap: var(--s-5); flex: 1 0 auto; }
.ha-room { display: flex; flex-direction: column; gap: var(--s-2); }
.ha-room h1 { font-size: var(--t-4); line-height: var(--lh-head); }
.ha-room-meta { display: flex; flex-wrap: wrap; gap: var(--s-1) var(--s-4); color: var(--ink-2); font-size: var(--t-1); }

.ha-ask { display: flex; flex-direction: column; gap: var(--s-3); padding: var(--s-4); border-radius: var(--r-2); background: var(--surface); }
.ha-ask .textarea { min-height: 84px; background: var(--sunk); border-color: var(--line); }
.ha-ask-foot { display: flex; align-items: center; justify-content: space-between; gap: var(--s-3); flex-wrap: wrap; color: var(--ink-3); font-size: var(--t-1); }
.ha-send { min-height: var(--target); background: var(--brand); border-color: var(--brand); color: var(--on-brand); font-weight: var(--w-bold); }
.ha-send:hover { background: var(--brand); }

.ha-sort { display: flex; gap: var(--s-1); border-bottom: var(--hair) solid var(--line); }
.ha-sort button { min-height: var(--target); padding: 0 var(--s-3); border: 0; border-bottom: var(--rule) solid transparent; margin-bottom: -1px; background: none; color: var(--ink-2); font-weight: var(--w-medium); }
.ha-sort button[aria-pressed="true"] { color: var(--ink); border-bottom-color: var(--brand); }

.ha-qs { display: flex; flex-direction: column; gap: var(--s-2); }
.ha-q { display: grid; grid-template-columns: 52px minmax(0, 1fr); gap: var(--s-3); align-items: start; padding: var(--s-3) var(--s-4) var(--s-3) var(--s-3); border-radius: var(--r-2); background: var(--surface); }
.ha-vote { display: flex; flex-direction: column; align-items: center; justify-content: center; width: 52px; min-height: 52px; border-radius: var(--r-2); border: var(--hair) solid var(--line); background: var(--sunk); color: var(--ink); font-weight: var(--w-bold); font-size: var(--t-1); line-height: 1.1; }
.ha-vote svg { width: 18px; height: 18px; }
.ha-vote:hover { border-color: var(--edge); }
.ha-vote[aria-pressed="true"] { border-color: var(--brand); color: var(--brand); }
.ha-q-body { display: flex; flex-direction: column; gap: var(--s-1); min-width: 0; padding-top: 2px; }
.ha-q-text { font-size: var(--t-2); overflow-wrap: anywhere; }
.ha-q-meta { display: flex; flex-wrap: wrap; gap: 0 var(--s-3); color: var(--ink-3); font-size: var(--t-1); }
.ha-answered { color: var(--brand); font-weight: var(--w-bold); }

.ha-foot { display: flex; align-items: center; justify-content: space-between; gap: var(--s-3); flex-wrap: wrap; padding: var(--s-3) max(var(--s-5), env(safe-area-inset-right, 0px)) calc(var(--s-3) + env(safe-area-inset-bottom, 0px)) max(var(--s-5), env(safe-area-inset-left, 0px)); border-top: var(--hair) solid var(--line); color: var(--ink-3); font-size: var(--t-1); }

@media (max-width: 640px) {
  .ha-head, .ha-main, .ha-foot { padding-left: max(16px, env(safe-area-inset-left, 0px)); padding-right: max(16px, env(safe-area-inset-right, 0px)); }
  .ha-room h1 { font-size: var(--t-3); }
  .ha-hide-sm { display: none; }
}
.sp-uploaded-logo {
  display: block;
  width: auto;
  height: var(--s-6);
  max-width: min(40vw, var(--s-10));
  object-fit: contain;
}

/* The status edge has no hydration or cookies. Native titles keep daily bars readable. */
@font-face { font-family: Switzer; src: url('/_edge/Switzer-Variable.woff2') format('woff2'); font-weight: 100 900; font-display: swap; }
:root { --font-switzer: Switzer; }
.edge-freshness { color: var(--ink-2); font-size: var(--t-2); }
.edge-freshness:empty { display: none; }
@media (max-width: 559px) { .sp .bars { gap: 1px; } }
