/* © 2026 William C. Chesher. All Rights Reserved. */
/* alpha.css - Mission Alpha's design system: the tokens (Night, Day, the night frame), then the al-* components */

/* No build step, no framework. Link it after launch.css or alone; every name is prefixed (--al-*, .al-*), so the two
   never collide. Spec: /mnt/project-files/launch/design/alpha-design-system.md.

   The idea, in three lines:
     Regolith, not graphite. Launch is a clean factory floor; Alpha is the same world after the dust got in: warm greys,
       a crater black, and one warm light, the lamp, which is ignition orange because it is the same orange as
       H.A.L.'s lens and P1's status light (mission-alpha.md section 11). Earthshine, a cold blue, is the link home.
     Two voices. The machine speaks in mono and condensed capitals (tiles, logs, readings, the HUD); people speak in a
       serif (conversation, the journal, notes on tiles, act titles). A note on a tile is a person, so it is serif.
     The Moon is still. Nothing moves for atmosphere. What moves means something: a trace playing, brackets closing
       on what you are looking at, the lamp. Under reduced motion even the lamp holds steady.

   Night always, whatever the computer prefers; Day only when the student chooses it (data-theme="day" on <html>,
   painted by the server as for launch). The shell's Motion setting is :root.is-still; the computer's own setting
   is honoured too, for a page that runs without the shell. Every colour below is a token: do not invent hues. */

/* ==================================================================================================
   1. Fonts: self-hosted, latin only, the faces in use. The four launch files are shared, so a student who has
   played launch has them cached; IBM Plex Serif is Alpha's own (the people's voice). Licences beside them.
   ================================================================================================== */
@font-face { font-family: "Barlow"; font-style: normal; font-weight: 400; font-display: swap; src: url("../fonts/barlow-400.woff2") format("woff2"); }
@font-face { font-family: "Barlow"; font-style: normal; font-weight: 600; font-display: swap; src: url("../fonts/barlow-600.woff2") format("woff2"); }
@font-face { font-family: "Barlow Condensed"; font-style: normal; font-weight: 600; font-display: swap; src: url("../fonts/barlow-condensed-600.woff2") format("woff2"); }
@font-face { font-family: "JetBrains Mono"; font-style: normal; font-weight: 100 800; font-display: swap; src: url("../fonts/jetbrains-mono.woff2") format("woff2"); }
@font-face { font-family: "IBM Plex Serif"; font-style: normal; font-weight: 400; font-display: swap; src: url("../fonts/ibm-plex-serif-400.woff2") format("woff2"); }
@font-face { font-family: "IBM Plex Serif"; font-style: italic; font-weight: 400; font-display: swap; src: url("../fonts/ibm-plex-serif-400-italic.woff2") format("woff2"); }

/* ==================================================================================================
   2. Tokens
   ================================================================================================== */
:root {
  /* Type: four families, two voices */
  --al-font-stencil: "Barlow Condensed", "Arial Narrow", system-ui, sans-serif;     /* the machine's capitals: buttons, HUD, stamps */
  --al-font-body: Barlow, system-ui, -apple-system, "Segoe UI", sans-serif;          /* interface prose, the player's own choices */
  --al-font-mono: "JetBrains Mono", ui-monospace, Consolas, Menlo, monospace;        /* tiles, logs, readings, time */
  --al-font-story: "IBM Plex Serif", Georgia, "Times New Roman", serif;              /* people: lines, the journal, notes, act titles */

  /* Type scale: fluid between 360 and 1920 wide; the 1366 laptop sits in the middle of every clamp */
  --al-text-2xs: 0.6875rem;                                    /* 11px: eyebrows and tape, mono capitals only */
  --al-text-xs: 0.75rem;                                       /* 12px: captions under data, timestamps */
  --al-text-sm: 0.875rem;                                      /* 14px: secondary interface text */
  --al-text-md: 1rem;                                          /* 16px: body, tiles */
  --al-text-lg: clamp(1.0625rem, 1rem + 0.25vw, 1.25rem);      /* 17 to 20px: a spoken line, a journal entry */
  --al-text-xl: clamp(1.25rem, 1.1rem + 0.6vw, 1.75rem);       /* 20 to 28px: panel titles, a speaker's name */
  --al-text-2xl: clamp(1.625rem, 1.3rem + 1.4vw, 2.75rem);     /* 26 to 44px: a place's name */
  --al-text-3xl: clamp(2.25rem, 1.5rem + 3.2vw, 5rem);         /* 36 to 80px: act titles, the cold open */
  --al-leading-tight: 1.1;
  --al-leading-ui: 1.4;
  --al-leading-story: 1.55;
  --al-tracking-stencil: 0.14em;
  --al-tracking-mono: 0.2em;
  --al-measure: 62ch;

  /* Space: a 4px base, eight steps */
  --al-space-1: 4px;
  --al-space-2: 8px;
  --al-space-3: 12px;
  --al-space-4: 16px;
  --al-space-5: 24px;
  --al-space-6: 32px;
  --al-space-7: 48px;
  --al-space-8: 64px;
  --al-gutter: clamp(16px, 2.4vw, 40px);                        /* page side gutter: 16px at 360, 40px at 1920 */

  /* Shape: square, as launch; the bracket is Alpha's corner */
  --al-radius-0: 0px;
  --al-radius-1: 2px;                                           /* tape and chips only */
  --al-line: 1px;
  --al-rule: 2px;
  --al-bracket: 14px;                                           /* the length of a bracket's arm */
  --al-target: 44px;                                            /* the smallest thing a pointer is asked to hit */

  /* Motion: still by default; these are for what means something */
  --al-ease: cubic-bezier(0.2, 0, 0, 1);                        /* machined: launch's ease, shared */
  --al-ease-settle: cubic-bezier(0.16, 1, 0.3, 1);              /* dust settling: long tail, no bounce (no air) */
  --al-dur-tick: 90ms;                                          /* one tile lighting in a trace at Fast */
  --al-dur-quick: 140ms;                                        /* hover, press, a bracket closing */
  --al-dur-ui: 240ms;                                           /* panels, tabs, a topic opening */
  --al-dur-scene: 600ms;                                        /* a place arriving, an act card */
  --al-dur-blink: 2800ms;                                       /* the lamp's cycle */
  --al-light-delay: 1.3s;                                       /* the Moon's one-way light time; the descent's press-to-effect is twice it */

  /* Layers */
  --al-z-place: 0;
  --al-z-hotspot: 10;
  --al-z-hud: 20;
  --al-z-drawer: 30;
  --al-z-alert: 40;
  --al-z-dialog: 50;
  --al-z-player: 60;

  /* Colour, Night (the default) */
  --al-void: #060606;            /* the crater: the floor under video, places and act cards; night in both themes */
  --al-well: #060606;            /* an inset that carries text: code, a log, a readout, the alarm; follows the theme */
  --al-ground: #0d0d0c;          /* the page */
  --al-surface: #151514;         /* panels, cards */
  --al-surface-raised: #1f1e1c;  /* a card on a panel, a selected row */
  --al-hairline: #32302c;        /* dividers; decoration, never the only edge of a control */
  --al-edge: #7a766e;            /* control borders (4.3:1 on ground) */
  --al-text-muted: #a39f96;      /* eyebrows, units, timestamps (7.4:1) */
  --al-text-secondary: #c7c3ba;  /* secondary prose (11:1) */
  --al-text: #ece9e2;            /* text (16:1) */
  --al-flare: #ffffff;           /* focus, the alarm: the brightest thing on screen is never a hue */
  --al-on-flare: #0d0d0c;
  --al-lamp: #ff7a2e;            /* the one warm light (7.5:1 on ground) */
  --al-on-lamp: #0d0d0c;
  --al-lamp-glow: #ff7a2e66;
  --al-lamp-line: #ff7a2ea6;
  --al-lamp-wash: #ff7a2e1a;
  --al-earth: #7fa3c9;           /* earthshine: the link home, the phone, the delay (7.4:1); always beside a word */
  --al-earth-wash: #7fa3c91a;
  --al-dust-1: #f2e6d608;        /* regolith dust: the faintest warm lift, for hover and wells */
  --al-dust-2: #f2e6d612;
  --al-dust-3: #f2e6d624;
  --al-tape: #d8cdb9;            /* gaffer and label tape: a paper strip, text on it is --al-on-tape */
  --al-on-tape: #1a1814;
  --al-shade: #000000a6;         /* scrims over stills and video */
  --al-scrim-caption: #000000c7; /* the caption band: white on it is 15:1 over any frame */
  --al-shadow-1: 0 1px 0 #f2e6d60f inset, 0 10px 24px -14px #000000d9;
  --al-shadow-2: 0 1px 0 #f2e6d614 inset, 0 24px 56px -18px #000000f2;
  --al-glow-lamp: 0 0 0 1px #ff7a2e8c, 0 0 16px 1px #ff7a2e4d;
  --al-focus: 0 0 0 2px #0d0d0c, 0 0 0 4px #ffffff;  /* a flare ring with a ground gap, legible on any frame */
  /* Grain: one 120px tile of noise, drawn once; laid over stills and panels at a few percent, never over video */
  --al-grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 .95 0 0 0 0 .9 0 0 0 .55 0'/%3E%3C/filter%3E%3Crect width='120' height='120' filter='url(%23n)'/%3E%3C/svg%3E");
  --al-grain-strength: 0.05;

  /* The pictures (board-screen-standard.md, drawn by static/boards/picture.js): a place, night in both themes, so set
     once. wchesher, 2026-10-30: "life is the only saturated colour on the Moon". The minerals are muted across a real
     range of regolith, the ice a cold grey, the printed coils the regolith sintered; only what grows is in colour.
     None of these carries words, and none is ever an alarm: the alarm is the flare, the moment is the lamp. */
  --al-regolith-1: #2a2824;      /* shadowed fines */
  --al-regolith-2: #36332e;
  --al-regolith-3: #43403a;
  --al-regolith-4: #524e46;      /* sunlit highland */
  --al-regolith-5: #67625a;      /* a fresh, bright ejecta fleck */
  --al-ice: #8c9aa2;             /* the floor's frost: cold grey, never a hue */
  --al-sintered: #8a8174;        /* a printed coil */
  --al-glass: #c9d6dc;           /* a pane, drawn faint */
  --al-life: #6dbb45;            /* leaf: lettuce, the young peas */
  --al-life-deep: #3d8a3b;       /* a leaf's shaded side */
  --al-life-fruit: #d4473f;      /* a radish's red shoulder */
  color-scheme: dark;
}

/* Day: the field notebook in daylight. Opt-in only. */
:root[data-theme="day"] {
  --al-ground: #efede7;
  --al-surface: #faf9f6;
  --al-surface-raised: #e4e1d9;
  --al-well: #e8e5de;
  --al-hairline: #cfcbc1;
  --al-edge: #7a756b;
  --al-text-muted: #5a564e;
  --al-text-secondary: #3a3732;
  --al-text: #191815;
  --al-flare: #000000;
  --al-on-flare: #ffffff;
  --al-lamp: #a8460b;
  --al-on-lamp: #ffffff;
  --al-lamp-glow: #a8460b40;
  --al-lamp-line: #a8460bc0;
  --al-lamp-wash: #a8460b14;
  --al-earth: #2b5986;
  --al-earth-wash: #2b598614;
  --al-dust-1: #3a28100a;
  --al-dust-2: #3a281012;
  --al-dust-3: #3a28101f;
  --al-tape: #e9dfc9;
  --al-on-tape: #1a1814;
  --al-shadow-1: 0 1px 0 #ffffff inset, 0 10px 24px -16px #19181540;
  --al-shadow-2: 0 1px 0 #ffffff inset, 0 24px 56px -20px #19181559;
  --al-glow-lamp: 0 0 0 1px #a8460b80, 0 0 12px 1px #a8460b33;
  --al-focus: 0 0 0 2px #efede7, 0 0 0 4px #000000;
  --al-grain-strength: 0.035;
  color-scheme: light;
}

/* The night frame: what is night by nature (the crater, video, a place at night, an act card) stays night on a Day
   page. Same values as Night, emitted again so a Day page can hold a night frame. */
.al-night {
  --al-ground: #0d0d0c;
  --al-surface: #151514;
  --al-surface-raised: #1f1e1c;
  --al-well: #060606;
  --al-hairline: #32302c;
  --al-edge: #7a766e;
  --al-text-muted: #a39f96;
  --al-text-secondary: #c7c3ba;
  --al-text: #ece9e2;
  --al-flare: #ffffff;
  --al-on-flare: #0d0d0c;
  --al-lamp: #ff7a2e;
  --al-on-lamp: #0d0d0c;
  --al-lamp-glow: #ff7a2e66;
  --al-lamp-line: #ff7a2ea6;
  --al-lamp-wash: #ff7a2e1a;
  --al-earth: #7fa3c9;
  --al-earth-wash: #7fa3c91a;
  --al-dust-1: #f2e6d608;
  --al-dust-2: #f2e6d612;
  --al-dust-3: #f2e6d624;
  --al-tape: #d8cdb9;
  --al-on-tape: #1a1814;
  --al-shadow-1: 0 1px 0 #f2e6d60f inset, 0 10px 24px -14px #000000d9;
  --al-shadow-2: 0 1px 0 #f2e6d614 inset, 0 24px 56px -18px #000000f2;
  --al-glow-lamp: 0 0 0 1px #ff7a2e8c, 0 0 16px 1px #ff7a2e4d;
  --al-focus: 0 0 0 2px #0d0d0c, 0 0 0 4px #ffffff;
  --al-grain-strength: 0.05;
  color-scheme: dark;
  color: var(--al-text);
}

/* Stillness: the shell's Motion setting, and the computer's own. Durations collapse; the lamp holds steady. */
:root.is-still {
  --al-dur-tick: 0ms;
  --al-dur-quick: 0ms;
  --al-dur-ui: 0ms;
  --al-dur-scene: 0ms;
}
@media (prefers-reduced-motion: reduce) {
  :root {
    --al-dur-tick: 0ms;
    --al-dur-quick: 0ms;
    --al-dur-ui: 0ms;
    --al-dur-scene: 0ms;
  }
}

