  /* Base — CSS variables, self-hosted font, global reset. Loaded first;
     holo-theme.css is loaded last so its rules win the cascade over these. */
  :root {
    --bg: #0B0A09;
    --panel: #1C1A17;
    --panel-2: #232019;
    --border: #4A463F;
    --text: #E4DDCE;
    --text-dim: #9B958A;
    --accent: #3E5A4C;
    --accent-2: #557C68;
    --green: #3ecf8e;
    --red: #ff6b6b;
    --amber: #f5b84f;
    --verdigris: #3E5A4C;
    --verdigris-hover: #557C68;
    --mono: "SF Mono", "Fira Code", Menlo, Consolas, monospace;
    /* Patina shimmer — verdigris/bone/silver stops for neutral controls,
       a crimson-only variant for warning/danger surfaces so those keep
       reading as "alert" rather than decorative. */
    --holo: conic-gradient(from 180deg,
      #3E5A4C, #5b7d6a, #9B958A, #E4DDCE, #c8ccc0,
      #9B958A, #6b8f7a, #4A463F, #3E5A4C);
    --holo-warn: conic-gradient(from 180deg, #dc143c, #ff8a4c, #ff3d68, #dc143c);
    --font-display: "Orbitron", "Segoe UI", sans-serif;
    --font-body: "Lexend", -apple-system, BlinkMacSystemFont, "Segoe UI", Inter, sans-serif;
  }
  /* Light-mode inverse (Bandua brand palette) — variables only; many
     component files still use hardcoded dark-theme hex literals, so this
     covers the base surfaces/text/accent but isn't a fully audited light
     theme yet.
     Profile theme preference ("auto"/"dark"/"light", see settings-profile.js)
     sets [data-theme] on <html> and takes priority; "auto" leaves the
     attribute unset and falls back to OS preference via the media query. */
  @media (prefers-color-scheme: light) {
    html:not([data-theme]) {
      --bg: #EFEAE0;
      --panel: #E4DDCE;
      --panel-2: #dcd4c2;
      --border: #4A463F;
      --text: #0B0A09;
      --text-dim: #4A463F;
      --accent: #2C4438;
      --accent-2: #3E5A4C;
      --verdigris: #2C4438;
      --verdigris-hover: #3E5A4C;
    }
  }
  html[data-theme="light"] {
    --bg: #EFEAE0;
    --panel: #E4DDCE;
    --panel-2: #dcd4c2;
    --border: #4A463F;
    --text: #0B0A09;
    --text-dim: #4A463F;
    --accent: #2C4438;
    --accent-2: #3E5A4C;
    --verdigris: #2C4438;
    --verdigris-hover: #3E5A4C;
  }
  /* Self-hosted (not a Google Fonts <link> — the CSP here is style-src
     'self', which blocks fonts.googleapis.com's stylesheet outright).
     Used only for short display text (nav labels, modal headers,
     buttons) — body/workspace/log text stays on the system sans stack for
     density and legibility. */
  @font-face {
    font-family: "Orbitron";
    src: url("/assets/fonts/orbitron.woff2") format("woff2");
    font-weight: 600 800;
    font-style: normal;
    font-display: swap;
  }
  /* Body font for workspace message content and the composer/input areas only —
     a variable font (weight range in one file) chosen for reading
     proficiency at small sizes. Nav/titles stay on --font-display /
     the plain system stack above; this is applied narrowly via
     --font-body, not on `body`, so it doesn't bleed into the rest of
     the UI. */
  @font-face {
    font-family: "Lexend";
    src: url("/assets/fonts/lexend.woff2") format("woff2-variations"), url("/assets/fonts/lexend.woff2") format("woff2");
    font-weight: 100 900;
    font-style: normal;
    font-display: swap;
  }
  * { box-sizing: border-box; }
  body {
    margin: 0;
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Inter, sans-serif;
    background: var(--bg);
    color: var(--text);
    height: 100vh;
    height: 100dvh; /* mobile browsers resize the vh unit as chrome shows/hides; dvh tracks the actual visible area so the composer doesn't get clipped */
    overflow: hidden;
  }
  #app { display: flex; height: 100vh; height: 100dvh; }

  /* Badges — one shared shape for every small status/kind/label pill in
     the app (task/goal status & priority, job status, capability-request
     status/kind, work items kind, tunnel status, repo category, agent-name
     labels). Individual files below only set background/color/border per
     state — keeps every badge in the app the same size and proportions
     instead of each screen inventing its own padding and radius. */
  .badge,
  .task-status-badge,
  .goal-priority-badge,
  .goal-status-badge,
  .cap-request-status-badge,
  .cap-request-kind-badge,
  .idea-badge,
  .work-item-kind-badge,
  .work-item-priority-badge,
  .work-item-impact-badge,
  .tunnel-badge,
  .repo-category-badge,
  .workspace-agent-badge,
  .template-row .agent-badge {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    flex-shrink: 0;
    font-size: 10px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.02em;
    line-height: 1.3;
    padding: 3px 8px;
    border-radius: 20px;
  }

  /* Freeform-text badges (project names, workspace titles, tags) — same pill
     shape as above but natural case, since the content isn't a fixed
     enum label. */
  .memory-project-badge,
  .repo-tag-badge,
  .work-item-link-badge,
  .work-item-workspace-badge,
  .eta-badge {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    flex-shrink: 0;
    font-size: 10.5px;
    font-weight: 600;
    line-height: 1.3;
    padding: 3px 8px;
    border-radius: 20px;
  }

  /* Shared entrance animations — a list row/card fading+sliding up on
     first paint (used by .goal-row, .work-item-row, .task-row, .project-card,
     .gpu-agent-card, ...) and a plain fade for a whole panel swap (see
     #view-body.view-body-enter, toggled from main-panel.js whenever a
     Workspaces/Work Items/Goals/... tab replaces #view-body's content). Defined
     once here since every list/grid across the app wants the same feel;
     individual files just apply `animation: list-row-in ... both;` to
     their own row/card selector and add their own nth-child stagger. */
  @keyframes list-row-in {
    from { opacity: 0; transform: translateY(6px); }
    to { opacity: 1; transform: translateY(0); }
  }
  @keyframes view-fade-in {
    from { opacity: 0; }
    to { opacity: 1; }
  }
  #view-body.view-body-enter { animation: view-fade-in 0.18s ease; }
  @media (prefers-reduced-motion: reduce) {
    #view-body.view-body-enter { animation: none; }
  }

