/* scan: intentional-colors — the face is one-theme black by design
   (SURFACES.md): its #000 grounds and print inversion follow no palette. */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

/* BEGIN:generated-face-root — ruby RAILS/tools/generate_face_root_css.rb */
:root {
  --c-text: oklch(86% 0.02 300);
  --x-text: #d8d6e0;
  --c-accent: oklch(78% 0.10 300);
  --c-danger: oklch(60% 0.14 35);
  --c-code: oklch(74% 0.11 275);
  --font-mono: "JetBrainsMono Nerd Font", "JetBrains Mono", "Cascadia Code", "Fira Code", ui-monospace, monospace;
  --font-label: "JetBrainsMono Nerd Font","JetBrains Mono","Cascadia Code",ui-monospace,"SFMono-Regular",Menlo,monospace;
  color-scheme: dark;
  --safe-top: env(safe-area-inset-top, 0px);
  --safe-right: env(safe-area-inset-right, 0px);
  --safe-bottom: env(safe-area-inset-bottom, 0px);
  --safe-left: env(safe-area-inset-left, 0px);
  --chrome-inset: 12px;
  --inset-t: calc(var(--chrome-inset) + var(--safe-top));
  --inset-r: calc(var(--chrome-inset) + var(--safe-right));
  --inset-b: calc(var(--chrome-inset) + var(--safe-bottom));
  --inset-l: calc(var(--chrome-inset) + var(--safe-left));
  --face-bg: black;
  --face-fg: var(--c-text);
  --face-muted: color-mix(in srgb, var(--c-text) 35%, transparent);
  --face-dim: color-mix(in srgb, var(--c-text) 18%, transparent);
  --face-soft: color-mix(in srgb, var(--c-text) 8%, transparent);
  --mood-accent: var(--c-accent);
  --canvas-mood-accent: var(--c-accent);
  --border-faint: color-mix(in srgb, var(--face-fg) 10%, transparent);
  --border-soft: color-mix(in srgb, var(--face-fg) 14%, transparent);
  --border-strong: color-mix(in srgb, var(--face-fg) 24%, transparent);
  --hover-tint: color-mix(in srgb, var(--face-fg) 8%, transparent);
  --tap-min: 44px;
  --hud-lg: 13px;
  --hud-md: 11px;
  --hud-sm: 10px;
  --radius-xs: 0;
  --radius-sm: 0;
  --radius-md: 0;
  --radius-lg: 0;
  --radius-pill: 0;
  --face-bar-height: 44px;
  --bar-height: 44px;
  --hud-tier-status: calc(var(--face-bar-height) + var(--safe-bottom) + 8px);
  --hud-tier-caption: calc(var(--face-bar-height) + var(--safe-bottom) + var(--tap-min));
  /* canvas-only knobs: read via getComputedStyle in face.runtime.js, not consumed by any CSS rule below */
  --face-particle-size: 0.019;
  --face-glow-scale: 1.22;
  --face-phosphor-decay: 0.80;
  --transition-fast: 180ms;
  --transition-normal: 300ms;
  --ease-out: cubic-bezier(0.16,1,0.3,1);
  --ease-linear: cubic-bezier(0,0,1,1);
  --ease-in-out: cubic-bezier(0.65,0,0.35,1);
  --ease-spring: cubic-bezier(0.32,0.72,0,1);
  /* z-scale: canvas(base) < chrome(persistent HUD) < ui < overlay(panels) < modal(blocking) < toast(errors) < skip(a11y skip-link) */
  --z-canvas: 1;
  --z-chrome: 10;
  --z-ui: 90;
  --z-overlay: 100;
  --z-modal: 1000;
  --z-toast: 1100;
  --z-skip: 2000;
}
/* END:generated-face-root */

/* Not a generated token. generate_face_root_css.rb owns the block above, so a
   hand-added line inside it is drift the deploy gate stops — correctly, since
   the generator would erase it on its next run. This one belongs to MASTER web
   alone: matching brgen's wordmark is a property of this surface, not a shared
   design value. */
:root {
  /* The wordmark, and only the wordmark. ai.brgen.no is the same brand as
   brgen.no, and that brand is set in Helvetica Neue Pro — the face on the
   printed stock. The Pro cut is licensed per seat and cannot ship as a
   webfont, so the stack names the printed face where it exists (Apple ships
   Helvetica Neue, most Linux ships the Nimbus Sans clone) and falls to Arial,
   which is metrically identical to Helvetica, where it does not. Same value
   as --font-brand in RAILS/shared _dialect_tokens.scss: matching the stack is
   what makes the two surfaces agree, and this one downloads nothing.
   Everything else here stays monospace. */
--font-brand: "Helvetica Neue", Helvetica, "Nimbus Sans", Arial, sans-serif;
}

html, body {
  height: 100%;
  background: var(--face-bg);
  color: var(--face-fg);
  font: 16px/1.5 system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
  font-feature-settings: "ss01","ss03","cv05","kern" 1;
  text-rendering: optimizeLegibility;
  overflow: hidden;
  -webkit-tap-highlight-color: transparent;
  touch-action: none;
  user-select: none;
  -webkit-font-smoothing: none;
  -moz-osx-font-smoothing: grayscale;
  cursor: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Crect x='7' y='0' width='2' height='6' fill='%23d8d6e0'/%3E%3Crect x='7' y='10' width='2' height='6' fill='%23d8d6e0'/%3E%3Crect x='0' y='7' width='6' height='2' fill='%23d8d6e0'/%3E%3Crect x='10' y='7' width='6' height='2' fill='%23d8d6e0'/%3E%3C/svg%3E") 8 8, crosshair;
}

body.face-loading {
  touch-action: manipulation;
}

body.font-mono {
  font-family: var(--font-mono);
}

body[data-high-contrast="1"] {
  --face-fg: white;
  --face-muted: white;
  --face-dim: white;
  --face-soft: white;
}
body[data-high-contrast="1"] .msg-body { color: white; }
body[data-high-contrast="1"] .enhance-text { color: white; }

@media (prefers-contrast: more) {
  :root {
    --face-muted: color-mix(in srgb, var(--c-text) 55%, transparent);
    --face-dim: color-mix(in srgb, var(--c-text) 34%, transparent);
    --border-faint: color-mix(in srgb, var(--face-fg) 22%, transparent);
    --border-soft: color-mix(in srgb, var(--face-fg) 30%, transparent);
  }
}

@media (prefers-reduced-transparency: reduce) {
  #cmd-palette { background: var(--face-bg); backdrop-filter: none; }
  #cmd-palette-panel { background: var(--face-bg); }
  #chat-history-panel { background: var(--face-bg); }
}

