/* Mint OS — the Mint brand ("Concept 1: The Bio-Digital Leaf"), site-wide.
   Obsidian #0D1117, Mint #00E6A5, Deep Teal #0A3A35, AI Violet #8A2BE2 and the
   off-white #F8FAFC. Mint is a fill and a dark-theme text colour only: on a
   light ground it fails contrast, so light text uses the darker mint tokens
   (--accent #00785A, 5.6:1 on white). Every colour below the palette blocks is
   a token, so the three themes (System / Dark / Light) are three sets of
   values. Three self-hosted OFL faces (public/fonts, latin subset):
     Space Grotesk  brand, headings, labels        --brand-font
     Inter          body, tables, forms, chat      --ui
     JetBrains Mono ids, logs, the clock           --mono

   Three page patterns share one frame (the top bar and sidebar never move):
     A  one screen   -- nothing scrolls but small inner lists       (.content.pat-a)
     B  fixed frame  -- the head stays, the panel body scrolls       (.content.pat-b)
     C  document     -- the content column scrolls under the frame   (.content.pat-c)
   os.css holds the page-level pieces built on top of these primitives. */

@font-face { font-family: "Space Grotesk"; font-style: normal; font-weight: 400; font-display: swap; src: url("fonts/space-grotesk-latin-400-normal.woff2?v=5.3.0") format("woff2"); }
@font-face { font-family: "Space Grotesk"; font-style: normal; font-weight: 500; font-display: swap; src: url("fonts/space-grotesk-latin-500-normal.woff2?v=5.3.0") format("woff2"); }
@font-face { font-family: "Space Grotesk"; font-style: normal; font-weight: 600; font-display: swap; src: url("fonts/space-grotesk-latin-600-normal.woff2?v=5.3.0") format("woff2"); }
@font-face { font-family: "Space Grotesk"; font-style: normal; font-weight: 700; font-display: swap; src: url("fonts/space-grotesk-latin-700-normal.woff2?v=5.3.0") format("woff2"); }
@font-face { font-family: "Inter"; font-style: normal; font-weight: 400; font-display: swap; src: url("fonts/inter-latin-400-normal.woff2?v=5.3.0") format("woff2"); }
@font-face { font-family: "Inter"; font-style: normal; font-weight: 500; font-display: swap; src: url("fonts/inter-latin-500-normal.woff2?v=5.3.0") format("woff2"); }
@font-face { font-family: "Inter"; font-style: normal; font-weight: 600; font-display: swap; src: url("fonts/inter-latin-600-normal.woff2?v=5.3.0") format("woff2"); }
@font-face { font-family: "Inter"; font-style: normal; font-weight: 700; font-display: swap; src: url("fonts/inter-latin-700-normal.woff2?v=5.3.0") format("woff2"); }
@font-face { font-family: "JetBrains Mono"; font-style: normal; font-weight: 400; font-display: swap; src: url("fonts/jetbrains-mono-latin-400-normal.woff2?v=5.3.0") format("woff2"); }
@font-face { font-family: "JetBrains Mono"; font-style: normal; font-weight: 500; font-display: swap; src: url("fonts/jetbrains-mono-latin-500-normal.woff2?v=5.3.0") format("woff2"); }
@font-face { font-family: "JetBrains Mono"; font-style: normal; font-weight: 600; font-display: swap; src: url("fonts/jetbrains-mono-latin-600-normal.woff2?v=5.3.0") format("woff2"); }

/* LIGHT is the base block; dark overrides it (explicitly, or from the system). */
:root {
  /* brand constants, the same in both themes */
  --obsidian: #0D1117;
  --mint: #00E6A5;
  --deep-teal: #0A3A35;
  --ai-violet: #8A2BE2;
  --offwhite: #F8FAFC;
  --grad-ai: linear-gradient(120deg, #00E6A5 0%, #3FC7C4 45%, #8A2BE2 100%);
  --grad-ai-soft: linear-gradient(120deg, rgba(0, 230, 165, .18), rgba(138, 43, 226, .18));
  --grad-ai-line: linear-gradient(120deg, rgba(0, 230, 165, .55), rgba(138, 43, 226, .55));

  --brand: #00E6A5;          /* a fill: always with --on-brand (dark) text */
  --brand-deep: #00785A;     /* mint as text */
  --brand-dark: #0A3A35;

  --bg: #F8FAFC;
  --bg-glow: #EEF6F3;
  --topbar-bg: rgba(255, 255, 255, .96);
  --panel: #FFFFFF;
  --panel-2: #F3F7F6;
  --panel-3: #E9F0EE;
  --card-a: rgba(255, 255, 255, .98);
  --card-b: rgba(250, 252, 252, .98);
  --rail-a: rgba(227, 248, 241, .55);
  --rail-b: rgba(248, 250, 252, .4);
  --hero-a: rgba(0, 230, 165, .12);
  --hero-b: rgba(255, 255, 255, .7);
  --label-bg: rgba(255, 255, 255, .92);
  --line: #E1E8E6;
  --line-strong: #C9D6D2;

  --ink: #0D1117;
  --body: #1F2A33;
  --muted: #46535E;
  --dim: #5F6B76;
  --navy: #253858;

  --accent: #00785A;         /* mint ink: links, active labels, 5.6:1 on white */
  --accent-2: #00A57A;       /* mint stroke: borders, focus, small fills */
  --accent-soft: rgba(0, 165, 122, .10);
  --glow: rgba(0, 230, 165, .18);   /* the softened light-mode glow */
  --on-accent: #0D1117;
  --btn-a: #00E6A5;
  --btn-b: #00D69A;

  --violet-ink: #7420C4;
  --violet-tint: #F1E8FC;
  --teal-tint: #E1F1ED;
  --teal-line: #9CCFC2;
  --leaf-a: #3FDDA0;
  --leaf-b: #0F7A64;
  --wordmark: #008A63;
  --pill-os: #00C98F;

  --work: #7A5D00;
  --warn: #9A5B00;
  --bad: #C62828;
  --off: #7F8C98;
  --code-bg: rgba(10, 58, 53, .05);
  --input-bg: #FFFFFF;
  --row-hover: rgba(0, 165, 122, .06);

  --orb-floret: #3FDDA0;
  --orb-floret-mid: #0F7A64;
  --orb-floret-hi: #0A3A35;
  --orb-core: #0A3A35;
  --orb-root: #9CCFC2;
  --orb-root-hi: #00A57A;
  --orb-sap: #00A57A;
  /* the Machine core's mycelium (public/mycelium.js): flat and structural */
  --dry: #B9C4C1; --dry-crack: #7F8C98;
  --sub-a: rgba(10, 58, 53, .06); --hypha: rgba(15, 122, 100, .55); --hypha-faint: rgba(15, 122, 100, .18);
  --pulse: #00A57A; --pulse-glow: rgba(0, 230, 165, .30); --spore: #C62828;
  --dark-thread: rgba(95, 107, 118, .28);
  --orb-glow: rgba(0, 230, 165, .25);
  --orb-hud: #00785A;
  --orb-node-bg: #FFFFFF;
  --orb-wood-a: #E9F0EE;
  --orb-wood-b: #F3F7F6;
  --grid-dot: rgba(10, 58, 53, .07);

  /* The memory graph's categories, in the brand hues: mint, violet and their
     neighbours, each re-set for dark so it keeps its contrast. */
  --g-people: #B4501A;
  --g-topic: #7420C4;
  --g-conv: #0E7C75;
  --g-doc: #9A5B00;
  --g-decision: #2E7D32;
  --g-figure: #2F5FC8;
  --g-trap: #C62828;
  --g-pref: #B0368F;
  --g-issue: #B45A00;
  --g-fact: #6B7F00;
  --g-session: #0B6BA8;
  --g-project: #00805C;
  --g-file: #8A5AD6;
  --g-run: #0F766E;
  --g-edge: rgba(70, 83, 94, .20);
  --g-edge-sem: rgba(154, 91, 0, .50);

  --on-brand: #0D1117;
  --on-bad: #FFFFFF;
  --brand-hover: #00D69A;
  --good-ink: #00604A;
  --bad-tint: #FDECEC;
  --bad-line: rgba(198, 40, 40, .32);
  --bad-ink: #8E1B1B;
  --warn-tint: #FFF3DC;
  --warn-tint-2: rgba(154, 91, 0, .06);
  --warn-line: rgba(154, 91, 0, .34);
  --warn-ink: #6B4000;
  --info-tint: #E3F8F1;
  --info-line: rgba(0, 165, 122, .30);
  --neutral-tint: rgba(13, 17, 23, .05);
  --scrim: rgba(13, 17, 23, .40);
  --code-ink: #0D1117;
  --shadow-sm: 0 1px 2px rgba(13, 17, 23, .05);
  --shadow-md: 0 6px 18px rgba(13, 17, 23, .06), 0 1px 2px rgba(13, 17, 23, .05);
  --glow-mint: 0 0 0 1px #00A57A, 0 0 0 4px rgba(0, 230, 165, .18);
  --glow-ai: 0 0 0 1px #9B5CE6, 0 0 0 4px rgba(138, 43, 226, .14);

  /* Names the older rules still use, pointed at the new palette. */
  --ground: var(--bg);
  --surface: var(--panel);
  --surface-2: var(--panel-2);
  --brand-tint: var(--accent-soft);
  --brand-tint-2: var(--line-strong);
  --brand-ink: var(--accent);
  --ok: var(--accent);
  --focus-ring: var(--accent-soft);
  --shadow: var(--shadow-md);

  --radius: 8px;
  --r: 14px;
  --gap: 12px;
  --side-w: 244px;
  --sidebar-w: var(--side-w);
  --topbar-h: 56px;

  --brand-font: "Space Grotesk", "Avenir Next", "Segoe UI", system-ui, sans-serif;
  --ui: "Inter", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial,
        "Noto Sans", "Noto Sans Arabic", sans-serif;
  --reading: "Inter", system-ui, -apple-system, "Segoe UI", sans-serif;
  --mono: "JetBrains Mono", ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;

  --fast: 140ms;
  --ease: cubic-bezier(0.2, 0, 0.2, 1);
  color-scheme: light;
}

/* Dark: Obsidian. Chosen with the theme switch in the top bar, or followed
   from the system when that is left on System (the default). theme-init.js
   sets data-theme before first paint. The same block twice, because a
   custom property cannot be shared between a selector and a media query. */
:root[data-theme="dark"] {
  color-scheme: dark;
  --brand: #00E6A5; --brand-deep: #00E6A5; --brand-dark: #0A3A35;
  --bg: #0D1117; --bg-glow: #0E1A1B; --topbar-bg: rgba(10, 14, 19, .94);
  --panel: #121A22; --panel-2: #17212B; --panel-3: #1D2934;
  --card-a: rgba(18, 26, 34, .96); --card-b: rgba(15, 22, 29, .96);
  --rail-a: rgba(10, 58, 53, .30); --rail-b: rgba(13, 17, 23, .2);
  --hero-a: rgba(0, 230, 165, .10); --hero-b: rgba(18, 26, 34, .6);
  --label-bg: rgba(13, 17, 23, .82);
  --line: #1F2B35; --line-strong: #2A3945;
  --ink: #E6EDF3; --body: #C3CDD6; --muted: #9DAAB6; --dim: #7F8C98; --navy: #A9BFE3;
  --accent: #00E6A5; --accent-2: #00C98F; --accent-soft: rgba(0, 230, 165, .10); --glow: rgba(0, 230, 165, .30);
  --on-accent: #0D1117; --btn-a: #00E6A5; --btn-b: #00CC93;
  --violet-ink: #B98CFF; --violet-tint: rgba(138, 43, 226, .16); --teal-tint: #0A3A35; --teal-line: #145A50;
  --leaf-a: #6DEBA8; --leaf-b: #248273; --wordmark: #6DEBA8; --pill-os: #6DEBA8;
  --work: #E8D86A; --warn: #F5B84A; --bad: #FF7A7A; --off: #6B7785;
  --code-bg: rgba(0, 0, 0, .32); --input-bg: #0F161D; --row-hover: rgba(0, 230, 165, .05);
  --orb-floret: #00E6A5; --orb-floret-mid: #6DEBA8; --orb-floret-hi: #C9FFEC; --orb-core: #E9FFF6;
  --orb-root: #145A50; --orb-root-hi: #6DEBA8; --orb-sap: #C9FFEC; --orb-glow: rgba(0, 230, 165, .45);
  --dry: #3A4652; --dry-crack: #5F6B76;
  --sub-a: rgba(0, 230, 165, .06); --hypha: rgba(30, 140, 119, .75); --hypha-faint: rgba(30, 140, 119, .25);
  --pulse: #00E6A5; --pulse-glow: rgba(0, 230, 165, .5); --spore: #FF7A7A;
  --dark-thread: rgba(127, 140, 152, .18);
  --orb-hud: #00E6A5; --orb-node-bg: #121A22; --orb-wood-a: #17212B; --orb-wood-b: #121A22;
  --grid-dot: rgba(0, 230, 165, .06);
  --g-people: #FF9E6B; --g-topic: #B98CFF; --g-conv: #3FD2C8; --g-doc: #F5B84A; --g-decision: #7CE38B;
  --g-figure: #5C9DFF; --g-trap: #FF7A7A; --g-pref: #F28CD8; --g-issue: #FFB36B; --g-fact: #D6F36B;
  --g-session: #6CC6FF; --g-project: #00E6A5; --g-file: #D7C2FF; --g-run: #7FE0D4;
  --g-edge: rgba(185, 140, 255, .16); --g-edge-sem: rgba(245, 184, 74, .5);
  --on-brand: #0D1117; --on-bad: #1A0D0D; --brand-hover: #00CC93; --good-ink: #9FF5D6;
  --bad-tint: rgba(255, 122, 122, .12); --bad-line: rgba(255, 122, 122, .4); --bad-ink: #FFB9B9;
  --warn-tint: rgba(245, 184, 74, .13); --warn-tint-2: rgba(245, 184, 74, .08); --warn-line: rgba(245, 184, 74, .45); --warn-ink: #F8D694;
  --info-tint: rgba(0, 230, 165, .10); --info-line: rgba(0, 230, 165, .30);
  --neutral-tint: rgba(255, 255, 255, .06);
  --scrim: rgba(0, 0, 0, .55); --code-ink: #E6EDF3;
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, .4);
  --shadow-md: 0 1px 0 rgba(255, 255, 255, .02) inset, 0 8px 24px rgba(0, 0, 0, .28);
  --glow-mint: 0 0 0 1px rgba(0, 230, 165, .35), 0 0 18px rgba(0, 230, 165, .25);
  --glow-ai: 0 0 0 1px rgba(160, 120, 255, .35), 0 0 22px rgba(138, 43, 226, .28);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --brand: #00E6A5; --brand-deep: #00E6A5; --brand-dark: #0A3A35;
    --bg: #0D1117; --bg-glow: #0E1A1B; --topbar-bg: rgba(10, 14, 19, .94);
    --panel: #121A22; --panel-2: #17212B; --panel-3: #1D2934;
    --card-a: rgba(18, 26, 34, .96); --card-b: rgba(15, 22, 29, .96);
    --rail-a: rgba(10, 58, 53, .30); --rail-b: rgba(13, 17, 23, .2);
    --hero-a: rgba(0, 230, 165, .10); --hero-b: rgba(18, 26, 34, .6);
    --label-bg: rgba(13, 17, 23, .82);
    --line: #1F2B35; --line-strong: #2A3945;
    --ink: #E6EDF3; --body: #C3CDD6; --muted: #9DAAB6; --dim: #7F8C98; --navy: #A9BFE3;
    --accent: #00E6A5; --accent-2: #00C98F; --accent-soft: rgba(0, 230, 165, .10); --glow: rgba(0, 230, 165, .30);
    --on-accent: #0D1117; --btn-a: #00E6A5; --btn-b: #00CC93;
    --violet-ink: #B98CFF; --violet-tint: rgba(138, 43, 226, .16); --teal-tint: #0A3A35; --teal-line: #145A50;
    --leaf-a: #6DEBA8; --leaf-b: #248273; --wordmark: #6DEBA8; --pill-os: #6DEBA8;
    --work: #E8D86A; --warn: #F5B84A; --bad: #FF7A7A; --off: #6B7785;
    --code-bg: rgba(0, 0, 0, .32); --input-bg: #0F161D; --row-hover: rgba(0, 230, 165, .05);
    --orb-floret: #00E6A5; --orb-floret-mid: #6DEBA8; --orb-floret-hi: #C9FFEC; --orb-core: #E9FFF6;
    --orb-root: #145A50; --orb-root-hi: #6DEBA8; --orb-sap: #C9FFEC; --orb-glow: rgba(0, 230, 165, .45);
    --dry: #3A4652; --dry-crack: #5F6B76;
    --sub-a: rgba(0, 230, 165, .06); --hypha: rgba(30, 140, 119, .75); --hypha-faint: rgba(30, 140, 119, .25);
    --pulse: #00E6A5; --pulse-glow: rgba(0, 230, 165, .5); --spore: #FF7A7A;
    --dark-thread: rgba(127, 140, 152, .18);
    --orb-hud: #00E6A5; --orb-node-bg: #121A22; --orb-wood-a: #17212B; --orb-wood-b: #121A22;
    --grid-dot: rgba(0, 230, 165, .06);
    --g-people: #FF9E6B; --g-topic: #B98CFF; --g-conv: #3FD2C8; --g-doc: #F5B84A; --g-decision: #7CE38B;
    --g-figure: #5C9DFF; --g-trap: #FF7A7A; --g-pref: #F28CD8; --g-issue: #FFB36B; --g-fact: #D6F36B;
    --g-session: #6CC6FF; --g-project: #00E6A5; --g-file: #D7C2FF; --g-run: #7FE0D4;
    --g-edge: rgba(185, 140, 255, .16); --g-edge-sem: rgba(245, 184, 74, .5);
    --on-brand: #0D1117; --on-bad: #1A0D0D; --brand-hover: #00CC93; --good-ink: #9FF5D6;
    --bad-tint: rgba(255, 122, 122, .12); --bad-line: rgba(255, 122, 122, .4); --bad-ink: #FFB9B9;
    --warn-tint: rgba(245, 184, 74, .13); --warn-tint-2: rgba(245, 184, 74, .08); --warn-line: rgba(245, 184, 74, .45); --warn-ink: #F8D694;
    --info-tint: rgba(0, 230, 165, .10); --info-line: rgba(0, 230, 165, .30);
    --neutral-tint: rgba(255, 255, 255, .06);
    --scrim: rgba(0, 0, 0, .55); --code-ink: #E6EDF3;
    --shadow-sm: 0 1px 2px rgba(0, 0, 0, .4);
    --shadow-md: 0 1px 0 rgba(255, 255, 255, .02) inset, 0 8px 24px rgba(0, 0, 0, .28);
    --glow-mint: 0 0 0 1px rgba(0, 230, 165, .35), 0 0 18px rgba(0, 230, 165, .25);
    --glow-ai: 0 0 0 1px rgba(160, 120, 255, .35), 0 0 22px rgba(138, 43, 226, .28);
  }
}

