/* Terminal skin — structure, type and effects.
   See docs/TERMINAL-SKIN-SPEC.md for the approved design.

   This is a SKIN FLAG on top of the colour system, not a replacement for it:

     <html data-skin="terminal" data-phos="mint">

   With data-skin absent (or "normal") the app looks exactly as it does today,
   so the whole thing reverts by removing one attribute.

   Deliberately NO colour tokens in here. appearance.js applies palettes as
   INLINE custom properties on <html>, and an inline property beats any
   stylesheet rule regardless of selector — so a --accent set here would be
   silently ignored the moment a theme loaded. The five phosphor palettes live
   in appearance.js beside the other themes and travel the same code path; this
   file owns only what a palette can't express.

   Part of the split style sheet — see index.html for the link order. */

/* ---------- Structure: sharp corners, monospace, flat surfaces ---------- */
:root[data-skin="terminal"] {
  --radius-sm: 2px;
  --radius-md: 2px;
  --radius-card: 3px;

  --font-body: var(--font-mono);
  --font-display: var(--font-mono);

  /* A hairline highlight plus a deep drop, instead of the soft ambient shadow.
     Glow, not lift. */
  --shadow-sm: 0 0 0 1px rgba(255, 255, 255, 0.03);
  --shadow-md: 0 0 0 1px rgba(255, 255, 255, 0.03), 0 12px 34px rgba(0, 0, 0, 0.7);
  --shadow-hover: 0 0 0 1px rgba(255, 255, 255, 0.05), 0 16px 44px rgba(0, 0, 0, 0.8);

  /* Frosted glass reads as a phone OS, not a terminal. Flatten it — panels
     become solid surfaces with a hard rule. */
  --glass-bg: var(--surface);
  --glass-border: var(--rule);
  --glass-blur: 0px;

  --term-tracking: 0.02em;
  --term-scan: repeating-linear-gradient(
    to bottom,
    rgba(255, 255, 255, 0.022) 0 1px,
    transparent 1px 3px
  );
  --term-glow: 0 0 14px color-mix(in srgb, var(--accent) 45%, transparent);
}

:root[data-skin="terminal"] body {
  letter-spacing: var(--term-tracking);
  /* The default body paints two radial accent washes. They fight a CRT
     ground, so terminal replaces the whole stack with flat paper. A custom
     background image still wins — that's the user's own choice. */
  background: var(--paper);
}

:root[data-skin="terminal"] body.has-custom-bg {
  background-size: cover;
  background-position: center;
  background-attachment: fixed;
}

/* Backdrop-filter is set directly on the panel classes in tokens.css, so the
   --glass-blur override above isn't enough on its own. */
:root[data-skin="terminal"] .glass-panel,
:root[data-skin="terminal"] .sidebar,
:root[data-skin="terminal"] .detail-pane,
:root[data-skin="terminal"] .task-item,
:root[data-skin="terminal"] .modal,
:root[data-skin="terminal"] .source-card,
:root[data-skin="terminal"] .field-row,
:root[data-skin="terminal"] .thread-frame-wrap {
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}

/* Body copy stays the calm off-white the palette sets — the phosphor is spent
   on chrome, labels and state. People compose paragraphs in the comment box,
   and bright phosphor on prose is fine to glance at and tiring to write in. */
:root[data-skin="terminal"] textarea {
  font-family: var(--font-mono);
}

/* Native checkboxes, radios and range thumbs render in the browser's own blue
   unless told otherwise, which is the one thing on screen that never got the
   memo about the phosphor. One line fixes every control in the app. */
:root[data-skin="terminal"] {
  accent-color: var(--accent);
}

/* The modal backdrop keeps its dim but loses the blur, for the same reason the
   panels did: a frosted pane reads as a phone OS. A hard dim is what a
   terminal would do — and it's cheaper to composite. */
:root[data-skin="terminal"] .modal-overlay {
  background: rgba(0, 0, 0, 0.62);
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}

/* Uppercase mono labels are the skin's main typographic move. */
:root[data-skin="terminal"] .sidebar-label,
:root[data-skin="terminal"] .section-label {
  text-transform: uppercase;
  letter-spacing: 0.12em;
  font-size: 9.5px;
}

/* ---------- Effect 1: scanlines ----------
   A fixed full-viewport overlay. pointer-events:none so it never eats a
   click, and it sits under modals rather than over them. */
:root[data-skin="terminal"][data-fx-scan="on"] body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 9;
  pointer-events: none;
  background: var(--term-scan);
}

/* ---------- Effect 2: blinking cursor ----------
   A block cursor on the current view, the way a shell marks where you are. */
:root[data-skin="terminal"][data-fx-cursor="on"] .nav-item.active::after {
  content: "";
  width: 7px;
  height: 13px;
  margin-left: auto;
  background: var(--accent);
  box-shadow: var(--term-glow);
  animation: term-blink 1.1s steps(1) infinite;
}

:root[data-skin="terminal"][data-fx-cursor="on"] .nav-item.active {
  display: flex;
  align-items: center;
  gap: 8px;
}

@keyframes term-blink {
  0%, 49% { opacity: 1; }
  50%, 100% { opacity: 0; }
}

/* ---------- The status strip ----------
   Terminal skin and admins only. The [hidden] attribute is set by JS for the
   admin half; this rule is the skin half. Both must be true.

   Everything on it is something that currently fails SILENTLY: backups can
   stop working and look identical to working, and a cache that stopped
   answering doesn't announce itself. */