/* Canvas filter tweaks encode runtime state (pixel_field systemic_emotion_mapping), not decorative glow. */
body[data-runtime-profile="battery"] canvas { filter: none; }
html[data-topology-flash="1"] canvas { filter: contrast(1.05); transition: filter .09s steps(2,end); }
body[data-runtime-profile="full"] canvas { filter: none; }
body[data-runtime-profile="calm"] canvas { filter: none; }
body[data-runtime-profile="calm"] #cognition-ecology { opacity: 0.72; mix-blend-mode: normal; }
body[data-runtime-profile="calm"] #ascii-star { display: none; }
body[data-long-silence="1"] canvas { filter: none; }
body[data-laughter="1"] canvas { filter: contrast(1.08) saturate(1.06); }
body[data-face-flash="1"] canvas {
  filter: saturate(1.08) contrast(1.04);
}

body[data-focus-mode="1"] .top-left-logo,
body[data-focus-mode="1"] .ui-status,
body[data-focus-mode="1"] .face-controls,
body[data-focus-mode="1"] #chat-shell,
body[data-focus-mode="1"] #ascii-star,
body[data-focus-mode="1"]
#photo-button {
  min-width: var(--tap-min);
  min-height: var(--tap-min);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  background: transparent;
  border: 0;
  color: inherit;
  font: inherit;
  cursor: pointer;
}
#photo-button:focus-visible,
#spin-btn:focus-visible,
#zin:focus-visible,
.skip-link:focus-visible {
  outline: 2px solid var(--c-accent, var(--accent, #7c6fd6));
  outline-offset: 2px;
}

#spin-btn {
  opacity: 0;
  pointer-events: none;
}

body[data-focus-mode="1"] #zsh {
  background: transparent;
  backdrop-filter: none;
}

/* WebGL layer stack (independent of the --z-* DOM chrome scale below): raw canvas(0) < face(1) < fx(2) */
canvas#face {
  background: #000;
  z-index: 1;
  transform: translateZ(0);
}

#cognition-ecology {
  z-index: 2;
  pointer-events: none;
  mix-blend-mode: screen;
  opacity: 0.88;
  transition: opacity 300ms var(--ease-out);
}

html[data-agent-engagement="thinking"] #cognition-ecology { opacity: 0.94; }
html[data-agent-engagement="speaking"] #cognition-ecology { opacity: 0.82; }

canvas {
  position: fixed;
  inset: 0;
  z-index: 0;
  display: block;
  width: 100dvw;
  height: 100dvh;
  image-rendering: pixelated;
  image-rendering: crisp-edges;
  touch-action: none;
  transition: filter var(--transition-fast) var(--ease-out);
}

body[data-focus-mode="1"] #cognition-ecology {
  opacity: 0.12;
  transition: opacity 280ms var(--ease-out);
}

body[data-runtime-visible="false"] canvas,
body[data-hidden-tab="1"] canvas {
  visibility: hidden;
}

body[data-runtime-visible="false"] #cognition-ecology,
body[data-hidden-tab="1"] #cognition-ecology {
  opacity: 0;
  transition: opacity 280ms var(--ease-out);
}

#cmd-palette {
  position: fixed;
  inset: 0;
  z-index: var(--z-modal);
  display: none;
  place-items: start center;
  padding: calc(12vh + var(--safe-top)) 16px 16px;
  background: color-mix(in srgb, var(--face-bg) 72%, transparent);
}

#cmd-palette[data-open="1"] { display: grid; }

#cmd-palette-panel {
  width: min(520px, 100%);
  border: 1px solid var(--border-soft);
  background: color-mix(in srgb, var(--face-bg) 94%, transparent);
  contain: layout style paint;
}

#cmd-palette-input {
  width: 100%;
  border: 0;
  border-bottom: 1px solid var(--border-faint);
  background: transparent;
  color: var(--face-fg);
  font: 16px/1.5 var(--font-label);
  padding: 12px 14px;
  outline: none;
}

#cmd-palette-list {
  list-style: none;
  max-height: 42vh;
  overflow: auto;
  margin: 0;
  padding: 6px 0;
}

#cmd-palette-list li {
  padding: 10px 14px;
  min-height: var(--tap-min);
  font: 16px/1.5 var(--font-label);
  color: color-mix(in srgb, var(--face-fg) 78%, transparent);
  cursor: pointer;
}

#cmd-palette-list li[data-active="1"],
#cmd-palette-list li:hover {
  background: var(--hover-tint);
  color: var(--face-fg);
}

#cmd-palette-list .cmd-hint {
  display: block;
  font-size: 14px;
  line-height: 1.5;
  color: var(--face-muted);
  margin-top: 2px;
}

body[data-face-pip="1"] canvas {
  width: min(34vw, 320px);
  height: min(34vw, 320px);
  inset: auto var(--chrome-inset) calc(56px + var(--safe-bottom)) auto;
  border-radius: 12px;
  transition: inset 180ms var(--ease-out), width 180ms var(--ease-out), height 180ms var(--ease-out), border-radius 180ms var(--ease-out), transform 180ms var(--ease-out), filter var(--transition-fast) var(--ease-out);
}

body[data-face-pip="1"][data-face-pip-corner="top-left"] canvas {
  inset: var(--inset-t) auto auto var(--inset-l);
}

body[data-face-pip="1"][data-face-pip-corner="top-right"] canvas {
  inset: var(--inset-t) var(--inset-r) auto auto;
}

body[data-face-pip="1"][data-face-pip-corner="bottom-left"] canvas {
  inset: auto auto calc(56px + var(--safe-bottom)) var(--inset-l);
}

body[data-face-pip="1"][data-face-pip-corner="bottom-right"] canvas {
  inset: auto var(--inset-r) calc(56px + var(--safe-bottom)) auto;
}

#zsh-wave {
  display: inline-flex;
  align-items: end;
  gap: 2px;
  height: 12px;
  margin-inline-start: 8px;
  opacity: .4;
}

#zsh-wave span {
  width: 3px;
  height: 4px;
  border-radius: 999px;
  background: var(--c-accent);
  transform-origin: center bottom;
  transition: height 90ms var(--ease-linear), opacity 90ms var(--ease-linear), transform 90ms var(--ease-linear);
}

@keyframes faceBootPulse {
  0%, 100% { opacity: .42; }
  50% { opacity: .78; }
}

@keyframes ttsPulse {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-1px); }
}

/* Pristine chrome: only the logo, face, and shell prompt stay visible --
   drop every top-right and bottom-right badge/status element. #mic-dot is
   exempt: it is the only feedback about whether the microphone is open.
   It used to be free when idle because it was invisible then — and that was
   the bug, since "off" and "no indicator" looked the same. It is now always
   drawn, grey when idle. One 18px glyph is the price of not having to guess. */
.model-badge,
.sound-on-chip,
.provider-chip,
body[data-council-persona]::after {
  display: none !important;
}

/* .ui-status is sr-only as of 2026-08-14, at the operator's request: no visible
   status text in the bottom-right corner.

   It is sr-only rather than display: none, and that distinction is the whole of
   what the 2026-08-13 exemption was defending. showStage writes "routing…",
   "scanning…" and "speaking…" here through an aria-live region, and display:
   none takes an element out of the accessibility tree entirely, so the
   announcements reached nobody — not the screen, not a screen reader. .sr-only
   clips instead, so the element still exists to assistive tech while rendering
   nothing. Sighted users lost a label they had for one day; screen reader users
   keep what that commit restored. Do not "simplify" this to display: none. */