* { box-sizing: border-box; }

/* The `hidden` attribute has to actually hide things: any class rule here
   would otherwise outrank the browser's own `display: none`. */
[hidden] { display: none !important; }

html, body { min-height: 100%; }

body {
  margin: 0;
  background: radial-gradient(1200px 700px at 55% 30%, var(--bg-glow) 0%, var(--bg) 62%), var(--bg);
  background-attachment: fixed;
  color: var(--body);
  font-family: var(--ui);
  font-size: 14px;
  line-height: 1.45;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  font-variant-numeric: tabular-nums;
}

a { color: var(--accent); text-decoration: none; text-underline-offset: 2px; }
a:hover { text-decoration: underline; }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px; }

h1, h2, h3 { color: var(--ink); font-weight: 650; letter-spacing: -0.01em; }
h1 { font-size: 21px; margin: 0; line-height: 1.25; }
h2 { font-size: 15px; margin: 0; line-height: 1.3; }
h3 { font-size: 14px; margin: 18px 0 8px; line-height: 1.35; }

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

.muted { color: var(--muted); }
.small { font-size: 12.5px; }
.mono { font-family: var(--mono); }
.right { text-align: right; }
.strong { font-weight: 650; color: var(--ink); }
.ico { flex: none; vertical-align: -0.18em; }
.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

/* ------------------------------------------------------------- top bar --- */

.topbar {
  position: sticky; top: 0; z-index: 30;
  height: var(--topbar-h);
  display: flex; align-items: center; gap: 18px;
  padding: 0 16px;
  background: var(--topbar-bg);
  border-bottom: 1px solid var(--line);
  backdrop-filter: blur(8px);
}

.topbar > .brand {
  display: flex; align-items: center; gap: 10px;
  color: var(--ink); font-weight: 750; letter-spacing: .01em; white-space: nowrap; flex: none;
}
.topbar > .brand:hover { text-decoration: none; }
.brand-mark {
  display: grid; place-items: center; width: 30px; height: 30px; border-radius: 8px;
  background: linear-gradient(145deg, var(--btn-a), var(--brand-deep));
  color: var(--on-accent);
  box-shadow: 0 0 18px -4px var(--glow);
}
.brand-text em { font-style: normal; color: var(--accent); margin-left: 4px; font-weight: 750; }

.top-tabs { display: flex; align-self: stretch; }
.top-tab {
  display: flex; align-items: center; gap: 8px; padding: 0 16px;
  color: var(--muted); font-weight: 650; font-size: 14px; white-space: nowrap;
  border-bottom: 2px solid transparent;
  transition: color var(--fast) var(--ease), background var(--fast) var(--ease);
}
.top-tab:hover { color: var(--ink); background: var(--accent-soft); text-decoration: none; }
.top-tab.on { color: var(--accent); border-bottom-color: var(--accent);
  background: linear-gradient(to top, var(--accent-soft), transparent); }

.top-right { margin-left: auto; display: flex; align-items: center; gap: 14px; }

/* The health chip: the one line that says whether anything needs you. */
.sys-chip {
  display: flex; align-items: center; gap: 8px; white-space: nowrap;
  font-size: 11px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
  color: var(--accent); background: var(--accent-soft); border: 1px solid var(--line-strong);
  padding: 5px 11px; border-radius: 999px;
}
.sys-chip:hover { text-decoration: none; border-color: var(--accent); }
.sys-chip.warn { color: var(--warn); border-color: var(--warn-line); background: var(--warn-tint); }
.sys-chip.bad { color: var(--bad); border-color: var(--bad-line); background: var(--bad-tint); }
.sys-chip .short { display: none; }

.chip {
  font-size: 12.5px; color: var(--accent); background: var(--accent-soft);
  border: 1px solid var(--line-strong); padding: 3px 10px; border-radius: 999px; white-space: nowrap;
}

.clock { text-align: right; line-height: 1.15; white-space: nowrap; }
.clock b { display: block; color: var(--ink); font: 600 16px/1.1 var(--mono); }
.clock span { font-size: 11px; color: var(--muted); }

.whoami {
  display: flex; flex-direction: column; line-height: 1.2;
  padding: 4px 8px; border-radius: 8px; color: var(--ink); white-space: nowrap;
}
.whoami:hover { background: var(--accent-soft); text-decoration: none; }
.whoami-name { font-size: 13px; font-weight: 700; }
.whoami-role { font-size: 11px; color: var(--muted); }

.logout { margin: 0; }
.logout button {
  display: grid; place-items: center; width: 34px; height: 34px; padding: 0;
  background: none; border: 1px solid var(--line); border-radius: 9px;
  color: var(--muted); cursor: pointer;
}
.logout button:hover { border-color: var(--bad); color: var(--bad); }

/* ------------------------------------------------------------- layout ---- */

.layout { display: grid; grid-template-columns: var(--side-w) minmax(0, 1fr); min-height: calc(100vh - var(--topbar-h)); }
.layout.bare { grid-template-columns: minmax(0, 1fr); }

.sidebar {
  position: sticky; top: var(--topbar-h);
  height: calc(100vh - var(--topbar-h));
  display: flex; flex-direction: column; min-height: 0;
  border-right: 1px solid var(--line);
  background: linear-gradient(180deg, var(--rail-a), var(--rail-b));
}
.side-scroll { flex: 1; min-height: 0; overflow: hidden auto; scrollbar-width: none; padding: 12px 10px 8px; }
.side-scroll::-webkit-scrollbar { display: none; }

