/* ==========================================================================
   NOUMA · the world — a full-bleed HUD over a living field

   The page IS the artwork. Everything else floats above it as a fixed instrument
   panel; the document never scrolls, because a swarm that scrolls is a report
   about a swarm rather than a view of one.

   Three layers, bottom to top:

     0  #world-field   the canvas: the swarm, the flow field, the market aura
     2  .hud-vignette  a soft radial darkening, so the eye lands on the middle
     3  .hud-grain     a static paper tooth, normally composited and cached
     10 .hud-panel     the four corner instruments

   Performance note that drives several choices below: the field repaints every
   frame, so nothing above it may use `backdrop-filter` or a heavy blend mode —
   either forces the whole scene to re-composite per frame, and the cost lands on
   the canvas rather than on the panel. Panels therefore use a plain translucent
   fill, and the grain is a static overlay the compositor can cache.

   Typography: no webfont is added. The three already shipped do the work through
   weight, size and tracking — Space Grotesk at 300 weight and display sizes reads
   as a scientific plate, and JetBrains Mono carries every figure. Adding a fourth
   face would put a network request on the critical path of the landing screen to
   buy a shape nobody can name.
   ========================================================================== */

/*
 * The HUD palette is an alias layer over the theme tokens, not a palette of its own.
 *
 * It used to be six hardcoded values in `:root`, which meant the world screen ignored
 * `data-theme` entirely: switch to Lab Dark and every panel stayed paper-white, because nothing here
 * read the attribute the shell writes on `<html>`. That is the bug this block fixes, and it is fixed
 * by pointing each name at the token that already exists rather than by writing a second set of
 * colours per theme — a second set is a second thing to keep in step.
 *
 * The names stay, because ~330 rules in this file use them and a rename would be a diff nobody can
 * review. The values are the theme's.
 *
 * Type follows the same rule, one layer down: every size at or below 14px is written
 * `max(Npx, var(--nouma-fs-floor))`, with `--nouma-fs-floor` declared in `styles.css` (loaded before
 * this file, see `index.html`). This file is where 10px and 10.5px actually live — it is the dense
 * instrument panel the floor was added for — and it was the one stylesheet the first pass missed, so
 * a reader who raised the floor saw every page grow except the landing screen.
 */
:root {
  /* The ground and the instrument surfaces. `--hud-panel` is the theme's *surface* rather than its
     background: an instrument sits forward of the field, and using the same colour for both is what
     made the panels look like holes punched in the page. */
  --hud-paper: var(--nouma-background);
  --hud-panel: var(--nouma-surface);
  --hud-ink: var(--nouma-text);
  --hud-ink-rgb: var(--nouma-text-rgb);
  --hud-accent: var(--nouma-accent);
  --hud-accent-rgb: var(--nouma-accent-rgb);
  --hud-hair: var(--nouma-border);
  --hud-muted: var(--nouma-text-muted);

  /* The four behaviour colours identify a state, and a state that changes colour with the weather is
     a state nobody can learn. They are therefore the theme's fixed behaviour tokens — which every
     theme emits identically, so "fixed" and "themed" agree by construction rather than by promise. */
  --hud-agitate: var(--nouma-behaviour-agitate);
  --hud-explore: var(--nouma-behaviour-explore);
  --hud-aggregate: var(--nouma-behaviour-aggregate);
  --hud-rest: var(--nouma-behaviour-rest);

  /* Status, in three. `alarm` is the theme's own, because "this is wrong" is a judgement the theme
     already has a colour for — the paper theme's deeper red is the right red on paper. `vital` and
     `warn` are *not* themed: they mark a life stage and a mid-scale reading, and a stage that changes
     colour with the weather is a stage nobody can learn. Same rule as the behaviours above. */
  --hud-alarm: var(--nouma-alarm);
  --hud-vital: #10b981;
  --hud-warn: #f59e0b;

  --hud-display: var(--nouma-font-display);
  --hud-mono: var(--nouma-font-mono);

  --hud-pad: clamp(14px, 2.4vw, 28px);
}

/*
 * The console is its own surface, and deliberately so.
 *
 * The terminal is a machine surface — the one place in this product that is *not* a view of the
 * swarm but a tool for talking to its gateway. It used to carry ~40 hardcoded hexes, which is a
 * palette with no name. They are named here, and they do **not** alias the theme: a dark console on
 * the paper theme is the correct answer, because a reader who switches themes to read the swarm
 * should not find their terminal turned into a light box.
 *
 * The consequence is deliberate and bounded: `data-theme` does not reach inside `.agent-terminal-*`.
 * Everything else on the world screen does.
 */
:root {
  --console-ground: #07080c;
  --console-raised: #0d0f17;
  /* The deepest of the four grounds, for a code block inside a panel inside the console. */
  --console-sunken: #030407;
  --console-ink: #d1d5db;
  --console-ink-rgb: 209, 213, 219;
  --console-hair: rgba(255, 255, 255, 0.08);
  --console-accent: #35e0ff;
  --console-accent-rgb: 53, 224, 255;
  --console-dim: rgba(209, 213, 219, 0.55);
  --console-signal: #f59e0b;
  --console-live: #4ade80;
}

/* --------------------------------------------------------------------------
   the page
   -------------------------------------------------------------------------- */

.world-page {
  position: fixed;
  inset: 0;
  overflow: hidden;
  background: var(--hud-paper);
  color: var(--hud-ink);
  transition: background 1.6s linear;
}

/* The shell normally wraps every screen in a padded, scrollable column. The
   world is the one screen that must escape it, so the wrapper is flattened for
   the duration — a `position: fixed` child inside a transformed or constrained
   ancestor would be clipped to it, which is how a "full-bleed" canvas ends up
   400px tall. */