/* Top-left logo — brgen wordmark (shared x tokens) */
.top-left-logo {
  position: fixed;
  top: calc(14px + var(--safe-top));
  inset-inline-start: calc(14px + var(--safe-left));
  z-index: var(--z-ui);
  font: 700 clamp(15px,3.8vw,24px)/1 var(--x-font, "Inter",-apple-system,system-ui,sans-serif);
  letter-spacing: -.03em;
  text-transform: none; /* brgen wordmark is lowercase */
  color: var(--x-text, var(--c-text));
  opacity: 1;
  pointer-events: none;
  user-select: none;
  text-rendering: optimizeLegibility;
  transition: opacity 1.2s var(--ease-out);
}
/* Mic indicator — top-right, always present, two states.
 *
 * Was a 10px dot at opacity 0 that appeared only while listening. That made
 * "microphone off" and "no indicator exists" the same picture, so the only way
 * to find out was to speak and wait for nothing to happen. Operator report
 * 2026-08-10: "no mic icon to indicate when its on and when its off (dark
 * grey), so user has to guess".
 *
 * Idle is dark grey and legible rather than hidden — a control you can see is
 * off is not clutter, it is the answer to the question. Listening keeps the
 * live colour and the pulse it always had. */
#mic-dot {
  position: fixed;
  top: calc(var(--inset-t) + 2px);
  inset-inline-end: calc(var(--inset-r) + 2px);
  width: 18px;
  height: 18px;
  color: var(--c-mic-off, #6b6b6b);
  opacity: 1;
  pointer-events: none;
  z-index: var(--z-ui);
  transition: color 160ms var(--ease-out), opacity 160ms var(--ease-out);
}

#mic-dot svg {
  width: 100%;
  height: 100%;
  display: block;
  fill: currentColor;
}

/* Listening: live colour and the pulse. */
body[data-mode="listening"] #mic-dot {
  color: var(--c-danger);
  will-change: transform;
  animation: micPulse 1.4s var(--ease-in-out) infinite;
}

/* While MASTER is speaking the mic is deliberately not listening, and saying so
 * is worth more than going blank -- this is the moment a user is most likely to
 * talk over it and wonder why nothing was heard. */
body[data-mode="speaking"] #mic-dot {
  opacity: 0.45;
}

@keyframes micPulse {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.12); }
}

/* Bottom-right status label */
.face-controls {
  position: fixed;
  inset-inline-start: var(--inset-l);
  bottom: var(--hud-tier-status);
  z-index: var(--z-ui);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  max-width: min(calc(100vw - 24px - var(--safe-left) - var(--safe-right)), 520px);
  padding: 6px 8px;
  border: 1px solid var(--border-faint);
  border-radius: var(--radius-lg);
  background: #000;
  contain: layout style paint;
}

.model-badge {
  position: fixed;
  top: calc(var(--inset-t) + 18px);
  inset-inline-end: var(--inset-r);
  z-index: var(--z-ui);
  padding: 5px 8px;
  border: 1px solid var(--border-faint);
  border-radius: var(--radius-pill);
  background: #000;
  color: var(--face-muted);
  font: 9px/1 var(--font-label);
  letter-spacing: .14em;
  text-transform: uppercase;
  opacity: 0;
  transform: translateY(-4px);
  transition: opacity 180ms var(--ease-out), transform 180ms var(--ease-out);
  pointer-events: none;
}

.model-badge[data-visible="1"] {
  opacity: 1;
  transform: translateY(0);
}

.soul-drift {
  position: fixed;
  top: var(--inset-t);
  z-index: var(--z-ui);
  pointer-events: none;
}

.soul-drift {
  inset-inline-start: var(--inset-l);
  padding: 5px 8px;
  border: 1px solid var(--border-faint);
  border-radius: var(--radius-pill);
  background: #000;
  color: var(--face-muted);
  font: 9px/1 var(--font-label);
  letter-spacing: .14em;
  text-transform: uppercase;
}

.face-scale {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--face-muted);
  font: 9px/1 var(--font-label);
  text-transform: uppercase;
  letter-spacing: .15em;
}

.face-scale input[type="range"] {
  width: 88px;
  accent-color: var(--face-fg);
}

/* SR-only for a11y live announcements (mood changes etc) — screen readers only, no visual */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* Primer overlay — Radio Bergen dialog style */
#primer {
  position: fixed;
  inset: 0;
  display: grid;
  place-items: center;
  z-index: var(--z-modal);
  background: color-mix(in srgb, var(--face-bg) 86%, transparent);
  cursor: pointer;
  text-align: center;
  padding: 16px;
  transition: opacity var(--transition-fast) var(--ease-out), background var(--transition-fast) var(--ease-out);
  touch-action: manipulation;
  pointer-events: auto;
  -webkit-tap-highlight-color: transparent;
}

#primer:focus-visible { outline: 1px solid var(--face-fg); outline-offset: -8px; }

/* The voice offer. One layer above #primer so its own tap is not swallowed by
   the full-viewport button underneath, and placed low enough that the thumb
   resting position for "just start" is still the primer itself. */
.primer-voice {
  position: fixed;
  inset-block-end: calc(18vh + var(--safe-bottom));
  inset-inline: 0;
  margin-inline: auto;
  width: fit-content;
  z-index: calc(var(--z-modal) + 1);
  min-height: var(--tap-min);
  padding: 0 1rem;
  background: transparent;
  border: 1px solid var(--border-soft);
  color: var(--face-muted);
  font: 400 0.875rem/1 var(--font-brand);
  cursor: pointer;
}
.primer-voice:hover { color: var(--face-fg); border-color: var(--border-strong); }
.primer-voice:focus-visible { outline: 1px solid var(--face-fg); outline-offset: 2px; }
body.face-ready .primer-voice { display: none; }

[id="face"]:focus-visible { outline: 2px solid var(--face-fg); outline-offset: 2px; }

#primer h1 {
  margin: 0;
  font: 400 clamp(1.05rem,3.2vw,1.5rem)/1.5 "Inter",Helvetica,Arial,sans-serif;
  letter-spacing: .01em;
  color: var(--face-fg);
  transition: transform var(--transition-fast) var(--ease-out);
}

#primer:active h1 { transform: scale(1.03); }
#primer .primer-consent { max-width: 42ch; margin: 16px auto 0; color: color-mix(in srgb, var(--c-text) 52%, transparent); font: 400 .8125rem/1.5 var(--font-label); }

/* Tap ripple */
@keyframes ripple { to { transform: translate(var(--x),var(--y)) translate(-50%,-50%) scale(22); opacity: 0; } }
.tap-ripple {
  position: fixed;
  inset-inline-start: 0;
  top: 0;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  pointer-events: none;
  transform: translate(var(--x),var(--y)) translate(-50%,-50%) scale(.4);
  opacity: .7;
  background: var(--border-strong);
  animation: ripple 680ms var(--ease-out) forwards;
  z-index: calc(var(--z-modal) - 1);
}

