/* Геовед / Картовед — the stylesheet of every page: design tokens (light and dark) and every kit component.
 *
 * The look of a geological survey publication (Геовед's restyle, 2026-10-31): warm paper, near-black ink, hairline
 * rules, square corners, a double rule under the top bar like a sheet's frame, ONE red-brown accent (the colour of a
 * map's "red" overprint) for "running / measured value". No gradients, no glass, no glow, no pill shapes.
 * Controls follow the owner's button design (2026-11-01): outlined, 3px corners; GREEN marks the
 * active / selected control and fills the primary action; status chips are outlined with a square dot (done green,
 * running blue, ready grey, blocked orange). Скановед's buttons share it. Type (fonts/fonts.css, self-hosted): Literata
 * for titles and the brand's name, Golos Text for everything else, JetBrains Mono only for keys and codes
 * (linked before this sheet by base.html: a stylesheet imports nothing, the kit's static test holds it).
 * The brand's mark (base.html, brand/): strata cut by a fault, the ore horizon in the red a sheet prints faults and ores
 * in; it draws itself from --mark, --on-fill and --mark-ore, so it turns over with the theme.
 *
 * Rules worth keeping (from the stylesheet before):
 *   1. no text-transform on running copy: the UI is bilingual and Russian all-caps is wider and harder to read;
 *      uppercase survives only on short labels (the step label, the last-map label, a row heading);
 *   2. every colour below the token blocks is a variable: a literal there is a colour the dark theme cannot reach;
 *   3. the SHEET INKS (--c-*) are what the canvas draws ON THE MAP (kit/viewer/inks.js reads them): the sheet is
 *      paper in either theme, so they are defined once and have no dark variant; the restyle left them as they were;
 *   4. no inline styles anywhere (CSP): what a script sizes it sets through the CSSOM (`style.setProperty`).
 *
 * The theme is `data-theme` on <html>, set by kit/theme.js before the first paint: the system's colour scheme
 * until the person presses the top bar's toggle, then their choice.
 */
:root {
  color-scheme: light;
  --bg: #f2efe6; --panel: #fbf9f3; --panel2: #f0ece1; --inset: #f6f3eb;
  --field: #fffdf8;
  --ink: #1b1a16; --muted: #565246; --faint: #6e695c;
  --line: #d3ccba; --line2: #e4dece;
  --rule: #1b1a16;
  --accent: #9b3a1a; --accent-hi: #b4461f; --accent-dim: #d8b7a5; --accent-soft: #f3e5da; --accent-ink: #8a3214;
  --navy: #1b1a16; --navy-hi: #9b3a1a;
  --warn: #8a5d00; --bad: #a3301d;
  --bad-ink: #93281a; --bad-soft: #f8ebe5; --bad-line: #e2b7aa;
  --warn-ink: #6f4c03; --warn-soft: #f8f0dc; --warn-line: #e3cf9d;
  --needs-soft: #f7efde; --needs-line: #e0cb9c;
  --outdated-ink: #85480b; --outdated-soft: #f6e9d6; --outdated-line: #dfbd8c;
  --info-ink: #2b5271; --info-soft: #e9eff2; --info-line: #b9cbd6;
  --hand-soft: #eeebe2; --hand-line: #cfc8b6;
  /* Controls (the owner's button design, 2026-11-01; geometry from MapMaven's library, 2026-11-01): an ink rim
     1.5px wide, 4px corners, green for the main action and for "on". */
  --btn-line: #1b1a16; --btn-r: 4px; --btn-bw: 1.5px;
  --go: #2f6f4a; --go-hi: #25583b; --go-ink: #24573a; --go-soft: #e1ede3; --go-line: #94bfa2;
  --block-ink: #b45f12; --block-line: #e6b07a;
  --run-ink: #2f62a0; --run-line: #9ab8dd;
  /* Disabled controls: dimmed but LEGIBLE (2026-10-20: the dark theme's disabled primary text was nearly unreadable;
     ink on bg is >= 4.5:1 in both themes, the tests hold >= 3). */
  --disabled-bg: #e1dccf; --disabled-ink: #4f4b41;
  --danger: #a3301d; --danger-hi: #bd3b25;
  --nda: #8b1a1a;
  --check-a: #ebe7dc; --check-b: #f5f2ea;
  --float: rgba(251, 249, 243, .96);
  --topbar: #fbf9f3;
  --backdrop: rgba(27, 26, 22, .42);
  --selection: rgba(155, 58, 26, .18);
  --r: 2px; --r-sm: 2px;
  --shadow-sm: none;
  --shadow: none;
  --shadow-run: none;
  /* What floats above the page is one family in the three programs (2026-11-02, the owner: «all elements of design
     consistent»): dialogs, the palette, the activity popup, the viewer and the corner notices share 8px corners, one
     soft shadow and one backdrop (no blur: no glass, and a blur costs frames); menus a lighter shadow. */
  --shadow-pop: 0 24px 64px -24px rgba(27, 26, 22, .45), 0 0 0 1px rgba(27, 26, 22, .04);
  --shadow-menu: 0 8px 22px rgba(27, 26, 22, .14);
  --r-float: 8px;
  --shadow-thumb: none;
  /* The keyboard's focus, one ring everywhere (Скановед draws it as a 2px accent outline 2px off the control: the
     same picture): a gap of paper, then 2px of the accent; inside a clipped segment, 2px of the accent within. */
  --ring: 0 0 0 2px var(--panel), 0 0 0 4px var(--accent);
  --ring-in: inset 0 0 0 2px var(--accent);
  --on-fill: #fbf9f3; --spin-track: rgba(251, 249, 243, .35);
  --mark: #1b1a16;
  --mark-ore: #c97a56;  /* the mark's ore horizon: the accent's light tone, legible on the ink square */
  --mark-shadow: none;
  --serif: "Literata", "Georgia", "Times New Roman", serif;
  --sans: "Golos Text", system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
  /* Two families carry the interface (the owner, 2026-11-01: no condensed or monospaced labels, they read as
     stretched): Literata for titles, Golos Text for everything else; the old tokens stay names for Golos Text.
     --code is JetBrains Mono, only where characters must line up (keys, codes), never for a control's label. */
  --narrow: var(--sans);
  --mono: var(--sans);
  --code: "JetBrains Mono", ui-monospace, "Cascadia Mono", "Segoe UI Mono", Consolas, monospace;
  --topbar-h: 52px;
  /* Three control heights only: 26px for a button, a tool, a small switch and every row's action; 30px for a bar (the
     program switch, a view switch, the filter bar, a search field); 32px for a page's one main action and its ⋯. */
  --h-ctl: 26px; --h-bar: 30px; --h-cta: 32px;
  --ws-panel: 360px;
  --ws-panel-wide: 500px;
  /* Motion's tokens (--motion-fast, --motion, --motion-slow, --ease-out): the motion block at the end of this sheet. */

  /* The sheet inks (rule 3): the canvas's one colour language (DESIGN 8.3). */
  --c-model: #1d3f7a;
  --c-hand: #0b8796;
  --c-select: #d6336c;
  --c-select-line: #7a1237;
  --c-hover: #f08c00;
  --c-reviewed: #2b8a3e;
  --c-halo: rgba(255, 255, 255, .92);
  --c-draft: #d6336c;
  --c-dim: #141a24;
  --c-grid: #0d7a5c;
  --c-grid-band: rgba(18, 163, 122, .14);
  --c-mask: #0d7a5c;
  --c-brush: #0b8796;
  /* The dykes' review lists (owner, 2026-10-25): accepted green, suggested blue, rejected red. */
  --c-accepted: #2f9e44;
  --c-suggest: #1c7ed6;
  --c-rejected: #e03131;
  /* A px setting's size while it is being set (the owner's ruler, 2026-10-27): on any sheet, under a dark outline. */
  --c-ruler: #fcc419;
  /* The kinds' inks, one per kind of thing in every program (pages/glyphs.js; 2026-11-02, «it's clear what goes
     from what»): text is the paper's ink, a map the accent's red-brown, a figure the info blue, a blank page the
     paper itself. A report's page strip, a file's mark, a map in /maps and a process's tile draw the same kind alike. */
  --k-text: #6f6a5c; --k-map: #9b3a1a; --k-figure: #2b5271; --k-blank: #e2ddd0;
  --k-map-soft: #f3e5da; --k-figure-soft: #e7eef3;
}
:root[data-theme="dark"] {
  /* Easy on the eyes (the owner, 2026-11-01): a warm charcoal rather than near-black, ink a soft paper grey rather
     than bright cream (text about 12:1, not 15:1, so letters do not glare), quieter rims and rules, and the accent and
     green a little calmer. Every text pair stays above 4.5:1 (faint hints above 4). */
  color-scheme: dark;
  --bg: #1c1b18; --panel: #23221e; --panel2: #2a2924; --inset: #201f1b;
  --field: #272521;
  --ink: #ddd8cc; --muted: #aba493; --faint: #958e7c;
  --line: #3a3832; --line2: #302e29;
  --rule: #8c8677;
  --accent: #c97a56; --accent-hi: #d88b66; --accent-dim: #5f3c2c; --accent-soft: #2d221c; --accent-ink: #dc9a76;
  --navy: #ddd8cc; --navy-hi: #d88b66;
  --warn: #d6a24f; --bad: #de7563;
  --bad-ink: #eaa08f; --bad-soft: #2e1d19; --bad-line: #5a2f27;
  --warn-ink: #e3bd7f; --warn-soft: #2b2418; --warn-line: #574424;
  --needs-soft: #29221a; --needs-line: #524125;
  --outdated-ink: #e2b170; --outdated-soft: #2f2418; --outdated-line: #6a4d24;
  --info-ink: #9dbcd2; --info-soft: #1d242a; --info-line: #344858;
  --hand-soft: #26241f; --hand-line: #3f3c34;
  --btn-line: #8c8677;
  --go: #5a9d77; --go-hi: #6caf89; --go-ink: #8ac6a1; --go-soft: #1e2c24; --go-line: #3b5f4a;
  --block-ink: #e3a46b; --block-line: #66462a;
  --run-ink: #8eb2dd; --run-line: #374f6b;
  --disabled-bg: #2e2c27; --disabled-ink: #a39c8a;
  --danger: #bd4d3b; --danger-hi: #cf5c48;
  --nda: #d96d62;
  --check-a: #1f1e1a; --check-b: #25231f;
  --float: rgba(35, 34, 30, .96);
  --topbar: #23221e;
  --backdrop: rgba(0, 0, 0, .55);
  --selection: rgba(201, 122, 86, .30);
  --shadow-pop: 0 24px 64px -24px rgba(0, 0, 0, .7), 0 0 0 1px rgba(0, 0, 0, .25);
  --shadow-menu: 0 8px 22px rgba(0, 0, 0, .4);
  --on-fill: #1c1b18; --spin-track: rgba(28, 27, 24, .35);
  --mark: #ddd8cc;
  --mark-ore: #9b3a1a;  /* the light theme's accent, on the paper-coloured square */
  --k-text: #8f887a; --k-map: #d27a52; --k-figure: #8fb6d4; --k-blank: #2f2c26;
  --k-map-soft: #2e2119; --k-figure-soft: #18222a;
}