.shell-content:has(.world-page) {
  display: block;
  overflow: hidden;
  padding: 0;
}

.world-field {
  position: fixed;
  inset: 0;
  display: block;
  width: 100vw;
  height: 100vh;
  z-index: 0;
  cursor: crosshair;
}

/* A static paper tooth. `background-image` rather than a second canvas so the
   compositor caches it once instead of repainting noise every frame. */
.hud-grain {
  position: fixed;
  inset: 0;
  z-index: 3;
  pointer-events: none;
  opacity: 0.05;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

.hud-vignette {
  position: fixed;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  background: radial-gradient(
    120% 90% at 50% 45%,
    transparent 40%,
    rgba(var(--hud-ink-rgb), 0.07) 100%
  );
}

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

.hud-topbar {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 10;
  display: flex;
  /* Wrapping is the honest answer on a 1024px laptop: the meta cluster drops to a
     second line instead of clipping its right-hand chips. Top-aligned, because
     centring two lines of unequal height makes the wordmark look dropped. */
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  row-gap: 8px;
  padding: var(--hud-pad);
  pointer-events: none;
}

.hud-topbar > * {
  pointer-events: auto;
}

.hud-wordmark {
  display: flex;
  align-items: baseline;
  gap: 9px;
}

.hud-wordmark .mark {
  fill: var(--hud-accent);
  opacity: 0.9;
  transform: translateY(3px);
  transition: fill 1.6s linear;
}

.hud-wordmark .name {
  font-family: var(--hud-display);
  font-weight: 400;
  font-size: clamp(20px, 2.6vw, 28px);
  letter-spacing: 0.02em;
  color: var(--hud-ink);
}

.hud-topmeta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: 8px;
  row-gap: 6px;
  max-width: 100%;
  font-family: var(--hud-mono);
  font-size: max(11px, var(--nouma-fs-floor));
  letter-spacing: 0.12em;
  text-transform: lowercase;
  color: var(--hud-muted);
}

.hud-topmeta .sep {
  opacity: 0.4;
}

/* The one motion in the chrome: a status dot that breathes when the link is up.
   Motion on a *state* is allowed; motion on a *value* would say the value is
   unstable, which is a different and false claim. */
.hud-link-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: rgba(var(--hud-ink-rgb), 0.3);
  transition: background var(--nouma-dur-data) var(--nouma-ease);
}

.hud-link-dot[data-tone="ok"] {
  background: var(--hud-accent);
}

@media (prefers-reduced-motion: no-preference) {
  .hud-link-dot[data-tone="ok"] {
    animation: hud-breathe 3.4s ease-in-out infinite;
  }
}

@keyframes hud-breathe {
  0%,
  100% {
    box-shadow: 0 0 0 0 rgba(var(--hud-accent-rgb), 0.45);
  }
  50% {
    box-shadow: 0 0 0 6px rgba(var(--hud-accent-rgb), 0);
  }
}

.hud-topmeta .hud-chip {
  font-family: var(--hud-mono);
  font-size: max(10px, var(--nouma-fs-floor));
  letter-spacing: 0.1em;
  color: var(--hud-muted);
  background: transparent;
  border: 1px solid var(--hud-hair);
  border-radius: 2px;
  padding: 4px 7px;
  cursor: pointer;
  transition: color 0.25s, border-color 0.25s;
  /* The row scrolls rather than wraps on a narrow screen, and a flex item that is allowed to shrink
     does not scroll — it squeezes. "trust network" would break over two lines and make the bar taller
     than the screen it is trying to save. */
  flex: 0 0 auto;
  white-space: nowrap;
}

.hud-topmeta .hud-chip:hover {
  color: var(--hud-ink);
  border-color: rgba(var(--hud-accent-rgb), 0.55);
}

/* Shortcuts that only exist because a panel folded away on a narrow screen —
   hidden by default, revealed in the 900px block below. */
.hud-chip-narrow {
  display: none;
}

/* --------------------------------------------------------------------------
   the corner instruments
   -------------------------------------------------------------------------- */

.hud-panel {
  position: fixed;
  z-index: 10;
  background: var(--hud-panel);
  border: 1px solid var(--hud-hair);
  border-radius: 4px;
  padding: 14px 16px;
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.4) inset,
    0 8px 30px rgba(var(--hud-ink-rgb), 0.05);
  transition:
    background 1.6s linear,
    border-color 1.6s linear,
    opacity 0.45s ease;
}

.hud-panel-title {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 10px;
  font-family: var(--hud-mono);
  font-size: max(10px, var(--nouma-fs-floor));
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--hud-muted);
}

/* --- economy, top-left --- */

.hud-panel-econ {
  left: var(--hud-pad);
  /* Tracks the bar's real height: it wraps on narrow screens, so a hardcoded
     offset would overlap the wordmark's second line. The 8px is the gap the
     instruments keep from the bar's last row. */
  top: calc(var(--hud-bar-h, 46px) + 8px);
  width: clamp(290px, 27vw, 360px);
}

.hud-econ-mode {
  font-family: var(--hud-mono);
  font-size: max(10px, var(--nouma-fs-floor));
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--hud-accent);
  border: 1px solid rgba(var(--hud-accent-rgb), 0.4);
  border-radius: 2px;
  padding: 1px 5px;
}

.hud-hero {
  display: flex;
  align-items: baseline;
  gap: 8px;
  flex-wrap: wrap;
}

.hud-hero-value {
  font-family: var(--hud-display);
  font-weight: 300;
  font-size: clamp(30px, 4.6vw, 46px);
  line-height: 1;
  letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums;
  color: var(--hud-ink);
}