#chat-shell {
  position: fixed;
  inset-inline: 0;
  inset-block-end: calc(var(--face-bar-height) + var(--safe-bottom));
  z-index: var(--z-chrome);
  pointer-events: none;
}

/* #41 Scroll momentum */
#chat-log {
  max-height: 40dvh;
  overflow-y: auto;
  padding: 8px 16px;
  font: 12px/1.42 var(--font-label);
  font-variant-numeric: tabular-nums;
  scroll-behavior: smooth;
  color: var(--face-fg);
  pointer-events: none;
  touch-action: pan-y;
  scroll-snap-type: y mandatory;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
  scrollbar-width: thin;
  scrollbar-color: color-mix(in srgb, var(--face-fg) 28%, transparent) transparent;
}

#chat-log::-webkit-scrollbar { width: 6px; height: 6px; }
#chat-log::-webkit-scrollbar-thumb { background: color-mix(in srgb, var(--face-fg) 28%, transparent); border-radius: 3px; }

#chat-log:not(:empty) { pointer-events: auto; }
.message { position:relative; margin-bottom: 8px; white-space: pre-wrap; word-break: break-word; scroll-snap-align: start; animation: msgIn 220ms var(--ease-spring) both; }
.message:focus-visible { outline: 1px solid var(--face-fg); outline-offset: 1px; }
.msg-prompt { font-weight: 700; margin-inline-end: 0.35em; }
.message.user .msg-prompt { color: var(--face-fg); }
.message.assistant .msg-prompt { color: var(--face-muted); }
.msg-body { color: color-mix(in srgb, var(--c-text) 82%, transparent); font-feature-settings:'liga' 1,'kern' 1; }
.cursor { display:inline-block; width:7px; height:1em; background:currentColor; vertical-align:text-bottom; animation:cursorBlink 900ms steps(2,end) infinite; margin-inline-start:1px; }
.enhance-confirm { margin-bottom: 8px; padding: 4px 0; white-space: pre-wrap; word-break: break-word; font-size: .88em; }
.enhance-arrow { color: color-mix(in srgb, var(--face-fg) 22%, transparent); animation: blink .5s step-end 4; opacity: .5; }
.enhance-text { color: color-mix(in srgb, var(--face-fg) 32%, transparent); font-style: italic; opacity: .75; }
.enhance-yn { color: var(--face-muted); letter-spacing: .08em; }
.message.msg-error-flash .msg-body { outline: 1px solid color-mix(in srgb, var(--c-danger) 55%, transparent); outline-offset: 2px; }
.message.msg-pass-flash { border-bottom: 1px solid var(--face-fg); }
.message.msg-settled { border-inline-start: 1px solid color-mix(in srgb, var(--face-fg) 35%, transparent); transition: border-color 1.8s var(--ease-out); }
@keyframes blink { 0%,49% { opacity: 1; } 50%,100% { opacity: 0; } }

/* Action menu for keyboard nav on messages (FA138) */
.action-menu {
  position: absolute;
  background: var(--face-bg);
  border: 1px solid var(--face-muted);
  font: 10px/1.2 var(--font-label);
  color: var(--face-fg);
  padding: 2px;
  z-index: var(--z-overlay);
  white-space: nowrap;
}
.action-menu button {
  background: none;
  border: 0;
  color: inherit;
  padding: 2px 6px;
  cursor: pointer;
  font: inherit;
}
.action-menu button:hover, .action-menu button:focus { background: var(--border-faint); }

.provider-chip {
  position: fixed;
  inset-inline-end: var(--inset-r);
  bottom: var(--hud-tier-caption);
  z-index: var(--z-ui);
  font: 10px/1.2 var(--font-label);
  color: color-mix(in srgb, var(--master-accent, var(--c-accent)) 72%, var(--face-fg));
  text-transform: uppercase;
  letter-spacing: .15em;
  opacity: .72;
  pointer-events: none;
  user-select: none;
  transition: opacity var(--transition-fast) var(--ease-out);
}
.provider-chip:empty { display: none; }
html[data-model-provider] .provider-chip { opacity: .92; }

body.brutalist-mode * { border-radius: 0 !important; }
body.brutalist-mode .message { animation-timing-function: steps(3,end) !important; } /* scan: intentional — the mode must beat every message's own easing */
body[data-primer-flash="1"] canvas#face { filter: contrast(1.12) brightness(1.08); transition: filter 0ms steps(2,end); }

/* Mission control uses document layout chrome (not immersive face overflow). */
body.mission-control {
  overflow: auto;
  min-height: 100dvh;
  padding: calc(var(--chrome-inset, 0.75rem) + var(--safe-top, 0px))
           calc(var(--chrome-inset, 0.75rem) + var(--safe-right, 0px))
           calc(var(--chrome-inset, 0.75rem) + var(--safe-bottom, 0px))
           calc(var(--chrome-inset, 0.75rem) + var(--safe-left, 0px));
  font-family: var(--font-mono, "JetBrains Mono", ui-monospace, monospace);
  font-size: var(--hud-lg);
  touch-action: manipulation;
  user-select: text;
  cursor: auto;
  -webkit-font-smoothing: antialiased;
}
body.mission-control .page-header {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.75rem;
  margin-bottom: 1rem;
  max-width: var(--measure-body, 66ch);
}
body.mission-control h1 {
  font-size: 14px;
  font-weight: 600;
  margin: 0;
  letter-spacing: 0.04em;
}
body.mission-control .grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: var(--chrome-inset, 0.75rem);
}
body.mission-control .panel {
  border: 1px solid color-mix(in srgb, var(--c-text) 18%, transparent);
  padding: 10px 12px;
  background: #000;
  border-radius: 0;
  min-height: var(--tap-min, 44px);
}
body.mission-control .panel h2 {
  font-size: var(--hud-md);
  text-transform: uppercase;
  letter-spacing: .1em;
  opacity: 0.55;
  margin-bottom: 8px;
}
body.mission-control pre {
  white-space: pre-wrap;
  word-break: break-word;
  opacity: 0.9;
}
body.mission-control .meta { opacity: 0.65; margin-bottom: 6px; }
body.mission-control a { color: var(--c-text); }
body.mission-control a:focus-visible {
  outline: 2px solid var(--c-accent);
  outline-offset: 2px;
}

.tool-progress-chip {
  font: 9px/1.2 var(--font-label);
  color: var(--c-code);
  letter-spacing: .14em;
  text-transform: uppercase;
  margin-inline-start: 8px;
  opacity: .85;
}
.tool-progress-chip:empty { display: none; }

.idle-help-trail {
  position: fixed;
  inset-inline-start: 50%;
  bottom: calc(var(--hud-tier-caption) + 28px);
  transform: translateX(-50%);
  font: 10px/1 var(--font-label);
  color: var(--face-muted);
  letter-spacing: .15em;
  text-transform: uppercase;
  pointer-events: none;
  will-change: opacity, transform;
  animation: idleTrail 2.4s steps(4,end) infinite;
}
@keyframes idleTrail {
  0%,100% { opacity: .15; transform: translateX(-50%) translateY(0); }
  50% { opacity: .55; transform: translateX(-50%) translateY(6px); }
}