/* ---------- base ---------- */
* { box-sizing: border-box; }
/* `hidden` must win over class rules that set `display`. */
[hidden] { display: none !important; }
html, body { margin: 0; }
body { background: var(--bg); color: var(--ink); font-family: var(--sans); font-size: 14px; line-height: 1.45;
  font-variant-numeric: tabular-nums;
  -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility; font-variant-numeric: lining-nums; }
::selection { background: var(--selection); }
a { color: var(--accent-ink); text-underline-offset: 2px; }
h1, h2, h3 { margin: 0; font-family: var(--serif); font-weight: 700; letter-spacing: 0; }
kbd { font-family: var(--code); font-size: 11px; background: var(--field); border: 1px solid var(--line);
  border-bottom-width: 2px; border-radius: 2px; padding: 0 4px; color: var(--ink); white-space: nowrap; }
.hint { font-size: 12px; color: var(--faint); margin: 8px 0 0; }
.link { color: var(--accent-ink); font-weight: 700; text-decoration: none; }
.link:hover { text-decoration: underline; }
.linklike { background: none; border: none; padding: 0; font: inherit; font-weight: 700; color: var(--accent-ink);
  cursor: pointer; }
.linklike:hover { text-decoration: underline; }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
button:focus-visible, input:focus-visible, select:focus-visible, textarea:focus-visible, a:focus-visible,
summary:focus-visible, [role="button"]:focus-visible { outline: none; box-shadow: var(--ring); }
/* Reduced motion: no transition at all (0 s, not a very short one: every element's `transition-property` is `all`
   unless it says otherwise, so a duration on `*` made every style change a transition, and a layout read in the same
   task got its first frame, the old value: the map view's toolbar measured its last step's widths and overflowed).
   Nothing waits for a transition's end (kit/motion.js resolves at once under reduced motion). */
@media (prefers-reduced-motion: reduce) {
  * { transition-duration: 0s !important; transition-delay: 0s !important; animation-duration: .01ms !important; }
}

/* ---------- top bar: the sheet's frame, a double rule under it ---------- */
.topbar { position: sticky; top: 0; z-index: 20; display: flex; align-items: center; gap: 14px;
  height: var(--topbar-h); padding: 0 20px; background: var(--topbar); border-bottom: 3px double var(--rule); }
.brand { display: flex; align-items: center; gap: 10px; text-decoration: none; flex: none; }
.mark { display: inline-flex; align-items: center; justify-content: center; width: 28px; height: 28px;
  border-radius: 0; color: var(--on-fill); background: var(--mark); box-shadow: var(--mark-shadow); }
.mark svg { display: block; }
.mark-ground { fill: var(--mark); }
.mark-bed { fill: var(--on-fill); }
.mark-ore { fill: var(--mark-ore); }
.mark-fault { fill: none; stroke: var(--mark); stroke-width: 1.1; }  /* the fault plane: a hairline of the ground */
.brand-name { font-family: var(--serif); font-size: 19px; font-weight: 650; letter-spacing: .005em; color: var(--ink); }
.crumb-sep { color: var(--faint); }
.crumb { min-width: 0; color: var(--muted); font-family: var(--narrow); font-size: 14px; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }
.spacer { flex: 1; }
.lang-toggle, .theme-toggle { display: inline-flex; align-items: center; justify-content: center; flex: none;
  width: 30px; height: 28px; padding: 0; border: 1px solid var(--btn-line); border-radius: var(--btn-r);
  background: var(--field); color: var(--ink); cursor: pointer;
  font-family: var(--mono); font-size: 12px; font-weight: 400; letter-spacing: 0;
  transition: background var(--motion-fast), color var(--motion-fast), border-color var(--motion-fast); }
.lang-toggle:hover, .theme-toggle:hover { color: var(--ink); border-color: var(--muted); }
/* An admin's NDA switch (kit/nda.js): the toggles' look. Pressed (NDA stuff shown): the NDA ink on its red tint and
   rim. Off: muted, struck through. */
.nda-toggle { display: inline-flex; align-items: center; justify-content: center; gap: 6px; flex: none; height: 28px;
  padding: 0 9px; border: 1px solid var(--btn-line); border-radius: var(--btn-r); background: var(--field);
  color: var(--muted); cursor: pointer; font-family: var(--mono); font-size: 12px; font-weight: 400;
  letter-spacing: 0; transition: background var(--motion-fast), color var(--motion-fast), border-color var(--motion-fast); }
/* a switch's dot: hollow while NDA stuff is hidden, filled while it is shown */
.nda-toggle::before { content: ""; width: 7px; height: 7px; border-radius: 50%; border: 1.5px solid currentColor;
  box-sizing: border-box; }
.nda-toggle[aria-pressed="true"]::before { background: currentColor; }
.nda-toggle:hover { color: var(--ink); border-color: var(--ink); }
.nda-toggle[aria-pressed="true"] { color: var(--nda); background: var(--bad-soft); border-color: var(--nda); }
.nda-toggle[aria-pressed="true"]:hover { background: var(--bad-line); }
.nda-toggle:disabled { opacity: .6; cursor: progress; }
.theme-toggle .i-sun, :root[data-theme="dark"] .theme-toggle .i-moon { display: none; }
:root[data-theme="dark"] .theme-toggle .i-sun { display: block; }
.top-admin { font-family: var(--mono); font-size: 12.5px; font-weight: 400; color: var(--go-ink);
  text-decoration: none; padding: 3px 10px; border: 1px solid var(--btn-line); border-radius: var(--btn-r);
  background: var(--field); }
.top-admin:hover { border-color: var(--go-line); background: var(--go-soft); }
.user { font-family: var(--narrow); font-size: 14px; color: var(--muted); margin: 0; display: inline-flex;
  align-items: baseline; gap: 4px; }

/* ---------- buttons ---------- */
button.run, a.run { font-family: var(--mono); font-size: 13px; font-weight: 400; letter-spacing: 0;
  color: var(--on-fill); background: var(--go); border: 1px solid var(--go); border-radius: var(--btn-r);
  padding: 7px 14px; cursor: pointer; display: inline-flex; align-items: center; gap: 8px; white-space: nowrap;
  text-decoration: none; box-shadow: var(--shadow-run); transition: background var(--motion-fast), border-color var(--motion-fast),
    transform var(--motion-fast) var(--ease-out); }
button.run:hover:not(:disabled), a.run:hover { background: var(--go-hi); border-color: var(--go-hi); }
button.run:active:not(:disabled), a.run:active { transform: translateY(1px) scale(.98); }  /* a press is felt */
button.run:disabled { background: var(--disabled-bg); border-color: var(--disabled-bg); color: var(--disabled-ink);
  cursor: not-allowed; box-shadow: none; }
button.run.danger { background: var(--danger); border-color: var(--danger); }
button.run.danger:hover:not(:disabled) { background: var(--danger-hi); border-color: var(--danger-hi); }
.tool { font-family: var(--mono); font-size: 12.5px; font-weight: 400; padding: 4px 10px; display: inline-flex;
  align-items: center; gap: 6px; border: 1px solid var(--btn-line); border-radius: var(--btn-r); background: var(--field);
  color: var(--ink); cursor: pointer; box-shadow: none; white-space: nowrap;
  transition: background var(--motion-fast), border-color var(--motion-fast), color var(--motion-fast), transform var(--motion-fast) var(--ease-out); }
.tool:hover:not(:disabled) { border-color: var(--muted); color: var(--ink); background: var(--field); }
.tool:active:not(:disabled) { transform: translateY(1px); }
.tool:disabled { opacity: .5; cursor: default; box-shadow: none; }
.tool.active { background: var(--go-soft); color: var(--go-ink); border-color: var(--go-line); font-weight: 400; }
.tool-icon { font-size: 13px; line-height: 1; }

/* ---------- chips: a state as a small square-cornered tag ---------- */
.chip { display: inline-flex; align-items: center; font-family: var(--mono); font-size: 12px; font-weight: 400;
  letter-spacing: 0; padding: 0 7px; border-radius: 2px; border: 1px solid var(--btn-line); background: var(--field);
  color: var(--muted); white-space: nowrap; line-height: 1.75; }
.chip::before { content: ""; width: 6px; height: 6px; border-radius: 0; background: currentColor; margin-right: 6px; }
.chip-confirmed, .chip-done { border-color: var(--go-line); color: var(--go-ink); }
.chip-running { border-color: var(--run-line); color: var(--run-ink); }
.chip-running::before { animation: chip-pulse 1.2s ease-in-out infinite; }
.chip-failed { border-color: var(--bad-line); color: var(--bad-ink); }
.chip-needs, .chip-blocked { border-color: var(--block-line); color: var(--block-ink); }
.chip-outdated, .chip-stale, .chip-changed { border-color: var(--outdated-line); color: var(--outdated-ink); }
.chip-draft, .chip-ready { border-color: var(--btn-line); color: var(--muted); }
@keyframes chip-pulse { 0%, 100% { opacity: .25; } 50% { opacity: 1; } }

/* ---------- the workspace (D1) ---------- */
.ws { display: grid; grid-template-columns: var(--ws-panel) minmax(0, 1fr); height: calc(100dvh - var(--topbar-h)); }
.ws-panel { overflow-y: auto; overscroll-behavior: contain; background: var(--panel); border-right: 1px solid var(--rule);
  padding: 14px 16px 40px; display: flex; flex-direction: column; gap: 12px; }
.ws:has(.ws-panel.wide) { grid-template-columns: var(--ws-panel-wide) minmax(0, 1fr); }
.ws-nav .back { font-family: var(--narrow); font-size: 14px; font-weight: 700; color: var(--accent-ink); text-decoration: none; }
.ws-nav .back:hover { text-decoration: underline; }
.ws-head { display: flex; align-items: center; gap: 10px; justify-content: space-between;
  padding-bottom: 10px; border-bottom: 1px solid var(--rule); }