.hud-hero-unit {
  font-family: var(--hud-mono);
  font-size: max(10px, var(--nouma-fs-floor));
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--hud-muted);
}

/* --- the micro grids: two columns of name-over-value, ruling line above --- */

.hud-micro {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 7px 14px;
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px solid var(--hud-hair);
}

.hud-micro > div {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
}

.hud-micro dt {
  font-family: var(--hud-mono);
  font-size: max(10px, var(--nouma-fs-floor));
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--hud-muted);
}

.hud-micro dd {
  margin: 0;
  font-family: var(--hud-mono);
  font-size: max(12px, var(--nouma-fs-floor));
  font-variant-numeric: tabular-nums;
  color: var(--hud-ink);
  opacity: 0.88;
}

/* --- the decision feed, inside the economy panel --- */

.hud-feed {
  margin-top: 12px;
  max-height: 118px;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  gap: 3px;
  font-family: var(--hud-mono);
  font-size: max(10px, var(--nouma-fs-floor));
  color: var(--hud-muted);
}

.hud-feed-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.hud-feed-row .who {
  color: var(--hud-ink);
  opacity: 0.75;
}

.hud-feed-row .kind {
  margin-left: auto;
  letter-spacing: 0.08em;
  text-transform: lowercase;
  color: var(--hud-accent);
}

/* A quiet tick, said once rather than forty-eight times. */
.hud-feed-quiet {
  font-family: var(--hud-mono);
  font-size: max(10px, var(--nouma-fs-floor));
  line-height: 1.6;
  color: var(--hud-muted);
  font-style: italic;
}

/* --- temperature, bottom-left --- */

.hud-panel-temp {
  left: var(--hud-pad);
  bottom: var(--hud-pad);
  width: clamp(250px, 27vw, 340px);
}

.hud-regime-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
}

.hud-regime {
  font-family: var(--hud-display);
  font-weight: 600;
  font-size: clamp(19px, 2.4vw, 25px);
  letter-spacing: 0.04em;
  text-transform: lowercase;
  color: var(--hud-accent);
  transition: color 1.2s linear;
}

.hud-temp-value {
  font-family: var(--hud-mono);
  font-weight: 300;
  font-size: clamp(15px, 1.9vw, 19px);
  font-variant-numeric: tabular-nums;
  color: var(--hud-ink);
  opacity: 0.82;
}

/* The meter is three pixels tall and carries one value. A gradient would suggest
   a range the swarm is not currently in. */
.hud-meter {
  position: relative;
  height: 3px;
  margin: 12px 0 6px;
  background: rgba(var(--hud-ink-rgb), 0.1);
  border-radius: 999px;
}

.hud-meter-fill {
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 50%;
  border-radius: 999px;
  background: var(--hud-accent);
  transition:
    width 1.1s cubic-bezier(0.22, 1, 0.36, 1),
    background 1.2s linear;
}

.hud-meter-tick {
  position: absolute;
  top: -3px;
  width: 1px;
  height: 9px;
  background: rgba(var(--hud-ink-rgb), 0.28);
}

.hud-meter-scale {
  display: flex;
  justify-content: space-between;
  font-family: var(--hud-mono);
  font-size: max(10px, var(--nouma-fs-floor));
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--hud-muted);
  opacity: 0.7;
}

.hud-spark {
  display: block;
  width: 100%;
  height: 40px;
  margin-top: 12px;
}

/* --- population, top-right --- */

.hud-panel-pop {
  right: var(--hud-pad);
  /* Same origin as the left instrument. It used to sit at `pad + 46px`, which put it under the
     chip strip as soon as that strip wrapped — 18px of overlap at 1440, 74px at 1024. Starting both
     top instruments from the bar's real height fixes the collision and aligns their top edges. */
  top: calc(var(--hud-bar-h, 46px) + 8px);
  width: clamp(226px, 24vw, 296px);
}

.hud-pop-size {
  font-family: var(--hud-mono);
  font-size: max(12px, var(--nouma-fs-floor));
  color: var(--hud-accent);
  opacity: 0.9;
}

.hud-dist {
  display: flex;
  gap: 2px;
  height: 8px;
  margin-bottom: 10px;
}

.hud-dist-seg {
  height: 100%;
  min-width: 0;
  border-radius: 2px;
  transition: flex-grow 1s cubic-bezier(0.22, 1, 0.36, 1), opacity 0.4s;
}

.hud-dist-seg[data-behaviour="agitate"] {
  background: var(--hud-agitate);
}
.hud-dist-seg[data-behaviour="explore"] {
  background: var(--hud-explore);
}
.hud-dist-seg[data-behaviour="aggregate"] {
  background: var(--hud-aggregate);
}
.hud-dist-seg[data-behaviour="rest"] {
  background: var(--hud-rest);
}
.hud-dist-seg.is-empty {
  opacity: 0.14;
}

.hud-dist-legend {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 5px 12px;
}

.hud-dist-legend li {
  display: flex;
  align-items: center;
  gap: 6px;
  font-family: var(--hud-mono);
  font-size: max(10.5px, var(--nouma-fs-floor));
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--hud-muted);
}

.hud-dist-legend .sw {
  flex: none;
  width: 6px;
  height: 6px;
  border-radius: 50%;
}

.hud-dist-legend b {
  margin-left: auto;
  font-weight: 500;
  color: var(--hud-ink);
  font-variant-numeric: tabular-nums;
}

/* --- about, bottom-right --- */

.hud-panel-about {
  right: var(--hud-pad);
  bottom: var(--hud-pad);
  width: clamp(250px, 27vw, 344px);
}