.fps-badge {
  position: fixed;
  top: var(--inset-t);
  inset-inline-start: var(--inset-l);
  z-index: var(--z-ui);
  font: 9px/1.2 var(--font-label);
  color: var(--face-fg);
  text-transform: uppercase;
  letter-spacing: .15em;
  pointer-events: none;
  user-select: none;
  opacity: .75;
}

#zsh {
  position: fixed;
  inset-inline: 0;
  inset-block-end: 0;
  display: flex;
  align-items: center;
  min-height: calc(var(--face-bar-height) + var(--safe-bottom));
  height: calc(var(--face-bar-height) + var(--safe-bottom));
  padding: 0 16px var(--safe-bottom);
  font: 16px/1.5 var(--font-label);
  color: var(--face-fg);
  border: 0;
  background: black;
  z-index: calc(var(--z-chrome) + 1);
  opacity: 0;
  pointer-events: none;
  transition: opacity .14s steps(5,end), transform .2s var(--ease-out);
  transform: translateY(30%);
}

body.zen #zsh,
body.zen #chat-log { opacity: .08; }
body.zen.zen-hidden .face-controls,
body.zen.zen-hidden #ui-status,
body.zen[data-edge-hover="1"] .face-controls,
body.zen[data-edge-hover="1"] #zsh { opacity: 1; pointer-events: auto; }

#shortcut-sheet { border: 1px solid var(--face-dim); background: #0a0a0a; color: var(--face-fg); padding: 12px 16px; max-width: 28rem; }
#shortcut-sheet table { width: 100%; font-size: 12px; }
#shortcut-sheet kbd { font-family: inherit; opacity: 0.85; }
.tool-diff pre.diff-body { font-size: var(--hud-sm); max-height: 12rem; overflow: auto; white-space: pre-wrap; }

body.zen #zsh.revealed { opacity: .96; pointer-events: auto; transform: none; }

body #zsh.live,
body:not(.face-ready) #zsh.live {
  opacity: 1;
  pointer-events: auto;
  transform: none;
}
#zsh .pp { color: color-mix(in srgb, var(--c-danger) 82%, transparent); font-weight: 700; }
#zsh .sep, #zsh .sep2 { color: var(--face-muted); margin-inline-end: 0.4ch; }
#zsh input, #zsh textarea { flex: 1; min-width: 0; background: transparent; border: 0; outline: 0; color: var(--face-fg); font: inherit; caret-color: var(--face-fg); padding: 2px 0; resize: none; line-height: 1.5; max-height: 120px; }
#zsh input::placeholder, #zsh textarea::placeholder { color: color-mix(in srgb, var(--face-fg) 22%, transparent); }
html[data-input-dense="1"] #zsh { border-top: 1.5px solid color-mix(in srgb, var(--face-fg) 28%, transparent); transition: border-top-width .2s var(--ease-out); }

/* Closed-caption strip (FA141) */
#tts-live {
  position: fixed;
  inset-inline-start: 50%;
  inset-inline-end: auto;
  transform: translateX(-50%);
  width: min(72vw, 520px);
  bottom: var(--hud-tier-caption);
  z-index: calc(var(--z-chrome) + 2);
  background: transparent;
  color: var(--face-fg);
  font: 12px/1.5 var(--font-label);
  padding: 1px 10px;
  text-align: center;
  white-space: pre-wrap;
  pointer-events: none;
  max-height: 2.5em;
  overflow: hidden;
  opacity: 0;
  transition: opacity 180ms var(--ease-out);
}
body[data-mode="speaking"] #tts-live,
body[data-tts-loading="true"] #tts-live {
  opacity: 1;
}

/* Inline status text — shows thinking/speaking inside the prompt bar */
#zsh-status {
  font: inherit;
  text-transform: uppercase;
  letter-spacing: .15em;
  color: var(--face-muted);
  opacity: 0;
  transition: opacity .2s, letter-spacing .4s var(--ease-out);
  white-space: nowrap;
  pointer-events: none;
  margin-inline-start: 4px;
}
body[data-mode="thinking"] #zsh-status { opacity: .7; }
body[data-mode="speaking"] #zsh-status { opacity: 1; }
body[data-tts-error="true"] #zsh-status { opacity: 1; color: var(--c-danger); }

/* Cancel button — appears during thinking/speaking */
#spin-btn {
  display: none;
  background: none;
  border: none;
  color: var(--c-accent);
  font: inherit;
  cursor: pointer;
  padding: 0 0 0 8px;
  min-width: var(--tap-min);
  min-height: var(--tap-min);
  opacity: .45;
  transition: opacity .1s;
}
#spin-btn:hover { opacity: 1; color: var(--face-fg); }
body[data-mode="thinking"] #spin-btn,
body[data-mode="speaking"] #spin-btn { display: block; }

:focus-visible { outline: 2px solid var(--face-fg); outline-offset: 2px; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation: none !important;
    scroll-behavior: auto;
    transition: none !important;
  }
  canvas#face, canvas#cognition-ecology { filter: none; }
  .message { animation: none; }
}

@media (min-width: 48rem) {
  #chat-log { padding-inline: 24px; }
  #zsh { padding-inline: 24px; }
}

@keyframes msgIn { from { opacity:0; transform:translateY(4px); } to { opacity:1; transform:none; } }

/* #35 User message right-align */
.message.user { flex-direction:row-reverse; text-align:right; border:0; padding-inline-end:8px; padding-inline-start:0; }

/* #36 Streaming cursor blink */
@keyframes cursorBlink { 0%,100%{opacity:1} 50%{opacity:0} }

/* #37 Code block */
.msg-body pre, .msg-body code { background:transparent; border-bottom:1px dotted color-mix(in srgb, var(--c-code) 18%, transparent); font-family:var(--font-label); padding:2px 5px; font-size:.88em; }
.msg-body pre { display:block; padding:8px 10px; margin:4px 0; white-space:pre-wrap; }
.typing-indicator { display:inline-flex; gap:3px; margin-inline-start:6px; vertical-align:middle; }
.typing-indicator span { width:4px; height:4px; border-radius:50%; background:var(--face-muted); animation:typingPulse 1s infinite var(--ease-in-out); }
.typing-indicator span:nth-child(2) { animation-delay: .16s; }
.typing-indicator span:nth-child(3) { animation-delay: .32s; }
@keyframes typingPulse { 0%, 80%, 100% { transform: translateY(0); opacity:.25; } 40% { transform: translateY(-2px); opacity:1; } }

/* #39 Message timestamp on hover */
.message[data-ts]::after { content:attr(data-ts); font-size:12px; line-height:1.5; color:var(--face-muted); opacity:0; transition:opacity .15s; margin-inline-start:8px; display:inline-block; vertical-align:middle; }
.message[data-ts]:hover::after { opacity:1; }

/* #40 Confidence band */
.message.assistant { border-inline-start:2px solid color-mix(in srgb, var(--c-code) calc(var(--conf-alpha,0.14) * 100%), transparent); padding-inline-start:8px; }