.ws-heading { display: flex; align-items: center; flex-wrap: wrap; gap: 8px 10px; min-width: 0; }
.ws-header-actions, .ws-header-controls { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; }
.ws-header-actions .tool { font-size: 13px; padding: 3px 8px; }
.ws-header-status, .ws-header-time { font-size: 12px; color: var(--muted); }
.ws-header-time { font-family: var(--mono); font-variant-numeric: tabular-nums; }
.ws-title { font-family: var(--serif); font-size: 21px; font-weight: 700; color: var(--ink); }
/* The deck's tabs (kit/deck.js): under the back link, and leading the toolbar in fullscreen only. Each is as wide as its
   name wants, so the row stays one line at the panel's 360 px whatever the language. The dot is the chips' colours. */
.deck-tabs { display: flex; flex-wrap: wrap; gap: 2px; padding: 2px; border: 1px solid var(--line); border-radius: var(--r-sm);
  background: var(--panel2); min-width: 0; }
.deck-tab { flex: 1 1 auto; display: inline-flex; align-items: center; justify-content: center; gap: 5px; padding: 4px 6px;
  border: 1px solid transparent; border-radius: 6px; font-size: 12px; font-weight: 600; color: var(--muted);
  text-decoration: none; white-space: nowrap; }
.deck-tab:hover { color: var(--ink); background: var(--panel); }
.deck-tab:focus-visible { outline: none; box-shadow: var(--ring); }
.deck-tab[aria-current="page"] { background: var(--accent-soft); border-color: var(--accent-dim); color: var(--accent-ink); }
.deck-dot { flex: none; width: 7px; height: 7px; border-radius: 50%; background: var(--faint); }
.deck-tab[data-state="confirmed"] .deck-dot { background: var(--go-ink); }
.deck-tab[data-state="running"] .deck-dot { background: var(--run-ink); animation: chip-pulse 1.2s ease-in-out infinite; }
.deck-tab[data-state="failed"] .deck-dot { background: var(--bad-ink); }
.deck-tab[data-state="needs"] .deck-dot { background: var(--block-ink); }
.deck-tab[data-state="outdated"] .deck-dot, .deck-tab[data-state="changed"] .deck-dot { background: var(--outdated-ink); }
.deck-tab[data-state="draft"] .deck-dot { background: var(--muted); }
.vw-bar .deck-tabs { display: none; }
.ws-view:fullscreen .vw-bar .deck-tabs, .ws-view.is-fullscreen .vw-bar .deck-tabs { display: flex; flex: none; }
.ws-inputs { list-style: none; margin: 0; padding: 0; display: grid; gap: 4px; font-size: 12.5px; color: var(--muted); }
.ws-inputs .input-ok { color: var(--go-ink); }
.ws-inputs .input-missing, .ws-inputs .input-optional { color: var(--warn-ink); }
.ws-banner { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; font-size: 12.5px; color: var(--warn-ink);
  background: var(--warn-soft); border: 1px solid var(--warn-line); border-left: 3px solid var(--warn);
  border-radius: 0; padding: 8px 12px; position: sticky; top: 0; z-index: 5; }
.ws-fatal { padding: 24px; grid-column: 1 / -1; }
.ws-steps { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0;
  border-top: 1px solid var(--line); }

/* one step: a numbered entry of a list, ruled, the open one marked in the accent's margin (folded too: it is still
   the step on the view); the caret points down while the card is unfolded */
.step { border: 0; border-bottom: 1px solid var(--line); border-radius: 0; background: transparent;
  transition: background var(--motion-fast), box-shadow var(--motion-fast); }
.step.open { background: var(--panel); box-shadow: inset 3px 0 0 var(--accent); }
.step-h { margin: 0; font-size: inherit; font-family: var(--sans); }
.step-hd { width: 100%; display: grid; grid-template-columns: 12px auto minmax(0, 1fr) auto; align-items: center;
  gap: 8px; padding: 9px 10px 9px 12px; background: none; border: 0; border-radius: 0; cursor: pointer; text-align: left;
  font-family: var(--sans); color: var(--ink); }
.step-hd:hover { background: var(--panel2); }
.step.open .step-hd { border-bottom-left-radius: 0; border-bottom-right-radius: 0; }
.step-caret { width: 0; height: 0; border-left: 5px solid var(--faint); border-top: 4px solid transparent;
  border-bottom: 4px solid transparent; transition: transform .15s; }
.step.open .step-caret { border-left-color: var(--accent); }
.step-hd[aria-expanded="true"] .step-caret { transform: rotate(90deg); }
.step-label { font-family: var(--mono); font-size: 11px; font-weight: 400; letter-spacing: .06em; text-transform: uppercase;
  color: var(--accent-ink); white-space: nowrap; }
/* A stage's title wraps rather than ending in an ellipsis (the owner, 2026-11-05: "Ручная пра…"). */
.step-title { font-size: 14.5px; font-weight: 700; min-width: 0; overflow-wrap: anywhere; line-height: 1.25; }
.step-bd { padding: 2px 14px 14px; display: flex; flex-direction: column; gap: 12px; border-top: 1px dotted var(--line); }
.step-desc { margin: 10px 0 0; font-size: 13px; color: var(--muted); }
.step-notes { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; }
.note { font-size: 12.5px; color: var(--muted); background: var(--accent-soft); border: 0;
  border-left: 3px solid var(--accent); border-radius: 0; padding: 7px 11px; }
.note-warn { color: var(--warn-ink); background: var(--warn-soft); border-left-color: var(--warn); }
.note-info { color: var(--info-ink); background: var(--info-soft); border-left-color: var(--info-ink); }
.step-settings { display: flex; flex-direction: column; gap: 6px; }
.step-defaults { align-self: flex-start; font-size: 13px; }
.step-run { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; }
.step-run-btn.again { background: transparent; color: var(--ink); border: 1px solid var(--ink); box-shadow: none; }
.step-run-btn.again:hover:not(:disabled) { background: var(--ink); color: var(--panel); border-color: var(--ink); }
.step-why { margin: 0; font-size: 12.5px; color: var(--warn-ink); }
.step-why .err-detail { color: var(--muted); }
.step-facts { display: flex; flex-wrap: wrap; gap: 4px 12px; font-size: 12.5px; color: var(--muted); }
.step-facts .fact { font-family: var(--mono); font-size: 12px; }
.step-facts .fact-time { color: var(--accent-ink); }
.step-facts .fact-warn { font-family: var(--sans); font-size: 12.5px; color: var(--warn-ink); }
/* What is on the map now (kit/stepcard.js `setCount`; the toolbar's pill until 2026-11-05). */
.step-count { margin: 0; font-family: var(--mono); font-size: 12px; color: var(--go-ink); overflow-wrap: anywhere; }
.step-slot:empty { display: none; }
.step-slot { display: flex; flex-direction: column; gap: 10px; }
.step-confirm { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; padding: 14px 12px 4px;
  border-top: 3px double var(--rule); }
.confirm-line { margin: 0; font-size: 12.5px; color: var(--muted); }
.confirm-rows { display: grid; grid-template-columns: max-content minmax(0, 1fr); gap: 1px 12px; margin: 0; }
.confirm-rows dt { color: var(--muted); }
.confirm-rows dd { margin: 0; overflow-wrap: anywhere; font-variant-numeric: tabular-nums; }
.confirm-ok { color: var(--go-ink); }
.confirm-warn { color: var(--warn-ink); }
.step-next { display: flex; justify-content: flex-end; }
.next-btn { font-family: var(--mono); font-size: 12.5px; font-weight: 400; color: var(--go-ink); background: var(--field);
  border: 1px solid var(--go-line); border-radius: var(--btn-r); padding: 4px 12px; cursor: pointer; }
.next-btn:hover { border-color: var(--go); background: var(--go-soft); }

/* the error box */
.err { font-size: 12.5px; color: var(--bad-ink); background: var(--bad-soft); border: 1px solid var(--bad-line);
  border-left: 3px solid var(--bad); border-radius: 0; padding: 8px 12px; display: none; overflow-wrap: break-word; }
.err.show { display: block; }
.err-title { font-weight: 700; }
.err-detail { display: block; margin-top: 4px; font-family: var(--mono); font-size: 11.5px; color: var(--muted); }
.err-act { display: block; margin-top: 8px; }

/* ---------- controls ---------- */
/* Compact (owner, 2026-10-25): the name and its description on one line, the control under it, a number's unit
   inside its box. */