.hud-about-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 8px;
}

.hud-about-head .hud-panel-title {
  margin-bottom: 0;
}

.hud-about-body {
  font-family: var(--hud-mono);
  font-size: max(10.5px, var(--nouma-fs-floor));
  line-height: 1.72;
  color: var(--hud-ink);
  opacity: 0.82;
}

.hud-about-points {
  list-style: none;
  margin: 10px 0 0;
  padding: 10px 0 0;
  border-top: 1px solid var(--hud-hair);
  display: flex;
  flex-direction: column;
  gap: 5px;
}

.hud-about-points li {
  position: relative;
  padding-left: 12px;
  font-family: var(--hud-mono);
  font-size: max(10.5px, var(--nouma-fs-floor));
  line-height: 1.55;
  color: var(--hud-muted);
}

.hud-about-points li::before {
  content: "";
  position: absolute;
  left: 2px;
  top: 6px;
  width: 3px;
  height: 3px;
  border-radius: 50%;
  background: var(--hud-accent);
  opacity: 0.8;
}

/* --------------------------------------------------------------------------
   no action buttons here

   `.hud-actions` and `.hud-btn` were a button row for a panel that no longer has one. Nothing in
   `app/` or `src/` produces either name, so the styles have been inert since the control they dressed
   was removed — a phantom affordance in the stylesheet reads, to the next person, like a component
   waiting to be used. The HUD's real controls are `.hud-chip` and `.hud-mode-btn`, both live.
   -------------------------------------------------------------------------- */

/* --------------------------------------------------------------------------
   the drawer's scrim, suppressed on this screen

   The shell's drawer ships a scrim, which is right for a page of text: it dims the page and a click
   anywhere dismisses the panel. On this screen both halves are wrong. The swarm is still the point —
   the drawer exists so the picture underneath keeps moving — and the scrim is painted above the
   instrument layer, so it swallowed every click aimed at the chip row: switching from one drawer to
   the next took two clicks (one to dismiss, one to open) and read as "the chips do nothing".

   Without it the drawer is what `src/ui/drawer.ts` says it is: not a modal. The chips swap the panel
   in one click, a click on the field picks another fly, and the panel closes on × or Escape. The
   panel keeps its own shadow and border, so it still reads as a surface in front of the field.
   -------------------------------------------------------------------------- */

body:has(.world-page) .drawer-scrim {
  display: none;
}

/* The panel starts below the top bar rather than at the viewport edge.
   The bar is `position: fixed` across the full width and its chip cluster is right-aligned, so a
   full-height panel on the right edge lands directly on top of the navigation: at 1440px it covered 7
   of the 8 chips, at 1024px all 8, and the visitor's next click went to the panel. Starting the panel
   under the bar leaves the whole row visible and clickable while a drawer is open, which is what makes
   "click another chip" work in one click. `--hud-bar-h` is measured by `world.ts` and published on
   `<html>` for exactly this; the fallback is the bar's height at the default type scale. */
body:has(.world-page) .drawer {
  top: calc(var(--hud-bar-h, 46px) + 8px);
  /* The drawer is written `top: 0; bottom: 0; height: 100vh`; with a top offset the fixed height would
     push its bottom past the viewport, so let `bottom` decide instead. */
  height: auto;
}

/* --------------------------------------------------------------------------
   no drawer styles here

   There used to be a second drawer: `hud-drawer`, with its own head, body and close button, plus a
   rule that faded `.hud-page` behind it. None of it ever rendered. The world screen opens the shell's
   drawer (`src/ui/drawer.ts`, styled as `.drawer` / `.drawer-open` in `styles.css`), and its root is
   `.world-page`, so `.hud-drawer` and `[data-drawer="true"]` had no writer and no reader between them.

   Deleted rather than wired up, for one specific reason: that rule also set `pointer-events: none` on
   every `.hud-panel`, so had it ever matched, opening a drawer would have made the navigation chips
   unclickable — which is precisely the symptom "the chips do nothing" that it would then have been
   blamed for. The panels stay live behind the drawer on purpose: the drawer is not a modal, and the
   swarm keeps ticking underneath it.
   -------------------------------------------------------------------------- */


/* --------------------------------------------------------------------------
   the drawer's own tables — defined here rather than in styles.css so the world
   screen owns everything it renders
   -------------------------------------------------------------------------- */

.hud-table {
  width: 100%;
  border-collapse: collapse;
  font-family: var(--hud-mono);
  font-size: max(10.5px, var(--nouma-fs-floor));
}

.hud-table th {
  position: sticky;
  top: 0;
  padding: 6px 8px;
  text-align: left;
  font-weight: 500;
  font-size: max(10px, var(--nouma-fs-floor));
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--hud-muted);
  background: var(--hud-paper);
  border-bottom: 1px solid var(--hud-hair);
}

.hud-table td {
  padding: 6px 8px;
  border-bottom: 1px solid rgba(var(--hud-ink-rgb), 0.06);
  font-variant-numeric: tabular-nums;
  vertical-align: baseline;
}

.hud-table tr:hover td {
  background: rgba(var(--hud-accent-rgb), 0.06);
}

.hud-stage {
  font-size: max(10px, var(--nouma-fs-floor));
  letter-spacing: 0.1em;
  text-transform: uppercase;
  padding: 1px 5px;
  border-radius: 2px;
  border: 1px solid var(--hud-hair);
  color: var(--hud-muted);
}