.side-id {
  display: grid; grid-template-columns: 34px minmax(0, 1fr); gap: 10px; align-items: center;
  padding: 8px 10px 12px; margin-bottom: 6px; border-bottom: 1px dashed var(--line);
}
.side-id-mark {
  width: 34px; height: 34px; border-radius: 50%; display: grid; place-items: center; position: relative;
  background: var(--accent-soft); border: 1px solid var(--line-strong); color: var(--accent);
}
.side-id-mark::after {
  content: ""; position: absolute; inset: -4px; border-radius: 50%;
  border: 1px dashed var(--line-strong); animation: spin 24s linear infinite;
}
.side-id b { display: block; color: var(--ink); font-size: 13px; line-height: 1.25; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.side-id small { display: block; font: 11px var(--mono); color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.side-home { margin-bottom: 2px; }
.side-label {
  font: 700 10.5px var(--ui); letter-spacing: .14em; text-transform: uppercase;
  color: var(--ink); opacity: .9; padding: 12px 10px 4px;
  display: flex; align-items: center; gap: 8px;
}
.side-label::after { content: ""; flex: 1; height: 1px; background: linear-gradient(90deg, var(--line-strong), transparent); }
.side-sublabel { font: 11px var(--mono); color: var(--muted); padding: 6px 10px 2px 12px; }
.side-item {
  display: grid; grid-template-columns: 18px minmax(0, 1fr) auto; align-items: center; gap: 10px;
  padding: 6px 10px; margin: 1px 0; border-radius: 9px; position: relative;
  color: var(--body); font-size: 13.5px; border: 1px solid transparent;
  transition: background var(--fast) var(--ease), color var(--fast) var(--ease);
}
.side-item > span:not(.badge) { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.side-item:hover { background: var(--accent-soft); color: var(--ink); text-decoration: none; }
.side-item.on { color: var(--ink); font-weight: 650; background: linear-gradient(90deg, var(--accent-soft), transparent); border-color: var(--line); }
.side-item.on::before {
  content: ""; position: absolute; left: -10px; top: 7px; bottom: 7px; width: 3px;
  border-radius: 0 3px 3px 0; background: var(--accent); box-shadow: 0 0 10px var(--glow);
}
.side-item.on .ico { color: var(--accent); }

.badge {
  font: 600 10.5px var(--mono); padding: 0 6px; border-radius: 999px; line-height: 17px;
  border: 1px solid var(--line); color: var(--muted); display: inline-flex; align-items: center; gap: 4px; white-space: nowrap;
}
.badge.ok { color: var(--accent); border-color: var(--line-strong); }
.badge.warn { color: var(--warn); border-color: var(--warn-line); }
.badge.bad { color: var(--bad); border-color: var(--bad-line); }

.side-foot { padding: 8px 10px 10px; border-top: 1px solid var(--line); }
.side-collapse {
  display: flex; align-items: center; gap: 8px; width: 100%;
  background: none; border: 1px solid var(--line); border-radius: 8px;
  color: var(--muted); padding: 5px 9px; font: 12px var(--ui); cursor: pointer;
}
.side-collapse:hover { color: var(--ink); border-color: var(--line-strong); }

/* Collapsed to icons, remembered per browser (localStorage "moni-side",
   applied before paint by theme-init.js). Badges become a dot on the icon. */
:root[data-side="collapsed"] { --side-w: 64px; }
:root[data-side="collapsed"] .side-item { grid-template-columns: 18px; justify-content: center; padding: 8px; }
:root[data-side="collapsed"] .side-item > span:not(.badge),
:root[data-side="collapsed"] .side-label,
:root[data-side="collapsed"] .side-sublabel,
:root[data-side="collapsed"] .side-id > div,
:root[data-side="collapsed"] .side-collapse span { display: none; }
:root[data-side="collapsed"] .side-item .badge {
  position: absolute; top: 3px; right: 5px; width: 7px; height: 7px; padding: 0; font-size: 0; line-height: 0;
  border: 0; background: var(--muted);
}
:root[data-side="collapsed"] .side-item .badge.ok { background: var(--accent); }
:root[data-side="collapsed"] .side-item .badge.warn { background: var(--warn); }
:root[data-side="collapsed"] .side-item .badge.bad { background: var(--bad); }
:root[data-side="collapsed"] .side-item .badge.plain { display: none; }
:root[data-side="collapsed"] .side-id { grid-template-columns: 34px; justify-content: center; padding: 8px 0 12px; }
:root[data-side="collapsed"] .side-label { display: block; height: 1px; padding: 0; margin: 8px 6px; background: var(--line); opacity: 1; font-size: 0; overflow: hidden; }
:root[data-side="collapsed"] .side-label::after { display: none; }
:root[data-side="collapsed"] .side-collapse { justify-content: center; }
:root[data-side="collapsed"] .side-collapse .ico { transform: scaleX(-1); }

/* ------------------------------------------------------- content column --- */

.content { min-width: 0; min-height: 0; position: relative; padding: 14px 18px 40px; }
.content > * { margin-bottom: var(--gap); }
.content > *:last-child { margin-bottom: 0; }
.content > form { margin-bottom: 0; }
.content.flush { padding: 0; height: 100%; overflow: hidden; overflow: clip; }
.content.flush > * { margin-bottom: 0; }

.page-head {
  display: flex; align-items: flex-end; justify-content: space-between; gap: 16px; flex-wrap: wrap;
}
.crumbs { font: 11px var(--mono); color: var(--muted); letter-spacing: .04em; margin-bottom: 2px; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.crumbs a { color: var(--muted); }
.crumbs a:hover { color: var(--accent); text-decoration: none; }
.page-head h1 { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.page-head .sub { margin: 2px 0 0; color: var(--muted); font-size: 13px; max-width: 90ch; }
.page-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; justify-content: flex-end; }

.auth-wrap { min-height: 100vh; display: grid; place-items: center; padding: 24px; }
.auth-wrap .card { width: 100%; max-width: 420px; }
.auth-wrap .card::before, .auth-wrap .card::after { content: ""; position: absolute; width: 10px; height: 10px; border: 1.5px solid var(--accent); opacity: .55; pointer-events: none; }
.auth-wrap .card::before { top: -1px; left: -1px; border-right: 0; border-bottom: 0; border-top-left-radius: var(--r); }
.auth-wrap .card::after { bottom: -1px; right: -1px; border-left: 0; border-top: 0; border-bottom-right-radius: var(--r); }

/* --------------------------------------------------------------- cards --- */

.card {
  position: relative; min-width: 0;
  background: linear-gradient(180deg, var(--card-a), var(--card-b));
  border: 1px solid var(--line); border-radius: var(--r);
  padding: 12px 14px; margin-bottom: var(--gap);
}
/* HUD corners: two bright brackets, top-left and bottom-right. */
.hud::before, .hud::after { content: ""; position: absolute; width: 10px; height: 10px; border: 1.5px solid var(--accent); opacity: .55; pointer-events: none; }
.hud::before { top: -1px; left: -1px; border-right: 0; border-bottom: 0; border-top-left-radius: var(--r); }
.hud::after { bottom: -1px; right: -1px; border-left: 0; border-top: 0; border-bottom-right-radius: var(--r); }

.card-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; flex-wrap: wrap; margin-bottom: 9px; min-height: 22px; }
.card-head h2 {
  display: flex; align-items: center; gap: 8px; margin: 0; line-height: 1.3;
  font-size: 11px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--ink);
}
.card-head h2 .ico { color: var(--accent); width: 14px; height: 14px; }
.card > h2 { margin-bottom: 8px; }
.card-aside { font-size: 11px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.grid { display: grid; gap: var(--gap); grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr)); }
.grid.cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grid .card { margin-bottom: 0; }

/* --------------------------------------------------------------- stats --- */

.statrow { display: grid; gap: 10px; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); }
.statbox {
  position: relative; display: grid; grid-template-columns: 34px minmax(0, 1fr); gap: 0 10px; align-items: center;
  background: linear-gradient(180deg, var(--card-a), var(--card-b));
  border: 1px solid var(--line); border-radius: var(--r); padding: 7px 12px;
}
.statbox-ico {
  grid-row: span 2; width: 34px; height: 34px; border-radius: 50%; display: grid; place-items: center;
  color: var(--accent); background: var(--accent-soft); border: 1px solid var(--line-strong);
}
.statbox-ico svg { width: 16px; height: 16px; }
.statbox-value { color: var(--ink); font: 650 19px/1.15 var(--mono); }
.statbox-label { font-size: 11px; color: var(--muted); letter-spacing: .06em; text-transform: uppercase; }

.meter + .meter { margin-top: 10px; }
.meter-head { display: flex; justify-content: space-between; font-size: 12.5px; margin-bottom: 5px; }
.bar { height: 5px; background: var(--line); border-radius: 3px; overflow: hidden; }
.fill { height: 100%; background: var(--accent-2); }
.fill.warn { background: var(--warn); }
.fill.bad { background: var(--bad); }

/* -------------------------------------------------------------- tables --- */

table { width: 100%; border-collapse: collapse; }
.rows { border-collapse: separate; border-spacing: 0; font-size: 13px; }
.rows th {
  text-align: left; font: 700 10.5px var(--ui); letter-spacing: .1em; text-transform: uppercase;
  color: var(--muted); padding: 7px 10px; border-bottom: 1px solid var(--line-strong); white-space: nowrap;
  position: sticky; top: 0; z-index: 1; background: var(--panel);
}
.rows td { padding: 8px 10px; border-bottom: 1px dashed var(--line); vertical-align: middle; color: var(--body); }
.rows tr:last-child td { border-bottom: 0; }
.rows tbody tr:hover td { background: var(--row-hover); }
.rows td.mono, .rows td .mono { font-size: 12px; }

.kv { border-collapse: collapse; }
.kv td { padding: 5px 0; border-bottom: 1px dashed var(--line); vertical-align: top; font-size: 13px; color: var(--ink); }
.kv tr:last-child td { border-bottom: 0; }
.kv td:first-child { color: var(--muted); width: 40%; padding-right: 10px; font-size: 12.5px; }

/* --------------------------------------------------------------- pills --- */

.pill {
  display: inline-flex; align-items: center; gap: 6px; white-space: nowrap;
  font: 700 10.5px/1.5 var(--ui); letter-spacing: .07em; text-transform: uppercase;
  padding: 2px 9px 2px 8px; border-radius: 999px;
  border: 1px solid var(--line-strong); color: var(--accent); background: var(--accent-soft);
}
.pill::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: currentColor; box-shadow: 0 0 6px currentColor; flex: none; }
.pill.ok { color: var(--accent); }
.pill.bad { color: var(--bad); border-color: var(--bad-line); background: var(--bad-tint); }
.pill.warn { color: var(--warn); border-color: var(--warn-line); background: var(--warn-tint); }
.pill.neutral { color: var(--muted); border-color: var(--line); background: none; }
.pill.neutral::before { box-shadow: none; }
.pill.nodot::before, .pill.act::before { display: none; }
.pill.act { font: 600 11px var(--mono); text-transform: none; letter-spacing: 0; }
.pill.work::before { animation: blink 1.4s infinite; }
.pill.mono { font-family: var(--mono); }

.dot { width: 8px; height: 8px; border-radius: 50%; display: inline-block; flex: none; background: var(--accent-2); box-shadow: 0 0 8px var(--accent-2); }
.dot.warn { background: var(--warn); box-shadow: 0 0 8px var(--warn); }
.dot.bad { background: var(--bad); box-shadow: 0 0 8px var(--bad); }
.dot.off { background: var(--off); box-shadow: none; }

.tag {
  display: inline-block; font-size: 11px; padding: 1px 7px; border-radius: 6px; margin-left: 6px;
  background: var(--accent-soft); color: var(--accent); border: 1px solid var(--line);
}
.tag.warn-tag { background: var(--warn-tint); color: var(--warn); border-color: var(--warn-line); }

/* ------------------------------------------------------------- buttons --- */

.btn {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 12px; border-radius: 8px;
  border: 1px solid var(--line-strong); background: var(--panel);
  color: var(--body); font: inherit; font-size: 12.5px; font-weight: 650; line-height: 1.3;
  cursor: pointer; white-space: nowrap;
  transition: border-color var(--fast) var(--ease), color var(--fast) var(--ease), box-shadow var(--fast) var(--ease), transform var(--fast) var(--ease);
}
.btn .ico { width: 14px; height: 14px; }
.btn:hover { color: var(--ink); border-color: var(--accent); text-decoration: none; }
.btn:active:not([disabled]) { transform: translateY(1px); }
.btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.btn.primary { background: linear-gradient(180deg, var(--btn-a), var(--btn-b)); color: var(--on-accent); border-color: transparent; box-shadow: 0 0 16px -6px var(--glow); }
.btn.primary:hover { filter: brightness(1.06); color: var(--on-accent); }
.btn.danger { color: var(--bad); border-color: var(--bad-line); background: var(--bad-tint); }
.btn.danger:hover { border-color: var(--bad); color: var(--bad); }
.btn.small { padding: 4px 9px; font-size: 12px; border-radius: 7px; }
.btn[disabled], .btn[aria-disabled="true"] { opacity: .45; cursor: not-allowed; }

.btn-row { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; margin-top: 12px; }
.num-short { width: 7em; max-width: 100%; display: inline-block; margin-left: 6px; }
.card-head .btn-row { margin-top: 0; }
form.inline { display: inline; margin: 0; }

/* --------------------------------------------------------------- forms --- */

label { display: block; margin: 0 0 14px; font-size: 13px; font-weight: 600; color: var(--ink); }
label .hint { display: block; font-weight: 400; color: var(--muted); font-size: 12px; margin-top: 2px; }

input:not([type=checkbox], [type=radio], [type=file], [type=submit], [type=button],
          [type=reset], [type=image], [type=range], [type=color], [type=hidden]),