.term-strip { display: none; }

:root[data-skin="terminal"] .term-strip:not([hidden]) {
  display: flex;
  gap: 16px;
  align-items: center;
  flex-wrap: wrap;
  margin-bottom: 13px;
  padding: 8px 12px;
  border: 1px solid var(--rule);
  border-radius: var(--radius-sm);
  background: var(--surface);
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

.term-strip b {
  font-weight: 600;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
}

/* A number that has gone wrong shouldn't wear the same colour as one that
   hasn't — the accent means "fine", the warn colour means "look at this". */
.term-strip b.is-warn { color: var(--gold); }
.term-strip b.is-bad { color: var(--danger); }

.term-strip-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  display: inline-block;
  margin-right: 6px;
  background: var(--accent);
  box-shadow: var(--term-glow);
}

.term-strip-dot.is-bad { background: var(--danger); box-shadow: none; }
.term-strip-gap { flex: 1; }

/* The activity feed is not terminal-only, but under the skin it should read as
   a log rather than a card: solid surface, hard rule, monospace throughout. */
:root[data-skin="terminal"] .activity-panel {
  background: var(--surface-2);
  border-color: var(--rule);
}

:root[data-skin="terminal"] .activity-head { border-color: var(--rule); }

:root[data-skin="terminal"] .activity-item {
  font-family: var(--font-mono);
  font-size: 10.5px;
}

/* ---------- Effect 3: the system status panel ----------
   Lives in the sidebar gap between the nav and the footer. */
.term-status {
  display: none;
}

:root[data-skin="terminal"][data-fx-spider="on"] .term-status {
  display: block;
  margin: 14px 0 4px;
  border: 1px solid var(--rule);
  border-radius: var(--radius-card);
  background: var(--surface-2);
  overflow: hidden;
  /* Sits last among the sidebar's panels, so it was the one that lost its
     height first when "Needs your attention" appeared above it — the spider
     disappeared exactly when there was a problem to look at. See
     .attention-panel in layout.css. */
  flex-shrink: 0;
}

.term-status-head {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 7px 9px;
  border-bottom: 1px solid var(--rule);
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-muted);
}

.term-status-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  flex: none;
  background: var(--accent);
  box-shadow: var(--term-glow);
}

.term-status-body {
  padding: 8px 9px 9px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.term-status-state {
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.09em;
  color: var(--accent);
}

/* The canvas scales to the panel; image-rendering keeps the 3px cells crisp
   rather than resampling them into mush at fractional widths. */
.term-spider {
  display: block;
  width: 100%;
  height: auto;
  image-rendering: pixelated;
  cursor: crosshair;
}

.term-status-foot {
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-muted);
}

.term-status-foot b {
  font-weight: 400;
  color: var(--ink-soft);
  font-variant-numeric: tabular-nums;
}

/* ---------- The inverted-slab problem ----------
   Three places paint `background: var(--ink); color: var(--paper)` to get a
   high-contrast inverted block. That works in every normal theme, where --ink
   is near-black. Under terminal --ink is a near-WHITE off-white, so each one
   becomes the single brightest object on a very dark screen — a white slab in
   a phosphor terminal.

   They aren't bugs in those files; the assumption was reasonable until this
   skin existed. Each gets the treatment its role deserves instead. */

/* Selected filter: the accent, which is what the mockup used for selection. */
:root[data-skin="terminal"] .filter-btn.active {
  background: var(--accent);
  color: var(--accent-contrast);
  border-color: var(--accent);
  font-weight: 700;
}

/* Toast: a bordered surface that glows, not a white pill. */
:root[data-skin="terminal"] .ctt-toast {
  background: var(--surface);
  color: var(--ink);
  border: 1px solid var(--accent);
  border-radius: var(--radius-sm);
  box-shadow: var(--term-glow), var(--shadow-md);
}

/* The generated Work Log summary is the worst of the three — a full-width
   block of text. It's output, so it reads as a terminal pane. */
:root[data-skin="terminal"] pre.wl-out {
  background: var(--surface-2);
  color: var(--ink);
  border: 1px solid var(--rule);
}

/* The light/dark button is disabled under terminal — all five phosphors are
   dark and the light ramp has nowhere to put a glow. Make that visible rather
   than leaving a button that looks live and does nothing. */
:root[data-skin="terminal"] .btn-ghost:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

/* ---------- Motion restraint ----------
   Infinite animations keep the compositor awake and cost laptop battery, so
   they stop when the tab is hidden as well as when motion is unwelcome. The
   spider's own loop is stopped in JS; this covers the CSS animations. */
:root.term-hidden .nav-item.active::after {
  animation-play-state: paused;
}

@media (prefers-reduced-motion: reduce) {
  :root[data-skin="terminal"] .nav-item.active::after {
    animation: none;
  }
}

/* The comment editor, under the skin: the box glows when focused rather than
   carrying a soft ring, and the toolbar reads as chrome. Body text stays the
   calm off-white the palette sets — this is the one place people write
   paragraphs, and bright phosphor on prose is tiring to compose in. */
:root[data-skin="terminal"] .rt-editor {
  background: var(--surface-2);
  border-color: var(--rule);
}

:root[data-skin="terminal"] .rt-editor:focus-within {
  border-color: var(--accent);
  box-shadow: var(--term-glow);
}

:root[data-skin="terminal"] .rt-bar { border-color: var(--rule); }

:root[data-skin="terminal"] .rt-btn {
  font-family: var(--font-mono);
}