/* #42 Edge hover reveal */
body[data-edge-hover="1"] #zsh,
body[data-edge-swipe="1"] #zsh { opacity: .96; pointer-events: auto; transform: none; }

/* #43 Empty state ghost */
#chat-log:empty::after { content:'no history'; position:absolute; top:50%; left:50%; transform:translate(-50%,-50%); color:var(--face-dim); font-size:12px; line-height:1.5; text-transform:uppercase; letter-spacing:.15em; pointer-events:none; }

/* #44 Thinking-mode input dim */
body[data-mode="thinking"] #zin { opacity:.38; }
body[data-mode="speaking"] #zin { opacity:.75; }

/* #45 Char count warn threshold */
#char-count:not(:empty) { opacity: .5; }

/* #46 Char count */
#char-count { font: inherit; color:var(--face-muted); opacity:0; transition:opacity .15s; white-space:nowrap; margin-inline-start:4px; }

/* #47 Listening eye boost */
body[data-mode="listening"] canvas { filter: saturate(1.08) brightness(1.06) contrast(1.02); }

/* #48 Cancel button pulse during thinking */
body[data-mode="thinking"] #spin-btn { will-change: opacity; animation:cancelPulse 1.1s var(--ease-in-out) infinite; }
@keyframes cancelPulse { 0%,100%{opacity:.45} 50%{opacity:.85} }

/* #49 Idle help trail */
body[data-long-silence="1"] #cognition-ecology { opacity: .38; }

/* #51 Disabled state during boot — hide ghost prompt until primer tap */
body.face-loading #zsh:not(.live):not(.revealed) { opacity: 0; visibility: hidden; pointer-events: none; }
body:not(.face-ready) #zsh:not(.live):not(.revealed) { opacity: .22; pointer-events: none; }

body[data-boot-state="ERROR"] #zsh-status {
  color: color-mix(in srgb, var(--c-danger) 78%, var(--face-fg));
  font-size: var(--hud-md);
  letter-spacing: .04em;
  text-transform: none;
}

/* #52 Violation flash */
body[data-violation-flash="1"] canvas { filter: contrast(1.12) saturate(0.55); }

/* #54 Uncertain shimmer */
body[data-uncertain="1"] #zsh-status { opacity: 1; animation: uncertainBlink 900ms steps(3,end) infinite; }
@keyframes uncertainBlink { 0%,100%{opacity:.55} 50%{opacity:1} }

/* #55 Primer .gone fade */
#primer.gone { opacity: 0; transform: scale(0.96); pointer-events: none; transition: opacity 180ms var(--ease-out), transform 180ms var(--ease-out); }
/* Embeds / front-page autostart: no "launch AI" click overlay (boot still runs go()). */
body.primer-autostart #primer {
  opacity: 0;
  pointer-events: none;
  visibility: hidden;
}

.chips { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; margin-top: 14px; }
.chip { font: 14px/1.5 var(--font-label); letter-spacing: .08em; padding: 10px 14px; min-height: var(--tap-min); border: 1px solid color-mix(in srgb, var(--face-fg) 8%, transparent); border-radius: var(--radius-xs); color: color-mix(in srgb, var(--c-text) 62%, transparent); transition: background 120ms var(--ease-out); }
#primer .tagline { opacity: .72; font-size: .9em; margin-top: 14px; letter-spacing: .1em; }

/* #56 Sleeping dim */
body[data-sleeping="1"] canvas { filter: brightness(0.85); }
body[data-sleeping="1"] #zsh { opacity: .18; }

/* #57 Mood cold */
body[data-mood-cold="1"] canvas { filter: none; }

/* #58 TTS loading shimmer */
body[data-tts-loading="true"] #zsh-status { animation:ttsShimmer 700ms steps(4,end) infinite; }
@keyframes ttsShimmer { 0%,100%{opacity:.4} 50%{opacity:1} }

/* #60 Network stall */
body[data-network-stall="1"] #zsh-status { opacity: .85; color: var(--c-accent); }
body[data-network-stall="1"] canvas { filter: none; }

/* #61 Council persona badge */
body[data-council-persona]::after { content:attr(data-council-persona); position:fixed; top:calc(10px + var(--safe-top)); right:calc(10px + var(--safe-right)); font:9px/1.4 var(--font-label); text-transform:uppercase; letter-spacing:.14em; color:var(--face-muted); opacity:.6; z-index:var(--z-ui); pointer-events:none; }

/* Prompt typography */
#zsh input,#zsh .pp,#zsh .sep,#zsh .sep2 { font-feature-settings:'liga' 0; }

/* #65 Line-height breathe during speaking */
body[data-mode="speaking"] .msg-body { line-height:1.62; transition:line-height .6s var(--ease-out); }

/* #66 Letter-spacing expand during thinking */
body[data-mode="thinking"] #zsh-status { letter-spacing:.32em; }

body[data-tts-loading="true"] canvas { filter: none; }

/* FA75 copy button */
.message.assistant .msg-copy { position:absolute; top:4px; right:6px; background:none; border:none; color:var(--face-dim); cursor:pointer; font:12px/1.5 var(--font-label); opacity:0; transition:opacity .15s; padding:8px; min-width: var(--tap-min); min-height: var(--tap-min); }
.message.assistant:hover .msg-copy,
.message.assistant:focus-within .msg-copy { opacity:1; }
.message.assistant .msg-copy:hover { color:var(--c-text); }

.message.assistant .msg-actions {
  position: absolute;
  top: 3px;
  inset-inline-end: 28px;
  display: flex;
  gap: 2px;
  opacity: .42;
  transition: opacity .15s;
}

.message.assistant:hover .msg-actions,
.message.assistant:focus-within .msg-actions {
  opacity: 1;
}

.message.assistant .msg-actions button {
  background: none;
  border: 0;
  color: var(--face-dim);
  cursor: pointer;
  font: 12px/1.5 var(--font-label);
  padding: 8px 10px;
  min-width: var(--tap-min);
  min-height: var(--tap-min);
}

.message.assistant .msg-actions button:hover {
  color: var(--c-text);
}

.face-error-banner {
  position: fixed;
  inset-inline: var(--chrome-inset);
  top: var(--inset-t);
  z-index: var(--z-toast);
  padding: 10px 12px;
  border: 1px solid var(--border-strong);
  background: color-mix(in srgb, var(--face-bg) 88%, transparent);
  color: var(--face-fg);
  font: 14px/1.5 var(--font-label);
  border-radius: var(--radius-md);
  pointer-events: none;
}

::selection { background: color-mix(in srgb, var(--c-danger) 22%, transparent); color: inherit; }

.tool { background:none; border:0; color:var(--face-muted); font:inherit; padding:10px 8px; margin-inline-end:6px; cursor:pointer; letter-spacing:.02em; opacity:.6; transition:opacity .15s,color .15s; min-width: var(--tap-min); min-height: var(--tap-min); }
.tool:hover, .tool:focus { opacity:1; color:var(--face-fg); }
.tool.active { color:var(--c-accent); opacity:1; }