select, textarea {
  width: 100%; margin-top: 5px; padding: 8px 11px;
  background: var(--input-bg); color: var(--ink);
  border: 1px solid var(--line-strong); border-radius: 9px;
  font: inherit; font-size: 13.5px; font-weight: 400;
}
input:focus, select:focus, textarea:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
input[type=checkbox], input[type=radio] { accent-color: var(--accent-2); }
textarea { resize: vertical; }
textarea.code { font-family: var(--mono); font-size: 12.5px; line-height: 1.55; tab-size: 2; }

label.check { display: flex; align-items: center; gap: 9px; font-weight: 400; }
label.check input { width: auto; margin: 0; }

.searchbar { display: flex; gap: 8px; margin-bottom: 14px; }
.searchbar input { flex: 1; margin: 0; }

/* -------------------------------------------------------------- alerts --- */

.alert {
  display: flex; gap: 10px; align-items: flex-start;
  padding: 8px 12px; border-radius: 10px; border: 1px solid; margin-bottom: var(--gap);
  font-size: 13px; color: var(--ink);
}
.alert .ico { margin-top: 1px; }
.alert a { font-weight: 650; color: var(--accent); text-decoration: underline; }
.alert.good { background: var(--accent-soft); border-color: var(--line-strong); }
.alert.good .ico { color: var(--accent); }
.alert.bad { background: var(--bad-tint); border-color: var(--bad-line); }
.alert.bad .ico { color: var(--bad); }
.alert.warn { background: var(--warn-tint-2); border-color: var(--warn-line); }
.alert.warn .ico { color: var(--warn); }
.alert.info { background: var(--info-tint); border-color: var(--info-line); }
.alert.info .ico { color: var(--accent); }

/* --------------------------------------------------------------- misc ---- */

pre {
  background: var(--code-bg); border: 1px solid var(--line);
  border-radius: 9px; padding: 10px 12px; overflow-x: auto;
  font-family: var(--mono); font-size: 12px; line-height: 1.6; color: var(--ink);
  margin: 0 0 12px;
}
code { font: .92em var(--mono); background: var(--accent-soft); border: 1px solid var(--line); padding: 0 5px; border-radius: 4px; color: var(--ink); }
pre code { background: none; border: 0; padding: 0; }
.secret { display: inline-block; font-size: 15px; letter-spacing: .06em; padding: 4px 9px; }

.empty { text-align: center; padding: 26px 20px; }
.empty-ico { display: inline-grid; place-items: center; width: 52px; height: 52px;
  border-radius: 50%; background: var(--accent-soft); border: 1px solid var(--line-strong); color: var(--accent); margin-bottom: 10px; }
.empty-title { font-weight: 700; color: var(--ink); margin: 0 0 4px; }

.tabs { display: flex; gap: 2px; border-bottom: 1px solid var(--line); flex-wrap: wrap; }
.tabs a { display: flex; align-items: center; gap: 7px; padding: 7px 14px; color: var(--muted); border-bottom: 2px solid transparent; margin-bottom: -1px; font-size: 13px; font-weight: 650; }
.tabs a .ico { width: 14px; height: 14px; }
.tabs a:hover { color: var(--ink); text-decoration: none; }
.tabs a.on { color: var(--accent); border-bottom-color: var(--accent); }

.logs { max-height: 620px; overflow: auto; font-size: 11.5px; line-height: 1.55; }

.hits { display: flex; flex-direction: column; gap: 10px; }
.hit { border: 1px solid var(--line); border-radius: 10px; background: var(--code-bg); padding: 10px 12px; }
.hit-head { display: flex; align-items: baseline; gap: 8px; margin-bottom: 6px; flex-wrap: wrap; }
.hit-head .right { margin-left: auto; }
.snippet { margin: 0; white-space: pre-wrap; word-break: break-word; background: none;
  border: 0; padding: 0; font-size: 12.5px; max-height: 200px; overflow: auto; }

.danger-zone { border-color: var(--bad-line); }
.danger-zone h2, .danger-zone h2 .ico { color: var(--bad); }

.toc { display: flex; flex-wrap: wrap; gap: 8px 18px; }
.diagram { line-height: 1.45; font-size: 12.5px; }
ol.steps { padding-left: 20px; margin: 0; }
ol.steps li { margin: 5px 0; }
.card ul { padding-left: 20px; margin: 0; }
.card ul li { margin: 5px 0; }

@keyframes spin { to { transform: rotate(360deg); } }

/* --------------------------------------------------- add-on catalogue ---- */

.addon-grid { display: grid; gap: 14px; grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr)); }
.addon {
  border: 1px solid var(--line); border-radius: var(--radius);
  padding: 14px 16px; background: var(--surface); display: flex; flex-direction: column; gap: 8px;
}
.addon.on { border-color: var(--brand); background: var(--brand-tint); }
.addon.unavailable { opacity: .62; }
.addon-top { display: flex; align-items: center; gap: 10px; }
.addon-ico { display: grid; place-items: center; width: 34px; height: 34px; flex: none;
  border-radius: var(--radius); background: var(--brand-tint); color: var(--brand-deep); }
.addon.on .addon-ico { background: var(--brand); color: var(--on-brand); }
.addon-name { font-weight: 700; color: var(--ink); font-size: 14px; }
.addon-cat { font-size: 11px; color: var(--muted); text-transform: uppercase; letter-spacing: .06em; }
.addon-desc { font-size: 13px; margin: 0; }
.addon-foot { margin-top: auto; display: flex; align-items: center; justify-content: space-between; gap: 8px; }

/* -------------------------------------------------------------- mobile --- */

/* =========================================================== small screens ==
 *
 * One breakpoint, at 900px. Below it the two columns stop being columns: the
 * sidebar becomes a drawer over the page, and the content column takes the
 * whole width. Everything here is additive -- no rule above this line is
 * written for a phone, so the desktop layout is exactly what it always was.
 *
 * The drawer is not a nicety. The previous version turned the sidebar into a
 * horizontal strip of icons with the category labels hidden, which fitted but
 * meant a rail of unlabelled glyphs was the only way to navigate. A panel that
 * slides in keeps the real thing -- labels, groups, the lot.
 */

.nav-toggle, .chats-toggle {
  display: none;                     /* a drawer control, and there is no drawer here */
  align-items: center; justify-content: center;
  flex: none; width: 38px; height: 38px;
  padding: 0; margin: 0;
  background: none; border: 1px solid transparent; border-radius: var(--radius);
  color: var(--body); cursor: pointer;
}
.nav-toggle:hover, .chats-toggle:hover { background: var(--brand-tint); color: var(--ink); }

/* Covers the page while a drawer is open. Kept out of the layer entirely when
   closed -- `hidden` is set from app.js -- so it can never swallow a tap. */
.nav-scrim, .chat-scrim {
  position: fixed; inset: 0; z-index: 39;
  background: var(--scrim);
  opacity: 0; pointer-events: none;
  transition: opacity var(--fast) var(--ease);
}

@media (max-width: 900px) {
  /* ---- the fix that makes everything else possible ----------------------
     .layout is align-items: flex-start, which on a row is right and in a
     column means "size children to their content". So one wide table made the
     content column wider than the phone, and every heading and card stretched
     with it. Every page overflowed; the table was only ever the excuse. */
  .layout { display: block; }
  .content { width: 100%; min-width: 0; max-width: 100%; padding: 16px 14px 40px; }

  /* ---- top bar ---- */
  .topbar { gap: 8px; padding: 0 10px; }
  .nav-toggle { display: flex; }
  .brand-text { display: none; }
  .top-tab { padding: 0 11px; }
  .top-tab span { display: none; }
  .top-right { gap: 6px; }
  /* The status chip ("3 running", "up 4d") is a glance-value on a wide screen
     and the thing that overflows the bar on a narrow one. Every page that shows
     it also states the same number in its own first card. */
  .top-right .chip, .top-right .clock, .top-right .sys-chip { display: none; }
  .side-foot { display: none; }
  .whoami { padding: 4px 6px; }
  .whoami-role { display: none; }
  .whoami-name { max-width: 74px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .logout button { padding: 7px 9px; }
  .logout button span { display: none; }

  /* ---- the sidebar, as a drawer ---- */
  .sidebar {
    position: fixed; z-index: 40;
    top: var(--topbar-h); left: 0; bottom: 0;
    width: min(282px, 84vw); height: auto;
    background: var(--panel);
    padding: 0 0 env(safe-area-inset-bottom);
    transform: translateX(-100%);
    transition: transform var(--fast) var(--ease);
    box-shadow: var(--shadow-md);
    overscroll-behavior: contain;
  }
  :root.nav-open .sidebar { transform: none; }
  :root.nav-open .nav-scrim { opacity: 1; pointer-events: auto; }
  /* The page must not scroll under an open drawer; the drawer scrolls instead. */
  :root.nav-open, :root.chats-open,
  :root.nav-open body, :root.chats-open body { overflow: hidden; }

  /* ---- content density ---- */
  .page-head { gap: 10px; }
  h1 { font-size: 19px; }
  .card { padding: 14px; }
  .statrow { grid-template-columns: repeat(auto-fit, minmax(136px, 1fr)); gap: 10px; }
  /* min() in the base track keeps auto-fit grids from forcing a 300px column
     onto a 274px screen; this collapses the fixed two-column ones as well. */
  .grid.cols-2 { grid-template-columns: 1fr; }

  /* ---- anything wider than a phone scrolls inside its own box ----
     A table of six columns cannot become narrow and must not be truncated:
     both would cost information. So it keeps its shape and scrolls sideways
     within the card, which leaves the page itself scrolling only one way. */
  .table-scroll, .card > table, .card > form > table {
    display: block; width: 100%; overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior-x: contain;
  }
  /* Key/value tables are two columns and genuinely do narrow, so they stack
     instead -- a label above its value reads better than either half clipped. */
  table.kv, table.kv tbody, table.kv tr, table.kv td { display: block; width: auto; min-width: 0; }
  table.kv tr { padding: 9px 0; border-bottom: 1px solid var(--line); }
  table.kv tr:last-child { border-bottom: 0; }
  table.kv td:first-child { color: var(--muted); font-size: 12.5px; padding: 0 0 2px; }
  table.kv td { padding: 0; border: 0; }

  pre, .secret, .logs, .diagram { max-width: 100%; overflow-x: auto; }
  /* Long unbroken strings -- a token preview, a path, an address -- would
     otherwise set a minimum width for the whole column. */
  .mono, code, .chip, .pill { overflow-wrap: anywhere; }

  /* ---- touch targets ----
     40px is the smallest thing a thumb hits reliably; several of these were
     28-32 because a mouse does not need more. */
  .btn { padding: 9px 14px; }
  .btn.small { padding: 8px 12px; font-size: 12.5px; }
  .side-item { padding: 10px 12px; }
  .menu-item { padding: 11px 14px; }
  .row-end, .stack-actions { display: flex; flex-wrap: wrap; gap: 6px; justify-content: flex-end; }
  .btn-row .btn { flex: 1 1 auto; justify-content: center; }
}

/* The narrowest phones still in use, around 320px. The top bar is the only
   thing that does not fit by then -- five fixed-width controls and no text to
   wrap -- so it gives up spacing and most of the username rather than dropping
   a control somebody would then have no way to reach. */
@media (max-width: 380px) {
  .topbar { gap: 5px; padding: 0 8px; }
  .top-tab { padding: 0 8px; }
  .whoami { padding: 4px 4px; }
  .whoami-name { max-width: 48px; }
  .content { padding: 14px 11px 36px; }
  .card { padding: 12px; }
  .statrow { grid-template-columns: repeat(auto-fit, minmax(118px, 1fr)); }
}

/* A phone in landscape, or a small tablet: the drawer still applies, but the
   content column can breathe and two-column grids are worth keeping. */
@media (min-width: 601px) and (max-width: 900px) {
  .content { padding: 20px 20px 44px; }
  .grid.cols-2 { grid-template-columns: 1fr 1fr; }
}

/* Channel type: show only the fields that belong to the selected transport.
   Pure CSS via :has() rather than a script, because the CSP forbids inline
   handlers and this is not worth an external file. Browsers without :has()
   simply see both sections, which is the old behaviour and still correct. */
form:has(input[name="type"][value="telegram"]:checked) .only-whatsapp { display: none; }
form:has(input[name="type"][value="whatsapp"]:checked) .only-telegram { display: none; }

/* Keep the type cards in step with the radio inside them. */
label.addon:has(input[type="radio"]:checked),
label.addon:has(input[type="checkbox"]:checked) {
  border-color: var(--brand);
  background: var(--brand-tint);
}
label.addon:has(input[type="radio"]:checked) .addon-ico,
label.addon:has(input[type="checkbox"]:checked) .addon-ico {
  background: var(--brand);
  color: var(--on-brand);
}

/* ------------------------------------------------- CSP-safe utilities ---- */
/* The CSP is style-src 'self', so a style="" attribute is blocked outright.
   Everything that would have been an inline style lives here instead. */

.w-full { width: 100%; }
.center { text-align: center; }
.clickable { cursor: pointer; }
.static-cursor { cursor: default; }
.warn-text { color: var(--warn); }
.inline-badge { display: inline-flex; align-items: center; gap: 6px; }
.row-end { display: flex; gap: 6px; justify-content: flex-end; }
.stack-actions { margin-top: 6px; }

.mt-8 { margin-top: 8px; }
.mt-12 { margin-top: 12px; }
.mt-16 { margin-top: 16px; }
.mb-14 { margin-bottom: 14px; }
.mb-18 { margin-bottom: 18px; }

/* Radios and checkboxes must not stretch like text inputs. */
.pick { width: auto; margin: 0; }

/* --------------------------------------------------------------- console --- */

/* The chat owns the whole viewport below the top bar: its own list on the left,
   a scrolling transcript, and a composer pinned to the bottom. Nothing here
   scrolls the page itself -- only the transcript moves. */
.layout.bare { height: calc(100vh - var(--topbar-h)); }
.content.flush { padding: 0; height: 100%; overflow: hidden; }

.chat-layout { display: flex; height: 100%; min-height: 0; }

.chat-list {
  flex: none; width: 258px;
  display: flex; flex-direction: column; gap: 12px;
  padding: 14px 10px;
  border-right: 1px solid var(--line);
  background: var(--surface-2);
  overflow-y: auto;
  scrollbar-width: thin;
  scrollbar-color: var(--line-strong) transparent;
}
.chat-new { margin: 0; }

.chat-filter {
  display: flex; align-items: center; gap: 7px;
  padding: 0 10px; border-radius: 8px;
  border: 1px solid var(--line); background: var(--surface);
  color: var(--muted);
  transition: border-color var(--fast) var(--ease), box-shadow var(--fast) var(--ease);
}
.chat-filter:focus-within { border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-tint); }
.chat-filter input {
  margin: 0; border: 0; background: none; box-shadow: none;
  padding: 7px 0; font-size: 13px; width: 100%;
}
.chat-filter input:focus { outline: none; box-shadow: none; }

