/* ═══════════════════════════════════════════════════════════════
   Your hospital's AI programme. Windows classic, as it looked in 2000.

   What changed and why: the previous "calm desk" stylesheet was the
   default look a language model produces (paper tones, one teal, serif
   headings, pills, soft shadows). DESIGN.md lists the tells. This file
   replaces all of it. The desk is a desktop: the programme is a tabbed
   window, the quarter's figures run as their own small program, the
   diary is a text file open in a notepad, and a taskbar with a Start
   menu sits along the bottom. Proposals are cards drawn as small
   windows, events are message boxes, decisions are dialog icons.
   Grey chrome, one-pixel-plus-one-pixel bevels, navy title bars,
   Tahoma. Nothing rounded, nothing soft.

   Content this look needed: once events became email messages, the
   third-person card text read as narration, so every event body in
   content/ was rewritten in the sender's own words, dated notices got
   an automated "Regulatory calendar" sender, and a reply may carry its
   own article chip (one line in js/engine.js). DESIGN.md allows this.

   The render code in js/ui.js and js/screens.js is untouched: every
   class it emits is restyled under its old name. index.html adds the
   title bars, client areas, the two side programs and the taskbar.
   ═══════════════════════════════════════════════════════════════ */

:root {
  --face: #c0c0c0;
  --face-light: #dfdfdf;
  --chart-bg: #000000; --chart-grid: #008040; --chart-line: #00ff00; --chart-mark: #ffff00; /* the performance-monitor graph on the review */
  --hilight: #ffffff;
  --shadow: #808080;
  --dark: #000000;
  --title-a: #0a246a;
  --title-b: #a6caf0;
  --title-text: #ffffff;
  --window: #ffffff;
  --window-text: #000000;
  --desktop: #3a6ea5;
  --select: #0a246a;
  --select-text: #ffffff;
  --gray-text: #303030;
  --disabled-text: #5a5a5a;
  --link: #0000ff;
  --info: #ffffe1;
  --stamp-green: #008000;
  --stamp-red: #c00000;
  --band-watchful: #f0c000; /* the watchful band as a fill (the review's year blocks); amber is its text colour */
  --stamp-blue: #000080;
  --stamp-amber: #b08000;
  /* The four figures' icon colours (js/ui.js RES_LABEL, C.ICONS.res): 3:1 on the window, the face and the modern surface. */
  --res-budget: #8a5a00;
  --res-capacity: #1a5fb4;
  --res-benefit: #b0125e;
  --res-trust: #6b3fb5;
  --font: Tahoma, "MS Sans Serif", Arial, "Segoe UI", sans-serif;
  --font-mono: "Courier New", Courier, monospace;
  /* Department colours: the same hex as content/meta.json departments (tests/css.test.js holds them level). Each gives
     3:1 as a dot or stripe on the light and dark surfaces and 4.5:1 under white text on the kicker bar. */
  --dept-emergency-department: #d0662f;
  --dept-acute-medicine: #cd5263;
  --dept-radiology: #677baa;
  --dept-pharmacy: #288a7c;
  --dept-nursing: #c8553d;
  --dept-outpatients: #b8860b;
  --dept-operations: #a47229;
  --dept-human-resources: #6f8a3d;
  --dept-education-and-training: #768326;
  --dept-it: #26879a;
  --dept-data-and-analytics: #3780bf;
  --dept-research: #8a6cc0;
  --dept-communications: #b9567e;
  --dept-finance: #358b60;
  --dept-governance: #8f7760;
  --dept-executive: #9d65b5;
  --dept-outside: #7b7b7b;
  --dept-staff-side: #bd51b4;
  --dept-patients: #7373ca;
  --action: #5b3cf5; /* programmes and one-offs: things you can do, in a colour no department has (tests/css.test.js) */
  /* The action icons' families (js/ui.js actionIcon; .ic-action.ic-<key> below): one colour per meaning, so the stops are
     all red and the two ways of waiting share a plum. Each holds 3:1 on the window, the classic face and the modern
     surface, and the seven are at least ΔE 30 apart (tests/css.test.js). */
  --act-do: var(--action); --act-money: var(--res-budget); --act-staff: var(--res-capacity); --act-stop: var(--stamp-red);
  --act-pilot: #0b6b62; --act-wait: #7a2a8a; --act-on: #0a6b0a;
  --dept: var(--shadow);
  --target: 23px;
  --titlebar: 18px;
}
[data-dept="emergency-department"] { --dept: var(--dept-emergency-department); }
[data-dept="acute-medicine"] { --dept: var(--dept-acute-medicine); }
[data-dept="radiology"] { --dept: var(--dept-radiology); }
[data-dept="pharmacy"] { --dept: var(--dept-pharmacy); }
[data-dept="nursing"] { --dept: var(--dept-nursing); }
[data-dept="outpatients"] { --dept: var(--dept-outpatients); }
[data-dept="operations"] { --dept: var(--dept-operations); }
[data-dept="human-resources"] { --dept: var(--dept-human-resources); }
[data-dept="education-and-training"] { --dept: var(--dept-education-and-training); }
[data-dept="it"] { --dept: var(--dept-it); }
[data-dept="data-and-analytics"] { --dept: var(--dept-data-and-analytics); }
[data-dept="research"] { --dept: var(--dept-research); }
[data-dept="communications"] { --dept: var(--dept-communications); }
[data-dept="finance"] { --dept: var(--dept-finance); }
[data-dept="governance"] { --dept: var(--dept-governance); }
[data-dept="executive"] { --dept: var(--dept-executive); }
[data-dept="outside"] { --dept: var(--dept-outside); }
[data-dept="staff-side"] { --dept: var(--dept-staff-side); }
[data-dept="patients"] { --dept: var(--dept-patients); }

/* Dark is the "High Contrast Black" scheme: black face, white text, purple title bars, green selection. */
:root[data-theme="dark"] {
  --face: #000000; --face-light: #404040; --hilight: #ffffff; --shadow: #808080; --dark: #c0c0c0;
  --title-a: #800080; --title-b: #000000; --title-text: #ffffff;
  --window: #000000; --window-text: #ffffff; --desktop: #000000; --select: #008000; --select-text: #ffffff;
  --gray-text: #c0c0c0; --disabled-text: #a0a0a0; --link: #80ff80; --info: #000000;
  --stamp-green: #40ff40; --stamp-red: #ff6060; --stamp-blue: #80c0ff; --stamp-amber: #ffd040;
  --res-budget: #f0b940; --res-capacity: #78b8ff; --res-benefit: #ff7ab8; --res-trust: #c3a6ff;
  --action: #a896ff;
  --act-pilot: #3fd0c0; --act-wait: #f080d0; --act-on: #58d058;
}
@media (pointer: coarse) { :root { --target: 44px; --titlebar: 30px; } }

/* ── Base ── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html { font-size: 13px; }
body { font-family: var(--font); font-size: 1rem; line-height: 1.4; background: var(--desktop); color: var(--window-text); min-height: 100dvh; overflow-x: hidden; }
html:has(body.ui-large-text) { font-size: 15px; } /* Larger text grows the root, so everything sized in rem grows with it, paragraphs included */
body.high-contrast { --gray-text: var(--window-text); --shadow: var(--dark); --face-light: var(--hilight); --res-budget: var(--window-text); --res-capacity: var(--window-text); --res-benefit: var(--window-text); --res-trust: var(--window-text); }
h1, h2, h3, .sheet-title { font-family: var(--font); font-weight: 700; line-height: 1.25; }
h1 { font-size: 1.5rem; } h2 { font-size: 1.15rem; } h3 { font-size: 1rem; margin: 10px 0 4px; }
p { margin-bottom: 0.7em; }
button { font: inherit; color: inherit; background: none; border: none; cursor: default; }
a { color: var(--link); }
.hidden { display: none !important; }
.hint { color: var(--gray-text); font-size: 0.92rem; }
.small { font-size: 0.9rem; }
.badge { color: var(--gray-text); font-size: 0.85rem; margin-top: 12px; }
.build-line { font-size: 0.8rem; color: var(--window-text); opacity: 0.7; margin: 4px 0 0; overflow-wrap: anywhere; }
.prose p { color: var(--window-text); }
.scene { font-size: 1rem; color: var(--window-text); }
.mono { font-family: var(--font-mono); }
*:focus-visible { outline: 1px dotted var(--window-text); outline-offset: -4px; }
input, select { font: inherit; color: var(--window-text); background: var(--window); border: 1px solid; border-color: var(--shadow) var(--hilight) var(--hilight) var(--shadow); box-shadow: inset 1px 1px var(--dark), inset -1px -1px var(--face-light); padding: 2px 4px; border-radius: 0; min-height: var(--target); }
input[type="checkbox"] { min-height: 0; width: 13px; height: 13px; margin-right: 6px; }

/* ── Bevels: one pixel outside, one pixel inside, the way Win95 drew them ── */
.btn, .choice, .start-card, .folder-tab, .drawer-tab, .task-btn, .start-btn, .folder-panel, .turn-banner, .air-pill, .more-menu, .menu-sub, .doc, .btn-small {
  border: 1px solid; border-color: var(--hilight) var(--dark) var(--dark) var(--hilight); box-shadow: inset -1px -1px var(--shadow), inset 1px 1px var(--face-light); background: var(--face); border-radius: 0;
}
.win, .sheet, .drawer-panel, .taskbar {
  border: 1px solid; border-color: var(--face-light) var(--dark) var(--dark) var(--face-light); box-shadow: inset -1px -1px var(--shadow), inset 1px 1px var(--hilight); background: var(--face); border-radius: 0;
}
.mg-field, .mg-readout, .mg-meter, .mg-art, .mg-install, .mg-pip, .mg-score-bar, .pane, .register, .programmes-list, .timeline, .story, .log-peek, .drawer-body, .num, .trust, .leaf, .trust-bar-wrap, .controls, .file, .ledger-wrap, .notice, .surcharge, .review-cell, .ledger-q, .metric-chip, .cast-list, .cast-folders, .choice.chosen, .choice:active, .btn:active, .start-card:active, .task-btn[aria-pressed="true"], .task-btn:active, .start-btn[aria-expanded="true"] {
  border: 1px solid; border-color: var(--shadow) var(--hilight) var(--hilight) var(--shadow); box-shadow: inset 1px 1px var(--dark), inset -1px -1px var(--face-light); border-radius: 0;
}
.pane, .register, .programmes-list, .timeline, .story, .log-peek, .drawer-body, .controls, .ledger-wrap, .review-cell, .metric-chip, .cast-list, .cast-folders { background: var(--window); color: var(--window-text); }

/* ── Screens (prototype pattern kept: stacked fixed layers, cross-fade) ── */
.screen { position: fixed; inset: 0; display: flex; flex-direction: column; min-height: 100dvh; transition: opacity 0.2s; overflow: auto; scroll-padding-top: 12px; }
.screen.hidden { display: flex !important; opacity: 0; pointer-events: none; }
.screen.hidden * { pointer-events: none !important; }
.transition-overlay { position: fixed; inset: 0; background: var(--desktop); opacity: 0; pointer-events: none; transition: opacity 0.2s; z-index: 90; }
.transition-overlay.active { opacity: 1; pointer-events: auto; }