.controls { display: flex; flex-direction: column; gap: 6px; }
.ctl { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.ctl-head { display: flex; align-items: baseline; flex-wrap: wrap; column-gap: 6px; row-gap: 0; min-width: 0; }
.ctl-label { font-family: var(--narrow); font-size: 14px; font-weight: 700; color: var(--ink);
  display: flex; justify-content: space-between; gap: 8px; }
.ctl-head .ctl-label { flex: none; }
.ctl-unit { font-family: var(--mono); font-weight: 400; color: var(--faint); }
.ctl-row { display: flex; align-items: center; gap: 10px; }
.ctl-row input[type=range] { flex: 1; min-width: 0; }
.ctl-num { width: 86px; flex: none; }
.ctl-reset { display: inline-flex; align-items: center; justify-content: center; flex: none;
  width: 28px; height: 30px; padding: 0; border: 1px solid var(--btn-line); border-radius: var(--btn-r);
  background: var(--field); color: var(--go-ink); font: 19px/1 var(--sans); cursor: pointer; }
.ctl-reset:hover:not(:disabled) { border-color: var(--go-line); background: var(--go-soft); }
.ctl-reset:disabled { color: var(--faint); opacity: .5; cursor: default; }
.ctl-numbox { position: relative; display: inline-flex; flex: none; }
.ctl-numbox .ctl-num { padding-right: 28px; }
.ctl-numbox .ctl-unit { position: absolute; right: 9px; top: 50%; transform: translateY(-50%); pointer-events: none;
  font-size: 11.5px; line-height: 1; }
.ctl-hint { margin: 0; font-size: 12px; color: var(--faint); min-width: 0; }
.ctl-check { display: inline-flex; align-items: center; gap: 8px; font-size: 13px; color: var(--ink); cursor: pointer; }
/* A range is a fine scale line with a square mark on it (no pills). */
input[type=range] { -webkit-appearance: none; appearance: none; height: 3px; border-radius: 0; background: var(--line);
  border: 0; cursor: pointer; margin: 6px 0; }
input[type=range]::-webkit-slider-thumb { -webkit-appearance: none; width: 12px; height: 16px; border-radius: 0;
  background: var(--ink); border: 2px solid var(--panel); outline: 1px solid var(--ink); box-shadow: var(--shadow-thumb); }
input[type=range]::-moz-range-thumb { width: 10px; height: 14px; border-radius: 0; background: var(--ink);
  border: 2px solid var(--panel); outline: 1px solid var(--ink); box-shadow: var(--shadow-thumb); }
input[type=range]:hover::-webkit-slider-thumb { background: var(--accent); outline-color: var(--accent); }
input[type=range]:hover::-moz-range-thumb { background: var(--accent); outline-color: var(--accent); }
input[type=range]:disabled { opacity: .5; cursor: default; }
input[type=number], input[type=text], select, textarea, .dlg-input { font-family: var(--mono); font-size: 13px;
  background: var(--field); color: var(--ink); border: 1px solid var(--line); border-radius: 2px; padding: 6px 8px;
  box-shadow: none; }
input[type=number]:hover, input[type=text]:hover, select:hover, textarea:hover, .dlg-input:hover { border-color: var(--muted); }
input[type=text], .dlg-input, textarea { font-family: var(--sans); }
input[type=checkbox], input[type=radio] { accent-color: var(--accent); }
.radios { display: flex; gap: 0; flex-wrap: wrap; }
.radios label { font-family: var(--mono); font-size: 12.5px; font-weight: 400; padding: 4px 11px; border: 1px solid var(--btn-line);
  margin: 0 -1px -1px 0; border-radius: 0; cursor: pointer; color: var(--muted); background: var(--field);
  display: inline-flex; align-items: center; gap: 7px; user-select: none; }
.radios label:hover { color: var(--ink); background: var(--panel2); }
.radios label:has(input:checked) { position: relative; border-color: var(--go-line); background: var(--go-soft); color: var(--go-ink); }
.radios input { accent-color: var(--go); }

/* ---------- the progress bar (kit/progress.js): a ruled scale, filled in the accent ---------- */
.pbar { display: flex; flex-direction: column; gap: 5px; width: 100%; min-width: 0; }
.pbar-track { display: flex; gap: 2px; height: 6px; width: 100%; }
.pbar-phase { flex-basis: 0; min-width: 10px; background: var(--line2); border: 1px solid var(--line); border-radius: 0; overflow: hidden; }
.pbar-fill { height: 100%; width: 0%; border-radius: 0; background: var(--accent);
  transition: width var(--motion-slow) var(--ease-out); }
.pbar-phase.done .pbar-fill { background: var(--accent-dim); }
.pbar-phase.pulse .pbar-fill { animation: pbar-pulse 1.4s ease-in-out infinite; }
@keyframes pbar-pulse { 0%, 100% { opacity: .22; } 50% { opacity: .85; } }
.pbar-line { display: flex; align-items: baseline; gap: 4px 10px; min-width: 0; font-size: 12.5px; color: var(--ink); }
.pbar-what { flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere; }
.pbar-time { flex: none; margin-left: auto; white-space: nowrap; font-family: var(--mono); font-size: 12px;
  color: var(--muted); font-variant-numeric: tabular-nums; }

/* ---------- the map view ---------- */
.ws-view { display: flex; flex-direction: column; min-width: 0; min-height: 0; background: var(--bg); }
.ws-view.is-fullscreen { position: fixed; inset: 0; z-index: 50; }
.ws-view:fullscreen { background: var(--bg); }
/* One row (kit/toolbar.js measures `data-compact`, the detail given up to stay on it); wrapping only past the last
   step (`data-fit="wrap"`). Nothing in the row shrinks: what does not fit is measured, not squeezed. */
.vw-bar { display: flex; flex-wrap: nowrap; align-items: center; gap: 6px 8px; padding: 7px 12px; background: var(--panel);
  border-bottom: 1px solid var(--rule); min-width: 0; }
.vw-bar[data-fit="wrap"] { flex-wrap: wrap; }
.vw-bar > * { flex-shrink: 0; }
.vw-group { display: inline-flex; flex-wrap: nowrap; align-items: center; gap: 4px; }
.vw-group > * { flex-shrink: 0; }
.vw-sep { width: 1px; align-self: stretch; background: var(--line); margin: 2px 3px; }
.vw-bar > .vw-spacer { flex: 1 1 0; min-width: 0; }
/* A step's second row (kit/toolbar.js `buildMethods`: the regions page's Hard Trace): its label, its tools, a note
   when they are off, its own overlays. The first row's look; it wraps rather than compacts (and is no `.vw-bar`: the
   toolbar measures that one alone). */
.vw-methods { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; padding: 7px 12px; background: var(--panel);
  border-bottom: 1px solid var(--rule); min-width: 0; }
.vw-methods[hidden] { display: none; }
.vw-methods > * { flex-shrink: 0; }
.vw-methods > .vw-spacer { flex: 1 1 0; min-width: 0; }
.vw-row-label { flex: none; font-family: var(--mono); font-size: 11px; letter-spacing: .06em; text-transform: uppercase;
  color: var(--faint); margin-right: 2px; }
.vw-row-note { font-size: 12px; color: var(--muted); max-width: 46ch; }
.vw-toggles { gap: 12px; }
.vw-layer { display: inline-flex; align-items: center; gap: 6px; }
.vw-toggle { display: inline-flex; align-items: center; gap: 6px; font-family: var(--narrow); font-size: 14px;
  color: var(--muted); cursor: pointer; }
.vw-layer input[type=range] { width: 84px; }
.vw-border { display: inline-flex; align-items: center; gap: 5px; font-family: var(--narrow); font-size: 14px; color: var(--muted); }
.vw-layer .vw-border input[type=range] { width: 52px; }
.vw-border-val { font-family: var(--mono); font-size: 11.5px; min-width: 8px; }
.vw-size { display: inline-flex; align-items: center; gap: 6px; font-family: var(--narrow); font-size: 14px;
  color: var(--muted); margin-left: 6px; }
.vw-size input[type=range] { width: 84px; }
.vw-size-val { font-family: var(--mono); min-width: 3ch; color: var(--accent-ink); }
.tool-keys { width: 30px; justify-content: center; padding: 4px 0; font-weight: 700; }
.step-picks { display: flex; flex-direction: column; gap: 10px; }
.pick-note { font-family: var(--mono); font-size: 11px; font-weight: 400; color: var(--accent-ink); background: var(--accent-soft);
  border: 1px solid var(--accent-dim); border-radius: 2px; padding: 0 5px; }
.radios label:has(input:checked) .pick-note { background: var(--field); color: var(--accent-ink); }
/* The toolbar's compaction steps (kit/toolbar.js `fit`): words go, glyphs, tooltips and aria-labels stay. The tools'
   words go LAST (the owner, 2026-11-01: a tool's glyph alone is ambiguous); the history and view buttons' go first
   (↶ ↷ ⤢ ⛶ read without words). 1: those words; 2: narrower sliders, no separators, a smaller count; 3: the layer
   toggles keep their words at every step (the owner, 2026-11-05); 3: narrower sliders still; 4: the tools' words. */
.vw-bar:not([data-compact="0"]) .vw-group:not(.vw-tools) .tool-text { display: none; }
.vw-bar:not([data-compact="0"]) .vw-group:not(.vw-tools) .tool { padding: 4px 8px; }
.vw-bar[data-compact="2"] .vw-layer input[type=range], .vw-bar[data-compact="2"] .vw-size input[type=range] { width: 52px; }
.vw-bar[data-compact="3"] .vw-layer input[type=range], .vw-bar[data-compact="3"] .vw-size input[type=range],
.vw-bar[data-compact="4"] .vw-layer input[type=range], .vw-bar[data-compact="4"] .vw-size input[type=range] { width: 40px; }
.vw-bar[data-compact="2"] .vw-layer .vw-border input[type=range] { width: 40px; }
.vw-bar[data-compact="3"] .vw-layer .vw-border input[type=range],
.vw-bar[data-compact="4"] .vw-layer .vw-border input[type=range] { width: 32px; }
.vw-bar[data-compact="2"] .vw-sep, .vw-bar[data-compact="3"] .vw-sep, .vw-bar[data-compact="4"] .vw-sep { display: none; }
/* 3 and 4: tighter spacing too (the names stay: the owner, 2026-11-05). */
.vw-bar[data-compact="3"], .vw-bar[data-compact="4"] { gap: 6px 6px; padding: 7px 8px; }
.vw-bar[data-compact="3"] .vw-toggles, .vw-bar[data-compact="4"] .vw-toggles { gap: 8px; }
.vw-bar[data-compact="3"] .vw-layer, .vw-bar[data-compact="4"] .vw-layer,
.vw-bar[data-compact="3"] .vw-toggle, .vw-bar[data-compact="4"] .vw-toggle,
.vw-bar[data-compact="3"] .vw-size, .vw-bar[data-compact="4"] .vw-size,
.vw-bar[data-compact="3"] .vw-border, .vw-bar[data-compact="4"] .vw-border { gap: 4px; }
.vw-bar.vw-bar[data-compact="4"] .vw-group .tool { padding: 4px 6px; }
.vw-bar[data-compact="4"] .vw-tools .tool-text { display: none; }
.vw-bar[data-compact="4"] .vw-tools .tool { padding: 4px 8px; }
/* Measured with nothing in transition (kit/toolbar.js `fit` reads each step's widths at once). */
.vw-bar[data-fit="measure"], .vw-bar[data-fit="measure"] * { transition: none !important; }
.vw-stage { position: relative; flex: 1; min-height: 0; overflow: hidden;
  background: repeating-conic-gradient(var(--check-a) 0% 25%, var(--check-b) 0% 50%) 50% / 22px 22px; }
.vw-canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; touch-action: none; outline: none; }
.vw-status { position: absolute; left: 10px; bottom: 10px; max-width: calc(100% - 20px); font-family: var(--mono); font-size: 12px;
  color: var(--ink); background: var(--float); border: 1px solid var(--rule); border-radius: 0; padding: 3px 8px;
  pointer-events: none; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.vw-status:empty { display: none; }
.vw-help { position: absolute; top: 10px; right: 10px; width: min(380px, calc(100% - 20px)); max-height: calc(100% - 60px);
  overflow-y: auto; background: var(--float); border: 1px solid var(--rule); border-radius: 0; padding: 10px 14px;
  box-shadow: var(--shadow-pop); font-size: 12.5px; z-index: 2; }
.help-head { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; margin-bottom: 6px;
  padding-bottom: 6px; border-bottom: 1px solid var(--line); }
.help-rows { display: grid; grid-template-columns: max-content 1fr; gap: 5px 12px; align-items: baseline; }
.help-row { display: contents; }
.help-keys { text-align: right; white-space: nowrap; }
.help-or { color: var(--faint); }
.help-label { color: var(--muted); }

/* ---------- dialogs (kit/dialog.js): the floating family (8px corners, the soft shadow, the one backdrop) ---------- */
dialog.dlg { padding: 0; border: 1px solid var(--rule); border-radius: var(--r-float); background: var(--panel);
  color: var(--ink); box-shadow: var(--shadow-pop); width: min(460px, calc(100vw - 32px)); max-height: calc(100dvh - 32px); }
dialog.dlg::backdrop { background: var(--backdrop); }
.dlg-inner { padding: 16px 20px 16px; display: flex; flex-direction: column; gap: 12px; }
.dlg-title { font-family: var(--serif); font-size: 18px; font-weight: 700; }
.dlg-body { display: flex; flex-direction: column; gap: 10px; font-size: 13.5px; color: var(--ink); }
.dlg-body p { margin: 0; }
.dlg-body .hint { margin: 0; }
.dlg-counts { margin: 0; padding-left: 20px; display: grid; gap: 3px; font-size: 13px; }
.dlg-field { display: flex; flex-direction: column; gap: 5px; font-family: var(--narrow); font-size: 14px; font-weight: 700; color: var(--ink); }
.dlg-buttons { display: flex; justify-content: flex-end; gap: 8px; margin-top: 4px; padding-top: 12px; border-top: 1px solid var(--line); }

/* ---------- pages ---------- */
.wrap { max-width: 1180px; margin: 0 auto; padding: 28px 24px 96px; }
.card { background: var(--panel); border: 1px solid var(--line); border-radius: 0; box-shadow: var(--shadow); }
.noscript { padding: 24px; color: var(--warn-ink); }

/* ---------- the kit demo (static/demo/) ---------- */
.demo-bar { display: inline-flex; gap: 6px; align-items: center; }
.demo-legend { display: grid; gap: 4px; font-size: 12.5px; color: var(--muted); }
.demo-legend b { color: var(--ink); }
.demo-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 0; max-height: 180px; overflow-y: auto;
  border: 1px solid var(--line); border-radius: 0; background: var(--inset); }