.chat-items { display: flex; flex-direction: column; gap: 2px; }
.chat-none { padding: 10px; margin: 0; }

.chat-item {
  display: flex; flex-direction: column; gap: 1px;
  padding: 8px 11px; border-radius: 8px;
  color: var(--body);
  position: relative;
  transition: background var(--fast) var(--ease);
}
.chat-item:hover { background: var(--brand-tint); text-decoration: none; }
.chat-item.on { background: var(--brand-tint); }
/* A bar rather than a border, so the row does not shift by a pixel when it
   becomes the current one. */
.chat-item.on::before {
  content: ""; position: absolute; left: 3px; top: 8px; bottom: 8px;
  width: 3px; border-radius: 999px; background: var(--brand);
}
.chat-title {
  font-size: 13px; font-weight: 600; color: var(--ink);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.chat-item.on .chat-title { color: var(--brand-deep); }
.chat-meta { font-size: 11px; color: var(--muted); }

/* Archived chats live behind a disclosure with their count on it, because the
   count is the only reason anybody opens it. */
.chat-archive { margin-top: 2px; border-top: 1px solid var(--line); padding-top: 10px; }
.chat-archive > summary {
  display: flex; align-items: center; gap: 7px;
  padding: 5px 11px; border-radius: 8px;
  font-size: 11px; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase;
  color: var(--muted); cursor: pointer; list-style: none;
}
.chat-archive > summary::-webkit-details-marker { display: none; }
.chat-archive > summary:hover { background: var(--brand-tint); color: var(--brand-deep); }
.chat-archive > summary .count {
  margin-left: auto; font-size: 11px; letter-spacing: 0;
  background: var(--line); color: var(--body);
  padding: 0 6px; border-radius: 999px; font-weight: 600;
}
.chat-archive > nav { margin-top: 4px; }
.chat-archive .chat-title { font-weight: 500; color: var(--body); }

/* ------------------------------------------------------------------ menu -- */

.menu { position: relative; flex: none; }
.menu > summary {
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; border-radius: 8px;
  color: var(--muted); cursor: pointer; list-style: none;
  transition: background var(--fast) var(--ease), color var(--fast) var(--ease);
}
.menu > summary::-webkit-details-marker { display: none; }
.menu > summary:hover,
.menu[open] > summary { background: var(--brand-tint); color: var(--ink); }
.menu-pop {
  position: absolute; right: 0; top: calc(100% + 6px); z-index: 40;
  min-width: 232px; padding: 8px;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: 10px; box-shadow: var(--shadow-md);
  animation: pop 120ms var(--ease) both;
}
@keyframes pop {
  from { opacity: 0; transform: translateY(-4px) scale(.985); }
  to   { opacity: 1; transform: none; }
}
.menu-pop form { margin: 0; }
.menu-rename { display: flex; flex-direction: column; gap: 7px; padding: 2px 2px 8px; }
.menu-rename label { margin: 0; font-size: 11px; font-weight: 700; color: var(--muted);
  text-transform: uppercase; letter-spacing: 0.05em; }
.menu-rename input { margin-top: 4px; font-size: 13px; padding: 6px 9px; }
.menu-sep { height: 1px; background: var(--line); margin: 2px 0 6px; }
.menu-item {
  display: flex; align-items: center; gap: 9px; width: 100%;
  padding: 7px 9px; border: 0; border-radius: 7px;
  background: none; color: var(--body);
  font: inherit; font-size: 13px; font-weight: 500;
  cursor: pointer; text-align: left;
  transition: background var(--fast) var(--ease), color var(--fast) var(--ease);
}
.menu-item:hover { background: var(--brand-tint); color: var(--ink); }
.menu-item.danger { color: var(--bad); }
.menu-item.danger:hover { background: var(--bad-tint); }

.chat-main { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.chat-empty { margin: auto; max-width: 460px; padding: 24px; }

.chat-topline {
  display: flex; align-items: center; gap: 12px;
  padding: 9px 18px; border-bottom: 1px solid var(--line);
  background: var(--surface);
}
.chat-name {
  flex: 1; min-width: 0;
  font-size: 13.5px; font-weight: 600; color: var(--ink);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* The full-access warning, folded away. It matters once -- when you first
   realise what this chat can do -- and after that it is a line you scroll past
   every time. So: one quiet line, open it if you want it. */
.chat-notice {
  margin: 10px 18px 0;
  border: 1px solid var(--warn-line); border-radius: var(--radius);
  background: var(--warn-tint-2);
  font-size: 12.5px;
}
.chat-notice > summary {
  display: flex; align-items: center; gap: 7px;
  padding: 6px 12px; cursor: pointer;
  color: var(--warn); font-weight: 600;
  list-style: none;
}
.chat-notice > summary::-webkit-details-marker { display: none; }
.chat-notice > summary:hover { background: var(--warn-tint); border-radius: var(--radius); }
.chat-notice > summary svg { flex: none; }
.chat-notice p { margin: 0 12px 10px; color: var(--body); line-height: 1.55; }
.chat-notice p:first-of-type { margin-top: 2px; }

.chat-scroll {
  flex: 1; min-height: 0; overflow-y: auto;
  padding: 22px 22px 10px;
  display: flex; flex-direction: column; gap: 14px;
  /* The transcript is the only thing on the page that repaints continuously.
     Telling the compositor so keeps a long streaming answer off the main
     thread's critical path. */
  contain: layout paint;
  overscroll-behavior: contain;
  scrollbar-width: thin;
  scrollbar-color: var(--line-strong) transparent;
}
.chat-scroll::-webkit-scrollbar { width: 10px; }
.chat-scroll::-webkit-scrollbar-thumb {
  background: var(--line-strong); border-radius: 999px;
  border: 3px solid var(--ground); background-clip: padding-box;
}
.chat-scroll::-webkit-scrollbar-track { background: transparent; }
.chat-hint { margin: auto; max-width: 520px; text-align: center; }
.chat-hint .chips { justify-content: center; margin-top: 14px; }

.msg { display: flex; animation: rise var(--fast) var(--ease) both; }
@keyframes rise {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: none; }
}

.msg.user { justify-content: flex-end; }
.msg .bubble {
  max-width: min(760px, 82%);
  padding: 10px 15px; border-radius: 14px;
  word-wrap: break-word; overflow-wrap: anywhere;
  font-size: 14px; line-height: 1.6;
}
.msg.user .bubble {
  background: var(--brand); color: var(--on-brand);
  border-bottom-right-radius: 5px;
  white-space: pre-wrap;
}

/* The answer is the one thing here that is read rather than scanned, so it gets
   a reading face, a longer measure and looser leading than the rest of the app.
   No border and no card: prose does not need a box drawn round it. */
.msg.assistant .bubble {
  background: none; color: var(--ink);
  padding: 2px 0 2px 2px;
  max-width: 74ch;
  font-family: var(--reading);
  font-size: 15.5px; line-height: 1.72;
}
.msg.assistant .bubble.streaming::after {
  content: ""; display: inline-block;
  width: 2px; height: 1.05em; margin-left: 2px;
  vertical-align: -0.16em; background: var(--brand);
  animation: blink 1.1s steps(1) infinite;
}
@keyframes blink { 50% { opacity: 0; } }

/* Markdown inside an answer. Restrained: the shapes exist so a list reads as a
   list, not so the reply looks like a document. */
.msg.assistant .bubble > *:first-child { margin-top: 0; }
.msg.assistant .bubble > *:last-child { margin-bottom: 0; }
.msg.assistant .bubble p { margin: 0 0 0.85em; }
.msg.assistant .bubble ul,
.msg.assistant .bubble ol { margin: 0 0 0.85em; padding-left: 1.35em; }
.msg.assistant .bubble li { margin: 0.2em 0; }
.msg.assistant .bubble h1,
.msg.assistant .bubble h2,
.msg.assistant .bubble h3 {
  font-family: var(--ui); font-weight: 650;
  margin: 1.3em 0 0.5em; font-size: 15px;
}
.msg.assistant .bubble strong { font-weight: 650; color: var(--ink); }
.msg.assistant .bubble code {
  font-family: var(--mono); font-size: 0.855em;
  background: var(--brand-tint); color: var(--brand-deep);
  padding: 0.1em 0.38em; border-radius: 4px;
}
.msg.assistant .bubble pre {
  margin: 0 0 0.85em; padding: 11px 13px;
  background: var(--brand-dark); color: var(--code-ink);
  border-radius: 9px; overflow-x: auto;
  font-size: 12.5px; line-height: 1.6;
}
.msg.assistant .bubble pre code {
  background: none; color: inherit; padding: 0; font-size: inherit;
}
.msg.assistant .bubble blockquote {
  margin: 0 0 0.85em; padding-left: 12px;
  border-left: 2px solid var(--line-strong); color: var(--body);
}
.msg.assistant .bubble hr { border: 0; border-top: 1px solid var(--line); margin: 1.2em 0; }

.msg.system .note {
  font-size: 12.5px; color: var(--warn);
  background: var(--warn-tint); border: 1px solid var(--warn-line);
  padding: 8px 12px; border-radius: 9px;
  white-space: pre-wrap;
}
.msg-meta {
  font-size: 11px; color: var(--muted); padding-left: 4px;
  opacity: 0; animation: fade-in 240ms var(--ease) 60ms forwards;
}
@keyframes fade-in { to { opacity: 1; } }

/* What it did, folded to one line. The steps are the only record of what
   actually happened, so they are hidden rather than dropped. */
.activity { font-size: 12px; }
.activity > summary {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 10px; border-radius: 999px;
  background: var(--surface); border: 1px solid var(--line);
  color: var(--muted); cursor: pointer; list-style: none;
  font-variant-numeric: tabular-nums;
}
.activity > summary::-webkit-details-marker { display: none; }
.activity > summary::before { content: "▸"; font-size: 10px; }
.activity[open] > summary::before { content: "▾"; }
.activity > summary:hover { border-color: var(--brand); color: var(--brand-deep); }
.activity-body {
  margin: 6px 0 0 10px; padding-left: 10px;
  border-left: 2px solid var(--line);
  display: flex; flex-direction: column; gap: 2px;
}

/* One line per tool call. Deliberately quiet: it is context, not content. */
.tool-row {
  display: flex; gap: 8px; align-items: baseline;
  font-size: 12px; color: var(--muted);
  padding: 2px 4px;
}
.tool-name {
  font-weight: 700; color: var(--brand-deep);
  background: var(--brand-tint); border-radius: 4px; padding: 1px 7px;
  flex: none;
}
.tool-arg {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* The composer: one bordered box holding the message field and, beneath it, the
   controls that decide how the next message is answered. Keeping them together
   is the point -- model, effort, reach and directory are properties of what you
   are about to send, so they belong where you are about to send it rather than
   in a header you stop noticing. */
.chat-compose { flex: none; padding: 10px 18px 12px; }

.composer {
  border: 1px solid var(--line); border-radius: 12px;
  background: var(--surface);
  transition: border-color .12s ease, box-shadow .12s ease;
}
.composer:focus-within {
  border-color: var(--brand);
  box-shadow: 0 0 0 3px var(--brand-tint);
}
.composer textarea {
  display: block; width: 100%; margin: 0;
  border: 0; background: none; box-shadow: none;
  padding: 12px 14px 8px;
  font-size: 14px; line-height: 1.55;
  resize: none; overflow-y: auto; min-height: 54px; max-height: 220px;
}
.composer textarea:focus { outline: none; box-shadow: none; }

/* One row: what the chat is, on the left; what you do with it, on the right.
 *
 * It was nine controls in a single wrapping row, which at 1024px found seven
 * vertical positions and put Send on a line of its own. Splitting it into two
 * rows fixed the raggedness and introduced a different problem -- two long
 * stretches of nothing, one at the end of each row, with the eye having to
 * cross them. One row with the two groups pushed apart has no voids in it,
 * and it gives the transcript back the second row as well.
 *
 * Below 700px there is not room for both groups side by side, and there it
 * does become two rows -- but by then it is a phone and a stacked bar is what
 * you want anyway.
 */
.composer-bar {
  display: flex; align-items: center; gap: 10px;
  padding: 5px 8px 7px 8px;
}

/* The settings shrink and scroll; the actions never move. A narrow window
   should cost you a swipe to reach the model picker, not the Send button. */
.composer-settings {
  display: flex; align-items: center; gap: 3px;
  flex: 0 1 auto; min-width: 0;
  flex-wrap: nowrap; overflow-x: auto; overscroll-behavior-x: contain;
  scrollbar-width: none; padding-bottom: 1px;
}
.composer-settings::-webkit-scrollbar { display: none; }

.composer-actions { display: flex; align-items: center; gap: 6px; flex: none; margin-left: auto; }
/* The status text used to hold the two groups apart with an auto margin. The
   groups do that themselves now, and leaving it would open a second void
   inside the actions. */
.composer-actions .composer-status { margin-left: 0; }

/* Live is a mode; the rest are things you do once. The rule says so without
   spending a word on it. */
.composer-actions .live-controls {
  padding-right: 8px; margin-right: 2px;
  border-right: 1px solid var(--line);
}

/* One height for everything in the bar, so the row reads as a row. They were
   26, 29, 30 and 32 before, which is most of why it looked assembled rather
   than designed. */
.composer-settings .pick,
.composer-settings .root-toggle,
.composer-settings .toggle { height: 28px; }
.composer-actions .icon-btn { width: 30px; height: 30px; }
/* Except this one, which carries a word. The square rule above is more
   specific than .live-btn's own `width: auto`, so it won -- and the button
   rendered as a 30px box with "Live" clipped inside it. */
.composer-actions .live-btn { width: auto; }
.composer-actions .btn.small { height: 30px; padding: 0 12px; }

@media (max-width: 700px) {
  .composer-bar { flex-direction: column; align-items: stretch; gap: 5px; }
  .composer-actions { margin-left: 0; }
  .composer-actions .composer-status { margin-left: auto; }
}

.chat-controls { display: flex; align-items: center; gap: 4px; margin: 0; min-width: 0; flex: 0 0 auto; flex-wrap: nowrap; }
/* Nothing in the strip stretches. The gap between the settings and the buttons
   is made by the status text's auto margin, so each control stays the width of
   what it says. */
.chat-controls.grow { flex: 0 1 auto; }

/* The gate on a root-enabled chat. Centred and alone, because it is the whole
   page: the transcript behind it was never sent. */
.chat-lock { flex: 1; display: grid; place-items: center; padding: 24px; }
.lock-card {
  width: 100%; max-width: 380px; text-align: center;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: 12px; padding: 26px 24px;
  box-shadow: var(--shadow-md);
  animation: rise 160ms var(--ease) both;
}
.lock-ico.warn { background: var(--warn-tint); }
.lock-ico {
  display: grid; place-items: center;
  width: 52px; height: 52px; margin: 0 auto 12px;
  border-radius: 50%; background: var(--warn-tint-2); color: var(--warn);
  border: 1px solid var(--warn-line);
}
.lock-card h2 { margin-bottom: 8px; }
.lock-card p { margin: 0 0 16px; }
.lock-card form { margin: 0; text-align: left; }
.lock-card .alert { text-align: left; margin-bottom: 14px; }
.lock-card input {
  font-family: var(--mono); font-size: 20px; letter-spacing: .3em;
  text-align: center; padding: 10px;
}
.lock-card p.small { margin: 14px 0 0; }


/* Root on or off for this chat. A switch rather than another dropdown: it is
   the one control here with two states and real consequences, and it should
   look like something you flip deliberately. */
.root-toggle { margin: 0; flex: none; }
/* Off is a link to a confirmation page rather than a panel that unfolds in
   place. This control sits on the bottom edge of a pane that clips, which a
   popover kept losing an argument with, and turning root on reads better as a
   screen than as a hover. */
a.toggle { text-decoration: none; }
a.toggle:hover { text-decoration: none; border-color: var(--line-strong); }
.toggle {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 3px 9px 3px 5px; border-radius: 999px;
  border: 1px solid var(--line); background: var(--surface);
  color: var(--muted); font: inherit; font-size: 11.5px; font-weight: 700;
  letter-spacing: 0.04em; text-transform: uppercase;
  cursor: pointer;
  transition: background var(--fast) var(--ease), border-color var(--fast) var(--ease),
              color var(--fast) var(--ease);
}
.toggle:hover { border-color: var(--line-strong); }
.toggle:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
.toggle-track {
  position: relative; flex: none;
  width: 26px; height: 15px; border-radius: 999px;
  background: var(--line-strong);
  transition: background var(--fast) var(--ease);
}
.toggle-knob {
  position: absolute; top: 2px; left: 2px;
  width: 11px; height: 11px; border-radius: 50%;
  background: var(--surface); box-shadow: var(--shadow-sm);
  transition: transform var(--fast) var(--ease);
}
.toggle.on { color: var(--warn); border-color: var(--warn-line); background: var(--warn-tint-2); }
.toggle.on:hover { border-color: var(--warn); }
.toggle.on .toggle-track { background: var(--warn); }
.toggle.on .toggle-knob { transform: translateX(11px); }

/* A picker that reads as a label until you go near it. Borrowed shape from the
   status line of a terminal tool: an icon, a word, and no chrome competing with
   the message you are writing. */
.pick {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 2px 4px 2px 7px; border-radius: 7px;
  border: 1px solid transparent;
  color: var(--muted); min-width: 0;
}
.pick:hover { border-color: var(--line); background: var(--bg); }
.pick svg { flex: none; opacity: .75; }
.pick select {
  margin: 0; border: 0; background: none; box-shadow: none;
  padding: 3px 2px; font-size: 12px; font-weight: 600;
  color: var(--body); width: auto; max-width: 190px; cursor: pointer;
}
.pick select:focus { outline: none; box-shadow: none; }
.pick select:disabled { cursor: default; opacity: .8; }
/* The directory picker gets a fixed width, and the reason is a quirk worth
   naming: `width: auto` on a <select> sizes it to its *longest option*, not to
   the one that is selected. The list holds paths like
   /opt/moni-agents/agents/admin/workspace, so the control sat at its 210px
   ceiling permanently -- showing "/" against a chevron stranded 200px away,
   which read as two separate broken controls. A fixed width is honest: it is
   the same size whatever is in it, and the browser truncates the long ones. */
.pick.wide { flex: 0 1 auto; min-width: 0; }
.pick.wide select {
  width: 148px; max-width: 148px;
  font-family: var(--mono); font-weight: 500;
  text-overflow: ellipsis;
}
/* Whole-server reach is worth a glance from across the room. */
.pick.hot { color: var(--warn); }
.pick.hot svg { opacity: 1; }
.pick.hot select { color: var(--warn); }

/* Ask-first: the turn is genuinely paused here, so the question belongs in the
   transcript at the point it was asked, not in a dialog over the top of it. */
.permission {
  align-self: flex-start; max-width: min(700px, 88%);
  border: 1px solid var(--brand); border-radius: 12px;
  background: var(--brand-tint);
  padding: 12px 14px;
  display: flex; flex-direction: column; gap: 8px;
}
.permission.answered { border-color: var(--line); background: var(--surface); opacity: .7; }
.perm-title { font-size: 13.5px; font-weight: 700; color: var(--ink); }
.perm-what { display: flex; gap: 8px; align-items: baseline; font-size: 12px; min-width: 0; }
.perm-what .tool-arg { white-space: pre-wrap; word-break: break-word; color: var(--body); }
.perm-desc { font-size: 12.5px; color: var(--body); }
.perm-actions { display: flex; gap: 8px; align-items: center; font-size: 12.5px; color: var(--muted); }

/* Attachments waiting to be sent. */
.attachments { display: flex; flex-wrap: wrap; gap: 6px; padding: 10px 12px 0; }
.attachment {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 12px; padding: 3px 6px 3px 10px; border-radius: 999px;
  background: var(--brand-tint); color: var(--brand-deep);
  border: 1px solid var(--brand-tint-2);
  max-width: 260px;
}
.attachment.pending { opacity: .55; }
.attachment-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.attachment-x {
  border: 0; background: none; cursor: pointer; padding: 0 2px;
  color: var(--brand-deep); font-size: 15px; line-height: 1;
}
.attachment-x:hover { color: var(--bad); }

.chat-compose.dropping .composer { border-color: var(--brand); background: var(--brand-tint); }

/* Icon-only actions in the composer bar: the same target size as a button
   without the width a label would cost in an already busy strip. */
.icon-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; flex: none;
  border: 1px solid transparent; border-radius: 8px;
  background: none; color: var(--muted); cursor: pointer;
}
.icon-btn:hover { border-color: var(--line); background: var(--bg); color: var(--ink); }
.icon-btn.recording {
  color: var(--on-bad); background: var(--bad); border-color: var(--bad);
  animation: pulse 1.4s ease-in-out infinite;
}
@keyframes pulse { 50% { opacity: .55; } }
@media (prefers-reduced-motion: reduce) { .icon-btn.recording { animation: none; } }

.pick.ask { color: var(--brand-deep); }
.pick.ask select { color: var(--brand-deep); }
.pick.plan { color: var(--muted); }

.composer-status { margin-left: auto; padding-right: 4px; white-space: nowrap; }
.composer-bar .btn { flex: none; }
.composer-hint { margin: 6px 0 0; padding-left: 4px; font-size: 11px; }

/* The console on a phone.
 *
 * The chat list used to be `display: none` here, which fitted the screen by
 * removing the only way to start a chat, switch chats, or reach the archive --
 * the transcript was all that was left. It is a drawer now, on the same
 * mechanism as the sidebar, opened from a button in the chat's own top line.
 */
@media (max-width: 900px) {
  .chats-toggle { display: flex; margin-left: -6px; }

  .chat-list {
    position: fixed; z-index: 40;
    top: var(--topbar-h); left: 0; bottom: 0;
    width: min(290px, 86vw);
    border-right: 1px solid var(--line);
    padding-bottom: calc(14px + env(safe-area-inset-bottom));
    transform: translateX(-100%);
    transition: transform var(--fast) var(--ease);
    box-shadow: var(--shadow-md);
  }
  :root.chats-open .chat-list { transform: none; }
  :root.chats-open .chat-scrim { opacity: 1; pointer-events: auto; }

  /* 100dvh, not 100vh: on a phone 100vh is the viewport with the browser's
     address bar *hidden*, so a composer pinned to the bottom of it spends the
     first scroll underneath that bar. dvh follows the bar as it moves. */
  .layout.bare { height: calc(100vh - var(--topbar-h)); }
  @supports (height: 100dvh) {
    .layout.bare { height: calc(100dvh - var(--topbar-h)); }
  }

  .chat-topline { padding: 7px 12px; gap: 8px; }
  .chat-scroll { padding: 16px 12px 8px; gap: 12px; }
  .msg .bubble { max-width: 92%; }
  .chat-notice { margin: 8px 12px 0; }
  .chat-compose { padding: 8px 12px calc(10px + env(safe-area-inset-bottom)); }

  /* The two rows hold on a phone; they just get tighter. The settings row was
     already built to scroll rather than wrap, which is what keeps this from
     becoming the three-row, 156px block it used to be. */
  .composer-bar { gap: 4px; padding: 6px 6px 7px 8px; }
  .composer-status { display: none; }
  .composer-hint { display: none; }
}

/* ---------------------------------------------------------------- wizard --- */

.wizard {
  display: flex; flex-wrap: wrap; gap: 8px;
  list-style: none; margin: 0; padding: 0;
}
.wizard-step {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 14px 8px 10px;
  border: 1px solid var(--line); border-radius: 999px;
  background: var(--surface); color: var(--muted); font-size: 13px;
}
.wizard-num {
  display: inline-flex; align-items: center; justify-content: center;
  width: 22px; height: 22px; border-radius: 50%;
  background: var(--line); color: var(--body);
  font-size: 12px; font-weight: 700;
}
.wizard-step.on { border-color: var(--brand); color: var(--brand-deep); background: var(--brand-tint); }
.wizard-step.on .wizard-num { background: var(--brand); color: var(--on-brand); }
.wizard-step.done { color: var(--brand-deep); }
.wizard-step.done .wizard-num { background: var(--brand-tint-2); color: var(--brand-deep); }

/* An input and its button on one line — the add-a-member form. */
.row-form { display: flex; gap: 8px; align-items: flex-start; }
.row-form input { margin: 0; flex: 1; min-width: 0; }
.row-form button { flex: none; }

/* ------------------------------------------------- users, roles, access --- */

.pill.brand { background: var(--brand); color: var(--on-brand); }

.row-title { font-weight: 600; color: var(--ink); }

.chips { display: flex; flex-wrap: wrap; gap: 7px; }
.chip-link, .chip-static {
  display: inline-flex; align-items: baseline; gap: 6px;
  font-size: 12.5px; padding: 4px 11px; border-radius: 999px;
  border: 1px solid var(--line); background: var(--surface); color: var(--body);
}
.chip-link:hover { border-color: var(--brand); color: var(--brand-deep); text-decoration: none; }

/* The permission editor. One column of checkboxes per group: the labels are
   sentences, and two columns of sentences is a wall rather than a list. */
.perm-group + .perm-group { margin-top: 22px; padding-top: 18px; border-top: 1px solid var(--line); }
.perm-head h3 { font-size: 14px; margin: 0 0 2px; color: var(--ink); }
.perm-head { margin-bottom: 10px; }
label.check.perm { align-items: flex-start; padding: 5px 0; }
label.check.perm input { margin-top: 3px; }
label.check.perm > span { display: flex; flex-direction: column; gap: 1px; }
.perm-label { font-size: 13.5px; color: var(--ink); }

fieldset.scope { border: 1px solid var(--line); border-radius: var(--radius); padding: 12px 14px; margin: 0; }
fieldset.scope legend { font-size: 12px; font-weight: 700; color: var(--ink); padding: 0 6px; }
.scope-list {
  margin-top: 10px; padding-top: 10px; border-top: 1px dashed var(--line);
  display: flex; flex-direction: column; gap: 5px;
  max-height: 260px; overflow-y: auto;
}

/* The enrolment screen shows a password and a TOTP secret exactly once, so
   they are set large enough to read off a screen and copy without error. */
/* The WhatsApp pairing code, kept current. The countdown is there so a code
   about to turn over visibly is, rather than the reader wondering whether the
   scan failed or the picture was simply stale. */
.qr-live { display: flex; flex-direction: column; align-items: center; gap: 10px; margin: 4px 0 14px; }
.qr-frame {
  position: relative;
  padding: 14px; border-radius: 12px;
  background: #fff; border: 1px solid var(--line);
  box-shadow: var(--shadow-sm);
  line-height: 0;
}
.qr-frame img { border-radius: 4px; }
.qr-age {
  position: absolute; right: 8px; bottom: 8px;
  min-width: 30px; padding: 2px 7px; border-radius: 999px;
  background: var(--brand-tint); color: var(--brand-deep);
  font-size: 11px; font-weight: 700; line-height: 1.5;
  font-variant-numeric: tabular-nums; text-align: center;
}
.qr-live p { max-width: 44ch; margin: 0; }
.center { text-align: center; }

.qr-wrap { text-align: center; }
.qr { border: 1px solid var(--line); border-radius: var(--radius); background: #fff; padding: 8px; }

/* Meter fill. A percentage cannot be a class name computed at render time
   without an inline style, so the widths are enumerated and the value is
   rounded to the nearest whole percent when the bar is built. */
.fill[data-w="0"] { width: 0; }
.fill[data-w="1"] { width: 1%; }    .fill[data-w="2"] { width: 2%; }
.fill[data-w="3"] { width: 3%; }    .fill[data-w="4"] { width: 4%; }
.fill[data-w="5"] { width: 5%; }    .fill[data-w="6"] { width: 6%; }
.fill[data-w="7"] { width: 7%; }    .fill[data-w="8"] { width: 8%; }
.fill[data-w="9"] { width: 9%; }    .fill[data-w="10"] { width: 10%; }
.fill[data-w="11"] { width: 11%; }  .fill[data-w="12"] { width: 12%; }
.fill[data-w="13"] { width: 13%; }  .fill[data-w="14"] { width: 14%; }
.fill[data-w="15"] { width: 15%; }  .fill[data-w="16"] { width: 16%; }
.fill[data-w="17"] { width: 17%; }  .fill[data-w="18"] { width: 18%; }
.fill[data-w="19"] { width: 19%; }  .fill[data-w="20"] { width: 20%; }
.fill[data-w="21"] { width: 21%; }  .fill[data-w="22"] { width: 22%; }
.fill[data-w="23"] { width: 23%; }  .fill[data-w="24"] { width: 24%; }
.fill[data-w="25"] { width: 25%; }  .fill[data-w="26"] { width: 26%; }
.fill[data-w="27"] { width: 27%; }  .fill[data-w="28"] { width: 28%; }
.fill[data-w="29"] { width: 29%; }  .fill[data-w="30"] { width: 30%; }
.fill[data-w="31"] { width: 31%; }  .fill[data-w="32"] { width: 32%; }
.fill[data-w="33"] { width: 33%; }  .fill[data-w="34"] { width: 34%; }
.fill[data-w="35"] { width: 35%; }  .fill[data-w="36"] { width: 36%; }
.fill[data-w="37"] { width: 37%; }  .fill[data-w="38"] { width: 38%; }
.fill[data-w="39"] { width: 39%; }  .fill[data-w="40"] { width: 40%; }
.fill[data-w="41"] { width: 41%; }  .fill[data-w="42"] { width: 42%; }
.fill[data-w="43"] { width: 43%; }  .fill[data-w="44"] { width: 44%; }
.fill[data-w="45"] { width: 45%; }  .fill[data-w="46"] { width: 46%; }
.fill[data-w="47"] { width: 47%; }  .fill[data-w="48"] { width: 48%; }
.fill[data-w="49"] { width: 49%; }  .fill[data-w="50"] { width: 50%; }
.fill[data-w="51"] { width: 51%; }  .fill[data-w="52"] { width: 52%; }
.fill[data-w="53"] { width: 53%; }  .fill[data-w="54"] { width: 54%; }
.fill[data-w="55"] { width: 55%; }  .fill[data-w="56"] { width: 56%; }
.fill[data-w="57"] { width: 57%; }  .fill[data-w="58"] { width: 58%; }
.fill[data-w="59"] { width: 59%; }  .fill[data-w="60"] { width: 60%; }
.fill[data-w="61"] { width: 61%; }  .fill[data-w="62"] { width: 62%; }
.fill[data-w="63"] { width: 63%; }  .fill[data-w="64"] { width: 64%; }
.fill[data-w="65"] { width: 65%; }  .fill[data-w="66"] { width: 66%; }
.fill[data-w="67"] { width: 67%; }  .fill[data-w="68"] { width: 68%; }
.fill[data-w="69"] { width: 69%; }  .fill[data-w="70"] { width: 70%; }
.fill[data-w="71"] { width: 71%; }  .fill[data-w="72"] { width: 72%; }
.fill[data-w="73"] { width: 73%; }  .fill[data-w="74"] { width: 74%; }
.fill[data-w="75"] { width: 75%; }  .fill[data-w="76"] { width: 76%; }
.fill[data-w="77"] { width: 77%; }  .fill[data-w="78"] { width: 78%; }
.fill[data-w="79"] { width: 79%; }  .fill[data-w="80"] { width: 80%; }
.fill[data-w="81"] { width: 81%; }  .fill[data-w="82"] { width: 82%; }
.fill[data-w="83"] { width: 83%; }  .fill[data-w="84"] { width: 84%; }
.fill[data-w="85"] { width: 85%; }  .fill[data-w="86"] { width: 86%; }
.fill[data-w="87"] { width: 87%; }  .fill[data-w="88"] { width: 88%; }
.fill[data-w="89"] { width: 89%; }  .fill[data-w="90"] { width: 90%; }
.fill[data-w="91"] { width: 91%; }  .fill[data-w="92"] { width: 92%; }
.fill[data-w="93"] { width: 93%; }  .fill[data-w="94"] { width: 94%; }
.fill[data-w="95"] { width: 95%; }  .fill[data-w="96"] { width: 96%; }
.fill[data-w="97"] { width: 97%; }  .fill[data-w="98"] { width: 98%; }
.fill[data-w="99"] { width: 99%; }  .fill[data-w="100"] { width: 100%; }

/* Live mode: talk to it, hear the answer. Wider than the other icon buttons
   because it is a mode rather than an action -- you need to see at a glance
   whether the microphone is open, and a 30px glyph does not say that. */
.live-controls { gap: 5px; flex: none; }
/* min-width, not just padding. This is a flex item in a row that is allowed to
   shrink, and without a floor the label was the first thing to give -- the
   button rendered as "Liv" with the microphone half outside it. */
.live-btn {
  width: auto; min-width: 0; flex: none;
  padding: 0 11px; gap: 6px; white-space: nowrap;
}
.live-btn span { font-size: 12px; font-weight: 600; }
.live-btn.on {
  background: var(--brand); border-color: var(--brand); color: var(--on-brand);
  animation: pulse 2s ease-in-out infinite;
}
.live-btn.on:hover { background: var(--brand-hover); border-color: var(--brand-hover); color: var(--on-brand); }
@media (prefers-reduced-motion: reduce) { .live-btn.on { animation: none; } }
/* No OpenAI key: the button stays in its place, dimmed, with where to fix it
   beside it rather than a control that fails when pressed. */
.live-controls.voice-off { display: inline-flex; align-items: center; }
.icon-btn:disabled, .live-btn:disabled { opacity: .45; cursor: not-allowed; }
.voice-setup { font-size: 12px; white-space: nowrap; }
@media (max-width: 720px) { .voice-setup { display: none; } }

/* ------------------------------------------------------------ Claude Code - */
.cc-filters { display: flex; flex-wrap: wrap; gap: 10px 14px; align-items: flex-end; margin-bottom: 14px; }
.cc-filters label { margin: 0; flex: 1 1 160px; max-width: 280px; }
.cc-filters label.check { flex: 0 0 auto; padding-bottom: 8px; }
.cc-filters input, .cc-filters select { margin-top: 4px; }
.cc-narrow { flex: 0 0 180px; margin: 0; }
.cc-line { margin: -6px 0 var(--gap); }
.cc-pager { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; margin: 12px 0; }
.cc-pager span.btn { opacity: .45; cursor: default; }
.cc-scroll { overflow-x: auto; }
.cc-tall { max-height: 420px; overflow-y: auto; }
.cc-title-cell { min-width: 240px; max-width: 420px; }
.nowrap { white-space: nowrap; }
.cc-cmd, .cc-log { white-space: pre-wrap; word-break: break-all; font-size: 12px; }
.cc-fact { font-size: 14px; }
.cc-ex { display: flex; flex-direction: column; gap: 8px; padding: 14px 0; border-top: 1px solid var(--line); }
.cc-ex-meta { opacity: 1; animation: none; }
.cc-ex .msg { animation: none; }
.cc-text { white-space: pre-wrap; }
.cc-summary .bubble { background: var(--surface-2); color: var(--body); border: 1px dashed var(--line-strong); }
.cc-tools { margin-left: 0; }
.cc-tools .tool-arg { flex: 1; min-width: 0; }
.cc-size { flex: none; font-variant-numeric: tabular-nums; }
tr.cc-on td { background: var(--brand-tint); }

/* ------------------------------------------------------- theme switch --- */
/* System / Dark / Light, in the top bar of every page. app.js wires it; the
   choice lives in localStorage under "moni-theme". */
.theme-seg { display: flex; padding: 2px; gap: 0; border-radius: 9px; border: 1px solid var(--line); background: var(--accent-soft); }
.theme-seg button { display: flex; align-items: center; gap: 6px; border: 0; background: none; padding: 4px 10px; border-radius: 7px;
  font: 600 13px var(--ui); color: var(--muted); cursor: pointer; }
.theme-seg button svg { width: 14px; height: 14px; }
.theme-seg button:hover { color: var(--ink); }
.theme-seg button[aria-checked="true"] { background: var(--panel); color: var(--accent); box-shadow: var(--shadow-sm), inset 0 0 0 1px var(--line-strong); }
@media (max-width: 1360px) { .theme-seg button span { display: none; } .theme-seg button { padding: 4px 7px; } }
@media (max-width: 900px) { .theme-seg { display: none; } }

/* ======================================================================
   Mint brand layer. The rules above are the structure; these give it the
   Mint voice: Space Grotesk for the brand, headings and labels, the leaf
   lockups, the mint "vein" on cards, and solid mint for primary actions.
   ====================================================================== */

body { background: var(--bg); font-family: var(--ui); font-size: 13.5px; }
:root[data-theme="dark"] body { background: radial-gradient(1200px 700px at 55% 30%, var(--bg-glow) 0%, var(--bg) 62%), var(--bg); background-attachment: fixed; }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) body { background: radial-gradient(1200px 700px at 55% 30%, var(--bg-glow) 0%, var(--bg) 62%), var(--bg); background-attachment: fixed; } }
h1, h2, h3, h4 { font-family: var(--brand-font); letter-spacing: -.005em; }
h1 { font-size: 23px; font-weight: 700; letter-spacing: -.01em; }
h2 { font-weight: 700; }
.mono, code, kbd, samp { font-family: var(--mono); }
::selection { background: rgba(0, 230, 165, .28); }
:focus-visible { outline-color: var(--accent-2); }

/* ---- lockups: MINT [OS] / MINT [AI] ---- */
.lockup { display: inline-flex; align-items: center; gap: .55em; font-family: var(--brand-font); line-height: 1; color: var(--ink); }
.lockup .lk-mk { display: inline-flex; }
.lockup .lk-mk svg { height: 1.9em; width: auto; display: block; }
.lockup.ai .lk-mk svg { height: 2.35em; margin: -.3em -.15em -.1em; }
.lockup .lk-wm { display: flex; flex-direction: column; gap: .32em; }
.lockup .lk-row { display: flex; align-items: center; gap: .3em; }
.lockup .lk-mint { font-weight: 700; font-size: 1.28em; letter-spacing: .05em; color: var(--wordmark); }
.lockup .lk-sub { font-weight: 600; font-size: .5em; letter-spacing: .06em; color: var(--ink); text-transform: uppercase; }
.lockup.full { gap: .5em; }
.lockup.full .lk-wm { gap: .2em; }
.lockup.full .lk-mk svg { height: 3.3em; }
.lockup.ai.full .lk-mk svg { height: 5.1em; margin: -1.05em -.25em -.6em; }
.pill-brand { display: inline-flex; align-items: center; font-weight: 700; font-size: .74em; letter-spacing: .04em; padding: .16em .34em .18em; border-radius: .3em; line-height: 1; white-space: nowrap; color: var(--obsidian); }
.pill-brand b { font-weight: 700; margin: 0 .07em; }
.pill-os { background: var(--pill-os); }
.pill-ai { background: var(--grad-ai); box-shadow: 0 0 .9em rgba(138, 43, 226, .45), 0 0 .5em rgba(0, 230, 165, .25); }
:root[data-theme="light"] .pill-ai { box-shadow: 0 0 .6em rgba(138, 43, 226, .22); }
@media (prefers-color-scheme: light) { :root:not([data-theme="dark"]) .pill-ai { box-shadow: 0 0 .6em rgba(138, 43, 226, .22); } }
.mark-ai .ai-halo { opacity: .75; }
:root[data-theme="light"] .mark-ai .ai-halo { opacity: .35; }
@media (prefers-color-scheme: light) { :root:not([data-theme="dark"]) .mark-ai .ai-halo { opacity: .35; } }

/* ---- top bar ---- */
.topbar { gap: 14px; }
.topbar::after { content: ""; position: absolute; left: 0; right: 0; bottom: -1px; height: 1px; background: linear-gradient(90deg, transparent, rgba(0, 230, 165, .35) 20%, transparent 55%); pointer-events: none; }
.cc-page .topbar::after { background: linear-gradient(90deg, transparent, rgba(0, 230, 165, .4) 15%, rgba(138, 43, 226, .45) 45%, transparent 75%); }
.topbar > .brand { font-size: 15px; padding-right: 6px; gap: 0; }
.topbar > .brand .brand-text em { display: none; }
.top-tab { font: 600 14px/1 var(--brand-font); color: var(--muted); border-bottom: 0; position: relative; }
.top-tab .spark { width: 16px; height: 16px; }
.top-tab.on { color: var(--ink); background: linear-gradient(180deg, transparent, var(--accent-soft)); }
.top-tab.on::after { content: ""; position: absolute; left: 12px; right: 12px; bottom: 0; height: 2px; border-radius: 2px 2px 0 0; background: var(--brand); }
.top-tab.ai.on { background: linear-gradient(180deg, transparent, var(--violet-tint)); }
.top-tab.ai.on::after { background: var(--grad-ai); box-shadow: 0 0 10px rgba(138, 43, 226, .6); }
.sys-chip { font-family: var(--brand-font); letter-spacing: .09em; }
.sys-chip, .sys-chip:hover { border-color: color-mix(in srgb, var(--accent-2) 45%, transparent); }
.whoami-name { font: 600 13.5px var(--brand-font); }
.theme-seg button { font-family: var(--brand-font); }

/* ---- sidebar ---- */
.sidebar { background: var(--topbar-bg); }
.side-id-mark { border-radius: 10px; width: 38px; height: 38px; background: var(--teal-tint); border: 1px solid var(--teal-line); }
.side-id-mark::after { display: none; }
.side-id-mark svg.mark { height: 26px; width: auto; }
.side-id-mark svg.seedling { height: 34px; width: auto; }
.side-id { grid-template-columns: 38px minmax(0, 1fr); border-bottom-style: solid; }
.side-id b { font: 700 14px var(--brand-font); }
.side-label { font: 700 11px/1 var(--brand-font); letter-spacing: .14em; color: var(--muted); opacity: 1; padding: 14px 10px 6px; }
.side-label::after { background: var(--line); }
.side-sublabel { font: 500 11px var(--brand-font); color: var(--dim); letter-spacing: .03em; }
.side-item { font: 500 14px var(--brand-font); color: var(--ink); border: 0; border-radius: 8px; }
.side-item .ico { color: var(--muted); }
.side-item:hover { background: var(--panel-2); }
.side-item.on { background: var(--teal-tint); font-weight: 700; }
.side-item.on::before { background: var(--brand); box-shadow: none; }
.side-item.on .ico { color: var(--accent); }
.badge { border-radius: 5px; background: var(--panel-2); line-height: 18px; }
.badge.ok { color: var(--accent); background: var(--accent-soft); border-color: transparent; }
.badge.warn { background: var(--warn-tint); border-color: transparent; }
.badge.bad { background: var(--bad-tint); border-color: transparent; }
.side-collapse { font: 500 12.5px var(--ui); }

/* ---- page head ---- */
.crumbs { font: 400 11.5px var(--mono); letter-spacing: 0; }
.page-head .sub { font-size: 13.5px; }

/* ---- cards: surface, a soft shadow and the OS "vein" -- a structural
   accent drawn from the leaf's divide ---- */
.card, .statbox { background: var(--panel); border-radius: var(--r); box-shadow: var(--shadow-md); }
.card > .card-head::before { content: ""; position: absolute; left: -1px; top: 14px; width: 2px; height: 18px; border-radius: 0 2px 2px 0; background: var(--brand); opacity: .85; }
.card-head h2 { font: 700 12px/1.2 var(--brand-font); letter-spacing: .13em; }
.statbox-value { font: 700 21px/1.15 var(--brand-font); }
.statbox-label { font: 700 10.5px var(--brand-font); letter-spacing: .1em; }
.statbox-ico { background: var(--teal-tint); border-color: var(--teal-line); color: var(--accent); }
.rows th { font: 700 10.5px var(--brand-font); letter-spacing: .1em; }
.pill { font-family: var(--brand-font); letter-spacing: .08em; border-radius: 6px; }
.pill::before { box-shadow: 0 0 0 3px color-mix(in srgb, currentColor 22%, transparent); }
.pill.brand, .pill.solid { color: var(--on-brand); background: var(--brand); border-color: transparent; }
.pill.ai { color: var(--obsidian); background: var(--grad-ai); border-color: transparent; }
.pill.ai::before { background: var(--obsidian); box-shadow: none; }

/* ---- buttons ---- */
.btn { font: 600 13px/1.3 var(--brand-font); border-color: var(--line-strong); background: var(--panel); color: var(--ink); }
.btn:hover { border-color: var(--accent-2); }
.btn.primary { background: var(--brand); color: var(--on-brand); border-color: var(--accent-2); box-shadow: none; }
.btn.primary:hover { color: var(--on-brand); filter: brightness(1.06); }
.btn.ai { background: var(--grad-ai); color: var(--obsidian); border: 0; box-shadow: 0 0 16px rgba(138, 43, 226, .3); }

/* ---- the sign-in pages: the full lockup, and a large faint leaf ---- */
.auth-wrap { position: relative; overflow: hidden; }
.auth-leaf { position: fixed; right: -6vw; bottom: -12vh; width: min(58vw, 760px); opacity: .07; pointer-events: none; z-index: 0; transform: rotate(-14deg); }
.auth-leaf svg { width: 100%; height: auto; display: block; }
:root[data-theme="light"] .auth-leaf { opacity: .09; }
.auth-wrap > .card { position: relative; z-index: 1; }
.auth-wrap > .auth-leaf { position: fixed; }
.auth-wrap .card.auth-card::before, .auth-wrap .card.auth-card::after { display: none; }
.auth-brand { display: flex; justify-content: center; margin: 4px 0 18px; font-size: 22px; }
.auth-wrap .card { box-shadow: var(--shadow-md); }

/* ---- seedlings (the Agents nursery), coloured by theme ---- */
.seedling .sd-a { fill: var(--leaf-a); }
.seedling .sd-b { fill: var(--leaf-b); }
.seedling .sd-vein { stroke: var(--panel-2); stroke-width: 6; fill: none; }
.seedling .sd-stem { stroke: var(--leaf-b); stroke-width: 3; stroke-linecap: round; fill: none; }
.seedling .sd-soil { fill: var(--leaf-b); opacity: .4; }
.seedling.off .sd-a, .seedling.off .sd-b, .seedling.off .sd-stem { fill: var(--dim); stroke: var(--dim); opacity: .55; }
.seedling.off .sd-stem { fill: none; }
.auth-wrap .card.auth-card { max-width: 420px; padding: 30px 30px 22px; border-radius: 16px; }
.auth-lockup { font-size: 19px; margin: 0 0 22px; }
.auth-card h2 { font-size: 18px; letter-spacing: 0; text-transform: none; }
.auth-foot { display: flex; align-items: center; gap: 8px; margin: 14px 0 0; color: var(--muted); font-size: 12.5px; }
.auth-leaf { right: -8vw; bottom: -30vh; width: min(52vw, 700px); transform: none; opacity: .06; }
/* The HUD brackets give way to the OS vein. */
.hud::after { display: none; }
.hud::before { top: 14px; left: -1px; width: 2px; height: 18px; border: 0; border-radius: 0 2px 2px 0; background: var(--brand); opacity: .85; }
.seed.new .seedling { width: 56px; height: 58px; display: block; margin: 0 auto; }
.seed.new .seedling .sd-a { fill: var(--leaf-a); } .seed.new .seedling .sd-b { fill: var(--leaf-b); }
.seed.new .seedling .sd-vein { stroke: var(--panel); stroke-width: 6; fill: none; }
.seed.new .seedling .sd-stem { stroke: var(--leaf-b); stroke-width: 3; stroke-linecap: round; fill: none; }
.seed.new .seedling .sd-soil { fill: var(--leaf-b); opacity: .4; }
/* Phones: the top bar keeps just the leaf of the lockup. */
@media (max-width: 900px) {
  .topbar > .brand .lockup { display: inline-flex; }
  .topbar > .brand .lk-wm { display: none; }
  .topbar { gap: 8px; padding: 0 10px; }
}

/* Settings › OpenAI voice › Voice persona: a short list of choices, never free text. */
fieldset.radio-list { border: 1px solid var(--line); border-radius: var(--radius); padding: 10px 14px; margin: 0; display: grid; gap: 8px; }
fieldset.radio-list legend { font-size: 12px; font-weight: 700; color: var(--ink); padding: 0 6px; }
.radio-row { display: grid; grid-template-columns: auto 1fr; column-gap: 8px; align-items: baseline; cursor: pointer; }
.radio-row input { margin: 0; }
.radio-row .muted { grid-column: 2; }