/* ── Windows ── */
.win, .sheet { position: relative; padding: 2px; }
.titlebar { display: flex; align-items: center; gap: 5px; height: var(--titlebar); padding: 0 2px 0 5px; background: linear-gradient(90deg, var(--title-a), var(--title-b)); color: var(--title-text); font-weight: 700; font-size: 0.95rem; user-select: none; }
.titlebar-icon { font-size: 0.9rem; line-height: 1; width: 14px; text-align: center; }
.titlebar-text { flex: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.titlebar-text h2 { display: inline; font: inherit; }
.close-btn { position: static; width: 16px; height: 14px; min-width: 0; min-height: 0; line-height: 1; font-size: 12px; font-weight: 700; color: var(--dark); background: var(--face); border: 1px solid; border-color: var(--hilight) var(--dark) var(--dark) var(--hilight); box-shadow: inset -1px -1px var(--shadow), inset 1px 1px var(--face-light); padding: 0 0 1px; margin-left: 2px; flex: none; }
.close-btn:active { border-color: var(--dark) var(--hilight) var(--hilight) var(--dark); box-shadow: none; }
@media (pointer: coarse) { .close-btn { width: 32px; height: 26px; font-size: 16px; } }
.client { padding: 10px 10px 10px; }
.sheet-meta { display: flex; justify-content: space-between; gap: 12px; font-size: 0.9rem; color: var(--gray-text); margin-bottom: 6px; flex-wrap: wrap; }
.sheet-meta > span:first-child { color: var(--window-text); }
.sheet-meta > span:first-child:not(:empty)::before { content: ''; display: inline-block; width: 9px; height: 9px; background: var(--dept); border: 1px solid var(--dark); margin-right: 6px; vertical-align: -1px; }
.sheet-title { font-size: 1.15rem; margin: 2px 0 8px; }
.sheet-tall { max-width: 720px; }
.sheet-narrow { max-width: 420px; }

/* ── Buttons: 23px, one line, centred, the default one ringed in black ── */
.btn { min-height: var(--target); min-width: 75px; padding: 1px 12px; font-size: 1rem; color: var(--window-text); text-align: center; line-height: 1.3; white-space: nowrap; }
.btn:active { padding: 2px 11px 0 13px; }
.btn-primary { font-weight: 700; outline: 1px solid var(--dark); outline-offset: 0; position: relative; }
.btn-primary:focus-visible { outline: 1px solid var(--dark); }
.btn-primary:focus-visible::before { content: ''; position: absolute; inset: 3px; border: 1px dotted var(--window-text); pointer-events: none; }
.btn-danger { color: var(--stamp-red); }
.btn[disabled] { color: var(--disabled-text); cursor: not-allowed; }
.btn[disabled]:active { padding: 1px 12px; border-color: var(--hilight) var(--dark) var(--dark) var(--hilight); box-shadow: inset -1px -1px var(--shadow), inset 1px 1px var(--face-light); }
.btn small { display: inline; font-weight: 400; font-size: 0.85rem; color: var(--gray-text); margin-left: 8px; }
.btn[disabled] small { color: inherit; }
.btn-small { min-height: 21px; min-width: 0; padding: 0 9px; font-size: 0.92rem; }
.link-btn { color: var(--link); text-decoration: underline; font-size: 1rem; padding: 2px 0; min-height: var(--target); }
.actions { display: flex; flex-wrap: wrap; gap: 6px; justify-content: flex-end; margin: 12px 0 4px; }
.actions .btn { white-space: normal; }
.actions .btn-primary { order: -1; }
#sys-actions, #prog-actions, #iv-actions { display: grid; grid-template-columns: 1fr; gap: 4px; }
#sys-actions .btn, #prog-actions .btn, #iv-actions .btn { display: grid; grid-template-columns: 110px 1fr; gap: 8px; align-items: baseline; text-align: left; padding: 4px 10px; min-width: 0; }
#sys-actions .btn small, #prog-actions .btn small, #iv-actions .btn small { margin-left: 0; }
/* The proposal sheet's buttons carry only their title; the dots beneath say which resources move (hover lights them). */
#sys-actions { grid-template-columns: repeat(auto-fit, minmax(82px, 1fr)); }
#sys-actions .btn { display: flex; flex-direction: column; align-items: center; justify-content: flex-start; text-align: center; gap: 2px; padding: 6px 6px; }
#sys-actions .btn .res-dots { margin-top: 0; justify-content: center; gap: 6px; }
#sys-actions .btn .btn-label { line-height: 1.2; }
/* The proposal's buttons are tiles: the action's picture on top, big enough to find at a glance. */
#sys-actions .btn .btn-label .ic { display: block; width: 20px; height: 20px; margin: 0 auto 3px; }

/* Action buttons (the proposal's tiles, a programme's sizes and stop, a one-off's Do it, a control's Fund) keep the
   desktop's own button face. What tells them apart is the period's disabled look: on the old desktop, etched text (grey
   with a white shadow below right) and a grey icon; on the new one, the pale fill, text and border of its disabled
   buttons (css/modern.css). A button that can be pressed shows its action's icon in its family's colour (--act, set
   per key under Icons below; the action colour where a button has no key). */
:is(#sys-actions .btn, #prog-actions .btn, #iv-actions .btn, #prog-levels .choice, .control .btn-small):not([disabled]):not(.btn-primary) .ic-action { color: var(--act); }
body:not([data-os="modern"]) :is(#sys-actions .btn, #prog-actions .btn, #iv-actions .btn, .control .btn-small).btn-primary:not([disabled]) .ic-action { color: var(--act); }
body:not([data-os="modern"]) :is(#sys-actions .btn, #prog-actions .btn, #iv-actions .btn, #prog-levels .choice:not(.chosen), .control .btn-small)[disabled],
body:not([data-os="modern"]) :is(#sys-actions .btn, #prog-actions .btn, #iv-actions .btn, #prog-levels .choice:not(.chosen), .control .btn-small)[disabled] :is(small, span, strong) { color: var(--shadow); text-shadow: 1px 1px var(--hilight); opacity: 1; }
:root[data-theme="dark"] body:not([data-os="modern"]) :is(#sys-actions .btn, #prog-actions .btn, #iv-actions .btn, #prog-levels .choice:not(.chosen), .control .btn-small)[disabled],
:root[data-theme="dark"] body:not([data-os="modern"]) :is(#sys-actions .btn, #prog-actions .btn, #iv-actions .btn, #prog-levels .choice:not(.chosen), .control .btn-small)[disabled] :is(small, span, strong) { color: var(--disabled-text); text-shadow: none; }
:is(#sys-actions .btn, #prog-actions .btn, #iv-actions .btn, #prog-levels .choice, .control .btn-small)[disabled] .ic,
:is(#sys-actions .btn, #prog-actions .btn, #iv-actions .btn, #prog-levels .choice, .control .btn-small)[disabled] .res-dot::after { color: var(--disabled-text); }
#sys-actions .btn:active, #prog-actions .btn:active, #iv-actions .btn:active { padding: 5px 9px 3px 11px; }
.report-wrap .actions { justify-content: flex-start; }

/* ── Menu ── */
#screen-menu { align-items: center; justify-content: flex-start; padding: 24px 12px; }
.menu-wrap { max-width: 640px; width: 100%; margin: auto 0; }
.menu-title { font-size: 1.5rem; margin-bottom: 4px; }
.menu-intro { margin-bottom: 4px; }
.start-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin: 10px 0 12px; }
.start-card { display: flex; flex-direction: column; gap: 2px; text-align: left; padding: 8px 10px; color: var(--window-text); min-height: var(--target); }
.start-card strong { font-size: 1.1rem; }
.start-card span { color: var(--select); font-weight: 700; font-size: 0.92rem; }
.start-card.is-suggested { outline: 2px solid var(--select); outline-offset: -5px; }
.start-card.is-suggested strong { text-decoration: underline; }
.start-card small { color: var(--gray-text); font-size: 0.9rem; line-height: 1.35; margin-top: 4px; }
:root[data-theme="dark"] .start-card span { color: var(--link); }
.menu-buttons { display: flex; flex-wrap: wrap; gap: 6px; margin: 6px 0 12px; }
.menu-seed { margin: 6px 0 12px; font-size: 0.92rem; color: var(--gray-text); }
.menu-seed summary { cursor: default; color: var(--window-text); }
.menu-seed label { display: block; margin-top: 6px; }
.menu-seed input { width: 100%; }

/* ── Desktop: two columns of windows ── */
.desk { max-width: 1280px; width: 100%; margin: 0 auto; padding: 14px 14px 60px; display: grid; grid-template-columns: 240px minmax(0, 1fr) 260px; gap: 14px; align-items: start; }
.desk-col { display: flex; flex-direction: column; gap: 14px; min-width: 0; }
.desk-left, .desk-side { position: sticky; top: 14px; }
/* The middle column fits the screen above the taskbar: Status stays put and the folder's
   cards scroll inside it, under the tabs. Phones (one column) and very short screens scroll the page. */
@media (min-width: 861px) and (min-height: 520px) {
  .desk-main { position: sticky; top: 14px; max-height: calc(100dvh - 74px); }
  .folder { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
  .folder > .client { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
  /* The tab's toolbar stays put at the top of the panel; only the body under it scrolls. */
  .folder .folder-panel { flex: 1 1 auto; min-height: 0; overflow: hidden; }
  .folder .folder-body { flex: 1 1 auto; min-height: 0; overflow: auto; }
}
/* The left column fits the screen too, where it is a column of its own (three columns): the diary takes its usual
   height when it has the room and gives way to the planner above it, so opening a window never makes the desk scroll
   (a desk that can scroll jumps when a window opens or the AI programme button is pressed). */
@media (min-width: 1001px) and (min-height: 520px) {
  .desk-left { max-height: calc(100dvh - 74px); }
  .desk-left .notepad { flex: 0 1 auto; min-height: 0; display: flex; flex-direction: column; }
  .desk-left .notepad > .client { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
  .desk-left .log-peek { height: auto; min-height: 80px; flex: 0 1 60vh; }
}
/* A drawn scroll bar in the old desktop's style wherever the game scrolls inside a window (the folder, a sheet, the
 lower boxes of a proposal, a long card), so the player can see there is more: bevelled arrow buttons and thumb (the window bevel), on the dotted track. The modern look has its own. */
/* The classic scroll bar, wherever the game scrolls inside a window; the list is written once and nested (CSS nesting,
   Chrome 120, Safari 17.2, Firefox 117 and later; older browsers show their own bars). The dark theme swaps the arrows. */
body:not([data-os="modern"]) :is(.folder .folder-body, #sys-lower, .foldbox > .box-body, #modal-system > .sheet > .client, #modal-programme > .sheet > .client, #modal-intervention > .sheet > .client, #event-sheet .msg-body, .cast-list, .drawer-body, #modal-qmail .qmail-body, #timeline-list) {
  --sb-up: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='7' height='4'%3E%3Cpath d='M3 0h1v1h1v1h1v1h1v1H0V3h1V2h1V1h1z' fill='black'/%3E%3C/svg%3E"); --sb-down: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='7' height='4'%3E%3Cpath d='M0 0h7v1H6v1H5v1H4v1H3V3H2V2H1V1H0z' fill='black'/%3E%3C/svg%3E");
  &::-webkit-scrollbar { width: 16px; }
  &::-webkit-scrollbar-track { background-image: repeating-conic-gradient(var(--hilight) 0 25%, var(--face) 0 50%); background-size: 2px 2px; }
  &::-webkit-scrollbar-thumb,
  &::-webkit-scrollbar-button:vertical:start:decrement,
  &::-webkit-scrollbar-button:vertical:end:increment { background-color: var(--face); box-shadow: inset -1px -1px var(--dark), inset 1px 1px var(--face-light), inset -2px -2px var(--shadow), inset 2px 2px var(--hilight); }
  &::-webkit-scrollbar-button:vertical:start:decrement,
  &::-webkit-scrollbar-button:vertical:end:increment { display: block; height: 16px; background-repeat: no-repeat; background-position: 4px 6px; }
  &::-webkit-scrollbar-button:vertical:start:decrement { background-image: var(--sb-up); }
  &::-webkit-scrollbar-button:vertical:end:increment { background-image: var(--sb-down); }
  &::-webkit-scrollbar-button:vertical:start:decrement:active,
  &::-webkit-scrollbar-button:vertical:end:increment:active { box-shadow: inset 1px 1px var(--shadow), inset -1px -1px var(--shadow); background-position: 5px 7px; }
  &::-webkit-scrollbar-button:vertical:start:increment,
  &::-webkit-scrollbar-button:vertical:end:decrement { display: none; }
}
:root[data-theme="dark"] body:not([data-os="modern"]) :is(.folder .folder-body, #sys-lower, .foldbox > .box-body, #modal-system > .sheet > .client, #modal-programme > .sheet > .client, #modal-intervention > .sheet > .client, #event-sheet .msg-body, .cast-list, .drawer-body, #modal-qmail .qmail-body, #timeline-list) { --sb-up: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='7' height='4'%3E%3Cpath d='M3 0h1v1h1v1h1v1h1v1H0V3h1V2h1V1h1z' fill='white'/%3E%3C/svg%3E"); --sb-down: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='7' height='4'%3E%3Cpath d='M0 0h7v1H6v1H5v1H4v1H3V3H2V2H1V1H0z' fill='white'/%3E%3C/svg%3E"); }
.desk-section > .client { padding: 8px 8px 8px; }
.count-soft { font-weight: 400; color: var(--gray-text); }
.empty-note { color: var(--gray-text); padding: 10px 8px; }

/* The Calendar: the quarter, the date and the month */
.quarter .client { display: flex; flex-direction: column; gap: 8px; }
.leaf { display: flex; flex-direction: column; padding: 6px 10px; line-height: 1.2; background: var(--window); }
.leaf-period { font-weight: 700; font-size: 1.3rem; }
.leaf-turn { font-size: 0.9rem; color: var(--gray-text); }
.leaf-turn #turn-date { color: var(--window-text); }
/* Status: the figures, trust and End quarter, always on the desk (it cannot be minimised), with what is in the air below */
.status > .client { display: flex; flex-direction: column; gap: 8px; }
.status-row { display: flex; flex-wrap: wrap; gap: 6px; align-items: stretch; } /* one row on a wide desk; trust and End quarter wrap under the figures when narrow */
.status-row .numbers { flex: 3 1 260px; }
.status-row .trust { flex: 2 1 190px; justify-content: center; }
.numbers { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; }
.num { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 1px; padding: 5px 4px; line-height: 1.1; background: var(--window); text-align: center; }
.num strong { font-size: 1.25rem; font-weight: 700; font-variant-numeric: tabular-nums; }
.num strong small { font-size: 0.85rem; color: var(--gray-text); font-weight: 400; }
.num > span { font-size: 0.85rem; color: var(--gray-text); } /* the labels; the number's own span (capacity) keeps the number's size */
.trust { display: flex; flex-direction: column; gap: 4px; padding: 6px 10px; background: var(--window); }
.trust-label { display: flex; gap: 5px; align-items: baseline; font-size: 0.85rem; color: var(--gray-text); line-height: 1.1; }
.trust-label strong { color: var(--window-text); font-size: 1.1rem; }
.trust-label em { font-style: normal; }
.trust-bar-wrap { height: 12px; background: var(--window); overflow: hidden; }
#trust-bar { height: 100%; background: var(--stamp-green); transition: width 0.3s, background 0.3s; background-image: repeating-linear-gradient(90deg, transparent 0 8px, var(--window) 8px 10px); }
#trust-bar.band-watchful { background-color: var(--stamp-amber); }
#trust-bar.band-shaken { background-color: var(--stamp-red); animation: trustPulse 1.2s steps(2, end) infinite; }
.trust.band-steady .trust-label strong { color: var(--stamp-green); }
.trust.band-watchful .trust-label strong { color: var(--stamp-amber); }
.trust.band-shaken .trust-label strong { color: var(--stamp-red); }
@keyframes trustPulse { 0%,100% { opacity: 1; } 50% { opacity: 0.4; } }
.end-btn { width: 100%; min-height: calc(var(--target) + 4px); margin-top: 2px; }
/* What to do next (Engine.quarterOpen) beside End quarter, which carries the open count on a second line */
.status-next { display: flex; gap: 10px; align-items: center; }
.status-now { flex: 1 1 auto; font-size: 0.95rem; line-height: 1.35; }
.status-now::before { content: '\25B8'; margin-right: 6px; color: var(--action); }
.status-now.done::before { content: '\2713'; color: var(--stamp-green); }
.status-next .end-btn { flex: 0 0 auto; width: auto; min-width: 150px; margin-top: 0; padding: 4px 14px; }
/* What just happened (tell in js/screens.js): the last three consequences of the player's actions, newest on top.
   Each is two lines: who or what, with a tag and a mood chip, then the reply or the consequence. */
.status-news { list-style: none; display: flex; flex-direction: column; gap: 0; margin: 0; padding: 3px 8px; background: var(--window); line-height: 1.3; }
.news-item { display: flex; gap: 8px; align-items: flex-start; padding: 1px 0; }
.news-item + .news-item { border-top: 1px dotted var(--shadow); padding-top: 3px; margin-top: 2px; }
.news-item.older { font-size: 0.86em; opacity: 0.7; }
.news-mark { flex: none; width: 18px; text-align: center; padding-top: 1px; color: var(--action); }
.news-item.refused .news-mark { color: var(--stamp-red); font-weight: 700; }
.news-more { margin-left: auto; font-size: 0.8rem; min-height: 0; padding: 0 2px; line-height: 1.3; }
.word-portrait { flex: none; padding-top: 2px; }
.word-body { flex: 1 1 auto; min-width: 0; }
.word-head { display: flex; flex-wrap: wrap; align-items: baseline; column-gap: 5px; font-size: 0.82rem; color: var(--gray-text); }
.word-head strong { color: var(--window-text); }
.news-tag { margin-left: 3px; padding: 0 5px; border: 1px solid var(--shadow); font-size: 0.78rem; white-space: nowrap; }
.news-item.refused .news-tag { color: var(--stamp-red); border-color: var(--stamp-red); }
.word-head .mood-chip { margin: 0; }
.word-text { margin: 0; font-size: 0.95rem; }
.word-text.quote { font-style: italic; }
.num.lit, .trust.lit, .res-chip.lit { outline: 2px dotted var(--stamp-green); outline-offset: 1px; }
.num.lit-down, .trust.lit-down, .res-chip.lit-down { outline-color: var(--stamp-red); }
.res-chip.lit-mixed { outline: 2px dotted var(--stamp-amber); outline-offset: 1px; }
.res-chip.lit-kept { outline: 2px dotted var(--gray-text); outline-offset: 1px; }
.res-chip.lit-unknown { outline: 2px dashed var(--gray-text); outline-offset: 1px; }
#turn-date.ticked { animation: dateFlash 0.9s steps(2, end); }
@keyframes dateFlash { 0% { color: var(--stamp-blue); font-weight: 700; } 100% { color: inherit; } }

/* The diary: a text file in a notepad */
.menubar { display: flex; flex-wrap: wrap; gap: 2px; padding: 1px 2px; font-size: 0.95rem; border-bottom: 1px solid var(--shadow); box-shadow: 0 1px var(--hilight); margin-bottom: 2px; }
.menubar span { padding: 1px 6px; color: var(--disabled-text); }
.menubar-btn { padding: 1px 6px; color: var(--window-text); text-decoration: none; min-height: var(--target); white-space: nowrap; }
.menubar-btn:hover, .menubar-btn:focus-visible { background: var(--select); color: var(--select-text); outline: none; }
.notepad .client { padding: 2px; }
.log-peek { list-style: none; color: var(--window-text); font-family: var(--font-mono); font-size: 0.9rem; padding: 4px 6px; height: 60vh; min-height: 200px; overflow: auto; line-height: 1.35; }
.log-peek li { padding: 1px 0; }

/* ── The Year planner and the run strip: a year as four of the old desktop's progress bars ── */
/* Engine.runProgress through the run strip of js/views.js. The planner on the desk shows the year; the same strip
   over the ledger and the timeline shows every year of the run (run-all). A bar fills in blocks as the quarter runs;
   a pennant over a bar says a date of the Act applies from that quarter (grey once that quarter is behind). */
.planner .client { display: flex; flex-direction: column; gap: 2px; }
.planner .link-btn { align-self: flex-start; }
#planner-body { cursor: pointer; }
.run-strip { display: flex; flex-direction: column; gap: 6px; }
.run-years { display: flex; flex-wrap: wrap; gap: 6px 10px; }
.run-yr { flex: 1 1 100%; min-width: 0; }
.run-all .run-yr { flex: 1 1 70px; max-width: 150px; } /* seven years fit one row of the timeline's sheet; a phone wraps them */
.run-cells { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 3px; }
.run-all .run-cells { gap: 2px; }
.run-cell { position: relative; display: flex; flex-direction: column; gap: 1px; padding-top: 11px; min-width: 0; }
.run-bar { position: relative; display: block; height: 16px; background: var(--window); border: 1px solid; border-color: var(--shadow) var(--hilight) var(--hilight) var(--shadow); box-shadow: inset 1px 1px var(--dark); }
.run-all .run-bar { height: 12px; }
.run-fill { position: absolute; left: 2px; top: 2px; bottom: 1px; width: calc((100% - 3px) * var(--run-fill, 0)); background: repeating-linear-gradient(90deg, var(--select) 0 6px, transparent 6px 8px); }
.run-all .run-fill { background: var(--select); }
.run-cell.is-before .run-bar { background-image: repeating-conic-gradient(var(--hilight) 0 25%, var(--face) 0 50%); background-size: 2px 2px; box-shadow: none; }
.run-cell.is-now .run-bar { outline: 1px dotted var(--window-text); outline-offset: 1px; }
.run-flag { position: absolute; top: 1px; left: calc(50% - 1px); width: 8px; height: 5px; background: var(--stamp-amber); border-left: 1px solid var(--window-text); }
.run-flag::after { content: ''; position: absolute; left: -1px; top: 5px; width: 1px; height: 5px; background: var(--window-text); }
.run-cell.is-past .run-flag { background: var(--shadow); }
.run-q { font-size: 0.8rem; line-height: 1.2; text-align: center; color: var(--gray-text); }
.run-cell.is-now .run-q { color: var(--window-text); font-weight: 700; }
.run-all .run-q { display: none; }
.run-yr-label { font-size: 0.85rem; line-height: 1.3; text-align: center; color: var(--gray-text); }
.run-yr.is-current .run-yr-label { color: var(--window-text); font-weight: 700; }
.run-lines { display: flex; flex-direction: column; gap: 1px; font-size: 0.92rem; line-height: 1.3; }
.run-position { font-weight: 700; }
.run-next-head, .run-january { color: var(--gray-text); }
.run-next-list { list-style: none; }
.run-next-list li { padding-left: 10px; text-indent: -10px; }
.run-next-list li::before { content: '\25B8\00a0'; color: var(--stamp-amber); }
#timeline-run { margin-bottom: 8px; }
/* The timeline keeps to the screen: its note, the run strip and the foot line stay put and the list of dates scrolls inside */
#modal-timeline > .sheet > .client { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
#modal-timeline > .sheet > .client > * { flex: none; }
#modal-timeline #timeline-list { flex: 1 1 auto; min-height: 0; overflow: auto; }
/* The whole run in a window of its own under the yearly ledger (renderEvent in js/screens.js): the two are centred
   together as a lone message is, and the ledger gives up some height so both are in view. Years only: no lines. */
#event-planner { width: 100%; max-width: 760px; margin: 10px 0 auto; flex: none; }
.ledger-planner > .client { padding: 6px 10px 8px; }
#event-sheet.is-ledger { margin-bottom: 0; max-height: calc(100dvh - var(--event-pad-y, 40px) - 110px); }

/* Taskbar: Start, then the running programs */
.taskbar { position: fixed; left: 0; right: 0; bottom: 0; z-index: 5; display: flex; align-items: center; gap: 3px; padding: 3px 2px 2px; border-left: none; border-right: none; border-bottom: none; box-shadow: inset 0 1px var(--hilight); min-height: 30px; }
.start-btn { font-weight: 700; padding: 1px 8px 1px 6px; min-width: 0; min-height: var(--target); display: inline-flex; align-items: center; gap: 5px; }
.start-btn:active { padding: 2px 7px 0 7px; } /* the same width as at rest (.btn:active is wider), so the taskbar does not shift */
.start-btn::before { content: ''; display: inline-block; width: 14px; height: 12px; background: linear-gradient(90deg, #ff0000 50%, #00a000 50%) top / 100% 50% no-repeat, linear-gradient(90deg, #0000ff 50%, #ffff00 50%) bottom / 100% 50% no-repeat; border: 1px solid var(--dark); }
.task-btn { display: inline-flex; align-items: center; gap: 5px; min-height: var(--target); min-width: 120px; padding: 1px 8px; color: var(--window-text); text-decoration: none; font-size: 1rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* A program on the desk has its button pressed: a window that is open (aria-pressed), and the AI programme, which is
   always open and is a link to its window, not a toggle ([href]). */
.task-btn[aria-pressed="true"] { font-weight: 700; background-image: repeating-conic-gradient(var(--hilight) 0 25%, var(--face) 0 50%); background-size: 2px 2px; }
.taskbar::after { content: ''; margin-left: auto; }
/* A minimised program: its window leaves the desk, the column stays */
.desk-section.minimised { display: none; }
.taskbar .more-wrap { position: relative; }

/* Start menu */
.more-menu { position: absolute; left: 0; bottom: calc(100% + 2px); min-width: 210px; padding: 3px 3px 3px 26px; z-index: 20; display: flex; flex-direction: column; }
.more-menu::before { content: 'AI programme'; position: absolute; left: 3px; top: 3px; bottom: 3px; width: 22px; background: linear-gradient(0deg, var(--title-a), var(--shadow)); color: var(--title-text); font-weight: 700; font-size: 1.05rem; writing-mode: vertical-rl; transform: rotate(180deg); text-align: left; padding: 6px 0; letter-spacing: 0.04em; }
.more-menu button { position: relative; text-align: left; padding: 6px 24px 6px 30px; font-size: 1rem; min-height: 32px; color: var(--window-text); white-space: nowrap; }
.more-menu button > .ic { position: absolute; left: 7px; top: 50%; transform: translateY(-50%); width: 16px; height: 16px; }
.more-menu button:hover, .more-menu button:focus-visible { background: var(--select); color: var(--select-text); outline: none; }
/* The program group (toggleActGroup in js/screens.js): a folder item with an arrow, its programs in a cascading menu */
.menu-group { position: relative; display: flex; flex-direction: column; }
.menu-group-btn::after { content: '\25B8'; position: absolute; right: 8px; top: 50%; transform: translateY(-50%); }
.menu-group-btn[aria-expanded="true"] { background: var(--select); color: var(--select-text); }
.menu-sub { position: absolute; left: 100%; top: -3px; min-width: 180px; padding: 3px; z-index: 21; display: flex; flex-direction: column; }
.menu-sub-title { display: none; }
.more-menu .menu-shutdown { margin-top: 4px; }
.more-menu .menu-shutdown::after { content: ''; position: absolute; left: 2px; right: 2px; top: -3px; border-top: 1px solid var(--shadow); border-bottom: 1px solid var(--hilight); }
.more-menu .count { display: inline-block; min-width: 18px; padding: 0 4px; background: var(--window); color: var(--window-text); border: 1px solid var(--shadow); font-size: 0.85rem; text-align: center; margin-left: 6px; }
.more-menu button:hover .count { background: var(--select-text); color: var(--select); }

/* In the air: the conditions still running, under the figures in Status */
.status .air { display: flex; align-items: center; gap: 6px; }
.air-row { flex: 1; min-width: 0; display: flex; flex-wrap: wrap; gap: 6px; }
/* Several things in the air: one at a time. The row scrolls sideways and snaps to each entry, which is what makes it
   swipeable; its scrollbar is hidden, the arrows and the count beside it say where you are. */
.air-nav, .air-count { display: none; }
.air.many .air-nav { display: inline-flex; align-items: center; justify-content: center; flex: none; min-width: var(--target); min-height: var(--target); padding: 0 6px; } /* a full touch target on a phone */
.air.many .air-nav > .ic:first-child { margin-right: 0; }
.air.many .air-count { display: inline; flex: none; font-size: 0.85rem; color: var(--gray-text); white-space: nowrap; }
.air.many .air-row { flex-wrap: nowrap; gap: 0; overflow-x: auto; scroll-snap-type: x mandatory; scrollbar-width: none; overscroll-behavior-x: contain; }
.air.many .air-row::-webkit-scrollbar { display: none; }
.air.many .air-pill { flex: 0 0 100%; min-width: 0; flex-wrap: wrap; row-gap: 0; scroll-snap-align: start; }
.air-pill { display: flex; align-items: center; gap: 8px; padding: 3px 10px; font-size: 0.92rem; }
.air-pill::before { content: 'i'; display: inline-flex; align-items: center; justify-content: center; width: 14px; height: 14px; border-radius: 50%; background: var(--stamp-blue); color: #fff; font-weight: 700; font-family: Georgia, serif; font-size: 0.85rem; flex: none; }
.air-pill .air-note { color: var(--stamp-blue); font-weight: 700; }
.air-pill .air-left { color: var(--gray-text); }

/* Tabbed dialog */
.folder-tabs { display: flex; gap: 0; align-items: flex-end; padding: 0 2px; position: relative; z-index: 1; }
.folder-tab { border-bottom: none; padding: 3px 10px 4px; margin-right: -1px; font-size: 1rem; color: var(--window-text); min-height: calc(var(--target) - 2px); box-shadow: inset 1px 1px var(--face-light), inset -1px 0 var(--shadow); position: relative; top: 1px; }
.folder-tab.active { font-weight: 700; padding: 4px 12px 6px; margin-bottom: -1px; z-index: 2; background: var(--face); box-shadow: inset 1px 1px var(--face-light), inset -1px 0 var(--shadow), 0 1px var(--face); }
.folder-panel { padding: 12px 10px 10px; display: flex; flex-direction: column; gap: 8px; }
.folder-body { display: flex; flex-direction: column; gap: 8px; }
/* The order of a tab's list (deskListsModel in js/views.js): a small box at the top right of the panel */
/* A tab's toolbar: the In tray's filter and each tab's order, at the right, above the body that scrolls (folder-body). */
.desk-tools { display: flex; justify-content: flex-end; align-items: center; gap: 12px; }
.desk-tools > label { min-width: 0; }
.desk-tools > label select { min-width: 0; max-width: 100%; }
.desk-filter select { width: 9em; } /* its longest choice would otherwise squeeze the order beside it */
.desk-sort, .desk-filter { display: inline-flex; align-items: center; gap: 5px; font-size: 0.82rem; color: var(--gray-text); }
.desk-sort select, .desk-filter select { min-height: 22px; padding: 0 3px; font-size: 0.82rem; }
@media (pointer: coarse) { .desk-sort select, .desk-filter select { min-height: 30px; } } /* smaller than the usual touch target: the owner's call for this toolbar */

/* Cards: each proposal is a small window. Title bar, white document area, status bar. */
.card-row { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 10px; }
.card-row .empty-note { grid-column: 1 / -1; }
.doc { position: relative; display: grid; grid-template-columns: 1fr auto; grid-template-rows: auto auto 1fr auto; gap: 0; padding: 2px; text-align: left; color: var(--window-text); min-height: 150px; align-items: stretch; }
.doc:hover, .doc:focus-visible { outline: 1px dotted var(--window-text); outline-offset: 2px; }
.doc-kicker { grid-column: 1 / -1; display: flex; align-items: center; justify-content: space-between; gap: 6px; height: 18px; padding: 0 5px; --bar: color-mix(in srgb, var(--dept) 55%, #000); background: linear-gradient(90deg, var(--bar), color-mix(in srgb, var(--dept) 80%, #000)); color: #fff; font-weight: 700; font-size: 0.85rem; white-space: nowrap; overflow: hidden; }
.doc-kicker > span:first-child { flex: 1; overflow: hidden; text-overflow: ellipsis; }
.doc .doc-kicker .kind-tag { background: transparent; border: none; color: #fff; padding: 0; font-size: 0.85rem; font-weight: 700; align-self: center; }
.doc .doc-kicker .date-stamp { color: #fff; background: transparent; border: none; padding: 0; font-weight: 400; font-size: 0.85rem; }
.doc.is-new .doc-kicker::after { content: 'new'; font-size: 0.8rem; background: var(--info); color: #000; padding: 0 5px; font-weight: 700; border: 1px solid var(--dark); line-height: 1.2; }
.doc-title { grid-column: 1 / -1; display: flex; align-items: flex-start; gap: 8px; font-weight: 700; font-size: 1.05rem; padding: 6px 8px 2px; line-height: 1.25; background: var(--window); border: 1px solid var(--shadow); border-bottom: none; }
.doc-hook { grid-column: 1 / -1; padding: 0 8px 8px; font-size: 0.95rem; color: var(--window-text); font-style: italic; background: var(--window); border: 1px solid var(--shadow); border-top: none; }
.doc-foot { display: flex; flex-wrap: wrap; align-items: center; gap: 3px; margin-top: 3px; font-size: 0.85rem; min-height: 22px; min-width: 0; }
/* The two footer rows stack: people and claim, then the answer-by date on its own row at the right.
   Side by side, a wrapped first row ran under the date. */
.doc-foot { grid-column: 1 / -1; }
.doc-foot + .doc-foot { justify-self: end; }
.doc-foot:empty { display: none; }
.doc-foot > * { border: 1px solid; border-color: var(--shadow) var(--hilight) var(--hilight) var(--shadow); padding: 1px 5px; background: var(--face); color: var(--window-text); display: inline-flex; align-items: center; gap: 4px; min-height: 20px; white-space: nowrap; }
.doc-foot .people { margin-bottom: 0; color: var(--window-text); }
.doc-foot .claim, .doc-foot .date-stamp { border-style: solid; background: var(--face); }
.doc .stamp { font-size: 0.9rem; flex: none; margin-top: 1px; } /* on the title's line, at its end */
.doc-title-text { flex: 1; min-width: 0; }
.doc.is-programme .doc-kicker, .doc.is-intervention .doc-kicker, .sheet.is-action { --dept: var(--action); }
.doc-foot > :empty { display: none; }
.card-level { color: var(--dept); font-weight: 700; font-size: 0.9rem; }
.date-stamp { font-size: 0.85rem; color: var(--window-text); border: 1px solid var(--shadow); padding: 0 5px; white-space: nowrap; display: inline-block; background: var(--window); }
.date-stamp.soon { color: var(--stamp-red); font-weight: 700; }
.claim { font-size: 0.85rem; color: var(--gray-text); border: 1px dashed var(--shadow); padding: 0 5px; white-space: nowrap; background: var(--window); }
.claim.real { border-style: solid; color: var(--stamp-green); border-color: var(--stamp-green); }
.claim .ic { width: 13px; height: 13px; margin-right: 3px; vertical-align: -2px; }
.reg-row:hover .claim .ic, .reg-row:focus-visible .claim .ic { color: inherit; } /* on the selection colour the picture takes the row's own, or it would vanish */
.waiting { list-style: none; display: flex; flex-direction: column; gap: 4px; }
.waiting li { display: flex; align-items: center; gap: 8px; font-size: 0.92rem; padding: 4px 8px; border: 1px dotted var(--shadow); background: var(--window); }
.waiting li::before { content: '⌛'; font-size: 0.9rem; }
.waiting li .w-title { font-weight: 700; }
.waiting li .link-btn { margin-left: auto; min-height: 0; }

/* Register and programme lists: ListView rows */
.register, .programmes-list { list-style: none; overflow: hidden; }
.register-org { margin-top: 8px; }
.reg-row, .prog-row { display: grid; grid-template-columns: auto 1fr auto auto; gap: 10px; align-items: center; padding: 4px 8px; width: 100%; text-align: left; border-bottom: 1px dotted var(--face); border-left: 4px solid var(--dept); min-height: var(--target); color: var(--window-text); }
.prog-row { grid-template-columns: auto 1fr auto; border-left-color: var(--action); }
.reg-row:last-child, .prog-row:last-child { border-bottom: none; }
.reg-row:hover, .reg-row:focus-visible, .prog-row:hover, .prog-row:focus-visible { background: var(--select); color: var(--select-text); outline: 1px dotted var(--select-text); outline-offset: -2px; }
.reg-row:hover :is(.reg-icon, .reg-title, .reg-sub, .reg-status, .reg-due, .kind-tag, .date-stamp, .claim, .card-level), .reg-row:focus-visible :is(.reg-icon, .reg-title, .reg-sub, .reg-status, .reg-due, .kind-tag, .date-stamp, .claim, .card-level),
.prog-row:hover :is(.reg-icon, .reg-title, .reg-sub, .kind-tag, .card-level), .prog-row:focus-visible :is(.reg-icon, .reg-title, .reg-sub, .kind-tag, .card-level) { color: inherit; }
.reg-row:hover .kind-tag, .prog-row:hover .kind-tag, .reg-row:focus-visible .kind-tag, .prog-row:focus-visible .kind-tag, .reg-row:hover .date-stamp, .reg-row:hover .claim { background: transparent; border-color: var(--select-text); }
.reg-icon { font-size: 1.1rem; line-height: 1; width: 20px; text-align: center; }
.reg-title { font-weight: 700; }
.reg-sub { font-size: 0.9rem; color: var(--gray-text); }
.reg-status { font-size: 0.9rem; color: var(--window-text); display: flex; align-items: center; gap: 5px; white-space: nowrap; }
.dot { width: 8px; height: 8px; background: var(--gray-text); display: inline-block; border: 1px solid var(--dark); }
.dot.live { background: var(--stamp-green); } .dot.suspended, .dot.due { background: var(--stamp-red); } .dot.research, .dot.building { background: var(--stamp-blue); } .dot.proposed, .dot.deferred { background: var(--stamp-amber); } .dot.rejected, .dot.stopped { background: var(--shadow); }
.reg-due { font-size: 0.9rem; color: var(--stamp-red); font-weight: 700; white-space: nowrap; }
.reg-row.just-changed { animation: rowFlash 1.6s steps(4, end); }
@keyframes rowFlash { 0% { background: var(--select); color: var(--select-text); } 100% { background: transparent; } }
.register.blind { background: var(--face); }
.register.blind .reg-due, .register.blind .reg-status { font-family: var(--font-mono); color: var(--gray-text); }
.register-note { font-size: 0.92rem; color: var(--stamp-red); margin-bottom: 6px; }
.done-head { color: var(--gray-text); font-weight: 400; font-size: 0.92rem; margin: 4px 0 2px; }
.done-list .prog-row { opacity: 0.8; border-left-color: var(--stamp-amber); }
.kind-tag { display: inline-block; font-size: 0.85rem; padding: 0 5px; background: var(--face); color: var(--window-text); border: 1px solid var(--shadow); align-self: flex-start; }
.kind-tag.law { background: var(--select); color: var(--select-text); border-color: var(--select); }

/* ── Turn banner: a splash ── */
/* Closing the quarter is a progress dialog: time passes as the blocks march */
.turn-banner { position: fixed; top: 40%; left: 50%; transform: translate(-50%,-50%); width: 320px; max-width: calc(100% - 24px); padding: 28px 14px 12px; font-weight: 700; font-size: 1.1rem; z-index: 60; pointer-events: none; text-align: center; color: var(--window-text); opacity: 0; visibility: hidden; }
.turn-banner.show { opacity: 1; visibility: visible; }
.turn-banner::before { content: 'Closing the quarter'; position: absolute; top: 2px; left: 2px; right: 2px; height: 18px; line-height: 18px; padding: 0 6px; text-align: left; font-size: 0.95rem; background: linear-gradient(90deg, var(--title-a), var(--title-b)); color: var(--title-text); }
.turn-banner small { display: block; font-weight: 400; font-size: 0.92rem; color: var(--gray-text); margin-top: 2px; }
.turn-banner::after { content: ''; display: block; height: 16px; margin-top: 10px; border: 1px solid; border-color: var(--shadow) var(--hilight) var(--hilight) var(--shadow); box-shadow: inset 1px 1px var(--dark); background: repeating-linear-gradient(90deg, var(--select) 0 10px, transparent 10px 12px) 0 0 / 0% 100% no-repeat, var(--window); }
.turn-banner.show::after { animation: progress 1.3s steps(12, end) forwards; }
@keyframes progress { from { background-size: 0% 100%, auto; } to { background-size: 100% 100%, auto; } }

/* ── Sheets: dialogs over the desktop ── */
.overlay { position: fixed; inset: 0; background: rgba(0,0,0,0.25); display: flex; align-items: flex-start; justify-content: center; padding: 28px 12px 60px; z-index: 40; overflow: auto; }
/* Tall content scrolls instead of clipping: start at the top and let auto margins centre what fits */
#screen-event { align-items: center; justify-content: flex-start; padding: 20px 12px; }
#event-sheet { margin: auto 0; display: flex; flex-direction: column; max-height: calc(100dvh - var(--event-pad-y, 40px)); }
/* A card taller than the screen keeps its head and its answers in view; the body scrolls inside the card */
#event-sheet > .client { flex: 1 1 auto; min-height: 0; }
#event-sheet > .client > * { flex-shrink: 0; }
#event-sheet > .client > .msg-body { flex: 1 1 auto; min-height: 80px; overflow: auto; }
#modal-variant, #confirm-modal, #modal-options { align-items: flex-start; padding: 28px 12px; }
#modal-variant .sheet, #confirm-modal .sheet, #modal-options .sheet { margin: auto 0; }
.sheet { width: 100%; max-width: 620px; color: var(--window-text); }
.msgbox { max-width: 640px; }
.sheet-narrow.msgbox { max-width: 420px; } /* confirm, copy, tips: a small box, not the width of the window behind it */
.copy-text { width: 100%; box-sizing: border-box; font-family: var(--font-mono); font-size: 0.85rem; color: var(--window-text); background: var(--window); border: 1px solid; border-color: var(--shadow) var(--hilight) var(--hilight) var(--shadow); resize: vertical; margin-top: 6px; }
.msgbox.is-ledger { max-width: 760px; }
.msgbox.is-report { max-width: 700px; }
/* The message is an Outlook Express window: menu bar, labelled header, white body, reply toolbar, status bar */
.msgbox .client { display: flex; flex-direction: column; padding-top: 6px; }
.msg-head { position: relative; display: flex; flex-direction: column; gap: 2px; padding: 2px 48px 8px 0; border-bottom: 1px solid var(--shadow); box-shadow: 0 1px var(--hilight); margin-bottom: 8px; }
.msg-head .msg-row { display: grid; grid-template-columns: 64px 1fr; gap: 6px; align-items: baseline; font-size: 0.95rem; margin: 0; }
.msg-label { font-weight: 700; }
.msg-head .sheet-title { margin: 0; font-size: 1.05rem; }
.msg-head .people { margin: 0; color: var(--window-text); }
.msg-head .people > span:not(.person) { font-size: 0; }
.msg-cc:has(.people:empty) { display: none; }
.speaker-name { font-weight: 700; }
.speaker-does { color: var(--gray-text); }
.speaker-does:not(:empty)::before { content: '('; } .speaker-does:not(:empty)::after { content: ')'; }
.speaker-mood { color: var(--gray-text); font-size: 0.88rem; }
.speaker-mood:empty { display: none; }
.speaker-mood:not(:empty)::before { content: '· '; }
/* How a person stands with you: a small label beside their name (Who's who, the proposal sheet) */
.mood-chip { display: inline-block; font-size: 0.78rem; font-weight: 400; color: var(--gray-text); border: 1px solid var(--shadow); background: var(--window); padding: 0 5px; margin: 0 6px 0 0; vertical-align: middle; white-space: nowrap; }
.cast-name .mood-chip { margin: 0 0 0 6px; }
.msg-portrait { position: absolute; right: 0; top: 0; }
.msg-portrait:empty { display: none; }
.msg-body { padding: 10px; min-height: 120px; background: var(--window); color: var(--window-text); font-family: Arial, Helvetica, sans-serif; border: 1px solid; border-color: var(--shadow) var(--hilight) var(--hilight) var(--shadow); box-shadow: inset 1px 1px var(--dark), inset -1px -1px var(--face-light); }
.msg-body .scene { margin: 0; }
.msg-body .surcharge { margin: 8px 0 0; }
.msg-body .ledger-wrap { margin-bottom: 0; }
#event-result.outcome { margin-top: 6px; padding: 8px 10px; background: var(--window); font-family: Arial, Helvetica, sans-serif; border: 1px solid; border-color: var(--shadow) var(--hilight) var(--hilight) var(--shadow); box-shadow: inset 1px 1px var(--dark), inset -1px -1px var(--face-light); }
#event-result .actions { margin-bottom: 0; }
.msg-status { display: flex; flex-wrap: wrap; gap: 3px; margin: 6px -10px -10px; padding: 3px 3px 3px; border-top: 1px solid var(--hilight); }
.msg-status .event-res { display: contents; }
.msg-cell, .msg-status .res-chip { display: inline-flex; align-items: center; gap: 5px; min-height: 20px; padding: 1px 6px; font-size: 0.85rem; color: var(--window-text); background: var(--face); border: 1px solid; border-color: var(--shadow) var(--hilight) var(--hilight) var(--shadow); box-shadow: none; }
.msg-cell:empty { display: none; }
#event-system { flex: 1 1 auto; }
#event-system:not(:empty)::before { content: ''; width: 9px; height: 9px; background: var(--dept); border: 1px solid var(--dark); flex: none; }
.sheet.is-world #event-system::before { background: var(--stamp-amber); }
#event-options.choices { display: flex; flex-direction: row; align-items: stretch; gap: 0; margin: 6px -10px 0; padding: 4px 6px 4px; border-top: 1px solid var(--shadow); box-shadow: inset 0 1px var(--hilight); }
#event-options .choice { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; align-items: center; text-align: center; gap: 2px; padding: 5px 6px; min-height: 64px; border-color: transparent; box-shadow: none; background: transparent; }
#event-options .choice + .choice { border-left-color: var(--shadow); box-shadow: inset 1px 0 var(--hilight); }
/* The icon is the stamp the choice will earn: do, refuse, note or risk */
#event-options .choice::before { content: '✔'; display: inline-flex; align-items: center; justify-content: center; width: 20px; height: 20px; border-radius: 50%; background: var(--stamp-green); color: #fff; font-size: 0.9rem; font-weight: 700; line-height: 1; margin-bottom: 2px; }
#event-options .choice[data-tone="refuse"]::before { content: '✖'; background: var(--stamp-red); }
#event-options .choice[data-tone="note"]::before { content: 'i'; background: var(--stamp-blue); font-family: Georgia, serif; }
#event-options .choice[data-tone="risk"]::before { content: '!'; background: var(--stamp-amber); border-radius: 0; clip-path: polygon(50% 0, 100% 100%, 0 100%); width: 22px; padding-top: 5px; }
:root[data-theme="dark"] #event-options .choice::before { color: #000; }
/* An answer with its own icon: the picture sits in a badge whose colour and shape give the tone (do and note round,
   refuse square, risk a diamond), so the tone does not rest on colour alone. */
#event-options .choice.has-badge::before { content: none; display: none; }
.choice .choice-badge { display: inline-flex; align-items: center; justify-content: center; width: 24px; height: 24px; flex: none; border-radius: 50%; background: var(--stamp-green); color: #fff; margin-bottom: 2px; }
.choice-badge .ic { width: 14px; height: 14px; }
.choice[data-tone="note"] .choice-badge { background: var(--stamp-blue); }
.choice[data-tone="refuse"] .choice-badge { background: var(--stamp-red); border-radius: 3px; }
.choice[data-tone="risk"] .choice-badge { background: var(--stamp-amber); border-radius: 0; width: 28px; height: 28px; margin: -2px 0 0; clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%); }
.choice[data-tone="risk"] .choice-badge .ic { width: 12px; height: 12px; }
:root[data-theme="dark"] .choice .choice-badge { color: #000; }
#event-options .choice:hover, #event-options .choice:focus-visible { border-color: var(--hilight) var(--dark) var(--dark) var(--hilight); box-shadow: inset -1px -1px var(--shadow), inset 1px 1px var(--face-light); background: var(--face); }
#event-options .choice:active, #event-options .choice.chosen { border-color: var(--shadow) var(--hilight) var(--hilight) var(--shadow); box-shadow: inset 1px 1px var(--dark), inset -1px -1px var(--face-light); background: var(--face); padding: 6px 5px 4px 7px; }
#event-options .choice strong { font-weight: 700; }
#event-options .choice .key { margin-right: 4px; }
#event-options .choice > span { font-size: 0.85rem; }
#event-options .res-dots { justify-content: center; margin-top: auto; padding-top: 3px; }
#event-options .choice .stamp { position: static; transform: none; margin-top: 2px; }
.people { display: flex; flex-wrap: wrap; gap: 4px 10px; align-items: center; font-size: 0.9rem; color: var(--gray-text); margin-bottom: 6px; }
.people .person { display: inline-flex; align-items: center; gap: 4px; }
.event-res { display: flex; gap: 4px; flex-wrap: wrap; margin: 0 0 10px; }
.res-chip { display: inline-flex; align-items: center; gap: 5px; padding: 2px 8px; font-size: 0.85rem; color: var(--gray-text); border: 1px solid; border-color: var(--shadow) var(--hilight) var(--hilight) var(--shadow); background: var(--window); }
.res-chip strong { font-size: 1rem; color: var(--window-text); }
.res-chip.band-steady strong { color: var(--stamp-green); } .res-chip.band-watchful strong { color: var(--stamp-amber); } .res-chip.band-shaken strong { color: var(--stamp-red); }
.surcharge { font-size: 0.92rem; color: var(--stamp-red); padding: 5px 8px; margin-bottom: 10px; background: var(--window); }
.later { list-style: none; display: flex; flex-direction: column; gap: 2px; margin: 0 0 10px; }
.later li { font-size: 0.92rem; color: var(--gray-text); padding-left: 16px; position: relative; }
.later li::before { content: '└'; position: absolute; left: 2px; color: var(--shadow); font-family: var(--font-mono); }
.file { display: grid; grid-template-columns: max-content 1fr; gap: 6px 10px; font-size: 0.95rem; margin: 6px 0 12px; padding: 8px 10px; background: var(--window); }
.file dt { display: inline-flex; align-items: center; gap: 5px; color: var(--window-text); align-self: start; padding-top: 3px; }
.file dt::after { content: ':'; margin-left: -5px; } /* a form's label: "Built by:" */
.file dt .ic { width: 14px; height: 14px; color: var(--gray-text); }
/* The tier badge (tierBadge in js/ui.js): the tier's icon and short name, coloured by C.TIER_TONE. */
.tier-badge { display: inline-flex; align-items: center; gap: 4px; padding: 0 6px; font-size: 0.85rem; font-weight: 700; white-space: nowrap; color: #fff; background: var(--stamp-blue); border: 1px solid var(--dark); }
.tier-badge .ic { width: 12px; height: 12px; }
.tier-badge.tone-red { background: var(--stamp-red); } .tier-badge.tone-amber { background: var(--stamp-amber); color: #000; }
.tier-badge.tone-green { background: var(--stamp-green); } .tier-badge.tone-ink { background: var(--gray-text); color: var(--window); }
:root[data-theme="dark"] .tier-badge { color: #000; }
.doc-foot > .tier-badge { border: 1px solid var(--dark); color: #fff; background: var(--stamp-blue); }
.doc-foot > .tier-badge.tone-red { background: var(--stamp-red); } .doc-foot > .tier-badge.tone-amber { background: var(--stamp-amber); color: #000; }
.doc-foot > .tier-badge.tone-green { background: var(--stamp-green); } .doc-foot > .tier-badge.tone-ink { background: var(--gray-text); color: var(--window); }
:root[data-theme="dark"] .doc-foot > .tier-badge { color: #000; }
.legal-line .tier-badge { margin-right: 6px; vertical-align: 1px; }
.reg-row .tier-badge { margin: 2px 6px 0 0; vertical-align: 1px; }
/* A word picked out in the text (richText in js/ui.js, meta.glossary): its category's icon, a tint and an underline, so it
   stands out without colour alone. One that names an article is a button that opens it in the Reference drawer. */
.term { display: inline; padding: 0 2px; font: inherit; font-weight: 700; color: inherit; line-height: inherit; text-align: inherit;
  background: color-mix(in srgb, var(--term) 16%, transparent); border: none; border-bottom: 1px dotted var(--term); --term: var(--stamp-blue); }
.term .ic { width: 12px; height: 12px; margin-right: 2px; vertical-align: -1px; color: var(--term); }
/* A figure named in a tip, with its picture from Status before it (figureText in js/ui.js) */
.figure-word { font-weight: 700; white-space: nowrap; }
.figure-word .ic { width: 14px; height: 14px; margin-right: 3px; vertical-align: -2px; }
.term-status { --term: var(--stamp-amber); } .term-role { --term: var(--stamp-blue); } .term-term { --term: var(--stamp-green); }
button.term { cursor: pointer; min-height: 0; box-shadow: none; }
button.term:hover, button.term:focus-visible { border-bottom-style: solid; background: color-mix(in srgb, var(--term) 28%, transparent); outline: 1px dotted var(--window-text); outline-offset: 0; }
body.high-contrast .term { background: none; border-bottom: 2px solid var(--window-text); }
body.high-contrast .term .ic { color: var(--window-text); }
.file dd { margin: 0; min-width: 0; overflow-wrap: anywhere; } /* the value sits in a filled-in field, drawn with the logon's (below) */
.legal-line { font-size: 1rem; margin-bottom: 10px; }
.legal-line .muted { color: var(--gray-text); }
.notice { padding: 6px 8px 6px 30px; margin-bottom: 10px; font-size: 0.95rem; background: var(--info); color: var(--window-text); position: relative; }
:root[data-theme="dark"] .notice { border-color: var(--stamp-amber); }
.notice::before { content: 'i'; position: absolute; left: 8px; top: 7px; width: 15px; height: 15px; border-radius: 50%; background: var(--stamp-blue); color: #fff; font-weight: 700; font-family: Georgia, serif; font-size: 0.85rem; text-align: center; line-height: 15px; }

/* Controls: a ListView with a Fund button */
.controls { list-style: none; display: flex; flex-direction: column; padding: 2px 0; }
.controls:empty { display: none; } /* the hint says why there is nothing; no empty bar under it */
.control { display: grid; grid-template-columns: 1fr auto auto; gap: 10px; align-items: center; padding: 3px 8px; border-bottom: 1px dotted var(--face); font-size: 0.95rem; min-height: var(--target); }
.control:last-child { border-bottom: none; }
.control .c-label { display: flex; flex-wrap: wrap; gap: 5px; align-items: baseline; }
.control .c-status { font-size: 0.9rem; color: var(--gray-text); white-space: nowrap; display: flex; align-items: center; gap: 5px; }
.control.st-due .c-status { color: var(--stamp-red); font-weight: 700; }
.control.st-funded .c-status { color: var(--stamp-green); }
.control .c-cost { font-size: 0.9rem; color: var(--gray-text); }
.story { list-style: none; color: var(--window-text); font-size: 0.95rem; padding: 4px 8px; }
.story li { padding: 3px 0; border-bottom: 1px dotted var(--face); }
.story li:last-child { border-bottom: none; }
.story li.hint { color: var(--gray-text); }

/* Choices: the buttons along the bottom of a message box */
.choices { display: flex; flex-direction: column; gap: 6px; margin-top: 8px; }
.choices.two { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.choice { position: relative; display: flex; flex-direction: column; gap: 1px; text-align: left; padding: 5px 10px; font-size: 1rem; color: var(--window-text); min-height: var(--target); }
.choice:hover { background: var(--face-light); }
.choice:active, .choice.chosen { padding: 6px 9px 4px 11px; }
.choice strong { font-weight: 700; }
.choice span { font-size: 0.92rem; color: var(--gray-text); }
.choice .choice-warn { color: var(--stamp-red); font-weight: 700; } /* a version the player knows the Act bans (the version picker) */
.choice .key { color: var(--gray-text); font-size: 0.9rem; margin-right: 6px; font-family: var(--font-mono); }
.choice .means { display: block; font-size: 0.9rem; color: var(--gray-text); margin-top: 2px; }
.choice[disabled] { cursor: default; }
.choice[disabled]:not(.chosen) { color: var(--window-text); opacity: 0.7; }
.res-dots { display: flex; gap: 8px; margin-top: 4px; flex-wrap: wrap; }
.res-dot { display: inline-flex; align-items: center; gap: 3px; font-size: 0.85rem; color: var(--gray-text); }
.res-dot i { width: 8px; height: 8px; display: inline-block; background: var(--gray-text); border: 1px solid var(--dark); }
.res-dot.up i { background: var(--stamp-green); } .res-dot.down i { background: var(--stamp-red); } .res-dot.mixed i { background: linear-gradient(90deg, var(--stamp-green) 50%, var(--stamp-red) 50%); } .res-dot.kept i { background: transparent; }
.res-dot.unknown i { background: transparent; border-style: dashed; }
/* A dot with a resource icon: the icon takes the direction's colour, and an arrow says it without colour. */
.res-dot .ic { width: 14px; height: 14px; }
/* Dots inside the other action buttons: under the label and cost on the programme and one-off sheets, beside the word
   on a control's Fund button, on a programme size's last row; and on a desk card's foot, without the box its neighbours get. */
/* A one-off's Do it and a programme's Stop: the action's icon in a column of its own, centred down the button (the owner's
   call of 2026-10-08), the word beside it (with why it cannot be done, or what stopping costs), and the dots with how long
   it takes centred under both. */
#prog-actions .btn, #iv-actions .btn { grid-template-columns: 26px auto minmax(0, 1fr); column-gap: 10px; row-gap: 2px; align-content: center; }
#prog-actions .btn > .lead-ic, #iv-actions .btn > .lead-ic { grid-column: 1; grid-row: 1 / span 2; align-self: center; display: flex; justify-content: center; }
#prog-actions .btn > .lead-ic .ic, #iv-actions .btn > .lead-ic .ic { width: 22px; height: 22px; }
/* The dots span the whole button so they centre on it, not on the words beside the icon; padding as wide as the icon's
   column and gap (26px + 10px) on both sides keeps them clear of the icon and balanced. */
#prog-actions .btn .res-dots, #iv-actions .btn .res-dots { grid-column: 1 / -1; grid-row: 2; padding: 0 36px; margin-top: 2px; justify-content: center; align-items: center; gap: 4px 12px; }
/* How long an action takes, the last item of its row of dots (dotsRow in js/views.js), so it wraps with them. */
.res-dots .takes { font-size: 0.85rem; color: var(--gray-text); }
/* A programme size's last row: the dots, then how long it takes, one row that wraps as one and is centred on the button
   (the owner's calls of 2026-10-08 and 09, as on a proposal's tiles). */
#prog-levels .choice .level-foot { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 4px 12px; margin-top: 3px; }
/* A programme size is a button row in the desktop's own button look: the action's icon large at the left, centred down the
   button, and its three rows beside it (name, what it does, the dots and the days); no highlight on hover (the old desktop's
   buttons had none). */
#prog-levels .choice { display: grid; grid-template-columns: 26px minmax(0, 1fr); column-gap: 10px; align-items: start; }
#prog-levels .choice > :not(.lead-ic) { grid-column: 2; }
#prog-levels .choice > .lead-ic { grid-column: 1; grid-row: 1 / span 3; align-self: center; display: flex; justify-content: center; }
#prog-levels .choice > .lead-ic .ic { width: 22px; height: 22px; }
/* The last row spans the whole button so it centres on it, the icon's column and gap (26px + 10px) as padding on both
   sides so it stays clear of the icon. Its row is named: an auto-placed item would skip the row the icon reaches into. */
#prog-levels .choice > .level-foot { grid-column: 1 / -1; grid-row: 3; padding: 0 36px; }
body:not([data-os="modern"]) #prog-levels .choice:not(.chosen):hover { background: var(--face); }
.control .btn-small { display: inline-flex; align-items: center; gap: 6px; }
.control .btn-small .res-dots { margin-top: 0; gap: 4px; }
.control .btn-small .res-dot { font-size: 0; gap: 1px; } /* icon and arrow only: the button is small, the tooltip gives the cost */
.control .btn-small .res-dot.has-ic::after { font-size: 0.6rem; }
.control .btn-small .res-dot:not(.has-ic) i { width: 7px; height: 7px; }
.doc-foot > .res-dots { border: none; background: none; padding: 0; margin-top: 0; gap: 6px; min-height: 0; }
.res-dot.has-ic::after { font-size: 0.75em; line-height: 1; }
.res-dot.has-ic.up::after { content: '▲'; color: var(--stamp-green); } .res-dot.has-ic.down::after { content: '▼'; color: var(--stamp-red); }
.res-dot.has-ic.mixed::after { content: '▲▼'; color: var(--stamp-amber); } .res-dot.has-ic.kept::after { content: '='; }

/* ── Icons (js/icons.js; icon() in js/ui.js) ── */
/* Decorative pictures in the text colour, drawn from the current look's set. The classic set is pixel art on a 24 grid:
   at 12px or 24px its pixels land whole. */
.ic { display: inline-block; width: 16px; height: 16px; flex: none; vertical-align: -3px; overflow: visible; }
.icon-sprite { position: absolute; width: 0; height: 0; overflow: hidden; }
.btn > .ic:first-child, .folder-tab > .ic:first-child { margin-right: 5px; }
.btn-label .ic { margin-right: 5px; }
/* The four figures keep their own colour wherever they appear */
.ic-res.ic-budget { color: var(--res-budget); } .ic-res.ic-capacity { color: var(--res-capacity); }
.ic-res.ic-benefit { color: var(--res-benefit); } .ic-res.ic-trust { color: var(--res-trust); }
.res-dot .ic-res { color: var(--gray-text); }
/* Action icons: each key's family colour (the keys are C.ICONS.actions; tests/css.test.js holds every key to a family) */
.ic-action { --act: var(--action); }
.ic-action.ic-assess, .ic-action.ic-do_intervention { --act: var(--act-do); }
.ic-action.ic-buy, .ic-action.ic-fund { --act: var(--act-money); }
.ic-action.ic-build { --act: var(--act-staff); }
.ic-action.ic-research { --act: var(--act-pilot); }
.ic-action.ic-defer, .ic-action.ic-pause { --act: var(--act-wait); }
.ic-action.ic-reject, .ic-action.ic-stop, .ic-action.ic-stop_pilot, .ic-action.ic-stop_programme { --act: var(--act-stop); }
.ic-action.ic-go_live, .ic-action.ic-resume { --act: var(--act-on); }
.res-dot.up .ic-res { color: var(--stamp-green); } .res-dot.down .ic-res { color: var(--stamp-red); } .res-dot.mixed .ic-res { color: var(--stamp-amber); }
/* The label stays inline text, so its baseline is the word's and it lines up with the number beside it; the icon sits on the line. */
.num span[data-ic] .ic, .trust-label span[data-ic] .ic { width: 14px; height: 14px; margin-right: 3px; vertical-align: -2px; }
.res-chip .ic { width: 14px; height: 14px; align-self: center; }
.delta { display: inline-flex; align-items: center; gap: 4px; font-size: 0.9rem; font-weight: 700; padding: 1px 8px; border: 1px solid var(--stamp-green); color: var(--stamp-green); background: var(--window); }
.delta .ic { width: 14px; height: 14px; color: inherit; }
.outcome { margin-top: 12px; padding-top: 10px; border-top: 1px solid var(--shadow); box-shadow: 0 -1px var(--hilight) inset; }
.score { font-size: 0.92rem; color: var(--gray-text); margin-bottom: 6px; font-weight: 700; }
.score.full { color: var(--stamp-green); } .score.partial { color: var(--stamp-amber); } .score.none { color: var(--gray-text); }
.verdict { margin: 8px 0 12px; font-size: 0.95rem; }
.verdict-label { font-weight: 700; margin-right: 4px; }
.deltas { display: flex; gap: 6px; flex-wrap: wrap; margin: 2px 0 10px; }
.delta.down { border-color: var(--stamp-red); color: var(--stamp-red); }
.why { margin: 4px 0 12px; font-size: 0.95rem; }
.why summary { cursor: default; color: var(--link); text-decoration: underline; }
.why p { margin: 6px 0 4px; }
.tags { display: inline; }
.tag { display: inline-block; background: var(--window); color: var(--link); border: 1px solid var(--shadow); padding: 0 5px; font-size: 0.85rem; margin: 1px 4px 1px 0; text-decoration: underline; cursor: default; }
.tag.other { color: var(--stamp-amber); }

/* Stamps: dialog icons */
.stamp { display: inline-flex; align-items: center; gap: 6px; font-weight: 700; font-size: 0.95rem; color: var(--window-text); white-space: nowrap; pointer-events: none; }
.stamp::before { content: ''; display: inline-flex; align-items: center; justify-content: center; width: 18px; height: 18px; border-radius: 50%; background: var(--stamp-blue); color: #fff; font-size: 0.85rem; font-weight: 700; line-height: 1; flex: none; font-family: Georgia, serif; }
.stamp.tone-blue::before { content: 'i'; background: var(--stamp-blue); }
.stamp.tone-green::before { content: '✔'; background: var(--stamp-green); font-family: var(--font); }
.stamp.tone-red::before { content: '✖'; background: var(--stamp-red); font-family: var(--font); }
.stamp.tone-amber::before { content: '!'; background: var(--stamp-amber); border-radius: 0; clip-path: polygon(50% 0, 100% 100%, 0 100%); width: 20px; height: 18px; padding-top: 4px; font-family: var(--font); }
.stamp.tone-ink::before { content: '■'; background: transparent; color: var(--window-text); border: 1px solid var(--window-text); border-radius: 0; font-size: 0.6rem; }
.stamp.tone-green { color: var(--stamp-green); } .stamp.tone-red { color: var(--stamp-red); } .stamp.tone-amber { color: var(--stamp-amber); } .stamp.tone-blue { color: var(--stamp-blue); }
:root[data-theme="dark"] .stamp::before { color: #000; }
.stamp.landed { animation: stampIn 0.25s steps(3, end) both; }
@keyframes stampIn { 0% { transform: scale(1.3); opacity: 0; } 100% { transform: none; opacity: 1; } }
.stamp-row { min-height: 26px; margin: 2px 0 8px; display: flex; align-items: center; }
.sheet .stamp-corner { position: static; display: inline-flex; margin: 0 0 6px; }
/* The system sheet's stamp (Live, Pilot, Suspended…) sits in the meta row, just after the department and status; the date stays right. */
.sheet-meta .meta-stamp { margin-right: auto; display: inline-flex; align-items: center; }
.sheet-meta .meta-stamp .stamp-corner { margin: 0; font-size: 0.85rem; }
.choice .stamp { position: absolute; right: 10px; top: 50%; transform: translateY(-50%); }

/* Portraits: initials in a square, or a drawn face (img/portraits), which brings its own ground in the person's hue.
   The insides are 16, 32 and 64 pixels (sm, lg, the People card) so the classic pictures, drawn on a 16-pixel grid,
   scale by whole pixels. */
.portrait { display: inline-flex; align-items: center; justify-content: center; font-weight: 700; letter-spacing: 0.02em; background: hsl(var(--hue) 45% 80%); color: hsl(var(--hue) 50% 20%); border: 1px solid var(--dark); box-shadow: 1px 1px var(--dark); flex: none; font-family: var(--font); }
.portrait.lg { width: 34px; height: 34px; font-size: 1rem; }
.portrait.sm { width: 18px; height: 18px; font-size: 0.7rem; box-shadow: none; }
.portrait.doc-icon { background: var(--window); border: 1px dashed var(--shadow); color: var(--gray-text); box-shadow: none; }
:root[data-theme="dark"] .portrait { background: hsl(var(--hue) 35% 30%); color: hsl(var(--hue) 50% 90%); border-color: var(--hilight); box-shadow: none; }
.portrait.drawn { overflow: hidden; }
.portrait.drawn img { display: block; width: 100%; height: 100%; }
.portrait.drawn .pic-modern { display: none; }

/* World events: a system message from outside */
.sheet.is-world .titlebar { background: linear-gradient(90deg, #404040, #808080); }
/* A proposal's sheet takes its department's colour and a programme's or one-off's the action colour, as their cards'
   header bars do (the same mix under white text, held at 4.5:1 by tests/css.test.js). */
.sheet.is-proposal > .titlebar, .sheet.is-action > .titlebar { background: linear-gradient(90deg, color-mix(in srgb, var(--dept) 55%, #000), color-mix(in srgb, var(--dept) 80%, #000)); color: #fff; }
.sheet.is-world .titlebar-text::after { content: ' from outside'; font-weight: 400; }
.sheet.is-world .sheet-meta > span:first-child::before { background: var(--stamp-amber); }

/* Board meeting minutes and the ledger */
.sheet.is-review .sheet-title::before { content: 'Minutes'; display: block; font-size: 0.85rem; font-weight: 400; color: var(--gray-text); margin-bottom: 2px; }
.review-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(110px, 1fr)); gap: 6px; margin: 4px 0 12px; }
.review-cell { display: flex; flex-direction: column; gap: 1px; padding: 5px 8px; }
.review-label { font-size: 0.85rem; color: var(--gray-text); }
.review-value { font-size: 1.2rem; font-weight: 700; }
.review-cell.bad .review-value { color: var(--stamp-red); }
.review-cell.blind .review-value { color: var(--gray-text); font-family: var(--font-mono); }
/* The ledger is a year-end workbook: formula bar, row numbers, gridlines, a double rule under totals */
.sheet.is-ledger .titlebar-text::after { content: ' · ledger.xls'; font-weight: 400; }
.ledger-wrap { padding: 0; margin-bottom: 10px; border: none; box-shadow: none; background: transparent; counter-reset: row; --grid: #d4d4d4; }
.ledger-wrap .hint { padding: 0 0 4px; }
.ledger-quarters { display: grid; grid-template-columns: repeat(4, 1fr); gap: 0; margin: 0 0 6px; }
.ledger-q { padding: 2px 6px; font-family: Arial, Helvetica, sans-serif; font-size: 11px; color: var(--gray-text); background: var(--window); border: 1px solid var(--grid); box-shadow: none; }
.ledger-q strong { display: block; font-size: 13px; color: var(--window-text); }
.ledger { width: 100%; border-collapse: collapse; font-family: Arial, Helvetica, sans-serif; font-size: 12px; color: var(--window-text); font-variant-numeric: tabular-nums; background: var(--window); }
.ledger th, .ledger td { border: 1px solid var(--grid); padding: 2px 6px; vertical-align: top; }
.ledger tr { counter-increment: row; }
.ledger th:first-child, .ledger td:first-child { padding-left: 34px; position: relative; }
.ledger th:first-child::before, .ledger td:first-child::before { content: counter(row); position: absolute; left: 0; top: 0; bottom: 0; width: 27px; background: var(--face); color: var(--window-text); font-weight: 400; font-size: 11px; text-align: center; line-height: 20px; border-right: 1px solid #a0a0a0; }
.ledger th { text-align: left; font-weight: 700; background: var(--face); border-bottom: 1px solid var(--dark); }
.ledger td:first-child { width: 34%; min-width: 150px; }
.ledger td.n { text-align: right; white-space: nowrap; width: 1%; }
.ledger td.note { color: var(--gray-text); font-size: 11px; white-space: normal; }
.ledger tr.total td { font-weight: 700; border-top: 1px solid var(--dark); border-bottom: 3px double var(--dark); }
.ledger .up { color: var(--stamp-green); } .ledger .down { color: var(--stamp-red); }
:root[data-theme="dark"] .ledger-wrap { --grid: #404040; }
/* ── The quarter report: a mail from the hospital's own reporting. Where a message from outside has prose and replies,
   this has objects pasted in from the office programs of the day: two workbook sheets (the ledger's grid) and a
   chart, each in the hatched frame of an embedded object, and one Close. ── */
.sheet.is-report > .titlebar { background: linear-gradient(90deg, #0f4a25, #2a7a47); color: #fff; }
.sheet.is-report .titlebar-text::after { content: ' · quarter report.xls'; font-weight: 400; }
.qmail-body { display: flex; flex-direction: column; gap: 10px; }
/* It arrives the way a message from someone does, growing up from the taskbar, once the desk has been back a moment.
   Until then the desk is held (holdDesk in js/screens.js): shown, with the busy cursor, taking no input. */
#modal-qmail .sheet { transform-origin: 50% 100%; animation: windowOut 0.24s steps(4, end); }
#screen-play.desk-held { cursor: progress; }
#screen-play.desk-held * { pointer-events: none; }
/* The report fits the screen as the proposal sheet does, and only its sheets and chart scroll: the title bar, the
   From and Subject rows and Close stay where they are. */
#modal-qmail > .sheet > .client { flex: 1 1 auto; min-height: 0; }
#modal-qmail .msg-head, #modal-qmail .qmail-end, #modal-qmail .qmail-body > .embed { flex: none; }
#modal-qmail .qmail-body { flex: 1 1 auto; min-height: 80px; overflow: auto; }
.embed { padding: 3px; background: repeating-linear-gradient(45deg, var(--shadow) 0 1px, var(--window) 1px 4px); }
.embed-cap { padding: 1px 6px; font-family: Arial, Helvetica, sans-serif; font-size: 11px; color: var(--window-text); background: var(--face); border: 1px solid var(--shadow); border-bottom: none; }
.embed-body { background: var(--window); border: 1px solid var(--shadow); overflow-x: auto; counter-reset: row; --grid: #d4d4d4; }
.embed-body .hint { margin: 0; padding: 6px 8px; }
:root[data-theme="dark"] .embed-body { --grid: #404040; }
.xl th.n { text-align: right; }
.xl td { vertical-align: middle; }
.xl td.n.up, .xl td.n.down { font-weight: 700; }
.xl td.up, .xl td.down { white-space: nowrap; }
.xl td .ic-res { vertical-align: -2px; }
.xl .xl-who { white-space: nowrap; }
.xl .xl-who .portrait { vertical-align: middle; margin-right: 6px; }
.xl td.xl-who::before { display: flex; align-items: center; justify-content: center; } /* the row number level with the face */
.xl .xl-did { min-width: 200px; } /* on a phone the sheet scrolls sideways before this column squeezes to a word a line */
.embed .rv-chart-mini { max-width: 440px; border: none; }
/* In the report the chart is one pasted from the office programs of the day, not the review's monitor: a light ground,
   solid outlined bars and plain labels, so it reads at a glance. */
body:not([data-os="modern"]) .embed .rv-chart-mini { background: var(--window); }
body:not([data-os="modern"]) .embed .rv-chart-mini .grid { stroke: var(--shadow); }
body:not([data-os="modern"]) .embed .rv-chart-mini .bar { fill: #9999ff; stroke: var(--window-text); stroke-width: 1; }
body:not([data-os="modern"]) .embed .rv-chart-mini .axis { fill: var(--window-text); font-family: Arial, Helvetica, sans-serif; }
.qmail-end { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: 8px; }
.qmail-end .hint { margin: 0; }
.qmail-end .actions { margin: 0 0 0 auto; }
.deal-in { animation: dealIn 0.18s steps(3, end) both; }
@keyframes dealIn { 0% { opacity: 0; } 100% { opacity: 1; } }

/* ── Who's who: an address book. A toolbar under the menubar, a find row, a folder tree on the left, a list with
   column headers, the selected person's properties below, a status bar. ── */
/* The window fits the screen: the list and the properties box scroll inside it rather than the window growing */
.addressbook { max-width: 860px; max-height: calc(100dvh - 92px); display: flex; flex-direction: column; }
.cast-client { padding: 4px 6px 6px; display: flex; flex-direction: column; gap: 4px; flex: 1 1 auto; min-height: 0; }
.toolbar { display: flex; align-items: stretch; flex-wrap: wrap; gap: 0; padding: 2px 4px; border-bottom: 1px solid var(--shadow); box-shadow: 0 1px var(--hilight); }
.tool-btn { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px; min-width: 56px; min-height: 40px; padding: 3px 6px; font: inherit; font-size: 0.85rem; color: var(--window-text); background: transparent; border: 1px solid transparent; box-shadow: none; border-radius: 0; }
.tool-btn::before { content: attr(data-icon); font-size: 1.15rem; line-height: 1; }
.tool-btn[aria-hidden], button.tool-btn[disabled] { color: var(--disabled-text); }
button.tool-btn:not([disabled]):hover, button.tool-btn:focus-visible { border-color: var(--hilight) var(--dark) var(--dark) var(--hilight); box-shadow: inset -1px -1px var(--shadow), inset 1px 1px var(--face-light); background: var(--face); outline: none; }
.cast-find { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; padding: 4px 2px; }
.cast-find input { flex: 1 1 200px; min-width: 0; }
.cast-find input::placeholder { color: transparent; }
.cast-main { display: grid; grid-template-columns: 160px minmax(0, 1fr); gap: 4px; min-height: 0; flex: 1 1 auto; }
/* The folders: a tree like the Help window's, with a root and three folders under it */
.cast-folders { display: flex; flex-direction: column; align-self: start; padding: 4px 4px 6px 6px; }
.cast-folders::before { content: 'Contacts'; font-weight: 700; padding: 2px 4px; }
.cast-folder { position: relative; display: flex; align-items: center; gap: 6px; padding: 2px 4px 2px 32px; min-height: var(--target); text-align: left; font: inherit; color: var(--window-text); background: transparent; border: none; box-shadow: none; border-radius: 0; margin-left: 6px; }
.cast-folder::before { content: ''; position: absolute; left: 4px; top: 0; bottom: 0; border-left: 1px dotted var(--shadow); }
.cast-folder:last-child::before { bottom: 50%; }
.cast-folder::after { content: ''; position: absolute; left: 12px; top: 50%; width: 13px; height: 10px; margin-top: -5px; border: 1px solid var(--dark); background: linear-gradient(180deg, #d9b64a 0 3px, #f0d878 3px); }
.cast-folder .count { margin-left: auto; color: var(--gray-text); font-size: 0.85rem; }
.cast-folder.active { background: var(--select); color: var(--select-text); }
.cast-folder.active .count { color: inherit; }
.cast-folder:focus-visible { outline: 1px dotted var(--window-text); outline-offset: -2px; }
/* The list: a ListView. One track list for the header strip and every row, so the columns line up */
.cast-body { --cast-cols: 26px minmax(140px, 1.6fr) minmax(120px, 1.4fr) minmax(100px, 1fr) 84px 76px; display: flex; flex-direction: column; min-height: 0; }
.cast-cols { display: grid; grid-template-columns: var(--cast-cols); scrollbar-gutter: stable; }
.cast-cols span { font-size: 0.9rem; padding: 2px 6px; background: var(--face); border: 1px solid; border-color: var(--hilight) var(--shadow) var(--shadow) var(--hilight); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cast-list { list-style: none; flex: 1 1 auto; min-height: 96px; max-height: 40vh; overflow: auto; scrollbar-gutter: stable; }
.cast-row { display: grid; grid-template-columns: var(--cast-cols); align-items: center; min-height: var(--target); padding: 0; cursor: default; }
.cast-cell { padding: 2px 6px; font-size: 0.92rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cast-pic { padding: 2px 4px; display: flex; }
.cast-name { display: flex; align-items: center; gap: 6px; min-width: 0; }
.cast-name-text { overflow: hidden; text-overflow: ellipsis; }
.cast-row.selected, .cast-row:focus-visible { background: var(--select); color: var(--select-text); outline: 1px dotted var(--select-text); outline-offset: -2px; }
.cast-row.selected .cast-cell, .cast-row.selected .mood-chip { color: inherit; border-color: var(--select-text); background: transparent; }
.cast-row.unmet { color: var(--disabled-text); }
.cast-group { display: none; }
.cast-list .hint { padding: 6px 8px; }
/* The selected person's properties: a group box under the list */
/* The frame holds the border and the label on it; the card scrolls inside, so the scroll does not clip the label */
.cast-detail-box { position: relative; display: flex; flex-direction: column; flex: 0 1 auto; min-height: 0; border: 1px solid var(--shadow); box-shadow: inset 1px 1px var(--hilight), 1px 1px var(--hilight); margin: 12px 0 4px; background: var(--face); }
.cast-detail-box::before { content: 'Properties'; position: absolute; top: -9px; left: 8px; z-index: 1; background: var(--face); padding: 0 4px; font-size: 0.9rem; font-weight: 700; line-height: 1.2; }
.cast-detail { flex: 0 1 auto; min-height: 0; max-height: 36vh; overflow: auto; padding: 14px 10px 10px; outline: none; }
.cast-detail:focus-visible { outline: 1px dotted var(--window-text); outline-offset: -3px; }
.cast-card { display: grid; grid-template-columns: auto 1fr; gap: 2px 10px; align-items: center; }
.cast-card .portrait { grid-row: 1 / span 2; }
.cast-card .portrait.lg { width: 66px; height: 66px; font-size: 1.6rem; }
.cast-card-name { margin: 0; font-size: 1rem; }
.cast-card-name .mood-chip { margin: 0 0 0 6px; }
.cast-card-does { color: var(--gray-text); font-size: 0.92rem; }
.cast-section-label { font-size: 0.85rem; font-weight: 700; margin: 10px 0 2px; }
.cast-contact { display: grid; grid-template-columns: 150px 1fr; gap: 2px 8px; margin: 0; font-size: 0.92rem; }
.cast-contact dt { color: var(--gray-text); }
.cast-contact dd { margin: 0; }
.cast-quote { font-style: italic; margin: 0 0 2px; }
.cast-notes .hint { margin: 0; }
.cast-diary { list-style: none; font-size: 0.9rem; }
.cast-diary li { display: grid; grid-template-columns: 96px 1fr; gap: 8px; padding: 2px 0; border-bottom: 1px dotted var(--shadow); }
.cast-diary-date { color: var(--gray-text); white-space: nowrap; }
.cast-status { margin-top: 2px; }
@media (max-width: 760px) {
  .cast-main { grid-template-columns: 1fr; }
  .cast-folders { flex-direction: row; flex-wrap: wrap; padding: 4px; }
  .cast-folders::before { content: none; }
  .cast-folder { margin: 0; padding-left: 24px; }
  .cast-folder::before { content: none; }
  .cast-folder::after { left: 6px; }
  .cast-body { --cast-cols: 26px minmax(0, 1.6fr) minmax(0, 1.4fr) 84px; }
  .cast-cols span:nth-child(4), .cast-cols span:nth-child(6), .cast-row .cast-dept, .cast-row .cast-met { display: none; }
  .cast-contact { grid-template-columns: 130px 1fr; }
}

/* ── Timeline ── */
.timeline { list-style: none; display: flex; flex-direction: column; padding: 2px 0; }
.timeline li { display: grid; grid-template-columns: 140px 1fr; gap: 12px; padding: 6px 8px; border-bottom: 1px dotted var(--face); font-size: 0.95rem; }
.timeline li:last-child { border-bottom: none; }
.timeline li.now { background: var(--select); color: var(--select-text); }
.timeline li.now * { color: inherit; }
.timeline li.open .tl-date { color: var(--stamp-red); }
.tl-date { font-weight: 700; }
.tl-date small { display: block; font-weight: 400; color: var(--gray-text); font-size: 0.85rem; }
.tl-label { font-weight: 700; }
.tl-what { color: var(--gray-text); font-size: 0.92rem; }
.tl-turn { font-size: 0.85rem; color: var(--gray-text); margin-top: 2px; }

/* ── Reference: a docked window with a tree ── */
.drawer { position: fixed; inset: 0; z-index: 45; background: rgba(0,0,0,0.25); display: flex; justify-content: flex-end; }
.drawer-panel { position: relative; width: min(560px, 100%); height: 100%; display: flex; flex-direction: column; padding: 2px; }
.drawer-panel > .client { flex: 1; display: flex; flex-direction: column; min-height: 0; }
.drawer-tabs { display: flex; gap: 0; align-items: flex-end; margin-bottom: 0; padding: 0 2px; position: relative; z-index: 1; }
.drawer-tab { border-bottom: none; padding: 3px 10px 4px; margin-right: -1px; font-size: 0.95rem; min-height: calc(var(--target) - 2px); position: relative; top: 1px; color: var(--window-text); }
.drawer-tab.active { font-weight: 700; padding-bottom: 6px; margin-bottom: -1px; z-index: 2; }
.drawer-body { flex: 1; overflow: auto; padding: 4px 6px 4px 8px; margin-top: 0; }
.drawer-find { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; padding: 2px 2px 8px; }
.drawer-find input { flex: 1 1 160px; min-width: 0; }
.drawer-met { color: var(--gray-text); font-size: 0.9rem; }
.drawer-panel .hint { padding: 6px 2px 4px; }
.drawer-entry { padding: 3px 0 3px 34px; position: relative; }
.drawer-entry summary { cursor: default; font-weight: 700; font-size: 0.95rem; display: flex; justify-content: space-between; gap: 8px; align-items: center; list-style: none; }
.drawer-entry summary::-webkit-details-marker { display: none; }
.drawer-entry summary::before { content: '+'; position: absolute; left: 0; top: 4px; width: 11px; height: 11px; border: 1px solid var(--shadow); background: var(--window); font-size: 10px; line-height: 9px; text-align: center; font-weight: 400; font-family: var(--font-mono); }
.drawer-entry[open] summary::before { content: '−'; }
.drawer-entry summary:hover { background: var(--select); color: var(--select-text); }
.drawer-entry summary:hover .kind { color: inherit; }
.drawer-entry .kind { font-size: 0.85rem; color: var(--gray-text); white-space: nowrap; }
.drawer-entry .plain { margin: 6px 0 4px; font-size: 0.95rem; }
.drawer-entry .text { font-size: 0.9rem; color: var(--window-text); border-left: 2px solid var(--shadow); padding-left: 8px; margin-bottom: 4px; white-space: pre-wrap; font-family: var(--font-mono); }
.drawer-entry .text.current { border-left-color: var(--stamp-blue); }
.drawer-entry .wording-label { font-size: 0.85rem; color: var(--gray-text); margin: 6px 0 2px; }
.drawer-entry .src { font-size: 0.85rem; color: var(--gray-text); word-break: break-all; }
.drawer-entry.locked summary { color: var(--disabled-text); font-weight: 400; }

/* ── Report: a maximised window ── */
#screen-report { padding: 18px 12px; align-items: center; }
.report-wrap { max-width: 880px; width: 100%; }
.report-wrap h2 { margin: 18px 0 4px; }
.metric-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 6px; margin: 10px 0 6px; }
.metric-chip { display: flex; flex-direction: column; gap: 1px; padding: 6px 10px; }
.metric-label { font-size: 0.85rem; color: var(--gray-text); }
.metric-value { font-size: 1.3rem; font-weight: 700; }
.pane { padding: 0; overflow-x: auto; margin-bottom: 8px; }
.report-table { width: 100%; border-collapse: collapse; font-size: 0.92rem; }
.report-table th, .report-table td { text-align: left; padding: 3px 8px; vertical-align: top; }
.report-table th { font-weight: 400; background: var(--face); border: 1px solid; border-color: var(--hilight) var(--shadow) var(--shadow) var(--hilight); }
.report-table td { border-bottom: 1px dotted var(--face); }
.report-table .st-due, .report-table .st-open { color: var(--stamp-red); font-weight: 700; } .report-table .st-funded { color: var(--stamp-green); }

/* ── Options, toast, tooltip ── */
.options-body { display: flex; flex-direction: column; gap: 10px; }
.options-body label { display: flex; gap: 6px; align-items: center; min-height: var(--target); }
.options-body select { padding: 2px 4px; }
/* First-encounter tips */
#explainer-modal { z-index: 50; align-items: flex-start; padding: 28px 12px; }
#explainer-modal .sheet { margin: auto 0; }
.explainer-head { display: flex; align-items: center; gap: 8px; margin-bottom: 4px; }
.explainer-from { overflow-wrap: anywhere; }
.explainer-opt { display: flex; gap: 6px; align-items: center; min-height: var(--target); margin-top: 6px; }
/* Tips arrive as the computer's own messages (revealExplainer in js/screens.js). A tip is a notification from the tray:
   a balloon at the bottom right over the clock, on a clear overlay that still waits for Got it. A story message is a
   window that grows out of the tray. Under reduced motion both simply appear. */
#explainer-modal.as-note { background: transparent; align-items: flex-end; justify-content: flex-end; padding: 0 10px 44px; }
#explainer-modal.as-note .sheet { margin: 0; max-width: 360px; position: relative; --rise-y: 12px; animation: rise 0.25s ease-out; }
#explainer-modal.as-note .sheet .client { background: var(--info); }
#explainer-modal.as-note .sheet::after { content: ''; position: absolute; right: 34px; bottom: -11px; border: 11px solid transparent; border-bottom: 0; border-top-color: var(--window-text); }
#explainer-modal.as-note .sheet::before { content: ''; position: absolute; right: 35px; bottom: -9px; z-index: 1; border: 10px solid transparent; border-bottom: 0; border-top-color: var(--info); }
/* The one rise-in: a tip's note, a desk tab, the folder, a card put down on the desk, the new desktop's splash and review rows, each setting how far (and how small, and how turned) it starts from */
@keyframes rise { from { opacity: 0; transform: translateY(var(--rise-y, 12px)) scale(var(--rise-scale, 1)) rotate(var(--rise-turn, 0deg)); } to { opacity: 1; transform: none; } }
#explainer-modal.as-window .sheet { transform-origin: 100% 100%; animation: windowOut 0.24s steps(4, end); }
@keyframes windowOut { from { transform: scale(0.1); opacity: 0.4; } to { transform: none; opacity: 1; } }
/* The tray's notice icon blinks while a message is on its way */
.tray-note { display: inline-flex; align-items: center; justify-content: center; width: 14px; height: 14px; margin-right: 6px; border-radius: 50%; background: var(--stamp-blue); color: #fff; font: 700 0.75rem/1 Georgia, serif; animation: trayBlink 0.3s steps(2, end) infinite; }
@keyframes trayBlink { 50% { opacity: 0.15; } }
/* The toast (what someone says back, what an action did) sits three quarters of the way up the screen, where the eye is */
.toast { position: fixed; top: 25%; left: 50%; transform: translateX(-50%); max-width: min(560px, calc(100vw - 24px)); text-align: center; background: var(--info); color: var(--window-text); border: 1px solid var(--window-text); padding: 5px 12px; font-size: 0.95rem; z-index: 80; opacity: 0; transition: opacity 0.15s; }
.toast.show { opacity: 1; }
.tooltip { position: fixed; z-index: 100; max-width: 260px; background: var(--info); color: var(--window-text); border: 1px solid var(--window-text); padding: 3px 6px; font-size: 0.9rem; line-height: 1.35; pointer-events: none; opacity: 0; transition: opacity 0.1s; }
.tooltip.visible { opacity: 1; }

/* ── Play style: time on the desk ── */
.calendar { display: grid; grid-template-columns: 1fr; gap: 4px; padding: 4px; background: var(--window); border: 1px solid; border-color: var(--shadow) var(--hilight) var(--hilight) var(--shadow); box-shadow: inset 1px 1px var(--dark), inset -1px -1px var(--face-light); font-family: Arial, Helvetica, sans-serif; }
.cal-head { display: block; width: 100%; padding: 0; font-family: inherit; color: inherit; cursor: inherit; font-weight: 700; font-size: 11px; text-align: center; background: var(--face); border: 1px solid var(--shadow); margin-bottom: 2px; line-height: 15px; }
.cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 1px; }
.cal-dow { font-size: 9px; color: var(--gray-text); text-align: center; border-bottom: 1px solid var(--shadow); line-height: 12px; }
.cal-day { font-size: 10px; text-align: center; line-height: 15px; position: relative; color: var(--window-text); }
.cal-day.past { color: var(--disabled-text); }
.cal-day.today { background: var(--select); color: var(--select-text); font-weight: 700; }
.cal-day.due::after { content: ''; position: absolute; left: 50%; bottom: 1px; width: 4px; height: 4px; margin-left: -2px; background: var(--stamp-red); }
.cal-day.last { outline: 1px dotted var(--window-text); outline-offset: -1px; }
/* The month's name between two arrows that page through the quarter; a day with something on it is a button that opens
   it in the panel under the month (fillCalendar in js/views.js). */
.cal-nav { display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: 2px; margin-bottom: 2px; }
.cal-nav .cal-head { margin-bottom: 0; }
.cal-arrow { font-family: inherit; font-size: 11px; line-height: 13px; width: 17px; padding: 0; color: var(--window-text); background: var(--face); border: 1px solid; border-color: var(--hilight) var(--dark) var(--dark) var(--hilight); cursor: pointer; }
.cal-arrow:active:not(:disabled) { border-color: var(--dark) var(--hilight) var(--hilight) var(--dark); }
.cal-arrow:disabled { color: var(--disabled-text); cursor: default; }
button.cal-day { display: block; width: 100%; margin: 0; padding: 0; border: 0; background: transparent; font-family: inherit; cursor: pointer; }
button.cal-day.today { background: var(--select); }
.cal-day.selected { box-shadow: inset 0 0 0 1px var(--window-text); }
.cal-day.today.selected { box-shadow: inset 0 0 0 1px var(--select-text); }
/* A date of the Act: a corner flag, as on the Year planner. */
.cal-day.act::before { content: ''; position: absolute; top: 0; right: 0; border: 3px solid transparent; border-top-color: var(--select); border-right-color: var(--select); }
.cal-day.today.act::before { border-top-color: var(--select-text); border-right-color: var(--select-text); }
/* A card on its way: a small square in the corner of the day it arrives. */
.cal-day.expected { background-image: linear-gradient(var(--stamp-blue), var(--stamp-blue)); background-size: 4px 4px; background-repeat: no-repeat; background-position: 1px 1px; }
/* Cards coming back next quarter: a bar under the quarter's last day. */
.cal-day.back { box-shadow: inset 0 -2px var(--stamp-blue); }
.cal-panel { margin-top: 3px; padding-top: 3px; border-top: 1px solid var(--shadow); font-size: 11px; line-height: 1.3; }
.cal-panel-head { display: flex; align-items: center; justify-content: space-between; gap: 4px; font-weight: 700; }
.cal-panel-close { font-family: inherit; font-size: 11px; line-height: 11px; width: 15px; height: 14px; padding: 0; color: var(--window-text); background: var(--face); border: 1px solid; border-color: var(--hilight) var(--dark) var(--dark) var(--hilight); cursor: pointer; }
.cal-group { margin-top: 3px; }
.cal-group-head { color: var(--gray-text); font-size: 10px; }
.cal-items { list-style: none; margin: 0; padding: 0; }
.cal-item { display: flex; flex-direction: column; width: 100%; padding: 1px 2px; text-align: left; font-family: inherit; font-size: 11px; color: var(--window-text); background: none; border: 0; }
button.cal-item { color: var(--link); cursor: pointer; }
button.cal-item .cal-item-text { text-decoration: underline; }
.cal-item small { color: var(--gray-text); font-size: 10px; }
.cal-empty { margin-top: 2px; color: var(--gray-text); }
.cal-wait-row { margin-top: 4px; }
.cal-wait { width: 100%; min-height: 0; padding: 2px 6px; font-size: 11px; }
.cal-wait-warn { margin-top: 2px; color: var(--stamp-red); font-size: 10px; }
/* The date moving on (calendarTravel in js/screens.js): today's marker, one square under the numbers, hops a day at a
   time to the new date; the cell it stands on shows its number as today's does. On arrival the new date blinks inside
   an outline; under reduced motion there is no travel and the outline stays, still. */
.cal-grid { position: relative; }
.cal-marker { position: absolute; background: var(--select); pointer-events: none; transition-property: none; }
.cal-moving .cal-day.today { background: transparent; color: inherit; font-weight: inherit; }
.cal-moving .cal-day.past.today { color: var(--disabled-text); }
.cal-moving .cal-day.under { color: var(--select-text); font-weight: 700; }
.cal-day.cal-arrive { outline: 2px solid var(--action); outline-offset: 1px; z-index: 2; animation: calArrive 0.36s steps(2, end) 3; }
@keyframes calArrive { 0% { background: var(--select); color: var(--select-text); } 50% { background: var(--window); color: var(--select); } }
.task-btn.task-flash { animation: taskFlash 0.4s steps(2, end) 3; }
@keyframes taskFlash { 0% { background: var(--select); color: var(--select-text); } }

/* ── Play style: triage cues ── */
#tab-intray .count-soft { font-weight: 700; color: var(--select); }
.doc:has(.date-stamp.soon) { border-left: 2px solid var(--stamp-red); }
.doc:has(.date-stamp.soon) .doc-kicker::before { content: '⚑'; color: var(--stamp-red); background: #fff; width: 14px; height: 14px; line-height: 14px; text-align: center; font-size: 11px; margin-right: 4px; flex: none; }

/* ── Play style: assessment as a wizard ── */
.wizard { max-width: 640px; }
.wizard .client { display: grid; grid-template-columns: 150px 1fr; gap: 0; padding: 0; }
.wizard-banner { background: linear-gradient(180deg, var(--title-a), var(--title-b)); color: #fff; padding: 12px 10px; display: flex; align-items: flex-end; min-height: 320px; }
.wizard-banner .sheet-title { color: #fff; font-size: 1.05rem; margin: 0; }
.wizard-page { padding: 12px 14px 10px; display: flex; flex-direction: column; min-height: 320px; }
.wizard-page .sheet-meta { justify-content: flex-end; }
.wizard-page #assess-progress:not(:empty)::before { content: 'Step '; }
#assess-options .choice, #assess-options .choice.chosen, #assess-options .choice:active { border-color: transparent; box-shadow: none; background: transparent; padding: 4px 8px 4px 26px; position: relative; min-height: 26px; }
#assess-options .choice:hover { background: var(--face-light); }
#assess-options .choice::before { content: ''; position: absolute; left: 6px; top: 8px; width: 12px; height: 12px; border-radius: 50%; background: var(--window); border: 1px solid; border-color: var(--shadow) var(--hilight) var(--hilight) var(--shadow); box-shadow: inset 1px 1px var(--dark); }
#assess-options .choice.chosen::before { background: radial-gradient(circle, var(--window-text) 3px, var(--window) 3.5px); }
.wizard .outcome { border-top: 1px solid var(--shadow); box-shadow: inset 0 1px var(--hilight); margin-top: auto; padding-top: 8px; }
.wizard .actions { justify-content: flex-end; }
#assess-next-btn::after { content: ' >'; }

/* ── Play style: group boxes on property sheets ── */
.groupbox, .file, #sys-controls-wrap, #sys-history-wrap, #prog-levels { position: relative; border: 1px solid var(--shadow); box-shadow: inset 1px 1px var(--hilight), 1px 1px var(--hilight); padding: 14px 10px 10px; margin: 12px 0 14px; background: var(--face); }
.groupbox > .legend, .file::before, #prog-levels::before, #sys-controls-wrap > h3, #sys-history-wrap > h3 { position: absolute; top: -9px; left: 8px; background: var(--face); padding: 0 4px; margin: 0; font-size: 0.9rem; font-weight: 700; line-height: 1.2; }
.file::before { content: 'System entry'; }
#prog-levels::before { content: 'Levels'; }
#sys-controls-wrap .hint { margin-bottom: 8px; padding-bottom: 2px; }
/* The way out of an assessment started by mistake (stopAssessment in js/screens.js) */
.assess-stop-row { margin: 8px 0 0; font-size: 0.85rem; }
.assess-stop-row .link-btn { min-height: 0; font-size: inherit; }
/* The proposal, programme and one-off windows fit the screen: the title bar stays, the rest scrolls inside */
#modal-system > .sheet, #modal-programme > .sheet, #modal-intervention > .sheet, #modal-qmail > .sheet, #modal-timeline > .sheet { display: flex; flex-direction: column; max-height: calc(100dvh - var(--overlay-pad-y, 88px)); }
#modal-system > .sheet > .client, #modal-programme > .sheet > .client, #modal-intervention > .sheet > .client { flex: 1 1 auto; min-height: 0; overflow: auto; }
/* What it needs and Story so far fold to their legend (wireFoldbox in js/views.js). On a proposal the two scroll as one
   area (#sys-lower below); elsewhere a long list scrolls inside its own box */
.foldbox > h3 .box-toggle { all: unset; cursor: pointer; font: inherit; }
.foldbox > h3 .box-toggle::before { content: '\25BE\00a0'; }
.foldbox.folded > h3 .box-toggle::before { content: '\25B8\00a0'; }
.foldbox > h3 .box-toggle:focus-visible { outline: 1px dotted var(--window-text); }
.foldbox.folded { padding-top: 6px; padding-bottom: 0; }
.foldbox.folded > .box-body { display: none; }
.foldbox > .box-body { max-height: 30vh; overflow: auto; }
#sys-lower .foldbox > .box-body { max-height: none; overflow: visible; }
/* On a proposal the part above stays put and only the two boxes scroll, filling what is left of the window. If the part
   above is itself taller than the window (a small phone), the whole window scrolls as a last resort. */
#modal-system > .sheet > .client { display: flex; flex-direction: column; }
#modal-system > .sheet > .client > * { flex-shrink: 0; }
#modal-system > .sheet > .client > #sys-lower { flex: 1 1 auto; min-height: 0; overflow: auto; margin-top: 6px; padding-top: 2px; border-top: 1px solid var(--shadow); box-shadow: 0 -1px var(--hilight); }
#modal-system > .sheet > .client > #sys-lower:has(#sys-controls > li:nth-child(4), #sys-history > li:nth-child(4)) { min-height: min(240px, 38dvh); } /* a list long enough to need it: room for several rows before anything scrolls; a short one takes its own height */
.session .start-grid { margin: 0; }
.session-note { margin: 8px 0 0; font-size: 0.85rem; }
/* The test-build note and the form links (meta.test_note, meta.links): small, with the links underlined. */
.test-note { margin: 0 0 10px; font-size: 0.85rem; color: var(--gray-text); }
.test-note a { color: var(--link); text-decoration: underline; }
.rv-links { margin: -4px 0 10px; }

/* ── Play style: Reference as Windows Help ── */
.drawer-entry::before { content: ''; position: absolute; left: 5px; top: 0; bottom: 0; border-left: 1px dotted var(--shadow); }
.drawer-entry summary::before { z-index: 1; }
.drawer-entry summary > span:first-child::before { content: ''; display: inline-block; width: 10px; height: 12px; margin-right: 6px; vertical-align: -2px; border: 1px solid var(--dark); background: linear-gradient(90deg, #6d2323 0 3px, #b84040 3px); }
.drawer-entry[open] summary > span:first-child::before { background: linear-gradient(90deg, var(--window) 0 4px, var(--shadow) 4px 5px, var(--window) 5px); }
.help-status { display: flex; gap: 3px; margin-top: 4px; }
.help-status > * { flex: 1; margin: 0; padding: 2px 6px; font-size: 0.85rem; min-height: 20px; border: 1px solid; border-color: var(--shadow) var(--hilight) var(--hilight) var(--shadow); color: var(--window-text); }
.help-status .badge { flex: 2; color: var(--gray-text); }

/* ── Play style: logon ── */
.logon-banner { background: linear-gradient(90deg, var(--title-a), var(--title-b)); color: #fff; padding: 10px 12px 12px; margin: -10px -10px 12px; }
.logon-banner .menu-title { color: #fff; font-size: 1.4rem; margin: 0; }
.logon-fields { display: grid; grid-template-columns: 90px minmax(0, 320px); gap: 6px 8px; align-items: center; margin-bottom: 12px; }
.logon-label { font-size: 0.95rem; }
/* A filled-in field: the logon's user name and the system entry's values on a proposal sheet */
.logon-fields .field, .file dd { background: var(--window); color: var(--window-text); padding: 2px 6px; min-height: 22px; border: 1px solid; border-color: var(--shadow) var(--hilight) var(--hilight) var(--shadow); box-shadow: inset 1px 1px var(--dark), inset -1px -1px var(--face-light); }

/* About: the old desktop's own About box. A banner in the title-bar colours with a thin stripe, the product and
   its version, an etched rule, a sunken text box that scrolls, and who the copy is licensed to. Tokens only. */
.about-box { max-width: 480px; }
.about-banner { position: relative; display: flex; align-items: center; gap: 12px; padding: 14px 16px 16px; background: linear-gradient(90deg, var(--title-a), var(--title-b)); color: var(--title-text); }
.about-banner::after { content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 4px; background: linear-gradient(90deg, var(--stamp-red) 0 25%, var(--stamp-amber) 25% 50%, var(--stamp-green) 50% 75%, var(--stamp-blue) 75%); }
.about-glyph { display: flex; flex: none; align-items: center; justify-content: center; width: 40px; height: 40px; border: 2px solid var(--title-text); border-radius: 50%; font: italic 700 1.6rem Georgia, "Times New Roman", serif; }
.about-banner-text { min-width: 0; }
.about-banner-name { display: block; font-size: 1.3rem; font-weight: 700; line-height: 1.2; }
.about-banner-sub { display: block; font-size: 0.88rem; }
.about-version { margin: 0; font-size: 0.92rem; }
.about-rule { border: 0; border-top: 1px solid var(--shadow); border-bottom: 1px solid var(--hilight); margin: 10px 0; }
.about-body { max-height: 240px; overflow: auto; padding: 6px 10px; background: var(--window); color: var(--window-text); border: 1px solid; border-color: var(--shadow) var(--hilight) var(--hilight) var(--shadow); box-shadow: inset 1px 1px var(--dark), inset -1px -1px var(--face-light); }
.about-body:focus-visible { outline: 1px dotted var(--window-text); outline-offset: 2px; }
.about-body h3 { font-size: 0.95rem; margin: 10px 0 2px; }
.about-body h3:first-child { margin-top: 2px; }
.about-body p { margin: 0 0 6px; font-size: 0.92rem; }
.about-links { margin: 0 0 6px; padding-left: 18px; font-size: 0.92rem; }
.about-links a { color: var(--link); text-decoration: underline; }
/* The forms in About are buttons beside OK: anchors dressed as .btn, ahead of it in the row, OK at the end. */
.actions a.about-form { order: -2; display: inline-flex; align-items: center; justify-content: center; text-decoration: none; color: var(--window-text); }
.about-privacy { margin: 8px 0 0; font-size: 0.9rem; }
/* How to play: the About box's scrolling text box, taller, with its own row of buttons. */
.howto-box { max-width: 520px; }
.howto-body { max-height: 52vh; }
/* A button that reads as one of the links beside it (Copy details on the review). */
.link-btn { background: none; border: 0; padding: 0; font: inherit; color: var(--link); text-decoration: underline; cursor: pointer; }
.about-privacy a, .about-version a, .analytics-opt a, .options-body a { color: var(--link); text-decoration: underline; }

/* privacy.html: one old-desktop window on the desktop colour. The window's width sets the line length, so the
   text fills it with even padding on both sides. */
.policy-body { padding: 16px; }
.policy-page { max-width: 640px; margin: 0 auto; }
.policy-page .client { background: var(--window); padding: 16px 24px 18px; }
.policy-page h1 { font-size: 1.4rem; margin: 4px 0 10px; }
.policy-page h2 { font-size: 1.1rem; margin: 18px 0 6px; }
.policy-page ul { padding-left: 22px; margin: 0 0 8px; }
.policy-page a { color: var(--link); text-decoration: underline; }
.policy-page .terms-credit { font-style: italic; }
@media (max-width: 480px) { .policy-body { padding: 8px; } .policy-page .client { padding: 12px 14px 14px; } }

/* soon.html, the holding page: the old desktop with one setup program that never quite finishes, its last button the
   sign-up. The window is the assessment wizard's shape (a banner down the left, the page beside it) with the install
   screen's bar. The corners are the desk's: the asset tag bottom right, the small print bottom left. One column on a
   phone, where the small print follows the window. */
.soon-body { display: flex; flex-direction: column; justify-content: center; padding: 24px 16px 64px; }
.soon-body .asset-tag { bottom: 12px; }
.soon-desk { position: relative; z-index: 1; width: 100%; max-width: 600px; margin: 0 auto; }
.soon-setup .soon-setup-client { display: grid; grid-template-columns: 120px minmax(0, 1fr); padding: 0; }
.soon-banner { display: flex; align-items: flex-end; padding: 12px 10px; background: linear-gradient(180deg, var(--title-a), var(--title-b)); color: var(--title-text); font-weight: 700; font-size: 1.05rem; line-height: 1.2; }
.soon-page { min-width: 0; padding: 12px 14px 10px; }
.soon-title { font-size: 1.3rem; margin: 0 0 4px; }
/* The components: the old desktop's check boxes, drawn (a disabled input greys its tick away), ticked unless left out */
.soon-parts { list-style: none; }
.soon-parts li { position: relative; margin: 3px 0; padding-left: 20px; }
.soon-parts li::before { content: ''; position: absolute; left: 0; top: 0.1em; width: 13px; height: 13px; background: var(--window); border: 1px solid; border-color: var(--shadow) var(--hilight) var(--hilight) var(--shadow); box-shadow: inset 1px 1px var(--dark), inset -1px -1px var(--face-light); }
.soon-parts li.soon-on::after { content: ''; position: absolute; left: 5px; top: calc(0.1em + 2px); width: 3px; height: 6px; border: solid var(--window-text); border-width: 0 2px 2px 0; transform: rotate(45deg); }
.soon-status { margin: 0 0 4px; }
.soon-bar .install-fill { width: 97%; transition: width 0.4s steps(2, end); }
.soon-eta { margin: 4px 0 8px; }
/* Back and Next greyed, the sign-up where Cancel would be: last in the row, though it is the default button */
.soon-actions { padding-top: 10px; border-top: 1px solid var(--shadow); box-shadow: inset 0 1px var(--hilight); }
.soon-actions .btn-primary { order: 0; }
a.soon-signup { display: inline-flex; align-items: center; justify-content: center; text-decoration: none; color: var(--window-text); }
/* The message box that comes up once: the old desktop's warning, over the setup window, its one button centred */
.soon-popup { position: absolute; z-index: 2; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 300px; max-width: calc(100vw - 32px); box-shadow: inset -1px -1px var(--shadow), inset 1px 1px var(--hilight), 2px 2px 0 rgba(0, 0, 0, 0.35); }
.soon-popup-text { display: flex; align-items: center; gap: 12px; margin: 6px 4px 10px; }
.soon-popup-icon { flex: none; display: inline-flex; align-items: flex-end; justify-content: center; width: 32px; height: 28px; padding-bottom: 3px; background: var(--stamp-amber); color: #000000; font-weight: 700; font-size: 1rem; line-height: 1; clip-path: polygon(50% 0, 100% 100%, 0 100%); }
.soon-popup-icon::before { content: '!'; }
/* The last visit is a stop: the old desktop's red circle with a white cross */
.soon-popup[data-kind="stop"] .soon-popup-icon { align-items: center; width: 30px; height: 30px; padding: 0; background: var(--stamp-red); color: #ffffff; font-size: 1.2rem; clip-path: circle(50%); }
.soon-popup[data-kind="stop"] .soon-popup-icon::before { content: '\00D7'; }
.soon-popup .actions { justify-content: center; margin: 0 0 2px; }
/* The small print, bottom left: the asset tag's twin, in the same white on the desktop */
.soon-corner { position: fixed; left: 12px; bottom: 12px; z-index: 1; color: #ffffff; font-size: 0.8rem; line-height: 1.35; }
.soon-corner p { margin: 0; }
.soon-corner a { color: #ffffff; text-decoration: underline; }
.soon-corner .analytics-opt { margin: 4px 0 0; color: #ffffff; font-size: 0.8rem; }
@media (max-width: 760px) {
  .soon-body { padding: 16px; }
  .soon-setup .soon-setup-client { grid-template-columns: minmax(0, 1fr); }
  .soon-banner { display: none; } /* the title bar and the heading name the game already */
  /* Here a log line may wrap: two lines are held, the text sitting on the bar, so a short line does not pull the bar up */
  .soon-status { display: flex; align-items: flex-end; min-height: 2.8em; }
  .soon-corner { position: static; margin: 12px auto 0; width: 100%; max-width: 600px; }
  .soon-popup { position: fixed; }
}

/* The analytics checkbox at the foot of the logon: a dialog checkbox in small print, with the privacy link beside it. */
.analytics-opt { display: flex; flex-wrap: wrap; align-items: center; gap: 2px 10px; margin: 8px 0 0; font-size: 0.85rem; color: var(--gray-text); }
.analytics-opt label { display: inline-flex; align-items: center; }
@media (max-width: 760px) {
  .about-banner { padding: 10px 12px 12px; }
  .about-banner-sub { display: none; }
  .about-glyph { width: 32px; height: 32px; font-size: 1.3rem; }
  .about-body { max-height: 40vh; }
}

/* Chrome is not text: buttons, title bars, tabs, the taskbar and menus cannot be selected by a stray drag. */
button, .btn, .titlebar, .taskbar, .folder-tab, .more-menu, .menubar, .toolbar, .choice, .start-card { -webkit-user-select: none; user-select: none; }

/* Pieces only the new desktop shows (css/modern.css): the search pill, Start search, the user row, the tray
   glyphs and the weekday on the clock. The old desktop never had them. */
.task-search, .start-search, .start-user, .tray-glyphs, .tray-day { display: none; }

/* ── The ending: the crash screen when trust runs out, the win when a full run reaches its last date, the splash when a quick run is done ── */
#screen-ending { align-items: center; justify-content: center; padding: 16px; }
.ending { width: 100%; max-width: 760px; outline: none; cursor: pointer; }
#ending-box:focus, #ending-box:focus-visible { outline: none; } /* focused so keys land here; it is not a control */
.ending-prompt { margin-top: 18px; }
/* The old desktop's stop screen: blue, white monospace, a blinking cursor */
#screen-ending:has(.ending-crash.ending-classic) { background: #0000aa; }
.crash-classic { color: #ffffff; font-family: "Lucida Console", "Courier New", monospace; font-size: 1.05rem; line-height: 1.5; max-width: 68ch; }
.crash-classic p { margin: 0 0 12px; }
.crash-classic .crash-head { display: inline-block; background: #aaaaaa; color: #0000aa; padding: 0 8px; font-weight: 700; margin-bottom: 18px; }
.crash-classic .crash-code { font-weight: 700; letter-spacing: 0.04em; }
.crash-cursor { display: inline-block; margin-left: 4px; animation: crash-blink 1s steps(1) infinite; }
.crash-cursor.still { animation: none; }
@keyframes crash-blink { 50% { opacity: 0; } }
/* The old desktop's splash: a banner in the title-bar gradient, and a strip of blocks that fills */
.ending-splash.ending-classic .splash { background: var(--face); border: 1px solid; border-color: var(--hilight) var(--dark) var(--dark) var(--hilight); box-shadow: inset -1px -1px var(--shadow), inset 1px 1px var(--face-light); padding: 0 0 16px; }
.ending-splash.ending-classic .splash-banner { background: linear-gradient(90deg, var(--title-a), var(--title-b)); color: #ffffff; padding: 22px 24px 20px; display: grid; grid-template-columns: auto 1fr; column-gap: 16px; align-items: center; }
.ending-splash.ending-classic .splash-icon { grid-row: 1 / span 2; font-size: 2.6rem; }
.ending-splash.ending-classic .splash-title { margin: 0; font-size: 1.9rem; line-height: 1.15; color: #ffffff; }
.ending-splash.ending-classic .splash-line { margin: 6px 0 0; color: #e6eefa; }
.ending-splash.ending-classic .splash-style { margin: 16px 24px 0; font-weight: 700; font-size: 1.1rem; }
.ending-splash.ending-classic .splash-progress { margin: 14px 24px 0; height: 18px; border: 1px solid; border-color: var(--shadow) var(--hilight) var(--hilight) var(--shadow); padding: 2px; background: var(--window); }
.ending-splash.ending-classic .splash-progress i { display: block; height: 100%; width: 100%; background: repeating-linear-gradient(90deg, var(--select) 0 10px, transparent 10px 12px); transform-origin: left; animation: splash-fill 1.6s steps(24) both; }
.ending-splash.ending-classic .splash-progress.still i { animation: none; }
.ending-splash.ending-classic .ending-prompt { margin: 14px 24px 0; color: var(--gray-text); }
@keyframes splash-fill { from { transform: scaleX(0); } to { transform: scaleX(1); } }
/* The old desktop's win: the black screen that said it was now safe to switch off, in large orange letters */
#screen-ending:has(.ending-win.ending-classic) { background: #000000; }
.win-classic { color: #ff8c00; font-family: Arial, Helvetica, sans-serif; text-align: center; max-width: 64ch; margin: 0 auto; }
.win-classic p { margin: 0 0 12px; }
.win-classic .win-line { font-size: 1.2rem; }
.win-classic .win-safe { font-size: clamp(1.7rem, 4.6vw, 2.7rem); font-weight: 700; line-height: 1.25; margin: 6px 0 30px; }
.win-classic .win-grade { color: #ffffff; font-weight: 700; font-size: 1.25rem; }
.win-classic .ending-prompt { margin-top: 26px; color: #aaaaaa; font-family: "Lucida Console", "Courier New", monospace; font-size: 0.95rem; }

/* Text for screen readers only */
.copy-image { display: block; max-width: 100%; height: auto; margin: 8px 0; border: 1px solid var(--shadow); }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

/* ── The programme review (js/endscreen.js), old desktop: a tabbed properties window ── */
.review .client { display: flex; flex-direction: column; gap: 10px; }
.rv-hero { background: var(--window); border: 1px solid; border-color: var(--shadow) var(--hilight) var(--hilight) var(--shadow); padding: 10px 12px; }
.rv-hero-main { display: grid; grid-template-columns: auto 1fr; gap: 12px; align-items: start; }
.rv-hero-icon { font-size: 2.2rem; line-height: 1; }
.rv-hero-title { margin: 0; font-size: 1.45rem; line-height: 1.2; }
.rv-hero-trust .rv-hero-title { color: var(--stamp-red); }
.rv-hero-line { margin: 4px 0 0; }
.rv-hero-meta { margin: 4px 0 0; color: var(--gray-text); font-size: 0.9rem; }
.rv-style { margin-top: 10px; padding-top: 8px; border-top: 1px solid var(--shadow); box-shadow: 0 -1px var(--hilight) inset; }
.rv-style-pill { font-weight: 700; font-size: 1.1rem; }
.rv-style-line { margin: 2px 0 0; }
/* A win's letter: the mail window's header rows and its sunken body, inside the review */
.rv-letter { padding: 2px 2px 0; }
.rv-letter .msg-head { margin-bottom: 6px; }
.rv-letter .msg-body { min-height: 0; }
.rv-letter-text { margin: 0; line-height: 1.5; }
.rv-actions-top { display: flex; justify-content: flex-end; }
.rv-panel-title { display: none; }
.rv-panel.rv-off { display: none; } /* the tab not chosen; its own class, so the new look can show every panel without fighting .hidden */
.rv-detail > summary { display: none; }
.rv-groups { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
.rv-group { display: flex; flex-wrap: wrap; gap: 8px 18px; align-content: flex-start; }
.rv-fig { display: flex; flex-direction: column; min-width: 110px; }
.rv-num { font-size: 1.9rem; line-height: 1.1; display: inline-flex; align-items: center; gap: 4px; }
.rv-label { font-size: 0.9rem; }
.rv-sub { font-size: 0.82rem; color: var(--gray-text); }
.rv-bad, .rv-bad .rv-num { color: var(--stamp-red); }
.rv-mark { font-size: 0.8em; }
.rv-safety { display: flex; gap: 14px; align-items: flex-start; flex-wrap: wrap; width: 100%; }
.rv-ring { width: 130px; height: 130px; flex: none; }
.rv-safety-figs { display: flex; flex-wrap: wrap; gap: 6px 18px; flex: 1; min-width: 200px; }
.rv-reasons { list-style: none; margin: 0; padding: 0; width: 100%; font-size: 0.9rem; }
.rv-reasons li { padding: 1px 0; }
.rv-banned { margin: 2px 0 0; width: 100%; font-size: 0.9rem; }
.ring-safe { fill: var(--stamp-green); }
.ring-safe.full { fill: none; stroke: var(--stamp-green); }
.ring-unsafe { fill: url(#rv-hatch); }
.ring-unsafe.full { fill: none; stroke: url(#rv-hatch); }
.ring-empty { fill: none; stroke: var(--shadow); }
.hatch-bg { fill: var(--stamp-red); }
.hatch-line { stroke: rgba(255, 255, 255, 0.55); stroke-width: 2; }
.ring-num { font-size: 28px; font-weight: 700; fill: var(--window-text); }
.ring-sub { font-size: 11px; fill: var(--gray-text); }
.rv-trust-figs { display: flex; gap: 18px; flex-wrap: wrap; width: 100%; }
.rv-years { display: flex; flex-wrap: wrap; gap: 4px; width: 100%; }
.rv-year { width: 58px; min-height: 58px; padding: 3px; display: flex; flex-direction: column; align-items: center; justify-content: center; color: #ffffff; border: 1px solid var(--dark); font-size: 0.72rem; line-height: 1.15; text-align: center; }
.rv-year.band-steady { background: var(--stamp-green); }
.rv-year.band-watchful { background: var(--band-watchful); color: #000000; }
.rv-year.band-shaken { background: var(--stamp-red); }
.rv-year-num { font-size: 1.15rem; font-weight: 700; }
/* In the dark schemes the band colours are light, so the square text turns dark to stay readable */
:root[data-theme="dark"] .rv-year { color: #000000; }
.rv-footline { margin: 0; font-size: 0.92rem; }
.rv-take-group { margin-bottom: 10px; }
.rv-take-body { width: 100%; }
.rv-take-list { list-style: none; margin: 0; padding: 0; width: 100%; display: grid; gap: 8px; }
.rv-take-head, .rv-take-line, .rv-take-none { margin: 0; }
.rv-take-head { display: flex; flex-wrap: wrap; gap: 0 10px; align-items: baseline; }
.rv-take-sys { font-size: 0.9rem; color: var(--gray-text); }
.rv-take-line { font-size: 0.92rem; }
/* Performance monitor: black panel, green grid, bright green line and bars */
.rv-perf { display: grid; gap: 10px; }
.rv-figure { margin: 0; }
.rv-figure-title { font-weight: 700; margin-bottom: 3px; }
.rv-chart { display: block; width: 100%; height: auto; background: var(--chart-bg); border: 1px solid; border-color: var(--shadow) var(--hilight) var(--hilight) var(--shadow); }
.rv-chart .grid { stroke: var(--chart-grid); stroke-width: 1; }
.rv-chart .zone { fill: none; }
.rv-chart .area { fill: none; }
.rv-chart .line { fill: none; stroke: var(--chart-line); stroke-width: 2; stroke-linejoin: round; }
.rv-chart .threshold { stroke: var(--chart-line); stroke-width: 1; stroke-dasharray: 2 4; opacity: 0.7; }
.rv-chart .axis, .rv-chart .label { fill: var(--chart-line); font-family: "Lucida Console", "Courier New", monospace; font-size: 11px; }
.rv-chart .bar { fill: var(--chart-line); }
.rv-chart .marker { fill: var(--chart-bg); stroke: var(--chart-mark); stroke-width: 2; }
.rv-chart .label { fill: var(--chart-mark); paint-order: stroke; stroke: var(--chart-bg); stroke-width: 4px; stroke-linejoin: round; }
.rv-chart .hit { fill: transparent; }
.rv-chart .hit:hover { fill: rgba(0, 255, 0, 0.12); }
.rv-caption { margin-top: 4px; font-size: 0.88rem; }
.rv-table-wrap { overflow-x: auto; }
.rv-table th { padding: 0; }
.rv-sort { width: 100%; text-align: left; padding: 2px 6px; font: inherit; font-weight: 700; background: var(--face); color: var(--window-text); border: 1px solid; border-color: var(--hilight) var(--dark) var(--dark) var(--hilight); cursor: pointer; }
.rv-result-unsafe { color: var(--stamp-red); font-weight: 700; }
.rv-result-safe { color: var(--stamp-green); font-weight: 700; }
.rv-result-turned_down { color: var(--window-text); }
.rv-actions { flex-wrap: wrap; }
@media (max-width: 760px) {
  .rv-groups { grid-template-columns: minmax(0, 1fr); }
  .rv-hero-title { font-size: 1.2rem; }
}

/* ── Responsive ── */
@media (max-width: 1000px) {
  .desk { grid-template-columns: minmax(0, 1fr) 260px; }
  .desk-left { grid-column: 2; grid-row: 2; position: static; } /* the planner and the diary stay a column, under the Calendar */
  .desk-main { grid-row: 1 / span 2; }
  .desk-side { grid-row: 1; position: static; }
  .log-peek { height: 240px; }
}
@media (max-width: 860px) {
  .desk { grid-template-columns: 1fr; padding: 10px 8px 60px; gap: 10px; }
  .desk-col { display: contents; }
  .status { order: -3; }
  .quarter { order: -2; }
  #intray-section { order: -1; }
  .planner { order: 0; }
  .notepad { order: 1; }
  .log-peek { height: 140px; min-height: 0; }
}
@media (max-width: 760px) {
  .start-grid, .choices.two { grid-template-columns: 1fr; }
  .desk-section > .client, .client { padding: 8px; }
  .notepad .client { padding: 2px; }
  .card-row { grid-template-columns: 1fr; }
  .taskbar { gap: 2px; }
  /* A phone's taskbar is icons only, as the new desktop's is at any width: each button keeps its name for a screen
     reader (aria-label, and Start's own text at no size). */
  .task-btn { position: relative; min-width: var(--target); flex: none; padding: 1px 8px; justify-content: center; font-size: 1.15rem; }
  .task-label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
  /* The planner's strip is itself the way to the whole run on a phone (a full-width target), so its link sits close under it */
  .planner .link-btn { min-height: 0; padding: 2px 0 4px; }
  .start-btn { min-width: var(--target); justify-content: center; gap: 0; font-size: 0; }
  .reg-row { grid-template-columns: auto 1fr auto; }
  .reg-due { grid-column: 1 / -1; padding-left: 26px; }
  .control { grid-template-columns: 1fr auto; }
  .control .c-cost { grid-column: 1; }
  .timeline li { grid-template-columns: 1fr; gap: 2px; }
  .overlay, #screen-event { padding: 8px 4px 70px; }
  #explainer-modal.as-note { padding: 0 4px 64px; }
  #explainer-modal.as-note .sheet { max-width: none; }
  #event-sheet { --event-pad-y: 78px; }
  #event-sheet.is-ledger { max-height: calc(100dvh - 78px); } /* a phone scrolls down to the planner window */
  #modal-system > .sheet, #modal-programme > .sheet, #modal-intervention > .sheet, #modal-qmail > .sheet, #modal-timeline > .sheet { --overlay-pad-y: 78px; }
  .msgbox, .msgbox.is-ledger, .msgbox.is-review, .msgbox.is-report { max-width: none; }
  .ledger-quarters { grid-template-columns: repeat(2, 1fr); }
  .review-grid { grid-template-columns: 1fr 1fr; }
  .folder-tab { padding: 3px 8px 4px; font-size: 0.92rem; }
  .folder-tab.active { padding: 4px 10px 6px; }
  .actions .btn { flex: 1 1 auto; }
  #event-options.choices { flex-direction: column; }
  #event-options .choice { flex: 0 0 auto; min-height: var(--target); }
  #event-options .choice + .choice { border-left-color: transparent; border-top-color: var(--shadow); box-shadow: inset 0 1px var(--hilight); }
  .msg-head .msg-row { grid-template-columns: 56px 1fr; }
  .msg-head { padding-right: 44px; }
  .calendar { grid-template-columns: 1fr; }
  /* A phone shows Status, the Calendar, then the desk, so the first two are packed: smaller figures stacked over trust
     as one row and a shorter button, and the Calendar in one row, the quarter beside today's week (the leaf shows the
     quarter alone: the week shows the date). The calendar shows only today's week (its today marker, due dots and
     quarter end) and opens to the whole month with a tap. The diary peek is three lines. Each figure is one line;
     capacity is the number only, its people icons stay on wider screens. The Year planner comes after the desk. */
  .quarter .client { flex-direction: row; align-items: flex-start; gap: 6px; }
  .quarter .leaf { flex: none; align-self: stretch; justify-content: center; padding: 4px 8px; }
  .quarter .leaf-turn { display: none; }
  .quarter .calendar { flex: 1 1 auto; min-width: 0; }
  .leaf-period { font-size: 1.05rem; }
  .calendar { padding: 2px; gap: 2px; }
  .cal-head { margin-bottom: 1px; cursor: pointer; } /* its type and the week's are under Phone fit, at the end */
  .calendar:not(.open) .cal-day:not(.wk), .calendar:not(.open) .cal-blank:not(.wk) { display: none; }
  .cal-head::after { content: ' \25BE'; }
  .calendar.open .cal-head::after { content: ' \25B4'; }
  .num { flex-direction: row; align-items: baseline; gap: 4px; padding: 2px 4px; }
  .num strong { font-size: 1.1rem; }
  .trust { flex-direction: row; align-items: center; gap: 6px; padding: 4px 8px; }
  .trust-bar-wrap { flex: 1; }
  .end-btn { min-height: var(--target); margin-top: 0; }
  .status-row { flex-direction: column; gap: 5px; }
  .status-row .numbers, .status-row .trust { flex: 0 0 auto; }
  .status-next { flex-direction: column; align-items: stretch; gap: 5px; }
  .status-next .end-btn { width: 100%; }
  .status > .client { gap: 5px; }
  .log-peek { height: 84px; min-height: 0; }
  .wizard .client { grid-template-columns: 1fr; }
  .wizard-banner { min-height: 0; padding: 8px 10px; }
  .wizard-page { min-height: 0; }
  .logon-fields { grid-template-columns: 80px 1fr; }
  .logon-banner { margin: -8px -8px 10px; }
  .ledger-wrap { overflow-x: auto; }
}
/* The new computers arrive (installNewDesktop in js/screens.js): the old machine's setup screen comes up over
   everything, its bar fills in steps, the desktop changes behind it, and it lifts on the new one before Marek's message
   opens. It keeps the old look whatever the desktop under it has become: its colours are the old desktop's, taken as it
   opens (--in-*), and its type is the old machine's. Reduced motion: no screen (the script skips it). */
.install-screen { position: fixed; inset: 0; z-index: 95; display: flex; align-items: center; justify-content: center; padding: 16px; background: var(--in-desktop, var(--desktop)); color: var(--in-text, var(--window-text)); font-family: Tahoma, "MS Sans Serif", Arial, sans-serif; opacity: 0; transition: opacity 0.3s; }
.install-screen.show { opacity: 1; }
.install-screen.lifting { opacity: 0; transition: opacity 0.8s ease; }
.install-win { width: 380px; max-width: 100%; background: var(--in-face, var(--face)); border: 2px solid; border-color: var(--in-hilight, var(--hilight)) var(--in-dark, var(--dark)) var(--in-dark, var(--dark)) var(--in-hilight, var(--hilight)); }
.install-titlebar { padding: 3px 6px; font-weight: 700; font-size: 0.95rem; color: var(--in-title-text, var(--title-text)); background: linear-gradient(90deg, var(--in-title-a, var(--title-a)), var(--in-title-b, var(--title-b))); }
.install-body { padding: 14px 14px 16px; }
.install-title { font-weight: 700; font-size: 1.05rem; }
.install-text { margin: 6px 0 12px; font-size: 0.92rem; }
.install-bar { height: 18px; border: 1px solid; border-color: var(--in-shadow, var(--shadow)) var(--in-hilight, var(--hilight)) var(--in-hilight, var(--hilight)) var(--in-shadow, var(--shadow)); background: var(--in-window, var(--window)); }
.install-fill { display: block; height: 100%; width: 0; background: repeating-linear-gradient(90deg, var(--in-select, var(--select)) 0 10px, transparent 10px 12px); }
.install-screen.show .install-fill { animation: installFill var(--install-fill, 2.4s) steps(18, end) 0.3s forwards; }
@keyframes installFill { to { width: 100%; } }

/* ── Mini games: a break between a quarter's close and its cards (js/minigames.js; the window is js/views.js) ──
   A small game program of its desktop: here a grey box with a sunken playing field, raised square tiles and a
   counter in lit digits; css/modern.css redraws the same markup for the new desktop. Nothing here is animated
   (the games step on a timer), so reduced motion changes nothing. Sizes follow the window's width down to a phone. */
/* While a game is open every screen is out of sight, so the game sits on the bare desktop, as a message does. A rule,
   not a class a script sets, so a screen that changes behind an open game cannot bring the desk back into view. */
#modal-minigame { background: transparent; }
body:has(#modal-minigame:not(.hidden)) .screen { opacity: 0; }
.sheet.mg { max-width: 600px; margin: auto; } /* centred where it fits; a tall one still starts at the top and scrolls */
.mg .client { display: flex; flex-direction: column; gap: 8px; }
.mg .actions { margin-top: 4px; }
/* The brief and the result: a picture of the game beside the words. The result adds the game's stamp and the figure that moved. */
.mg-intro { display: flex; align-items: flex-start; gap: 14px; padding: 4px 2px; }
.mg-art { display: none; flex: none; width: min(200px, 34vw); aspect-ratio: 4 / 3; background: center bottom / 84% auto no-repeat, 0 0 / 32px 32px; }
.mg-words { flex: 1; min-width: 0; }
.mg-stamp { font-size: 1.15rem; margin-bottom: 6px; }
/* The result's stamp, inked: a bordered, slightly turned rubber stamp in the result's colour, like the ones the games
   put on a screen or a letter; on the new desktop it is that desktop's pill, larger (css/modern.css). */
.mg[data-stage="result"] .mg-stamp { display: inline-flex; margin: 2px 0 8px 2px; padding: 0 10px; font-size: 1.35rem; border: 3px solid currentColor; rotate: -4deg; }
.mg[data-stage="result"] .mg-stamp::before { content: none; }
.mg[data-stage="result"] .mg-stamp.tone-green { color: var(--stamp-green); }
.mg[data-stage="result"] .mg-stamp.tone-red { color: var(--stamp-red); }
/* The score: a block for each thing counted, filled up to the score in the result's colour, with a notch after the
   block that wins (so a loss shows how near it came), and the tally beside it. */
.mg-score { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; margin-top: 10px; }
.mg-score-bar { display: inline-flex; gap: 2px; padding: 3px; background: var(--window); }
.mg-score-blk { position: relative; width: 12px; height: 14px; background: color-mix(in srgb, var(--shadow) 35%, var(--window)); }
.mg[data-tone="green"] .mg-score-blk.mg-lit { background: var(--stamp-green); }
.mg[data-tone="red"] .mg-score-blk.mg-lit { background: var(--stamp-red); }
.mg-score-blk.mg-pass::after { content: ''; position: absolute; right: -2px; top: -6px; bottom: -6px; width: 2px; background: var(--window-text); }
.mg-score-tally { font-weight: 700; }
.mg-text { margin: 0; }
.mg-title { margin: 0 0 6px; }
.mg-guide { display: flex; flex-direction: column; gap: 3px; margin: 8px 0 0; padding: 0; list-style: none; color: var(--gray-text); font-size: 0.95rem; }
.mg-guide li { display: flex; align-items: center; gap: 7px; }
.mg-guide .ic { color: var(--action); }
.mg-stake { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 10px; }
.mg-stake .deltas { margin: 0; }
.mg-how { margin: 0 2px; }
.mg-bar { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.mg-readout { min-width: 9ch; margin-left: auto; padding: 1px 8px; font-family: var(--font-mono); font-weight: 700; text-align: right; background: var(--chart-bg); color: var(--chart-line); }
.mg-field { display: flex; align-items: center; justify-content: center; min-height: 190px; padding: 10px 6px; background: var(--face); user-select: none; -webkit-user-select: none; }
.mg-field.mg-over { pointer-events: none; }
.mg-pc, .mg-tile, .mg-hold { touch-action: manipulation; }
/* Vendors: a ward of nine desks, each with a computer (img/minigames, drawn by tools/build-minigame-art.py). The rep
   rises from behind a computer as an install starts on it: the picture is one figure, moved up in two steps. The
   screen is a box laid over the picture's screen (the geometry is in the tool's header) and shows the install, the
   stamp of one cancelled, or the trial that got in. */
.mg[data-game="vendors"] .mg-art { display: block; background-image: url("../img/minigames/classic/rep.svg"), url("../img/minigames/classic/floor.svg"); }
.mg[data-game="vendors"][data-tone="green"] .mg-art { background-image: url("../img/minigames/classic/rep-glum.svg"), url("../img/minigames/classic/floor.svg"); }
.mg[data-game="vendors"][data-tone="red"] .mg-art { background-image: url("../img/minigames/classic/rep-grin.svg"), url("../img/minigames/classic/floor.svg"); }
.mg[data-game="vendors"] .mg-field { padding: 12px 6px 8px; background: url("../img/minigames/classic/floor.svg") 0 0 / 32px 32px; }
body.high-contrast .mg[data-game="vendors"] .mg-field { background: var(--window); } /* higher contrast: the computers on a plain ground, no floor pattern behind them */
.mg-pcs { --mg-pc: min(150px, calc((100vw - 76px) / 3)); display: grid; grid-template-columns: repeat(3, var(--mg-pc)); gap: 6px 10px; }
.mg-pc { position: relative; height: var(--mg-pc); min-width: 0; padding: 0; border: none; background: none; color: var(--window-text); font-size: calc(var(--mg-pc) * 0.1); line-height: 1.1; cursor: pointer; }
.mg-rep { position: absolute; left: 17%; top: 26%; width: 66%; aspect-ratio: 4 / 3; background: url("../img/minigames/classic/rep.svg") center / contain no-repeat; visibility: hidden; }
.mg-pc[data-rep="1"] .mg-rep { visibility: visible; top: 12%; }
.mg-pc[data-rep="2"] .mg-rep, .mg-pc[data-rep="3"] .mg-rep { visibility: visible; top: 0; }
.mg-pc[data-rep="3"] .mg-rep { background-image: url("../img/minigames/classic/rep-grin.svg"); }
.mg-pc-box { position: absolute; left: 10%; bottom: 0; width: 80%; aspect-ratio: 64 / 60; background: url("../img/minigames/classic/pc.svg") center / contain no-repeat; }
.mg-pc-screen { position: absolute; left: 12.5%; top: 10%; width: 75%; height: 46.67%; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 0.3em; overflow: hidden; background: var(--desktop); }
.mg-pc-tag { position: absolute; right: 15%; bottom: 8%; min-width: 1.3em; padding: 0 0.2em; font-size: 0.7em; font-weight: 700; text-align: center; background: var(--window); color: var(--window-text); outline: 1px solid var(--shadow); } /* an asset sticker */
.mg-pc-app, .mg-pc-trial, .mg-pc-stamp, .mg-pc-word, .mg-install { display: none; }
.mg-pc-app, .mg-pc-trial { width: 1.5em; height: 1.5em; }
.mg-install { gap: 1px; width: 80%; height: 0.8em; padding: 1px; background: var(--window); }
.mg-blk { flex: 1; }
.mg-blk.mg-lit { background: var(--select); }
.mg-pc[data-state="busy"] .mg-pc-screen { justify-content: flex-end; padding-bottom: 0.4em; background: var(--face); box-shadow: inset 0 0.55em var(--title-a); }
.mg-pc[data-state="busy"] .mg-pc-app { display: block; }
.mg-pc[data-state="busy"] .mg-install { display: flex; }
.mg-pc[data-state="stopped"] .mg-pc-screen { background: var(--window); }
.mg-pc[data-state="stopped"] .mg-pc-stamp { display: block; padding: 0.05em 0.35em; border: 2px solid var(--stamp-green); color: var(--stamp-green); font-weight: 700; rotate: -8deg; animation: stampDown 0.12s steps(2, end) backwards; }
@keyframes stampDown { from { scale: 1.6; } } /* it lands already inked: the screen is only stamped for half a second, so it does not fade in as the message stamps do */
.mg-pc[data-state="installed"] .mg-pc-screen { background: var(--res-trust); color: var(--select-text); }
.mg-pc[data-state="installed"] .mg-pc-trial, .mg-pc[data-state="installed"] .mg-pc-word { display: block; }
.mg-pc-word { font-size: 0.85em; font-weight: 700; }
.mg-pip[data-state="stopped"] { background: var(--stamp-green); }
.mg-pip[data-state="installed"] { background: var(--window); box-shadow: inset 0 0 0 3px var(--stamp-red); }
/* The word a round is stamped with, where a scene shows one (Hold for review by the reader or a tray, Workflow over
   its board): the same rubber stamp as on a Free trial screen, placed by the game and shown by the scene's state. */
.mg-ink { display: none; position: absolute; z-index: 2; translate: -50% -50%; padding: 0.05em 0.4em; border: 2px solid var(--stamp-green); background: var(--window); color: var(--stamp-green); font-weight: 700; white-space: nowrap; rotate: -8deg; pointer-events: none; animation: stampDown 0.12s steps(2, end) backwards; }
.mg-ink[data-tone="red"] { border-color: var(--stamp-red); color: var(--stamp-red); }
/* Hold for review: an office. The AI tool hangs from a rail and carries a letter along it; the reader sits under the
   rail at the round's zone; a Send tray stands at each end. Under the scene is the track, the old desktop's
   progress bar: the lit block is where the tool is, and the zone is the stretch between the two black rules, so it
   reads without the drawing and without colour. Sizes are shares of the rail's length, so a phone gets the same scene. */
.mg[data-game="oversight"] .mg-art { display: block; background-image: url("../img/minigames/classic/carrier.svg"), url("../img/minigames/classic/carpet.svg"); background-position: center; background-size: 70% auto, 32px 32px; }
.mg[data-game="oversight"][data-tone="green"] .mg-art { background-image: url("../img/minigames/classic/reader-read.svg"), url("../img/minigames/classic/carpet.svg"); background-position: center bottom, 0 0; }
.mg[data-game="oversight"][data-tone="red"] .mg-art { background-image: url("../img/minigames/classic/tray.svg"), url("../img/minigames/classic/carpet.svg"); }
.mg[data-game="oversight"] .mg-field { padding: 10px 8px 12px; background: url("../img/minigames/classic/carpet.svg") 0 0 / 32px 32px; }
body.high-contrast .mg[data-game="oversight"] .mg-field { background: var(--window); }
.mg-watch { display: flex; flex-direction: column; align-items: stretch; gap: 10px; width: 100%; padding: 0 4%; } /* room at each side: at an end of the rail the tool reaches past the track by half its width */
.mg-line { position: relative; aspect-ratio: 18 / 5; margin: 0 3px; overflow: visible; } /* 3px: the track's own edge, so the tool stands over the lit block */
.mg-rail { position: absolute; left: 0; right: 0; top: 2%; height: 4px; background: var(--dark); box-shadow: 0 1px var(--hilight); }
.mg-carrier, .mg-reader, .mg-send { position: absolute; aspect-ratio: 4 / 3; background: center / contain no-repeat; }
.mg-carrier { top: 2%; width: 12%; margin-left: -6%; background-image: url("../img/minigames/classic/carrier.svg"); }
.mg-letter { position: absolute; left: 31%; top: 90%; width: 38%; aspect-ratio: 3 / 2; background: linear-gradient(var(--shadow), var(--shadow)) 50% 35% / 60% 1px no-repeat, linear-gradient(var(--shadow), var(--shadow)) 35% 65% / 40% 1px no-repeat, var(--window); outline: 1px solid var(--dark); }
.mg-line[data-state="held"] .mg-letter, .mg-line[data-state="missed"] .mg-letter { display: none; }
.mg-reader { bottom: 0; width: 13%; margin-left: -6.5%; background-image: url("../img/minigames/classic/reader.svg"); background-position: center bottom; }
.mg-line[data-state="held"] .mg-reader { background-image: url("../img/minigames/classic/reader-read.svg"); }
.mg-send { bottom: 0; width: 11%; background-image: url("../img/minigames/classic/tray.svg"); background-position: center bottom; }
.mg-send-a { left: 0; }
.mg-send-b { right: 0; }
.mg-line .mg-ink { top: 52%; font-size: 0.95rem; }
.mg-line[data-state="held"] .mg-ink, .mg-line[data-state="missed"] .mg-ink { display: block; }
.mg-pips { display: flex; flex-wrap: wrap; justify-content: center; gap: 5px; }
.mg-pip { width: 12px; height: 12px; background: var(--face); }
.mg-pip[data-state="now"] { background: var(--window); }
.mg-pip[data-state="held"] { background: var(--stamp-green); }
.mg-pip[data-state="missed"] { background: var(--window); box-shadow: inset 0 0 0 3px var(--stamp-red); }
.mg-meter { display: flex; gap: 2px; height: 26px; padding: 2px; background: var(--window); }
.mg-cell { flex: 1; }
.mg-cell.mg-zone { background: color-mix(in srgb, var(--stamp-green) 30%, var(--window)); box-shadow: inset 0 3px var(--dark), inset 0 -3px var(--dark); }
.mg-cell.mg-lit { background: var(--select); }
.mg-meter[data-result="held"] .mg-lit { background: var(--stamp-green); }
.mg-meter[data-result="missed"] .mg-lit { background: var(--stamp-red); }
.mg-hold { align-self: center; min-width: 160px; min-height: 44px; } /* the one button of a timing game: easy to hit on a phone */
.mg-over .mg-hold { visibility: hidden; }
/* Workflow: a process map pinned to a cork board. Each piece is a sticky note with a thick marker track on it (drawn
   for turn 0, the whole of it turned), running to the note's edge so its two openings are plain; a square with no
   piece is bare cork with a faint outline. A piece the work runs through has its track in green and its note gone
   pale green, so the run reads without telling blue from green; the piece where the run stops has a red edge. The
   steps are the chart's shapes (img/minigames): the request and the decision on a note at each edge, with a stub of
   track to the board, the AI step and the check on a blue note and a pink one. The strip above the board is the
   workflow as it should run. The board keeps its own colours in the dark theme, as the other two scenes do; they are
   named once here (--wf-*) and again for the new desktop, and higher contrast swaps them for the theme's own. */
.mg[data-game="workflow"] .mg-field {
  --wf-note: #fff7b2; --wf-note-edge: #d9c95a; --wf-note-ai: #bfe0ff; --wf-note-check: #ffc9d6; --wf-note-on: #d9f2d0;
  --wf-track: #3d5a99; --wf-run: #1e8e3e; --wf-slot: #c69c6d; --wf-next: #c8102e; --wf-ink: #1a1a1a;
  --wf-shade: 2px 2px 0 color-mix(in srgb, var(--dark) 45%, transparent); --wf-casing: #fffdf0;
  padding: 12px 6px 14px; background: url("../img/minigames/classic/cork.svg") 0 0 / 64px 64px;
}
body.high-contrast .mg[data-game="workflow"] .mg-field {
  --wf-note: var(--window); --wf-note-edge: var(--window-text); --wf-note-ai: var(--window); --wf-note-check: var(--window); --wf-note-on: var(--window);
  --wf-track: var(--window-text); --wf-run: var(--select); --wf-slot: transparent; --wf-next: var(--stamp-red); --wf-ink: var(--window-text); --wf-casing: transparent;
  background: var(--window);
}
body.high-contrast .mg[data-game="workflow"] :is(.mg-tile, .mg-end) { border: 2px solid var(--wf-ink); box-shadow: none; } /* every note has its full edge; an empty square shows nothing */
body.high-contrast .mg[data-game="workflow"] .mg-tile.mg-next { border-color: var(--wf-next); box-shadow: inset 0 0 0 2px var(--wf-next); }
.mg[data-game="workflow"] .mg-art { display: block; background: url("../img/minigames/classic/step-ai.svg") center / 46% auto no-repeat, url("../img/minigames/classic/cork.svg") 0 0 / 64px 64px; }
.mg[data-game="workflow"][data-tone="green"] .mg-art { background-image: url("../img/minigames/classic/step-decision.svg"), url("../img/minigames/classic/cork.svg"); }
.mg[data-game="workflow"][data-tone="red"] .mg-art { background-image: url("../img/minigames/classic/step-check.svg"), url("../img/minigames/classic/cork.svg"); }
.mg-map { display: flex; flex-direction: column; align-items: center; gap: 12px; }
.mg-steps { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 2px 6px; padding: 4px 12px; background: var(--window); color: var(--window-text); font-size: 0.92rem; box-shadow: 2px 2px 0 color-mix(in srgb, var(--dark) 30%, transparent); } /* a strip of paper on the cork */
.mg-steps-item { display: inline-flex; align-items: center; gap: 4px; white-space: nowrap; }
.mg-steps-arrow { color: var(--gray-text); }
.mg-step { display: block; background: center / contain no-repeat; }
.mg-step[data-step="request"] { background-image: url("../img/minigames/classic/step-request.svg"); }
.mg-step[data-step="ai"] { background-image: url("../img/minigames/classic/step-ai.svg"); }
.mg-step[data-step="check"] { background-image: url("../img/minigames/classic/step-check.svg"); }
.mg-step[data-step="decision"] { background-image: url("../img/minigames/classic/step-decision.svg"); }
.mg-steps .mg-step { width: 28px; height: 28px; }
.mg-board { position: relative; }
.mg-board .mg-ink { left: 50%; top: 46%; font-size: 1.5rem; }
.mg-board[data-state] .mg-ink { display: block; }
.mg-flow { --mg-tile: min(76px, calc((100vw - 96px) / 5.9)); --mg-end: calc(var(--mg-tile) * 0.95); --mg-w: calc(var(--mg-tile) * 0.2); display: grid; grid-auto-rows: var(--mg-tile); gap: 4px; }
.mg-tile { position: relative; min-width: 0; padding: 0; overflow: hidden; border: none; border-right: 2px solid var(--wf-note-edge); border-bottom: 2px solid var(--wf-note-edge); background: var(--wf-note); box-shadow: var(--wf-shade); cursor: pointer; }
.mg-tile[data-role="ai"] { background: var(--wf-note-ai); }
.mg-tile[data-role="check"] { background: var(--wf-note-check); }
.mg-tile.mg-on { background: var(--wf-note-on); }
.mg-tile.mg-done { background: color-mix(in srgb, var(--wf-run) 35%, var(--wf-note-on)); }
.mg-tile.mg-next { box-shadow: inset 0 0 0 3px var(--wf-next), var(--wf-shade); }
.mg-tile:active { translate: 1px 1px; }
.mg-tile:focus-visible { outline: 2px dotted var(--wf-ink); outline-offset: -5px; }
.mg-blank { outline: 1px solid var(--wf-slot); outline-offset: -2px; }
.mg-pipe { position: absolute; inset: 0; }
.mg-tile[data-rot="1"] .mg-pipe { transform: rotate(90deg); }
.mg-tile[data-rot="2"] .mg-pipe { transform: rotate(180deg); }
.mg-tile[data-rot="3"] .mg-pipe { transform: rotate(270deg); }
.mg-arm, .mg-stub { background: var(--wf-track); }
.mg-arm { position: absolute; }
.mg-arm-a { left: calc(50% - var(--mg-w) / 2); width: var(--mg-w); top: 0; bottom: 0; }
.mg-tile[data-kind="corner"] .mg-arm { border-bottom-left-radius: var(--mg-w); } /* the bend: the two arms share their outer corner, rounded */
.mg-tile[data-kind="corner"] .mg-arm-a { bottom: auto; height: calc(50% + var(--mg-w) / 2); }
.mg-arm-b { left: calc(50% - var(--mg-w) / 2); right: 0; top: calc(50% - var(--mg-w) / 2); height: var(--mg-w); }
.mg-tile.mg-on .mg-arm, .mg-end.mg-on .mg-stub { background: var(--wf-run); }
.mg-tile .mg-step { position: absolute; left: 27%; top: 27%; width: 46%; height: 46%; }
/* The request and the decision are notes too, at the board's two edges, so their stub of track is read on paper as every other track is, not on the cork. */
.mg-end { display: flex; align-items: center; border-right: 2px solid var(--wf-note-edge); border-bottom: 2px solid var(--wf-note-edge); background: var(--wf-note); box-shadow: var(--wf-shade); }
.mg-end.mg-on { background: var(--wf-note-on); }
.mg-end-in { padding-left: 5%; }
.mg-end-out { padding-right: 5%; }
.mg-end .mg-step { flex: none; width: 58%; aspect-ratio: 1; }
.mg-stub { position: relative; flex: 1; height: var(--mg-w); box-shadow: 0 0 0 2px var(--wf-casing); } /* a pale casing, so the stub stands clear of whatever is behind it, cork included */
.mg-end-out .mg-stub { margin-right: calc(var(--mg-w) * 0.7); }
.mg-end-out .mg-stub::after { content: ''; position: absolute; left: 100%; top: 50%; translate: 0 -50%; border: var(--mg-w) solid transparent; border-right-width: 0; border-left: calc(var(--mg-w) * 0.7) solid var(--wf-track); } /* the arrowhead into the decision */
.mg-end-out.mg-on .mg-stub::after { border-left-color: var(--wf-run); }
.mg-end-out .mg-step { opacity: 0.7; } /* the decision is not reached yet */
.mg-end-out.mg-on .mg-step { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
}

/* ── Drawing the eye (the outline stays under reduced motion; only the pulse goes) ── */
/* What an assessment just changed on the sheet (flashUpdated in js/screens.js) */
.just-updated { outline: 2px solid var(--action); outline-offset: 2px; animation: justUpdated 0.8s ease-in-out 2; }
@keyframes justUpdated { 0%, 100% { background-color: transparent; } 50% { background-color: color-mix(in srgb, var(--action) 18%, transparent); } }
/* Something shown for the first time (drawEye in js/screens.js): it grows and flashes amber four times inside a thick
   outline. Used for trust moving at a close, a tab or the folder coming in, a new Status entry, and a window a tip
   opens. Whole windows grow less (--eye-scale). Under reduced motion the outline stays, still. */
.draw-eye, .eye-held { position: relative; z-index: 3; outline: 3px solid var(--action); outline-offset: 2px; }
.draw-eye { animation: drawEye 0.6s ease-in-out 2; }
/* eye-held: the same mark, held still, on the thing a tip that is open is talking about (the EU AI Act folder in the
   Start menu, under the Reference tip). Inside a menu the mark sits within the item, where the menu's edge cannot clip it. */
.more-menu .draw-eye, .more-menu .eye-held { outline-offset: -3px; }
@keyframes drawEye { 50% { transform: scale(var(--eye-scale, 1.08)); background-color: color-mix(in srgb, var(--stamp-amber) 40%, var(--window)); } }
.desk-section.draw-eye { --eye-scale: 1.02; }
/* A desk tab the player has just reached (tabArrives in js/screens.js) rises in first; the dot stays until it is opened */
.folder-tab.tab-enter { --rise-y: 10px; --rise-scale: 0.8; animation: rise 0.5s ease-out; }
/* Trust moved at the close (trustMoved in js/screens.js): the change shows in a badge by the figure */
.trust { position: relative; }
.trust-delta { position: absolute; right: 8px; top: 50%; transform: translateY(-50%); padding: 0 8px; font-size: 1.6rem; font-weight: 700; line-height: 1.3; color: #fff; animation: deltaPop 2s ease-out forwards; }
.trust-delta.up { background: var(--stamp-green); }
.trust-delta.down { background: var(--stamp-red); }
@keyframes deltaPop { 0% { opacity: 0; transform: translateY(-50%) scale(0.4); } 12% { opacity: 1; transform: translateY(-50%) scale(1.25); } 22% { transform: translateY(-50%) scale(1); } 85% { opacity: 1; } 100% { opacity: 0; } }
/* The first desk of a tutorial run: the folder waits for the Status tip, then comes in (trayStaging in js/screens.js) */
.desk-section.tut-hidden { display: none; }
.desk-section.win-arrive { --rise-y: 24px; animation: rise 0.6s ease-out; }
/* A window the tutorial showed steps back to the taskbar (stepBack in js/screens.js): it shrinks down and away. */
.desk-section.win-leave { animation: winLeave 0.25s steps(3, end) forwards; transform-origin: 50% 100%; }
@keyframes winLeave { to { transform: scale(0.6) translateY(40%); opacity: 0; } }
/* A card put down on the desk (placeCards in js/screens.js): kept off it until the player is looking, so the cards
   already there sit at the top of the tray. Then those move down to make room, each from where it was (card-shift:
   --shift-x and --shift-y are the way back), and the new ones drop into the room made, from just above and a little
   turned, one after another (--i). Under reduced motion every card is simply in its place. */
.doc.card-waiting { display: none; }
.doc.card-shift { animation: shift 0.24s steps(5, end) backwards; }
@keyframes shift { from { transform: translate(var(--shift-x, 0), var(--shift-y, 0)); } to { transform: none; } }
.doc.card-arrive { --rise-y: -16px; --rise-scale: 1.05; --rise-turn: -2deg; animation: rise 0.22s steps(4, end) backwards; animation-delay: calc(0.2s + var(--i, 0) * 50ms); }
.folder-tab.tab-new::before { content: ''; position: absolute; top: 3px; right: 3px; width: 8px; height: 8px; border-radius: 50%; background: var(--stamp-red); }
/* End quarter when nothing is left to do this quarter (Engine.quarterDone) */
.end-btn.ready { outline: 2px solid var(--action); outline-offset: 1px; animation: endReady 1.6s ease-in-out infinite; }
@keyframes endReady { 0%, 100% { outline-offset: 1px; outline-color: var(--action); } 50% { outline-offset: 5px; outline-color: color-mix(in srgb, var(--action) 45%, transparent); } } /* the outline pulses; the bevel (box-shadow) is left alone */

/* ── The hospital's machine: tray clock and asset tag (content: meta.desktop) ── */
/* The tray is the sunken well at the right of the taskbar, as system trays were drawn. */
.tray { margin-left: auto; display: flex; align-items: center; min-height: 22px; padding: 0 8px; font-size: 0.9rem; white-space: nowrap; border: 1px solid; border-color: var(--shadow) var(--hilight) var(--hilight) var(--shadow); }
.taskbar:has(.tray)::after { content: none; }
.tray-clock { cursor: default; }
/* The tray speaker (js/sound.js): the one live icon in the tray, flat with no bevel, as tray icons were drawn.
   Pressed means sound on; off shows the speaker with a cross. The glyph is a mask, so it takes the text colour
   in both themes and in higher contrast. */
.tray-sound { display: inline-flex; align-items: center; justify-content: center; width: 20px; height: 18px; margin: 0 6px 0 -4px; padding: 0; border: none; background: transparent; color: inherit; cursor: pointer; font: inherit; }
.tray-sound:focus-visible { outline-offset: 0; }
.tray-sound-glyph { display: block; width: 14px; height: 12px; background: currentColor; --mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14 12' fill='none' stroke='%23000' stroke-width='1.2' stroke-linecap='round'%3E%3Cpath d='M1.5 4.3h2.4L7 1.8v8.4L3.9 7.7H1.5z' fill='%23000' stroke-linejoin='round'/%3E%3Cpath d='M9 4.2a2.6 2.6 0 0 1 0 3.6M10.8 2.4a5.2 5.2 0 0 1 0 7.2'/%3E%3C/svg%3E"); -webkit-mask: var(--mask) no-repeat center / contain; mask: var(--mask) no-repeat center / contain; }
.tray-sound.off .tray-sound-glyph { --mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14 12' fill='none' stroke='%23000' stroke-width='1.2' stroke-linecap='round'%3E%3Cpath d='M1.5 4.3h2.4L7 1.8v8.4L3.9 7.7H1.5z' fill='%23000' stroke-linejoin='round'/%3E%3Cpath d='M9.4 4.2l3.4 3.6M12.8 4.2L9.4 7.8'/%3E%3C/svg%3E"); -webkit-mask-image: var(--mask); mask-image: var(--mask); }
@media (pointer: coarse) { .tray-sound { width: 30px; height: 26px; } }
/* The asset tag is a desktop watermark, bottom right above the taskbar, the way the old system printed its
   build line on the wallpaper. It sits under the desk (which is raised above it), takes no clicks and is
   hidden from assistive technology, so it covers nothing. */
.desk { position: relative; z-index: 1; }
.asset-tag { position: fixed; right: 12px; bottom: 40px; z-index: 0; pointer-events: none; text-align: right; color: #ffffff; opacity: 0.75; font-family: var(--font); font-size: 0.8rem; line-height: 1.35; }
.asset-tag .asset-old, .asset-tag .asset-new { display: flex; flex-direction: column; }
.asset-tag .asset-new { display: none; }
[data-os="modern"] .asset-tag .asset-old { display: none; }
[data-os="modern"] .asset-tag .asset-new { display: flex; }
@media (max-width: 760px) { .asset-tag { display: none; } }
@media (max-width: 480px) { .tray { padding: 0 4px; font-size: 0.8rem; } }
/* On a narrow phone Start, the five program buttons and the tray are wider than the screen (by a few pixels at 375
   with a long date), so the date gives way (it is in Status and the Calendar); the sound button stays. Both looks
   (the id outranks modern.css). */
@media (max-width: 400px) { #tray-clock { display: none; } }

/* ── Dev panel (?debug only; developer tooling, not player-facing) ── */
.dev-panel { position: fixed; left: 4px; bottom: 36px; z-index: 80; width: 300px; max-width: calc(100vw - 16px); max-height: calc(100dvh - 48px); display: flex; flex-direction: column; font-size: 0.9rem; }
.dev-panel > .client { overflow: auto; padding: 6px 8px; }
.dev-sec { border-top: 1px solid var(--shadow); box-shadow: 0 -1px var(--hilight) inset; padding: 4px 0; }
.dev-sec:first-child { border-top: none; box-shadow: none; }
.dev-sec summary { cursor: default; font-weight: 700; color: var(--window-text); }
.dev-sec > div:not(.dev-row) { color: var(--window-text); font-family: var(--font-mono); font-size: 0.85rem; overflow-wrap: anywhere; }
.dev-row { display: flex; flex-wrap: wrap; gap: 4px; margin: 4px 0; }
.dev-row select { flex: 1 1 120px; min-width: 0; max-width: 100%; min-height: 24px; }
.dev-state { width: 100%; font-family: var(--font-mono); font-size: 0.8rem; color: var(--window-text); background: var(--window); border: 1px solid; border-color: var(--shadow) var(--hilight) var(--hilight) var(--shadow); resize: vertical; margin-top: 4px; }
.dev-reopen { position: fixed; left: 4px; bottom: 36px; z-index: 80; }

/* ── Phone fit (the owner's round of 2026-10-08) ──
   A phone gets the game at a size it can read and play with a thumb. The root goes to 16px, so everything sized in rem
   grows with it; the Calendar and the workbook sheets, drawn in the desktop's fixed pixels, go to rem; and every field
   is at least 16px, below which a phone zooms the page in when the field is tapped. Text grows on a narrow screen
   (under 761px) or a short touch one (a phone on its side). css/modern.css has the new desktop's twin of each rule. */
@media (max-width: 760px), (pointer: coarse) and (max-height: 520px) {
  html { font-size: 16px; }
  html:has(body.ui-large-text) { font-size: 18px; }
  .cal-head { font-size: 0.8rem; line-height: 1.6; }
  .cal-dow { font-size: 0.75rem; line-height: 1.5; }
  .cal-day { font-size: 0.85rem; line-height: 1.6; }
  .cal-arrow { width: 36px; font-size: 1rem; line-height: 1.6; }
  .cal-panel, .cal-item, .cal-wait { font-size: 0.85rem; }
  .cal-group-head, .cal-item small, .cal-wait-warn { font-size: 0.75rem; }
  .cal-panel-close { width: 32px; height: 28px; font-size: 1rem; line-height: 1; }
  .ledger { font-size: 0.8rem; }
  .ledger td.note, .ledger-q, .embed-cap { font-size: 0.75rem; }
  .ledger-q strong { font-size: 0.85rem; }
}
@media (max-width: 760px) {
  .cal-day { line-height: 36px; } /* the week strip's days: a row a thumb can hit */
}
@media (pointer: coarse) {
  input, select, textarea, .desk-sort select, .desk-filter select { font-size: max(16px, 1rem); }
  .cal-arrow { position: relative; }
  .cal-arrow::after { content: ''; position: absolute; inset: -8px -4px; } /* the arrow's touch area reaches past what it draws */
  .cal-wait { min-height: var(--target); }
}
/* Every window a player reads or decides in takes the phone's width and keeps its frame. It is as tall as its content,
   up to the height of the screen, and centred when it is shorter, as a message box sits on the desktop, so a short
   window leaves no empty face below it and nothing in it stretches to fill the screen (the owner's check on a phone,
   2026-10-09). It scrolls as one: the inner boxes that scrolled on their own (a proposal's duties, the report's
   sheets, the email's body, About's text, the address book's list) let their content run on in the window instead.
   The small boxes (confirm, copy, error, a version's choice, Options and the tips) stay boxes. The email is a screen,
   not an overlay: its window grows with the message, and the screen scrolls when the window is taller than it. */
@media (max-width: 760px), (max-height: 520px) {
  .phone-window { padding: max(4px, env(safe-area-inset-top)) max(4px, env(safe-area-inset-right)) max(4px, env(safe-area-inset-bottom)) max(4px, env(safe-area-inset-left)); align-items: flex-start; }
  .phone-window > .sheet {
    display: flex; flex-direction: column; width: 100%; max-width: none; margin: auto 0;
    max-height: calc(100dvh - max(4px, env(safe-area-inset-top)) - max(4px, env(safe-area-inset-bottom)));
  }
  .phone-window > .sheet > .client { flex: 1 1 auto; min-height: 0; overflow: auto; }
  #modal-system > .sheet > .client > #sys-lower, #modal-system > .sheet > .client > #sys-lower:has(#sys-controls > li:nth-child(4), #sys-history > li:nth-child(4)) { flex: none; min-height: 0; overflow: visible; }
  .foldbox > .box-body, #modal-qmail .qmail-body, #modal-timeline #timeline-list, .cast-list, .cast-detail, .about-body, .howto-body { flex: none; min-height: 0; max-height: none; overflow: visible; }
  #modal-cast .cast-main, #modal-cast .cast-body, #modal-cast .cast-detail-box { flex: none; }
  #screen-event { padding: max(4px, env(safe-area-inset-top)) max(4px, env(safe-area-inset-right)) max(4px, env(safe-area-inset-bottom)) max(4px, env(safe-area-inset-left)); align-items: stretch; }
  #event-sheet, #event-sheet.is-ledger { flex: 0 0 auto; width: 100%; max-width: none; max-height: none; margin: auto 0; }
  #event-sheet.is-ledger { margin-bottom: 0; } /* the year's ledger and the planner under it are centred together */
  #event-sheet > .client > .msg-body { flex: none; min-height: 0; overflow: visible; }
  #event-planner { margin: 6px 0 auto; max-width: none; }
  .wizard .client { align-content: start; } /* the assessment's banner keeps its own height */
}
/* The email on a phone. The menu bars that only dress a window (File, Edit, View and the rest, marked aria-hidden) give
   their line to the message; the diary's, which opens the diary, stays. So do the address book's toolbar buttons that
   only dress it (New, Delete, Print, Action), which leaves Properties and Find people on one row. The header's labels
   make room for "Subject:" at 16px. Each reply is a row: its badge at the left, then its title, the line under it and
   the figures it moves, about half the height of the tiles they were; the row of replies and the status bar reach the
   window's edges. */
@media (max-width: 760px), (max-height: 520px) {
  .menubar[aria-hidden="true"], .toolbar > .tool-btn[aria-hidden="true"] { display: none; }
  .desk { grid-template-columns: minmax(0, 1fr); } /* at 16px the swipeable In the air strip's widest pill would otherwise widen the column past a 320px screen */
  #event-sheet > .client { padding: 8px; }
  .msg-head .msg-row { grid-template-columns: 76px minmax(0, 1fr); }
  #event-options.choices { flex-direction: column; margin: 6px -8px 0; }
  #event-options .choice { display: grid; grid-template-columns: 30px minmax(0, 1fr); column-gap: 10px; row-gap: 1px; align-items: center; justify-items: start; text-align: left; min-height: 48px; padding: 6px 10px; }
  #event-options .choice:active, #event-options .choice.chosen { padding: 7px 9px 5px 11px; }
  #event-options .choice > * { grid-column: 2; }
  #event-options .choice > .choice-badge, #event-options .choice::before { grid-column: 1; grid-row: 1 / span 3; justify-self: center; margin: 0; }
  #event-options .res-dots { justify-content: flex-start; margin-top: 2px; padding-top: 0; }
  .msg-status { margin: 6px -8px -8px; }
  .msg-cell, .msg-status .res-chip { gap: 4px; padding: 1px 5px; }
}
/* The old desktop draws a reply and an assessment's answer flat until a pointer is over them, and a phone has no
   pointer to hover with. So on a phone each is a raised button at rest, set apart from the next, and sunk once it is
   pressed, chosen or opened (the owner's check on a phone, 2026-10-09). An answer keeps its round dot. */
@media (max-width: 760px), (max-height: 520px) {
  #event-options.choices { gap: 6px; padding: 8px; }
  #event-options .choice, #event-options .choice + .choice, #assess-options .choice { border-color: var(--hilight) var(--dark) var(--dark) var(--hilight); box-shadow: inset -1px -1px var(--shadow), inset 1px 1px var(--face-light); background: var(--face); }
  #event-options .choice:active, #event-options .choice.chosen, #event-options .choice.armed, #assess-options .choice:active, #assess-options .choice.chosen { border-color: var(--shadow) var(--hilight) var(--hilight) var(--shadow); box-shadow: inset 1px 1px var(--dark), inset -1px -1px var(--face-light); background: var(--face); }
}
/* A decision window (proposal, programme, one-off) on a phone covers the desk's figures, so it carries the email's
   status bar of the four figures under its client (resBar in js/views.js), lit by an action's hints as the desk's are.
   Its one row of buttons (a proposal's, a one-off's) stays pinned at the foot of the window while the rest scrolls;
   a programme's levels are the decision and can be tall, so they stay where they are, at the end. The desktop keeps
   the owner's call: no figures in the sheet (the bar is hidden above phone size). */
.sheet-res { display: none; }
@media (max-width: 760px), (max-height: 520px) {
  :is(#modal-system, #modal-programme, #modal-intervention) > .sheet > .client { padding: 8px; }
  .sheet-res { display: flex; flex: none; margin: 0; padding: 3px; border-top: 1px solid var(--hilight); }
  /* A row of buttons pinned to the foot of a window that scrolls as one: a system's and a one-off's actions (which end the
     window, so no bottom margin), the mail's end row, and the About and How to play actions. */
  #sys-actions, #iv-actions, #modal-qmail .qmail-end, :is(#modal-about, #modal-howto) > .sheet > .client > .actions { position: sticky; bottom: 0; z-index: 2; margin: 8px -8px -8px; padding: 6px 8px; background: var(--face); border-top: 1px solid var(--shadow); box-shadow: inset 0 1px var(--hilight); }
  #sys-actions, #iv-actions { margin-bottom: 0; }
}
/* Two taps on a touch screen (armThenAct in js/views.js): the first opens a button, the second does it. At rest on a
   phone a reply is one line, its badge, its title and the figures it moves as icon and arrow; its line under the title
   is kept for a screen reader but not drawn. Opened (.armed), it shows that line, the figures in words and "Tap again
   to select". A proposal's and a one-off's tiles keep their picture and name; what they move and cost comes in the note
   the first tap puts above their row. A programme's sizes keep their lines and add the note's words when opened. */
.tap-note { grid-column: 1 / -1; order: -2; flex: 1 1 100%; padding: 6px 8px; font-size: 0.95rem; text-align: left; color: var(--window-text); background: var(--info); border: 1px solid var(--window-text); }
.control > .tap-note { order: 1; } /* a control's note goes under its row */
.tap-note .res-dots { margin: 3px 0; }
.tap-open { grid-column: 2; display: flex; flex-direction: column; gap: 2px; }
#prog-levels .choice > .tap-open { grid-column: 1 / -1; align-items: center; text-align: center; } /* under a size's centred dots, centred too */
.tap-note-text { font-size: 0.9rem; color: var(--gray-text); }
.tap-again { display: block; font-weight: 700; color: var(--select); }
:root[data-theme="dark"] .tap-again { color: var(--link); }
.btn.armed, .choice.armed { border-color: var(--shadow) var(--hilight) var(--hilight) var(--shadow); box-shadow: inset 1px 1px var(--dark), inset -1px -1px var(--face-light); background: var(--face-light); }
#event-options .choice.armed { background: var(--window); }
@media (pointer: coarse) and (max-width: 760px), (pointer: coarse) and (max-height: 520px) {
  #event-options:not(.one) .choice:not(.armed) { grid-template-columns: 30px minmax(0, 1fr) auto; }
  #event-options:not(.one) .choice:not(.armed) > .choice-sub { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
  #event-options:not(.one) .choice:not(.armed) > .res-dots { grid-column: 3; grid-row: 1; flex-wrap: nowrap; gap: 7px; margin: 0; }
  #event-options:not(.one) .choice:not(.armed) .res-dot { font-size: 0; gap: 1px; }
  #event-options:not(.one) .choice:not(.armed) .res-dot.has-ic::after { font-size: 0.7rem; }
  #event-options:not(.one) .choice:not(.armed) .res-dot .ic { width: 16px; height: 16px; }
  #sys-actions .btn { min-height: 52px; padding: 4px 2px; }
  #sys-actions .btn .res-dots, #iv-actions .btn .res-dots, #iv-actions .btn:not([disabled]) small { display: none; } /* a disabled one-off keeps its reason: no tap note comes for it */
  #event-options .choice, #sys-actions .btn, #iv-actions .btn, #prog-actions .btn, #prog-levels .choice, .control .btn-small { touch-action: manipulation; } /* a quick second tap is a tap, not a zoom */
}
/* The quarter report on a phone. Its People sheet stacks each person as a row of their own (who and which way they
   moved, then what you did, then how they stand) instead of a sheet wider than the screen; the Figures sheet stays a
   sheet. Close stays pinned at the foot while the report scrolls, so focusing it as the mail opens moves nothing. */
@media (max-width: 760px), (max-height: 520px) {
  #modal-qmail > .sheet > .client { padding: 6px 8px 8px; }
  #qmail-people .xl { display: block; }
  #qmail-people .xl tr:first-child { display: none; }
  #qmail-people .xl tr { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 2px 10px; align-items: center; padding: 6px 8px; border-bottom: 1px solid var(--grid); }
  #qmail-people .xl td { padding: 0; border: 0; }
  #qmail-people .xl td.xl-who { grid-column: 1; padding-left: 0; white-space: normal; }
  #qmail-people .xl td.xl-who::before { display: none; }
  #qmail-people .xl td:nth-child(3) { grid-column: 2; grid-row: 1; }
  #qmail-people .xl td.xl-did, #qmail-people .xl td:nth-child(4) { grid-column: 1 / -1; min-width: 0; }
}
/* About and How to play scroll as one window on a phone, so their row of buttons is pinned at the foot: focusing OK as
   the window opens then moves nothing, and How to play still opens at the section for the screen the player is on. */
@media (max-width: 760px), (max-height: 520px) {
  :is(#modal-about, #modal-howto) > .sheet > .client { padding: 8px; }
}
/* The mini games on a phone (the owner's preview of 2026-10-08): the window takes the screen's width like the others.
   The opening's picture is a banner across the top, over the title, the story and the three lines on how to play at
   full size, and Start and Skip sit at the foot, within a thumb's reach. The fields grow into the full width (the
   allowances in --mg-pc and --mg-tile were for the boxed window), the counter keeps to one line, and Check is a
   full-width bar. */
@media (max-width: 760px), (max-height: 520px) {
  .mg-intro { flex-direction: column; align-items: stretch; gap: 10px; }
  .mg-art { width: 100%; aspect-ratio: 16 / 7; }
  .mg[data-game="vendors"] .mg-art { background-size: auto 92%, 32px 32px; }
  .mg[data-game="oversight"] .mg-art { background-size: auto 80%, 32px 32px; }
  .mg[data-game="workflow"] .mg-art { background-size: auto 60%, 64px 64px; }
  .mg-guide { font-size: 1rem; color: var(--window-text); }
  .mg .actions { margin-top: auto; }
  .mg-pcs { --mg-pc: min(150px, calc((100vw - 52px) / 3)); }
  .mg-flow { --mg-tile: min(76px, calc((100vw - 60px) / 5.9)); }
  .mg-bar { flex-wrap: wrap; }
  .mg-readout { white-space: nowrap; }
  .mg-hold { align-self: stretch; min-height: 52px; font-size: 1.1rem; }
}
/* A tip on a phone is a compact strip the width of the screen: its title at body size, and "Don't show tips like this"
   beside Got it rather than on a row of its own, so it covers about a third of the screen, not half. Over the desk it
   sits at the foot, above the taskbar, while what the first tips explain (the figures, the tray) is near the top; over
   a window or an email it goes to the top instead, out of the way of the buttons, the claim and the duties at their
   foot, and its arrow to the tray goes. */
@media (max-width: 760px), (max-height: 520px) {
  #explainer-modal.as-note { padding: 0 0 56px; }
  #explainer-modal.as-note .sheet { width: 100%; max-width: none; }
  #explainer-modal.as-note .sheet > .client { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; column-gap: 10px; padding: 8px 10px; }
  #explainer-modal.as-note .sheet > .client > * { grid-column: 1 / -1; }
  #explainer-modal.as-note .sheet-title { margin: 0 0 4px; font-size: 1rem; }
  #explainer-modal.as-note .scene { margin: 0 0 2px; }
  #explainer-modal.as-note .sheet > .client > .explainer-opt { grid-column: 1; margin: 0; font-size: 0.9rem; }
  #explainer-modal.as-note .sheet > .client > .explainer-opt.hidden + .actions { grid-column: 1 / -1; }
  #explainer-modal.as-note .sheet > .client > .actions { grid-column: 2; margin: 0; }
  body:has(.phone-window:not(.hidden), #screen-event:not(.hidden)) #explainer-modal.as-note { align-items: flex-start; padding: 0; }
  body:has(.phone-window:not(.hidden), #screen-event:not(.hidden)) #explainer-modal.as-note .sheet::before,
  body:has(.phone-window:not(.hidden), #screen-event:not(.hidden)) #explainer-modal.as-note .sheet::after { content: none; }
}
/* Touch targets of at least 44px on a touch screen (DESIGN.md's floor). Where growing a control would break the old
   desktop's look (its close box, the fold toggles drawn in a group box's border, Earlier in Status), an invisible area
   around it takes the tap instead. Left as they are: links inside running text, the Calendar's days (a week across a
   phone, 36px tall) and the desk toolbar's 30px menus (the owner's call). */
@media (pointer: coarse) {
  body:not([data-os="modern"]) .close-btn { position: relative; }
  body:not([data-os="modern"]) .close-btn::after { content: ''; position: absolute; inset: -9px -6px; }
  input[type="checkbox"] { width: 22px; height: 22px; }
  .btn-small, .drawer-entry summary, .rv-sort, .more-menu button { min-height: var(--target); }
  #assess-options .choice, #assess-options .choice.chosen, #assess-options .choice:active { min-height: var(--target); padding: 8px 8px 8px 34px; }
  #assess-options .choice::before { top: 12px; width: 18px; height: 18px; }
  #assess-options .choice.chosen::before { background: radial-gradient(circle, var(--window-text) 5px, var(--window) 5.5px); }
  .assess-stop-row { margin: 13px 0 3px; } /* room in the window for the touch area of Stop for now, above and below its line */
  .assess-stop-row .link-btn { position: relative; }
  .assess-stop-row .link-btn::after { content: ''; position: absolute; inset: -13px -6px; } /* the touch area, without spreading its sentence over uneven lines */
  .tray-sound { width: var(--target); height: var(--target); }
  .foldbox > h3 .box-toggle, .news-more { position: relative; }
  .foldbox > h3 .box-toggle::after, .news-more::after { content: ''; position: absolute; inset: -14px -10px; }
  .menu-seed summary, .why > summary { padding: 12px 0; }
  .cal-head { min-height: 32px; }
  .rv-links a, .rv-links .link-btn { display: inline-block; padding: 12px 0; }
}
/* The review's buttons on a phone: two to a row across the width, not ragged to the right */
@media (max-width: 760px) {
  .rv-actions { display: grid; grid-template-columns: 1fr 1fr; }
  .rv-actions .btn { width: 100%; min-width: 0; white-space: normal; } /* a label wraps rather than being cut at half the width */
  .rv-year { font-size: 0.78rem; } /* the trust years' labels stay at 12px or more at 16px */
}
/* Safe areas: the page asks for the whole screen (viewport-fit=cover, index.html), so on a phone with a notch or a home
   bar the taskbar, the desk, the screens, the windows and the tips keep clear of them. env() is 0 where a screen has
   none, so nothing moves elsewhere. */
.taskbar { padding-bottom: max(2px, env(safe-area-inset-bottom)); }
@media (max-width: 760px), (max-height: 520px) {
  .taskbar { padding-left: max(2px, env(safe-area-inset-left)); padding-right: max(2px, env(safe-area-inset-right)); }
  .desk { padding-left: max(8px, env(safe-area-inset-left)); padding-right: max(8px, env(safe-area-inset-right)); padding-bottom: calc(60px + env(safe-area-inset-bottom)); }
  #screen-menu { padding: max(24px, env(safe-area-inset-top)) max(12px, env(safe-area-inset-right)) max(24px, env(safe-area-inset-bottom)) max(12px, env(safe-area-inset-left)); }
  #screen-report { padding: max(18px, env(safe-area-inset-top)) max(12px, env(safe-area-inset-right)) max(18px, env(safe-area-inset-bottom)) max(12px, env(safe-area-inset-left)); }
  #screen-ending { padding: max(16px, env(safe-area-inset-top)) max(16px, env(safe-area-inset-right)) max(16px, env(safe-area-inset-bottom)) max(16px, env(safe-area-inset-left)); }
  #explainer-modal.as-note { padding-bottom: calc(56px + env(safe-area-inset-bottom)); }
  body:has(.phone-window:not(.hidden), #screen-event:not(.hidden)) #explainer-modal.as-note { padding-top: env(safe-area-inset-top); }
}
/* The narrowest phones (360px and under): Start, five programs and the tray's sound button at 44px each are wider than
   the screen, so they give 4px each in width (still 44px tall). */
@media (pointer: coarse) and (max-width: 360px) {
  .start-btn, .task-btn { min-width: 40px; }
  .tray-sound { width: 40px; }
}