.demo-list li { display: flex; justify-content: space-between; gap: 10px; padding: 4px 10px; font-size: 12.5px; cursor: pointer;
  border-bottom: 1px solid var(--line2); }
.demo-list li:hover { background: var(--panel2); }
.demo-list li.sel { background: var(--accent-soft); color: var(--accent-ink); font-weight: 700; }
.demo-list .mono { font-family: var(--code); font-size: 11.5px; color: var(--faint); }

/* ---------- phone width: the panel above the view (D1) ---------- */
@media (max-width: 899px) {
  .topbar { flex-wrap: wrap; height: auto; min-height: var(--topbar-h); padding: 8px 12px; gap: 8px; }
  .demo-bar .tool { padding: 4px 8px; font-size: 13px; }
  .crumb, .crumb-sep, .user-name { display: none; }
  .ws, .ws:has(.ws-panel.wide) { display: flex; flex-direction: column; height: auto; }
  .ws-panel { overflow: visible; border-right: 0; border-bottom: 1px solid var(--rule); padding: 12px 16px 16px; }
  .ws-view { height: 70vh; min-height: 360px; }
  .vw-bar { padding: 6px 8px; }
  .tool-keys { display: none; }
}

/* The NDA mark in a block's name (kit/errors.js blockTitle): dark red, a lighter red on the dark theme. */
.nda { color: var(--nda); font-weight: 700; }
/* NDA parts inside a page (engine/audience.py: a summary's or the extras' NDA member, an NDA layer's toggle): the
   NDA ink, never the word. */
.fact-nda, .nda-ink, .nda-ink span { color: var(--nda); }
.step-run-line { display: flex; align-items: center; gap: 10px; }
.step-run-note { font-size: 12px; color: var(--muted); }
.ctl-note { margin: 2px 0 0; font-size: 12px; color: var(--muted); }

/* The always-present upload, and the small tools beside it */
.top-upload { display: inline-flex; align-items: center; gap: 6px; flex: none; height: 30px; padding: 0 12px;
  border: 1px solid var(--accent-ink); border-radius: 2px; color: var(--accent-ink); text-decoration: none;
  font-family: var(--narrow); font-size: 14px; font-weight: 700; }
.top-upload:hover { background: var(--accent-ink); color: var(--topbar); }
.top-tools { display: inline-flex; align-items: center; gap: 4px; flex: none; padding-left: 10px;
  border-left: 1px solid var(--line); }
@media (max-width: 899px) {
  .topnav { order: 10; width: 100%; margin-left: 0; overflow-x: auto; }
  .topnav a { padding: 6px 10px; }
  .topnav .sub { display: none; }
  .scope-btn { max-width: 170px; }
  .scope-label, .top-upload span { display: none; }
  .top-tools { padding-left: 4px; border-left: 0; }
}

/* the Геовед path in the top bar of a map's pages (hub.mirror.links_of_map) */
a.crumb-link { color: var(--accent-ink); text-decoration: none; max-width: 22ch; }
a.crumb-link:hover { text-decoration: underline; }

/* ---------- one button geometry everywhere (the owner, 2026-11-01: MapMaven's library buttons; colours kept) ----------
   An ordinary button or tool is 26px tall, Golos Text 13px, its rim 1.5px of ink, 4px corners; an icon button a 26px
   square; the page's one main action (.cta) 32px and filled green; a group that switches one choice (.radios,
   .seg) one outlined box whose segments part with a 1px ink line, the chosen one tinted green. A disabled control
   keeps its shape: a light rim and faint words, never a fade. */
.tool, button.run, a.run, .next-btn, .top-admin, .nda-toggle {
  height: 26px; padding: 0 10px; line-height: 1; display: inline-flex; align-items: center; justify-content: center;
  border-width: var(--btn-bw); border-radius: var(--btn-r); font-family: var(--sans); font-size: 13px; box-sizing: border-box; }
.tool, .next-btn, .top-admin, .nda-toggle { border-color: var(--btn-line); }
.tool:hover:not(:disabled), .next-btn:hover, .top-admin:hover { background: var(--panel2); border-color: var(--btn-line); }
.tool.active, .tool[aria-pressed="true"] { background: var(--go-soft); color: var(--go-ink); border-color: var(--btn-line); }
.tool:disabled, .tool[aria-disabled="true"] { opacity: 1; border-color: var(--line); color: var(--faint); background: var(--field); }
button.run, a.run { border-color: var(--go); box-shadow: none; }
button.run:hover:not(:disabled), a.run:hover { background: var(--go-hi); border-color: var(--go-hi); }
button.run:disabled { opacity: 1; border-color: var(--line); background: var(--field); color: var(--faint); }
.cta, button.run.cta, a.run.cta { height: var(--h-cta); padding: 0 16px; font-size: 14px; }
button.run:focus-visible, a.run:focus-visible, .tool:focus-visible { box-shadow: var(--ring); }
.seg > :focus-visible, .program:focus-visible { box-shadow: var(--ring-in); }
.lang-toggle, .theme-toggle, .ctl-reset, .tool-icon-only, .more > summary.tool {
  width: 26px; height: 26px; padding: 0; border-width: var(--btn-bw); border-color: var(--btn-line); border-radius: var(--btn-r);
  line-height: 1; justify-content: center; }
.lang-toggle:hover, .theme-toggle:hover, .ctl-reset:hover:not(:disabled) { background: var(--panel2); border-color: var(--btn-line); }
.tool-keys { width: 26px; padding: 0; }
select.tool, .dlg select, select.fm-type, select.fm-select { height: 26px; border: var(--btn-bw) solid var(--btn-line); border-radius: var(--btn-r); }
.radios, .seg { display: inline-flex; flex-wrap: nowrap; height: var(--h-ctl); border: var(--btn-bw) solid var(--btn-line);
  border-radius: var(--btn-r); overflow: hidden; background: var(--field); }
.radios label, .seg > * { height: 100%; margin: 0; padding: 0 10px; border: 0; border-left: 1px solid var(--btn-line); border-radius: 0;
  font-family: var(--sans); font-size: 13px; line-height: 1; background: transparent; }
.radios label:first-child, .seg > *:first-child { border-left: 0; }
.radios label:has(input:checked), .seg > .on, .seg > [aria-selected="true"], .seg > [aria-pressed="true"] {
  background: var(--go-soft); color: var(--go-ink); border-color: var(--btn-line); }
.chip { border-radius: 3px; height: 20px; box-sizing: border-box; }
/* A step's pick over its result (kit/stepcard.js `updatePicks`: the regions granularity) is NOT a segmented bar: one
   row per choice at the panel's full width, the radio, the choice's name and its note right-aligned (the owner,
   2026-11-05: three levels with "37% · 100 regions" notes did not fit one bar). The rows share the bar's outline, a
   1px ink line between them and the chosen one tinted green; a name or a note too long for the row wraps inside it. */
.step-pick .radios { display: flex; flex-direction: column; width: 100%; height: auto; box-sizing: border-box; }
.step-pick .radios label { display: flex; flex-wrap: wrap; align-items: center; gap: 2px 8px; height: auto;
  min-height: var(--h-ctl); padding: 4px 10px; box-sizing: border-box; border-left: 0; border-top: 1px solid var(--btn-line);
  line-height: 1.25; }
.step-pick .radios label:first-child { border-top: 0; }
.step-pick .radios label > span:not(.pick-note) { flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere; }
.step-pick .radios input { margin: 0; flex: none; }
.step-pick .pick-note { flex: 0 1 auto; margin-left: auto; min-width: 0; text-align: right; overflow-wrap: anywhere;
  font-variant-numeric: tabular-nums; }


/* ---------- what runs (pages/activity.js; the owner, 2026-11-01): the top bar's activity button, the popup it opens
   above everything, the notices in the corner; the «Процессы» page (pages/hub.css .proc-*) uses the same words ---------- */
.act-toggle { position: relative; display: inline-grid; place-items: center; width: 26px; height: 26px; padding: 0;
  border: var(--btn-bw) solid var(--btn-line); border-radius: var(--btn-r); background: var(--field); color: var(--muted); cursor: pointer; }
.act-toggle:hover { color: var(--ink); background: var(--panel2); }
.act-toggle svg { width: 14px; height: 14px; }  /* the bar's other toggles' size (ru, theme): one row of equal squares */
.act-toggle.busy { color: var(--run-ink); border-color: var(--run-line); }
.act-toggle.busy svg { animation: act-beat 1.6s ease-in-out infinite; }
.act-count:empty { display: none; }
.act-count { position: absolute; top: -7px; right: -8px; min-width: 17px; height: 17px; padding: 0 4px; border-radius: 9px;
  background: var(--run-ink); color: var(--on-fill); font-size: 10.5px; font-weight: 700; line-height: 17px; text-align: center; }