.hud-stage[data-stage="ADULT"] {
  color: var(--hud-accent);
  border-color: rgba(var(--hud-accent-rgb), 0.5);
}
.hud-stage[data-stage="ELDER"] {
  color: var(--hud-explore);
}
.hud-stage[data-stage="DEATH"] {
  opacity: 0.45;
}

/* the empty and error states, because a panel with nothing to show must say so
   rather than render a convincing zero */
.hud-empty {
  padding: 18px 0;
  font-family: var(--hud-mono);
  font-size: max(10.5px, var(--nouma-fs-floor));
  line-height: 1.7;
  color: var(--hud-muted);
}

.hud-alert {
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding: 7px 9px;
  margin-bottom: 6px;
  border-left: 2px solid var(--hud-hair);
  background: rgba(var(--hud-ink-rgb), 0.03);
  font-size: max(10.5px, var(--nouma-fs-floor));
  line-height: 1.55;
}

.hud-alert[data-level="L3"] {
  border-left-color: var(--hud-alarm);
}
.hud-alert[data-level="L2"] {
  border-left-color: var(--hud-explore);
}
.hud-alert[data-level="L1"] {
  border-left-color: var(--hud-aggregate);
}

.hud-alert .lvl {
  flex: none;
  font-size: max(10px, var(--nouma-fs-floor));
  letter-spacing: 0.1em;
  color: var(--hud-muted);
}

/* --------------------------------------------------------------------------
   deep data drawer: trust network, lineage & individual fly profile
   -------------------------------------------------------------------------- */

.hud-section-title {
  margin: 18px 0 8px;
  font-size: max(10px, var(--nouma-fs-floor));
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--hud-muted);
  border-bottom: 1px solid var(--hud-hair);
  padding-bottom: 4px;
}

.hud-stat-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(110px, 1fr));
  gap: 8px;
  margin-bottom: 14px;
}

.hud-stat-card {
  padding: 8px 10px;
  background: rgba(var(--hud-ink-rgb), 0.025);
  border: 1px solid var(--hud-hair);
  border-radius: 2px;
}

.hud-stat-card .label {
  font-size: max(10px, var(--nouma-fs-floor));
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--hud-muted);
  margin-bottom: 3px;
}

.hud-stat-card .value {
  font-family: var(--hud-mono);
  font-size: max(14px, var(--nouma-fs-floor));
  font-weight: 500;
  color: var(--hud-ink);
  font-variant-numeric: tabular-nums;
}

.hud-badge {
  display: inline-block;
  padding: 1px 6px;
  font-size: max(10px, var(--nouma-fs-floor));
  letter-spacing: 0.08em;
  text-transform: uppercase;
  border-radius: 2px;
  border: 1px solid var(--hud-hair);
}

.hud-badge[data-tier="FULL_COOP"] {
  color: var(--hud-accent);
  border-color: rgba(var(--hud-accent-rgb), 0.6);
  background: rgba(var(--hud-accent-rgb), 0.08);
}

.hud-badge[data-tier="CAUTIOUS"] {
  color: var(--hud-explore);
  border-color: rgba(184, 150, 78, 0.4);
}

.hud-badge[data-tier="MINIMAL"] {
  color: var(--hud-muted);
}

.hud-badge[data-tier="HOSTILE"] {
  color: var(--hud-alarm);
  border-color: rgba(255, 84, 112, 0.4);
}

.hud-progress-track {
  width: 100%;
  height: 4px;
  background: rgba(var(--hud-ink-rgb), 0.08);
  border-radius: 999px;
  overflow: hidden;
  margin-top: 4px;
}

.hud-progress-fill {
  height: 100%;
  background: var(--hud-accent);
}

.hud-clickable-row {
  cursor: pointer;
}

.hud-clickable-row:hover td {
  background: rgba(var(--hud-accent-rgb), 0.1) !important;
}

/* --------------------------------------------------------------------------
   Fly Quick Picker Grid (48 Flies Direct Access)
   -------------------------------------------------------------------------- */

.hud-picker-wrap {
  margin-top: 10px;
  padding-top: 8px;
  border-top: 1px solid var(--hud-hair);
}

.hud-picker-title {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: max(10px, var(--nouma-fs-floor));
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--hud-muted);
  margin-bottom: 6px;
}

.hud-fly-picker {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: 3px;
}

.hud-picker-cell {
  /* A <button> now, not a <div>: the roster has to be reachable by Tab. A button arrives with its own
     font, padding and alignment, so the reset comes first — the plate underneath still wins, because
     the cell must look exactly as it did or all 48 of them would change shape together. */
  font: inherit;
  padding: 0;
  appearance: none;
  aspect-ratio: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--hud-mono);
  font-size: max(10px, var(--nouma-fs-floor));
  border: 1px solid var(--hud-hair);
  border-radius: 2px;
  background: rgba(var(--hud-ink-rgb), 0.03);
  color: var(--hud-muted);
  cursor: pointer;
  transition: all 0.15s ease;
  user-select: none;
}

.hud-picker-cell:hover {
  border-color: var(--hud-accent);
  color: var(--hud-ink);
  background: rgba(var(--hud-accent-rgb), 0.18);
  transform: scale(1.15);
  z-index: 2;
}

.hud-picker-cell[data-stage="ADULT"] {
  border-color: rgba(var(--hud-accent-rgb), 0.45);
}

.hud-picker-cell[data-stage="ELDER"] {
  border-color: rgba(184, 150, 78, 0.45);
  color: var(--hud-explore);
}

.hud-picker-cell[data-stage="YOUTH"] {
  border-color: rgba(16, 185, 129, 0.45);
  color: var(--hud-vital);
}

/* The roster drawn inside the drawer is the same grid as the corner panel, but
   the drawer is narrower than the panel it replaces — tighter gutters and a
   floor on the cell height keep 48 of them legible instead of squashed. */