/* ==================================================================================================
   3. Base. Opt-in: put .al-page on <body> (or a root) for Alpha's ground and type. Nothing here styles bare tags
   outside an .al-page, so linking alpha.css into a launch page changes nothing until a component asks.
   ================================================================================================== */
.al-page { margin: 0; min-height: 100vh; background: var(--al-ground); color: var(--al-text); font-family: var(--al-font-body);
  font-size: var(--al-text-md); line-height: var(--al-leading-ui); -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility; }
.al-page :where(h1, h2, h3, h4, p, ol, ul, figure, blockquote) { margin: 0; }
.al-page :where(button, input, select, textarea) { font: inherit; color: inherit; }
:where([class^="al-"], [class*=" al-"]) { box-sizing: border-box; }
:where([class^="al-"], [class*=" al-"])::before, :where([class^="al-"], [class*=" al-"])::after { box-sizing: border-box; }

/* Focus: the flare ring, everywhere, the same. Never removed, only restyled. */
:where(.al-page, .al-night) :where(a, button, input, select, textarea, [tabindex]):focus-visible { outline: none; box-shadow: var(--al-focus); }

/* The two voices, and the small parts of each */
.al-eyebrow { font-family: var(--al-font-mono); font-size: var(--al-text-2xs); font-weight: 500; letter-spacing: var(--al-tracking-mono);
  text-transform: uppercase; color: var(--al-text-muted); }
.al-stencil { font-family: var(--al-font-stencil); font-weight: 600; letter-spacing: var(--al-tracking-stencil); text-transform: uppercase; line-height: var(--al-leading-tight); }
.al-mono { font-family: var(--al-font-mono); font-variant-numeric: tabular-nums; }
/* Code is read letter by letter by students learning it: no ligatures (== stays two equals signs). */
:is(.al-mono, .al-code, .al-program, .al-field, .al-strip, .al-inspect, .al-table, .al-bits, .al-eyebrow) { font-variant-ligatures: none; }
.al-story { font-family: var(--al-font-story); font-size: var(--al-text-lg); line-height: var(--al-leading-story); max-width: var(--al-measure); }
.al-title { font-family: var(--al-font-stencil); font-weight: 600; font-size: var(--al-text-xl); letter-spacing: 0.08em; text-transform: uppercase; line-height: var(--al-leading-tight); }
.al-heading { font-family: var(--al-font-story); font-weight: 400; font-size: var(--al-text-2xl); line-height: var(--al-leading-tight); letter-spacing: -0.005em; }
.al-muted { color: var(--al-text-muted); }
/* Readings: a heading in the eyebrow voice over the machine's lines (a site card's What it costs, What it gives). */
.al-readings { display: grid; gap: var(--al-space-1); margin: 0; font-family: var(--al-font-mono); font-size: var(--al-text-sm); line-height: 1.55; color: var(--al-text-secondary); font-variant-ligatures: none; }
.al-readings dt:not(:first-child) { margin-top: var(--al-space-3); }
.al-readings dd { margin: 0; }
.al-sr { position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

/* Grain: regolith dust in the light. One static layer; never over video, never animated. */
.al-grain { position: relative; isolation: isolate; }
.al-grain::after { content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none; background: var(--al-grain); opacity: var(--al-grain-strength); mix-blend-mode: overlay; }

/* ==================================================================================================
   4. Layout
   ================================================================================================== */
.al-stack { display: grid; gap: var(--al-gap, var(--al-space-4)); align-content: start; }
/* A list laid out as a stack is a stack: no browser indent, no markers (the item says its own number). */
:is(ol, ul, dl).al-stack { margin: 0; padding: 0; list-style: none; }
.al-stack > dd { margin: 0; }
.al-cluster { display: flex; flex-wrap: wrap; align-items: center; gap: var(--al-gap, var(--al-space-3)); }
/* A ranked row: its number and name, then its buttons in fixed columns, so Up and Down line up down the list
   whatever the names' widths (town rank and queue cards). */
.al-rank-row { display: grid; grid-template-columns: minmax(0, 1fr) repeat(var(--al-rank-buttons, 2), max-content); align-items: center; gap: var(--al-space-3); }
.al-rank-row > :first-child { overflow-wrap: anywhere; }
.al-rank-row-single { --al-rank-buttons: 1; }
.al-split { display: grid; grid-template-columns: minmax(0, 1fr) minmax(16rem, var(--al-aside, 24rem)); gap: var(--al-space-5); align-items: start; }
/* The yard: the course with Flip go and what the run said beside it, in the first screen (town/yard.js); stacked, the press first. */
.al-yard-run { display: grid; grid-template-columns: minmax(0, 34rem) minmax(min-content, 1fr); gap: var(--al-space-4); align-items: start; }
/* The yard's cards under the course (board audit item 4): a student's own across the whole row, a crewmate's folded
   ones side by side under them. */
.al-yard-jobs { display: grid; grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr)); gap: var(--al-space-4); align-items: start; }
.al-yard-jobs > :not(.is-folded) { grid-column: 1 / -1; }
/* HELLO's stamps: a key cap per stamp, the one in hand lifted on the lamp, and a slot to put it down in. */
.al-stamps { gap: var(--al-space-2); min-height: var(--al-target); }
.al-stamp { appearance: none; min-width: var(--al-target); min-height: var(--al-target); padding: 0 var(--al-space-2); border: var(--al-line) solid var(--al-hairline);
  background: var(--al-surface-raised); color: var(--al-text); font-size: var(--al-text-lg); cursor: pointer; }
.al-stamp[aria-pressed="true"] { border-color: var(--al-lamp); color: var(--al-lamp); transform: translateY(-3px); }
.al-stamp[aria-disabled="true"] { cursor: default; color: var(--al-text-secondary); }
.al-stamp-gap { appearance: none; width: 14px; min-height: var(--al-target); padding: 0; border: var(--al-line) dashed var(--al-lamp); background: transparent; cursor: pointer; }
.al-stamp-gap:hover, .al-stamp-gap:focus-visible { background: var(--al-surface-raised); }
.al-stamps-bench .al-stamp { background: var(--al-surface); }
.al-wrap { width: 100%; max-width: 1760px; margin-inline: auto; padding-inline: var(--al-gutter); }

/* The console frame: the HUD across the top, the work, and a side column (journal, tasks, the phone) */
.al-frame { display: grid; min-height: 100vh; grid-template-columns: minmax(0, 1fr) minmax(18rem, 22rem); grid-template-rows: auto minmax(0, 1fr);
  grid-template-areas: "hud hud" "main side"; background: var(--al-ground); }
.al-frame > .al-hud { grid-area: hud; }
.al-frame-main { grid-area: main; min-width: 0; padding: var(--al-space-5) var(--al-gutter); }
.al-frame-side { grid-area: side; min-width: 0; border-left: var(--al-line) solid var(--al-hairline); background: var(--al-surface); padding: var(--al-space-5) var(--al-space-4); }

/* ==================================================================================================
   5. Controls
   ================================================================================================== */
.al-btn { appearance: none; display: inline-flex; align-items: center; justify-content: center; gap: var(--al-space-2); min-height: var(--al-target); padding: 0 var(--al-space-5);
  font-family: var(--al-font-stencil); font-size: 0.9375rem; font-weight: 600; letter-spacing: var(--al-tracking-stencil); text-transform: uppercase; white-space: nowrap;
  border: var(--al-line) solid var(--al-edge); border-radius: var(--al-radius-0); background: transparent; color: var(--al-text); cursor: pointer;
  transition: background-color var(--al-dur-quick) var(--al-ease), border-color var(--al-dur-quick) var(--al-ease), transform var(--al-dur-quick) var(--al-ease); }
.al-btn:hover { background: var(--al-dust-2); border-color: var(--al-text); }
.al-btn:active { transform: translateY(1px); }
.al-btn:disabled, .al-btn[aria-disabled="true"] { border-color: var(--al-hairline); color: var(--al-text-muted); background: transparent; cursor: not-allowed; transform: none; }
/* The lamp: the one thing to press on this screen. One per view. */
.al-btn-lamp { background: var(--al-lamp); border-color: var(--al-lamp); color: var(--al-on-lamp); box-shadow: var(--al-glow-lamp); }
.al-btn-lamp:hover { background: var(--al-lamp); border-color: var(--al-lamp); filter: brightness(1.08); }
/* An unlit lamp: the disabled look wins, glow and hover included, so a press that is not ready never reads as one. */
.al-btn-lamp:disabled, .al-btn-lamp[aria-disabled="true"] { background: transparent; border-color: var(--al-hairline); color: var(--al-text-muted); box-shadow: none; filter: none; }
/* Quiet: secondary actions in a row of them; no border until hovered */
.al-btn-quiet { border-color: transparent; padding-inline: var(--al-space-3); color: var(--al-text-secondary); }
.al-btn-quiet:hover { color: var(--al-text); border-color: var(--al-hairline); }
/* A quiet button that cannot be pressed stays quiet: a box drawn round it would read as the one you can press. */
.al-btn-quiet:disabled, .al-btn-quiet[aria-disabled="true"] { border-color: transparent; }
/* The real thing: Fly, Land, Run the sol, Send. Logged and carries consequences, so it reads heavier than Test. */
.al-btn-commit { border-width: var(--al-rule); border-color: var(--al-flare); color: var(--al-flare); background: var(--al-dust-1); }
.al-btn-commit::after { content: attr(data-logged); font-family: var(--al-font-mono); font-size: var(--al-text-2xs); letter-spacing: var(--al-tracking-mono); color: var(--al-text-muted); }
.al-btn-small { min-height: 32px; padding-inline: var(--al-space-3); font-size: 0.8125rem; }
/* A 32px button still answers a 44px reach on touch screens */
@media (pointer: coarse) { .al-btn-small { min-height: var(--al-target); } }

/* Segmented row: the transport (Run, Step, Fast, Stop), the Pace, a filter */
.al-seg { display: inline-flex; justify-self: start; max-width: 100%; border: var(--al-line) solid var(--al-edge); }
.al-seg > .al-btn { border: 0; border-right: var(--al-line) solid var(--al-hairline); }
.al-seg > .al-btn:last-child { border-right: 0; }
.al-seg > .al-btn[aria-pressed="true"], .al-seg > .al-btn[aria-current="true"] { background: var(--al-surface-raised); color: var(--al-text); box-shadow: inset 0 calc(-1 * var(--al-rule)) 0 var(--al-lamp); }

/* Switch: a button with role="switch"; the word says the state, the track only repeats it */
.al-switch { appearance: none; display: inline-flex; align-items: center; gap: var(--al-space-3); min-height: var(--al-target); padding: 0 var(--al-space-2); border: 0; background: none; cursor: pointer;
  font-family: var(--al-font-mono); font-size: var(--al-text-xs); letter-spacing: 0.12em; text-transform: uppercase; color: var(--al-text-secondary); }
.al-switch::before { content: ""; width: 34px; height: 18px; border: var(--al-line) solid var(--al-edge); background: linear-gradient(var(--al-text-muted), var(--al-text-muted)) 3px 50% / 10px 10px no-repeat;
  transition: background-position var(--al-dur-quick) var(--al-ease); }
.al-switch[aria-checked="true"]::before { border-color: var(--al-lamp); background: linear-gradient(var(--al-lamp), var(--al-lamp)) calc(100% - 3px) 50% / 10px 10px no-repeat; }
.al-switch[aria-checked="true"] { color: var(--al-text); }

/* Field: typed numbers on a tile, a note, a search */
.al-field { justify-self: start; max-width: 100%; min-height: 36px; padding: 0 var(--al-space-3); border: 0; border-bottom: var(--al-line) solid var(--al-edge); background: var(--al-dust-1); color: var(--al-text);
  font-family: var(--al-font-mono); font-size: var(--al-text-md); font-variant-numeric: tabular-nums; border-radius: var(--al-radius-0); }
.al-field:hover { border-bottom-color: var(--al-text-secondary); }
.al-field:focus-visible { border-bottom-color: var(--al-flare); }
.al-field[aria-invalid="true"] { border-bottom: var(--al-rule) solid var(--al-flare); }
.al-field::placeholder { color: var(--al-text-muted); }

/* Tabs: the chairs (Flight Engineer, Surface Lead, Mission Director), the journal's filters */
.al-tabs { display: flex; gap: var(--al-space-1); border-bottom: var(--al-line) solid var(--al-hairline); overflow-x: auto; scrollbar-width: none; }
.al-tab { appearance: none; min-height: var(--al-target); padding: 0 var(--al-space-4); border: 0; background: none; cursor: pointer; white-space: nowrap;
  font-family: var(--al-font-stencil); font-weight: 600; font-size: 0.9375rem; letter-spacing: 0.12em; text-transform: uppercase; color: var(--al-text-muted);
  box-shadow: inset 0 calc(-1 * var(--al-rule)) 0 transparent; transition: color var(--al-dur-quick) var(--al-ease), box-shadow var(--al-dur-quick) var(--al-ease); }
.al-tab:hover { color: var(--al-text); }
.al-tab[aria-selected="true"] { color: var(--al-text); box-shadow: inset 0 calc(-1 * var(--al-rule)) 0 var(--al-lamp); }
.al-tab-count { margin-left: var(--al-space-2); font-family: var(--al-font-mono); font-size: var(--al-text-2xs); color: var(--al-text-muted); }

/* ==================================================================================================
   6. Surfaces and marks
   ================================================================================================== */