@keyframes act-beat { 0%, 100% { opacity: 1; } 50% { opacity: .45; } }
/* the popup: the Ctrl+K palette's frame and rows (pages/hub.css .jump-*: the same values, here for every page, Картовед's
   too), centred 12vh from the top; a row's actions show on the chosen row (the arrows, the pointer, the keyboard) */
.act-dlg { width: min(92vw, 720px); margin-top: 12vh; padding: 0; border: 1px solid var(--rule); border-radius: var(--r-float);
  background: var(--panel); color: var(--ink); box-shadow: var(--shadow-pop); overflow: hidden; }
.act-dlg::backdrop { background: var(--backdrop); }
.act-pop { display: flex; flex-direction: column; }
.act-pop-head { display: flex; align-items: baseline; gap: 12px; padding: 16px 18px; border-bottom: 1px solid var(--line);
  font-family: var(--sans); font-size: 17px; }
.act-pop-name { flex: none; color: var(--ink); font-weight: 700; }
.act-pop-sum { flex: none; color: var(--muted); font-size: 13px; }
.act-pop-find { flex: 1; min-width: 90px; margin: 0 0 0 6px; padding: 0; border: 0; background: transparent; color: var(--ink);
  font: inherit; font-size: 15px; outline: none; }
.act-pop-find::placeholder { color: var(--faint); }
/* the head is the palette's input: the filter draws no box of its own, the head's rule takes the focus colour */
.act-dlg .act-pop-find:focus-visible { box-shadow: none; }
.act-pop-head:focus-within { border-bottom-color: var(--accent-dim); box-shadow: 0 1px 0 0 var(--accent-dim); }
.act-pop-find::-webkit-search-cancel-button { filter: grayscale(1) opacity(.55); cursor: pointer; }
/* the server's line while something of the person's runs or waits: one quiet line, never a second head */
.act-pop-res { padding: 7px 18px; border-bottom: 1px solid var(--line2); background: var(--inset); color: var(--muted);
  font-size: 12.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.act-pop-res[hidden] { display: none; }
.act-pop-list { list-style: none; margin: 0; padding: 6px; max-height: 52vh; overflow-y: auto; }
.act-pop-group { padding: 8px 10px 2px; font-family: var(--narrow); font-size: 11.5px; font-weight: 700; letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--muted); }
.act-pop-row { position: relative; display: grid; grid-template-columns: 30px minmax(0, 1fr); grid-template-rows: auto auto auto;
  column-gap: 8px; padding: 7px 10px; border-radius: var(--btn-r); cursor: pointer; }
.act-pop-row.on { background: var(--go-soft); }
.act-pop-tile { grid-row: span 2; align-self: center; display: grid; place-items: center; width: 26px; height: 26px; border-radius: var(--btn-r);
  font-size: 14px; background: color-mix(in srgb, currentColor 12%, transparent); }
/* a process's tile is the mark of what it works on, in that kind's ink (pages/glyphs.js PROGRAM_KIND): a map for
   Картовед, a report for Скановед, ◈ for Геовед; the program's colour stays on its NAME (.act-badge, the lanes) */