.drawer .hud-fly-picker {
  gap: 4px;
}

.drawer .hud-picker-cell {
  min-height: 28px;
  font-size: max(10px, var(--nouma-fs-floor));
}

/* --------------------------------------------------------------------------
   Lifecycle & Family Lineage UI
   -------------------------------------------------------------------------- */

.hud-life-container {
  margin: 6px 0 16px;
}

.hud-life-labels {
  display: flex;
  justify-content: space-between;
  font-size: max(10px, var(--nouma-fs-floor));
  font-family: var(--hud-mono);
  color: var(--hud-muted);
  margin-bottom: 4px;
}

.hud-life-track {
  width: 100%;
  height: 6px;
  background: rgba(var(--hud-ink-rgb), 0.06);
  border-radius: 999px;
  overflow: hidden;
  position: relative;
  border: 1px solid var(--hud-hair);
}

.hud-life-fill {
  height: 100%;
  background: linear-gradient(90deg, var(--hud-vital) 0%, var(--hud-warn) 60%, var(--hud-alarm) 100%);
  border-radius: 999px;
  transition: width 0.3s ease;
}

.hud-kinship-wrap {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 6px;
}

.hud-kinship-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-family: var(--hud-mono);
  font-size: max(10.5px, var(--nouma-fs-floor));
  padding: 3px 8px;
  border: 1px solid var(--hud-hair);
  border-radius: 2px;
  background: rgba(var(--hud-ink-rgb), 0.03);
  color: var(--hud-ink);
  cursor: pointer;
  transition: all var(--nouma-dur-interact) var(--nouma-ease);
}

.hud-kinship-chip:hover {
  border-color: var(--hud-accent);
  background: rgba(var(--hud-accent-rgb), 0.12);
  color: var(--hud-accent);
}

/* --------------------------------------------------------------------------
   Dual-Mode Switcher: Human HUD <-> Agent 402 Terminal
   -------------------------------------------------------------------------- */

.hud-mode-pill {
  display: inline-flex;
  align-items: center;
  background: rgba(var(--hud-ink-rgb), 0.05);
  border: 1px solid var(--hud-hair);
  border-radius: 999px;
  padding: 2px;
  margin-right: 8px;
  gap: 2px;
  flex: 0 0 auto;
}

.hud-mode-btn {
  font-family: var(--hud-mono);
  font-size: max(10.5px, var(--nouma-fs-floor));
  letter-spacing: 0.08em;
  padding: 3px 9px;
  border-radius: 999px;
  border: none;
  background: transparent;
  color: var(--hud-muted);
  cursor: pointer;
  transition: all var(--nouma-dur-interact) var(--nouma-ease);
  /* The pill is a fixed control, not a stretchy one. Squeezed, the label broke over two lines and the
     pill grew to three times the bar's height — a 390px screen spent a fifth of itself on two words. */
  display: inline-flex;
  align-items: center;
  flex: 0 0 auto;
  white-space: nowrap;
}

.hud-mode-btn.is-active {
  background: var(--hud-ink);
  color: var(--hud-paper);
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.15);
}

/* An inline glyph inside a chip or the mode pill. Without this the 14px mark sits flush against the
   label and on the text baseline; the mark is how the control is recognised before its word is read,
   so it needs the gap and the nudge. */
.hud-chip > svg.glyph,
.hud-mode-btn > svg.glyph {
  vertical-align: -2px;
  margin-right: 5px;
}

/* A state dot inside a sentence — the breeding verdict in the fly table. Left on the baseline it
   reads as a full stop rather than as a mark beside the word. */
.hud-table td > svg.glyph {
  vertical-align: -1px;
  margin-right: 5px;
}

.hud-chip-highlight {
  border-color: rgba(245, 158, 11, 0.5) !important;
  color: var(--hud-warn) !important;
  background: rgba(245, 158, 11, 0.08) !important;
  font-weight: 500;
}

/* --------------------------------------------------------------------------
   Agent 402 Fullscreen Protocol Terminal Overlay
   -------------------------------------------------------------------------- */

.agent-terminal-overlay {
  position: fixed;
  inset: 0;
  z-index: 100;
  background: var(--console-ground);
  color: var(--console-ink);
  font-family: var(--hud-mono);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  box-sizing: border-box;
}

.agent-terminal-overlay:not(.is-open) {
  display: none;
}

.terminal-header {
  flex: none;
  height: 48px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 0 20px;
  background: var(--console-raised);
  border-bottom: 1px solid var(--console-hair);
}

.terminal-header .title {
  display: flex;
  align-items: center;
  gap: 12px;
  /* The title is the half that gives way: the exit button must stay whole at any width. */
  min-width: 0;
  font-size: max(11px, var(--nouma-fs-floor));
  letter-spacing: 0.14em;
  color: var(--console-signal);
  white-space: nowrap;
}

.terminal-header .dot-live {
  flex: none;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--console-live);
  box-shadow: 0 0 8px var(--console-live);
}

/* The exit control carries `.hud-chip`, whose rules live under `.hud-topmeta` — the paper bar.
   Out here that class brings no styling at all, so the browser's own button rendered as a bright
   white pill on a near-black header. These are the same declarations the bar's chips use, restated
   against the console's palette. */
.terminal-header .hud-chip {
  flex: 0 0 auto;
  font-family: var(--hud-mono);
  font-size: max(10.5px, var(--nouma-fs-floor));
  letter-spacing: 0.1em;
  color: var(--console-dim);
  background: transparent;
  border: 1px solid rgba(255, 255, 255, 0.14);
  border-radius: 2px;
  padding: 5px 10px;
  cursor: pointer;
  white-space: nowrap;
  transition: color 0.25s, border-color 0.25s;
}