.al-panel { position: relative; padding: var(--al-space-5); background: var(--al-surface); border-top: var(--al-line) solid var(--al-hairline); box-shadow: var(--al-shadow-1); }
.al-panel-raised { background: var(--al-surface-raised); box-shadow: var(--al-shadow-2); }
.al-panel-head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: var(--al-space-2) var(--al-space-4); margin-bottom: var(--al-space-4); }
.al-card { position: relative; padding: var(--al-space-4); background: var(--al-surface-raised); border: var(--al-line) solid var(--al-hairline); }
/* A crewmate's card or panel folds to its heading, whose job it is, and "Show" (alpha/fold.js `foldCard`, the yard first,
   then every board of sessions 2 to 7); the heading keeps the left edge so the mark and the button sit together on the
   right. Reference a student needs only when stuck sits behind "Show me" (fold.js `showMe`). */
.al-card > .al-panel-head > :first-child { margin-right: auto; }
.is-folded > :not([data-fold-head]) { display: none !important; }
/* A slashed zero on the yard's stamps (town/yard.js), so 0 and O never look alike. */
.al-zero { position: relative; display: inline-block; }
.al-zero::after { content: ""; position: absolute; left: 10%; right: 10%; top: 50%; border-top: 2px solid currentColor; transform: rotate(-60deg); }
/* The yard's guess card after a rewire (town/yard.js): lit, so a guess the station let go of is never missed. */
[data-rewired] { outline: 2px solid var(--al-lamp); outline-offset: 2px; }
.al-yard-rewired { color: var(--al-lamp); font-weight: 600; }
.is-folded > [data-fold-head] { margin-bottom: 0; }
.al-show-me-fold { display: grid; gap: var(--al-space-3); justify-items: start; }
.al-show-me-fold > :not(summary) { justify-self: stretch; }
.al-show-me { list-style: none; cursor: pointer; }
.al-show-me::-webkit-details-marker { display: none; }
.al-rule { height: var(--al-line); border: 0; margin: var(--al-space-4) 0; background: var(--al-hairline); }

/* Tape: a strip of label tape, stencilled. Part numbers, owners, where a clue came from. */
.al-tape { display: inline-block; padding: 2px var(--al-space-2) 1px; background: var(--al-tape); color: var(--al-on-tape); border-radius: var(--al-radius-1);
  font-family: var(--al-font-mono); font-size: var(--al-text-2xs); font-weight: 600; letter-spacing: 0.16em; text-transform: uppercase; line-height: 1.5;
  clip-path: polygon(0 8%, 3% 0, 97% 6%, 100% 0, 99% 92%, 100% 100%, 2% 96%, 0 100%); }
.al-tape-outline { background: transparent; color: var(--al-text-secondary); box-shadow: inset 0 0 0 var(--al-line) var(--al-edge); clip-path: none; }

/* Brackets: the four corners of a viewfinder. Alpha's attention mark: what you are looking at, what you can look at. */
.al-brackets { position: relative; }
.al-brackets::before { content: ""; position: absolute; inset: 0; pointer-events: none; --c: var(--al-bracket-color, var(--al-text));
  background:
    linear-gradient(var(--c), var(--c)) top left / var(--al-bracket) var(--al-rule) no-repeat,
    linear-gradient(var(--c), var(--c)) top left / var(--al-rule) var(--al-bracket) no-repeat,
    linear-gradient(var(--c), var(--c)) top right / var(--al-bracket) var(--al-rule) no-repeat,
    linear-gradient(var(--c), var(--c)) top right / var(--al-rule) var(--al-bracket) no-repeat,
    linear-gradient(var(--c), var(--c)) bottom left / var(--al-bracket) var(--al-rule) no-repeat,
    linear-gradient(var(--c), var(--c)) bottom left / var(--al-rule) var(--al-bracket) no-repeat,
    linear-gradient(var(--c), var(--c)) bottom right / var(--al-bracket) var(--al-rule) no-repeat,
    linear-gradient(var(--c), var(--c)) bottom right / var(--al-rule) var(--al-bracket) no-repeat; }

/* The lamp: a status light, always beside its word (ON, KEEPING, LIVE). data-state: on | blink | off */
.al-lamp { display: inline-flex; align-items: center; gap: var(--al-space-2); font-family: var(--al-font-mono); font-size: var(--al-text-xs); letter-spacing: 0.14em; text-transform: uppercase; color: var(--al-text-secondary); }
.al-lamp::before { content: ""; flex: none; width: 0.625em; height: 0.625em; border-radius: 50%; background: var(--al-lamp); box-shadow: 0 0 0 2px var(--al-lamp-wash), 0 0 10px 1px var(--al-lamp-glow); }
.al-lamp[data-state="off"]::before { background: transparent; box-shadow: inset 0 0 0 var(--al-line) var(--al-edge); }
.al-lamp[data-state="earth"]::before { background: var(--al-earth); box-shadow: 0 0 0 2px var(--al-earth-wash); }

/* Stamp: PART 4 CLOSED. Stencilled, a little crooked, never animated in. */
.al-stamp { display: inline-block; padding: var(--al-space-2) var(--al-space-4); border: var(--al-rule) solid currentColor; outline: var(--al-line) solid currentColor; outline-offset: 3px;
  font-family: var(--al-font-stencil); font-weight: 600; font-size: var(--al-text-xl); letter-spacing: 0.2em; text-transform: uppercase; color: var(--al-text); transform: rotate(-2.5deg); }
.al-stamp-lamp { color: var(--al-lamp); }

/* ==================================================================================================
   7. Plain: the tile editor. A program is an ordered list of tiles; the keyboard model (Tab in, arrows to move,
   Enter to edit, Delete to remove, Alt with Up or Down to reorder) is alpha.js rovingList. The keyword is always
   printed; its plate's shape repeats the kind for a glance, never alone.
     data-kind: sequence (DO, WAIT, SAY) | event (WHEN) | condition (IF, ELSE) | loop (REPEAT) | function (DEFINE, CALL)
                | data (KEEP IF, MATCH, SET, CHANGE) | message (SEND, PARITY) | claim (CLAIM, RELEASE)
   ================================================================================================== */
.al-program { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--al-space-1); counter-reset: al-step; font-family: var(--al-font-mono); }
.al-tile { position: relative; display: grid; grid-template-columns: 2.75rem minmax(0, 1fr) auto; align-items: start; gap: 0 var(--al-space-3);
  min-height: var(--al-target); padding: var(--al-space-2) var(--al-space-3) var(--al-space-2) 0; background: var(--al-surface); border: var(--al-line) solid var(--al-hairline);
  counter-increment: al-step; cursor: default; transition: background-color var(--al-dur-quick) var(--al-ease), border-color var(--al-dur-quick) var(--al-ease); }
.al-tile::before { content: counter(al-step); align-self: center; text-align: right; font-size: var(--al-text-xs); color: var(--al-text-muted); font-variant-numeric: tabular-nums; }
.al-tile:hover { border-color: var(--al-edge); }
.al-tile:focus-visible { box-shadow: var(--al-focus); z-index: 1; }
.al-tile[data-current="true"] { background: var(--al-surface-raised); border-color: var(--al-text-secondary); }
.al-tile-body { display: flex; flex-wrap: wrap; align-items: center; gap: var(--al-space-2); min-width: 0; padding-top: 2px; font-size: var(--al-text-md); line-height: 1.6; }
.al-tile-tail { display: flex; align-items: center; gap: var(--al-space-2); }

.al-kw { display: inline-flex; align-items: center; min-height: 26px; padding: 0 var(--al-space-2); font-weight: 700; font-size: 0.875rem; letter-spacing: 0.08em; text-transform: uppercase;
  background: var(--al-surface-raised); color: var(--al-text); box-shadow: inset 0 0 0 var(--al-line) var(--al-edge); }
.al-tile[data-kind="event"] .al-kw { padding-left: var(--al-space-4); clip-path: polygon(10px 0, 100% 0, 100% 100%, 10px 100%, 0 50%); background: var(--al-lamp-wash); box-shadow: none; }
.al-tile[data-kind="condition"] .al-kw { padding-right: var(--al-space-4); clip-path: polygon(0 0, calc(100% - 10px) 0, 100% 50%, calc(100% - 10px) 100%, 0 100%); box-shadow: none; }
.al-tile[data-kind="loop"] .al-kw { box-shadow: inset 3px 0 0 var(--al-text-secondary), inset -3px 0 0 var(--al-text-secondary); }
.al-tile[data-kind="function"] .al-kw { box-shadow: inset 0 0 0 var(--al-line) var(--al-edge), inset 0 0 0 3px var(--al-surface-raised), inset 0 0 0 4px var(--al-edge); padding-inline: var(--al-space-3); }
.al-tile[data-kind="data"] .al-kw { background: transparent; box-shadow: inset 0 calc(-1 * var(--al-rule)) 0 var(--al-text-secondary); }
.al-tile[data-kind="message"] .al-kw { background: var(--al-earth-wash); box-shadow: inset 0 0 0 var(--al-line) var(--al-earth); }
.al-tile[data-kind="claim"] .al-kw { background: transparent; box-shadow: inset 0 0 0 var(--al-rule) var(--al-text-secondary); }
.al-op { color: var(--al-text-muted); font-weight: 600; }
/* An argument: an action, a reading, a typed number. Editable ones are underlined, and are .al-field when open. */
.al-arg { color: var(--al-text); font-weight: 500; }
.al-arg-edit { padding: 0 2px; border-bottom: var(--al-line) dashed var(--al-edge); cursor: text; }
.al-arg-number { font-variant-numeric: tabular-nums; }
.al-arg-text { color: var(--al-text-secondary); }
/* The note: a person wrote it, so it is in the story voice. Navarro reads them at the harvest. */
.al-note { flex-basis: 100%; margin-top: 2px; font-family: var(--al-font-story); font-style: italic; font-size: var(--al-text-sm); line-height: 1.45; color: var(--al-text-secondary); }
.al-note::before { content: "Note: "; font-style: normal; font-family: var(--al-font-mono); font-size: var(--al-text-2xs); letter-spacing: 0.16em; text-transform: uppercase; color: var(--al-text-muted); }

/* Nesting: THEN, ELSE, REPEAT and DEFINE hold a block, three deep at most, on a rail */
.al-block { list-style: none; margin: var(--al-space-1) 0 0; padding: 0 0 0 var(--al-space-5); display: grid; gap: var(--al-space-1); grid-column: 2 / -1; position: relative; }
.al-block::before { content: ""; position: absolute; left: var(--al-space-2); top: 0; bottom: var(--al-space-3); width: var(--al-rule); background: var(--al-hairline); }
.al-block::after { content: ""; position: absolute; left: var(--al-space-2); bottom: var(--al-space-3); width: var(--al-space-3); height: var(--al-rule); background: var(--al-hairline); }
.al-tile[data-kind="loop"] > .al-block::before, .al-tile[data-kind="loop"] > .al-block::after { background: var(--al-text-muted); }
.al-block > .al-tile { padding-left: var(--al-space-3); grid-template-columns: minmax(0, 1fr) auto; counter-increment: none; }
.al-block > .al-tile::before { display: none; }

/* States. Running: the trace is on this tile now. Error: the checker's word for it, under it. */
.al-tile[aria-current="step"] { background: linear-gradient(90deg, var(--al-lamp-wash), transparent 70%), var(--al-surface-raised); border-color: var(--al-lamp-line); }
.al-tile[aria-current="step"]::after { content: ""; position: absolute; left: -1px; top: -1px; bottom: -1px; width: 3px; background: var(--al-lamp); box-shadow: 0 0 10px var(--al-lamp-glow); }
.al-tile.is-error { border: var(--al-rule) solid var(--al-flare); }
.al-tile-error { grid-column: 2 / -1; margin-top: var(--al-space-2); font-size: var(--al-text-sm); color: var(--al-text); }
.al-tile-error::before { content: "Check: "; color: var(--al-flare); font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; font-size: var(--al-text-xs); }
/* Locked: another chair owns this rule. A non-owner proposes a change instead (a pull request). */
.al-tile.is-locked { background: repeating-linear-gradient(-45deg, var(--al-dust-1) 0 6px, transparent 6px 12px), var(--al-surface); }
.al-tile.is-locked .al-arg-edit { border-bottom-style: none; cursor: default; }
/* Changed: needs the Mission Director's review signature before it flies */
.al-tile.is-changed { border-style: dashed; border-color: var(--al-text-secondary); }
.al-tile.is-moving { box-shadow: var(--al-shadow-2), var(--al-focus); transform: translateX(4px); z-index: 2; }
.al-tile-insert { height: var(--al-rule); margin: -1px 0; background: var(--al-lamp); box-shadow: 0 0 8px var(--al-lamp-glow); }

/* The cap: TILES 7 OF 24. Twenty-four segments read at a glance; the words are the value. */
.al-cap { display: grid; gap: var(--al-space-1); min-width: 10rem; }
.al-cap-bar { height: 6px; background: repeating-linear-gradient(90deg, var(--al-hairline) 0 calc(100% / var(--al-cap-of, 12) - 2px), transparent 0 calc(100% / var(--al-cap-of, 12))); position: relative; }
.al-cap-bar::after { content: ""; position: absolute; inset: 0; width: calc(100% * var(--al-cap-used, 0) / var(--al-cap-of, 12));
  background: repeating-linear-gradient(90deg, var(--al-text-secondary) 0 calc(100% / var(--al-cap-used, 1) - 2px), transparent 0 calc(100% / var(--al-cap-used, 1))); }
.al-cap.is-full .al-cap-bar::after { background: repeating-linear-gradient(90deg, var(--al-lamp) 0 calc(100% / var(--al-cap-used, 1) - 2px), transparent 0 calc(100% / var(--al-cap-used, 1))); }

/* Step inspector: every reading and variable beside the tile that just ran. A changed value says so in words. */
.al-inspect { display: grid; grid-template-columns: auto 1fr; gap: var(--al-space-1) var(--al-space-4); margin: 0; font-family: var(--al-font-mono); font-size: var(--al-text-sm); font-variant-numeric: tabular-nums; }
.al-inspect dt { color: var(--al-text-muted); text-transform: lowercase; }
.al-inspect dd { margin: 0; color: var(--al-text); text-align: right; }
.al-inspect dd.is-changed { color: var(--al-lamp); }
.al-inspect dd.is-changed::after { content: " changed"; font-size: var(--al-text-2xs); letter-spacing: 0.12em; text-transform: uppercase; color: var(--al-text-muted); }
.al-inspect dd.is-wrapped { color: var(--al-flare); font-weight: 700; }

