/* ===========================================================
   SAVANNAH AI -- DESIGN SYSTEM
   "Built To Perform." — retro-organic, vintage-engraving,
   editorial dark mode. Design tokens + application shell + component
   primitives. Plain CSS, no build step (see docs/limitations.md).
   Every visual decision below is a real, applied choice — every
   component class below is still the same one every view module in
   js/views/*.js already renders through js/ui.js, so this file is the
   single place the brand is actually enforced from.
   =========================================================== */

:root {
  /*
   * Official brand palette — Master Completion mission (premium black
   * + metallic-silver system, mandatory app-wide, not just the welcome
   * screen). Replaces the prior "ink-black / warm-ivory" vintage-
   * engraving palette at the token level only: every rule below this
   * block already consumes these four variables (confirmed by grepping
   * for hardcoded hex colors outside :root before this change — only
   * two existed, .entry's radial-gradient and .entry-card's rgba
   * background, both fixed separately below since literal color
   * values can't inherit from a token rename). Do not drift from these
   * four without an explicit brand decision — everything else is
   * derived.
   */
  --ink-black: #000000;
  --warm-ivory: #E5E7EB;       /* bright silver */
  --muted-warm-gray: #858B95;  /* dark/mid silver, used for secondary text */
  --ivory-hover: #FFFFFF;

  /* Dedicated subtle-border silver, per the mission's own named
     palette — used for border-subtle/strong below instead of a
     low-alpha tint of the text color, so hairline borders read as a
     neutral steel-gray rather than a faint wash of the accent color. */
  --silver-border: #44484F;

  --bg-canvas: var(--ink-black);
  /* Neutral near-black panel surfaces — deliberately NOT tinted green/
     teal/olive (the previous #0a1a18/#0f211e/#152a26 were a green-
     tinted dark, which the brand directive explicitly now prohibits:
     "No unintended dark-green, teal, olive, or muddy off-black
     surfaces"). */
  --bg-surface: #0d0d0f;
  --bg-surface-raised: #141417;
  --bg-surface-hover: #1c1c20;
  --border-subtle: rgba(68, 72, 79, 0.5);
  --border-strong: rgba(68, 72, 79, 0.85);

  --text-primary: var(--warm-ivory);
  --text-secondary: var(--muted-warm-gray);
  --text-tertiary: #858b95; /* neutral gray; raised from #6b6e76 so muted text meets WCAG AA (4.5:1) on the dark surfaces, found by the axe-core scan */
  --text-inverse: var(--ink-black);

  /* No separate brand "accent" hue exists — the bright-silver token IS
     the one interactive color, used the same way a blue/purple accent
     would be in a conventional dark-mode system (links, primary
     actions, active nav, focus rings). Monochrome on purpose. */
  --accent: var(--warm-ivory);
  --accent-hover: var(--ivory-hover);
  --accent-dim: rgba(229, 231, 235, 0.1);

  /* Status colors restrained toward the warm/ink palette (worn pigment,
     not neon) while staying distinguishable from each other and from
     plain ivory text — "accessible distinctions," per the brand brief,
     not a second unrelated color system. */
  --success: #93AD82;
  --success-dim: rgba(147, 173, 130, 0.14);
  --warning: #C8A24B;
  --warning-dim: rgba(200, 162, 75, 0.14);
  --danger: #BD6454;
  --danger-dim: rgba(189, 100, 84, 0.14);
  --info: #7FA39B;

  /*
   * Brand typeface: Special Elite Regular — real, verified, present in
   * this repository at apps/studio/fonts/SpecialElite-Regular.ttf.
   * License checked before use (not assumed from the filename): the
   * ZIP included a full Apache License 2.0 text (apps/studio/fonts/
   * SpecialElite-LICENSE.txt), and the TTF's own embedded name-table
   * metadata independently confirms the same thing — "Copyright (c)
   * 2010 by Brian J. Bonislawsky DBA Astigmatic (AOETI). All rights
   * reserved. Available under the Apache 2.0 licence," with the
   * matching http://www.apache.org/licenses/LICENSE-2.0 URL. Apache 2.0
   * is a permissive OSI license that explicitly allows commercial use,
   * modification, and redistribution (the license file is kept
   * alongside the font to satisfy its notice-retention terms). Family/
   * style confirmed via fc-scan: "Special Elite" / "Regular".
   *
   * Bakerie Rough Regular (the earlier brand-font request) is still not
   * present in this repository. It was named in this stack and backed
   * by a dormant @font-face further down so it could be lit up later —
   * removed from both places this pass (see the @font-face's own former
   * location, just below the Special Elite block) after live testing
   * showed it causing real 404s. Dropping the real file at
   * apps/studio/fonts/BakerieRoughRegular.woff2 (+.woff) and adding both
   * an @font-face for it and its name back into this stack is still the
   * only step needed to use it.
   */
  --font-brand: "Special Elite", Georgia, "Iowan Old Style", "Palatino Linotype", "Book Antiqua", "Times New Roman", serif;
  --font-serif: var(--font-brand);
  --font-sans: var(--font-brand);
  /* Dense/technical content (code, terminal output, logs, JSON) stays
     on a real monospace stack regardless of --font-brand's status — a
     rough display face would distort fixed-width technical data, and
     the brief explicitly asks this to be preserved. */
  --font-mono: ui-monospace, "SF Mono", "Cascadia Code", Menlo, Consolas, monospace;
  --text-xs: 0.75rem;
  --text-sm: 0.8125rem;
  --text-base: 0.9375rem;
  --text-lg: 1.125rem;
  --text-xl: 1.5rem;
  --text-2xl: 2.25rem;

  /* 8px rhythm (space-1 is the one half-step, used only for tight
     control padding) */
  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1rem;
  --space-5: 1.5rem;
  --space-6: 2rem;
  --space-8: 3rem;

  /* Mostly square corners — a small, deliberate chamfer, not the
     rounded-pill look of a conventional SaaS console. */
  --radius-sm: 2px;
  --radius-md: 3px;
  --radius-lg: 4px;

  --shadow-sm: 0 1px 2px rgba(0,0,0,0.45);
  --shadow-md: 0 8px 24px rgba(0,0,0,0.5);

  --sidebar-width: 232px;
  --topbar-height: 56px;
  --content-max-width: 1280px;
}

/*
 * Special Elite Regular — real font file, license verified (see the
 * --font-brand comment above). TTF only (as supplied); font-display:
 * swap avoids a blank-text flash while it loads.
 */