.terminal-header .hud-chip:hover,
.terminal-header .hud-chip:focus-visible {
  color: var(--console-ink);
  border-color: rgba(245, 158, 11, 0.55);
}

.terminal-body {
  flex: 1;
  min-height: 0;
  display: grid;
  /* Left is the operation and its output, right is the reference. The left column keeps a floor
     because a transcript narrower than about 380px wraps every request line onto two. */
  grid-template-columns: minmax(380px, 1fr) minmax(340px, 1.05fr);
  overflow: hidden;
}

.terminal-pane {
  min-height: 0;
  padding: 20px 24px;
  overflow-y: auto;
  box-sizing: border-box;
}

.terminal-pane-left {
  /* A column rather than a block, so the transcript takes exactly the height the descriptors leave
     instead of stopping at a fixed ceiling and leaving the rest of the column black. */
  display: flex;
  flex-direction: column;
  border-right: 1px solid var(--console-hair);
  background: var(--console-raised);
}

.terminal-subhead {
  flex: none;
  font-size: max(10px, var(--nouma-fs-floor));
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--console-dim);
  margin: 0 0 10px;
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.code-block {
  background: var(--console-sunken);
  border: 1px solid var(--console-hair);
  border-radius: 4px;
  padding: 11px 14px;
  font-size: max(10.5px, var(--nouma-fs-floor));
  line-height: 1.55;
  color: var(--console-ink);
  margin-bottom: 14px;
  white-space: pre-wrap;
  /* Break at the spaces the code already has, and only inside a token when a single token is wider
     than the block. `break-all` was cutting `swarm/snapshot` in half on a 1024px column. */
  overflow-wrap: break-word;
  position: relative;
}

.code-amber { color: var(--console-signal); }
.code-green { color: #10b981; }
.code-cyan { color: #38bdf8; }
.code-dim { color: var(--console-dim); }
/* A transport failure, or a credential the gateway refused. The console had no colour for "this went
   wrong" — a failed request was printed in the same grey as the request line. */
.code-red { color: #ef4444; }

.sandbox-btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  background: var(--console-signal);
  color: var(--console-ground);
  font-family: var(--hud-mono);
  font-size: max(11px, var(--nouma-fs-floor));
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  padding: 8px 16px;
  border: none;
  border-radius: 2px;
  cursor: pointer;
  transition: all var(--nouma-dur-interact) var(--nouma-ease);
  margin-bottom: 16px;
}

.sandbox-btn:hover {
  background: var(--console-signal);
  box-shadow: 0 0 16px rgba(245, 158, 11, 0.4);
}

/* The sandbox block was written for the paper drawer, where `--hud-muted` is dark ink on cream. On
   the console's near-black ground those two roles are invisible, so the title and the note are
   restated here — the note is the paragraph that explains what the button will actually do. */
.agent-terminal-overlay .hud-panel-title {
  margin-bottom: 6px;
  color: var(--console-dim);
}

.agent-terminal-overlay .hud-empty {
  padding: 0 0 14px;
  font-size: max(10.5px, var(--nouma-fs-floor));
  color: var(--console-dim);
}

.terminal-controls {
  flex: none;
}

/* The transcript's own frame: a head that does not scroll, and the window that does. */
.terminal-log {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
  margin-bottom: 20px;
}

.terminal-log-head {
  display: flex;
  flex: none;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 6px;
}

/* The log head is shared: the paper drawer renders it first, and the console restates the two
   colours further down. Written the other way round, the drawer inherited a grey that was chosen
   for a black ground and the button all but disappeared against cream. */
.terminal-log-head .label {
  font-size: max(10px, var(--nouma-fs-floor));
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--hud-muted);
}

.terminal-copy {
  font-family: var(--hud-mono);
  font-size: max(10.5px, var(--nouma-fs-floor));
  letter-spacing: 0.08em;
  color: var(--hud-muted);
  background: transparent;
  border: 1px solid var(--hud-hair);
  border-radius: 2px;
  padding: 3px 9px;
  cursor: pointer;
  transition: color var(--nouma-dur-interact), border-color var(--nouma-dur-interact),
    background var(--nouma-dur-interact);
}

.terminal-copy:hover,
.terminal-copy:focus-visible {
  color: var(--hud-ink);
  border-color: rgba(var(--hud-accent-rgb), 0.55);
  background: rgba(var(--hud-accent-rgb), 0.08);
}

.agent-terminal-overlay .terminal-log-head .label {
  color: var(--console-dim);
}

.agent-terminal-overlay .terminal-copy {
  color: var(--console-dim);
  border-color: rgba(255, 255, 255, 0.14);
}

.agent-terminal-overlay .terminal-copy:hover,
.agent-terminal-overlay .terminal-copy:focus-visible {
  color: var(--console-ink);
  border-color: rgba(245, 158, 11, 0.5);
  background: rgba(245, 158, 11, 0.08);
}

/* The gateway's four doors. A grid rather than a list so the column fills its width at 1440 and
   folds to one card per row when the column narrows, without a second breakpoint. */
.terminal-endpoints {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(232px, 1fr));
  gap: 8px;
  margin-bottom: 16px;
}

.terminal-endpoint {
  border: 1px solid var(--console-hair);
  border-radius: 2px;
  background: var(--console-raised);
  padding: 8px 11px;
}