.act-pop-tile.act-scan { color: var(--k-text); }
.act-pop-tile.act-kart { color: var(--k-map); }
.act-pop-tile.act-geoved { color: var(--accent-ink); }
.act-pop-label { grid-column: 2; color: var(--ink); font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.act-pop-hint { grid-column: 2; color: var(--muted); font-size: 12.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* a row's actions lie over its right end (the words keep the whole width when it is not chosen), on the row's tint */
.act-pop-acts { position: absolute; top: 50%; right: 10px; transform: translateY(-50%); display: flex; gap: 4px; padding-left: 28px;
  background: linear-gradient(90deg, transparent, var(--go-soft) 24px); opacity: 0; pointer-events: none;
  transition: opacity var(--motion-fast) var(--ease-out); }
.act-pop-row.on .act-pop-acts, .act-pop-row:hover .act-pop-acts, .act-pop-acts:focus-within { opacity: 1; pointer-events: auto; }
.act-pop-acts .tool { height: var(--h-ctl); padding: 0 10px; font-size: 13px; text-decoration: none; display: inline-flex; align-items: center; }
.act-pop-acts .tool.stop, .act-acts .tool.stop { border-color: var(--bad-line); color: var(--bad-ink); }
.act-pop-acts .tool.retry, .act-acts .tool.retry { border-color: var(--go-line); color: var(--go-ink); }
/* how far a running process is: a thin bar under its words (the page draws a taller one, pages/hub.css) */
.act-bar { grid-column: 2; display: block; height: 3px; margin: 5px 0 1px; background: var(--line2); overflow: hidden; }
.act-bar-fill { display: block; width: 0; height: 100%; background: var(--run-ink); transition: width var(--motion-slow) var(--ease-out); }
.act-pop-empty { padding: 14px; color: var(--muted); text-align: center; }
.act-pop-note { padding: 8px 14px 4px; color: var(--faint); font-size: 12.5px; text-align: center; }
.act-pop-foot { display: flex; align-items: center; gap: 12px; margin: 0; padding: 8px 14px; border-top: 1px solid var(--line); color: var(--faint);
  font-size: 12px; font-family: var(--mono); }
.act-pop-foot .link { margin-left: auto; font-family: var(--sans); font-size: 13px; }
/* the «Процессы» page's history table (hub_processes.js) */
.act-table { width: 100%; border-collapse: collapse; }
.act-row td { padding: 7px 8px; border-top: 1px solid var(--line2); vertical-align: middle; }
.act-row.focus td { background: var(--accent-soft); }
.act-prog { width: 1%; white-space: nowrap; }
.act-badge { display: inline-flex; align-items: center; height: 20px; padding: 0 7px; border: 1px solid currentColor; border-radius: 3px;
  font-size: 12px; }  /* a chip's geometry (.chip) */
.act-badge.act-scan { color: var(--info-ink); }
.act-badge.act-kart { color: var(--go-ink); }
.act-badge.act-geoved { color: var(--accent-ink); }
.act-badge .glyph { margin-right: 5px; }
/* A thing's mark (pages/glyphs.js) beside words, on every page of the three programs: its shape says what it is, its
   ink is its kind's (a map the map pages' red-brown wherever it is: a file's row, /maps, a process, a work's maps). */
.glyph { display: inline-flex; align-items: center; justify-content: center; flex: none; line-height: 1; vertical-align: -2px; }
.glyph svg { display: block; }
.glyph-map { color: var(--k-map); }
.glyph-report, .glyph-text { color: var(--k-text); }
.glyph-figure { color: var(--k-figure); }
.glyph-site, .glyph-none { color: var(--accent-ink); }
.glyph-folder, .glyph-project, .glyph-other, .glyph-table, .glyph-reading, .glyph-deposit { color: var(--muted); }
/* Where a thing comes from (pages/glyphs.js originLine): the mark of its source and «из отчёта …, стр. 12» or «прил. 1
   к …», one quiet line that leads back there; a long title is cut at its own end, so the page stays in sight. */
.from { display: inline-flex; align-items: baseline; min-width: 0; max-width: 100%; vertical-align: bottom;
  color: var(--muted); text-decoration: none; white-space: nowrap; }
.from > .glyph { align-self: center; margin-right: 5px; }
.from-pre { flex: none; }
.from-title { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.from-page { flex: none; }
.from:hover > span:not(.glyph) { color: var(--accent-ink); text-decoration: underline; }
.act-what { min-width: 0; }
.act-kind { font-size: 12px; color: var(--muted); }
.act-title { display: block; max-width: 340px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--ink);
  font-weight: 700; text-decoration: none; }
.act-title:hover { color: var(--accent-ink); text-decoration: underline; }
.act-where { font-size: 12px; color: var(--faint); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 420px; }
.act-state { white-space: nowrap; }
.act-word { font-size: 12.5px; }
.act-word.tone-run { color: var(--run-ink); }
.act-word.tone-run::before { content: "● "; animation: act-beat 1.6s ease-in-out infinite; }
.act-word.tone-wait { color: var(--muted); }
.act-word.tone-wait::before { content: "◌ "; }
.act-word.tone-done { color: var(--go-ink); }
.act-word.tone-done::before { content: "✓ "; }
.act-word.tone-bad { color: var(--bad-ink); }
.act-word.tone-bad::before { content: "! "; font-weight: 700; }
.act-when, .act-took { width: 1%; white-space: nowrap; color: var(--faint); font-size: 12px; text-align: right; }
.act-acts { width: 1%; white-space: nowrap; text-align: right; }
.act-acts .tool { height: var(--h-ctl); padding: 0 10px; margin-left: 4px; font-size: 13px; text-decoration: none; display: inline-flex;
  align-items: center; }
.act-empty { margin: 4px 0 0; }
.act-toasts { position: fixed; right: 18px; bottom: 18px; z-index: 90; display: flex; flex-direction: column; gap: 8px; width: min(92vw, 340px); }
.act-toast { padding: 10px 12px; border: 1px solid var(--line); border-left: 3px solid var(--go); border-radius: var(--r-float); background: var(--panel);
  box-shadow: var(--shadow-pop); animation: act-toast-in var(--motion-slow) var(--ease-out);
  transition: opacity 500ms var(--ease-out), transform 500ms var(--ease-out); }  /* the way out lasts until activity.js
     takes the notice away (half a second after it starts going): the notices under it never jump */
.act-toast.bad { border-left-color: var(--bad); }
.act-toast.gone { opacity: 0; transform: translateX(16px); }
@keyframes act-toast-in { from { opacity: 0; transform: translateX(24px); } }
.act-toast-head { font-size: 12px; color: var(--muted); }
.act-toast-title { margin: 2px 0 2px; font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.act-toast-more { margin: 0 0 6px; font-size: 12.5px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.act-toast.bad .act-toast-more { color: var(--bad-ink); }
.act-toast-next { margin: -4px 0 6px; font-size: 12px; color: var(--faint); }
.act-toast-acts { display: flex; gap: 14px; margin-top: 6px; font-size: 13px; }
[data-activity] { cursor: pointer; }
[data-activity] .stage-text { text-decoration: underline dotted; text-underline-offset: 3px; }
@media (prefers-reduced-motion: reduce) {
  .act-toggle.busy svg, .act-word.tone-run::before, .act-toast { animation: none; }
  .act-pop-acts, .act-bar-fill { transition: none; }
}
@media (max-width: 760px) {
  .act-dlg { margin-top: 8vh; }
  .act-pop-acts { position: static; transform: none; grid-column: 2; padding-left: 0; background: none; opacity: 1;
    pointer-events: auto; flex-wrap: wrap; margin-top: 4px; }
  .act-row td.act-when, .act-row td.act-took { display: none; }
  .act-title { max-width: 46vw; }
}

/* ---------- one program of three (the owner, 2026-11-01): Геовед's участки, Картовед's maps, Скановед's reports
   under one bar (base.html; Скановед draws the same); the thumb slides between pages and the bar stays still while
   the page under it changes (cross-document view transitions: the motion block at the end) ---------- */
.programs { position: relative; flex: none; display: inline-grid; grid-auto-flow: column; grid-auto-columns: 1fr; margin-left: 16px;
  height: var(--h-bar); border: var(--btn-bw) solid var(--btn-line); border-radius: var(--btn-r); overflow: hidden; background: var(--field); }
/* a tab's label and, under it, its hidden bold copy (base.html) in one cell: the chosen tab's bold words never widen
   the switch, so nothing in the bar moves when the program changes */
.program { position: relative; z-index: 1; display: inline-grid; place-items: center;
  height: 100%;
  padding: 0 14px; color: var(--ink); font-size: 13.5px; text-decoration: none; white-space: nowrap;
  transition: color var(--motion-fast) var(--ease-out), background-color var(--motion-fast) var(--ease-out); }
.program > span { grid-area: 1 / 1; }
.program-room { font-weight: 700; visibility: hidden; }
.program + .program { border-left: 1px solid var(--btn-line); }
.program:hover { background: color-mix(in srgb, var(--panel2) 70%, transparent); }
.program-thumb { position: absolute; z-index: 0; top: 0; bottom: 0; left: 0; width: calc(100% / 3); background: var(--go-soft);
  transform: translateX(0); transition: transform var(--motion) var(--ease-out); }
.programs[data-program="maps"] .program-thumb { transform: translateX(100%); }
.programs[data-program="reports"] .program-thumb { transform: translateX(200%); }
.programs[data-program=""] .program-thumb { opacity: 0; }
.programs[data-program="sites"] [data-program-link="sites"], .programs[data-program="maps"] [data-program-link="maps"],
.programs[data-program="reports"] [data-program-link="reports"] { color: var(--go-ink); font-weight: 700; }
@media (max-width: 760px) {
  .programs { margin-left: 8px; }
  .program { padding: 0 8px; font-size: 12.5px; }
}
/* a dialog's select is a dialog field (the 26px of the toolbars clipped its words) */
.dlg select.dlg-input, dialog select.dlg-input { height: auto; min-height: 34px; padding: 5px 10px; line-height: 1.4; }

/* ---------- motion that explains a change (kit/motion.js; the owner, 2026-11-01: interactive, never game-like): a
   list's new rows rise in, a row whose state changed flashes once, a removed row folds away; menus and dialogs open
   from where they belong. Idle content never moves; prefers-reduced-motion stops it all (the rule near the top). */
.m-enter { animation: m-rise var(--motion-slow) var(--ease-out) backwards; animation-delay: calc(var(--i, 0) * 30ms); }
/* from a light ink, not from nothing: rows that take a skeleton's place never leave a blank frame between the two
   (the owner, 2026-11-03: the loading looked bad) */
@keyframes m-rise { from { opacity: .4; transform: translateY(4px); } }
.m-changed { animation: m-flash 600ms ease-out; }
@keyframes m-flash { from { background-color: var(--go-soft); } }
.m-leave { min-height: 0 !important; overflow: hidden; pointer-events: none; animation: m-fold var(--motion) var(--ease-out) forwards; }
@keyframes m-fold {
  from { max-height: var(--h, 80px); }
  to { max-height: 0; opacity: 0; padding-top: 0; padding-bottom: 0; margin-top: 0; margin-bottom: 0; border-top-width: 0;
    border-bottom-width: 0; }
}
details.more[open] > .menu-list { animation: m-pop var(--motion-fast) var(--ease-out); transform-origin: top right; }
details.more.up[open] > .menu-list { transform-origin: bottom right; }
@keyframes m-pop { from { opacity: 0; transform: scale(.98); } }
/* Картовед's map page: the next step's green rule draws in when the card arrives or becomes the next */
.blockgrid .blockcard.bc-next { position: relative; box-shadow: none; }
.blockgrid .blockcard.bc-next::before { content: ""; position: absolute; left: 0; right: 0; top: 0; height: 3px;
  background: var(--go); transform-origin: left; pointer-events: none; }
.blockgrid .blockcard.bc-next.m-enter::before, .blockgrid .blockcard.bc-next.m-changed::before {
  animation: m-draw var(--motion-slow) var(--ease-out) backwards; animation-delay: calc(var(--i, 0) * 30ms + var(--motion)); }
@keyframes m-draw { from { transform: scaleX(0); } }

/* ========== motion: one set of tokens, the program switch, the interactions (the owner, 2026-11-02: «make switching
   between Карты and Отчёты and back smooth; add animation for interactivity where needed») ==========
   ONE set of tokens for Геовед, Картовед and Скановед (scanoved/web/src/index.css repeats these values): three
   durations from 120 to 240 ms and one easing, quick to start and soft to land. Motion explains a change and never
   plays: nothing moves on the map's canvas, on a poll's redraw that changed nothing, or under prefers-reduced-motion
   (the rule under «base», and the view transitions' rule below), and nothing waits for an animation to take input.
   The earlier pass above (kit/motion.js's m-* marks, the library's switch and groups, Геовед's tabs and rows) uses
   the same tokens. Two longer ones, on purpose: a changed row's 600 ms flash (a highlight to be seen, not a motion)
   and a corner notice's 500 ms way out (as long as activity.js keeps it). */
:root {
  --motion-fast: 120ms;  /* a press, a hover, a menu, a dialog */
  --motion: 180ms;       /* a fold, a switch's thumb, the page under the bar */
  --motion-slow: 240ms;  /* a corner notice, a list's rows coming in, a progress bar's step */
  --ease-out: cubic-bezier(.2, .8, .2, 1);
}

/* -- from one program to another, and between any two pages: the browser's cross-document view transition (same
   origin). The top bar is one layer that stays still, the same bar on every page (Скановед's too); the program's
   thumb slides from the old tab to the new under the tabs' words, each tab a layer of its own painted above it; the
   page under the bar fades in over the old one (opaque over opaque: no dip between them). The page switched to is
   usually drawn already: the other programs' lists are prerendered once a page has settled (pages/activity.js,
   web/hub_tree.py speculation_rules), so this is a cross-fade between two finished pages, never a blank one. -- */
@view-transition { navigation: auto; }
.topbar { view-transition-name: geoved-top; }
.program-thumb { view-transition-name: geoved-program; }
.programs[data-program=""] .program-thumb { view-transition-name: none; }  /* no program here: the thumb fades in */
.program[data-program-link="sites"] { view-transition-name: geoved-program-sites; }
.program[data-program-link="maps"] { view-transition-name: geoved-program-maps; }
.program[data-program-link="reports"] { view-transition-name: geoved-program-reports; }
::view-transition-group(*) { animation-duration: var(--motion); animation-timing-function: var(--ease-out); }
::view-transition-old(root), ::view-transition-new(root) { mix-blend-mode: normal; }
::view-transition-old(root) { animation: none; }
::view-transition-new(root) { animation: geoved-fade-in var(--motion) var(--ease-out) both; }
@keyframes geoved-fade-in { from { opacity: 0; } }
@media (prefers-reduced-motion: reduce) {
  ::view-transition-group(*), ::view-transition-old(*), ::view-transition-new(*) { animation: none !important; }
  .program-thumb { transition: none; }
}
/* The bar never shifts: every page keeps the scrollbar's room whether it scrolls or not (a list that grows a
   scrollbar, or a program without one, moved the bar's right end by its width); not the map's workspace, which never
   scrolls and takes the whole width. */
html { scrollbar-gutter: stable; }
html:has(#workspace) { scrollbar-gutter: auto; }

/* -- dialogs open and close alike (the kit's confirms, the upload, Ctrl+K, the activity popup, the page viewer): in,
   they fade and grow from 98 %; out, the reverse; the backdrop fades with them. CSS alone: @starting-style for the way
   in; `display` and the top layer (`overlay`) kept until the way out has played (allow-discrete); a dialog the page
   removes on closing waits for it (kit/motion.js removeAfterExit). The page viewer only fades: it measures its stage
   as it opens (hub_viewer.js `fit`), and a scaled stage would fit the page 2 % small. -- */
dialog.dlg, dialog.act-dlg, dialog.upload-dlg, dialog.jump-dlg, dialog.ql-dlg {
  transition: opacity var(--motion-fast) var(--ease-out), transform var(--motion-fast) var(--ease-out),
    overlay var(--motion-fast) var(--ease-out) allow-discrete,
    display var(--motion-fast) var(--ease-out) allow-discrete; }
dialog.dlg:not([open]), dialog.act-dlg:not([open]), dialog.upload-dlg:not([open]), dialog.jump-dlg:not([open]),
dialog.ql-dlg:not([open]) { opacity: 0; transform: scale(.98); pointer-events: none; }  /* going: takes no click */
dialog.ql-dlg:not([open]) { transform: none; }
dialog.dlg::backdrop, dialog.act-dlg::backdrop, dialog.upload-dlg::backdrop, dialog.jump-dlg::backdrop,
dialog.ql-dlg::backdrop {
  transition: opacity var(--motion-fast) var(--ease-out), overlay var(--motion-fast) var(--ease-out) allow-discrete,
    display var(--motion-fast) var(--ease-out) allow-discrete; }
dialog.dlg:not([open])::backdrop, dialog.act-dlg:not([open])::backdrop, dialog.upload-dlg:not([open])::backdrop,
dialog.jump-dlg:not([open])::backdrop, dialog.ql-dlg:not([open])::backdrop { opacity: 0; pointer-events: none; }
@starting-style {
  dialog.dlg[open], dialog.act-dlg[open], dialog.upload-dlg[open], dialog.jump-dlg[open] {
    opacity: 0; transform: scale(.98); }
  dialog.ql-dlg[open] { opacity: 0; }
  dialog.dlg[open]::backdrop, dialog.act-dlg[open]::backdrop, dialog.upload-dlg[open]::backdrop,
  dialog.jump-dlg[open]::backdrop, dialog.ql-dlg[open]::backdrop { opacity: 0; }
}

/* -- a step card folds (Картовед's steps panel: kit/stepcard.js hides a card's `.step-bd` and says aria-expanded on
   its header, when another step opens or the open one folds to its header line): unfolding, the body grows to its
   height and its content fades in, the card clipping what is not shown yet; folding, the content is gone at once
   (hidden is hidden: nothing can be read or clicked in a folded card) and only its room closes. Under the pointer
   only, so a page that opens on a step shows it at once; the caret turns in the same time. -- */
.step { overflow: clip; overflow-clip-margin: 6px; }  /* the margin keeps the header's focus ring whole */
.step-caret { transition: transform var(--motion-fast) var(--ease-out); }
.ws-panel:hover .step-bd {
  interpolate-size: allow-keywords;
  transition: height var(--motion) var(--ease-out), opacity var(--motion) var(--ease-out),
    padding-block var(--motion) var(--ease-out), display var(--motion) var(--ease-out) allow-discrete; }
.step-bd[hidden] { height: 0; opacity: 0; padding-block: 0; visibility: hidden; }
@starting-style { .ws-panel:hover .step-bd:not([hidden]) { height: 0; opacity: 0; padding-block: 0; } }

/* -- a folded section (a file's card, what the rules found, the expert system's notes: <details>) opens and closes
   as a step card does: opening, its room grows and its content fades in; closing, the content is gone at once and its
   room closes (::details-content; a browser without it just opens). -- */
details.doc-fold, details.doc-notes, details.notes-overflow { interpolate-size: allow-keywords; }
details.doc-fold::details-content, details.doc-notes::details-content, details.notes-overflow::details-content {
  height: 0; opacity: 0; overflow: clip; visibility: hidden;
  transition: height var(--motion) var(--ease-out), opacity var(--motion) var(--ease-out),
    content-visibility var(--motion) var(--ease-out) allow-discrete; }
details.doc-fold[open]::details-content, details.doc-notes[open]::details-content,
details.notes-overflow[open]::details-content { height: auto; opacity: 1; visibility: visible; }

/* -- a press is felt and a hover answers, on every button and segment alike (the run and tool buttons above): the
   colours ease, a press sinks a pixel. -- */
.lang-toggle, .theme-toggle, .act-toggle, .ctl-reset, .nda-toggle, .top-admin, .next-btn, .seg > *, .radios label {
  transition: background-color var(--motion-fast) var(--ease-out), border-color var(--motion-fast) var(--ease-out),
    color var(--motion-fast) var(--ease-out), transform var(--motion-fast) var(--ease-out); }
.lang-toggle:active, .theme-toggle:active, .act-toggle:active, .ctl-reset:active:not(:disabled),
.nda-toggle:active:not(:disabled), .top-admin:active, .next-btn:active { transform: translateY(1px); }

/* -- a block page loading (the owner, 2026-11-03: «the loading screen looks bad … make it more interactive»): the page
   has its frame from the first paint (templates/workspace.html, in these same classes, so nothing changes size when
   the kit draws the real panel): the steps panel with a light sweeping over the lines where the block's title, tabs
   and steps will be (the kit's own boot box draws the same rows), the toolbar's row at its height, and in the view the
   sheet's light picture where the map will be, one status line («Загружаю карту…», then «Готовлю слои…») and one quiet
   progress line along its top; once the map is drawn the picture glides onto it and fades (kit/mapstage.js). The
   sweep and the line are loops, not transitions (like a running chip's dot); reduced motion stills them. -- */
.vw-bar { min-height: calc(var(--h-ctl) + 15px); }  /* its row from the first paint: the stage never shrinks under the map */
.skel-text, .skel-chip { position: relative; overflow: hidden; border-radius: 2px; background: var(--line2); color: transparent; }
.skel-text { display: inline-block; vertical-align: top;  /* a line of text's band, in the line's own height */
  background: linear-gradient(transparent 24%, var(--line2) 24%, var(--line2) 76%, transparent 76%); }
.ws-title .skel-text { width: 11em; }  /* a title's length (the heading shrinks to what it holds: no % here) */
.skel-chip { width: 74px; border-color: transparent; }  /* a chip's own box (.chip), no words yet */
.ws-boot { position: relative; overflow: hidden; }
.ws-boot > .hint { position: absolute; width: 1px; height: 1px; margin: 0; overflow: hidden; clip-path: inset(50%);
  white-space: nowrap; }  /* for a screen reader: the view's line says it for everyone else */
/* four step rows of the real list's geometry (a 38 px header, a 1 px rule): its label and its title as bars */
.ws-boot::after { content: ""; display: block; height: calc(4 * 39px); border-top: 1px solid var(--line);
  background:
    linear-gradient(to bottom, transparent 38px, var(--line) 38px) 0 0 / 100% 39px repeat-y,
    linear-gradient(to bottom, transparent 15px, var(--line2) 15px, var(--line2) 24px, transparent 24px) 32px 0 / 44px 39px repeat-y,
    linear-gradient(to bottom, transparent 13px, var(--line2) 13px, var(--line2) 25px, transparent 25px) 86px 0 / 52% 39px repeat-y; }
.ws-boot:has(.err)::before, .ws-boot:has(.err)::after { display: none; }  /* a page that failed to start says so,
   alone and still */
.ws-steps:empty { border-top-width: 0; }  /* no stray rule under the boot box before the steps come */
.ws-inputs:empty { display: none; }  /* nor an empty list's gap: a block that reads nothing keeps its rows in place */
.ws-chip:empty { display: inline-block; height: 22px; }  /* the block's chip keeps its line before it is read (a deck's
   head has nothing else) */
.vw-stage:has(> .vw-boot:not(.gone)) > .vw-status { visibility: hidden; }  /* one status line: the loading one */
.skel-text::after, .skel-chip::after, .ws-boot::before { content: ""; position: absolute; inset: 0; z-index: 1;
  pointer-events: none; background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--panel) 80%, transparent), transparent);
  transform: translateX(-100%); animation: m-sweep 1.6s ease-in-out infinite; }
@keyframes m-sweep { to { transform: translateX(100%); } }
.vw-preview { position: absolute; left: 1%; top: 1%; width: 98%; height: 98%; object-fit: contain; pointer-events: none;
  user-select: none; transform-origin: 0 0;
  transition: opacity var(--motion-slow) var(--ease-out), transform var(--motion-slow) var(--ease-out); }
.vw-boot { position: absolute; inset: 0; overflow: hidden; pointer-events: none;
  transition: opacity var(--motion-slow) var(--ease-out); }
/* the line: a third of the stage's width crossing it, moved by transform alone (the compositor's: no repaint a frame) */
.vw-boot::before { content: ""; position: absolute; left: 0; top: 0; width: 30%; height: 2px; opacity: .7;
  background: linear-gradient(90deg, transparent, var(--accent), transparent); transform: translateX(-100%);
  animation: m-line 1.6s ease-in-out infinite; }
@keyframes m-line { to { transform: translateX(334%); } }
.vw-boot-text { position: absolute; left: 10px; bottom: 10px; padding: 3px 8px; border: 1px solid var(--rule);
  background: var(--float); color: var(--ink); font-family: var(--mono); font-size: 12px; }  /* the status line's place */
.vw-preview.gone, .vw-boot.gone { opacity: 0; }
@media (prefers-reduced-motion: reduce) {
  .skel-text::after, .skel-chip::after, .ws-boot::before, .vw-boot::before { animation: none; }
  .skel-text::after, .skel-chip::after, .ws-boot::before { display: none; }
}

/* ---------- the review lists (blocks/review/*.js: the dykes' and the faults' "Review & find more"): the three lists
 * (Suggested, Accepted, Rejected) and their rows (a thumbnail of the map, the line's words, the selected row's own
 * buttons). Here, not in a block's stylesheet, because two blocks share them and either may be the only one of its
 * page's deck the user has. The thumbnails are canvases the script draws (the map's own tiles). ---------- */

.rv-panel { display: grid; gap: 8px; min-width: 0; }
.rv-panel .hint { margin: 0; }
.rv-lists { display: grid; gap: 6px; min-width: 0; }

/* One list: a header that opens and closes it, then its rows. */
.rv-list { border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--panel); min-width: 0; }
.rv-list-hd { display: flex; align-items: baseline; gap: 6px; width: 100%; padding: 7px 10px; border: 0;
  background: transparent; color: var(--ink); font: inherit; font-weight: 650; cursor: pointer; text-align: left;
  border-radius: var(--r-sm); }
.rv-list-hd:hover { background: var(--panel2); }
.rv-list-hd:focus-visible { outline: none; box-shadow: var(--ring); }
.rv-caret::before { content: "▸"; display: inline-block; width: 1em; color: var(--muted); }
.rv-list.open .rv-caret::before { content: "▾"; }
.rv-list-title { flex: none; }
.rv-count { flex: none; font-family: var(--mono); font-size: 12px; font-weight: 600; color: var(--muted); }
.rv-list-order { margin-left: auto; font-size: 11.5px; font-weight: 500; color: var(--faint); }
.rv-list-bd { padding: 0 6px 6px; }
.rv-rows { display: grid; gap: 2px; max-height: 340px; overflow-y: auto; overscroll-behavior: contain; }
.rv-more { margin: 6px 4px 0; font-size: 12px; }
.rv-empty { padding: 4px 6px; }

/* One row: the thumbnail, then its words (a tag on the right) and, while it is selected, its own buttons under them. */
.rv-row { display: flex; align-items: center; gap: 8px; width: 100%; padding: 3px 6px 3px 3px; border: 1px solid transparent;
  border-radius: 8px; color: var(--ink); font-size: 12.5px; cursor: pointer; min-width: 0; }
.rv-row:hover { background: var(--panel2); border-color: var(--line); }
.rv-row.selected { background: var(--accent-soft); border-color: var(--accent-dim); }
.rv-thumb { width: 72px; height: 48px; flex: none; border-radius: 5px; border: 1px solid var(--line); background: var(--inset); }
.rv-row-body { flex: 1; min-width: 0; display: grid; gap: 4px; }
.rv-row-line { display: flex; align-items: center; gap: 8px; min-width: 0; }
.rv-row-text { flex: 1; min-width: 0; font-family: var(--mono); font-size: 12px; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; }
.rv-tag { flex: none; padding: 1px 7px; border-radius: 999px; font-size: 11px; font-weight: 600; border: 1px solid var(--line);
  color: var(--muted); background: var(--panel2); }
.rv-tag.drawn { color: var(--info-ink); background: var(--info-soft); border-color: var(--info-line); }
.rv-tag.accepted { color: var(--accent-ink); background: var(--accent-soft); border-color: var(--accent-dim); }
.rv-tag.edited { color: var(--warn-ink); background: var(--warn-soft); border-color: var(--warn-line); }
.rv-acts { display: none; flex-wrap: wrap; gap: 4px; }
.rv-row.selected .rv-acts { display: flex; }
.rv-act { padding: 2px 9px; font-size: 12px; border-radius: 7px; box-shadow: none; }

/* "Clear and start over": under the lists, as wide as its words. */
.rv-clear { justify-self: start; }