#ascii-star { position: fixed; top: calc(48px + var(--safe-top)); left: 14px; font: 600 22px/1 var(--font-label); color: var(--face-fg); mix-blend-mode: difference; pointer-events: none; z-index: calc(var(--z-chrome) - 1); transition: color 220ms var(--ease-linear); }

.compaction-note,
.btw-note,
.message.system {
  font: 14px/1.5 var(--font-label);
  color: var(--face-muted);
  padding: 6px 0 2px 2px;
  border-inline-start: 2px solid var(--border-strong);
  margin: 4px 0;
}

.compaction-title { font-size: 12px; text-transform: uppercase; letter-spacing: 0.08em; opacity: 0.6; margin-bottom: 4px; }
.compaction-body { white-space: pre-wrap; font-size: 14px; line-height: 1.5; max-height: 160px; overflow: auto; }

.message.msg-phantom .msg-body {
  text-decoration: line-through;
  text-decoration-color: color-mix(in srgb, var(--c-danger) 40%, transparent);
}

body[data-phantom-glitch="1"] canvas {
  filter: contrast(1.2) hue-rotate(8deg);
  transition: filter 120ms steps(3, end);
}

.tool-stack {
  font: 10px/1.35 var(--font-label);
  color: var(--face-dim);
  margin-bottom: 4px;
}

.tool-stack summary { cursor: pointer; list-style: none; }
.tool-stack summary::before { content: "▸ "; }
.tool-stack[open] summary::before { content: "▾ "; }

.pipeline-stage {
  display: none;
}

#chat-history-panel {
  position: fixed;
  top: var(--inset-t);
  inset-inline-start: var(--inset-l);
  bottom: calc(52px + var(--safe-bottom));
  width: min(320px, calc(100vw - 24px - var(--safe-left) - var(--safe-right)));
  z-index: calc(var(--z-toast) + 100);
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 10px 12px;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-md);
  background: color-mix(in srgb, var(--face-bg) 92%, transparent);
  color: var(--face-fg);
  transform: translateX(calc(-100% - 18px));
  opacity: 0;
  pointer-events: none;
  contain: layout style paint;
  transition: transform 220ms var(--ease-out), opacity 180ms var(--ease-out);
}

#chat-history-panel[data-open="1"] {
  transform: translateX(0);
  opacity: 1;
  pointer-events: auto;
}

.history-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}

.history-title {
  font: 10px/1 var(--font-label);
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--face-muted);
}

#history-close {
  background: none;
  border: 0;
  color: var(--face-muted);
  font: 16px/1 var(--font-label);
  cursor: pointer;
  padding: 2px 6px;
  min-width: var(--tap-min);
  min-height: var(--tap-min);
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

#history-search {
  width: 100%;
  background: transparent;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-sm);
  color: inherit;
  font: 11px/1.4 var(--font-label);
  padding: 6px 8px;
}

#history-list {
  list-style: none;
  margin: 0;
  padding: 0;
  overflow: auto;
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

#history-list li {
  display: grid;
  grid-template-columns: 42px 1fr;
  gap: 6px;
  padding: 6px 4px;
  border-radius: var(--radius-sm);
  cursor: pointer;
  content-visibility: auto;
  contain-intrinsic-size: auto 48px;
  transition: background 120ms var(--ease-out);
}

#history-list li:hover {
  background: var(--hover-tint);
}

.history-role {
  font: 9px/1.3 var(--font-label);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--face-dim);
}

.history-body {
  font: 11px/1.35 var(--font-label);
  color: color-mix(in srgb, var(--c-text) 78%, transparent);
  overflow: hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
}

body[data-history-open="1"] #chat-log {
  margin-inline-start: min(332px, calc(100vw - 24px));
  transition: margin-left 220ms var(--ease-out);
}

/* Family skip-link: hard-hide until focus (same contract as RAILS _shell.scss). */
.skip-link {
  position: fixed;
  inset-block-start: calc(var(--chrome-inset, 0.75rem) + var(--safe-top, 0px));
  inset-inline-start: calc(var(--chrome-inset, 0.75rem) + var(--safe-left, 0px));
  z-index: var(--z-skip);
  padding: 0.5rem 0.75rem;
  min-height: var(--tap-min, 44px);
  display: inline-flex;
  align-items: center;
  background: #000;
  color: var(--face-fg);
  border: 1px solid var(--border-strong);
  border-radius: 0;
  font: 10px/1 var(--font-label);
  text-decoration: none;
  width: 1px;
  height: 1px;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  clip-path: inset(50%);
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
}

.skip-link:focus,
.skip-link:focus-visible {
  width: auto;
  height: auto;
  margin: 0;
  overflow: visible;
  clip: auto;
  clip-path: none;
  white-space: normal;
  opacity: 1;
  pointer-events: auto;
  outline: 2px solid var(--c-accent);
  outline-offset: 2px;
}

.debug-panel {
  position: fixed;
  inset-inline-start: var(--inset-l);
  bottom: calc(56px + var(--safe-bottom));
  z-index: var(--z-ui);
  padding: 6px 8px;
  background: color-mix(in srgb, #000 88%, transparent);
  border: 1px solid var(--border-soft);
  font: 9px/1.35 var(--font-label);
  color: var(--face-muted);
  pointer-events: none;
}

.stream-retry {
  margin-inline-start: 8px;
  background: transparent;
  border: 1px solid var(--border-strong);
  color: var(--face-fg);
  font: inherit;
  padding: 2px 8px;
  cursor: pointer;
}

.log-search {
  width: 100%;
  margin-bottom: 6px;
  background: transparent;
  border: 1px solid var(--border-soft);
  color: var(--face-fg);
  font: 11px var(--font-label);
  padding: 6px 8px;
}

.msg-collapse summary {
  cursor: pointer;
  font: 10px var(--font-label);
  color: var(--face-dim);
  margin-bottom: 4px;
}

body.face-loading::before {
  content: '';
  position: fixed;
  inset: 0;
  background: #000;
  opacity: 0.35;
  pointer-events: none;
  z-index: 2;
}

body[data-runtime-profile="crt"] canvas {
  filter: contrast(1.08) brightness(1.04) saturate(0.96);
  image-rendering: pixelated;
}
body[data-runtime-profile="crt"] #cognition-ecology {
  opacity: 0.88;
}

/* canvas-fx overlay tier: sits above raw canvas(0/1/2), below persistent chrome(--z-chrome/10) — loading-dither(2) < council-multi-face(3) < council-persona-badge(4) */
.council-persona-badge {
  position: fixed;
  top: 12%;
  inset-inline-start: 50%;
  transform: translateX(-50%);
  padding: 4px 10px;
  font: 11px/1.2 var(--font-label);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--face-fg) 82%, transparent);
  background: color-mix(in srgb, var(--face-bg) 55%, transparent);
  border: 1px solid color-mix(in srgb, var(--face-fg) 18%, transparent);
  pointer-events: none;
  z-index: 4;
  opacity: 0;
  transition: opacity 180ms var(--ease-out);
}
.council-persona-badge[data-visible="1"] { opacity: 1; }
.council-persona-badge[data-lane="left"] { left: 28%; transform: none; }
.council-persona-badge[data-lane="right"] { left: auto; right: 28%; transform: none; }