/* Show as Python: read-only, generated from the tiles; notes come through as comments */
.al-code { margin: 0; padding: var(--al-space-4) var(--al-space-4) var(--al-space-4) 0; overflow-x: auto; background: var(--al-well); border: var(--al-line) solid var(--al-hairline);
  font-family: var(--al-font-mono); font-size: var(--al-text-sm); line-height: 1.7; color: var(--al-text-secondary); counter-reset: al-line; tab-size: 4; }
.al-code > span { display: block; padding-left: 3.5rem; position: relative; white-space: pre; counter-increment: al-line; }
.al-code > span::before { content: counter(al-line); position: absolute; left: 0; width: 2.5rem; text-align: right; color: var(--al-text-muted); }
.al-code .k { color: var(--al-text); font-weight: 700; }
.al-code .n { color: var(--al-text); }
.al-code .s { color: var(--al-earth); }
.al-code .c { color: var(--al-text-muted); font-style: italic; }
.al-code > span[aria-current="step"] { background: var(--al-lamp-wash); box-shadow: inset 3px 0 0 var(--al-lamp); }

/* ==================================================================================================
   8. Boards: one frame, three kinds of world (grid, timeline, strip), and a text table of the same world always
   one press away (Plain's accessibility rule: every board has a text table of its world).
   ================================================================================================== */
.al-board { display: grid; gap: var(--al-space-3); padding: var(--al-space-4); background: var(--al-surface); border: var(--al-line) solid var(--al-hairline); }
.al-board-head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--al-space-2) var(--al-space-4); }
.al-board-tick { font-family: var(--al-font-mono); font-size: var(--al-text-sm); color: var(--al-text-secondary); font-variant-numeric: tabular-nums; }
.al-board-tick b { color: var(--al-text); font-weight: 600; }
.al-board-world { position: relative; background: var(--al-void); border: var(--al-line) solid var(--al-hairline); overflow: hidden; }
.al-legend { display: flex; flex-wrap: wrap; gap: var(--al-space-2) var(--al-space-4); margin: 0; padding: 0; list-style: none; font-family: var(--al-font-mono); font-size: var(--al-text-xs); color: var(--al-text-muted); }
.al-legend li { display: inline-flex; align-items: center; gap: var(--al-space-2); }
.al-legend .al-cell { width: 16px; height: 16px; flex: none; }

/* Grid world: the yard, the robots, the town, the tracks. Ground is told apart by pattern, never by hue. */
.al-grid { display: grid; grid-template-columns: repeat(var(--al-cols, 12), minmax(0, 1fr)); aspect-ratio: var(--al-cols, 12) / var(--al-rows, 8); gap: 1px; padding: 1px; background: var(--al-hairline); }
.al-cell { position: relative; background: var(--al-surface); }
.al-cell[data-ground="regolith"] { background: radial-gradient(var(--al-dust-3) 0.8px, transparent 1px) 0 0 / 6px 6px, var(--al-surface); }
.al-cell[data-ground="rock"] { background: radial-gradient(var(--al-text-muted) 1.4px, transparent 1.6px) 0 0 / 5px 5px, var(--al-surface-raised); }
.al-cell[data-ground="shadow"] { background: var(--al-void); }
.al-cell[data-ground="ice"] { background: repeating-linear-gradient(45deg, var(--al-text-secondary) 0 1px, transparent 1px 5px), var(--al-well); }
.al-cell[data-ground="pad"] { background: linear-gradient(var(--al-edge), var(--al-edge)) 50% 0 / 1px 100% no-repeat, linear-gradient(var(--al-edge), var(--al-edge)) 0 50% / 100% 1px no-repeat, var(--al-surface-raised); }
.al-cell[data-ground="ramp"] { background: repeating-linear-gradient(0deg, var(--al-text-muted) 0 1px, transparent 1px 4px), var(--al-surface); }
.al-cell[data-ground="building"] { background: repeating-linear-gradient(0deg, var(--al-edge) 0 2px, var(--al-surface-raised) 2px 5px); }
.al-cell[data-ground="cone"] { background: radial-gradient(circle, var(--al-text) 0 22%, transparent 24%), var(--al-surface); }
.al-cell.is-trail::after { content: ""; position: absolute; inset: 38%; background: var(--al-lamp-line); }
.al-cell.is-track::after { content: ""; position: absolute; left: 20%; right: 20%; top: 46%; height: 8%; background: repeating-linear-gradient(90deg, var(--al-text-secondary) 0 3px, transparent 3px 6px); }
/* A machine: a square with its short name printed. The one the trace is on carries the lamp. */
.al-machine { position: absolute; inset: 12%; display: grid; place-items: center; background: var(--al-text); color: var(--al-ground);
  font-family: var(--al-font-mono); font-weight: 700; font-size: clamp(9px, 1.1vw, 13px); letter-spacing: 0.04em; text-transform: uppercase; line-height: 1; z-index: 1;
  transition: transform var(--al-dur-tick) linear; }
.al-machine[data-facing="north"] { box-shadow: inset 0 3px 0 var(--al-lamp); }
.al-machine[data-facing="east"] { box-shadow: inset -3px 0 0 var(--al-lamp); }
.al-machine[data-facing="south"] { box-shadow: inset 0 -3px 0 var(--al-lamp); }
.al-machine[data-facing="west"] { box-shadow: inset 3px 0 0 var(--al-lamp); }
.al-machine.is-active { outline: var(--al-rule) solid var(--al-lamp); outline-offset: 2px; }
.al-machine.is-waiting { background: var(--al-text-muted); }
.al-machine-p1 { background: var(--al-well); color: var(--al-lamp); box-shadow: inset 0 0 0 var(--al-rule) var(--al-lamp); }

