/* ==========================================================================
   Eryce — design system (round 5: attention)
   One page background, one panel surface, one ink for every word.
   Hierarchy comes from size, weight, position and elevation, never from grey.
   Calm by default, unmissable when a person is needed: everything that waits
   for a person takes the one attention treatment (.attn): an ink surface,
   white words, a fine RGB gradient border whose hue drifts slowly. Nothing
   else gets it. Dark red is left for the Wren & Vera yin-yang and the count
   of what waits for you. Agents at work show by motion and ink, never colour.
   ========================================================================== */

/* ---------- Fonts (local, offline) ---------- */
@font-face {
  font-family: "Hanken Grotesk"; font-style: normal; font-weight: 300 700; font-display: swap;
  src: url("../fonts/hanken-grotesk-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Hanken Grotesk"; font-style: normal; font-weight: 300 700; font-display: swap;
  src: url("../fonts/hanken-grotesk-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Geist Mono"; font-style: normal; font-weight: 400 600; font-display: swap;
  src: url("../fonts/geist-mono-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Geist Mono"; font-style: normal; font-weight: 400 600; font-display: swap;
  src: url("../fonts/geist-mono-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ---------- Tokens ---------- */
:root {
  /* Two surfaces, and only two: the room and the panel. */
  --bg: #F3F3F1;              /* the page */
  --surface: #FFFFFF;         /* panels, cards, bubbles, floating layers */

  /* Neutral fills for controls and marks: tracks, chips, avatars, the selected row, our bubbles.
     Translucent ink, so they read the same on the page and on a panel. Never a container background. */
  --fill: rgba(28, 27, 31, .06);
  --fill-2: rgba(28, 27, 31, .11);   /* progress track, pressed */
  --track: rgba(28, 27, 31, .15);    /* a switch that is off */
  --track-hover: rgba(28, 27, 31, .21);
  --fill-solid: #EFEEEB;             /* the same fill, opaque: avatars, our bubbles (things that overlap) */
  --hover: rgba(28, 27, 31, .035);   /* hover on a surface */
  --press: #F7F7F6;                  /* hover on a white control */
  --line: rgba(28, 27, 31, .09);     /* hairline between things */
  --line-strong: rgba(28, 27, 31, .16); /* the outline of a control */
  --line-hover: rgba(28, 27, 31, .26);  /* the outline of a control under the pointer */

  /* Ink: the one colour for every word. */
  --ink: #1C1B1F;
  --ink-hover: #36343B;       /* hover on an ink fill */
  --on-ink: #FFFFFF;          /* words on ink or on the accent */

  /* Strokes: rings, connectors, inactive marks, disabled glyphs. Never text. */
  --stroke: #B3B1AD;
  --stroke-faint: #D9D7D3;

  /* The accent: dark red. Only the yin-yang and the count of what waits for you. */
  --accent: #A3173F;
  --accent-strong: #84102F;
  --accent-on-ink: #D63A6C;   /* the same red on an ink surface */

  /* Attention: the one treatment for what waits for a person (.attn). The ink is held here, because inside
     .attn --ink means white. --attn-h is the drifting hue (registered below, one clock for the page). */
  --attn-fill: #1C1B1F;
  --attn-fill-hover: #2B2A30;
  --attn-fill-press: #111013;
  --attn-w: 1.5px;
  --attn-period: 30s;
  --attn-c1: oklch(.75 .16 calc(var(--attn-h, 0) + 20));
  --attn-c2: oklch(.75 .16 calc(var(--attn-h, 0) + 80));
  --attn-c3: oklch(.75 .16 calc(var(--attn-h, 0) + 140));
  --attn-c4: oklch(.75 .16 calc(var(--attn-h, 0) + 200));
  --attn-c5: oklch(.75 .16 calc(var(--attn-h, 0) + 260));
  --attn-c6: oklch(.75 .16 calc(var(--attn-h, 0) + 320));
  --attn-ring: linear-gradient(115deg, var(--attn-c1), var(--attn-c2), var(--attn-c3), var(--attn-c4), var(--attn-c5), var(--attn-c6), var(--attn-c1));
  --attn-lift: 0 1px 2px rgba(28, 27, 31, .12), 0 10px 24px -12px rgba(28, 27, 31, .42);

  /* The documents shelf: a darker tray for files, never the ink of attention, never a gradient. */
  --shelf: #2C2B31;

  /* Type: five sizes, three weights, one ink. See the text styles below. */
  --font: "Hanken Grotesk", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  --mono: "Geist Mono", ui-monospace, "SF Mono", Menlo, monospace;
  --fs-meta: 12px;
  --fs-body: 14px;
  --fs-heading: 16px;
  --fs-title: 20px;
  --fs-figure: 32px;

  /* Space: 4px base */
  --space-1: 4px;  --space-2: 8px;  --space-3: 12px; --space-4: 16px; --space-5: 20px;
  --space-6: 24px; --space-8: 32px; --space-10: 40px; --space-12: 48px; --space-16: 64px;

  /* Radius */
  --r-1: 6px;    /* tiny marks, kbd */
  --r-2: 10px;   /* inputs, rows */
  --r-3: 14px;   /* cards, menus, popovers, callouts, the decision */
  --r-4: 18px;   /* panels, tiles, drawers, the review queue */
  --r-5: 24px;   /* modals */
  --r-pill: 999px;

  /* Elevation. Flat at rest. Floating layers float. What waits for a person carries its own lift (--attn-lift). */
  --ring: 0 0 0 1px rgba(28, 27, 31, .06);
  --shadow-1: 0 1px 2px rgba(28, 27, 31, .08), 0 0 0 1px rgba(28, 27, 31, .05);
  --shadow-2: 0 8px 20px -8px rgba(28, 27, 31, .16), 0 2px 4px rgba(28, 27, 31, .04), 0 0 0 1px rgba(28, 27, 31, .06);
  --shadow-3: 0 18px 40px -12px rgba(28, 27, 31, .22), 0 4px 10px -4px rgba(28, 27, 31, .08), 0 0 0 1px rgba(28, 27, 31, .06);
  --shadow-4: 0 40px 80px -20px rgba(28, 27, 31, .30), 0 10px 24px -10px rgba(28, 27, 31, .12), 0 0 0 1px rgba(28, 27, 31, .06);

  /* Motion: quick, soft, never bouncy. Repeating motion means an agent is working. */
  --ease: cubic-bezier(.2, .7, .2, 1);
  --ease-io: cubic-bezier(.6, 0, .25, 1);
  --dur-1: 120ms;
  --dur-2: 200ms;
  --dur-3: 320ms;
  --breath: 2.8s;
  --turn: 12s;

  /* Layout */
  --bar-h: 60px;
  --page-max: 1280px;
  --page-pad: 40px;
  --gap: 16px;
}

/* Earlier names, remapped to the round-4 meaning. Use the names above in new code. They are declared again inside
   the dark scopes (.attn, the documents shelf), so they follow the flipped tokens there. */
:root, .attn, .docs {
  --bg-2: var(--fill);
  --bg-3: var(--fill-2);
  --surface-2: var(--surface);          /* no insets inside a panel */
  --surface-hover: var(--hover);
  --line-solid: #E6E5E1;
  --ink-2: var(--ink);                  /* every text token is the ink */
  --ink-3: var(--ink);
  --ink-4: var(--stroke);               /* strokes only */
  --ink-5: var(--stroke-faint);
  --agent: var(--ink);                  /* agents are ink; work shows as motion */
  --agent-strong: var(--ink);
  --agent-bright: var(--ink);
  --agent-soft: var(--stroke);
  --agent-tint: var(--fill);
  --agent-tint-2: rgba(28, 27, 31, .10);
  --human: var(--accent);               /* a fill that signals: the count badge */
  --human-strong: var(--accent-strong);
  --human-bright: var(--accent);        /* earlier the needs-you marker; that is the attention mark now */
  --human-ink: var(--ink);              /* words stay ink */
  --human-tint: transparent;            /* no washes */
  --human-tint-2: transparent;
  --chat-room: var(--surface);          /* the conversation sits on the panel */
  --chat-theirs: var(--surface);        /* theirs: white with a hairline */
  --chat-theirs-ink: var(--ink);
  --chat-ours: var(--fill-solid);       /* ours: the neutral fill */
  --chat-ours-ink: var(--ink);
  --chat-ours-meta: var(--ink);
  --chat-outbox-edge: var(--stroke);    /* in the outbox: dashed */
  --chat-team-room: var(--surface);
  --chat-team: var(--surface);
  --chat-team-me: var(--fill-solid);
  --chat-team-ink: var(--ink);
  --ok: var(--ink);
  --ok-tint: var(--fill);
  --danger: var(--ink);
  --danger-tint: var(--fill);
  --src-writing: var(--ink);
  --src-stated: var(--ink);
  --src-estimate: var(--ink);
  --src-unknown: var(--ink);
  --src-disagree: var(--ink);
  --t-xs: var(--fs-meta);
  --t-sm: var(--fs-body);
  --t-md: var(--fs-body);
  --t-lg: var(--fs-heading);
  --t-xl: var(--fs-title);
  --t-2xl: var(--fs-figure);
  --t-3xl: var(--fs-figure);
  --t-num: var(--fs-figure);
}
@media (max-width: 1360px) { :root { --page-pad: 32px; } }

/* ---------- Base ---------- */
*, *::before, *::after { box-sizing: border-box; }
[hidden] { display: none !important; } /* components set display; `hidden` must still hide them */
html, body { height: 100%; }
body {
  margin: 0; background: var(--bg); color: var(--ink);
  font: 400 var(--fs-body)/1.5 var(--font);
  -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-rendering: optimizeLegibility;
  overflow: hidden;
}
button, input, select, textarea { font: inherit; color: inherit; }
button { cursor: pointer; }
a { color: inherit; }
img, svg { display: block; }
h1, h2, h3, h4, p { margin: 0; }
::selection { background: rgba(28, 27, 31, .14); color: var(--ink); }
:focus { outline: none; }
:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
* { scrollbar-width: thin; scrollbar-color: rgba(28, 27, 31, .18) transparent; }
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-thumb { background: rgba(28, 27, 31, .16); border-radius: 10px; border: 3px solid transparent; background-clip: content-box; }
::-webkit-scrollbar-track { background: transparent; }

/* Icons: 20-unit grid, 1.5 stroke, currentColor (ink) */
.ic { width: 18px; height: 18px; flex: none; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
.ic-12 { width: 12px; height: 12px; }
.ic-14 { width: 14px; height: 14px; }
.ic-16 { width: 16px; height: 16px; }
.ic-20 { width: 20px; height: 20px; }
.ic-24 { width: 24px; height: 24px; }

/* ==========================================================================
   Text styles — the only six, all in ink (plus code for machine text)
   ========================================================================== */
.t-figure  { font-size: var(--fs-figure);  font-weight: 300; line-height: 1.1; font-variant-numeric: tabular-nums; }  /* the greeting, figures that matter */
.t-title   { font-size: var(--fs-title);   font-weight: 500; line-height: 1.3; }   /* view titles, a site's name, modal titles */
.t-heading { font-size: var(--fs-heading); font-weight: 500; line-height: 1.4; }   /* panel and section headings, the question in a decision */
.t-strong  { font-size: var(--fs-body);    font-weight: 500; line-height: 1.45; }  /* names, labels, values, buttons, row titles */
.t-body    { font-size: var(--fs-body);    font-weight: 400; line-height: 1.5; }   /* everything you read, emails included */
.t-meta    { font-size: var(--fs-meta);    font-weight: 400; line-height: 1.4; }   /* times, sources, counts, chips */
.t-code    { font-family: var(--mono); font-size: var(--fs-meta); font-weight: 400; line-height: 1.6; } /* agent chains, tool calls, keys, ids */
.unit { font-size: var(--fs-body); font-weight: 500; margin-left: .2em; }        /* "MW" after a figure: the Strong style */

/* Earlier utilities, mapped onto the styles above */
.t-xs { font-size: var(--fs-meta); line-height: 1.4; }
.t-sm, .t-md { font-size: var(--fs-body); line-height: 1.5; }
.t-lg { font-size: var(--fs-heading); line-height: 1.45; }
.t-xl, .t-2xl { font-size: var(--fs-title); font-weight: 500; line-height: 1.3; }
.t-3xl, .t-num { font-size: var(--fs-figure); font-weight: 300; line-height: 1.1; font-variant-numeric: tabular-nums; }
.strong, .medium { font-weight: 500; }
.muted, .subtle, .human-text, .agent-text { color: var(--ink); } /* no quieter inks: hierarchy is size and weight */
.mono { font-family: var(--mono); font-size: var(--fs-meta); }
.tnum { font-variant-numeric: tabular-nums; }
.truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; } /* never on names, dates or reasons */
.clamp-2 { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; } /* prose that is the content: two lines at most */
.nowrap { white-space: nowrap; } /* a name, a date or a figure stays whole on its line */
/* UI.seq(parts): a meta line whose parts wrap whole. The "·" sits in the gap before a part; a part that starts a
   line pushes its "·" outside the box, where it is clipped, so a separator never ends or starts a line. */
.seq { display: flex; flex-wrap: wrap; column-gap: .8em; min-width: 0; overflow: hidden; }
.seq > span { position: relative; min-width: 0; overflow-wrap: anywhere; }
.seq > span + span::before { content: "·"; position: absolute; right: 100%; width: .8em; text-align: center; }
.label { font-size: var(--fs-body); font-weight: 500; }
.sep-dot::before { content: "·"; margin: 0 .45em; }
.visually-hidden { position: absolute !important; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

/* Layout helpers (keep view CSS for real layout) */
.row { display: flex; align-items: center; gap: var(--space-2); min-width: 0; }
.col { display: flex; flex-direction: column; gap: var(--space-2); min-width: 0; }
.grow { flex: 1 1 auto; min-width: 0; }
.spacer { flex: 1 1 auto; }
.hr { height: 1px; background: var(--line); border: 0; margin: var(--space-4) 0; }

/* ==========================================================================
   Shell
   ========================================================================== */
.app { height: 100vh; display: grid; grid-template-rows: var(--bar-h) minmax(0, 1fr); }
.bar {
  position: relative; z-index: 30; height: var(--bar-h);
  display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: var(--space-4);
  padding: 0 20px;
}
.bar-left, .bar-right { display: flex; align-items: center; gap: var(--space-2); min-width: 0; }
.bar-right { justify-content: flex-end; }
.brand { display: inline-flex; align-items: center; gap: 10px; height: 36px; padding: 0 10px 0 6px; border-radius: var(--r-pill); text-decoration: none; color: var(--ink); }
.brand-mark { width: 22px; height: 22px; color: var(--ink); }
.brand-name { font-size: var(--fs-heading); font-weight: 500; line-height: 1; }

.nav { display: flex; align-items: center; gap: 2px; padding: 3px; background: var(--fill); border-radius: var(--r-pill); }
.nav-item {
  position: relative; display: inline-flex; align-items: center; gap: 8px; height: 34px; padding: 0 16px;
  border-radius: var(--r-pill); color: var(--ink); text-decoration: none; font-weight: 500; font-size: var(--fs-body);
  transition: background var(--dur-2) var(--ease), box-shadow var(--dur-2) var(--ease);
}
.nav-item:hover { background: rgba(255, 255, 255, .55); }
.nav-item.is-active { background: var(--surface); box-shadow: var(--shadow-1); }
.nav-item .ic { width: 16px; height: 16px; }

/* Count badge. Neutral by default; .count-human is the dark-red count of what waits for you. */
.count {
  display: inline-grid; place-items: center; min-width: 20px; height: 20px; padding: 0 6px; border-radius: var(--r-pill);
  font-size: var(--fs-meta); font-weight: 400; font-variant-numeric: tabular-nums; line-height: 1;
  background: var(--fill); color: var(--ink);
}
.count-human { background: var(--accent); color: var(--on-ink); }
.count-agent { background: var(--fill); color: var(--ink); }
/* Once you are in the Inbox its review queue carries the count: the tab badge goes quiet. */
.nav-item.is-active .count-human { background: var(--fill); color: var(--ink); }

.mode-btn {
  display: inline-flex; align-items: center; gap: 8px; height: 36px; padding: 0 14px 0 12px; border-radius: var(--r-pill);
  border: 0; background: transparent; box-shadow: inset 0 0 0 1px var(--line-strong); color: var(--ink); font-weight: 500;
  text-decoration: none; transition: background var(--dur-1) var(--ease), box-shadow var(--dur-1) var(--ease);
}
.mode-btn:hover { background: var(--surface); box-shadow: inset 0 0 0 1px var(--line-strong), var(--shadow-1); }
.mode-btn .ic { width: 16px; height: 16px; }

/* A phone-width window: the mark without its name, Grid-first as its glyph, Settings in the account menu, and the
   views as a row that scrolls sideways. Nothing else changes. */
@media (max-width: 760px) {
  .bar { grid-template-columns: auto minmax(0, 1fr) auto; gap: var(--space-2); padding: 0 10px; }
  .bar .brand { padding: 0 6px; }
  .bar .brand-name, .bar-right > [data-nav="settings"] { display: none; }
  .mode-btn { gap: 0; padding: 0 10px; font-size: 0; }
  .nav { justify-self: center; max-width: 100%; overflow-x: auto; scrollbar-width: none; }
  .nav::-webkit-scrollbar { display: none; }
  .nav-item { flex: none; padding: 0 12px; }
}

.main { position: relative; min-height: 0; overflow: hidden; }
.view { position: absolute; inset: 0; overflow: auto; }
.view.is-entering { animation: view-in var(--dur-3) var(--ease); }
.page { max-width: calc(var(--page-max) + var(--page-pad) * 2); margin: 0 auto; padding: 8px var(--page-pad) 40px; }

/* Grid-first is its own mode: the map is the room, the bar floats on it */
.app[data-mode="grid"] { grid-template-rows: minmax(0, 1fr); }
.app[data-mode="grid"] .bar { position: absolute; inset: 0 0 auto 0; display: flex; justify-content: space-between; padding: 12px 16px 0; pointer-events: none; }
.app[data-mode="grid"] .bar > * { pointer-events: auto; }
.app[data-mode="grid"] .bar-right { pointer-events: none; }
.app[data-mode="grid"] .bar-right > .mode-exit { pointer-events: auto; }
.app[data-mode="grid"] .main { grid-row: 1; }
.mode-title { display: none; align-items: center; gap: 10px; height: 44px; padding: 0 16px 0 10px; border-radius: var(--r-pill); background: rgba(255, 255, 255, .9); backdrop-filter: blur(14px); box-shadow: var(--shadow-2); }
.mode-title .brand { padding: 0 6px; height: 30px; }
.mode-title .mode-name { font-weight: 500; padding-left: 12px; border-left: 1px solid var(--line-strong); line-height: 18px; }
.app[data-mode="grid"] .bar-left > .brand, .app[data-mode="grid"] .nav, .app[data-mode="grid"] .bar-right > :not(.mode-exit) { display: none; }
.app[data-mode="grid"] .mode-title { display: inline-flex; }
.app:not([data-mode="grid"]) .mode-exit { display: none; }
.app[data-mode="grid"] .mode-exit { display: inline-flex; background: rgba(255, 255, 255, .9); backdrop-filter: blur(14px); box-shadow: var(--shadow-2); height: 44px; padding: 0 18px 0 14px; }

/* Signing in is a page of its own: no bar, the view fills the window */
.app[data-mode="auth"] { grid-template-rows: minmax(0, 1fr); }
/* While the first answer is on its way: the mark alone, still, in the middle (and what went wrong, if it did) */
.boot { position: absolute; inset: 0; display: grid; place-items: center; padding: 40px; }
.boot > .brand-mark { width: 32px; height: 32px; animation: rise var(--dur-3) var(--ease) both; }

/* Placeholder for views that are not built yet */
.placeholder { min-height: 100%; display: grid; place-items: center; padding: 40px; }
.placeholder-inner { max-width: 440px; text-align: center; display: flex; flex-direction: column; align-items: center; gap: 12px; animation: rise var(--dur-3) var(--ease); }
.placeholder-mark { width: 56px; height: 56px; border-radius: 18px; background: var(--surface); box-shadow: var(--ring); display: grid; place-items: center; margin-bottom: 4px; }
.placeholder-mark .ic { width: 24px; height: 24px; }
.placeholder h1 { font-size: var(--fs-title); font-weight: 500; line-height: 1.3; }
.placeholder p { font-size: var(--fs-body); line-height: 1.5; }
.placeholder .note { font-size: var(--fs-meta); }

/* ==========================================================================
   Surfaces
   ========================================================================== */
.tile {
  position: relative; display: flex; flex-direction: column; min-width: 0; min-height: 0;
  background: var(--surface); border-radius: var(--r-4); padding: 20px 24px; box-shadow: var(--ring);
}
.tile-head { display: flex; align-items: center; gap: 12px; min-width: 0; min-height: 32px; }
.tile-heading { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.tile-title { font-size: var(--fs-heading); font-weight: 500; line-height: 1.4; }
.tile-sub { font-size: var(--fs-body); line-height: 1.45; }
.tile-actions { margin-left: auto; display: flex; align-items: center; gap: 6px; flex: none; }
.tile-foot { margin-top: auto; display: flex; align-items: center; gap: 10px; padding-top: 16px; min-width: 0; }
.tile.is-link { cursor: pointer; transition: box-shadow var(--dur-2) var(--ease); }
.tile.is-link:hover { box-shadow: var(--shadow-2); }

.card { background: var(--surface); border-radius: var(--r-3); box-shadow: var(--ring); padding: 14px 16px; }
.well { border-radius: var(--r-3); padding: 14px 16px; box-shadow: inset 0 0 0 1px var(--line); }

/* ==========================================================================
   Attention — the one treatment for what waits for a person (FEEDBACK-3, rule 1)
   .attn on the card, row, line or button that waits: an ink surface, white words, a fine RGB gradient border
   whose hue drifts slowly, a soft lift. No extra markup. Nothing else gets it: the documents shelf is dark too,
   but never ink and never ringed.
   ========================================================================== */
/* One hue for the whole page, animated on the root while something waits: every .attn, every attention mark and
   every gradient made from --attn-c1…6 drift on the same clock, and no element's own animation is touched.
   Ten steps a second (a 1.2° step is invisible); still under prefers-reduced-motion. */
@property --attn-h { syntax: "<number>"; inherits: true; initial-value: 0; }
@property --attn-bg { syntax: "<color>"; inherits: false; initial-value: #1C1B1F; }
@keyframes attn-drift { to { --attn-h: 360; } }
:root:has(.attn, .dot-human, .toast-human) { animation: attn-drift var(--attn-period) steps(300) infinite; }
@media (prefers-reduced-motion: reduce) { :root:has(.attn, .dot-human, .toast-human) { animation: none; } }

/* Dark scopes: inside .attn and on the documents shelf (.docs) the surface is dark, and the same tokens flip,
   so every shared piece inside (avatars, marks, buttons, chips, stages, counts, progress, icons) comes out
   inverted with no CSS of its own. Words keep one ink: white. */
.attn, .docs {
  --ink: #FFFFFF;
  --ink-hover: #E6E5E9;
  --on-ink: #1C1B1F;
  --surface: var(--dark);
  --bg: var(--dark);
  --press: var(--dark-press);
  --fill: rgba(255, 255, 255, .10);
  --fill-2: rgba(255, 255, 255, .17);
  --track: rgba(255, 255, 255, .2);
  --track-hover: rgba(255, 255, 255, .28);
  --fill-solid: #3A393F;
  --hover: rgba(255, 255, 255, .06);
  --line: rgba(255, 255, 255, .13);
  --line-strong: rgba(255, 255, 255, .26);
  --line-hover: rgba(255, 255, 255, .44);
  --line-solid: #3A393F;
  --stroke: rgba(255, 255, 255, .5);
  --stroke-faint: rgba(255, 255, 255, .24);
  --accent: var(--accent-on-ink);
  --agent-tint-2: rgba(255, 255, 255, .14);
  color: var(--ink);
}
.attn ::selection, .docs ::selection { background: rgba(255, 255, 255, .28); color: var(--ink); }
.attn .count-human { color: #FFFFFF; }

/* The treatment itself. Your CSS keeps radius, padding and layout; background, border, colour and shadow are
   held here (!important), so a view's own hover or tone can never take it away. */
.attn {
  --attn-bg: var(--attn-fill);
  --dark: var(--attn-bg);
  --dark-press: #34333A;
  color: var(--ink) !important;
  border: var(--attn-w) solid transparent !important;
  background: linear-gradient(var(--attn-bg), var(--attn-bg)) padding-box, var(--attn-ring) border-box !important;
  box-shadow: var(--attn-lift) !important;
}
/* Under the pointer and pressed: links and buttons by themselves, anything else with .attn-hover. */
:is(a, button, label, [role="button"], [tabindex]).attn:hover, .attn.attn-hover:hover { --attn-bg: var(--attn-fill-hover); }
:is(a, button, label, [role="button"], [tabindex]).attn:active, .attn.attn-hover:active { --attn-bg: var(--attn-fill-press); }
.attn:focus-visible { outline: 2px solid var(--attn-fill); outline-offset: 2px; }

/* ==========================================================================
   Buttons — ink is the action
   ========================================================================== */
.btn {
  --h: 36px;
  display: inline-flex; align-items: center; justify-content: center; gap: 8px; height: var(--h); padding: 0 16px;
  border: 0; border-radius: var(--r-pill); background: var(--surface); color: var(--ink);
  box-shadow: inset 0 0 0 1px var(--line-strong);
  font: 500 var(--fs-body)/1 var(--font); white-space: nowrap; text-decoration: none; user-select: none;
  transition: background var(--dur-1) var(--ease), box-shadow var(--dur-1) var(--ease), color var(--dur-1) var(--ease), transform var(--dur-1) var(--ease);
}
.btn:hover { background: var(--press); box-shadow: inset 0 0 0 1px var(--line-hover); }
.btn:active { transform: translateY(.5px); }
.btn .ic { width: 16px; height: 16px; margin: 0 -2px; }
/* Primary: ink. One per area. The recommended choice of a decision is primary too. */
.btn-primary, .btn-human { background: var(--ink); color: var(--on-ink); box-shadow: none; }
.btn-primary:hover, .btn-human:hover { background: var(--ink-hover); box-shadow: none; }
.btn-agent { background: var(--surface); color: var(--ink); }
.btn-ghost { background: transparent; box-shadow: none; }
.btn-ghost:hover { background: var(--fill); box-shadow: none; }
/* Destructive: plain until you mean it. The confirmation names what is lost. */
.btn-danger:hover { background: var(--ink); color: var(--on-ink); box-shadow: none; }
.btn-sm { --h: 30px; padding: 0 12px; gap: 6px; }
.btn-sm .ic { width: 14px; height: 14px; }
.btn-lg { --h: 44px; padding: 0 22px; gap: 10px; }
.btn-block { width: 100%; }
.btn[disabled], .btn.is-disabled { opacity: .4; pointer-events: none; }
.btn-link { display: inline-flex; align-items: center; gap: 4px; flex: none; border: 0; background: none; padding: 0; color: var(--ink); font-weight: 500; font-size: var(--fs-body); white-space: nowrap; text-decoration: none; text-underline-offset: 3px; text-decoration-thickness: 1px; }
.btn-link:hover { text-decoration: underline; text-decoration-color: var(--stroke); }
.btn-link .ic { width: 14px; height: 14px; transition: transform var(--dur-2) var(--ease); }
.btn-link:hover .ic { transform: translateX(2px); }
/* Send: the one send button (the inbox composer, the prioritizer chat). Label first, then the paper plane.
   Ink when there is something to send; a quiet pill when there is not (a disabled control fades, like every other). */
.btn-send { --h: 32px; padding: 0 14px 0 16px; gap: 7px; background: var(--ink); color: var(--on-ink); box-shadow: none; }
.btn-send:hover { background: var(--ink-hover); box-shadow: none; }
.btn-send .ic { width: 14px; height: 14px; margin: 0 -1px 0 0; }
.btn-send[disabled], .btn-send.is-disabled { background: rgba(28, 27, 31, .15); color: var(--ink); box-shadow: none; } /* at .4: the fill */

.icon-btn {
  --s: 32px;
  width: var(--s); height: var(--s); flex: none; display: inline-grid; place-items: center; padding: 0;
  border: 0; border-radius: var(--r-pill); background: transparent; color: var(--ink); text-decoration: none;
  transition: background var(--dur-1) var(--ease), box-shadow var(--dur-1) var(--ease);
}
.icon-btn:hover { background: var(--fill); }
.icon-btn.is-active, .icon-btn[aria-expanded="true"] { background: var(--fill-2); }
.icon-btn .ic { width: 18px; height: 18px; }
.icon-btn-sm { --s: 28px; }
.icon-btn-sm .ic { width: 16px; height: 16px; }
.icon-btn-lg { --s: 40px; }
.icon-btn-lg .ic { width: 20px; height: 20px; }
.icon-btn-outline { background: var(--surface); box-shadow: inset 0 0 0 1px var(--line-strong); }
.icon-btn-outline:hover { background: var(--press); }
.icon-btn-solid { background: var(--ink); color: var(--on-ink); }
.icon-btn-solid:hover { background: var(--ink-hover); }
.icon-btn[disabled] { opacity: .4; pointer-events: none; }

/* Zoom: the one control for a map canvas (Map, Grid-first). A vertical white stack, bottom right:
   the whole world, a hairline, then in and out. Views move it with their own class if a panel is in the way. */
.zoomctl { position: absolute; right: 16px; bottom: 16px; z-index: 5; display: flex; flex-direction: column; align-items: center; gap: 2px; padding: 4px; border-radius: var(--r-pill); background: var(--surface); box-shadow: var(--shadow-2); }
.zoomctl-btn { position: relative; width: 36px; height: 36px; flex: none; display: grid; place-items: center; padding: 0; border: 0; border-radius: 50%; background: transparent; color: var(--ink); transition: background var(--dur-1) var(--ease), opacity var(--dur-2) var(--ease); }
.zoomctl-btn:hover { background: var(--fill); }
.zoomctl-btn:active { background: var(--fill-2); }
.zoomctl-btn .ic { width: 18px; height: 18px; }
.zoomctl-btn[data-zoom="world"] { margin-bottom: 5px; }
.zoomctl-btn[data-zoom="world"]::after { content: ""; position: absolute; left: 10px; right: 10px; bottom: -4px; height: 1px; background: var(--line); pointer-events: none; }
.zoomctl-btn[disabled], .zoomctl-btn.is-off { opacity: .4; pointer-events: none; }

/* ==========================================================================
   Controls — one language: on is ink, off is a quiet track, the choice is raised
   ========================================================================== */
.switch {
  --w: 40px; --h: 24px; --k: 18px;
  position: relative; flex: none; width: var(--w); height: var(--h); padding: 0; border: 0; border-radius: var(--r-pill);
  background: var(--track); transition: background var(--dur-2) var(--ease);
}
.switch::after {
  content: ""; position: absolute; top: calc((var(--h) - var(--k)) / 2); left: calc((var(--h) - var(--k)) / 2);
  width: var(--k); height: var(--k); border-radius: 50%; background: #fff;
  box-shadow: 0 1px 3px rgba(28, 27, 31, .22), 0 0 0 .5px rgba(28, 27, 31, .06);
  transition: transform var(--dur-2) var(--ease), background var(--dur-2) var(--ease);
}
.switch:hover { background: var(--track-hover); }
.switch[aria-checked="true"] { background: var(--ink); }
.switch[aria-checked="true"]:hover { background: var(--ink-hover); }
/* On: the thumb takes the words' colour on ink (white on the page, ink inside a dark scope, where the track is white) */
.switch[aria-checked="true"]::after { background: var(--on-ink); transform: translateX(calc(var(--w) - var(--h))); }
.switch-sm { --w: 32px; --h: 20px; --k: 14px; }
.switch[disabled] { opacity: .4; pointer-events: none; }
.switch-field { display: flex; align-items: center; gap: 12px; }

/* Segmented control: equal segments on a quiet track, the choice raised in white.  --n = segments, --i = active index */
.seg {
  --n: 2; --i: 0; --h: 34px;
  position: relative; display: inline-grid; grid-auto-flow: column; grid-auto-columns: 1fr; align-items: stretch;
  height: var(--h); padding: 3px; border-radius: var(--r-pill); background: var(--fill); isolation: isolate;
}
.seg-thumb {
  position: absolute; z-index: -1; top: 3px; bottom: 3px; left: 3px; width: calc((100% - 6px) / var(--n));
  border-radius: var(--r-pill); background: var(--surface); box-shadow: var(--shadow-1);
  transform: translateX(calc(var(--i) * 100%)); transition: transform var(--dur-2) var(--ease), background var(--dur-2) var(--ease), box-shadow var(--dur-2) var(--ease);
}
.seg > button {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px; padding: 0 14px; border: 0; background: none;
  border-radius: var(--r-pill); color: var(--ink); font-weight: 500; font-size: var(--fs-body); white-space: nowrap;
  transition: color var(--dur-2) var(--ease);
}
.seg > button .ic { width: 14px; height: 14px; }
.seg-sm { --h: 28px; }
.seg-sm > button { padding: 0 10px; }
.seg-lg { --h: 40px; }
.seg-lg > button { padding: 0 18px; }

/* On / Drafts / Off: the thumb carries the state. On is ink (like a switch that is on), Drafts is ringed, Off is plain. */
.tri { --n: 3; --h: 30px; }
.tri > button { padding: 0 11px; min-width: 56px; }
.tri[data-value="on"] .seg-thumb { background: var(--ink); box-shadow: none; }
.tri[data-value="on"] > button[aria-checked="true"] { color: var(--on-ink); }
.tri[data-value="drafts"] .seg-thumb { background: var(--surface); box-shadow: inset 0 0 0 1.5px var(--ink), var(--shadow-1); }

/* Tabs: rooms and content. Ink words, the open one underlined in ink. */
.tabs { display: flex; align-items: center; gap: 24px; min-width: 0; }
.tab {
  position: relative; display: inline-flex; align-items: center; gap: 8px; height: 40px; padding: 0; border: 0; background: none;
  color: var(--ink); font-weight: 500; font-size: var(--fs-body); white-space: nowrap; text-decoration: none;
}
.tab .ic { width: 16px; height: 16px; }
.tab::after { content: ""; position: absolute; left: 0; right: 0; bottom: -1px; height: 2px; border-radius: 2px; background: var(--ink); transform: scaleX(0); transition: transform var(--dur-2) var(--ease); }
.tab:hover::after { transform: scaleX(1); background: var(--line-strong); }
.tab.is-active::after, .tab[aria-selected="true"]::after { transform: scaleX(1); background: var(--ink); }
.tab .count { margin-left: 2px; }
.tab .av { --s: 20px; }

/* Checkbox and radio: a ring that fills with ink. */
.check, .radio { display: inline-flex; align-items: center; gap: 10px; cursor: pointer; font-size: var(--fs-body); }
.check input, .radio input {
  appearance: none; -webkit-appearance: none; flex: none; width: 18px; height: 18px; margin: 0; background: var(--surface);
  box-shadow: inset 0 0 0 1.5px var(--stroke); transition: background var(--dur-1), box-shadow var(--dur-1); cursor: pointer;
}
.check input { border-radius: 5px; }
.radio input { border-radius: 50%; }
.check input:hover, .radio input:hover { box-shadow: inset 0 0 0 1.5px var(--ink); }
.check input:checked { background: var(--ink) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='none' stroke='white' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5.5 10.5l3 3 6-7'/%3E%3C/svg%3E") center / 14px no-repeat; box-shadow: none; }
.radio input:checked { background: radial-gradient(circle, var(--ink) 0 4px, var(--surface) 4.5px); box-shadow: inset 0 0 0 1.5px var(--ink); }
.check input:disabled, .radio input:disabled { opacity: .4; cursor: default; }

/* Progress: a quiet track, an ink bar. */
.progress { --v: 50%; height: 4px; border-radius: 4px; background: var(--fill-2); overflow: hidden; }
.progress > i { display: block; width: var(--v); height: 100%; border-radius: 4px; background: var(--ink); transition: width var(--dur-3) var(--ease); }
.progress-agent > i, .progress-human > i { background: var(--ink); }

/* ==========================================================================
   Inputs
   ========================================================================== */
.field { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.field-label { display: inline-flex; align-items: center; gap: 6px; font-size: var(--fs-body); font-weight: 500; }
.field-label .ic { width: 14px; height: 14px; }
.field-hint { font-size: var(--fs-meta); line-height: 1.45; }
.field-row { display: flex; align-items: center; justify-content: space-between; gap: 16px; }
.input, .select, .textarea {
  width: 100%; height: 38px; padding: 0 12px; border: 0; border-radius: var(--r-2);
  background: var(--surface); color: var(--ink); box-shadow: inset 0 0 0 1px var(--line-strong);
  font: 400 var(--fs-body)/1.4 var(--font); transition: box-shadow var(--dur-1) var(--ease), background var(--dur-1) var(--ease);
}
.input::placeholder, .textarea::placeholder { color: var(--ink); opacity: .42; } /* the one place text is lighter */
.input:hover, .select:hover, .textarea:hover { box-shadow: inset 0 0 0 1px rgba(28, 27, 31, .26); }
.input:focus, .select:focus, .textarea:focus { outline: none; box-shadow: inset 0 0 0 1px var(--ink), 0 0 0 3px rgba(28, 27, 31, .08); }
.input-quiet { box-shadow: none; background: var(--fill); }
.input-quiet:hover { box-shadow: none; background: var(--fill-2); }
.textarea { height: auto; min-height: 96px; padding: 10px 12px; line-height: 1.55; resize: vertical; display: block; }
.textarea.mono { font-family: var(--mono); font-size: var(--fs-meta); line-height: 1.65; }
.select {
  appearance: none; -webkit-appearance: none; padding-right: 34px; cursor: pointer; text-overflow: ellipsis;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='none' stroke='%231C1B1F' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 8l4 4 4-4'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 10px center; background-size: 16px;
}
/* On a dark surface (.attn, the documents shelf) its chevron and its list turn light, like its words */
.attn .select, .docs .select {
  color-scheme: dark;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='none' stroke='%23FFFFFF' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 8l4 4 4-4'/%3E%3C/svg%3E");
}
.input-wrap { position: relative; display: flex; align-items: center; }
.input-wrap > .ic { position: absolute; left: 12px; width: 16px; height: 16px; pointer-events: none; }
.input-wrap > .input { padding-left: 36px; }
.input-sm, .select-sm { height: 32px; }
/* A field that cannot be changed here fades, like every disabled control */
.input:disabled, .select:disabled, .textarea:disabled { opacity: .4; cursor: default; }

.stepper { display: inline-flex; align-items: center; align-self: flex-start; flex: none; height: 38px; padding: 0 3px; border-radius: var(--r-pill); background: var(--surface); box-shadow: inset 0 0 0 1px var(--line-strong); }
.stepper > button { width: 32px; height: 32px; border: 0; background: none; border-radius: 50%; display: grid; place-items: center; color: var(--ink); transition: background var(--dur-1); }
.stepper > button:hover { background: var(--fill); }
.stepper > button .ic { width: 16px; height: 16px; }
.stepper > output { min-width: 30px; text-align: center; font-weight: 500; font-variant-numeric: tabular-nums; }
/* Shown, not changed here (the agents' settings for someone who is not an admin): the control fades */
.stepper.is-disabled { opacity: .4; }
.stepper > button[disabled] { cursor: default; }
.stepper > button[disabled]:hover { background: none; }

/* Composer-style token input (To / Cc) */
.tokens { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; min-height: 38px; padding: 5px 8px; border-radius: var(--r-2); box-shadow: inset 0 0 0 1px var(--line-strong); background: var(--surface); }
.tokens > input { flex: 1; min-width: 80px; border: 0; outline: 0; background: none; height: 26px; }

/* ==========================================================================
   Floating layers: menu, popover, tooltip, modal, drawer, toast
   Layers: bar 30 · scrim 50 · modal/drawer 51 · menu/popover 70 · tooltip 90 · toasts 95
   ========================================================================== */
.menu {
  position: fixed; z-index: 70; min-width: 220px; max-width: 320px; padding: 6px; border-radius: var(--r-3);
  background: var(--surface); box-shadow: var(--shadow-3); animation: pop-in var(--dur-2) var(--ease);
}
.menu-item {
  display: flex; align-items: center; gap: 10px; width: 100%; min-height: 36px; padding: 0 10px; border: 0; border-radius: 9px;
  background: none; color: var(--ink); font-size: var(--fs-body); text-align: left; text-decoration: none;
}
.menu-item:hover, .menu-item.is-focus, .menu-item:focus-visible { background: var(--fill); outline: none; }
.menu-item > .ic { width: 16px; height: 16px; }
.menu-item .menu-meta { margin-left: auto; font-size: var(--fs-meta); }
.menu-item .menu-check { margin-left: auto; display: grid; }
.menu-item.is-disabled { opacity: .4; pointer-events: none; }
/* A setting the item turns on and off (Debug mode): its switch on the right */
.menu-item .menu-switch { margin-left: auto; pointer-events: none; }
.menu-sep { height: 1px; background: var(--line); margin: 6px 4px; }
.menu-label { padding: 8px 10px 4px; font-size: var(--fs-meta); }
.menu-text { padding: 8px 10px; font-size: var(--fs-meta); line-height: 1.45; }

.popover {
  position: fixed; z-index: 70; width: max-content; max-width: 380px; padding: 16px 18px; border-radius: var(--r-3);
  background: var(--surface); box-shadow: var(--shadow-3); animation: pop-in var(--dur-2) var(--ease);
}
.popover-title { font-weight: 500; font-size: var(--fs-body); margin-bottom: 4px; }
.popover-text { font-size: var(--fs-body); line-height: 1.5; }

/* Set aside: why, and when to look again (UI.askSetAside) */
.aside-pop { padding: 18px 18px 16px; }
.aside-form { display: flex; flex-direction: column; gap: 14px; }
.aside-form .popover-title { margin: 0; font-size: var(--fs-heading); line-height: 1.4; }
.aside-form .textarea { min-height: 64px; }
.aside-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: -6px; }
.aside-optional { margin-left: 4px; font-size: var(--fs-meta); font-weight: 400; }
.aside-foot { display: flex; justify-content: flex-end; gap: 8px; padding-top: 2px; }

.tooltip {
  position: fixed; z-index: 90; max-width: 280px; padding: 6px 10px; border-radius: 9px; pointer-events: none;
  background: var(--ink); color: var(--on-ink); font-size: var(--fs-meta); font-weight: 500; line-height: 1.4;
  box-shadow: 0 8px 20px -8px rgba(28, 27, 31, .4); animation: fade-in var(--dur-1) var(--ease);
}
.tooltip .tip-sub { font-weight: 400; }

.scrim { position: fixed; inset: 0; z-index: 50; background: rgba(28, 27, 31, .22); backdrop-filter: blur(2px); animation: fade-in var(--dur-3) var(--ease); }
.scrim.is-light { background: rgba(28, 27, 31, .08); backdrop-filter: none; }
.scrim.is-leaving { animation: fade-out var(--dur-2) var(--ease) forwards; }

.modal {
  position: fixed; z-index: 51; left: 50%; top: 50%; translate: -50% -50%; width: min(var(--modal-w, 720px), calc(100vw - 48px));
  height: min(var(--modal-h, auto), calc(100vh - 64px)); max-height: calc(100vh - 64px);
  display: flex; flex-direction: column; overflow: hidden;
  background: var(--surface); border-radius: var(--r-5); box-shadow: var(--shadow-4); animation: modal-in var(--dur-3) var(--ease);
}
.modal.is-leaving { animation: modal-out var(--dur-2) var(--ease) forwards; }
.modal-head { display: flex; align-items: center; gap: 14px; padding: 22px 24px 0; }
.modal-heading { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.modal-title { font-size: var(--fs-title); font-weight: 500; line-height: 1.3; }
.modal-sub { font-size: var(--fs-body); }
.modal-head > .icon-btn { margin: -4px -8px 0 auto; align-self: flex-start; }
.modal-tabs { padding: 8px 24px 0; border-bottom: 1px solid var(--line); }
.modal-body { flex: 1 1 auto; min-height: 0; overflow: auto; padding: 22px 24px 24px; }
.modal-foot { display: flex; align-items: center; gap: 10px; padding: 14px 24px; border-top: 1px solid var(--line); background: var(--surface); }

.drawer {
  position: fixed; z-index: 51; top: 10px; right: 10px; bottom: 10px; width: min(var(--drawer-w, 480px), calc(100vw - 20px));
  display: flex; flex-direction: column; overflow: hidden;
  background: var(--surface); border-radius: var(--r-4); box-shadow: var(--shadow-4); animation: drawer-in var(--dur-3) var(--ease);
}
.drawer.is-leaving { animation: drawer-out var(--dur-2) var(--ease) forwards; }
.drawer-head { position: relative; display: flex; align-items: flex-start; gap: 12px; padding: 20px 24px 20px; border-bottom: 1px solid var(--line); }
.drawer-head > .icon-btn { margin: -4px -8px 0 auto; }
/* A site's state header runs the full width; the close button sits in the corner beside Stop/Resume. */
.drawer-head:has(> .grow > .state) > .icon-btn { position: absolute; top: 19px; right: 16px; margin: 0; }
.drawer-body { flex: 1 1 auto; min-height: 0; overflow: auto; padding: 24px 24px 32px; }
.drawer-foot { display: flex; align-items: center; gap: 10px; padding: 14px 24px; border-top: 1px solid var(--line); }

.toasts { position: fixed; left: 50%; bottom: 28px; translate: -50% 0; z-index: 95; display: flex; flex-direction: column; align-items: center; gap: 8px; pointer-events: none; }
.toast {
  display: flex; align-items: center; gap: 12px; min-height: 44px; padding: 6px 6px 6px 18px; border-radius: var(--r-pill);
  background: var(--ink); color: var(--on-ink); font-size: var(--fs-body); font-weight: 500; box-shadow: 0 16px 36px -12px rgba(28, 27, 31, .45);
  pointer-events: auto; animation: toast-in var(--dur-3) var(--ease);
}
.toast:not(:has(.toast-action)) { padding-right: 20px; }
.toast > .ic { width: 16px; height: 16px; margin-left: -4px; }
.toast.is-leaving { animation: toast-out var(--dur-2) var(--ease) forwards; }
.toast-action { height: 32px; padding: 0 14px; border: 0; border-radius: var(--r-pill); background: rgba(255, 255, 255, .14); color: var(--on-ink); font-weight: 500; font-size: var(--fs-body); }
.toast-action:hover { background: rgba(255, 255, 255, .24); }
.toast-dot { width: 8px; height: 8px; border-radius: 50%; margin-left: -4px; flex: none; }
.toast-agent .toast-dot { background: var(--on-ink); animation: breathe-dot var(--breath) var(--ease-io) infinite; }
/* Waits for a person: the attention mark, the ink of the toast inside the drifting ring */
.toast-human .toast-dot { width: 10px; height: 10px; border: 2px solid transparent; background: linear-gradient(var(--attn-fill), var(--attn-fill)) padding-box, var(--attn-ring) border-box; }

/* ==========================================================================
   Avatars — one style. Circle = a person, rounded square = an agent.
   ========================================================================== */
.av {
  --s: 32px;
  position: relative; flex: none; width: var(--s); height: var(--s); display: inline-grid; place-items: center;
  border-radius: 50%; background: var(--av-bg, var(--fill-solid)); color: var(--av-fg, var(--ink));
  font: 400 var(--fs-meta)/1 var(--font); user-select: none;
}
.av-xs { --s: 20px; }
.av-sm { --s: 24px; }
.av-md { --s: 32px; }
.av-lg { --s: 40px; font-size: var(--fs-body); font-weight: 500; }
.av-xl { --s: 56px; font-size: var(--fs-body); font-weight: 500; }
.av-agent { border-radius: 31%; }
.av-agent svg { width: 64%; height: 64%; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
/* Working now: a small ink dot that breathes (by size: always full ink). Calm, never a ring around the face. */
.av-agent.is-live::after {
  content: ""; position: absolute; right: -2px; bottom: -2px; width: max(6px, calc(var(--s) * .24)); height: max(6px, calc(var(--s) * .24));
  border-radius: 50%; background: var(--ink); box-shadow: 0 0 0 2px var(--surface);
  animation: breathe-dot var(--breath) var(--ease-io) infinite;
}
.av-xs.av-agent.is-live::after { right: -1.5px; bottom: -1.5px; box-shadow: 0 0 0 1.5px var(--surface); }
.av-agent.is-off { --av-fg: var(--stroke); }  /* paused or off: the glyph fades, like a disabled control */
.av-stack { display: inline-flex; align-items: center; }
.av-stack > .av { box-shadow: 0 0 0 2px var(--surface); }
.av-stack > .av + .av { margin-left: calc(var(--s) * -.22); }
.av-stack.on-bg > .av { box-shadow: 0 0 0 2px var(--bg); }

/* ==========================================================================
   Chips, marks, dots
   ========================================================================== */
.chip {
  display: inline-flex; align-items: center; gap: 6px; height: 24px; padding: 0 10px; border-radius: var(--r-pill);
  background: var(--chip-bg, var(--fill)); color: var(--chip-fg, var(--ink)); box-shadow: var(--chip-ring, none);
  font-size: var(--fs-meta); font-weight: 400; line-height: 1; white-space: nowrap; flex: none;
}
.chip .ic { width: 13px; height: 13px; margin-left: -2px; }
.chip .dot { width: 6px; height: 6px; margin-left: -2px; }
.chip-lg { height: 30px; padding: 0 12px; font-size: var(--fs-body); }
.chip-lg .ic { width: 14px; height: 14px; }
.chip-agent, .chip-ok { --chip-bg: var(--fill); }
.chip-human { --chip-bg: var(--surface); --chip-ring: inset 0 0 0 1px var(--ink); }
.chip-ink { --chip-bg: var(--ink); --chip-fg: var(--on-ink); }
.chip-outline { --chip-bg: transparent; --chip-ring: inset 0 0 0 1px var(--line-strong); }
.chip-remove { display: grid; place-items: center; width: 16px; height: 16px; margin-right: -5px; border: 0; padding: 0; border-radius: 50%; background: transparent; color: inherit; }
.chip-remove:hover { background: var(--fill-2); }
.chip-remove .ic { width: 12px; height: 12px; margin: 0; }
.chip-btn { cursor: pointer; border: 0; }
.chip-btn:hover { --chip-bg: var(--fill-2); }
/* A chip that toggles (aria-pressed): pressed = ink ring and ink words, off = hairline. */
button.chip[aria-pressed] { cursor: pointer; border: 0; transition: box-shadow var(--dur-1) var(--ease), background var(--dur-1) var(--ease); }
button.chip[aria-pressed="true"] { --chip-bg: var(--surface); --chip-ring: inset 0 0 0 1.5px var(--ink); }
button.chip[aria-pressed="false"] { --chip-bg: transparent; --chip-ring: inset 0 0 0 1px var(--line-strong); }
button.chip[aria-pressed="false"]:hover { --chip-ring: inset 0 0 0 1px rgba(28, 27, 31, .3); }

/* Certainty: the shape is the meaning. ● in writing · ◐ stated · ○ our estimate · ◌ not known yet · two rings = sources disagree */
.src { display: inline-flex; align-items: center; gap: 7px; font-size: var(--fs-meta); font-weight: 400; color: var(--ink); white-space: nowrap; line-height: 1.4; }
.src-glyph { width: 12px; height: 12px; flex: none; fill: none; stroke: currentColor; stroke-width: 1.3; }
.src-glyph .fill { fill: currentColor; stroke: none; }
.src-disagree .src-glyph { width: 14px; }
.src.is-bare { gap: 0; }

/* Stage of a site */
.stage { display: inline-flex; align-items: center; gap: 6px; height: 24px; padding: 0 10px; border-radius: var(--r-pill); background: var(--fill); color: var(--ink); font-size: var(--fs-meta); font-weight: 400; line-height: 1; white-space: nowrap; }
.stage-person { background: var(--surface); box-shadow: inset 0 0 0 1px var(--ink); }
.stage-acquisition { background: var(--ink); color: var(--on-ink); }
.stage-aside { background: transparent; box-shadow: inset 0 0 0 1px var(--line-strong); }

/* Status: two marks, two meanings, everywhere. Breathing ink = an agent is working now. The attention mark = waits
   for a person: an ink dot in the drifting RGB ring, only where the thing itself can't take .attn (a mark on a map,
   a toast); never beside an .attn. On, connected, idle and off get no mark (only exceptions are marked); unread is
   weight, not a dot. Circles beside values (● ◐ ○ ◌) are the certainty scale only, never a status. Other kinds draw nothing. */
.dot { position: relative; display: inline-block; flex: none; width: 8px; height: 8px; border-radius: 50%; }
.dot-live { background: var(--ink); animation: breathe-dot var(--breath) var(--ease-io) infinite; }
.dot-human { width: 10px; height: 10px; margin: -1px; border: 2px solid transparent; background: linear-gradient(var(--attn-fill), var(--attn-fill)) padding-box, var(--attn-ring) border-box; }
.dot-human.dot-sm { width: 8px; height: 8px; border-width: 1.5px; }
.dot-sm { width: 6px; height: 6px; }

/* Live line: "● Wren · Writing to An Peeters". The noun first; the words wrap to two lines at most, never cut a name. */
.live { display: flex; align-items: flex-start; gap: 10px; min-width: 0; font-size: var(--fs-body); line-height: 1.5; }
.live > .dot { margin: calc((1lh - 8px) / 2) 2px 0; }
.live b { font-weight: 500; }
.live-text { min-width: 0; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.live-text.is-swapping { animation: swap var(--dur-3) var(--ease); }

/* Slots: running sessions out of max parallel */
.slots { display: inline-flex; align-items: center; gap: 3px; flex: none; }
.slots > i { width: 6px; height: 6px; border-radius: 2px; background: var(--fill-2); }
.slots > i.on { background: var(--ink); }
.slots-label { font-size: var(--fs-meta); font-variant-numeric: tabular-nums; white-space: nowrap; margin-left: 6px; }

/* Countdown: time left in the 1-hour outbox hold */
.countdown { display: inline-flex; align-items: center; gap: 6px; font-size: var(--fs-meta); font-weight: 400; color: var(--ink); font-variant-numeric: tabular-nums; white-space: nowrap; }
.countdown svg { width: 14px; height: 14px; transform: rotate(-90deg); flex: none; }
.countdown .cd-track { fill: none; stroke: var(--fill-2); stroke-width: 2.5; }
.countdown .cd-left { fill: none; stroke: var(--ink); stroke-width: 2.5; stroke-linecap: round; }

.kbd { display: inline-grid; place-items: center; min-width: 20px; height: 20px; padding: 0 5px; border-radius: var(--r-1); background: var(--surface); box-shadow: inset 0 0 0 1px var(--line-strong), 0 1px 0 var(--line-strong); font: 400 var(--fs-meta)/1 var(--font); }

/* ==========================================================================
   Lists, plain key/value lists, callouts, empty states, section titles
   ========================================================================== */
.list { display: flex; flex-direction: column; gap: 2px; }
.list-row {
  display: flex; align-items: center; gap: 12px; min-width: 0; padding: 10px 12px; border-radius: var(--r-2);
  color: inherit; text-decoration: none; transition: background var(--dur-1) var(--ease);
}
a.list-row, button.list-row, .list-row.is-link { cursor: pointer; }
button.list-row { width: 100%; border: 0; background: none; text-align: left; }
a.list-row:hover, button.list-row:hover, .list-row.is-link:hover { background: var(--hover); }
.list-row.is-active { background: var(--fill); }
.list-row-main { display: flex; flex-direction: column; gap: 1px; min-width: 0; flex: 1 1 auto; }
.list-row-title { font-weight: 500; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.list-row-sub { font-size: var(--fs-meta); line-height: 1.4; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.list-row-meta { flex: none; font-size: var(--fs-meta); font-variant-numeric: tabular-nums; }
.list-divided > .list-row + .list-row { box-shadow: 0 -1px 0 var(--line); border-radius: 0; }

/* Plain key/value lists (not site facts: those use UI.facts) */
.facts { display: grid; grid-template-columns: minmax(120px, 40%) 1fr; column-gap: 16px; }
.fact { display: contents; }
.fact > dt, .fact > dd { margin: 0; padding: 10px 0; border-top: 1px solid var(--line); }
.fact:first-child > dt, .fact:first-child > dd { border-top: 0; }
.fact > dt { line-height: 1.45; }
.fact > dd { display: flex; flex-direction: column; gap: 6px; min-width: 0; font-weight: 500; }
.answer { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; min-width: 0; }
.answer-value { font-weight: 500; font-variant-numeric: tabular-nums; }
.answer-note { font-size: var(--fs-meta); line-height: 1.45; }
.answer.is-history .answer-value { font-weight: 400; text-decoration: line-through; text-decoration-color: var(--stroke); }
.conflict { display: flex; flex-direction: column; gap: 6px; padding-left: 12px; box-shadow: inset 1.5px 0 0 var(--ink); }

/* Callouts: a note inside a panel. Outlined, never filled. */
.callout { display: flex; align-items: flex-start; gap: 12px; padding: 14px 16px; border-radius: var(--r-3); box-shadow: inset 0 0 0 1px var(--line-strong); }
.callout > .ic { margin-top: 1px; }
.callout-body { display: flex; flex-direction: column; gap: 4px; min-width: 0; flex: 1; }
.callout-title { font-weight: 500; line-height: 1.45; }
.callout-text { line-height: 1.5; }
.callout-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 6px; }
.callout-agent { box-shadow: inset 0 0 0 1px var(--line-strong); }

.empty { display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; gap: 6px; padding: 40px 24px; }
.empty-mark { width: 48px; height: 48px; margin-bottom: 8px; border-radius: 50%; display: grid; place-items: center; background: var(--fill); }
.empty-mark .ic { width: 20px; height: 20px; }
.empty-title { font-size: var(--fs-heading); font-weight: 500; line-height: 1.4; }
.empty-text { max-width: 320px; font-size: var(--fs-body); line-height: 1.5; }
.empty .btn { margin-top: 10px; }

/* Section heading inside a panel or drawer */
.section-title { display: flex; align-items: center; gap: 8px; min-height: 30px; font-size: var(--fs-heading); font-weight: 500; line-height: 1.4; margin: 0 0 8px; }
.section-title .btn-link, .section-title .btn { margin-left: auto; }
.section-title .count { margin-left: 2px; }

/* ==========================================================================
   Documents — a shelf for files: a darker tray, clearly apart from the facts
   Rows as in Finder or Drive: type icon · name over who and when · size, Open and Download on hover; drop files on
   the shelf to upload. The tokens flip on it (see the dark scopes), so its words are white. Never ink, never ringed:
   that is what waits for a person.
   ========================================================================== */
.docs {
  --dark: var(--shelf); --dark-press: #3B3A41; --doc-under: var(--shelf);
  position: relative; display: flex; flex-direction: column; min-width: 0; padding: 12px 16px 10px; border-radius: var(--r-3);
  background: var(--shelf); color: var(--ink); box-shadow: inset 0 1px 6px -2px rgba(0, 0, 0, .55);
}
.docs-head { display: flex; align-items: center; gap: 8px; min-height: 32px; margin-bottom: 4px; }
.docs-title { font-size: var(--fs-heading); font-weight: 500; line-height: 1.4; }
.docs-count { font-size: var(--fs-meta); font-variant-numeric: tabular-nums; }
.docs-add { margin-left: auto; }
/* Rows bleed by their own padding, so icons and sizes sit on the header's edges, like every list beside them. */
.docs-list { display: flex; flex-direction: column; min-width: 0; margin: 0 -8px; }
/* The site's original files close the list under their own label (Strong, with its count): space first, no frame. */
.docs-group { display: flex; flex-direction: column; min-width: 0; }
.docs-list > * + .docs-group { margin-top: 12px; }
.docs-group-head { display: flex; align-items: center; gap: 8px; min-height: 32px; padding: 0 8px; font-size: var(--fs-body); font-weight: 500; line-height: 1.45; }
.doc-row { position: relative; display: flex; align-items: center; min-width: 0; border-radius: var(--r-2); transition: background var(--dur-1) var(--ease); }
.doc-row + .doc-row::before { content: ""; position: absolute; left: 44px; right: 8px; top: 0; height: 1px; background: var(--line); }
.doc-row:hover { background: var(--hover); }
.doc-row:hover::before, .doc-row:hover + .doc-row::before { opacity: 0; }
.doc { flex: 1 1 auto; display: flex; align-items: center; gap: 12px; min-width: 0; padding: 9px 8px; border-radius: var(--r-2); text-decoration: none; color: inherit; }
.doc-icon { width: 24px; height: 24px; flex: none; display: grid; place-items: center; color: var(--ink); }
.doc-icon svg { width: 24px; height: 24px; fill: none; stroke: currentColor; stroke-width: 1.3; stroke-linecap: round; stroke-linejoin: round; }
.doc-icon .fill { fill: currentColor; stroke: none; }
.doc-main, .doc > .grow { display: flex; flex-direction: column; gap: 1px; min-width: 0; flex: 1 1 auto; }
/* A name is never cut: it wraps to two lines (UI.midcut shortens the rare longer one in the middle). */
.doc-name { font-size: var(--fs-body); font-weight: 500; line-height: 1.4; min-width: 0; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; overflow-wrap: anywhere; }
.doc-meta { font-size: var(--fs-meta); line-height: 1.4; }
.doc-size { flex: none; min-width: 52px; text-align: right; font-size: var(--fs-meta); font-variant-numeric: tabular-nums; white-space: nowrap; transition: opacity var(--dur-1) var(--ease); }
/* Open and Download on hover, on the row's own hover colour over --doc-under (the shelf, set by .docs). */
.doc-acts { position: absolute; right: 6px; top: 50%; translate: 0 -50%; display: flex; gap: 2px; padding-left: 8px; border-radius: var(--r-2); background: linear-gradient(var(--hover), var(--hover)), var(--doc-under, var(--surface)); opacity: 0; pointer-events: none; transition: opacity var(--dur-1) var(--ease); }
.doc-row:focus-within { background: var(--hover); }
.doc-row:hover .doc-acts, .doc-row:focus-within .doc-acts { opacity: 1; pointer-events: auto; }
.doc-row:hover .doc-size, .doc-row:focus-within .doc-size { opacity: 0; }
.docs-more { align-self: flex-start; margin: 8px 0 0; }
.docs-none { display: flex; align-items: center; justify-content: center; gap: 10px; min-height: 64px; margin: 4px 8px 0; border-radius: var(--r-3); border: 1.5px dashed var(--stroke); font-size: var(--fs-body); cursor: pointer; transition: border-color var(--dur-2) var(--ease); }
.docs-none:hover { border-color: var(--ink); }
.docs-none .ic { width: 16px; height: 16px; }
/* While files are dragged over the shelf: a dashed frame that says where they go. */
.docs-over { position: absolute; inset: 0; z-index: 2; display: none; align-items: center; justify-content: center; gap: 10px; border-radius: inherit; border: 1.5px dashed var(--ink); background: color-mix(in srgb, var(--shelf) 94%, transparent); font-size: var(--fs-body); font-weight: 500; pointer-events: none; }
.docs-over .ic { width: 18px; height: 18px; }
.docs.is-over .docs-over { display: flex; animation: fade-in var(--dur-1) var(--ease); }

/* A site's archive, first on its shelf: a button in a file's place (it opens in the reader) */
button.doc { width: 100%; border: 0; background: none; font: inherit; text-align: left; cursor: pointer; }

/* ==========================================================================
   Reading — a document as written (UI.markdown) and the reader it opens in (UI.openReader)
   The six text styles only: headings step down Title → Heading → Strong; the words at Body with room to read;
   tables at the meta size so their columns fit; code and front matter in the code style. Code and quotes are
   outlined or ruled, never filled.
   ========================================================================== */
.md { min-width: 0; font-size: var(--fs-body); line-height: 1.6; overflow-wrap: break-word; }
.md > :first-child { margin-top: 0; }
.md h1, .md h2, .md h3, .md h4, .md h5, .md h6 { margin: 26px 0 0; font-weight: 500; }
.md h1 { font-size: var(--fs-title); line-height: 1.3; }
.md h2 { padding-bottom: 6px; border-bottom: 1px solid var(--line-strong); font-size: var(--fs-heading); line-height: 1.4; }
.md h3, .md h4, .md h5, .md h6 { font-size: var(--fs-body); line-height: 1.45; }
.md h4, .md h5, .md h6 { margin-top: 18px; }
.md p, .md ul, .md ol, .md blockquote, .md pre, .md .md-table, .md .md-fold { margin: 10px 0 0; }
.md ul, .md ol { padding-left: 22px; }
.md li + li, .md li > ul, .md li > ol, .md li > p + p { margin-top: 4px; }
.md b { font-weight: 500; }
.md s { text-decoration-color: var(--stroke); }
.md a { color: var(--ink); text-decoration: underline; text-decoration-color: var(--stroke); text-underline-offset: 3px; text-decoration-thickness: 1px; }
.md a:hover { text-decoration-color: var(--ink); }
.md code { font-family: var(--mono); font-size: var(--fs-meta); }
.md pre { padding: 10px 12px; border-radius: var(--r-2); box-shadow: inset 0 0 0 1px var(--line); }
.md pre code { display: block; line-height: 1.6; white-space: pre-wrap; }
.md blockquote { padding-left: 14px; box-shadow: inset 2px 0 0 var(--line-strong); }
.md hr { height: 1px; margin: 20px 0; border: 0; background: var(--line); }
/* A collapsed block: closed until its title is clicked; what it holds sits under the title's words */
.md .md-fold > summary { cursor: pointer; }
.md .md-fold > summary ~ * { margin-left: 18px; }
.md .md-front { margin: 0 0 6px; }
/* Front matter: the document's properties, key (code) and value (meta), outlined like code */
.md .md-props { display: grid; grid-template-columns: max-content minmax(0, 1fr); gap: 3px 16px; margin: 0 0 6px; padding: 10px 12px; border-radius: var(--r-2); box-shadow: inset 0 0 0 1px var(--line); font-size: var(--fs-meta); line-height: 1.45; }
.md-props dt { font-family: var(--mono); }
.md-props dd { min-width: 0; margin: 0; }
.md-props dd code { display: block; white-space: pre-wrap; }
.md .md-table { overflow-x: auto; }
.md table { width: 100%; border-collapse: collapse; font-size: var(--fs-meta); line-height: 1.45; }
.md th, .md td { padding: 7px 12px 7px 0; text-align: left; vertical-align: top; }
.md th { border-bottom: 1px solid var(--line-strong); font-weight: 400; }
.md td { border-top: 1px solid var(--line); }
.md tbody tr:first-child td { border-top: 0; }
.md th:last-child, .md td:last-child { padding-right: 0; }
.md .is-center { text-align: center; }
.md .is-right { text-align: right; }

.modal.is-reader .modal-body { padding: 18px 32px 40px; }
.reader-wait { font-size: var(--fs-body); }

/* ==========================================================================
   Site record (shared drawer)
   ========================================================================== */
.site-section { margin-top: 32px; }
.site-summary { line-height: 1.6; }
.site-summary p + p { margin-top: 10px; }
.note-line { display: grid; grid-template-columns: 20px minmax(0, 1fr) auto; align-items: start; gap: 10px; padding: 10px 0; font-size: var(--fs-body); line-height: 1.5; }
.note-line + .note-line { border-top: 1px solid var(--line); }
.note-line > .av { margin-top: 1px; }
.note-line .note-when { padding-left: 8px; font-size: var(--fs-meta); line-height: 21px; white-space: nowrap; }
.drawer-head .state { flex: 1; }
.drawer-head .state-top { padding-right: 40px; }
.drawer-body > .decision + .callout { margin-top: 12px; }
/* Under the checklist: every answer, with who gave it and the earlier ones struck through, one click away */
.site-answers-bar { display: flex; margin-top: 16px; }
.site-answers { margin-top: 8px; }
/* One left and one right edge for every row in the record: hover rows bleed by their padding (documents do so everywhere). */
.site-section > .list { margin: 0 -12px; }
/* Stop / Resume among the site's actions in the footer, at the buttons' height */
.drawer-foot .stopgo { height: var(--h, 36px); min-width: 36px; padding: 0 12px; }
.drawer-foot .stopgo:hover, .drawer-foot .stopgo:focus-visible { padding: 0 16px 0 14px; }

/* ==========================================================================
   New site and Write to (shared modals, UI.openNewSite · UI.openWriteTo): fields in rows; the contact stands apart
   behind a hairline. A field that cannot be changed here fades, like every disabled control.
   ========================================================================== */
.sform { display: flex; flex-direction: column; gap: 16px; }
.sform-row { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
.sform-row.is-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.sform-row[hidden] { display: none; }
.sform-part { display: flex; flex-direction: column; gap: 12px; padding-top: 16px; border-top: 1px solid var(--line); }
.sform-part > .field-label { align-self: flex-start; }
.sform .textarea { min-height: 64px; }
.modal.is-sform .modal-sub { overflow-wrap: anywhere; }

/* ==========================================================================
   Patterns for a site
   ========================================================================== */

/* Busy mark: Wren & Vera as one dark-red yin-yang. Wren writes (the red half), Vera reviews (the white half).
   It turns while they are on (.is-active), twice as fast while they work (.is-working), and is still otherwise. */
.busy { display: inline-flex; align-items: center; gap: 8px; min-width: 0; color: var(--ink); font-size: var(--fs-body); font-weight: 500; white-space: nowrap; }
.busy-mark { width: var(--s, 18px); height: var(--s, 18px); flex: none; display: block; transform-origin: 50% 50%; }
.busy-mark .bm-yin { fill: var(--accent); }
.busy-mark .bm-yang { fill: var(--surface); }
.busy-mark .bm-rim { fill: none; stroke: var(--accent); stroke-width: 1.1; }
.busy.is-active .busy-mark { animation: busy-turn var(--turn) linear infinite; }
.busy.is-working .busy-mark { animation-duration: calc(var(--turn) / 2); }
@keyframes busy-turn { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .busy.is-active .busy-mark { animation: none; } }

/* Stop / Resume all research on a site. An icon pill at rest; on hover it opens to STOP or RESUME
   (the one place words are set in capitals, because the owner asked for it). Stopped is ink: a state a person chose. */
.stopgo {
  display: inline-flex; align-items: center; justify-content: center; flex: none; height: 30px; min-width: 30px; padding: 0 9px; overflow: hidden;
  border: 0; border-radius: var(--r-pill); background: var(--surface); color: var(--ink); box-shadow: inset 0 0 0 1px var(--line-strong);
  font: 500 var(--fs-meta)/1 var(--font); white-space: nowrap;
  transition: background var(--dur-2) var(--ease), color var(--dur-2) var(--ease), box-shadow var(--dur-2) var(--ease), padding var(--dur-3) var(--ease);
}
.stopgo svg { width: 10px; height: 10px; flex: none; fill: currentColor; }
.stopgo-label { max-width: 0; margin-left: 0; opacity: 0; transition: max-width var(--dur-3) var(--ease), margin var(--dur-3) var(--ease), opacity var(--dur-2) var(--ease); }
.stopgo:hover, .stopgo:focus-visible { padding: 0 14px 0 12px; }
.stopgo:hover .stopgo-label, .stopgo:focus-visible .stopgo-label { max-width: 80px; margin-left: 8px; opacity: 1; }
.stopgo.is-running:hover { background: var(--ink); color: var(--on-ink); box-shadow: none; }
.stopgo.is-stopped { background: var(--ink); color: var(--on-ink); box-shadow: none; }
.stopgo.is-stopped:hover { background: var(--ink-hover); }

/* Decision needed: the one pattern for every moment a person must decide, and the most important thing on screen.
   It waits for a person, so it carries the attention treatment (.attn: ink, white words, the drifting ring) ·
   "Decision needed" · one question · the evidence as rows · the choices as buttons (the recommended one white)
   · "Answer in your own words" on its own row under them. */
.decision { display: flex; flex-direction: column; gap: 14px; min-width: 0; padding: 18px 22px 20px; border-radius: var(--r-3); }
.decision-head { display: flex; align-items: center; gap: 12px; min-width: 0; min-height: 20px; }
.decision-tag { display: inline-flex; align-items: center; gap: 10px; font-size: var(--fs-body); font-weight: 500; white-space: nowrap; }
.decision-meta { margin-left: auto; justify-content: flex-end; font-size: var(--fs-meta); line-height: 1.4; }
.decision-fold { margin: -6px -8px -6px -4px; }
/* Debug mode: the agent run behind the question, a quiet link after who asked */
.run-link { font-size: var(--fs-meta); font-weight: 400; }
.decision-run { flex: none; }
.decision-q { margin: 0; font-size: var(--fs-heading); font-weight: 500; line-height: 1.45; }
/* Evidence: one continuous hairline per row (no column gap: the space is the value's own padding).
   The certainty mark follows its value, "10 MW ◐"; a row without a value carries it after its words. */
.decision-ev { display: grid; grid-template-columns: max-content minmax(0, 1fr); margin: 0; }
.decision-ev.is-plain { grid-template-columns: minmax(0, 1fr); }
.decision-row { display: contents; }
.decision-ev dt, .decision-ev dd { margin: 0; padding: 10px 0; border-top: 1px solid var(--line); font-size: var(--fs-body); line-height: 1.5; }
.decision-ev dt { padding-right: 16px; font-weight: 500; white-space: nowrap; font-variant-numeric: tabular-nums; }
.decision-ev dd { min-width: 0; }
.decision-mark { white-space: nowrap; font-weight: 400; }
.decision-doc { display: inline-grid; place-items: center; width: 22px; height: 22px; margin-left: 8px; vertical-align: -5px; border: 0; border-radius: 6px; background: var(--fill); color: var(--ink); }
.decision-doc:hover { background: var(--fill-2); }
.decision-doc .ic { width: 13px; height: 13px; }
.decision-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; padding-top: 2px; }
/* Under the choices, in the Meta style: what each one tells Wren (and which agent suggested it), one choice a group */
.decision-said { display: flex; flex-direction: column; gap: 6px; }
.decision-says b { font-weight: 400; }
.decision-own { display: flex; margin-top: -4px; }
.decision.is-folded .decision-ev { display: none; }
.decision.is-compact { gap: 12px; padding: 16px 18px 18px; }

/* Site state: what is the state of this site, at a glance. */
.state { display: flex; flex-direction: column; gap: 14px; min-width: 0; }
.state-top { display: flex; align-items: center; gap: 10px; min-width: 0; }
.state-rank { font-size: var(--fs-meta); white-space: nowrap; font-variant-numeric: tabular-nums; }
.state-top .stopgo { margin-left: auto; }
.state-title { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.state-name { margin: 0; padding: 0; border: 0; background: none; text-align: left; font-size: var(--fs-title); font-weight: 500; line-height: 1.3; color: var(--ink); text-decoration: none; }
button.state-name, a.state-name { cursor: pointer; text-underline-offset: 4px; text-decoration-thickness: 1px; }
button.state-name:hover, a.state-name:hover { text-decoration: underline; text-decoration-color: var(--stroke); }
.state-place { font-size: var(--fs-body); }
.state-pin { font-size: var(--fs-meta); line-height: 1.4; }
.state-lines { display: flex; flex-direction: column; margin: 0 -8px; padding: 0; list-style: none; }
.state-line { position: relative; display: grid; grid-template-columns: 20px minmax(0, 1fr) auto; align-items: start; gap: 10px; padding: 7px 8px; border-radius: var(--r-2); font-size: var(--fs-body); line-height: 1.45; color: var(--ink); text-decoration: none; }
.state-line b { font-weight: 500; }
.state-ic { display: grid; place-items: center; width: 20px; height: 20px; }
.state-ic .dot { width: 8px; height: 8px; }
.state-ic .countdown svg { width: 16px; height: 16px; }
.state-ic .stopgo-ic { width: 10px; height: 10px; border-radius: 2px; background: var(--ink); }
.state-text { min-width: 0; }
.state-when { font-size: var(--fs-meta); }
.state-go { display: grid; place-items: center; height: 20px; opacity: 0; transition: opacity var(--dur-1) var(--ease), transform var(--dur-2) var(--ease); }
.state-go .ic { width: 14px; height: 14px; }
a.state-line, button.state-line { cursor: pointer; transition: background var(--dur-1) var(--ease); }
a.state-line:hover, button.state-line:hover { background: var(--hover); }
a.state-line:hover .state-go { opacity: 1; transform: translateX(2px); }
/* "Waiting for your decision ↓": a button to the card below; the arrow goes once the card is passed (.is-passed). */
button.state-line { width: 100%; margin: 0; border: 0; background: none; font: inherit; font-size: var(--fs-body); line-height: 1.45; text-align: left; }
.state-arrow { white-space: nowrap; }
.state-arrow .ic { display: inline-block; width: 14px; height: 14px; margin-left: 2px; vertical-align: -2px; transition: opacity var(--dur-2) var(--ease), transform var(--dur-2) var(--ease); }
button.state-line:hover .state-arrow .ic { transform: translateY(2px); }
.state-line.is-passed .state-arrow .ic { opacity: 0; }
/* What waits for a person, as a line: the attention treatment, the record's full width, its arrow always shown. */
.state-line.attn { grid-template-columns: minmax(0, 1fr) auto; width: auto; margin: 2px 8px 4px; padding: 9px 12px 9px 14px; transition: --attn-bg var(--dur-1) var(--ease); }
.state-line.attn > .state-ic { display: none; }
.state-line.attn .state-go { opacity: 1; }

/* Facts about a site: one pattern everywhere.
   Label (body) · the value (strong) with its certainty mark right after it, "10 MW ◐", and who said it under it (meta).
   Two answers that disagree are held together by an ink rule; earlier answers are struck through. */
.attrs { --attr-label: 120px; display: grid; grid-template-columns: var(--attr-label) minmax(0, 1fr); margin: 0; font-size: var(--fs-body); line-height: 1.45; }
.attr { display: contents; }
.attr > dt, .attr > dd { margin: 0; padding: 10px 0; border-top: 1px solid var(--line); }
.attr:first-child > dt, .attr:first-child > dd { border-top: 0; }
.attr > dt { display: flex; flex-direction: column; align-items: flex-start; gap: 4px; padding-right: 12px; }
.attr > dt[data-tip] { cursor: default; }
.attr > dd { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.attr-a { display: flex; align-items: flex-start; gap: 8px; min-width: 0; }
.attr-main { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.attr-val { font-weight: 500; font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
.attr-mark { white-space: nowrap; font-weight: 400; }
.attr-mark .src, .decision-mark .src { vertical-align: -1px; }   /* the glyph sits on the figures' cap height */
.attr-by { font-size: var(--fs-meta); line-height: 1.4; overflow-wrap: anywhere; }
.attr-a > .src { flex: none; margin-top: 4px; }   /* rows hand-built before UI.attrRow: the mark after the answer */
.attr-a.is-open .attr-val { font-weight: 400; }
.attr-a.is-history .attr-val { font-weight: 400; }
.attr-a.is-history .attr-text { text-decoration: line-through; text-decoration-color: var(--stroke); text-decoration-thickness: 1px; }
.attr-flag { display: inline-flex; align-items: center; gap: 6px; height: 20px; margin-bottom: -2px; font-size: var(--fs-meta); white-space: nowrap; }
.attr-flag .src-glyph { width: 14px; }
.attr-group { display: flex; flex-direction: column; gap: 10px; margin-left: -10px; padding-left: 10px; box-shadow: inset 1.5px 0 0 var(--ink); }

/* Completion (UI.completion): what we know about a site is a checklist of the attributes that decide whether it is
   viable, in sections, under one figure: how complete it is. Completion is progress. Rows are the facts' pattern:
   label · the value with its certainty mark after it; a missing one says "Not known yet ◌" in the body weight;
   sources that disagree are flagged above their value. */
.cmp { display: flex; flex-direction: column; min-width: 0; }
.cmp-sum { display: flex; align-items: baseline; flex-wrap: wrap; gap: 2px 12px; }
.cmp-pct { font-size: var(--fs-figure); font-weight: 300; line-height: 1.1; font-variant-numeric: tabular-nums; cursor: default; }
.cmp-of { font-size: var(--fs-meta); line-height: 1.4; font-variant-numeric: tabular-nums; }
.cmp-bar { height: 6px; margin-top: 12px; }
.cmp-sec { margin-top: 22px; }
.cmp-sec-head { display: flex; align-items: baseline; gap: 12px; padding-bottom: 4px; border-bottom: 1px solid var(--line-strong); font-size: var(--fs-body); font-weight: 500; line-height: 1.45; }
.cmp-sec-n { margin-left: auto; font-size: var(--fs-meta); font-weight: 400; font-variant-numeric: tabular-nums; white-space: nowrap; }
.cmp .attrs { --attr-label: 136px; }
.cmp .attr:first-child > dt, .cmp .attr:first-child > dd { border-top: 0; }
.cmp .attr-flag { margin-bottom: 0; }
/* compact (a card, a list): the figure in the Strong style and the bar, no sections */
.cmp.is-compact .cmp-sum { gap: 8px; }
.cmp.is-compact .cmp-pct { font-size: var(--fs-body); font-weight: 500; line-height: 1.45; }
.cmp.is-compact .cmp-bar { height: 4px; margin-top: 6px; }

/* Steps: what has been done and what comes next. Done = check · next = ink ring and dot · to do = faint ring. */
.steps { display: flex; flex-direction: column; margin: 0; padding: 0; list-style: none; }
.step { position: relative; display: grid; grid-template-columns: 20px minmax(0, 1fr); align-items: start; gap: 10px; padding: 6px 0; font-size: var(--fs-body); line-height: 1.45; }
.step:not(:last-child)::before { content: ""; position: absolute; left: 9.5px; top: 28px; bottom: -4px; width: 1px; background: var(--line-strong); }
.step-ic { display: grid; place-items: center; width: 20px; height: 20px; border-radius: 50%; }
.step-ic .ic { width: 12px; height: 12px; stroke-width: 2.2; }
.step.is-done .step-ic { background: var(--fill); }
.step.is-next .step-ic { box-shadow: inset 0 0 0 1.5px var(--ink); }
.step.is-next .step-ic::after { content: ""; width: 6px; height: 6px; border-radius: 50%; background: var(--ink); }
.step.is-todo .step-ic { box-shadow: inset 0 0 0 1.5px var(--stroke-faint); }
.step-main { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.step.is-next .step-text { font-weight: 500; }
.step-meta { font-size: var(--fs-meta); line-height: 1.4; }

/* Chat bubbles. The conversation sits on the panel: theirs is white with a hairline, ours is the neutral fill,
   an email in the outbox is dashed. Team Chat uses the same pair: others white, your own notes filled. */
.chat-room { background: var(--chat-room); }
.chat-room.is-team { background: var(--chat-team-room); }
.bubble { max-width: 560px; padding: 10px 14px; border-radius: 18px; font-size: var(--fs-body); line-height: 1.55; overflow-wrap: anywhere; }
.bubble-theirs { background: var(--chat-theirs); color: var(--chat-theirs-ink); border-bottom-left-radius: 6px; box-shadow: inset 0 0 0 1px var(--line-strong); }
.bubble-ours { background: var(--chat-ours); color: var(--chat-ours-ink); border-bottom-right-radius: 6px; }
.bubble-outbox { background: transparent; color: var(--ink); border: 1.5px dashed var(--chat-outbox-edge); border-bottom-right-radius: 6px; }
.bubble-team { background: var(--chat-team); color: var(--chat-team-ink); border-radius: 14px; box-shadow: inset 0 0 0 1px var(--line-strong); }
.bubble-team-me { background: var(--chat-team-me); box-shadow: none; }
.bubble-who { display: block; margin-bottom: 2px; font-size: var(--fs-meta); font-weight: 400; }

/* The review queue: decisions waiting for a person. A white panel: the title with the dark-red count right beside it,
   then one card per request, each with the attention treatment (.attn): who asked (the asking agent's glyph on the
   contact's avatar), the decision, "Asked by Vera · Kari Nilsen, Brumunddal", how long it has waited, and with
   toInbox (the Overview) a "To inbox" button. The whole card links to the decision in the Inbox. */
.queue { display: flex; flex-direction: column; min-width: 0; padding: 8px; border-radius: var(--r-4); background: var(--surface); box-shadow: var(--ring); }
.queue-head { display: flex; align-items: center; gap: 8px; min-height: 40px; padding: 4px 12px 6px; font-size: var(--fs-heading); font-weight: 500; line-height: 1.4; }
.queue-list { display: flex; flex-direction: column; gap: 6px; }
.queue-row { --row-bg: var(--surface); position: relative; display: flex; align-items: flex-start; gap: 12px; padding: 10px 12px; border-radius: var(--r-3); text-decoration: none; transition: --attn-bg var(--dur-1) var(--ease); }
/* The open one (the Inbox): a lighter ink and a wider ring */
.queue-row.is-active, .queue-row[aria-current="true"] { --attn-bg: var(--attn-fill-hover); --attn-w: 2.5px; }
/* Who asked: the agent's glyph sits on the contact's avatar, cut out by a ring in the row's own colour */
.queue-who { position: relative; flex: none; display: inline-flex; margin-top: 2px; }
.queue-who > .av-agent { --s: 16px; position: absolute; right: -5px; bottom: -5px; box-shadow: 0 0 0 2px var(--row-bg); }
.queue-who > .av-agent svg { stroke-width: 2; }
.queue-row-main { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1 1 auto; font-size: var(--fs-body); }
.queue-row-main b { font-weight: 500; line-height: 1.4; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.queue-row-meta { font-size: var(--fs-meta); line-height: 1.4; }
.queue-row-age { flex: none; display: flex; align-items: center; gap: 2px; font-size: var(--fs-meta); line-height: 20px; font-variant-numeric: tabular-nums; white-space: nowrap; }
.queue-row-age .ic { width: 14px; height: 14px; margin-right: -4px; transition: transform var(--dur-2) var(--ease); }
.queue-row:hover .queue-row-age .ic { transform: translateX(2px); }
/* "To inbox": the request's one action, white on the ink, under its words */
.queue-go { align-self: flex-start; margin-top: 10px; }
.queue-row:hover .queue-go { background: var(--ink-hover); }
.queue-go .ic { transition: transform var(--dur-2) var(--ease); }
.queue-row:hover .queue-go .ic { transform: translateX(2px); }
/* Large rows (the Overview): the decision as a Heading, more room around each request */
.queue-row.is-large { gap: 14px; padding: 16px 18px; }
.queue-row.is-large .queue-row-main { gap: 4px; }
.queue-row.is-large .queue-row-age { line-height: 22px; }
.queue-row.is-large .queue-who { margin-top: 0; }
.queue-row.is-large .queue-who > .av-agent { --s: 20px; right: -6px; bottom: -6px; }
.queue-row.is-large .queue-who > .av-agent svg { stroke-width: 1.8; }
.queue-none { display: flex; align-items: center; gap: 10px; padding: 8px 12px 10px; font-size: var(--fs-body); }

/* ==========================================================================
   Agent settings (shared modal)
   ========================================================================== */
.agent-head { display: flex; align-items: center; gap: 14px; padding-bottom: 20px; margin-bottom: 22px; border-bottom: 1px solid var(--line); }
.agent-head .grow { display: flex; flex-direction: column; gap: 2px; }
.agent-name { font-size: var(--fs-heading); font-weight: 500; line-height: 1.4; }
.agent-role { font-size: var(--fs-body); }
.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; }
.form-grid .span-2 { grid-column: 1 / -1; }
.sessions-field { display: flex; align-items: center; gap: 14px; }
/* The instructions: the current version in words, the editor behind a button */
.agent-ins { display: flex; align-items: center; justify-content: space-between; gap: 12px; min-height: 38px; }
.agent-ins-ver { min-width: 0; }
/* An agent that is on but cannot work: the note that waits for a person, under the head */
.agent-waits { align-items: center; margin: -6px 0 22px; }
.reads { display: flex; flex-wrap: wrap; gap: 8px; }
/* What an agent reads first: shown, not chosen here */
.reads.is-fixed > button.chip { cursor: default; pointer-events: none; }
.weights-bar { display: flex; height: 36px; border-radius: 12px; overflow: hidden; gap: 3px; }
.weights-bar > div { display: flex; align-items: center; padding: 0 12px; font-size: var(--fs-body); font-weight: 500; white-space: nowrap; overflow: hidden; transition: flex-grow var(--dur-3) var(--ease); }
.weights-bar > .w-power { background: var(--ink); color: var(--on-ink); }
.weights-bar > .w-permits { background: var(--fill-2); color: var(--ink); }
.weights-bar > .w-connectivity { background: var(--fill); color: var(--ink); }

/* ==========================================================================
   Instructions (shared modal, UI.openInstructions): the text in full, large and monospace, beside its versions
   ========================================================================== */
.modal.is-instructions .modal-body { display: flex; padding: 0; overflow: hidden; }
.ins { display: grid; grid-template-columns: minmax(0, 1fr) 288px; flex: 1 1 auto; min-height: 0; }
.ins-main { display: flex; flex-direction: column; gap: 12px; min-width: 0; min-height: 0; padding: 20px 24px; }
.ins-text {
  flex: 1 1 auto; min-height: 0; width: 100%; margin: 0; padding: 16px 18px; border: 0; border-radius: var(--r-2);
  background: var(--surface); color: var(--ink); box-shadow: inset 0 0 0 1px var(--line-strong);
  font: 400 var(--fs-meta)/1.75 var(--mono); white-space: pre-wrap; overflow-wrap: anywhere; overflow: auto; tab-size: 4;
}
.ins-edit { resize: none; transition: box-shadow var(--dur-1) var(--ease); }
.ins-edit:focus { outline: none; box-shadow: inset 0 0 0 1px var(--ink), 0 0 0 3px rgba(28, 27, 31, .08); }
.ins-read:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
.ins-bar { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; min-height: 32px; }
.ins-bar-what { display: inline-flex; align-items: baseline; flex-wrap: wrap; gap: 10px; min-width: 0; }
.ins-bar-what > b { font-weight: 500; }
.ins-bar-meta { font-size: var(--fs-meta); }
.ins-wait { margin: 0; }
.ins-side { display: flex; flex-direction: column; min-height: 0; border-left: 1px solid var(--line); }
.ins-side-head { padding: 20px 20px 8px; font-weight: 500; }
.ins-list { display: flex; flex-direction: column; gap: 2px; flex: 1 1 auto; min-height: 0; overflow: auto; padding: 0 10px 16px; }
.ins-ver {
  display: flex; flex-direction: column; gap: 2px; width: 100%; padding: 10px 12px; border: 0; border-radius: var(--r-2);
  background: none; color: var(--ink); text-align: left; cursor: pointer; transition: background var(--dur-1) var(--ease);
}
.ins-ver:hover { background: var(--hover); }
.ins-ver.is-active { background: var(--fill); }
.ins-ver-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; min-height: 22px; font-weight: 500; }
.ins-ver-head > .chip { height: 22px; }
.ins-ver-meta { font-size: var(--fs-meta); }
.ins-ver-note { margin-top: 2px; line-height: 1.45; overflow-wrap: anywhere; }
.ins-none { margin: 0; padding: 10px 12px; }
.modal.is-instructions .modal-foot { gap: 12px; }
.ins-note { flex: 0 1 440px; }
.ins-count { font-size: var(--fs-meta); white-space: nowrap; font-variant-numeric: tabular-nums; }

/* ==========================================================================
   Questions (shared modal, UI.openQuestions): the Archivist's facts in a list beside the open one, its questions
   under its definition; under both, the test sites, run again with the saved questions. The instructions editor's
   pieces (.ins-*) where they fit.
   ========================================================================== */
.modal.is-questions .modal-body { display: flex; flex-direction: column; padding: 0; overflow: hidden; }
.modal.is-questions .modal-foot { gap: 12px; }
.qs { display: grid; grid-template-columns: 296px minmax(0, 1fr); flex: 1 1 auto; min-height: 0; }
/* The facts: its name over how many of its questions are on, its switch beside; the open one on the fill */
.qs-side { display: flex; flex-direction: column; min-height: 0; border-right: 1px solid var(--line); }
.qs-facts { display: flex; flex-direction: column; gap: 2px; flex: 1 1 auto; min-height: 0; overflow: auto; padding: 0 10px 8px; }
.qs-fact { display: flex; align-items: center; gap: 10px; padding-right: 12px; border-radius: var(--r-2); transition: background var(--dur-1) var(--ease); }
.qs-fact:hover { background: var(--hover); }
.qs-fact.is-active { background: var(--fill); }
.qs-fact-open {
  display: flex; flex-direction: column; gap: 2px; flex: 1 1 auto; min-width: 0; padding: 10px 0 10px 12px; border: 0;
  border-radius: var(--r-2); background: none; color: var(--ink); text-align: left; cursor: pointer;
}
.qs-fact-name { font-weight: 500; line-height: 1.45; overflow-wrap: anywhere; }
.qs-fact-meta { font-size: var(--fs-meta); line-height: 1.4; }
.qs-side-foot { flex: none; padding: 8px 20px 16px; }
/* The open fact: its fields, then its questions in their order, each with its switch and Delete. A text field is as
   tall as its words: the pane scrolls, not the field. */
.qs-main { display: flex; flex-direction: column; min-width: 0; min-height: 0; }
.qs-wait { padding: 20px 24px; }
.qs-alerts { display: flex; flex-direction: column; gap: 10px; flex: none; padding: 20px 24px 0; }
.qs-alerts:empty { display: none; }
.qs-edit { display: flex; flex-direction: column; gap: 24px; flex: 1 1 auto; min-height: 0; overflow: auto; padding: 20px 24px 28px; }
.qs-key { display: flex; align-items: center; min-height: 38px; overflow-wrap: anywhere; }
.qs-def, .qs-q-text { resize: none; overflow: hidden; }
.qs-def { min-height: 120px; }
.qs-q-text { min-height: 64px; }
.qs-list { display: flex; flex-direction: column; gap: 20px; margin: 0; padding: 0; list-style: none; }
.qs-q { display: flex; flex-direction: column; gap: 8px; }
.qs-q-head { display: flex; align-items: center; gap: 10px; min-height: 30px; }
.qs-acts { display: flex; align-items: center; gap: 8px; }
/* A disabled control takes no pointer: the tip that says why sits on this, around it */
.qs-why { display: inline-flex; }
/* The test sites: Repeat, Run test sites, and the latest test run: its round, each site's state, the lab */
.qs-run { display: flex; flex-direction: column; gap: 10px; flex: none; padding: 14px 24px; border-top: 1px solid var(--line); }
.qs-run-bar { display: flex; align-items: center; flex-wrap: wrap; gap: 10px 16px; min-height: 38px; }
.qs-run-title { display: inline-flex; align-items: center; gap: 8px; font-weight: 500; }
.qs-run-rounds { display: inline-flex; align-items: center; gap: 10px; }
.qs-run-sum { display: flex; align-items: center; flex-wrap: wrap; gap: 4px 16px; min-width: 0; }
.qs-run-sites { display: flex; flex-wrap: wrap; gap: 6px 24px; margin: 0; padding: 0; list-style: none; }
.qs-run-site { display: inline-flex; align-items: center; gap: 8px; min-height: 24px; }
.qs-run-name { font-weight: 500; }
.qs-run-state { display: inline-flex; align-items: center; gap: 6px; font-size: var(--fs-meta); }

/* ==========================================================================
   Motion
   ========================================================================== */
@keyframes fade-in { from { opacity: 0; } }
@keyframes fade-out { to { opacity: 0; } }
@keyframes rise { from { opacity: 0; transform: translateY(6px); } }
@keyframes view-in { from { opacity: 0; } }
@keyframes pop-in { from { opacity: 0; transform: translateY(-4px) scale(.985); } }
@keyframes modal-in { from { opacity: 0; transform: translateY(10px) scale(.985); } }
@keyframes modal-out { to { opacity: 0; transform: translateY(6px) scale(.99); } }
@keyframes drawer-in { from { opacity: 0; transform: translateX(28px); } }
@keyframes drawer-out { to { opacity: 0; transform: translateX(20px); } }
@keyframes toast-in { from { opacity: 0; transform: translateY(10px) scale(.98); } }
@keyframes toast-out { to { opacity: 0; transform: translateY(6px); } }
@keyframes swap { from { opacity: 0; transform: translateY(4px); } }
/* Breathing: slow, and it stays dark, so a working mark never reads as grey.
   A status dot breathes by size (always full ink); marks drawn in SVG (areas, scan lines) breathe by opacity, 1 ↔ .7. */
@keyframes breathe {
  0%, 100% { opacity: 1; }
  50% { opacity: .7; }
}
@keyframes breathe-dot {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(.7); }
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .001ms !important; animation-iteration-count: 1 !important; transition-duration: .001ms !important; }
}