.sound-on-chip {
  position: fixed;
  top: calc(var(--inset-t) + 36px);
  inset-inline-end: var(--inset-r);
  z-index: var(--z-ui);
  padding: 4px 8px;
  border: 1px solid var(--border-faint);
  border-radius: var(--radius-pill);
  background: #000;
  color: var(--face-muted);
  font: 9px/1 var(--font-label);
  letter-spacing: .12em;
  text-transform: uppercase;
  cursor: pointer;
  opacity: .72;
}
.sound-on-chip:hover,
.sound-on-chip:focus-visible {
  opacity: 1;
  color: var(--face-fg);
}

.council-multi-face {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 3;
  opacity: 0;
  transition: opacity 180ms var(--ease-out);
}
.council-multi-face[data-visible="1"] { opacity: 1; }
.council-multi-face .council-lane {
  position: absolute;
  top: 22%;
  width: 14px;
  height: 14px;
  margin-inline-start: -7px;
  border-radius: 50%;
  border: 1px solid color-mix(in srgb, var(--face-fg) 35%, transparent);
  background: color-mix(in srgb, var(--face-fg) 8%, transparent);
  transform: scale(0.85);
  transition: transform 220ms var(--ease-out), opacity 220ms var(--ease-out);
}
.council-multi-face .council-lane[data-active="1"] {
  transform: scale(1.15);
  background: color-mix(in srgb, var(--face-fg) 22%, transparent);
}
.council-multi-face .council-lane.pulse { animation: council-lane-pulse 0.9s var(--ease-out); }
@keyframes council-lane-pulse {
  0% { transform: scale(0.9); opacity: 0.6; }
  45% { transform: scale(1.35); opacity: 1; }
  100% { transform: scale(1); opacity: 0.85; }
}

.virtual-spacer { width: 100%; pointer-events: none; flex-shrink: 0; }

#face { touch-action: manipulation; min-height: 44vh; }

.emotional-timeline {
  position: fixed;
  inset-inline-start: 8px;
  inset-inline-end: 8px;
  bottom: 92px;
  height: 6px;
  display: flex;
  gap: 2px;
  align-items: flex-end;
  pointer-events: none;
  z-index: 3;
  opacity: 0.55;
}
.emotional-timeline span {
  flex: 1;
  min-width: 3px;
  background: color-mix(in srgb, var(--face-fg) 35%, transparent);
}

@media print {
  canvas, #cognition-ecology, #primer, #zsh, .face-controls, .ui-status, #chat-history-panel, .skip-link { display: none !important; }
  body { background: #fff; color: #000; }
  #chat-log { position: static; max-height: none; overflow: visible; opacity: 1; }
  .message { break-inside: avoid; color: #000; }
}

/* wscons aesthetic — flat 80-column scrollback log (MASTER_AESTHETIC=wscons) */
html[data-aesthetic="wscons"],
body.wscons-mode {
  --c-text: #63c363;
  --x-text: #63c363;
  --face-phosphor-decay: 0;
  --radius-xs: 0;
  --radius-sm: 0;
  --radius-md: 0;
  --radius-lg: 0;
  --radius-pill: 0;
}

html[data-aesthetic="wscons"] body,
body.wscons-mode {
  font-family: var(--font-mono);
  font-size: 16px;
  line-height: 1.5;
  -webkit-font-smoothing: auto;
}

html[data-aesthetic="wscons"] #zsh,
html[data-aesthetic="wscons"] #chat-log,
body.wscons-mode #zsh,
body.wscons-mode #chat-log {
  max-width: 80ch;
  border-radius: 0;
}

html[data-aesthetic="wscons"] #face-phosphor-trail,
body.wscons-mode #face-phosphor-trail {
  display: none !important;
}

/* UI_REFINEMENTS pass — face chrome only; does not touch WebGL boot path */
#primer {
  display: grid;
  place-items: center;
  gap: 0.75rem;
  text-align: center;
  color: var(--face-fg);
  font-family: var(--font-mono, ui-monospace, monospace);
}
#primer-title {
  font-weight: 400;
  letter-spacing: 0.08em;
  text-transform: lowercase;
}
#primer .tagline,
.primer-consent {
  color: var(--face-muted);
  max-width: 28rem;
  font-size: var(--hud-lg); /* joined the HUD ramp; was 0.85rem (13.6px) */
}
#hud-tier-status,
#hud-tier-caption,
.hud-tier-status,
.hud-tier-caption {
  border-top: 1px solid var(--border-faint);
}
.hud-tier-caption,
#hud-tier-caption {
  max-width: 66ch;
}
#chat-input,
.chat-input,
textarea.chat-input {
  border-top: 1px solid var(--border-faint);
  caret-color: var(--c-accent);
  font-family: var(--font-mono, ui-monospace, monospace);
}
#face-canvas,
canvas#face,
[data-face-canvas] {
  outline: none;
}
.face-bar button,
.face-bar a,
.bar-btn {
  min-width: var(--tap-min);
  min-height: var(--tap-min);
}
#push-enable-btn,
.permission-prompt button {
  font-family: var(--font-mono, ui-monospace, monospace);
  border-radius: 0;
  border: 1px solid var(--border-strong);
  background: transparent;
  color: var(--face-fg);
  min-height: var(--tap-min);
  padding: 0 1rem;
}

/* The wordmark the three RAILS apps carry, saying which host this is.
   Same markup and class names as shared/_brand_mark so the two surfaces read
   as one family; the tokens are this surface own, because face.css has its
   own palette and z-scale and reaching for brgen would name variables that do
   not exist here. Type only: no chip, no border, no background.

   width: fit-content and inset-inline-end: auto together are what stop a fixed
   box spanning the viewport — without them the whole top strip becomes a link
   home and swallows taps on everything up there. */
.brand-mark {
  position: fixed;
  z-index: var(--z-chrome);
  top: calc(var(--chrome-inset) + var(--safe-top));
  inset-inline-start: calc(var(--chrome-inset) + var(--safe-left));
  inset-inline-end: auto;
  width: fit-content;
  display: inline-flex;
  align-items: center;
  min-height: var(--tap-min);
  /* 0.25rem both ways. The inline value was 0.35rem, which is 5.6px at a
     16px root and the exact case design_tokens.yml documents: a sub-grid
     fraction landing on a fractional device pixel, which the browser
     antialiases. Nearest declared step is 4px, which the block value already
     was. */
  padding: 0.25rem;
  /* 800 is brgen's --weight-heavy. The literal 700 here was the other half of
     the mismatch: monospace at 700 beside a sans at 800 reads as two brands. */
  font: 800 clamp(0.9375rem, 2.8vw, 1.125rem) / 1 var(--font-brand);
  letter-spacing: -0.03em;
  color: var(--c-text);
  text-decoration: none;
  text-rendering: optimizeLegibility;
}

.brand-text {
  text-transform: none;
  letter-spacing: -0.03em;
}