@font-face {
  font-family: "Special Elite";
  src: url("../fonts/SpecialElite-Regular.ttf") format("truetype");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

/*
 * Bakerie Rough Regular is still not present in this repository. An
 * earlier pass kept a dormant @font-face for it so it could be lit up
 * later by just dropping the file in — but live Playwright testing
 * during this pass (brand brief: "no broken font URLs") showed Chromium
 * actually requests that @font-face's src on every page load (glyph-
 * coverage fallback probing) and logs a real 404, even though no text
 * ever renders in it. Removed for that reason — supplying the real
 * woff2/woff files and re-adding both the @font-face and its name to
 * --font-brand's stack above is still the only step needed to use it.
 */

* { box-sizing: border-box; }

html, body { max-width: 100%; overflow-x: hidden; }

/* Browsers do not inherit the page font into form controls/buttons by
   default (they use the OS UI font instead) — found checking the brand
   font's actual reach: .btn, .sidebar-item, .tab and every other plain
   <button> in this app were silently exempt from --font-brand without
   this. input/select/textarea already had their own font-family:
   inherit; this is the same fix for <button> and <select>, applied
   once, globally, rather than per component class. */
button, select { font-family: inherit; }

body {
  font-family: var(--font-sans);
  margin: 0;
  background: var(--bg-canvas);
  color: var(--text-primary);
  font-size: var(--text-base);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

h1, h2 { font-family: var(--font-serif); font-weight: 600; letter-spacing: -0.01em; margin: 0 0 var(--space-3) 0; }
h2 { font-size: var(--text-xl); }
h3 { font-family: var(--font-sans); font-size: var(--text-sm); color: var(--text-secondary); text-transform: uppercase; letter-spacing: 0.08em; font-weight: 600; margin: 0 0 var(--space-3) 0; }
em, i, .emphasis { font-style: italic; }
a { color: var(--accent-hover); }
:focus-visible { outline: 2px solid var(--accent-hover); outline-offset: 2px; border-radius: var(--radius-sm); }

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

.app-shell { display: flex; min-height: 100vh; }
.sidebar {
  width: var(--sidebar-width);
  flex-shrink: 0;
  background: var(--bg-surface);
  border-right: 1px solid var(--border-subtle);
  display: flex;
  flex-direction: column;
  padding: var(--space-4) var(--space-3);
  gap: var(--space-1);
  position: sticky;
  top: 0;
  height: 100vh;
  overflow-y: auto;
}
.sidebar-brand {
  font-family: var(--font-serif); font-weight: 600; font-size: var(--text-lg);
  padding: var(--space-2) var(--space-2) var(--space-5); letter-spacing: 0.02em;
  border-bottom: 1px solid var(--border-subtle); margin-bottom: var(--space-2);
}
.sidebar-brand .dot { color: var(--text-secondary); font-style: italic; }
.sidebar-section-label { font-size: 0.6875rem; text-transform: uppercase; letter-spacing: 0.1em; color: var(--text-tertiary); padding: var(--space-4) var(--space-2) var(--space-1); }
.sidebar-item {
  display: flex; align-items: center; gap: var(--space-2);
  padding: var(--space-2) var(--space-2);
  border-radius: var(--radius-sm);
  color: var(--text-secondary);
  font-size: var(--text-sm);
  cursor: pointer;
  border: none; background: none; width: 100%; text-align: left;
  border-left: 2px solid transparent;
}
.sidebar-item:hover { background: var(--bg-surface-hover); color: var(--text-primary); }
.sidebar-item.active { background: var(--accent-dim); color: var(--accent-hover); font-weight: 600; border-left-color: var(--accent); }

.main-column { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.topbar {
  height: var(--topbar-height);
  border-bottom: 1px solid var(--border-subtle);
  display: flex; align-items: center;
  padding: 0 var(--space-5);
  gap: var(--space-4);
  background: var(--bg-canvas);
  position: sticky; top: 0; z-index: 10;
}
/* flex-start + auto-margin on .topbar-actions (not justify-content:
   space-between) so the leading group works whether it's just
   .topbar-scope (desktop) or .menu-toggle + .topbar-scope (mobile)
   without the middle item drifting. */
.topbar-actions { margin-left: auto; }
.topbar-scope { display: flex; align-items: center; gap: var(--space-2); font-size: var(--text-sm); min-width: 0; overflow-x: auto; }
.scope-select {
  background: var(--bg-surface); border: 1px solid var(--border-subtle); color: var(--text-primary);
  padding: var(--space-1) var(--space-2); border-radius: var(--radius-sm); font-size: var(--text-sm); max-width: 160px;
}
.scope-sep { color: var(--text-tertiary); }
.topbar-actions { display: flex; align-items: center; gap: var(--space-3); }
.cmdk-hint { font-size: var(--text-xs); color: var(--text-tertiary); background: transparent; border: 1px solid var(--border-subtle); border-radius: var(--radius-sm); padding: 0.15rem 0.4rem; cursor: pointer; }
.account-menu { position: relative; }
.account-badge { width: 28px; height: 28px; border-radius: 50%; background: var(--accent-dim); color: var(--accent-hover); display: flex; align-items: center; justify-content: center; font-size: var(--text-xs); font-weight: 700; cursor: pointer; border: none; }
.account-dropdown { position: absolute; right: 0; top: 36px; background: var(--bg-surface-raised); border: 1px solid var(--border-subtle); border-radius: var(--radius-md); box-shadow: var(--shadow-md); min-width: 160px; padding: var(--space-1); display: none; z-index: 20; }
.account-dropdown.open { display: block; }
.account-dropdown button { width: 100%; text-align: left; background: none; border: none; color: var(--text-primary); padding: var(--space-2); border-radius: var(--radius-sm); cursor: pointer; font-size: var(--text-sm); }
.account-dropdown button:hover { background: var(--bg-surface-hover); }

main#main { padding: var(--space-6) var(--space-5); max-width: var(--content-max-width); margin: 0 auto; width: 100%; }

input, select, textarea {
  background: var(--bg-surface); border: 1px solid var(--border-subtle); color: var(--text-primary);
  padding: var(--space-2) var(--space-3); border-radius: var(--radius-sm); margin: var(--space-1) var(--space-1) var(--space-1) 0;
  font-family: inherit; font-size: var(--text-sm); transition: border-color 0.12s ease;
}
input:focus, select:focus, textarea:focus { border-color: var(--accent); outline: none; }
textarea { width: 100%; display: block; }

/* The chat composer's own textarea: auto-grows via JS (scrollHeight) as
   the user types a longer message, instead of either clipping a long
   draft at a fixed 2 rows or letting the page grow without bound —
   capped here, then scrolls internally like any other chat app's
   composer once a message gets long enough. resize:none since the
   auto-grow already does that job; a manual drag-handle fighting it
   looks broken. */
.composer-input { resize: none; overflow-y: auto; max-height: 40vh; }

/* Chat composer attachments (UX mission): the "+" menu, its items, and
   the attachment preview cards below the textarea. Touch targets sized
   >=40px throughout — this is the one part of Studio explicitly meant
   to work for someone with only a phone. */
.composer-toolbar { display: flex; align-items: center; gap: var(--space-2); margin-bottom: var(--space-2); flex-wrap: wrap; }
.plus-wrap { position: relative; display: inline-block; }
.plus-btn {
  width: 40px; height: 40px; padding: 0; border-radius: var(--radius-md);
  font-size: 1.3rem; line-height: 1; display: flex; align-items: center; justify-content: center;
}
.attach-menu {
  position: absolute; left: 0; top: 46px; z-index: 20; min-width: 220px;
  background: var(--bg-surface-raised); border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md); box-shadow: var(--shadow-md); padding: var(--space-1);
}
.attach-menu-item {
  display: block; width: 100%; text-align: left; background: none; border: none;
  color: var(--text-primary); padding: var(--space-3) var(--space-3); border-radius: var(--radius-sm);
  cursor: pointer; font-size: var(--text-sm); min-height: 40px;
}
.attach-menu-item:hover, .attach-menu-item:focus-visible { background: var(--bg-surface-hover); }

.composer-attachments { display: none; flex-wrap: wrap; gap: var(--space-2); margin-bottom: var(--space-2); }
.attachment-card {
  display: flex; align-items: center; gap: var(--space-2);
  background: var(--bg-surface); border: 1px solid var(--border-subtle); border-radius: var(--radius-md);
  padding: var(--space-1) var(--space-2); max-width: 220px;
}
.attachment-card.attachment-error { border-color: var(--danger); }
.attachment-thumb { width: 36px; height: 36px; object-fit: cover; border-radius: var(--radius-sm); flex-shrink: 0; }
.attachment-icon { width: 36px; height: 36px; display: flex; align-items: center; justify-content: center; font-size: 1.2rem; flex-shrink: 0; }
.attachment-info { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.attachment-filename { font-size: var(--text-xs); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.attachment-meta { font-size: var(--text-xs); color: var(--text-tertiary); }
.attachment-card.attachment-error .attachment-meta { color: var(--danger); }
.attachment-remove {
  background: none; border: none; color: var(--text-tertiary); cursor: pointer; font-size: 1.1rem;
  width: 28px; height: 28px; flex-shrink: 0; border-radius: var(--radius-sm); line-height: 1;
}
.attachment-remove:hover, .attachment-remove:focus-visible { color: var(--text-primary); background: var(--bg-surface-hover); }

.btn {
  background: var(--bg-surface-hover); border: 1px solid var(--border-strong); color: var(--text-primary);
  padding: var(--space-2) var(--space-4); border-radius: var(--radius-sm); cursor: pointer; font-size: var(--text-sm);
  font-weight: 550; transition: all 0.12s ease;
}
.btn:hover { border-color: var(--accent); }
.btn:active { transform: translateY(1px); }
.btn.primary { background: var(--accent); border-color: var(--accent); color: var(--text-inverse); font-weight: 600; }
.btn.primary:hover { background: var(--accent-hover); border-color: var(--accent-hover); }
.btn.danger { background: var(--danger-dim); border-color: transparent; color: #D4786A; /* lighter than --danger so text stays >= 4.5:1 on the tinted background and on hovered rows */ }
.btn.oauth { background: var(--bg-surface); }
.btn.oauth:hover { border-color: var(--accent); }
.btn:disabled { opacity: 0.5; cursor: not-allowed; }

.card { background: var(--bg-surface); border: 1px solid var(--border-subtle); border-radius: var(--radius-lg); padding: var(--space-5); margin-bottom: var(--space-3); }
.section { margin: var(--space-5) 0; }
.section h3 { margin-bottom: var(--space-2); }

.table-scroll { width: 100%; overflow-x: auto; margin-bottom: var(--space-3); }
table.data-table { width: 100%; border-collapse: collapse; font-size: var(--text-sm); }
table.data-table th { text-align: left; padding: var(--space-2) var(--space-3); color: var(--text-tertiary); font-weight: 600; font-size: var(--text-xs); text-transform: uppercase; letter-spacing: 0.04em; border-bottom: 1px solid var(--border-subtle); }
table.data-table td { padding: var(--space-3); border-bottom: 1px solid var(--border-subtle); }
table.data-table tr:hover td { background: var(--bg-surface-hover); }

.badge { display: inline-flex; align-items: center; padding: 0.15rem 0.55rem; border-radius: 999px; background: var(--bg-surface-hover); font-size: var(--text-xs); font-weight: 600; }
.badge.risk-low { background: var(--success-dim); color: var(--success); }
.badge.risk-medium { background: var(--warning-dim); color: var(--warning); }
.badge.risk-high, .badge.risk-critical { background: var(--danger-dim); color: var(--danger); }
.badge.status-completed, .badge.status-executed, .badge.status-active, .badge.status-approved, .badge.status-ok { background: var(--success-dim); color: var(--success); }
.badge.status-failed, .badge.status-rejected, .badge.status-error { background: var(--danger-dim); color: var(--danger); }
.badge.status-queued, .badge.status-proposed, .badge.status-awaiting_approval, .badge.status-pending { background: var(--warning-dim); color: var(--warning); }
.badge.status-cancelled { background: var(--bg-surface-hover); color: var(--text-tertiary); }

.state { padding: var(--space-5) 0; font-size: var(--text-sm); }
.state.empty { color: var(--text-tertiary); font-style: italic; }
.state.error { color: var(--danger); }
.state.success { color: var(--success); }
.state.unavailable { color: var(--warning); font-style: italic; }
.state.loading { color: var(--text-tertiary); }

@keyframes skeleton-pulse { 0%, 100% { opacity: 0.5; } 50% { opacity: 0.9; } }
.skeleton { background: var(--bg-surface-hover); border-radius: var(--radius-sm); animation: skeleton-pulse 1.4s ease-in-out infinite; }
.skeleton-line { height: 14px; margin-bottom: var(--space-2); }
.skeleton-row { display: flex; gap: var(--space-3); margin-bottom: var(--space-2); }

.tabs { display: flex; gap: var(--space-1); border-bottom: 1px solid var(--border-subtle); margin-bottom: var(--space-4); }
.tab { padding: var(--space-2) var(--space-3); font-size: var(--text-sm); color: var(--text-secondary); border: none; background: none; cursor: pointer; border-bottom: 2px solid transparent; margin-bottom: -1px; }
.tab:hover { color: var(--text-primary); }
.tab.active { color: var(--accent-hover); border-bottom-color: var(--accent); }

.stat-grid { display: flex; gap: var(--space-3); flex-wrap: wrap; }
.stat { background: var(--bg-surface); border: 1px solid var(--border-subtle); border-radius: var(--radius-md); padding: var(--space-4); font-size: var(--text-sm); min-width: 140px; }
.stat .stat-value { font-size: var(--text-xl); font-weight: 700; display: block; margin-top: var(--space-1); }
.stat .stat-label { color: var(--text-tertiary); font-size: var(--text-xs); text-transform: uppercase; letter-spacing: 0.05em; }

.toolbar { display: flex; align-items: center; gap: var(--space-2); margin-bottom: var(--space-4); flex-wrap: wrap; }
.hint { color: var(--text-tertiary); font-size: var(--text-xs); margin-top: var(--space-2); }
.hint.error { color: var(--danger); }
.hint.success { color: var(--success); }
.hint.warning { color: var(--warning); }

/* Chat-first layout mission: Chat vs Build tabs inside the Savannah
   view. Only 2 tabs, so no horizontal-scroll handling is needed even
   at 390px — both fit with room to spare. */
.savannah-tabs { display: flex; gap: var(--space-2); margin: var(--space-4) 0; border-bottom: 1px solid var(--border-subtle); }
.savannah-tab-btn {
  background: none; border: none; border-bottom: 2px solid transparent; color: var(--text-tertiary);
  padding: var(--space-3) var(--space-2); font-size: var(--text-sm); font-weight: 600; cursor: pointer;
  min-height: 44px; /* real touch target, not a visual-only size */
}
.savannah-tab-btn:hover { color: var(--text-primary); }
.savannah-tab-btn.active { color: var(--text-primary); border-bottom-color: var(--accent); }
.savannah-tab-panel { min-width: 0; } /* prevents a long unbroken token (e.g. a workspace path) from forcing the panel wider than its flex parent */

/* Conversation management mission: chat list row actions wrap on
   narrow screens instead of forcing horizontal overflow, and the
   search input is full-width so it's reachable with a thumb. */
.chat-row-actions { display: flex; gap: var(--space-2); flex-wrap: wrap; }
.chat-search { width: 100%; max-width: 320px; margin-bottom: var(--space-3); }
/* Found live at 390px: three side-by-side action buttons forced the
   whole table wider than the viewport, so Delete was only reachable by
   scrolling the table horizontally first — stacking them removes that
   extra width instead of relying on scroll-to-discover. */
@media (max-width: 640px) {
  .chat-row-actions { flex-direction: column; align-items: stretch; }
  .chat-row-actions .btn { width: 100%; }
  /* Measured live: Chat+Mode+Created+Actions together still exceeded
     the available ~324px mobile content width even after stacking the
     actions column — Mode/Created are secondary here, so they're
     dropped on narrow screens rather than forcing horizontal scroll to
     reach Rename/Delete. */
  .chat-list-table th:nth-child(2), .chat-list-table td:nth-child(2),
  .chat-list-table th:nth-child(3), .chat-list-table td:nth-child(3) { display: none; }
}

/* Permissions & Approvals mission */
.approval-policy-options { display: flex; flex-direction: column; gap: var(--space-2); margin-bottom: var(--space-3); }
.approval-policy-option {
  display: flex; align-items: flex-start; gap: var(--space-3); padding: var(--space-3);
  border: 1px solid var(--border-subtle); border-radius: var(--radius-md); cursor: pointer;
}
.approval-policy-option.selected { border-color: var(--accent); background: var(--bg-surface-hover); }
.approval-policy-option input[type="radio"] { margin-top: 3px; flex-shrink: 0; }
.approval-policy-option-title { font-weight: 600; margin-bottom: 2px; }
.approval-policy-option-desc { font-size: var(--text-xs); color: var(--text-tertiary); }
.output { background: var(--bg-canvas); border: 1px solid var(--border-subtle); border-radius: var(--radius-md); padding: var(--space-4); font-size: var(--text-xs); font-family: var(--font-mono); overflow-x: auto; max-height: 420px; }
.banner { padding: var(--space-3) var(--space-4); border-radius: var(--radius-md); margin-bottom: var(--space-4); font-weight: 600; font-size: var(--text-sm); }
.banner.ok { background: var(--success-dim); color: var(--success); }
.banner.fail { background: var(--danger-dim); color: var(--danger); }

.chat-thread { display: flex; flex-direction: column; gap: var(--space-3); max-height: 480px; overflow-y: auto; padding: var(--space-3); background: var(--bg-canvas); border: 1px solid var(--border-subtle); border-radius: var(--radius-md); margin-bottom: var(--space-3); }
.chat-message { max-width: 85%; padding: var(--space-3) var(--space-4); border-radius: var(--radius-lg); font-size: var(--text-sm); line-height: 1.5; white-space: pre-wrap; word-break: break-word; }
.chat-message.role-user { align-self: flex-end; background: var(--accent-dim); border: 1px solid var(--border-subtle); }
.chat-message.role-system { align-self: stretch; max-width: 100%; background: var(--bg-surface-raised); border: 1px solid var(--border-subtle); }
.chat-message.role-system.diagnostic { border-color: var(--warning); background: var(--warning-dim); }
.chat-message .chat-message-meta { font-size: var(--text-xs); color: var(--text-tertiary); margin-bottom: var(--space-1); text-transform: uppercase; letter-spacing: 0.05em; }
.chat-message .chat-message-actions { margin-top: var(--space-3); }
.approval-panel { border: 1px solid var(--accent); border-radius: var(--radius-md); padding: var(--space-4); margin-top: var(--space-3); }
.divider { color: var(--text-tertiary); font-size: var(--text-xs); text-transform: uppercase; letter-spacing: 0.08em; margin: var(--space-3) 0; text-align: center; }
.link { color: var(--accent-hover); text-decoration: none; cursor: pointer; }
.link:hover { text-decoration: underline; }

.modal-overlay { position: fixed; inset: 0; background: rgba(0,0,0,0.55); display: flex; align-items: flex-start; justify-content: center; padding-top: 12vh; z-index: 100; }
.modal { background: var(--bg-surface-raised); border: 1px solid var(--border-strong); border-radius: var(--radius-lg); box-shadow: var(--shadow-md); width: 100%; max-width: 480px; padding: var(--space-4); }
.cmdk-input { width: 100%; font-size: var(--text-base); padding: var(--space-3); margin: 0 0 var(--space-3); }
.cmdk-list { max-height: 320px; overflow-y: auto; display: flex; flex-direction: column; gap: 2px; }
.cmdk-item { padding: var(--space-2) var(--space-3); border-radius: var(--radius-sm); cursor: pointer; font-size: var(--text-sm); display: flex; justify-content: space-between; }
.cmdk-item:hover, .cmdk-item.selected { background: var(--accent-dim); color: var(--accent-hover); }

/* Cinematic opening screen (brand brief Reference 3): deep ink-black
   canvas with a soft radial falloff toward the edges for atmospheric
   depth — pure CSS, no image asset, so it costs nothing to load and
   never shifts layout. */
.entry {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  min-height: 100vh; text-align: center; gap: var(--space-6);
  padding: var(--space-8) var(--space-4);
  background: radial-gradient(ellipse 80% 60% at 50% 38%, #0d0d0f 0%, var(--ink-black) 70%);
}
.entry-hero { position: relative; display: flex; flex-direction: column; align-items: center; margin-bottom: var(--space-2); }
/* No real engraving illustration asset exists in this repo — this is a
   restrained, hand-authored inline-SVG line/stipple motif used as the
   honest CSS fallback the brand brief asks for, not a claim of real
   artwork. Enlarged and lowered further toward Reference 1's "subtle
   celestial/angelic geometry" treatment — sits behind the hero text,
   never over it, and never blocks clicks. */
.entry-hero::before {
  content: '';
  position: absolute;
  top: 50%; left: 50%;
  width: 520px; height: 520px;
  transform: translate(-50%, -50%);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 200'%3E%3Cg fill='none' stroke='%23E8E4D3' stroke-width='1.25' stroke-linecap='round'%3E%3Cline x1='100' y1='8' x2='100' y2='192'/%3E%3Cline x1='100' y1='28' x2='130' y2='12'/%3E%3Cline x1='100' y1='52' x2='70' y2='36'/%3E%3Cline x1='100' y1='76' x2='130' y2='60'/%3E%3Cline x1='100' y1='100' x2='70' y2='84'/%3E%3Cline x1='100' y1='124' x2='130' y2='108'/%3E%3Cline x1='100' y1='148' x2='70' y2='132'/%3E%3Cline x1='100' y1='172' x2='130' y2='156'/%3E%3C/g%3E%3Cg fill='%23E8E4D3'%3E%3Ccircle cx='38' cy='38' r='1'/%3E%3Ccircle cx='162' cy='48' r='1'/%3E%3Ccircle cx='33' cy='100' r='1'/%3E%3Ccircle cx='167' cy='112' r='1'/%3E%3Ccircle cx='44' cy='162' r='1'/%3E%3Ccircle cx='156' cy='167' r='1'/%3E%3Ccircle cx='58' cy='22' r='0.75'/%3E%3Ccircle cx='142' cy='28' r='0.75'/%3E%3Ccircle cx='53' cy='177' r='0.75'/%3E%3Ccircle cx='147' cy='182' r='0.75'/%3E%3C/g%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: center;
  background-size: contain;
  opacity: 0.07;
  pointer-events: none;
  z-index: 0;
  animation: entry-motif-breathe 10s ease-in-out infinite;
}
@keyframes entry-motif-breathe { 0%, 100% { opacity: 0.07; } 50% { opacity: 0.12; } }
.entry-hero > * { position: relative; z-index: 1; }
/* The existing Savannah mark (same "S" monogram as the favicon, see
   index.html) elevated as the hero's focal point — not a new or
   substituted symbol, just a larger, refined rendering of the one
   identity mark this product already has. Gradient stops are the
   palette's own two ivory tokens, so the metallic effect never
   introduces a fifth color. */
.entry-logo { width: 84px; height: 84px; margin-bottom: var(--space-4); filter: drop-shadow(0 2px 10px rgba(0,0,0,0.6)); }
.entry-kicker { font-size: var(--text-xs); letter-spacing: 0.28em; color: var(--text-secondary); font-weight: 700; text-transform: uppercase; }
.entry-title { font-size: clamp(1.75rem, 1.2rem + 2.2vw, 2.75rem); font-weight: 600; letter-spacing: -0.01em; margin: 0.25rem 0 0; color: var(--text-primary); }
.entry-title.muted { color: var(--text-tertiary); font-style: italic; }
.entry-sub { max-width: 480px; color: var(--text-secondary); font-size: var(--text-base); line-height: 1.6; margin-top: var(--space-3); }
/* Subtle glass surface (brand brief: glass reserved for nav/overlays/
   pricing cards, never editors/logs/tables) — the auth card is part of
   the cinematic entry experience, not a data surface. */
.entry-card {
  width: 100%; max-width: 360px; padding: var(--space-6);
  background: rgba(0, 0, 0, 0.72);
  -webkit-backdrop-filter: blur(16px);
  backdrop-filter: blur(16px);
  border: 1px solid var(--border-subtle);
  box-shadow: var(--shadow-md), 0 0 0 1px rgba(232, 228, 211, 0.04) inset;
}
.entry-card .btn.full { width: 100%; box-sizing: border-box; margin: 0.3rem 0; }
.entry-card input { width: 100%; box-sizing: border-box; }
.entry-footer { margin-top: var(--space-3); font-size: var(--text-sm); }
@media (prefers-reduced-motion: reduce) {
  .entry-hero::before { animation: none; }
}

/*
 * Welcome screen — the pre-login splash, shown once per browser load
 * before the login form (see js/main.js's renderWelcomeScreen()). Full
 * deep-black canvas (the brand's existing --bg-canvas token, not a new
 * color), the dragonfly logo displayed with contain-style scaling only
 * (see renderWelcomeScreen()'s own comment for exactly which file is
 * rendered, why, and the non-destructive guarantee behind it), and a
 * metallic-silver gradient-text headline. No button, no card, no
 * gradient background panel — the whole screen is one tap/click/
 * keyboard-activatable region that advances to login.
 */
.welcome-screen {
  min-height: 100vh;
  width: 100%;
  background: #000; /* pure black, per the approved welcome-screen directive — distinct from the brand's usual near-black --bg-canvas */
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-6);
  padding: var(--space-8) var(--space-4);
  text-align: center;
  cursor: pointer;
}
/*
 * Brand hierarchy (per the approved directive): the dragonfly logo at
 * the top, the SAVANNAH AI wordmark directly beneath it, then the
 * headline. Nothing else — no descriptor, no tagline. "Built To
 * Perform" is Syntrovia's (the parent company's) tagline, not Savannah
 * AI's — deliberately absent from this screen.
 */
.welcome-wordmark {
  font-family: var(--font-brand);
  font-weight: 400;
  font-size: clamp(1.5rem, 1.1rem + 1.8vw, 2.5rem);
  letter-spacing: 0.08em;
  margin: 0;
  color: var(--text-primary); /* fallback for browsers without background-clip: text */
}
/*
 * Source resolution, inspected directly (not assumed): the official
 * dragonfly artwork is 371x559px — no higher-resolution variant exists
 * anywhere in this repo to serve via srcset for denser displays, so
 * this IS the real ceiling on how large this image can render without
 * upscaling. Sized here to stay pixel-perfect (no upscaling at all)
 * through 2x "Retina"-class density — the common case for laptop/
 * desktop screens and the large majority of phones: 180px CSS width x
 * 2x DPR = 360 physical px, still under the source's 371px native
 * width. On the minority of screens at 3x device pixel ratio (e.g.
 * iPhone Pro-class phones), this is a real, disclosed trade-off: the
 * browser upscales by roughly 1.46x (540 physical px requested from a
 * 371px source) to keep the mark visually prominent at that size,
 * which introduces mild softening rather than the hard pixel-perfect
 * render achieved at 1x/2x. This is the actual, honest ceiling of a
 * single 371x559px source — a sharper 3x render would require a
 * higher-resolution source image, which does not currently exist. No
 * drop-shadow/blur filter: a blurred shadow reads as a cheap effect on
 * a pure black background where it has nothing to contrast against.
 */
.welcome-logo {
  display: block;
  width: min(180px, 46vw);
  height: auto;
  max-height: 42vh;
  object-fit: contain;
}
/*
 * font-weight: 400 (normal) throughout this screen's text is
 * deliberate, not an oversight: SpecialElite-Regular.ttf ships exactly
 * one weight (confirmed via its own name table — "Special Elite
 * Regular"/400, no bold/italic companions). Asking for 600/700 would
 * not select a different real weight; it would make the browser
 * SYNTHESIZE a fake bold by algorithmically thickening the real
 * outlines, which both looks rougher than the authentic typeface and
 * is exactly the kind of "approximation" the font directive says to
 * avoid. Weight/size/spacing below are tuned for this specific
 * typewriter-style face (wider, more even strokes than a conventional
 * serif) rather than carried over from a different font's proportions.
 */
.welcome-headline {
  font-family: var(--font-brand);
  font-weight: 400;
  font-size: clamp(1.35rem, 0.95rem + 1.9vw, 2.5rem);
  line-height: 1.5;
  margin: 0;
  letter-spacing: 0;
  color: var(--text-primary); /* fallback for browsers without background-clip: text */
}
/* Forced two-line composition (two literal <span> rows, not text that
   happens to wrap there) — "The developer is the limit." / "Not the
   laptop." is the intended break at every viewport width, not just
   ones where the font's natural wrap happens to land on it. */
.welcome-headline span { display: block; }
/* Premium metallic-silver typography — a pure CSS gradient clipped to
   the text, applied only to this screen's text elements. Entirely
   presentational and reversible: the logo's own metallic look is a
   separate image (dragonfly-logo-chrome.png, see renderWelcomeScreen()'s
   own comment) — this gradient never touches image pixels. */
@supports (background-clip: text) or (-webkit-background-clip: text) {
  .welcome-wordmark, .welcome-headline {
    background: linear-gradient(115deg, #8d8f94 0%, #e9ebee 24%, #ffffff 46%, #c6c8cc 62%, #f3f4f6 80%, #97999e 100%);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
    -webkit-text-fill-color: transparent;
  }
}

/* Hidden by default (desktop always shows the sidebar inline); the
   media query below is the only place this becomes visible. */
.menu-toggle { display: none; background: none; border: 1px solid var(--border-subtle); color: var(--text-primary); border-radius: var(--radius-sm); width: 36px; height: 36px; font-size: var(--text-lg); line-height: 1; cursor: pointer; flex-shrink: 0; }
.menu-toggle:hover { border-color: var(--accent); }
.sidebar-overlay { display: none; }

@media (max-width: 860px) {
  .sidebar { position: fixed; left: 0; z-index: 30; transform: translateX(-100%); transition: transform 0.18s ease; box-shadow: var(--shadow-md); }
  .sidebar.open { transform: translateX(0); }
  main#main { padding: var(--space-4); }
  .topbar { padding: 0 var(--space-3); gap: var(--space-2); }
  .menu-toggle { display: inline-flex; align-items: center; justify-content: center; }
  .topbar-scope { max-width: 46vw; }
  .sidebar-overlay {
    display: block; position: fixed; inset: 0; background: rgba(3, 18, 17, 0.6);
    z-index: 25; opacity: 0; pointer-events: none; transition: opacity 0.18s ease;
  }
  .sidebar-overlay.open { opacity: 1; pointer-events: auto; }

  /* Touch targets: Apple HIG / WCAG 2.5.5 recommend a 44x44pt minimum
     for touch. Desktop's tighter sizing (mouse input, dense admin
     screens) is left exactly as-is — this is scoped to the mobile
     breakpoint only, not a global bump. Plain inline text links
     (a.link, e.g. "Forgot password?") are deliberately excluded: WCAG's
     own target-size guidance exempts inline links within a sentence,
     and forcing 44px on them would require breaking their natural text
     flow for no real usability gain. */
  .btn, .sidebar-item, .menu-toggle, .account-badge,
  input, select, textarea {
    min-height: 44px;
  }
  /* iOS Safari zooms the whole page when a form control under 16px is focused (the composer, selects, search). 16px prevents that. */
  input, select, textarea { font-size: 16px; }
  .btn { padding-top: var(--space-3); padding-bottom: var(--space-3); box-sizing: border-box; }
  .sidebar-item { padding-top: var(--space-3); padding-bottom: var(--space-3); box-sizing: border-box; }
  .account-badge { min-width: 44px; border-radius: 22px; }
  .menu-toggle { min-width: 44px; }
}

@media (prefers-reduced-motion: reduce) {
  .sidebar { transition: none; }
}

/* ---------- Page header ---------- */
.page-header { margin-bottom: var(--space-5); }
.page-header-row { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); }
.page-header-row h2 { margin: 0; }
.page-header-subtitle { color: var(--text-tertiary); font-size: var(--text-sm); margin: var(--space-1) 0 0; max-width: 640px; }

/* ---------- Method badges (API screen) ---------- */
.badge.method-get { background: var(--info); color: var(--text-inverse); }
.badge.method-post { background: var(--success); color: var(--text-inverse); }
.badge.method-put, .badge.method-patch { background: var(--warning); color: var(--text-inverse); }
.badge.method-delete { background: var(--danger); color: var(--text-inverse); }

/* ---------- Provider / health status ---------- */
.provider-status { display: inline-flex; align-items: center; gap: var(--space-2); font-size: var(--text-sm); }
.provider-status-dot { width: 8px; height: 8px; border-radius: 50%; display: inline-block; }
.provider-status-ok .provider-status-dot { background: var(--success); }
.provider-status-warn .provider-status-dot { background: var(--warning); }
.provider-status-bad .provider-status-dot { background: var(--danger); }
.provider-status-muted .provider-status-dot { background: var(--text-tertiary); }
.provider-status-muted { color: var(--text-tertiary); }

/* ---------- Key/value list ---------- */
.kv-list { display: grid; grid-template-columns: 160px 1fr; gap: var(--space-2) var(--space-4); font-size: var(--text-sm); margin: 0; }
.kv-list dt { color: var(--text-tertiary); }
.kv-list dd { margin: 0; color: var(--text-primary); }

/* ---------- JSON viewer with copy button ---------- */
.json-viewer { position: relative; }
.json-viewer .copy-btn { position: absolute; top: var(--space-2); right: var(--space-2); padding: 0.2rem 0.6rem; font-size: var(--text-xs); }

/* ---------- Deployment pipeline timeline ---------- */
.timeline { display: flex; align-items: flex-start; gap: 0; flex-wrap: wrap; margin: var(--space-3) 0; }
.timeline-step { display: flex; flex-direction: column; align-items: center; gap: var(--space-1); flex: 1; min-width: 72px; position: relative; }
.timeline-step:not(:last-child)::after { content: ''; position: absolute; top: 6px; left: 55%; width: 90%; height: 2px; background: var(--border-subtle); }
.timeline-step.reached:not(:last-child)::after { background: var(--accent); }
.timeline-dot { width: 12px; height: 12px; border-radius: 50%; background: var(--border-strong); z-index: 1; }
.timeline-step.reached .timeline-dot { background: var(--accent); }
.timeline-step.current .timeline-dot { background: var(--accent-hover); box-shadow: 0 0 0 3px var(--accent-dim); }
.timeline-step.failure .timeline-dot { background: var(--danger); box-shadow: 0 0 0 3px var(--danger-dim); }
.timeline-label { font-size: 0.6875rem; color: var(--text-tertiary); text-transform: capitalize; text-align: center; }
.timeline-step.reached .timeline-label { color: var(--text-secondary); }

/* ---------- Usage bar (Plan & Usage) ---------- */
.usage-bar { height: 8px; background: var(--bg-surface-hover); border-radius: 999px; overflow: hidden; margin: var(--space-3) 0 var(--space-2); }
.usage-bar-fill { height: 100%; background: var(--accent); border-radius: 999px; transition: width 0.3s ease; }

/* ---------- Pricing (Reference 2): dark glass cards, restrained edge
   illumination, fine borders, large readable price, pill CTA. This is
   one of the brand brief's named exceptions to the design system's
   otherwise-square corner language (see --radius-* above) — scoped to
   .pricing-card only, never applied to .btn globally. Desktop lays
   plans side by side; narrower viewports fall back to a single column
   automatically via auto-fit, no separate mobile override needed. */
.pricing-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: var(--space-5); align-items: stretch; margin-top: var(--space-5); }
.pricing-card {
  display: flex; flex-direction: column;
  background: linear-gradient(160deg, var(--bg-surface-raised) 0%, var(--bg-surface) 100%);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg);
  padding: var(--space-6) var(--space-5);
  box-shadow: var(--shadow-sm);
}
.pricing-card-current { border-color: var(--border-strong); box-shadow: 0 0 0 1px var(--accent-dim), var(--shadow-md); }
.pricing-card-name { font-family: var(--font-brand); font-size: var(--text-lg); color: var(--text-primary); }
.pricing-card-price { font-size: var(--text-2xl); font-weight: 600; color: var(--text-primary); margin: var(--space-2) 0 0; }
.pricing-card-interval { font-size: var(--text-xs); color: var(--text-tertiary); margin-bottom: var(--space-4); }
.pricing-card-features { list-style: none; margin: 0 0 var(--space-5); padding: 0; display: flex; flex-direction: column; gap: var(--space-2); flex: 1; }
.pricing-card-features li { font-size: var(--text-sm); color: var(--text-secondary); padding-left: var(--space-4); position: relative; }
.pricing-card-features li::before { content: '—'; position: absolute; left: 0; color: var(--text-tertiary); }
.pricing-card-note { font-size: var(--text-xs); color: var(--text-tertiary); text-align: center; padding: var(--space-2) 0; }
.pricing-card .btn.full { border-radius: 999px; width: 100%; box-sizing: border-box; }
.pricing-card .pricing-current { background: var(--accent-dim); border: 1px solid var(--border-strong); color: var(--text-secondary); text-align: center; padding: 0.55rem 0; cursor: default; }
.pricing-footer { margin-top: var(--space-5); display: flex; justify-content: center; }

/* ---------- Site footer (copyright + legal links) ---------- */
.site-footer {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: center;
  gap: var(--space-2) var(--space-4);
  font-size: var(--text-xs); color: var(--text-tertiary);
  padding: var(--space-4);
  text-align: center;
}
.site-footer a { color: var(--text-tertiary); text-decoration: none; }
.site-footer a:hover { color: var(--text-secondary); text-decoration: underline; }
.site-footer .sep { color: var(--border-strong); }
.sidebar-footer {
  margin-top: auto;
  padding-top: var(--space-3);
  border-top: 1px solid var(--border-subtle);
  font-size: 0.6875rem;
  color: var(--text-tertiary);
  display: flex; flex-direction: column; gap: var(--space-1);
}
.sidebar-footer a { color: var(--text-tertiary); text-decoration: none; }
.sidebar-footer a:hover { color: var(--text-secondary); text-decoration: underline; }
.sidebar-footer .legal-links { display: flex; gap: var(--space-2); flex-wrap: wrap; }

/* ---------- Standalone legal pages (privacy.html / terms.html) ---------- */
.legal-page { max-width: 760px; margin: 0 auto; padding: var(--space-8) var(--space-4) var(--space-6); }
.legal-page .legal-back { display: inline-block; margin-bottom: var(--space-6); font-size: var(--text-sm); }
.legal-page h1 { font-size: var(--text-2xl); margin-bottom: var(--space-2); }
.legal-page .legal-updated { color: var(--text-tertiary); font-size: var(--text-sm); margin-bottom: var(--space-6); }
.legal-page h2 { font-size: var(--text-lg); margin-top: var(--space-6); padding-top: var(--space-5); border-top: 1px solid var(--border-subtle); }
.legal-page h2:first-of-type { border-top: none; padding-top: 0; }
.legal-page p, .legal-page li { color: var(--text-secondary); line-height: 1.7; font-size: var(--text-sm); }
.legal-page ul { padding-left: var(--space-5); }
.legal-page li { margin-bottom: var(--space-2); }
.legal-page .placeholder { color: var(--warning); font-style: italic; }
.legal-page strong { color: var(--text-primary); }

/* ---------- Voice input / read-aloud (Mission 37) ---------- */
.voice-controls { margin: var(--space-2) 0; display: flex; flex-direction: column; gap: var(--space-2); }
.voice-row { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); }
.voice-row .btn, .voice-row select { min-height: 44px; } /* touch-sized targets */
.voice-language { max-width: 100%; }
.voice-mic.recording { border-color: var(--danger, #d33); color: var(--danger, #d33); }
.voice-status { min-height: 1.25em; font-size: var(--text-sm); color: var(--text-secondary); overflow-wrap: anywhere; }
.voice-status.recording { color: var(--danger, #d33); font-weight: 600; }
.voice-status.error { color: var(--danger, #d33); }
.voice-status.success { color: var(--success, #2a8); }
.voice-disclosure, .voice-note { font-size: 0.75rem; overflow-wrap: anywhere; }
.voice-preview { border: 1px solid var(--border-subtle); border-radius: 8px; padding: var(--space-3); display: flex; flex-direction: column; gap: var(--space-2); }
.voice-preview-title { font-weight: 600; font-size: var(--text-sm); }
.voice-preview-text { margin: 0; padding-left: var(--space-3); border-left: 3px solid var(--border-strong); white-space: pre-wrap; overflow-wrap: anywhere; }
.voice-flag { font-size: var(--text-sm); color: var(--warning, #c80); }
.voice-readaloud { display: inline-flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); }
.voice-readaloud-note { font-size: 0.75rem; }
@media (max-width: 600px) {
  .voice-row { flex-direction: column; align-items: stretch; }
  .voice-row .btn, .voice-row select { width: 100%; }
}

/* ==========================================================================
   Mission 39 — usage orb, chat header/menu, dragonfly activity indicator,
   and the usage / background-tasks / share-project panels.
   ========================================================================== */

/* --- Usage orb ----------------------------------------------------------- */
.usage-orb { position: relative; display: inline-block; flex: none; line-height: 0; }
.usage-orb-canvas { display: block; }
.usage-orb-label {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  color: #eef1f2; font-family: var(--font-mono); font-weight: 600; letter-spacing: -0.02em; line-height: 1;
  text-shadow: 0 0 6px rgba(3, 18, 17, 0.9); pointer-events: none; font-variant-numeric: tabular-nums;
}
.usage-orb[data-state="unavailable"] .usage-orb-label,
.usage-orb[data-state="loading"] .usage-orb-label { color: var(--text-secondary); }
.usage-orb[data-state="error"] .usage-orb-label { color: var(--warning); }

/* --- Chat header + three-dot menu --------------------------------------- */
.chat-header { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); min-width: 0; margin: var(--space-3) 0; }
.chat-header-title { margin: 0; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--text-lg); }
.chat-header-actions { display: flex; align-items: center; gap: var(--space-2); flex: none; }
.orb-button, .menu-button {
  display: inline-flex; align-items: center; justify-content: center; min-width: 44px; min-height: 44px; padding: 0;
  background: transparent; border: 1px solid var(--border-subtle); border-radius: 999px; color: var(--text-primary); cursor: pointer; font-size: 1.25rem;
}
.orb-button:hover, .menu-button:hover { border-color: var(--accent); }
.chat-menu-wrap { position: relative; }
.chat-menu {
  position: absolute; right: 0; top: calc(100% + 6px); z-index: 60; min-width: 190px; max-width: min(280px, calc(100vw - 32px));
  display: flex; flex-direction: column; padding: var(--space-1); background: var(--bg-surface-raised);
  border: 1px solid var(--border-strong); border-radius: var(--radius-md); box-shadow: var(--shadow-md);
}
.chat-menu[hidden] { display: none; }
.chat-menu-item {
  min-height: 44px; padding: var(--space-2) var(--space-3); text-align: left; background: transparent; border: 0; border-radius: var(--radius-sm);
  color: var(--text-primary); font: inherit; cursor: pointer;
}
.chat-menu-item:hover, .chat-menu-item:focus-visible { background: var(--bg-surface-hover); }

/* --- Dragonfly activity indicator ---------------------------------------
   The supplied artwork is an opaque JPEG on pure black, shown unaltered on a
   black square with `screen` blending (black adds nothing). It is square
   (1:1) and is never cropped, rotated, stretched or recoloured. */
.activity-indicator {
  display: flex; align-items: center; gap: var(--space-3); margin: var(--space-3) 0; padding: var(--space-2) var(--space-3);
  background: #000; border: 1px solid var(--border-subtle); border-radius: var(--radius-md); min-width: 0;
}
.activity-indicator[hidden] { display: none; }
.dragonfly-frame { position: relative; flex: none; width: 56px; height: 56px; overflow: hidden; border-radius: 10px; background: #000; }
.dragonfly-art { display: block; width: 100%; height: 100%; aspect-ratio: 1 / 1; object-fit: contain; mix-blend-mode: screen; user-select: none; -webkit-user-drag: none; }
.dragonfly-frame::before { content: ""; position: absolute; inset: 0; pointer-events: none; opacity: 0; mix-blend-mode: screen; background: radial-gradient(circle at 50% 50%, rgba(214, 220, 224, 0.55), rgba(214, 220, 224, 0) 62%); }
/* The sweep lives inside a STATIC, masked parent: the soft circular falloff therefore stays fixed while the gradient slides through it,
   so no hard-edged band ever shows at the frame's edge (a mask on the moving element itself would travel with it). */
.dragonfly-sheen { position: absolute; inset: 0; overflow: hidden; pointer-events: none; mix-blend-mode: screen; -webkit-mask-image: radial-gradient(circle closest-side at 50% 50%, #000 40%, transparent 100%); mask-image: radial-gradient(circle closest-side at 50% 50%, #000 40%, transparent 100%); }
.dragonfly-sheen::after { content: ""; position: absolute; inset: 0; opacity: 0; background: linear-gradient(105deg, rgba(255, 255, 255, 0) 30%, rgba(255, 255, 255, 0.3) 50%, rgba(255, 255, 255, 0) 70%); transform: translateX(-120%); }
.activity-indicator[data-animated="true"] .dragonfly-frame::before { animation: dragonfly-breathe 3.6s ease-in-out infinite; }
.activity-indicator[data-animated="true"] .dragonfly-sheen::after { animation: dragonfly-sweep 3.6s ease-in-out infinite; }
.activity-indicator[data-phase="working"] .dragonfly-frame::before { animation-duration: 2.4s; }
.activity-indicator[data-phase="working"] .dragonfly-sheen::after { animation-duration: 2.4s; }
@keyframes dragonfly-breathe { 0%, 100% { opacity: 0; } 50% { opacity: 0.7; } }
@keyframes dragonfly-sweep { 0% { transform: translateX(-120%); opacity: 0; } 15% { opacity: 1; } 55% { transform: translateX(120%); opacity: 1; } 100% { transform: translateX(120%); opacity: 0; } }
.activity-copy { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; }
.activity-text { color: var(--text-primary); overflow-wrap: anywhere; }
.activity-detail { color: var(--text-secondary); font-size: var(--text-sm); overflow-wrap: anywhere; }
.activity-indicator[data-phase="failed"] .activity-text { color: var(--danger); }
.activity-indicator[data-phase="awaiting_approval"] .activity-text { color: var(--warning); }
.activity-dismiss { flex: none; min-width: 44px; min-height: 44px; background: transparent; border: 0; color: var(--text-secondary); font-size: 1.25rem; cursor: pointer; }

/* --- Panels (usage / background tasks / share) --------------------------- */
.panel-overlay { position: fixed; inset: 0; z-index: 110; display: flex; align-items: flex-start; justify-content: center; padding: 6vh var(--space-4) var(--space-4); background: rgba(0, 0, 0, 0.6); }
.panel-sheet {
  display: flex; flex-direction: column; width: 100%; max-width: 560px; max-height: 88vh; max-height: 88dvh; overflow: hidden;
  background: var(--bg-surface-raised); border: 1px solid var(--border-strong); border-radius: var(--radius-lg); box-shadow: var(--shadow-md);
}
.panel-sheet.panel-wide { max-width: 760px; }
.panel-head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); padding: var(--space-3) var(--space-4); border-bottom: 1px solid var(--border-subtle); }
.panel-title { margin: 0; font-size: var(--text-lg); }
.panel-close { min-width: 44px; min-height: 44px; background: transparent; border: 0; color: var(--text-primary); font-size: 1.5rem; cursor: pointer; }
.panel-body { padding: var(--space-4); padding-bottom: max(var(--space-4), env(safe-area-inset-bottom)); overflow-y: auto; overscroll-behavior: contain; min-height: 0; }
.panel-sheet .btn { min-height: 44px; }
.panel-actions { margin-top: var(--space-4); display: flex; gap: var(--space-2); flex-wrap: wrap; }
@media (max-width: 640px) {
  .panel-overlay { align-items: flex-end; padding: 0; }
  .panel-sheet, .panel-sheet.panel-wide { max-width: none; max-height: 92vh; max-height: 92dvh; border-radius: var(--radius-lg) var(--radius-lg) 0 0; }
}

.usage-headline { display: flex; align-items: center; gap: var(--space-4); }
.usage-headline-text { min-width: 0; }
.usage-headline-text p { margin: var(--space-1) 0 0; }
.usage-subhead { margin: var(--space-4) 0 var(--space-2); font-size: var(--text-base); }
.usage-list { margin: 0; display: grid; gap: 0; }
.usage-row { display: grid; grid-template-columns: minmax(0, 11rem) minmax(0, 1fr); gap: var(--space-3); padding: var(--space-2) 0; border-top: 1px solid var(--border-subtle); }
.usage-row dt { color: var(--text-secondary); }
.usage-row dd { margin: 0; display: flex; flex-direction: column; overflow-wrap: anywhere; }
.usage-row small { color: var(--text-tertiary); }
.data-table td.num, .data-table th:not(:first-child) { text-align: right; font-variant-numeric: tabular-nums; }
.state.warning { color: var(--warning); background: var(--warning-dim); }
@media (max-width: 480px) { .usage-row { grid-template-columns: 1fr; gap: 2px; } .usage-headline { flex-direction: column; align-items: flex-start; } }

.tasks-toolbar { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); flex-wrap: wrap; margin-bottom: var(--space-3); }
.tasks-count { margin: 0; color: var(--text-secondary); font-size: var(--text-sm); }
.tasks-group-title { margin: var(--space-4) 0 var(--space-2); font-size: var(--text-base); }
.task-card { padding: var(--space-3); margin-bottom: var(--space-2); background: var(--bg-surface); border: 1px solid var(--border-subtle); border-radius: var(--radius-md); min-width: 0; }
.task-card-head { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--space-2); }
.task-card-title { margin: 0; font-size: var(--text-base); overflow-wrap: anywhere; min-width: 0; }
.task-card-meta { margin: var(--space-1) 0 0; color: var(--text-secondary); font-size: var(--text-sm); overflow-wrap: anywhere; }
.task-card-summary { margin: var(--space-2) 0 0; overflow-wrap: anywhere; }
.task-card-error { margin: var(--space-2) 0 0; color: var(--danger); overflow-wrap: anywhere; }
.task-card-actions { display: flex; gap: var(--space-2); flex-wrap: wrap; margin-top: var(--space-2); }
.task-card-actions .btn { min-height: 44px; }
.task-card-request { margin: var(--space-2) 0; padding: var(--space-2); max-height: 10rem; overflow: auto; white-space: pre-wrap; overflow-wrap: anywhere; background: #000; border-radius: var(--radius-sm); font-family: var(--font-mono); font-size: var(--text-xs); }
.task-events { margin: var(--space-2) 0 0; padding-left: 1.25rem; font-size: var(--text-sm); }
.task-event-state { color: var(--text-secondary); margin-right: var(--space-2); }
.task-event-message { overflow-wrap: anywhere; }

.share-list { list-style: none; margin: 0; padding: 0; }
.share-row { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); padding: var(--space-2) 0; border-top: 1px solid var(--border-subtle); min-width: 0; }
.share-who { display: flex; flex-direction: column; min-width: 0; overflow-wrap: anywhere; }
.share-who small { color: var(--text-secondary); }
.share-add { display: flex; gap: var(--space-2); flex-wrap: wrap; align-items: center; }
.share-select { flex: 1; min-width: 12rem; min-height: 44px; }
.share-roles { margin: 0; padding-left: 1.25rem; font-size: var(--text-sm); }

/* --- Reduced motion: everything above becomes static ------------------- */
@media (prefers-reduced-motion: reduce) {
  .activity-indicator[data-animated="true"] .dragonfly-frame::before,
  .activity-indicator[data-animated="true"] .dragonfly-sheen::after { animation: none !important; }
  .activity-indicator[data-animated="true"] .dragonfly-frame::before { opacity: 0.25; }
}

/* =====================================================================================================================================
   Mobile conversation experience (Mission 47)
   Desktop is unchanged: everything below is either hidden by default or confined to the <=860px media query. On phones the Savannah AI
   screen becomes: [hamburger | chat title | usage | menu] header, the conversation filling the screen, and a composer pinned above the
   keyboard / home indicator. Chat history lives in the slide-in drawer (js/chatDrawer.js).
   Safe areas: --safe-* come from env(safe-area-inset-*), which is non-zero on notched iPhones because index.html sets viewport-fit=cover.
   --app-height is the VISIBLE height (js/viewport.js), so the composer stays above the on-screen keyboard.
   ===================================================================================================================================== */
:root {
  --safe-top: env(safe-area-inset-top, 0px);
  --safe-bottom: env(safe-area-inset-bottom, 0px);
  --safe-left: env(safe-area-inset-left, 0px);
  --safe-right: env(safe-area-inset-right, 0px);
}
.mobile-only { display: none; }
/* The original navigation, now wrapped in .nav-pane so the phone drawer can switch between Chats and Menu. These two rules keep the
   desktop sidebar identical to before the wrapper existed: same 4px item gap, footer still pushed to the bottom. */
.nav-pane { display: flex; flex-direction: column; gap: var(--space-1); flex: 1; min-height: 0; }
.chat-header-menu-toggle, .drawer-tabs, .chat-pane, .drawer-close, .sidebar-tagline,
.chat-empty-brand, .chat-empty-tagline, .chat-header-project { display: none; }
.chat-header-titles { min-width: 0; display: contents; }
.chat-empty { display: contents; }

@media (max-width: 860px) {
  .desktop-only { display: none !important; }
  .sidebar-logout.mobile-only { display: flex; align-items: center; width: 100%; min-height: 44px; margin-top: var(--space-3); padding: var(--space-3) var(--space-2); background: none; border: 0; border-top: 1px solid var(--border-subtle); color: var(--text-secondary); font: inherit; font-size: var(--text-sm); text-align: left; cursor: pointer; }
  .chat-header-menu-toggle { display: inline-flex; }

  /* ---- Drawer ------------------------------------------------------------------------------------------------------------------- */
  .sidebar {
    width: min(88vw, 340px); height: var(--app-height, 100dvh); overflow: hidden; gap: 0;
    padding: calc(var(--space-3) + var(--safe-top)) var(--space-3) calc(var(--space-3) + var(--safe-bottom)) calc(var(--space-3) + var(--safe-left));
    overscroll-behavior: contain;
  }
  .sidebar-brand { display: flex; align-items: center; flex-wrap: wrap; position: relative; padding: var(--space-1) 0 var(--space-3); margin-bottom: var(--space-2); }
  .sidebar-tagline { display: block; width: 100%; order: 3; margin-top: 2px; font-size: var(--text-xs); letter-spacing: 0.14em; text-transform: uppercase; color: var(--text-secondary); }
  .drawer-close { display: inline-flex; align-items: center; justify-content: center; margin-left: auto; min-width: 44px; min-height: 44px; background: none; border: 1px solid var(--border-subtle); border-radius: 999px; color: var(--text-primary); cursor: pointer; }
  .drawer-tabs { display: grid; grid-template-columns: 1fr 1fr; gap: 4px; padding: 4px; margin: 0 0 var(--space-3); background: var(--bg-surface-raised); border-radius: 12px; }
  .drawer-tab { min-height: 44px; border: 0; border-radius: 9px; background: transparent; color: var(--text-secondary); font: inherit; font-size: var(--text-sm); cursor: pointer; }
  .drawer-tab.active { background: var(--accent-dim); color: var(--text-primary); font-weight: 600; }
  .sidebar[data-pane="chats"] .nav-pane { display: none; }
  .sidebar[data-pane="menu"] .chat-pane { display: none; }
  .nav-pane { flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain; }

  .chat-pane { display: flex; flex-direction: column; flex: 1; min-height: 0; }
  .chat-pane-new { flex: none; width: 100%; min-height: 48px; border: 1px solid var(--border-strong); border-radius: 12px; background: var(--accent); color: var(--text-inverse); font: inherit; font-weight: 600; cursor: pointer; }
  .chat-pane-new:disabled { opacity: 0.6; }
  .chat-pane-search { flex: none; width: 100%; box-sizing: border-box; margin: var(--space-3) 0 var(--space-2); border-radius: 12px; }
  .chat-pane-chips { flex: none; display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: var(--space-1); }
  .chat-pane-chip { min-height: 44px; max-width: 100%; padding: 0 var(--space-3); border: 1px solid var(--border-subtle); border-radius: 999px; background: transparent; color: var(--text-secondary); font: inherit; font-size: var(--text-sm); cursor: pointer; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .chat-pane-chip.active { background: var(--accent-dim); border-color: var(--accent); color: var(--text-primary); }
  .chat-pane-status { flex: none; margin: var(--space-1) 0; font-size: var(--text-xs); color: var(--text-secondary); }
  .chat-pane-status:empty { display: none; }
  .chat-pane-list { flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding-bottom: var(--space-2); }
  .chat-pane-group { margin: var(--space-4) 0 var(--space-1); padding: 0 var(--space-2); font-size: 0.6875rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--text-tertiary); font-weight: 600; }
  .chat-pane-empty { padding: var(--space-3) var(--space-2); color: var(--text-secondary); font-size: var(--text-sm); }
  .chat-pane-row { display: grid; grid-template-columns: minmax(0, 1fr) 44px; align-items: center; border-left: 3px solid transparent; border-radius: 10px; }
  .chat-pane-row.active { background: var(--accent-dim); border-left-color: var(--accent); }
  .chat-pane-open { display: flex; flex-direction: column; align-items: flex-start; justify-content: center; gap: 2px; min-width: 0; min-height: 48px; padding: var(--space-1) var(--space-2); background: none; border: 0; text-align: left; color: var(--text-primary); font: inherit; font-size: var(--text-sm); cursor: pointer; }
  .chat-pane-row.active .chat-pane-open { font-weight: 600; }
  .chat-pane-title { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .chat-pane-badge { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 0.6875rem; color: var(--text-secondary); letter-spacing: 0.04em; }
  .chat-pane-more { min-width: 44px; min-height: 44px; background: none; border: 0; color: var(--text-secondary); font-size: 1.25rem; cursor: pointer; }
  .chat-pane-menu { grid-column: 1 / -1; display: flex; gap: 8px; padding: 0 var(--space-2) var(--space-2); }
  .chat-pane-action { flex: 1; min-height: 44px; border: 1px solid var(--border-strong); border-radius: 10px; background: var(--bg-surface-raised); color: var(--text-primary); font: inherit; font-size: var(--text-sm); cursor: pointer; }
  .chat-pane-action.danger { color: var(--danger); background: var(--danger-dim); border-color: transparent; }
  .chat-pane-org { flex: none; display: flex; align-items: center; gap: var(--space-2); margin-top: var(--space-2); padding-top: var(--space-3); border-top: 1px solid var(--border-subtle); font-size: var(--text-sm); min-width: 0; }
  .chat-pane-org:empty { display: none; }
  .chat-pane-org-label { flex: none; font-size: 0.6875rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--text-tertiary); }
  .chat-pane-org-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .chat-pane-org .scope-select { flex: 1; min-width: 0; max-width: none; }

  /* ---- Other screens: keep clear of the notch / home indicator ------------------------------------------------------------------- */
  /* The organization / project / environment selects share the bar (each truncates) instead of scrolling sideways inside a clipped box. */
  .topbar-scope { flex: 1; max-width: none; overflow: hidden; gap: var(--space-1); }
  .topbar-scope .scope-select { flex: 1 1 0; min-width: 0; max-width: none; text-overflow: ellipsis; }
  .topbar-scope .scope-sep { display: none; }
  .topbar { padding-top: var(--safe-top); height: calc(var(--topbar-height) + var(--safe-top)); padding-left: calc(var(--space-3) + var(--safe-left)); padding-right: calc(var(--space-3) + var(--safe-right)); }
  main#main { padding-left: calc(var(--space-4) + var(--safe-left)); padding-right: calc(var(--space-4) + var(--safe-right)); padding-bottom: calc(var(--space-4) + var(--safe-bottom)); }
  .modal { max-height: calc(var(--app-height, 100dvh) - 24px); overflow-y: auto; }

  /* ---- Savannah AI conversation screen ------------------------------------------------------------------------------------------- */
  body.view-ai { overflow: hidden; }
  body.view-ai .app-shell { height: var(--app-height, 100dvh); min-height: 0; overflow: hidden; }
  body.view-ai .topbar { display: none; }
  body.view-ai .main-column { height: var(--app-height, 100dvh); min-height: 0; }
  body.view-ai main#main { flex: 1; min-height: 0; max-width: none; padding: 0; display: flex; flex-direction: column; overflow: hidden; }

  body.view-ai .chat-header, .mobile-start .start-header {
    flex: none; display: flex; align-items: center; min-width: 0; justify-content: flex-start; gap: var(--space-2); margin: 0; background: var(--bg-canvas); border-bottom: 1px solid var(--border-subtle);
    padding: calc(var(--space-2) + var(--safe-top)) calc(var(--space-3) + var(--safe-right)) var(--space-2) calc(var(--space-3) + var(--safe-left));
  }
  .chat-header-menu-toggle { align-items: center; justify-content: center; flex: none; min-width: 44px; min-height: 44px; padding: 0; background: transparent; border: 1px solid var(--border-subtle); border-radius: 999px; color: var(--text-primary); font-size: 1.125rem; cursor: pointer; }
  body.view-ai .chat-header-title, .mobile-start .chat-header-title { flex: 1; font-size: var(--text-base); }
  .chat-header-titles { flex: 1; min-width: 0; display: flex; flex-direction: column; justify-content: center; }
  .chat-header-titles .chat-header-title { flex: none; }
  .chat-header-project { display: block; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 0.6875rem; letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-secondary); }
  body.view-ai .chat-header-actions { margin-left: auto; }
  .chat-menu { right: 0; }

  body.view-ai .savannah-tabs { flex: none; margin: 0; padding: 0 calc(var(--space-3) + var(--safe-left)); gap: var(--space-4); }
  body.view-ai .savannah-tab-btn { min-height: 44px; }

  .chat-panel { flex: 1; min-height: 0; display: flex; flex-direction: column; }
  .build-panel { flex: 1; min-height: 0; overflow-y: auto; padding: 0 calc(var(--space-3) + var(--safe-right)) var(--space-4) calc(var(--space-3) + var(--safe-left)); overscroll-behavior: contain; }
  .chat-panel > .section:first-child { flex: 1; min-height: 0; margin: 0; display: flex; flex-direction: column; }
  .chat-panel > .section:first-child > h3 { display: none; }
  .chat-panel > .section:first-child > div { flex: 1; min-height: 0; display: flex; flex-direction: column; }
  .chat-panel .chat-thread {
    flex: 1; min-height: 0; max-height: none; border: 0; border-radius: 0; gap: var(--space-3); overscroll-behavior: contain; -webkit-overflow-scrolling: touch;
    padding: var(--space-3) calc(var(--space-3) + var(--safe-right)) var(--space-3) calc(var(--space-3) + var(--safe-left));
  }
  .chat-panel .chat-message { max-width: 88%; font-size: 0.9375rem; }
  .chat-panel .chat-message.role-system { max-width: 100%; }
  .chat-panel .chat-thread > .hint { margin: auto; }
  .chat-empty { display: flex; flex-direction: column; align-items: center; justify-content: center; margin: auto; text-align: center; gap: var(--space-1); padding: var(--space-6) var(--space-4); }
  .chat-empty-brand, .mobile-start .chat-empty-brand { display: block; font-family: var(--font-serif); font-size: var(--text-xl); letter-spacing: 0.08em; }
  .chat-empty-tagline, .mobile-start .chat-empty-tagline { display: block; font-size: var(--text-sm); letter-spacing: 0.16em; text-transform: uppercase; color: var(--text-secondary); margin-bottom: var(--space-3); }

  .mobile-start { display: flex; flex-direction: column; flex: 1; min-height: 0; }
  .mobile-start-body { flex: 1; min-height: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; padding: var(--space-5) calc(var(--space-4) + var(--safe-right)) calc(var(--space-5) + var(--safe-bottom)) calc(var(--space-4) + var(--safe-left)); }
  .mobile-start-actions { display: flex; flex-direction: column; gap: var(--space-2); width: 100%; max-width: 320px; margin-top: var(--space-3); }

  /* Composer: pinned to the bottom, above the keyboard (via --app-height) and the home indicator. */
  .chat-panel .activity-indicator { flex: none; margin: 0 calc(var(--space-3) + var(--safe-right)) var(--space-2) calc(var(--space-3) + var(--safe-left)); }
  .composer {
    flex: none; margin: 0; background: var(--bg-canvas); border-top: 1px solid var(--border-subtle);
    padding: var(--space-2) calc(var(--space-3) + var(--safe-right)) calc(var(--space-2) + var(--safe-bottom)) calc(var(--space-3) + var(--safe-left));
  }
  .composer > h3 { display: none; }
  .composer > div { display: grid; grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: "tools tools" "attach attach" "input send" "voice voice" "out out"; gap: var(--space-2); align-items: end; }
  .composer .composer-toolbar { grid-area: tools; margin: 0; flex-wrap: nowrap; min-width: 0; }
  .composer .composer-toolbar select { min-width: 0; max-width: 56%; }
  .composer .composer-attachments { grid-area: attach; margin: 0; }
  .composer .composer-input { grid-area: input; min-width: 0; margin: 0; max-height: 28vh; box-sizing: border-box; border-radius: 14px; }
  .composer .composer-send { grid-area: send; align-self: end; min-width: 76px; min-height: 44px; margin: 0; font-size: var(--text-sm); }
  .composer .composer-voice { grid-area: voice; margin: 0; display: none; }
  .composer.voice-open .composer-voice { display: flex; max-height: 34vh; overflow-y: auto; }
  .composer .composer-voice .voice-disclosure, .composer .composer-voice .voice-note { font-size: 0.6875rem; }
  .composer .composer-voice-toggle.mobile-only { display: inline-flex; align-items: center; justify-content: center; min-width: 44px; padding: 0 var(--space-2); }
  .composer .composer-toolbar > * { flex: none; }
  .composer .composer-toolbar button { min-width: 44px; }
  .composer .composer-toolbar select { flex: 1 1 auto; }
  .composer .composer-input { min-height: 44px; }
  .composer > div > .state, .composer .output { grid-area: out; margin: 0; padding: 0; max-height: 18vh; overflow-y: auto; }
  .composer > div > .state:empty, .composer .output:empty { display: none; }
  .keyboard-open .composer { padding-bottom: var(--space-2); }
  .cmdk-hint { display: none; } /* a keyboard shortcut hint: meaningless on a touch phone */
  .chat-panel .chat-message-actions { display: flex; flex-wrap: wrap; gap: var(--space-2); }
  .chat-panel .chat-message-actions .btn { min-height: 40px; }
}
@media (max-width: 860px) and (orientation: landscape) {
  /* Short landscape screens: keep the conversation visible; the composer's secondary rows are one tap away. */
  .composer .composer-toolbar { display: none; }
  .composer .composer-input { max-height: 22vh; }
}

/* ===== Aura Lumina (Mission 48): stored-screenshot gallery. Uses the existing tokens; layout is mobile-first and never scrolls sideways. ===== */
.aura-access, .aura-capture, .aura-gallery-host, .aura-permissions { margin-bottom: var(--space-4); }
.aura-banner { border: 1px solid var(--border-subtle); border-radius: var(--radius-md, 6px); padding: var(--space-3) var(--space-4); background: var(--bg-surface); }
.aura-banner p { margin: var(--space-1) 0 var(--space-2); }
.aura-banner-locked { border-color: var(--text-secondary); }
.aura-muted { color: var(--text-secondary); font-size: var(--text-sm); }
.aura-capture-form { display: flex; flex-wrap: wrap; gap: var(--space-3); align-items: end; }
.aura-capture-form label { display: flex; flex-direction: column; gap: var(--space-1); min-width: 0; flex: 1 1 10rem; font-size: var(--text-sm); }
.aura-capture-form input, .aura-capture-form select { min-height: 44px; }
.aura-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 14rem), 1fr)); gap: var(--space-3); }
.aura-card { display: flex; flex-direction: column; gap: var(--space-1); text-align: left; min-width: 0; padding: var(--space-2); background: var(--bg-surface); border: 1px solid var(--border-subtle); border-radius: var(--radius-sm); color: inherit; font: inherit; cursor: pointer; min-height: 44px; }
.aura-card:focus-visible { outline: 2px solid var(--text-primary); outline-offset: 2px; }
.aura-thumb { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; object-position: top; background: #000; border-radius: var(--radius-sm); display: block; }
.aura-thumb-missing { display: flex; align-items: center; justify-content: center; color: var(--text-secondary); font-size: var(--text-sm); }
.aura-card-meta { text-transform: capitalize; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.aura-viewer { max-width: min(92vw, 60rem); max-height: 88vh; overflow: auto; }
.aura-viewer-img { max-width: 100%; height: auto; display: block; border: 1px solid var(--border-subtle); }
.aura-meta { display: grid; grid-template-columns: max-content 1fr; gap: var(--space-1) var(--space-3); margin: var(--space-3) 0; font-size: var(--text-sm); }
.aura-meta dd { margin: 0; overflow-wrap: anywhere; }
.aura-meta dt { color: var(--text-secondary); }
.aura-viewer-actions { display: flex; gap: var(--space-2); flex-wrap: wrap; }
.aura-viewer-actions .btn, .aura-perm-row .btn { min-height: 44px; }
.aura-perm-list { display: flex; flex-direction: column; gap: var(--space-2); }
.aura-perm-row { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2) var(--space-3); padding: var(--space-2) 0; border-bottom: 1px solid var(--border-subtle); }
.aura-perm-who { flex: 1 1 12rem; min-width: 0; overflow-wrap: anywhere; }
@media (max-width: 860px) {
  .aura-gallery-host .btn, .aura-capture-form .btn, .aura-banner .btn { min-height: 44px; }
  .modal:has(.aura-viewer) { width: calc(100vw - var(--space-3) * 2); max-width: none; padding: var(--space-3); }
}
.modal:has(.aura-viewer) { max-width: min(92vw, 60rem); }

/* Screen-reader-only text (visually hidden, still announced). */
.aura-sr-only { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

/* Recovery panel (Milestone 3). Meaning is carried by the +/- prefix and by words; colour is reinforcement only. */
.recovery-panel .recovery-items { list-style: none; margin: 8px 0; padding: 0; display: grid; gap: 8px; }
.recovery-panel .recovery-item { border: 1px solid var(--border, #444); border-radius: 8px; padding: 10px; }
.recovery-panel .diff-view { overflow-x: auto; max-height: 360px; margin: 6px 0; padding: 8px; font: 12px/1.5 ui-monospace, SFMono-Regular, Menlo, monospace; white-space: pre; border: 1px solid var(--border, #444); border-radius: 6px; }
.recovery-panel .diff-line { display: block; }
.recovery-panel .diff-add { background: rgba(60, 160, 90, 0.18); }
.recovery-panel .diff-del { background: rgba(200, 70, 70, 0.18); }
.recovery-panel .recovery-checks, .recovery-panel .recovery-history, .recovery-panel .recovery-timeline { margin: 6px 0; padding-left: 20px; }
.recovery-panel .recovery-shot { margin: 0; flex: 1 1 220px; max-width: 100%; }
.recovery-panel .recovery-shot img { display: block; max-width: 100%; height: auto; }
.recovery-panel button:focus-visible, .recovery-panel select:focus-visible, .recovery-panel .diff-view:focus-visible { outline: 2px solid currentColor; outline-offset: 2px; }
@media (max-width: 520px) { .recovery-panel .row { flex-wrap: wrap; } }
.recovery-panel .badge.status-fixed { background: var(--success-dim); color: var(--success); }
.recovery-panel .badge.status-repair-failed { background: var(--danger-dim); color: var(--danger); }
.recovery-panel .badge.status-awaiting-approval, .recovery-panel .badge.status-detected, .recovery-panel .badge.status-diagnosis-ready { background: var(--warning-dim); color: var(--warning); }
.recovery-panel .badge.status-rolled-back, .recovery-panel .badge.status-ignored, .recovery-panel .badge.status-cancelled { background: var(--bg-surface-hover); color: var(--text-tertiary); }

/* Screenshot annotator (Milestone 6) */
.annotator { display: flex; flex-direction: column; gap: var(--space-3, 0.75rem); }
.annotator-stage { position: relative; display: inline-block; max-width: 100%; border: 1px solid var(--border-subtle); line-height: 0; touch-action: manipulation; }
.annotator-img { max-width: 100%; max-height: 60vh; height: auto; display: block; user-select: none; }
.annotator-layer { position: absolute; inset: 0; cursor: crosshair; }
.annotator-pin { position: absolute; transform: translate(-50%, -50%); min-width: 1.6rem; height: 1.6rem; border-radius: 999px; background: #E8E8EC; color: #0d0d0f; font: 700 0.8rem/1.6rem var(--font-body, sans-serif); text-align: center; box-shadow: 0 0 0 2px #0d0d0f, 0 0 0 4px #E8E8EC; pointer-events: none; }
.annotator-pins { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-2, 0.5rem); }
.annotator-pin-head { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; margin-bottom: 0.25rem; }
.annotator-num { width: 4.5rem; }
.annotator-comment, .annotator-title { width: 100%; box-sizing: border-box; }
.annotator-actions { display: flex; gap: 0.5rem; flex-wrap: wrap; }
.annotator-prompt { white-space: pre-wrap; overflow-wrap: anywhere; max-height: 14rem; overflow: auto; }
.modal-overlay:has(.annotator) { padding-top: 3vh; }
.modal:has(.annotator) { max-width: min(94vw, 56rem); max-height: 92vh; overflow-y: auto; }

/* Notifications and budgets (Milestone 7) */
.notif-wrap { position: relative; display: inline-block; }
.notif-bell { position: relative; min-width: 2.5rem; min-height: 2.5rem; background: transparent; border: 1px solid var(--border-subtle); border-radius: var(--radius-md, 8px); color: inherit; cursor: pointer; }
.notif-badge { position: absolute; top: -0.35rem; right: -0.35rem; min-width: 1.2rem; height: 1.2rem; padding: 0 0.25rem; border-radius: 999px; background: #E8E8EC; color: #0d0d0f; font: 700 0.7rem/1.2rem var(--font-body, sans-serif); text-align: center; }
.notif-panel { position: absolute; right: 0; top: calc(100% + 0.4rem); width: min(24rem, 92vw); max-height: 70vh; overflow-y: auto; z-index: 90; background: var(--bg-surface-raised); border: 1px solid var(--border-strong); border-radius: var(--radius-lg, 12px); box-shadow: var(--shadow-md); padding: 0.75rem; }
.notif-head, .notif-foot { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; margin-bottom: 0.5rem; }
.notif-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.4rem; }
.notif-item { display: flex; gap: 0.5rem; align-items: flex-start; border: 1px solid var(--border-subtle); border-radius: 8px; padding: 0.5rem; }
.notif-item.unread { border-color: #B8B8C0; background: rgba(232,232,236,0.06); }
.notif-open { flex: 1; display: flex; flex-direction: column; align-items: flex-start; gap: 0.15rem; text-align: left; background: transparent; border: 0; color: inherit; cursor: pointer; padding: 0; min-height: 2.5rem; }
.notif-sev { font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.04em; color: var(--text-secondary, #b8b8c0); }
.notif-body { font-size: 0.85rem; color: var(--text-secondary, #b8b8c0); overflow-wrap: anywhere; }
.notif-time { font-size: 0.75rem; color: var(--text-secondary, #b8b8c0); }
.budget-meter { height: 0.7rem; border-radius: 999px; background: var(--bg-surface-hover); overflow: hidden; }
.budget-fill { height: 100%; background: #B8B8C0; } .budget-fill.high { background: #D9A441; } .budget-fill.over { background: #D4786A; }
.budget-form { display: flex; flex-direction: column; gap: 0.5rem; max-width: 32rem; margin-top: 0.75rem; }
.inline-check { display: inline-flex; align-items: center; gap: 0.35rem; }

.sidebar-notif { padding: 0.25rem var(--space-3, 0.75rem); }
@media (max-width: 860px) {
  .sidebar-notif.mobile-only { display: block; }
  .notif-panel { position: fixed; left: var(--space-3, 0.75rem); right: var(--space-3, 0.75rem); top: calc(var(--topbar-height, 3rem) + 0.5rem); width: auto; }
}

/* Idea to production workflow (Milestone 7) */
.wf-stages{list-style:none;margin:16px 0;padding:0;display:grid;gap:12px}
.wf-stage{border:1px solid var(--border,#444);border-radius:10px;padding:12px 14px;min-width:0}
.wf-stage h3{margin:0;font-size:1rem}
.wf-stage.wf-active,.wf-stage.wf-running,.wf-stage.wf-awaiting_approval{border-color:var(--accent,#c0c0c0)}
.wf-stage.wf-failed{border-color:#d9534f}
.wf-badge{display:inline-block;padding:2px 8px;border-radius:999px;border:1px solid currentColor;font-size:.75rem;white-space:nowrap}
.wf-badge.wf-done{color:#6fcf97}.wf-badge.wf-failed{color:#ff8a80}.wf-badge.wf-pending,.wf-badge.wf-skipped{color:#9aa0a6}
.wf-shots{display:flex;flex-wrap:wrap;gap:12px}.wf-shots figure{margin:0;max-width:100%}
.wf-shot{max-width:100%;height:auto;border:1px solid var(--border,#444);border-radius:6px}
.wf-list{list-style:none;padding:0;display:grid;gap:8px}
@media (max-width:860px){.wf-shots figure{width:100%}.wf-stage textarea,.wf-stage select{width:100%;box-sizing:border-box}}