/* Timeline: the flight and the descent. Rules down the side, ticks across, a mark where each fired. */
.al-timeline { position: relative; display: grid; grid-template-columns: minmax(9rem, 14rem) minmax(0, 1fr); font-family: var(--al-font-mono); font-size: var(--al-text-xs); }
.al-timeline-rule { display: flex; align-items: center; min-height: 32px; padding: 0 var(--al-space-3); border-bottom: var(--al-line) solid var(--al-hairline); color: var(--al-text-secondary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.al-timeline-track { position: relative; min-height: 32px; border-bottom: var(--al-line) solid var(--al-hairline);
  background: repeating-linear-gradient(90deg, var(--al-hairline) 0 1px, transparent 1px calc(100% / var(--al-divisions, 10))); }
.al-timeline-mark { position: absolute; top: 50%; left: var(--al-at, 0%); width: 10px; height: 10px; transform: translate(-50%, -50%); background: var(--al-text); }
.al-timeline-mark.is-now { background: var(--al-lamp); box-shadow: 0 0 10px var(--al-lamp-glow); }
.al-timeline-mark.is-failed { background: var(--al-well); box-shadow: inset 0 0 0 var(--al-rule) var(--al-flare); }
.al-timeline-axis { grid-column: 2; display: flex; justify-content: space-between; padding: var(--al-space-1) 0; color: var(--al-text-muted); font-variant-numeric: tabular-nums; }
.al-timeline-now { position: absolute; top: 0; bottom: 0; left: var(--al-at, 0%); width: 1px; background: var(--al-lamp); pointer-events: none; }
/* The fired caption: RULE 4 FIRED. T PLUS 158. STAGE. */
.al-fired { font-family: var(--al-font-mono); font-size: var(--al-text-sm); letter-spacing: 0.1em; text-transform: uppercase; color: var(--al-text); }
.al-fired b { color: var(--al-lamp); font-weight: 700; }

/* A live call: one button, one moment, a visible clock. The window drains as a bar under the button. */
.al-call { display: grid; gap: var(--al-space-2); justify-items: start; }
.al-call .al-btn { min-height: 56px; font-size: 1.125rem; padding-inline: var(--al-space-6); }
.al-call-window { width: 100%; max-width: 22rem; height: 4px; background: var(--al-hairline); position: relative; overflow: hidden; }
.al-call-window::after { content: ""; position: absolute; inset: 0; background: var(--al-lamp); transform-origin: left; transform: scaleX(var(--al-left, 1)); }
.al-call-clock { font-family: var(--al-font-mono); font-size: var(--al-text-sm); color: var(--al-text-secondary); font-variant-numeric: tabular-nums; }

/* Strip: the logs, the camera frames, the decoder, the message. Rows of records; KEEP IF keeps some and drops the rest. */
.al-strip { display: grid; font-family: var(--al-font-mono); font-size: var(--al-text-sm); font-variant-numeric: tabular-nums; }
.al-strip-row { display: grid; grid-template-columns: var(--al-strip-columns, 6rem 1fr 6rem); gap: var(--al-space-3); align-items: center; min-height: 30px; padding: 0 var(--al-space-3);
  border-bottom: var(--al-line) solid var(--al-hairline); color: var(--al-text-secondary); }
.al-strip-row.is-head { min-height: 28px; font-size: var(--al-text-2xs); letter-spacing: 0.16em; text-transform: uppercase; color: var(--al-text-muted); border-bottom-color: var(--al-edge); }
.al-strip-row.is-kept { color: var(--al-text); background: var(--al-dust-1); box-shadow: inset 3px 0 0 var(--al-text); }
.al-strip-row.is-dropped { color: var(--al-text-muted); }
.al-strip-row.is-match { color: var(--al-text); box-shadow: inset 3px 0 0 var(--al-lamp); background: var(--al-lamp-wash); }
.al-strip-row > :last-child { text-align: right; }
.al-strip-gap { padding: var(--al-space-1) var(--al-space-3); font-size: var(--al-text-xs); color: var(--al-text-muted); letter-spacing: 0.1em; border-bottom: var(--al-line) solid var(--al-hairline); }

/* Bits: the relay's burst. Grouped by the markup (al-bits-group), so sevens and eights are the student's choice, not the stylesheet's. */
.al-bits { display: flex; flex-wrap: wrap; gap: var(--al-space-2) var(--al-space-3); font-family: var(--al-font-mono); font-size: var(--al-text-md); line-height: 1; }
.al-bits-group { display: inline-flex; flex-direction: column; gap: var(--al-space-1); align-items: center; }
.al-bits-cells { display: inline-flex; }
.al-bit { display: inline-grid; place-items: center; width: 1.4em; height: 1.75em; border: var(--al-line) solid var(--al-hairline); margin-left: -1px; color: var(--al-text-muted); }
.al-bit[data-bit="1"] { color: var(--al-ground); background: var(--al-text); border-color: var(--al-text); }
.al-bit.is-parity { border-bottom: var(--al-rule) solid var(--al-lamp); }
.al-bit.is-flipped { box-shadow: inset 0 0 0 var(--al-rule) var(--al-flare); background: var(--al-well); color: var(--al-flare); }
.al-bits-char { font-size: var(--al-text-sm); color: var(--al-text); font-weight: 700; min-height: 1.2em; }
.al-bits-char.is-nonsense { color: var(--al-text-muted); font-weight: 400; }

/* The text table: every board's world, as rows */
.al-table { width: 100%; border-collapse: collapse; font-family: var(--al-font-mono); font-size: var(--al-text-sm); font-variant-numeric: tabular-nums; }
.al-table caption { text-align: left; padding-bottom: var(--al-space-2); font-size: var(--al-text-2xs); letter-spacing: var(--al-tracking-mono); text-transform: uppercase; color: var(--al-text-muted); }
.al-table th { text-align: left; font-weight: 500; font-size: var(--al-text-2xs); letter-spacing: 0.16em; text-transform: uppercase; color: var(--al-text-muted); border-bottom: var(--al-line) solid var(--al-edge); padding: var(--al-space-2) var(--al-space-3); }
.al-table td { padding: var(--al-space-2) var(--al-space-3); border-bottom: var(--al-line) solid var(--al-hairline); color: var(--al-text-secondary); }
.al-table td.is-num, .al-table th.is-num { text-align: right; }
.al-table tr[aria-current] td { color: var(--al-text); background: var(--al-lamp-wash); }

/* ==================================================================================================
   9. Places: a still with hotspots. Hunt by pointer, as the old adventures did, or by Tab, which shows each one;
   "Show what I can look at" (data-reveal on the place) shows all of them at once.
   Position each hotspot in percent of the still: style="--x: 41%; --y: 22%; --w: 13%; --h: 30%".
   ================================================================================================== */
.al-place { position: relative; aspect-ratio: 16 / 9; width: 100%; overflow: hidden; background: var(--al-void); isolation: isolate; container-type: inline-size; }
.al-place-still { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; z-index: 0; }
.al-place::before { content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none; background: var(--al-grain); opacity: calc(var(--al-grain-strength) * 1.6); mix-blend-mode: overlay; }
.al-place::after { content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none; background: radial-gradient(120% 90% at 50% 45%, transparent 55%, var(--al-shade)); }
.al-place[data-light="night"]::after { background: radial-gradient(90% 80% at 50% 40%, transparent 30%, #000000d9); }
.al-place-head { position: absolute; z-index: 3; left: 0; right: 0; top: 0; display: flex; justify-content: space-between; align-items: flex-start; gap: var(--al-space-3);
  padding: var(--al-space-4) var(--al-space-5); background: linear-gradient(var(--al-shade), transparent); pointer-events: none; }
.al-place-head > * { pointer-events: auto; }
.al-place-name { font-family: var(--al-font-story); font-size: var(--al-text-2xl); line-height: var(--al-leading-tight); color: var(--al-text); text-shadow: 0 1px 12px #000; }
.al-place-time { font-family: var(--al-font-mono); font-size: var(--al-text-xs); letter-spacing: var(--al-tracking-mono); text-transform: uppercase; color: var(--al-text-secondary); }
.al-place-exits { position: absolute; z-index: 3; left: 0; right: 0; bottom: 0; display: flex; flex-wrap: wrap; gap: var(--al-space-2); padding: var(--al-space-4) var(--al-space-5);
  background: linear-gradient(transparent, var(--al-shade)); }
.al-place-exits .al-btn { background: var(--al-shade); }

.al-hotspot { position: absolute; z-index: var(--al-z-hotspot); left: var(--x); top: var(--y); width: var(--w); height: var(--h); min-width: var(--al-target); min-height: var(--al-target);
  padding: 0; border: 0; background: transparent; cursor: pointer; --al-bracket-color: var(--al-text); }
.al-hotspot::before { content: ""; position: absolute; inset: 0; pointer-events: none; opacity: 0; transform: scale(1.12); --c: var(--al-bracket-color);
  background:
    linear-gradient(var(--c), var(--c)) top left / var(--al-bracket) var(--al-rule) no-repeat,
    linear-gradient(var(--c), var(--c)) top left / var(--al-rule) var(--al-bracket) no-repeat,
    linear-gradient(var(--c), var(--c)) top right / var(--al-bracket) var(--al-rule) no-repeat,
    linear-gradient(var(--c), var(--c)) top right / var(--al-rule) var(--al-bracket) no-repeat,
    linear-gradient(var(--c), var(--c)) bottom left / var(--al-bracket) var(--al-rule) no-repeat,
    linear-gradient(var(--c), var(--c)) bottom left / var(--al-rule) var(--al-bracket) no-repeat,
    linear-gradient(var(--c), var(--c)) bottom right / var(--al-bracket) var(--al-rule) no-repeat,
    linear-gradient(var(--c), var(--c)) bottom right / var(--al-rule) var(--al-bracket) no-repeat;
  filter: drop-shadow(0 0 3px #000); transition: opacity var(--al-dur-quick) var(--al-ease), transform var(--al-dur-ui) var(--al-ease-settle); }
.al-hotspot-label { position: absolute; left: 50%; top: calc(100% + var(--al-space-2)); transform: translateX(-50%); padding: 3px var(--al-space-2); white-space: nowrap;
  background: var(--al-scrim-caption); color: var(--al-text); font-family: var(--al-font-mono); font-size: var(--al-text-xs); letter-spacing: 0.12em; text-transform: uppercase;
  opacity: 0; pointer-events: none; transition: opacity var(--al-dur-quick) var(--al-ease); }
.al-hotspot:hover::before, .al-hotspot:focus-visible::before, .al-place[data-reveal] .al-hotspot::before { opacity: 1; transform: scale(1); }
.al-hotspot:hover .al-hotspot-label, .al-hotspot:focus-visible .al-hotspot-label, .al-place[data-reveal] .al-hotspot-label { opacity: 1; }
.al-hotspot:focus-visible { box-shadow: none; --al-bracket-color: var(--al-flare); }
.al-hotspot:focus-visible .al-hotspot-label { box-shadow: var(--al-focus); }
.al-hotspot.is-new { --al-bracket-color: var(--al-lamp); }
.al-hotspot.is-seen .al-hotspot-label::after { content: " / seen"; color: var(--al-text-muted); }
.al-hotspot-top .al-hotspot-label { top: auto; bottom: calc(100% + var(--al-space-2)); }

/* ==================================================================================================
   10. Conversation: a talking portrait, the line in the story voice, and three or four topics. The topics are
   the crew's own words, so they are in the body face; people's words are serif. Number keys pick (alpha.js topics).
   ================================================================================================== */
.al-talk { display: grid; grid-template-columns: minmax(12rem, 22rem) minmax(0, 1fr); gap: var(--al-space-5); align-items: end; }
.al-portrait { position: relative; aspect-ratio: 3 / 4; background: var(--al-void); overflow: hidden; border-bottom: var(--al-rule) solid var(--al-hairline); }
.al-portrait > :is(canvas, img, video) { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }
.al-portrait.is-speaking { border-bottom-color: var(--al-lamp); }
.al-talk-body { display: grid; gap: var(--al-space-4); align-content: end; min-width: 0; }
.al-speaker { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--al-space-1) var(--al-space-3); }
.al-speaker-name { font-family: var(--al-font-story); font-size: var(--al-text-xl); color: var(--al-text); }
.al-speaker-role { font-family: var(--al-font-mono); font-size: var(--al-text-2xs); letter-spacing: var(--al-tracking-mono); text-transform: uppercase; color: var(--al-text-muted); }
.al-line { font-family: var(--al-font-story); font-size: var(--al-text-lg); line-height: var(--al-leading-story); color: var(--al-text); max-width: var(--al-measure); }
.al-line-sound { font-family: var(--al-font-mono); font-size: var(--al-text-xs); letter-spacing: 0.12em; text-transform: uppercase; color: var(--al-text-muted); }
.al-topics { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--al-space-1); counter-reset: al-topic; }
.al-topic { appearance: none; display: grid; grid-template-columns: 2rem minmax(0, 1fr) auto; align-items: center; gap: var(--al-space-3); width: 100%; min-height: var(--al-target);
  padding: var(--al-space-2) var(--al-space-3); text-align: left; cursor: pointer; border: var(--al-line) solid var(--al-hairline); background: var(--al-surface);
  font-family: var(--al-font-body); font-size: var(--al-text-md); color: var(--al-text); counter-increment: al-topic;
  transition: background-color var(--al-dur-quick) var(--al-ease), border-color var(--al-dur-quick) var(--al-ease); }
.al-topic::before { content: counter(al-topic); font-family: var(--al-font-mono); font-size: var(--al-text-sm); color: var(--al-text-muted); text-align: center; }
.al-topic:hover { background: var(--al-surface-raised); border-color: var(--al-edge); }
.al-topic.is-new::after { content: "New"; padding: 1px var(--al-space-2); background: var(--al-tape); color: var(--al-on-tape); font-family: var(--al-font-mono); font-size: var(--al-text-2xs);
  font-weight: 600; letter-spacing: 0.16em; text-transform: uppercase; }
.al-topic.is-spent { color: var(--al-text-secondary); }
.al-topic.is-spent::after { content: "Asked"; font-family: var(--al-font-mono); font-size: var(--al-text-2xs); letter-spacing: 0.16em; text-transform: uppercase; color: var(--al-text-muted); }
.al-topic-show { border-style: dashed; border-color: var(--al-edge); }

/* ==================================================================================================
   11. Journal: one shared crew journal. Every clue, claim and log finding, entered with where it came from.
   data-kind: clue | claim | log | note. The kind is the tape's word; the shape of the body repeats it.
   ================================================================================================== */
.al-journal { display: grid; gap: var(--al-space-3); }
.al-journal-list { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--al-space-3); }
.al-journal-list > li { content-visibility: auto; contain-intrinsic-size: auto 120px; }
.al-entry { position: relative; display: grid; gap: var(--al-space-2); padding: var(--al-space-3) var(--al-space-4) var(--al-space-4); background: var(--al-surface-raised);
  border-top: var(--al-line) solid var(--al-hairline); box-shadow: var(--al-shadow-1); }
.al-entry-head { display: flex; flex-wrap: wrap; align-items: center; gap: var(--al-space-2) var(--al-space-3); }
.al-entry-source { font-family: var(--al-font-mono); font-size: var(--al-text-2xs); letter-spacing: 0.16em; text-transform: uppercase; color: var(--al-text-secondary); }
.al-entry-time { margin-left: auto; font-family: var(--al-font-mono); font-size: var(--al-text-2xs); letter-spacing: 0.12em; color: var(--al-text-muted); font-variant-numeric: tabular-nums; }
.al-entry-body { font-family: var(--al-font-story); font-size: var(--al-text-md); line-height: var(--al-leading-story); color: var(--al-text); }
.al-entry[data-kind="claim"] .al-entry-body { font-style: italic; padding-left: var(--al-space-3); box-shadow: inset var(--al-rule) 0 0 var(--al-edge); }
.al-entry-by { font-family: var(--al-font-body); font-style: normal; font-size: var(--al-text-sm); color: var(--al-text-muted); }
.al-entry[data-kind="log"] .al-entry-body { font-family: var(--al-font-mono); font-size: var(--al-text-sm); line-height: 1.6; padding: var(--al-space-2) var(--al-space-3); background: var(--al-well); color: var(--al-text-secondary); }
.al-entry[data-kind="note"] { background: var(--al-surface); border-top-style: dashed; }
.al-entry[data-kind="clue"] .al-entry-body { font-size: var(--al-text-lg); }
.al-entry.is-new { box-shadow: var(--al-shadow-1), inset 0 var(--al-rule) 0 var(--al-lamp); }
/* Checked against a log: the claim and the log line side by side, and the verdict in words with its own shape */
.al-check { display: inline-flex; align-items: center; gap: var(--al-space-2); font-family: var(--al-font-mono); font-size: var(--al-text-2xs); font-weight: 600; letter-spacing: 0.16em; text-transform: uppercase; color: var(--al-text); }
.al-check::before { content: ""; width: 10px; height: 10px; flex: none; background: var(--al-text); }
.al-check[data-verdict="contradicts"]::before { background: transparent; box-shadow: inset 0 0 0 var(--al-rule) var(--al-flare); transform: rotate(45deg); }
.al-check[data-verdict="open"]::before { background: transparent; box-shadow: inset 0 0 0 var(--al-line) var(--al-edge); }

/* ==================================================================================================
   12. Case board: five questions, each answered with a journal entry. Cards are pinned with tape, not string.
   ================================================================================================== */
.al-case { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr)); gap: var(--al-space-5); padding: var(--al-space-5);
  background: radial-gradient(var(--al-dust-2) 1px, transparent 1.2px) 0 0 / 18px 18px, var(--al-well); border: var(--al-line) solid var(--al-hairline); }
.al-question { display: grid; gap: var(--al-space-3); align-content: start; }
.al-question-text { font-family: var(--al-font-story); font-size: var(--al-text-lg); line-height: 1.35; color: var(--al-text); }
.al-question-number { font-family: var(--al-font-mono); font-size: var(--al-text-2xs); letter-spacing: var(--al-tracking-mono); text-transform: uppercase; color: var(--al-text-muted); }
.al-slot { appearance: none; display: grid; place-items: center; min-height: 7.5rem; padding: var(--al-space-4); border: var(--al-line) dashed var(--al-edge); background: transparent; cursor: pointer;
  font-family: var(--al-font-mono); font-size: var(--al-text-xs); letter-spacing: 0.14em; text-transform: uppercase; color: var(--al-text-muted); text-align: center; }
.al-slot:hover { border-color: var(--al-text-secondary); color: var(--al-text-secondary); background: var(--al-dust-1); }
.al-slot.is-target { border-style: solid; border-color: var(--al-lamp); color: var(--al-text); background: var(--al-lamp-wash); }
.al-pinned { position: relative; margin-top: var(--al-space-2); transform: rotate(var(--al-tilt, -0.6deg)); }
.al-pinned::before { content: ""; position: absolute; z-index: 1; top: -9px; left: 50%; width: 64px; height: 18px; transform: translateX(-50%) rotate(2deg); background: var(--al-tape); opacity: 0.85;
  clip-path: polygon(0 10%, 4% 0, 96% 8%, 100% 0, 98% 90%, 100% 100%, 3% 94%, 0 100%); }
.al-pinned:nth-child(even) { --al-tilt: 0.5deg; }
.al-question.is-answered .al-question-number::after { content: " / answered"; color: var(--al-text); }
.al-question.is-wrong .al-question-number::after { content: " / their alibi holds"; color: var(--al-flare); }

/* ==================================================================================================
   13. Phone: call Waypoint or call Earth, from the station drawer. The handset's light is earthshine: the link home.
   ================================================================================================== */
.al-phone { display: grid; grid-template-rows: auto 1fr auto; width: min(100%, 22rem); min-height: 28rem; background: var(--al-surface); border: var(--al-line) solid var(--al-edge); box-shadow: var(--al-shadow-2); }
.al-phone-display { display: flex; justify-content: space-between; align-items: center; gap: var(--al-space-3); padding: var(--al-space-3) var(--al-space-4); background: var(--al-well);
  border-bottom: var(--al-line) solid var(--al-hairline); font-family: var(--al-font-mono); font-size: var(--al-text-xs); letter-spacing: 0.14em; text-transform: uppercase; color: var(--al-earth); font-variant-numeric: tabular-nums; }
.al-phone-list { list-style: none; margin: 0; padding: var(--al-space-2); display: grid; gap: var(--al-space-1); align-content: start; }
.al-contact { appearance: none; display: grid; grid-template-columns: 1fr auto; align-items: center; gap: var(--al-space-1) var(--al-space-3); width: 100%; min-height: 56px;
  padding: var(--al-space-2) var(--al-space-3); border: var(--al-line) solid transparent; background: none; text-align: left; cursor: pointer; color: var(--al-text); }
.al-contact:hover { background: var(--al-dust-2); border-color: var(--al-hairline); }
.al-contact-name { font-family: var(--al-font-story); font-size: var(--al-text-lg); line-height: 1.2; }
.al-contact-kind { grid-column: 1; font-family: var(--al-font-mono); font-size: var(--al-text-2xs); letter-spacing: 0.14em; text-transform: uppercase; color: var(--al-text-muted); }
.al-contact-where { grid-row: 1 / span 2; grid-column: 2; font-family: var(--al-font-mono); font-size: var(--al-text-2xs); letter-spacing: 0.12em; text-transform: uppercase; color: var(--al-earth); }
.al-phone-call { display: grid; gap: var(--al-space-3); align-content: start; padding: var(--al-space-5) var(--al-space-4); }
.al-phone-foot { display: flex; gap: var(--al-space-2); padding: var(--al-space-3); border-top: var(--al-line) solid var(--al-hairline); }
.al-phone-foot .al-btn { flex: 1; }

/* ==================================================================================================
   14. The cutscene player's visuals and controls. The streaming plumbing (HLS renditions, the source) is the
   architecture's; this is the frame, the captions, the bar, the poster fallback, the title and act cards.
   alpha.js player() wires it. data-state on the figure: idle | playing | paused | buffering | ended | still
   ================================================================================================== */
.al-player { position: relative; margin: 0; background: var(--al-void); color: var(--al-text); isolation: isolate; }
.al-player-stage { position: relative; aspect-ratio: 16 / 9; overflow: hidden; background: var(--al-void); }
.al-player-video, .al-player-poster { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; display: block; background: var(--al-void); }
.al-player-poster { object-fit: cover; opacity: 0; transition: opacity var(--al-dur-scene) var(--al-ease); }
.al-player:is([data-state="idle"], [data-state="still"], [data-state="ended"]) .al-player-poster { opacity: 1; }
.al-player[data-state="still"] .al-player-video { visibility: hidden; }

/* Captions: always ours, never the browser's, so they follow the student's caption size and place */
.al-captions { position: absolute; z-index: 2; left: 50%; bottom: 7%; width: min(92%, 52rem); transform: translateX(-50%); text-align: center; pointer-events: none; }
.al-captions > span { display: inline; padding: 0.15em 0.5em; background: var(--al-scrim-caption); color: #ffffff; box-decoration-break: clone; -webkit-box-decoration-break: clone;
  font-family: var(--al-font-body); font-weight: 600; font-size: clamp(1rem, 0.85rem + 0.9cqi, 1.75rem); line-height: 1.6; }
.al-captions .al-captions-who { font-family: var(--al-font-mono); font-size: 0.7em; font-weight: 500; letter-spacing: 0.14em; text-transform: uppercase; color: #ffffffc7; margin-right: 0.5em; }
:root[data-captions="large"] .al-captions > span { font-size: clamp(1.25rem, 1rem + 1.4cqi, 2.25rem); }
:root[data-captions-at="top"] .al-captions { bottom: auto; top: 7%; }
.al-player.is-captions-off .al-captions { display: none; }
/* Captions follow the ear (launch.css, shell.js 01): a caption marked data-heard shows only when nothing was heard */
:root[data-captions-show="unheard"] [data-heard]:not([data-heard="no"]) { visibility: hidden; }
.al-player-stage { container-type: inline-size; }
/* A camera feed's burn-in (cutscene.js FEEDS): mono, lower left, 2.2% of the 16:9 frame's height (1.24cqi of its width) */
.al-player-feed { position: absolute; z-index: 2; left: 3%; bottom: 3%; margin: 0; pointer-events: none; white-space: pre;
  font-family: var(--al-font-mono); font-size: 1.24cqi; line-height: 1; letter-spacing: 0.06em; color: var(--al-text); font-variant-numeric: tabular-nums; }

.al-player-state { position: absolute; z-index: 3; left: var(--al-space-4); top: var(--al-space-4); margin: 0; padding: 3px var(--al-space-2); background: var(--al-scrim-caption);
  font-family: var(--al-font-mono); font-size: var(--al-text-2xs); letter-spacing: var(--al-tracking-mono); text-transform: uppercase; color: var(--al-text-secondary); display: none; }
.al-player[data-state="buffering"] .al-player-state { display: block; }
.al-player-quality { font-family: var(--al-font-mono); font-size: var(--al-text-2xs); letter-spacing: 0.14em; color: var(--al-text-muted); text-transform: uppercase; }
.al-player-start { position: absolute; z-index: 3; left: 50%; top: 50%; transform: translate(-50%, -50%); }
.al-player:not([data-state="idle"]):not([data-state="still"]) .al-player-start { display: none; }

/* The bar: under the frame, not over it, so no picture is hidden and no control disappears on a timer */
.al-player-bar { display: flex; align-items: center; gap: var(--al-space-2) var(--al-space-3); flex-wrap: wrap; padding: var(--al-space-2) var(--al-space-3); background: var(--al-ground); border-top: var(--al-line) solid var(--al-hairline); }
.al-player-bar .al-btn { min-height: 36px; padding-inline: var(--al-space-3); font-size: 0.8125rem; }
@media (pointer: coarse) { .al-player-bar .al-btn { min-height: var(--al-target); } }
.al-player-skip { margin-left: auto; }
.al-progress { flex: 1 1 8rem; min-width: 6rem; height: 3px; background: var(--al-hairline); position: relative; overflow: hidden; }
.al-progress::after { content: ""; position: absolute; inset: 0; background: var(--al-text); transform-origin: left; transform: scaleX(var(--al-progress, 0)); }
.al-player-time { font-family: var(--al-font-mono); font-size: var(--al-text-xs); color: var(--al-text-secondary); font-variant-numeric: tabular-nums; white-space: nowrap; }
/* Reduced motion: the still and its words. The transcript is the shot, read. */
.al-player-transcript { display: none; margin: 0; padding: var(--al-space-4) var(--al-space-5); background: var(--al-surface); font-family: var(--al-font-story); font-size: var(--al-text-md); line-height: var(--al-leading-story); color: var(--al-text-secondary); }
.al-player[data-state="still"] .al-player-transcript { display: block; }
.al-player[data-state="still"] .al-captions { display: none; }
/* The poster fallback (cutscene.js): the shot's frame with its captions timed over it, when the room's link or the
   class's lever says no video. It moves on by itself at the shot's length; the bar still pauses and skips it. */
.al-player[data-state="poster"] .al-player-poster { opacity: 1; }
.al-player[data-state="poster"] .al-player-video { visibility: hidden; }
/* The scene card (cutscene.js): a shot not yet delivered, told on its place's still (or the night plate when the media
   has none), its title over the frame and its lines as captions one at a time; Next and Continue are the student's. */
.al-scene-card .al-player-stage { background: radial-gradient(ellipse at 50% 120%, var(--al-ground), var(--al-void) 70%); }
.al-scene-card .al-player-poster { opacity: 0.55; }
.al-scene-card-title { position: absolute; z-index: 2; left: 0; right: 0; top: 12%; margin: 0; padding-inline: var(--al-space-5); text-align: center;
  font-family: var(--al-font-story); font-size: var(--al-text-2xl); line-height: var(--al-leading-tight); color: var(--al-text); text-shadow: 0 1px 12px #000; }
.al-scene-card .al-captions { bottom: 18%; }
.al-scene-card .al-captions > span { font-size: var(--al-text-lg); }
/* The cutscene over the page: one dialog, the frame as large as the window allows at 16:9, the bar under it. */
.al-cutscene { position: fixed; inset: 0; z-index: var(--al-z-player); display: grid; place-items: center; padding: var(--al-space-4);
  background: var(--al-void); overflow: auto; }
.al-cutscene > .al-player { width: min(100%, calc((100vh - 7rem) * 16 / 9)); }
/* A replay's shot or Moon beat, seen in play 1 (alpha/seen.js): its caption at the foot of the screen with Watch again,
   over nothing and waiting on nothing. It leaves by itself after a reading pace. */
.al-seen { position: fixed; z-index: var(--al-z-drawer); left: 50%; bottom: var(--al-space-5); transform: translateX(-50%);
  display: grid; gap: var(--al-space-2); width: min(40rem, calc(100vw - 32px)); padding: var(--al-space-4);
  background: var(--al-surface-raised); color: var(--al-text); box-shadow: var(--al-shadow-2), inset 0 0 0 var(--al-line) var(--al-hairline); }
.al-seen p { margin: 0; }
.al-seen-title { font-family: var(--al-font-mono); font-size: var(--al-text-2xs); letter-spacing: var(--al-tracking-mono); text-transform: uppercase; color: var(--al-text-secondary); }
.al-seen-words { font-family: var(--al-font-story); font-size: var(--al-text-md); line-height: var(--al-leading-story); max-height: 9.5em; overflow: auto; }
.al-seen-bar { display: flex; gap: var(--al-space-2); justify-content: flex-end; }

/* Title card: NINETEEN YEARS AGO. Mono, wide, alone on the black. */
.al-title-card { display: grid; place-items: center; aspect-ratio: 16 / 9; background: var(--al-void); padding: var(--al-space-6); text-align: center; }
.al-title-card-text { font-family: var(--al-font-mono); font-size: clamp(0.875rem, 0.6rem + 1.2vw, 1.5rem); font-weight: 500; letter-spacing: 0.42em; text-transform: uppercase; color: var(--al-text); padding-left: 0.42em; }
/* Act card: PART 5, The Light in the Crater. The mystery's own voice. */
.al-actcard { display: grid; align-content: center; justify-items: start; gap: var(--al-space-4); aspect-ratio: 16 / 9; padding: var(--al-space-7) clamp(24px, 8vw, 160px); background: var(--al-void); }
.al-actcard-part { font-family: var(--al-font-mono); font-size: var(--al-text-xs); letter-spacing: 0.4em; text-transform: uppercase; color: var(--al-text-muted); }
.al-actcard-title { font-family: var(--al-font-story); font-size: var(--al-text-3xl); font-weight: 400; line-height: 1.02; letter-spacing: -0.01em; color: var(--al-text); max-width: 14ch; }
.al-actcard-rule { width: 4rem; height: var(--al-rule); background: var(--al-lamp); box-shadow: 0 0 12px var(--al-lamp-glow); }
.al-actcard-day { font-family: var(--al-font-mono); font-size: var(--al-text-sm); letter-spacing: 0.2em; text-transform: uppercase; color: var(--al-text-secondary); }

/* ==================================================================================================
   15. Leon Tusk's feed. Captions only: no face, no voice. SpaceWhy's world is the one glossy thing on the Moon,
   so it is the one surface with no grain and a little too much polish; the station's side-eye answers underneath.
   ================================================================================================== */
.al-feed { display: grid; gap: var(--al-space-3); }
.al-feed-head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--al-space-3); padding-bottom: var(--al-space-2); border-bottom: var(--al-line) solid var(--al-hairline); }
.al-feed-brand { font-family: var(--al-font-stencil); font-weight: 600; font-size: var(--al-text-xl); letter-spacing: 0.02em; text-transform: none; color: var(--al-text); }
.al-feed-brand b { font-weight: 600; color: var(--al-flare); letter-spacing: 0.3em; text-transform: uppercase; font-size: 0.55em; vertical-align: 0.35em; margin-left: 0.4em; }
.al-feed-tagline { font-family: var(--al-font-body); font-size: var(--al-text-sm); font-style: normal; color: var(--al-text-muted); }
.al-post { display: grid; grid-template-columns: 2.5rem minmax(0, 1fr); gap: var(--al-space-1) var(--al-space-3); padding: var(--al-space-4);
  background: linear-gradient(160deg, var(--al-dust-3), transparent 45%), var(--al-surface-raised); border: var(--al-line) solid var(--al-hairline); }
.al-post-mark { grid-row: span 3; display: grid; place-items: center; width: 2.5rem; height: 2.5rem; background: var(--al-flare); color: var(--al-on-flare);
  font-family: var(--al-font-stencil); font-weight: 600; font-size: 0.9375rem; letter-spacing: 0.04em; }
.al-post-who { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 var(--al-space-2); font-size: var(--al-text-sm); }
.al-post-name { font-weight: 600; color: var(--al-text); }
.al-post-handle, .al-post-time { font-family: var(--al-font-mono); font-size: var(--al-text-xs); color: var(--al-text-muted); }
.al-post-body { font-family: var(--al-font-body); font-size: var(--al-text-lg); line-height: 1.4; color: var(--al-text); }
.al-post-meta { display: flex; flex-wrap: wrap; gap: var(--al-space-4); font-family: var(--al-font-mono); font-size: var(--al-text-2xs); letter-spacing: 0.1em; text-transform: uppercase; color: var(--al-text-muted); font-variant-numeric: tabular-nums; }
/* The side-eye: Voss, H.A.L., Seo, Calder answering underneath, in the people's voice */
.al-sideeye { grid-column: 2; margin-top: var(--al-space-3); padding: var(--al-space-3) 0 0 var(--al-space-3); border-top: var(--al-line) solid var(--al-hairline); box-shadow: inset var(--al-rule) 0 0 var(--al-edge); }
.al-sideeye-who { font-family: var(--al-font-mono); font-size: var(--al-text-2xs); letter-spacing: var(--al-tracking-mono); text-transform: uppercase; color: var(--al-text-muted); }
.al-sideeye-line { font-family: var(--al-font-story); font-style: italic; font-size: var(--al-text-md); line-height: var(--al-leading-story); color: var(--al-text-secondary); }

/* ==================================================================================================
   16. HUD and alerts
   ================================================================================================== */
.al-hud { position: sticky; top: 0; z-index: var(--al-z-hud); display: flex; flex-wrap: wrap; align-items: center; gap: var(--al-space-2) var(--al-space-5);
  min-height: 56px; padding: var(--al-space-2) var(--al-gutter); background: var(--al-ground); border-bottom: var(--al-line) solid var(--al-hairline); }
.al-hud-part { display: grid; gap: 2px; min-width: 0; }
.al-hud-part-title { font-family: var(--al-font-story); font-size: var(--al-text-lg); line-height: 1.2; color: var(--al-text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.al-hud-end { margin-left: auto; display: flex; flex-wrap: wrap; align-items: center; gap: var(--al-space-2) var(--al-space-5); }
/* The corner counter: T MINUS 60 DAYS TO CREW LANDING, then DAY 31 ON THE MOON. It never jumps. */
.al-counter { font-family: var(--al-font-mono); font-size: var(--al-text-sm); font-weight: 600; letter-spacing: 0.16em; text-transform: uppercase; color: var(--al-text); font-variant-numeric: tabular-nums; white-space: nowrap; }
.al-counter b { color: var(--al-lamp); font-weight: 700; }
/* The delay: what we know and how old it is. Earthshine, beside its word. */
.al-delay { display: inline-flex; align-items: center; gap: var(--al-space-2); font-family: var(--al-font-mono); font-size: var(--al-text-xs); letter-spacing: 0.14em; text-transform: uppercase; color: var(--al-earth); white-space: nowrap; }
.al-delay::before { content: ""; width: 18px; height: var(--al-rule); background: linear-gradient(90deg, var(--al-earth) 0 4px, transparent 4px 7px) 0 0 / 7px 100% repeat-x; }

/* Tasks: two or three open, in plain words, checked off as the log says */
.al-tasks { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--al-space-2); }
.al-task { display: grid; grid-template-columns: 14px minmax(0, 1fr); gap: var(--al-space-3); align-items: baseline; font-size: var(--al-text-md); line-height: 1.4; color: var(--al-text); }
.al-task::before { content: ""; width: 12px; height: 12px; translate: 0 1px; box-shadow: inset 0 0 0 var(--al-line) var(--al-edge); }
.al-task.is-done { color: var(--al-text-muted); text-decoration: line-through; text-decoration-color: var(--al-text-muted); }
.al-task.is-done::before { background: linear-gradient(var(--al-text-muted), var(--al-text-muted)) center / 6px 6px no-repeat; }
.al-task.is-new::before { box-shadow: inset 0 0 0 var(--al-rule) var(--al-lamp); }

/* Alerts: a region that stacks them, top right. data-tone: notice | lamp | alarm | filed */
.al-alerts { position: fixed; z-index: var(--al-z-alert); top: calc(56px + var(--al-space-3)); right: var(--al-gutter); display: grid; gap: var(--al-space-2); width: min(26rem, calc(100vw - 2 * var(--al-gutter))); pointer-events: none; }
.al-alert { pointer-events: auto; display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: var(--al-space-1) var(--al-space-3); align-items: start; padding: var(--al-space-3) var(--al-space-4);
  background: var(--al-surface-raised); border: var(--al-line) solid var(--al-edge); box-shadow: var(--al-shadow-2); animation: al-arrive var(--al-dur-ui) var(--al-ease-settle) both; }
.al-alert-title { font-family: var(--al-font-stencil); font-weight: 600; font-size: var(--al-text-md); letter-spacing: 0.12em; text-transform: uppercase; color: var(--al-text); }
.al-alert-text { grid-column: 1; font-size: var(--al-text-sm); color: var(--al-text-secondary); }
.al-alert-close { grid-column: 2; grid-row: 1 / span 2; }
.al-alert[data-tone="lamp"] { border-color: var(--al-lamp-line); box-shadow: var(--al-shadow-2), inset 3px 0 0 var(--al-lamp); }
/* The alarm: PROGRAM ALARM 1202. The brightest edge on the screen, and no hue. */
.al-alert[data-tone="alarm"] { border: var(--al-rule) solid var(--al-flare); background: var(--al-well); }
.al-alert[data-tone="alarm"] .al-alert-title { color: var(--al-flare); font-family: var(--al-font-mono); letter-spacing: 0.18em; }
/* Filed: an H.A.L. receipt. Mono, and it always ends "Filed." */
.al-alert[data-tone="filed"] .al-alert-title { font-family: var(--al-font-mono); font-size: var(--al-text-2xs); letter-spacing: var(--al-tracking-mono); color: var(--al-text-muted); }
.al-alert[data-tone="filed"] .al-alert-text { font-family: var(--al-font-mono); font-size: var(--al-text-sm); color: var(--al-text); }

/* Dialog: Second Chance, a confirmation. Use <dialog>; its backdrop is the scrim. */
.al-dialog { width: min(36rem, calc(100vw - 2 * var(--al-gutter))); padding: 0; border: var(--al-line) solid var(--al-edge); background: var(--al-surface); color: var(--al-text); box-shadow: var(--al-shadow-2); }
.al-dialog::backdrop { background: var(--al-shade); }
.al-dialog[open] { animation: al-arrive var(--al-dur-ui) var(--al-ease-settle) both; }
.al-dialog-body { display: grid; gap: var(--al-space-4); padding: var(--al-space-6) var(--al-space-6) var(--al-space-5); }
.al-dialog-title { font-family: var(--al-font-story); font-size: var(--al-text-2xl); line-height: 1.1; }
.al-dialog-log { font-family: var(--al-font-mono); font-size: var(--al-text-sm); letter-spacing: 0.06em; color: var(--al-text-secondary); padding: var(--al-space-2) var(--al-space-3); background: var(--al-well); }
.al-dialog-foot { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: var(--al-space-2); padding: var(--al-space-3) var(--al-space-6) var(--al-space-5); }

/* ==================================================================================================
   17. Motion. Three things move: arrival (dust settling), the lamp, a trace. Nothing else, and nothing at all
   when still. The lamp blinks only where data-state="blink"; it holds steady (ON) under reduced motion.
   ================================================================================================== */
@keyframes al-arrive { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
@keyframes al-blink { 0%, 62% { opacity: 1; } 70%, 92% { opacity: 0.18; } 100% { opacity: 1; } }
@keyframes al-settle { from { opacity: 0; filter: blur(2px); } to { opacity: 1; filter: none; } }
.al-lamp[data-state="blink"]::before { animation: al-blink var(--al-dur-blink) steps(1, end) infinite; }
.al-arrive { animation: al-arrive var(--al-dur-scene) var(--al-ease-settle) both; }
.al-actcard > * { animation: al-settle var(--al-dur-scene) var(--al-ease-settle) both; }
.al-actcard > :nth-child(2) { animation-delay: calc(var(--al-dur-scene) * 0.4); }
.al-actcard > :nth-child(n + 3) { animation-delay: calc(var(--al-dur-scene) * 0.8); }
:root.is-still :is(.al-lamp, .al-alert, .al-dialog, .al-arrive, .al-actcard > *, .al-actcard), :root.is-still .al-lamp::before { animation: none !important; }
:root.is-still .al-hotspot::before { transform: none; }
@media (prefers-reduced-motion: reduce) {
  :is(.al-lamp, .al-alert, .al-dialog, .al-arrive, .al-actcard > *), .al-lamp::before { animation: none !important; }
  .al-hotspot::before { transform: none; }
}

/* ==================================================================================================
   18. Small screens. Built for 1920 and 1366; at 360 everything is one column and nothing scrolls sideways.
   ================================================================================================== */
@media (max-width: 1100px) {
  .al-yard-run { grid-template-columns: minmax(0, 1fr); }
  .al-yard-run-side { order: -1; }
  .al-frame { grid-template-columns: minmax(0, 1fr); grid-template-areas: "hud" "main" "side"; }
  .al-frame-side { border-left: 0; border-top: var(--al-line) solid var(--al-hairline); }
  .al-split { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 720px) {
  .al-talk { grid-template-columns: minmax(0, 1fr); }
  .al-portrait { aspect-ratio: 4 / 3; }
  .al-timeline { grid-template-columns: minmax(6.5rem, 9rem) minmax(0, 1fr); }
  .al-place-head, .al-place-exits { padding: var(--al-space-2) var(--al-space-3); }
  .al-place { aspect-ratio: 4 / 3; }
  .al-place-head { flex-direction: column; gap: var(--al-space-1); }
  .al-place-name { font-size: var(--al-text-xl); }
  .al-place-head .al-switch { min-height: 32px; padding: 0; }
  .al-hud-end { margin-left: 0; width: 100%; justify-content: space-between; }
  .al-tile { grid-template-columns: 2rem minmax(0, 1fr); }
  .al-tile-tail { grid-column: 2; }
  .al-dialog-body { padding: var(--al-space-5) var(--al-space-4) var(--al-space-4); }
  .al-dialog-foot { padding: var(--al-space-3) var(--al-space-4) var(--al-space-4); }
  .al-player-skip { margin-left: 0; }
  .al-actcard, .al-title-card { aspect-ratio: auto; min-height: 20rem; }
}

/* ---- the two job frames (alpha/frames.js): at the controls has a window, the workbench does not ----
   wchesher, 2026-10-31: "at the chair has a window", "workbench does not", "you occupy one at a time", "make them feel
   like they are in that seat", "this may need some actual design". The student sits in one of them: a dark cab with a
   framed window and an instrument deck under it, or a lit bench against a pegboard wall. The head is the same in both. */
.al-seat { position: relative; display: grid; grid-template-rows: auto auto minmax(0, 1fr); gap: var(--al-space-3); min-height: 100vh;
  padding: var(--al-space-4) var(--al-space-5) var(--al-space-5); color: var(--al-text); isolation: isolate; }
.al-seat-head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--al-space-3) var(--al-space-5); }
.al-seat-title { display: grid; gap: 2px; }
.al-seat-title .al-heading { margin: 0; font-size: var(--al-text-xl, 1.5rem); }
.al-seat-back { gap: var(--al-space-3); background: var(--al-ground); }
.al-seat-lamp-words { font-family: var(--al-font-mono); font-size: var(--al-text-2xs); letter-spacing: var(--al-tracking-mono); text-transform: uppercase; color: var(--al-lamp); }
.al-seat-back .al-lamp[data-state="off"] { display: none; }
.al-seat-line { margin: 0; max-width: 62ch; padding-left: var(--al-space-3); border-left: var(--al-rule) solid var(--al-lamp); }
.al-seat-test:empty, .al-seat-parts:empty, .al-seat-bench-tag:empty, .al-seat-window-label:empty { display: none; }

/* AT THE CONTROLS: the screen wall. wchesher, 2026-10-31: "yes rebuild it, cyan glow" (on the control-room reference). The
   glow is cyan inside the seats only, overriding for them the 2026-10-30 rule of one warm light; the lamp stays Alpha's
   everywhere else, and "Back to console"'s lamp stays the lamp. Night is the dark room; Day (data-theme="day") the white. */
.al-seat-at-controls {
  --al-seat-glow: #3fe0ff; --al-seat-glow-soft: #3fe0ff59; --al-seat-glow-wash: #3fe0ff1f;
  --al-seat-room: #101317; --al-seat-room-panel: #161a1f; --al-seat-seam: #262c33; --al-seat-desk: #1b2026; --al-seat-desk-top: #2a3139;
  --al-seat-bezel: #2c333b; --al-seat-ink: #e9f6fa;
  background:
    linear-gradient(90deg, transparent calc(50% - 1px), var(--al-seat-seam) calc(50% - 1px) calc(50% + 1px), transparent calc(50% + 1px)),
    radial-gradient(60% 40% at 50% 0%, #ffffff12, transparent 70%),
    linear-gradient(var(--al-seat-room-panel), var(--al-seat-room) 70%);
  color: var(--al-seat-ink); }
:root[data-theme="day"] .al-seat-at-controls {
  --al-seat-glow: #00a9cf; --al-seat-glow-soft: #00a9cf4d; --al-seat-glow-wash: #00a9cf1a;
  --al-seat-room: #c9cfd4; --al-seat-room-panel: #e4e8eb; --al-seat-seam: #a9b1b8; --al-seat-desk: #d8dde1; --al-seat-desk-top: #f1f3f5;
  --al-seat-bezel: #b9c0c6; --al-seat-ink: #14191d; }
.al-seat-at-controls { grid-template-rows: auto minmax(0, 1fr); }
.al-seat-at-controls .al-heading { color: var(--al-seat-ink); }
.al-seat-chair { position: relative; display: grid; grid-template-rows: minmax(0, 1fr) auto; min-height: 0; padding-bottom: 54px; }
/* The wall: a side screen, the main screen, a side screen. Each screen is a bezel and a lit glass. */
.al-seat-wall { display: grid; grid-template-columns: minmax(9rem, 15rem) minmax(0, 1fr) minmax(9rem, 15rem); gap: var(--al-space-4); align-items: stretch; min-height: 0; }
.al-seat-screen { position: relative; display: grid; min-height: 0; padding: 8px; border-radius: 12px; background: var(--al-seat-bezel);
  box-shadow: inset 0 1px 0 #ffffff1f, 0 0 0 1px #00000066, 0 0 28px -6px var(--al-seat-glow-soft); }
.al-seat-glass-side { align-self: center; height: 78%; }
.al-seat-screen-in { position: relative; min-height: 0; overflow: hidden; border-radius: 6px; background: #05080b;
  box-shadow: inset 0 0 0 1px var(--al-seat-glow-soft), inset 0 0 24px var(--al-seat-glow-wash); }
.al-seat-side-in { display: grid; align-content: start; gap: var(--al-space-3); padding: var(--al-space-3); color: #e9f6fa;
  background: linear-gradient(var(--al-seat-glow-wash), transparent 40%), #05080b; }
.al-seat-side-in::before { content: attr(data-label); font-family: var(--al-font-mono); font-size: var(--al-text-2xs); letter-spacing: var(--al-tracking-mono);
  text-transform: uppercase; color: var(--al-seat-glow); }
.al-seat-face { display: grid; place-items: center; aspect-ratio: 1; border: 1px solid var(--al-seat-glow-soft); border-radius: 50%; overflow: hidden;
  background: radial-gradient(circle at 50% 40%, var(--al-seat-glow-wash), transparent 70%); }
.al-seat-face:empty { display: none; }
.al-seat-face > * { width: 100%; height: 100%; object-fit: cover; }
.al-seat-at-controls .al-seat-line { padding: 0; border: 0; font-size: var(--al-text-sm, 0.95rem); color: #e9f6fa; }
.al-seat-window { position: relative; height: 100%; min-height: 46vh; }
.al-seat-window > * { width: 100%; height: 100%; }
/* The main screen's camera: corner ticks and a faint scan glare, over whatever it shows. */
.al-seat-window::after { content: ""; position: absolute; inset: 0; pointer-events: none; z-index: 2;
  background:
    linear-gradient(160deg, #ffffff12 0%, transparent 30%),
    repeating-linear-gradient(#ffffff05 0 1px, transparent 1px 3px),
    linear-gradient(var(--al-seat-glow), var(--al-seat-glow)) 14px 14px / 20px 2px no-repeat, linear-gradient(var(--al-seat-glow), var(--al-seat-glow)) 14px 14px / 2px 20px no-repeat,
    linear-gradient(var(--al-seat-glow), var(--al-seat-glow)) calc(100% - 14px) 14px / 20px 2px no-repeat, linear-gradient(var(--al-seat-glow), var(--al-seat-glow)) calc(100% - 14px) 14px / 2px 20px no-repeat,
    linear-gradient(var(--al-seat-glow), var(--al-seat-glow)) 14px calc(100% - 14px) / 20px 2px no-repeat, linear-gradient(var(--al-seat-glow), var(--al-seat-glow)) 14px calc(100% - 14px) / 2px 20px no-repeat,
    linear-gradient(var(--al-seat-glow), var(--al-seat-glow)) calc(100% - 14px) calc(100% - 14px) / 20px 2px no-repeat, linear-gradient(var(--al-seat-glow), var(--al-seat-glow)) calc(100% - 14px) calc(100% - 14px) / 2px 20px no-repeat; }
.al-seat-window-label { position: absolute; z-index: 3; top: 12px; left: 50%; transform: translateX(-50%); padding: 2px 10px;
  font-family: var(--al-font-mono); font-size: var(--al-text-2xs); letter-spacing: var(--al-tracking-mono); text-transform: uppercase;
  color: var(--al-seat-glow); background: #000000b3; border: 1px solid var(--al-seat-glow-soft); }
.al-seat-readouts { display: grid; gap: var(--al-space-2); }
.al-seat-readouts > * { padding: 6px 10px; font-family: var(--al-font-mono); font-size: var(--al-text-sm); font-variant-numeric: tabular-nums;
  color: var(--al-seat-glow); border-left: 2px solid var(--al-seat-glow); background: var(--al-seat-glow-wash); }
/* The desk: its top under the screens, a lit front edge, the controls on it. */
.al-seat-desk { position: relative; display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: var(--al-space-3);
  margin-top: var(--al-space-3); padding: var(--al-space-4) var(--al-space-5) calc(var(--al-space-4) + 6px);
  background: linear-gradient(var(--al-seat-desk-top), var(--al-seat-desk)); border-radius: 6px 6px 2px 2px;
  box-shadow: inset 0 1px 0 #ffffff26, 0 14px 30px -14px #000000; }
.al-seat-desk::after { content: ""; position: absolute; left: 4%; right: 4%; bottom: 3px; height: 3px; border-radius: 2px;
  background: var(--al-seat-glow); box-shadow: 0 0 12px 2px var(--al-seat-glow-soft); }
.al-seat-at-controls .al-btn { color: var(--al-seat-ink); border-color: var(--al-seat-glow-soft); background: var(--al-seat-desk); }
.al-seat-at-controls .al-btn:hover { border-color: var(--al-seat-glow); box-shadow: 0 0 10px var(--al-seat-glow-wash); }
/* The chair: its back's top edge, at the bottom of the screen, so the student is in it. */

/* THE WORKBENCH. No window: a pegboard wall, a task lamp's pool on a cutting mat, a parts tray at the side. */
.al-seat-workbench { background:
  radial-gradient(80% 55% at 42% 45%, #ffb07026, transparent 70%),
  linear-gradient(90deg, transparent calc(33% - 1px), #15181b calc(33% - 1px) calc(33% + 1px), transparent calc(33% + 1px),
    transparent calc(66% - 1px), #15181b calc(66% - 1px) calc(66% + 1px), transparent calc(66% + 1px)),
  radial-gradient(circle, #121417 1.7px, transparent 2.3px) 9px 9px / 18px 18px,
  linear-gradient(#41464c, #33373c); color: #ece9e2; }
.al-seat-workbench .al-seat-head { padding: var(--al-space-2) var(--al-space-3); background: #1b1a17e6; border-radius: 4px; }
.al-seat-workbench .al-seat-line { background: #1b1a17e6; padding: var(--al-space-2) var(--al-space-3); }
.al-seat-workbench .al-heading { color: #f4f1ea; }
.al-seat-bench { position: relative; margin-top: 44px; display: grid; grid-template-columns: minmax(0, 1fr) minmax(13rem, 17rem); gap: var(--al-space-4); align-items: stretch;
  padding: var(--al-space-5) var(--al-space-5) var(--al-space-6); border-radius: 4px;
  /* a space lab's bench: brushed steel, a rolled front edge */
  background: repeating-linear-gradient(90deg, #ffffff06 0 1px, transparent 1px 3px), linear-gradient(#5d5c58, #4a4946 70%, #3a3936);
  border-top: 5px solid #8a8883; border-bottom: 8px solid #2a2927; box-shadow: 0 30px 50px -24px #000000, inset 0 1px 0 #ffffff33; }
.al-seat-bench-tag { position: absolute; right: var(--al-space-5); top: 4px; padding: 3px 8px;
  font-family: var(--al-font-mono); font-size: var(--al-text-2xs); letter-spacing: var(--al-tracking-mono); text-transform: uppercase;
  color: #1a1917; background: #d9d4c7; }
/* The lamp overhead: its arm reaches in from the top, its light pools on the mat. */
.al-seat-bench::before { content: ""; position: absolute; top: -40px; left: 38%; width: 120px; height: 34px; border-radius: 60px 60px 10px 10px;
  background: linear-gradient(#3a3834, #22211e); box-shadow: 0 6px 0 -2px var(--al-lamp), 0 14px 40px 6px #ff7a2e40; }
.al-seat-piece { position: relative; display: grid; grid-template-rows: minmax(0, 1fr) auto; gap: var(--al-space-3); min-height: 42vh; padding: var(--al-space-5);
  border-radius: 6px; color: #f4f1ea;
  /* the static-safe mat, gridded, in the lamp's warm pool */
  background:
    radial-gradient(75% 70% at 45% 0%, #ffb07040, #ff7a2e14 45%, transparent 75%),
    linear-gradient(#ffffff0f 1px, transparent 1px) 0 0 / 24px 24px,
    linear-gradient(90deg, #ffffff0f 1px, transparent 1px) 0 0 / 24px 24px,
    #2a3036;
  border: 1px solid #14181b; box-shadow: inset 0 0 0 1px #ffffff14, 0 3px 0 #00000066; }
.al-seat-work { min-height: 0; }
.al-seat-test { display: flex; flex-wrap: wrap; gap: var(--al-space-3); padding-top: var(--al-space-3); border-top: 1px dashed #ffffff33; }
/* The tray: compartments, the parts in them. */
.al-seat-parts { display: grid; grid-auto-rows: minmax(56px, auto); gap: 6px; align-content: start; padding: 8px; border-radius: 6px;
  background: #121110; border: 1px solid #000000; box-shadow: inset 0 3px 8px #000000; }
.al-seat-parts > * { display: flex; align-items: center; gap: var(--al-space-2); padding: 8px 10px; border-radius: 3px;
  background: linear-gradient(#2a2926, #201f1c); box-shadow: inset 0 1px 0 #ffffff12, inset 0 -1px 0 #00000080; }
.al-seat-room { position: relative; display: grid; gap: 0; min-height: 0; }
.al-seat-workbench .al-seat-bench { margin-top: 0; border-radius: 4px 4px 0 0; }
.al-seat-workbench .al-btn { color: #f4f1ea; border-color: #8a857c; background: #1e1d1a; }

/* The room fits the screen: the main screen takes what the head and the desk leave, so the desk is never under the fold. */
@media (min-width: 721px) {
  .al-seat-at-controls { height: 100vh; min-height: 560px; }
  .al-seat-chair, .al-seat-screen { min-height: 0; }
  .al-seat-window { min-height: 0; }
}
@media (max-width: 720px) {
  .al-seat { padding: var(--al-space-3) var(--al-space-4) var(--al-space-4); }
  /* A phone: the main screen, then the desk's controls, then the crewmate and the readouts, compact. */
  .al-seat-chair { display: flex; flex-direction: column; gap: var(--al-space-3); }
  .al-seat-wall { display: contents; }
  .al-seat-glass-main { order: 1; }
  .al-seat-desk { order: 2; margin-top: 0; }
  .al-seat-glass-side { order: 3; height: auto; align-self: stretch; }
  .al-seat-side-in { grid-template-columns: auto minmax(0, 1fr); align-items: center; }
  .al-seat-side-in::before { grid-column: 1 / -1; }
  .al-seat-face { width: 56px; }
  .al-seat-chair { padding-bottom: 0; }
  .al-seat-bench { grid-template-columns: minmax(0, 1fr); padding: var(--al-space-4); }
  .al-seat-bench::before { display: none; }
  .al-seat-window, .al-seat-piece { min-height: 38vh; }
}

@media print {
  .al-page, .al-night { background: #ffffff; color: #000000; }
  .al-grain::after, .al-place::before, .al-place::after { display: none; }
  .al-hud, .al-alerts, .al-player-bar { display: none; }
}

/* The rooms are rendered from the bought sets (frames.js ROOMS; wchesher, 2026-11-01, "no you block the shot. Use the
   awesome preconfigured sets", "yes!"). On a wide screen the stage keeps the picture's 16:9, fitted under the head, and
   each placed slot sits over its place in the picture, its fractions set by frames.js. On a phone the picture is the
   backdrop, darkened, and the slots stack as before. */
.al-seat-stage { background: linear-gradient(#05080bcc, #05080bcc), var(--al-seat-picture) center / cover no-repeat; border-radius: 6px; }
.al-seat-room.al-seat-stage { padding: var(--al-space-3); }
.al-seat-at-controls, .al-seat-workbench { background: #05070a; }
.al-seat-stage .al-seat-bench { background: none; border: 0; box-shadow: none; }
.al-seat-stage .al-seat-bench::before { content: none; }
@media (min-width: 721px) {
  .al-seat-stage { position: relative; align-self: start; justify-self: center; aspect-ratio: 16 / 9; padding: 0;
    width: min(100%, calc((100vh - 7.5rem) * 16 / 9)); min-height: 0; background: var(--al-seat-picture) center / 100% 100% no-repeat; }
  /* At the controls, the picture is a layer the camera can push into (frames.js pushIn): seen whole first, then scaled
     so the console's screen spans the stage. The slots glide from their places in the room to their places on the
     screen in the same move. */
  .al-seat-chair.al-seat-stage { overflow: hidden; background: #05070a; }
  .al-seat-chair.al-seat-stage::before { content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none;
    background: var(--al-seat-picture) center / 100% 100% no-repeat; transform-origin: 0 0;
    transition: transform 1.6s cubic-bezier(0.45, 0, 0.2, 1), filter 1.6s ease; }
  .al-seat-chair.al-seat-zoomed::before { transform: translate(var(--al-seat-zoom-x), var(--al-seat-zoom-y)) scale(var(--al-seat-zoom-scale));
    filter: brightness(0.55) blur(1px); }
  .al-seat-chair .al-seat-wall, .al-seat-chair > .al-seat-desk { z-index: 1; }
  .al-seat-chair .al-seat-placed { transition: left 1.6s cubic-bezier(0.45, 0, 0.2, 1), top 1.6s cubic-bezier(0.45, 0, 0.2, 1),
    right 1.6s cubic-bezier(0.45, 0, 0.2, 1), bottom 1.6s cubic-bezier(0.45, 0, 0.2, 1), opacity 0.6s ease 1s; }
  /* The room is seen clean first; the screens light as the camera arrives. */
  .al-seat-chair:not(.al-seat-zoomed) .al-seat-placed { opacity: 0; transition-delay: 0s; }
  /* The workbench's head carries the crewmate's line under it: a row more to leave above the room. */
  .al-seat-workbench .al-seat-stage { width: min(100%, calc((100vh - 11.5rem) * 16 / 9)); }
  .al-seat-stage .al-seat-wall, .al-seat-stage .al-seat-bench { position: absolute; inset: 0; display: block; margin: 0; padding: 0;
    background: none; border: 0; box-shadow: none; }
  .al-seat-stage .al-seat-bench::before { content: none; }
  .al-seat-placed { position: absolute; box-sizing: border-box; min-height: 0; height: auto; overflow: auto;
    left: calc(var(--al-seat-left) * 100%); top: calc(var(--al-seat-top) * 100%);
    right: calc((1 - var(--al-seat-right)) * 100%); bottom: calc((1 - var(--al-seat-bottom)) * 100%); }
  /* The window IS the floating screen: no bezel of our own, the room's glow around it. */
  .al-seat-stage .al-seat-glass-main { padding: 0; border-radius: 4px; background: none; box-shadow: 0 0 32px -4px var(--al-seat-glow-soft); }
  .al-seat-stage .al-seat-glass-main .al-seat-screen-in, .al-seat-stage .al-seat-window { height: 100%; }
  /* The side panels are glass held against the room. */
  .al-seat-stage .al-seat-glass-side { align-self: auto; height: auto; padding: 4px; background: #0b1218b3; backdrop-filter: blur(3px); }
  .al-seat-stage .al-seat-desk { padding: var(--al-space-2); background: #0b1218cc; border-radius: 6px; box-shadow: 0 0 0 1px var(--al-seat-glow-soft); }
  .al-seat-stage .al-seat-desk::after { content: none; }
  .al-seat-chair.al-seat-stage { padding-bottom: 0; display: block; }
  /* The bench: the piece on the bench top under the room's own lamp light, the parts on the floor beside it. */
  .al-seat-stage .al-seat-piece { min-height: 0; padding: var(--al-space-3); background: #0b1014bf; backdrop-filter: blur(2px);
    border: 1px solid #ffffff26; }
  .al-seat-stage .al-seat-parts { background: #0b1014cc; }
  .al-seat-stage .al-seat-bench-tag { top: 8px; right: 8px; }
}

@media (prefers-reduced-motion: reduce) {
  .al-seat-chair.al-seat-stage::before, .al-seat-chair .al-seat-placed { transition: none; }
}