.terminal-endpoint .sig {
  display: flex;
  align-items: baseline;
  gap: 8px;
  /* At 1024 the card is ~250px wide and the longer path does not fit beside its method, so it takes
     the next line whole instead of being hyphenated into `?c` / `hallenge=1`. */
  flex-wrap: wrap;
  margin-bottom: 4px;
}

.terminal-endpoint .method {
  flex: none;
  font-size: max(10px, var(--nouma-fs-floor));
  letter-spacing: 0.1em;
  padding: 1px 5px;
  border: 1px solid rgba(245, 158, 11, 0.45);
  border-radius: 2px;
  color: var(--console-signal);
}

.terminal-endpoint .path {
  font-size: max(10.5px, var(--nouma-fs-floor));
  line-height: 1.5;
  color: var(--console-ink);
  word-break: break-all;
}

.terminal-endpoint .does {
  margin: 0 0 6px;
  font-size: max(10.5px, var(--nouma-fs-floor));
  line-height: 1.6;
  color: var(--console-dim);
}

.terminal-endpoint .cred {
  margin: 0;
  padding-top: 5px;
  border-top: 1px solid rgba(255, 255, 255, 0.06);
  font-size: max(10.5px, var(--nouma-fs-floor));
  line-height: 1.6;
  color: var(--console-dim);
}

.terminal-stream-log {
  background: var(--console-sunken);
  border: 1px solid rgba(245, 158, 11, 0.2);
  border-radius: 4px;
  padding: 16px;
  font-size: max(10.5px, var(--nouma-fs-floor));
  line-height: 1.7;
  min-height: 190px;
  max-height: 320px;
  overflow-y: auto;
  color: var(--console-dim);
}

/* The drawer wants a window of a fixed size; the console's transcript is the point of its column
   and takes the height the descriptors leave. */
.terminal-pane-left .terminal-stream-log {
  flex: 1 1 auto;
  max-height: none;
}

/* Below 900px the two columns stop being a comparison and start being a queue: operations first,
   reference after. The body scrolls as one page, because two independently scrolling columns on a
   phone is a trap — the reader swipes the wrong one and concludes the page is stuck. */
@media (max-width: 900px) {
  /* A block, not a one-column grid: grid rows in a height-constrained container were being sized to
     half the body each, so the left column's content spilled over the right one. In flow layout each
     pane takes its own height and the body scrolls, which is what a stacked console should do. */
  .terminal-body {
    display: block;
    overflow-y: auto;
  }

  .terminal-pane {
    padding: 18px 16px;
    overflow: visible;
  }

  .terminal-pane-left {
    display: block;
    border-right: 0;
    border-bottom: 1px solid var(--console-hair);
  }

  /* Stacked, the column has no height to divide, so the transcript goes back to its own window. */
  .terminal-pane-left .terminal-stream-log {
    flex: none;
    max-height: 320px;
  }

  .terminal-header {
    gap: 8px;
    padding: 0 12px;
  }

  .terminal-header .title {
    font-size: max(10px, var(--nouma-fs-floor));
    letter-spacing: 0.1em;
    overflow: hidden;
  }

  /* The exit button keeps its whole label, so the title is the part that gives way — clipped at the
     chip's edge rather than painted underneath it, which is what a nowrap flex row does by default. */
  .terminal-header .title-main {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  /* The network is already named in the descriptors block, so this is a repeat rather than a fact
     the narrow layout loses. */
  .terminal-header .title-net {
    display: none;
  }

  .terminal-endpoints {
    grid-template-columns: 1fr;
  }
}

/* --------------------------------------------------------------------------
   narrow screens

   The four corners cannot coexist below about 900px. The two instrument panels
   stay; the population and about panels fold into the drawer, which is the only
   honest thing to do — shrinking them to keep all four would produce four panels
   with nothing legible in them.
   -------------------------------------------------------------------------- */

@media (max-width: 900px) {
  .hud-panel-pop,
  .hud-panel-about {
    display: none;
  }

  /* The shortcuts that replace the folded panels. */
  .hud-chip-narrow {
    display: inline-flex;
  }

  /* A tighter bar so the chips still fit on one line at 390px. */
  .hud-topbar {
    padding: calc(var(--hud-pad) * 0.7) var(--hud-pad);
    /* The wordmark and the chip strip share one row here. Letting the strip wrap instead made the
       bar 168px tall — a fifth of the screen — because eleven chips cannot fit 390px. */
    flex-wrap: nowrap;
    align-items: center;
  }

  .hud-wordmark {
    flex: 0 0 auto;
  }

  /* One row, swiped rather than wrapped. Every chip stays reachable and the bar keeps its height. */
  .hud-topmeta {
    font-size: max(10px, var(--nouma-fs-floor));
    gap: 6px;
    flex: 1 1 auto;
    min-width: 0;
    flex-wrap: nowrap;
    justify-content: flex-start;
    overflow-x: auto;
    scrollbar-width: none;
    /* A little end padding so the last chip is not flush against the viewport edge when scrolled. */
    padding-block-end: 2px;
    /* The strip is wider than the screen, and a clipped chip looks like a bug rather than an
       invitation. Fading the last few pixels is the only affordance available without a script. */
    mask-image: linear-gradient(to right, #000 88%, transparent 100%);
    -webkit-mask-image: linear-gradient(to right, #000 88%, transparent 100%);
  }

  .hud-topmeta::-webkit-scrollbar {
    display: none;
  }

  .hud-topmeta .sep {
    display: none;
  }

  .hud-panel-econ,
  .hud-panel-temp {
    width: min(360px, calc(100vw - 2 * var(--hud-pad)));
  }

  .hud-panel-temp {
    bottom: var(--hud-pad);
  }

  .hud-feed {
    display: none;
  }
}
