/* 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: "Helvetica Neue Pro", "Helvetica Neue", Arial, sans-serif;
  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 oklch, var(--c-text) 81%, black);
  --face-dim: color-mix(in srgb, var(--c-text) 18%, transparent);
  --face-soft: color-mix(in srgb, var(--c-text) 8%, transparent);
  --face-alert: color-mix(in oklch, var(--c-danger) 75%, white);
  --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;
  --text-meta: 0.8125rem;
  --text-title: 1.25rem;
  --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));
  --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. The wordmark
   names its face as the brand, and the brand is the one sans family the owner
   set for every surface, so it reads --font-label rather than restating the
   stack. Helvetica Neue Pro is licensed per seat and cannot ship as a webfont;
   the stack names it where it is installed and falls to Helvetica Neue, then
   Arial, which is metrically identical, and downloads nothing. */
:root {
  --font-brand: var(--font-label);
}

html, body {
  height: 100%;
  background: var(--face-bg);
  color: var(--face-fg);
  font: 16px/1.5 var(--font-label);
  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; }

@media (prefers-contrast: more) {
  :root {
    --face-muted: var(--face-fg);
    --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-log,
body[data-focus-mode="1"] #ascii-star,
body[data-focus-mode="1"] #spin-btn {
  opacity: 0;
  pointer-events: none;
}

/* Here as well as in chat_upload.css, which loads late and can miss: the
   tap floor (LAYOUT_RULES.touch) must not wait on a deferred stylesheet. */
#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;
}

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-mono);
  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-mono);
  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: var(--text-meta);
  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: 2px; /* clamps to 1.5px on this 3x4px span — the pill idiom, on scale */
  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(--font-brand);
  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: var(--text-meta)/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: var(--text-meta)/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: var(--text-meta)/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; }

[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 var(--font-label);
  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: var(--face-muted); 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: 1rem/1.5 var(--font-mono);
  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) 22%, transparent); border-radius: 4px; }

#chat-log:not(:empty) { pointer-events: auto; }
/* TYPOGRAPHY.line_length: a reply is prose, 45–75ch, whatever the viewport. */
.message { position:relative; max-inline-size: 66ch; 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; }
.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); }
@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: var(--text-meta)/1.25 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: var(--text-meta)/1.25 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-label);
  font-size: var(--text-meta);
  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: 66ch;
}
body.mission-control h1 {
  font-size: var(--text-title, 1.25rem);
  font-weight: 600;
  margin: 0;
}
/* Mission control reads as one scrollback, the way dmesg does: sections one
   under another in an 80-column measure, space between them rather than boxes
   around them (UI_POLISH.space_not_lines), and each section named in lowercase
   by brightness rather than tracked capitals (TYPOGRAPHY_DISCIPLINE). */
body.mission-control .grid {
  display: block;
  max-inline-size: 80ch;
}
body.mission-control .panel {
  margin-block-end: 24px;
}
body.mission-control .panel h2 {
  font-size: var(--text-meta);
  font-weight: 400;
  color: var(--face-muted);
  margin-bottom: 4px;
}
body.mission-control pre {
  font-family: var(--font-mono);
  white-space: pre-wrap;
  word-break: break-word;
}
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: var(--text-meta)/1.25 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; }

.fps-badge {
  position: fixed;
  top: var(--inset-t);
  inset-inline-start: var(--inset-l);
  z-index: var(--z-ui);
  font: var(--text-meta)/1.25 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: var(--keyboard-inset, 0px);
  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-mono);
  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%);
}

/* The ghost is for the prompt before it goes live. The log is what MASTER
   said, and TYPOGRAPHY.accessibility asks 7:1 of it, which no opacity under
   one can give. */
body.zen #zsh { 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: var(--text-meta); }
#shortcut-sheet kbd { font-family: inherit; opacity: 0.85; }
.tool-diff pre.diff-body { font-size: var(--text-meta); 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;
  background: transparent;
}
body #zsh.live:focus-within {
  opacity: 1;
  background: black;
}
#zsh .pp { color: var(--face-alert); 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: var(--face-muted); }
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: var(--text-meta)/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); }
/* The reply is synthesized and waiting on the gesture the browser needs before
   it will play sound. The element's textContent is cleared on every mode
   change, so the line is printed from the attribute instead. */
body[data-tts-blocked="1"] #zsh-status::after { content: attr(data-blocked-label); opacity: 1; }

/* 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; } }

/* One column, ragged right (LAYOUT_RULES.alignment). The you$ and master$
   prefixes already say who speaks, so the side of the screen does not have to. */
.message.user { border:0; 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-mono); 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: var(--text-meta); 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; }

/* #42 Edge hover reveal */
body[data-edge-hover="1"] #zsh,
body[data-edge-swipe="1"] #zsh { opacity: .96; pointer-events: auto; transform: 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} }

/* A long silence dims the ecology; the face goes quiet rather than asking. */
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(--text-meta);
  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: var(--text-meta)/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: var(--text-meta)/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.6; 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; }

.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: var(--text-meta)/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 var(--text-title)/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,
.message.system {
  font: var(--text-meta)/1.5 var(--font-mono);
  color: var(--face-muted);
  padding: 6px 0 2px 2px;
  border-inline-start: 2px solid var(--border-strong);
  margin: 4px 0;
}

.compaction-title { font-size: var(--text-meta); text-transform: uppercase; letter-spacing: 0.08em; opacity: 0.6; margin-bottom: 4px; }
.compaction-body { white-space: pre-wrap; font-size: var(--text-meta); 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: var(--text-meta)/1.4 var(--font-mono);
  color: var(--face-muted);
  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: var(--text-meta)/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: 1rem/1.5 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: var(--text-meta)/1.25 var(--font-label);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--face-muted);
}

.history-body {
  font: var(--text-meta)/1.4 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: var(--text-meta)/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: var(--text-meta)/1.4 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: 1rem/1.5 var(--font-mono);
  padding: 6px 8px;
}

.msg-collapse summary {
  cursor: pointer;
  font: var(--text-meta) var(--font-mono);
  color: var(--face-muted);
  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: var(--text-meta)/1.25 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: var(--text-meta)/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-label);
}
#primer-title {
  font-weight: 400;
  text-transform: lowercase;
}
#primer .tagline,
.primer-consent {
  color: var(--face-muted);
  max-width: 28rem;
  font-size: var(--text-meta);
}
#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-label);
  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. */
/* Portrait take: only the field. The mark and the prompt are chrome, and a
   recording of the face is a recording of the field. */
body[data-portrait="1"] .brand-mark,
body[data-portrait="1"] .top-left-logo,
body[data-portrait="1"] #zsh,
body[data-portrait="1"] #mic-dot,
body[data-portrait="1"] #chat-log,
body[data-portrait="1"] .face-controls,
body[data-portrait="1"] #primer,
body[data-portrait="1"] #tts-live,
body[data-portrait="1"] .skip-link,
body[data-portrait="1"] #ascii-star {
  display: none !important;
}

.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;
}
