/* ── Reset & base ──────────────────────────────────────────── */
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }

/*
 * ── Design tokens ─────────────────────────────────────────────
 *
 * Canonical tokens (colors, font, type scale, spacing, radii) come from the CDN:
 *   https://cdn.neorgon.org/v1.0.0/styles/base.css   (linked in index.html)
 * Do NOT redeclare them here — a local copy is how the fleet drifted. The block
 * below holds only what base.css does not define, plus the per-site accent.
 *
 * Motion: base.css still ships --ease-snap (bounce) for legacy sites, but it is
 * deprecated for new work (impeccable law: ease-out exponential, no bounce).
 * Use --ease-out below.
 */

:root {
  /* Per-site identity — set to this site's hub card accent (PROJECTS.md section 4) */
  --accent: #65a30d;
  --accent-bright: #84cc16;
  /* Lime-600 is light enough that white on it lands at 3.1:1. The label
     goes dark instead, which reads 6.2:1 and passes AA. */
  --accent-fg: #0a1004;

  /* Site extras base.css does not define */
  --surface-toast: #1a1730;
  --danger: #e11d48;
  --danger-hover: #f43f5e;
  --warn: #f59e0b;
  --danger-soft: #fda4af;

  /* A card face is a piece of card stock, so it stays paper-coloured whatever
     theme the visitor picked. These are deliberately not theme tokens. */
  --card-stock: #f5f2ea;
  --card-ink: #141a2c;
  --card-rule: rgba(30, 40, 70, 0.35);
  --card-pick: #4d7c0f;
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --control-height: 44px;
  --control-height-sm: 36px;
  --shadow-card: 0 12px 28px rgba(15, 23, 42, 0.5);
  --shadow-modal: 0 24px 48px rgba(2, 6, 23, 0.58);
  --z-sticky-header: 200;
  --z-modal: 400;
  --z-toast: 500;
}

/* Author display values (e.g. .section/.stack flex) would otherwise defeat the
   hidden attribute — restore its authority once, globally. */
[hidden] { display: none !important; }

html { height: 100%; }
body {
  font-family: var(--font);
  background: var(--bg);
  min-height: 100%;
  color: var(--text-primary);
  display: flex; flex-direction: column;
}

body.modal-open {
  overflow: hidden;
}

main#main {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
  width: 100%;
}

/* ── Layout ────────────────────────────────────────────────── */
/*
 * GOTCHA: body { display:flex; flex-direction:column } + margin: 0 auto
 * on a child collapses its width — always pair with width: 100%.
 *
 * GOTCHA: External images (YouTube ggpht, Gravatar, etc.) may block loading
 * when the Referer header points to localhost or an unknown origin. Fix:
 * 1. Add <meta name="referrer" content="no-referrer"> in <head> (global)
 * 2. Or add referrerpolicy="no-referrer" on each <img> tag
 */
.container {
  max-width: 900px;
  width: 100%;
  margin: 0 auto;
  padding: var(--space-6);
  flex: 1;
}

/* Vertical rhythm: use inside .container or nested regions */
.stack {
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
}
.stack--tight { gap: var(--space-4); }
.stack--loose { gap: var(--space-8); }

/* Page section: title row + body (replaces “card everything” for grouping) */
.section {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}
.section__header {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--space-4);
}
.section__titles {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  min-width: 0;
}
.section__title {
  font-size: var(--text-xl);
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--text-primary);
}
.section__lead {
  font-size: var(--text-sm);
  color: var(--text-muted);
  line-height: 1.45;
  max-width: 52ch;
}
.section__lead code {
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace;
  font-size: 0.92em;
  color: var(--text-secondary);
}
.stack > .card { margin-bottom: 0; }
.toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
}

/* ── Header ────────────────────────────────────────────────────
 * Owned by the Neorgon Header Kit (css/neorgon-header.css — canonical
 * source: packages/neorgon-ui/header/). Do NOT style .header-bar,
 * .header-logo*, .header-title-link, .header-subtitle, .header-right,
 * .header-actions, or .header-home here. Auth styles (.auth-*) stay
 * site-owned below.
 */
nav {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

/* ── Buttons (canonical) ─────────────────────────────────────
 * Use .btn + a variant. Aliases: .nav-link = toolbar ghost; .auth-* map below.
 */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: var(--control-height);
  padding: 0 var(--space-4);
  border-radius: var(--radius-sm);
  font-family: inherit;
  font-size: var(--text-sm);
  font-weight: 600;
  line-height: 1.2;
  text-decoration: none;
  cursor: pointer;
  border: 1px solid transparent;
  background: transparent;
  color: var(--text-primary);
  transition:
    background-color var(--dur),
    color var(--dur),
    border-color var(--dur),
    box-shadow var(--dur),
    transform var(--dur-fast);
  -webkit-tap-highlight-color: transparent;
}
.btn:disabled,
.btn[aria-disabled="true"] {
  opacity: 0.45;
  cursor: not-allowed;
  pointer-events: none;
}
.btn--sm {
  min-height: var(--control-height-sm);
  padding: 0 var(--space-3);
  font-size: var(--text-xs);
}
.btn--block { width: 100%; }
.btn--icon {
  min-width: var(--control-height);
  padding: 0;
}
.btn--primary {
  background: var(--accent);
  color: var(--accent-fg);
  border-color: transparent;
}
.btn--primary:hover { background: var(--accent-bright); }
.btn--secondary {
  background: var(--surface-2);
  color: var(--text-primary);
  border-color: var(--border-strong);
}
.btn--secondary:hover {
  background: rgba(255, 255, 255, 0.1);
}
.btn--ghost {
  background: transparent;
  color: rgba(255,255,255,0.92);
  border-color: rgba(255,255,255,0.18);
}
.btn--ghost:hover {
  background: rgba(255,255,255,0.1);
  color: #fff;
}
.btn--danger {
  background: var(--danger);
  color: #fff;
  border-color: transparent;
}
.btn--danger:hover { background: var(--danger-hover); }

/* Toolbar ghost (header nav) — same as .btn.btn--ghost.btn--sm */
.nav-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: var(--control-height);
  padding: 0 var(--space-3);
  border: 1px solid rgba(255,255,255,0.18);
  border-radius: var(--radius-sm);
  background: transparent;
  color: rgba(255,255,255,0.92);
  cursor: pointer;
  font-family: inherit;
  font-size: var(--text-sm);
  font-weight: 600;
  transition: background-color var(--dur), color var(--dur), border-color var(--dur);
}
.nav-link:hover {
  background: rgba(255,255,255,0.1);
  color: #fff;
}

.auth-toggle {
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: var(--control-height);
  min-height: var(--control-height);
  padding: 0;
  border: 1px solid rgba(255,255,255,0.18);
  border-radius: var(--radius-sm);
  background: transparent;
  color: rgba(255,255,255,0.92);
  cursor: pointer;
  font-family: inherit;
  transition: background-color var(--dur), color var(--dur), border-color var(--dur);
}
.auth-toggle:hover {
  background: rgba(255,255,255,0.1);
  color: #fff;
}
.auth-toggle svg {
  width: 22px;
  height: 22px;
  flex-shrink: 0;
  display: block;
}
.auth-toggle.logged-in { color: var(--accent); }
.auth-toggle.logged-in svg circle:nth-of-type(2) {
  fill: currentColor;
  stroke: none;
}

/* ── Sheet (inline panel under header) — not a modal ─────────
 * Use for auth, filters, compact forms. No backdrop; page scrolls.
 * For blocking overlays use .modal below.
 */
.auth-panel {
  background: rgba(255,255,255,0.02);
  border-bottom: 1px solid var(--border-subtle);
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.3s ease-out;
}
.auth-panel.open { max-height: 300px; }
.auth-panel-inner {
  padding: var(--space-6);
  max-width: 400px;
  margin: 0 auto;
}
.auth-tabs {
  display: flex;
  gap: var(--space-2);
  margin-bottom: var(--space-4);
}
.auth-tab {
  flex: 1;
  min-height: var(--control-height-sm);
  padding: 0 var(--space-4);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--text-muted);
  cursor: pointer;
  font-family: inherit;
  font-size: var(--text-sm);
  font-weight: 600;
  transition: background-color var(--dur), color var(--dur), border-color var(--dur);
}
.auth-tab.active {
  background: var(--surface-2);
  color: var(--text-primary);
  border-color: var(--border-strong);
}
.auth-form input {
  width: 100%;
  padding: var(--space-3) var(--space-4);
  margin-bottom: var(--space-3);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface-1);
  color: var(--text-primary);
  font-size: var(--text-sm);
  font-family: inherit;
}
.auth-submit {
  width: 100%;
  min-height: var(--control-height);
  padding: 0 var(--space-4);
  border: none;
  border-radius: var(--radius-sm);
  background: var(--accent);
  color: #fff;
  font-family: inherit;
  font-weight: 600;
  font-size: var(--text-sm);
  cursor: pointer;
  transition: background-color var(--dur);
}
.auth-submit:hover { background: var(--accent-bright); }
.auth-submit { color: var(--accent-fg); }
#authUser {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
}
.auth-username {
  color: var(--text-primary);
  font-weight: 600;
}
.auth-logout {
  min-height: var(--control-height-sm);
  padding: 0 var(--space-3);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--text-muted);
  cursor: pointer;
  font-family: inherit;
  font-size: var(--text-sm);
  font-weight: 600;
  transition: background-color var(--dur), color var(--dur), border-color var(--dur);
}
.auth-logout:hover {
  background: var(--surface-2);
  color: var(--text-primary);
}
.auth-divider {
  height: 1px;
  background: var(--border-subtle);
}

/* ── Modal (blocking overlay) ──────────────────────────────── */
.modal[hidden] {
  display: none !important;
}
.modal {
  position: fixed;
  inset: 0;
  z-index: var(--z-modal);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-4);
}
.modal__backdrop {
  position: absolute;
  inset: 0;
  background: rgba(2, 4, 12, 0.85);
  -webkit-backdrop-filter: blur(10px); /* Safari still needs the prefix */
  backdrop-filter: blur(10px);
}
.modal__dialog {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  width: min(100%, 520px);
  max-height: min(90vh, 680px);
  overflow: hidden;
  background: var(--surface-1);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-modal);
}
/* For modals holding option grids or editors — narrow dialogs cramp them */
.modal__dialog--wide {
  width: min(100%, 760px);
}
.modal__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-4) var(--space-6);
  border-bottom: 1px solid var(--border-subtle);
}
.modal__header h2 {
  font-size: var(--text-lg);
  font-weight: 600;
  color: var(--text-primary);
}
.modal__body {
  padding: var(--space-6);
  overflow: auto;
  font-size: var(--text-sm);
  color: var(--text-secondary);
  line-height: 1.55;
}
.modal__body code {
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace;
  font-size: 0.9em;
  color: var(--text-primary);
}
.modal__footer {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: var(--space-2);
  padding: var(--space-4) var(--space-6);
  border-top: 1px solid var(--border-subtle);
}

/* ── Card ──────────────────────────────────────────────────── */
/*
 * GOTCHA: backdrop-filter creates a stacking context — dropdowns inside
 * a card can be clipped by a later card's stacking context. Fix by adding
 * position: relative; z-index: 10 to the card that owns the open dropdown.
 *
 * Default: static surface (no hover lift — avoids generic “dashboard demo”).
 * Use .card--interactive for raised hover + entrance motion.
 *
 * GOTCHA: a <button> or <a> used AS a card does not inherit body text color —
 * buttons default to canvas text (near-black), rendering invisible on the dark
 * bg. When a card is an interactive element, set color: var(--text-primary)
 * and font-family: var(--font) explicitly on it.
 */
.card {
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-6);
  margin-bottom: var(--space-6);
  backdrop-filter: blur(10px);
  transition: border-color var(--dur), box-shadow var(--dur);
}
.card:hover {
  border-color: var(--border-strong);
  box-shadow: 0 8px 20px rgba(15, 23, 42, 0.45);
}
.card--interactive {
  transition:
    transform var(--dur) ease-out,
    box-shadow var(--dur) ease-out,
    border-color var(--dur);
  animation: fadeIn 0.35s ease-out both;
}
.card--interactive:hover {
  transform: translateY(-3px);
  box-shadow: var(--shadow-card);
  border-color: var(--border-strong);
}
.card--enter {
  animation: fadeIn 0.35s ease-out both;
}
.card--flat:hover {
  box-shadow: none;
}
/* Card with an action row, in an equal-height grid: pin the toolbar to the
   bottom so buttons align across cards whose text wraps differently. */
.card--actions {
  display: flex;
  flex-direction: column;
}
.card--actions > .toolbar:last-child {
  margin-top: auto;
}

/* ── Button press feedback ─────────────────────────────────── */
button:active,
.btn:active,
.nav-link:active,
.auth-toggle:active,
.auth-tab:active,
.auth-submit:active,
.auth-logout:active {
  transform: scale(0.98);
  transition-duration: var(--dur-fast);
}

@keyframes fadeIn {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* ── Skeleton loading ──────────────────────────────────────── */
@keyframes shimmer { to { background-position: -200% 0; } }
.skeleton {
  background: linear-gradient(90deg, var(--surface-1) 25%, var(--surface-2) 50%, var(--surface-1) 75%);
  background-size: 200% 100%;
  animation: shimmer 1.5s ease-in-out infinite;
  border-radius: var(--radius);
}

/* ── Toast ─────────────────────────────────────────────────── */
.toast {
  position: fixed;
  bottom: var(--space-6);
  right: var(--space-6);
  z-index: var(--z-toast);
  max-width: min(360px, calc(100vw - var(--space-8)));
  background: var(--surface-toast);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: var(--space-3) var(--space-4);
  font-size: var(--text-sm);
  color: var(--text-primary);
  box-shadow: var(--shadow-card);
  pointer-events: none;
  transform: translateY(8px);
  opacity: 0;
  transition: opacity 0.2s ease-out, transform 0.2s ease-out;
}
.toast.visible {
  opacity: 1;
  transform: translateY(0);
}

/* ── Footer ────────────────────────────────────────────────────
   Owned by the Neorgon Footer Kit (css/neorgon-footer.css).
   Don't add .neo-footer rules here — edit packages/neorgon-ui/footer/
   and re-run sync-footer.sh. */

/* ── Focus styles ──────────────────────────────────────────── */
:focus-visible {
  outline: 2px solid var(--accent-bright);
  outline-offset: 2px;
}

/* ── Skip link ─────────────────────────────────────────────── */
.skip-link {
  position: absolute;
  top: 0;
  left: var(--space-4);
  z-index: 1000;
  padding: var(--space-2) var(--space-4);
  background: var(--accent-bright);
  color: #000;
  font-weight: 600;
  font-size: var(--text-sm);
  border-radius: 0 0 var(--radius-sm) var(--radius-sm);
  text-decoration: none;
  /* transform, not `top`: animating a layout property forces reflow. */
  transform: translateY(-200%);
  transition: transform var(--dur) var(--ease-out);
}
.skip-link:focus { transform: translateY(0); }

/* ── Reduced motion ────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
  .card--interactive:hover { transform: none; }
}

/* ── Responsive ────────────────────────────────────────────── */
@media (max-width: 600px) {
  .container { padding: var(--space-4); }
  .toast {
    left: var(--space-4);
    right: var(--space-4);
    max-width: none;
  }
}

/* ══════════════════════════════════════════════════════════════
   Boardwright
   A drafting surface, not a document: the workspace owns the
   viewport and each pane scrolls inside itself.
   ══════════════════════════════════════════════════════════════ */

.container { max-width: 1080px; }
main#main { min-height: 0; overflow: hidden; }

/* The app owns the viewport at desk widths. `min-height` alone leaves body's
   height auto, so main's flex:1 resolves against its own content and the
   document scrolls instead of the pane. A definite height fixes main to the
   viewport and hands the scrolling to .scroll-pane / .rail / .inspector.
   Below the stacking breakpoint the document scrolls on purpose, so the lock
   is scoped to the wide layout. */
@media (min-width: 981px) {
  body { height: 100dvh; overflow: hidden; }
}

/* ── View tabs ─────────────────────────────────────────────── */
.viewtabs {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  padding: 0 var(--space-4);
  border-bottom: 1px solid var(--border-subtle);
  background: rgba(255, 255, 255, 0.02);
  flex: 0 0 auto;
  overflow-x: auto;
  scrollbar-width: none;
}
.viewtabs::-webkit-scrollbar { display: none; }
.viewtabs-spacer { flex: 1; }

.viewtab {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-4);
  border: none;
  background: transparent;
  color: var(--text-muted);
  font-family: inherit;
  font-size: var(--text-sm);
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
  transition: color var(--dur);
}
.viewtab:hover { color: var(--text-secondary); }
.viewtab.is-active { color: var(--text-primary); }
.viewtab.is-active::after {
  content: '';
  position: absolute;
  left: var(--space-3);
  right: var(--space-3);
  bottom: -1px;
  height: 2px;
  background: var(--accent-bright);
  border-radius: 2px 2px 0 0;
}
.tab-count {
  min-width: 18px;
  padding: 0 5px;
  border-radius: 9px;
  background: var(--surface-2);
  color: var(--text-secondary);
  font-size: 11px;
  line-height: 18px;
  text-align: center;
}
.tab-count--blocked {
  background: rgba(225, 29, 72, 0.22);
  color: var(--danger-soft);
}
.doc-name {
  padding-right: var(--space-2);
  color: var(--text-muted);
  font-size: var(--text-xs);
  max-width: 30ch;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ── View shell ────────────────────────────────────────────── */
.view { flex: 1; min-height: 0; }
.view.is-active { display: flex; flex-direction: column; }
.scroll-pane { flex: 1; min-height: 0; overflow-y: auto; }
.scroll-pane .container { padding-block: var(--space-6) var(--space-8); }

.workspace {
  flex: 1;
  min-height: 0;
  display: grid;
  grid-template-columns: 232px minmax(0, 1fr) 312px;
}

/* ── Rails ─────────────────────────────────────────────────── */
.rail {
  min-height: 0;
  overflow-y: auto;
  padding: var(--space-4);
  border-right: 1px solid var(--border-subtle);
  background: rgba(255, 255, 255, 0.015);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.rail-head { display: flex; flex-direction: column; gap: var(--space-1); }
.rail-title {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.rail-badge {
  min-width: 18px;
  padding: 0 5px;
  border-radius: 9px;
  background: var(--surface-2);
  color: var(--text-secondary);
  font-size: 11px;
  line-height: 17px;
  text-align: center;
  letter-spacing: 0;
}
.rail-hint {
  font-size: var(--text-xs);
  line-height: 1.5;
  color: var(--text-muted);
}
.rail-list { list-style: none; display: flex; flex-direction: column; gap: 2px; }
.rail-empty {
  padding: var(--space-3);
  border: 1px dashed var(--border);
  border-radius: var(--radius-sm);
  font-size: var(--text-xs);
  line-height: 1.5;
  color: var(--text-muted);
}
.rail-item { --hue: 200; }
.rail-item-btn {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  width: 100%;
  padding: var(--space-2) var(--space-2);
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--text-secondary);
  font-family: inherit;
  font-size: var(--text-sm);
  text-align: left;
  cursor: pointer;
  transition: background-color var(--dur), color var(--dur);
}
.rail-item-btn:hover { background: var(--surface-2); color: var(--text-primary); }
.rail-item.is-on .rail-item-btn {
  background: var(--surface-2);
  border-color: var(--border-strong);
  color: var(--text-primary);
}
.rail-swatch {
  width: 10px;
  height: 10px;
  flex: 0 0 auto;
  border-radius: 3px;
  background: hsl(var(--hue) 70% 55%);
}
.rail-item-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rail-item-sub {
  margin-left: auto;
  flex: 0 0 auto;
  font-size: 11px;
  color: var(--text-muted);
}

.kind-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-1);
}
.kind-btn {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 7px 8px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface-1);
  color: var(--text-secondary);
  font-family: inherit;
  font-size: var(--text-xs);
  cursor: pointer;
  transition: background-color var(--dur), border-color var(--dur), color var(--dur);
}
.kind-btn:hover:not(:disabled) {
  background: var(--surface-2);
  border-color: var(--border-strong);
  color: var(--text-primary);
}
.kind-btn:disabled { opacity: 0.4; cursor: not-allowed; }
.kind-btn--plain { justify-content: center; }
.kind-swatch {
  width: 8px;
  height: 8px;
  flex: 0 0 auto;
  border-radius: 2px;
  background: hsl(var(--hue) 70% 55%);
}
.kind-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ── Stage ─────────────────────────────────────────────────── */
.stage-wrap {
  min-width: 0;
  min-height: 0;
  display: flex;
  flex-direction: column;
}
.stage-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--border-subtle);
}
.stage-note { font-size: var(--text-xs); color: var(--text-muted); }
/* `margin: auto` on the child, not justify/align-content: a flex item larger
   than a centering container gets its overflow clipped at the start edge. */
.stage-scroll {
  flex: 1;
  min-height: 0;
  overflow: auto;
  display: flex;
  padding: var(--space-4);
}
.stage-scroll > * { margin: auto; }

.mini-field {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: var(--text-xs);
  color: var(--text-muted);
}
.mini-field input {
  width: 68px;
  padding: 5px 6px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface-1);
  color: var(--text-primary);
  font-family: inherit;
  font-size: var(--text-xs);
}
.mini-field .times { opacity: 0.6; }
.check {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  /* The label is the hit area, so it carries the 24px target minimum
     (WCAG 2.5.8) that a bare 13px checkbox would fail. */
  min-height: 24px;
  padding: 0 4px;
  font-size: var(--text-xs);
  color: var(--text-muted);
  cursor: pointer;
}
.check input { accent-color: var(--accent-bright); }

/* The board itself — a drafting surface, so it reads as ruled paper. */
.stage {
  position: relative;
  flex: 0 0 auto;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background:
    linear-gradient(to right, rgba(255, 255, 255, 0.045) 1px, transparent 1px) 0 0 / var(--grid, 50px) var(--grid, 50px),
    linear-gradient(to bottom, rgba(255, 255, 255, 0.045) 1px, transparent 1px) 0 0 / var(--grid, 50px) var(--grid, 50px),
    #080c18;
  box-shadow: 0 18px 46px rgba(2, 6, 23, 0.55);
  touch-action: none;
}
.stage:focus-visible { outline: 2px solid var(--accent-bright); outline-offset: 3px; }

.zone {
  --hue: 200;
  position: absolute;
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: 9px 11px;
  border: 1.5px solid hsl(var(--hue) 72% 62% / 0.8);
  border-radius: 9px;
  background: hsl(var(--hue) 70% 52% / 0.15);
  cursor: grab;
  overflow: hidden;
  transition: box-shadow var(--dur), border-color var(--dur);
}
.zone:hover { border-color: hsl(var(--hue) 78% 70% / 0.95); }
.zone.is-selected {
  border-color: var(--accent-bright);
  box-shadow: 0 0 0 1px var(--accent-bright), 0 10px 26px rgba(0, 0, 0, 0.45);
  z-index: 5;
}
.zone:active { cursor: grabbing; }
.zone-name {
  font-size: 13px;
  font-weight: 600;
  color: #fff;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.zone-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 6px;
  font-size: 11px;
  color: hsl(var(--hue) 60% 84% / 0.92);
  overflow: hidden;
}
.zone-tag {
  padding: 0 5px;
  border-radius: 3px;
  background: hsl(var(--hue) 60% 60% / 0.25);
}
.zone-dot::before { content: '· '; opacity: 0.5; }

/* A track 90 units tall renders ~25px high. Two lines will not fit, so the
   metadata goes and the name keeps the room. */
.zone--short { padding: 4px 8px; justify-content: center; }
.zone--short .zone-meta { display: none; }
.zone--tiny .zone-name { font-size: 11px; }

/* Resize grips — quiet until the rect is hovered or selected. */
.grip {
  position: absolute;
  width: 10px;
  height: 10px;
  border: 1px solid rgba(255, 255, 255, 0.7);
  border-radius: 2px;
  background: var(--accent-bright);
  opacity: 0;
  transition: opacity var(--dur);
}
.zone:hover .grip,
.zone.is-selected .grip,
.slot:hover .grip,
.slot.is-selected .grip { opacity: 1; }
.grip--nw { top: -5px; left: -5px; cursor: nwse-resize; }
.grip--n  { top: -5px; left: calc(50% - 5px); cursor: ns-resize; }
.grip--ne { top: -5px; right: -5px; cursor: nesw-resize; }
.grip--w  { top: calc(50% - 5px); left: -5px; cursor: ew-resize; }
.grip--e  { top: calc(50% - 5px); right: -5px; cursor: ew-resize; }
.grip--sw { bottom: -5px; left: -5px; cursor: nesw-resize; }
.grip--s  { bottom: -5px; left: calc(50% - 5px); cursor: ns-resize; }
.grip--se { bottom: -5px; right: -5px; cursor: nwse-resize; }

/* ── Card face ─────────────────────────────────────────────── */
.cardface {
  position: relative;
  flex: 0 0 auto;
  background: var(--card-stock);
  box-shadow: 0 20px 50px rgba(2, 6, 23, 0.6);
  touch-action: none;
}
.cardface.is-empty {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 264px;
  height: 370px;
  border: 1px dashed var(--border-strong);
  border-radius: var(--radius);
  background: transparent;
  box-shadow: none;
}
.stage-empty {
  padding: var(--space-4);
  font-size: var(--text-sm);
  color: var(--text-muted);
  text-align: center;
}

.slot {
  position: absolute;
  display: flex;
  align-items: center;
  padding: 2px 4px;
  border: 1.5px dashed transparent;
  border-radius: 3px;
  /* Inherit the face's ink so a slot stays readable when the deck is
     repainted; a hardcoded near-black vanished on the dark decks. */
  color: var(--ink, var(--card-ink));
  cursor: grab;
  overflow: hidden;
}
/* The dashed guide is an editor affordance for an empty slot. A slot that
   draws its own plate does not need one, and it muddied the plate's edge. */
.slot.shape-none.fill-none { border-color: var(--card-rule); }
.slot.shape-none.fill-none:hover { border-color: rgba(30, 40, 70, 0.6); }
.slot.is-selected {
  border-style: solid;
  border-color: var(--card-pick);
  box-shadow: 0 0 0 1px var(--card-pick);
  z-index: 5;
}
.slot:active { cursor: grabbing; }
.slot[data-align="center"] { justify-content: center; text-align: center; }
.slot[data-align="right"] { justify-content: flex-end; text-align: right; }
.slot-text {
  font-weight: 600;
  line-height: 1.2;
  overflow: hidden;
}
.slot--sm .slot-text { font-size: 9px; }
.slot--md .slot-text { font-size: 12px; }
.slot--lg .slot-text { font-size: 17px; }
.slot--xl .slot-text { font-size: 36px; letter-spacing: -0.02em; }
.slot--paragraph .slot-text { font-weight: 400; }
.slot--art, .slot--icon {
  justify-content: center;
  background:
    repeating-linear-gradient(45deg, rgba(30, 40, 70, 0.06) 0 6px, transparent 6px 12px);
}
.slot-ph {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: rgba(30, 40, 70, 0.55);
}
.slot--badge.shape-none { background: rgba(30, 40, 70, 0.08); border-radius: 20px; }

/* ── Card face furniture ───────────────────────────────────────
   The oval and the corner wedges belong to the template, not to any
   slot: every card in a deck shares them, so drawing them per slot is
   how the deck drifts out of alignment. */
.face-column { display: flex; flex-direction: column; align-items: center; gap: var(--space-3); }

.face-oval {
  position: absolute;
  inset: 4% 7%;
  border-style: solid;
  border-color: var(--ink, #15161c);
  border-radius: 50%;
  pointer-events: none;
}
.face-wedge {
  position: absolute;
  width: 22%;
  aspect-ratio: 1;
  background: var(--ink, #15161c);
  pointer-events: none;
}
.face-wedge--tl { top: 0; left: 0; border-bottom-right-radius: 100%; }
.face-wedge--tr { top: 0; right: 0; border-bottom-left-radius: 100%; }
.face-wedge--bl { bottom: 0; left: 0; border-top-right-radius: 100%; }
.face-wedge--br { bottom: 0; right: 0; border-top-left-radius: 100%; }

/* A slot's own plate. `wedge` takes its curve from which corner it sits in,
   so a badge dragged across the card re-orients itself. */
.slot.shape-box    { border-radius: 3px; }
.slot.shape-pill   { border-radius: 999px; }
.slot.shape-circle { border-radius: 50%; }
.slot.shape-wedge  { border-radius: 0; }
.slot.shape-wedge[data-corner="tl"] { border-bottom-right-radius: 100%; }
.slot.shape-wedge[data-corner="tr"] { border-bottom-left-radius: 100%; }
.slot.shape-wedge[data-corner="bl"] { border-top-right-radius: 100%; }
.slot.shape-wedge[data-corner="br"] { border-top-left-radius: 100%; }

.slot.fill-ink    { background: var(--ink, #15161c); }
.slot.fill-face   { background: var(--face, #fbf8f2); }
.slot.fill-accent { background: var(--card-accent, #7c3aed); }
.slot.is-invert   { color: var(--face, #fbf8f2); }
.slot.fill-face.is-invert { color: var(--ink, #15161c); }

.slot-icon {
  width: 100%;
  height: 100%;
  display: block;
  overflow: visible;
}

/* ── Deck colour swatches ──────────────────────────────────── */
.variant-strip {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-2);
  max-width: 320px;
}
.swatch {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 26px;
  padding: 3px 10px 3px 5px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: transparent;
  font-family: inherit;
  font-size: 11px;
  cursor: pointer;
  transition: border-color var(--dur);
}
.swatch:hover { border-color: var(--border-strong); }
.swatch.is-on { border-color: var(--accent-bright); }
/* The dot carries the deck colour and the label stays in UI ink. Filling the
   whole pill put the label on its own deck colour, which is exactly the
   contrast problem the readiness check exists to catch. */
.swatch-dot {
  width: 14px;
  height: 14px;
  flex: 0 0 auto;
  border-radius: 50%;
  background: currentColor;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.35);
}
.swatch-name { color: var(--text-secondary); }
.swatch:hover .swatch-name,
.swatch.is-on .swatch-name { color: var(--text-primary); }

.variant-block { display: flex; flex-direction: column; gap: var(--space-2); }
.variant-head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); }
.variant-row {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--space-2);
  padding: var(--space-2);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-sm);
}
.variant-row > .form-field, .variant-row > .form-group { flex: 1 1 96px; min-width: 0; }

.color-field { display: flex; align-items: center; gap: 5px; min-width: 0; }
.color-swatch {
  width: 30px;
  height: 30px;
  flex: 0 0 auto;
  padding: 0;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background: transparent;
  cursor: pointer;
}
.color-swatch::-webkit-color-swatch-wrapper { padding: 2px; }
.color-swatch::-webkit-color-swatch { border: none; border-radius: 3px; }
.color-hex { min-width: 0; font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 12px; }
.slot.is-selected::after {
  content: attr(data-label);
  position: absolute;
  top: -15px;
  left: -1px;
  padding: 1px 5px;
  border-radius: 3px 3px 0 0;
  background: var(--card-pick);
  color: #fff;
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  white-space: nowrap;
}

/* ── Inspector ─────────────────────────────────────────────── */
.inspector {
  min-height: 0;
  overflow-y: auto;
  padding: var(--space-4);
  border-left: 1px solid var(--border-subtle);
  background: rgba(255, 255, 255, 0.015);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.inspector-title {
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.inspector-empty {
  font-size: var(--text-xs);
  line-height: 1.6;
  color: var(--text-muted);
}
.inspector-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  padding-bottom: var(--space-2);
  border-bottom: 1px solid var(--border-subtle);
}

/* ── Forms ─────────────────────────────────────────────────── */
.form-field {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}
.form-field--inline {
  flex-direction: row;
  align-items: center;
  gap: 7px;
  /* The label is the hit area for its checkbox; 24px minimum target. */
  min-height: 24px;
}
.form-label {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--text-muted);
}
.form-input {
  width: 100%;
  min-width: 0;
  padding: 7px 9px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface-1);
  color: var(--text-primary);
  font-family: inherit;
  font-size: var(--text-sm);
  transition: border-color var(--dur);
}
.form-input:hover { border-color: var(--border-strong); }
textarea.form-input { resize: vertical; line-height: 1.5; }
select.form-input { cursor: pointer; }
.form-input--inline { width: auto; }
.form-check { width: 15px; height: 15px; accent-color: var(--accent-bright); cursor: pointer; }
.form-hint {
  font-size: 11px;
  line-height: 1.45;
  color: var(--text-muted);
}
.form-group { display: flex; flex-direction: column; gap: 4px; }
.form-group-label {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--text-muted);
}
.form-row {
  display: flex;
  gap: var(--space-2);
}
.form-row > .form-field { flex: 1; }
.form-row .form-label { font-size: 10px; }

.chips { display: flex; flex-wrap: wrap; gap: 4px; }
.chip {
  padding: 4px 9px;
  border: 1px solid var(--border);
  border-radius: 20px;
  background: transparent;
  color: var(--text-muted);
  font-family: inherit;
  font-size: 11px;
  cursor: pointer;
  transition: background-color var(--dur), color var(--dur), border-color var(--dur);
}
.chip:hover { border-color: var(--border-strong); color: var(--text-secondary); }
.chip.is-on {
  background: color-mix(in oklab, var(--accent) 26%, transparent);
  border-color: var(--accent-bright);
  color: var(--text-primary);
}

/* ── Panels and list rows (Rules, Check, Export) ────────────── */
.panel {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-5);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--surface-1);
}
.panel-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
}
.panel-title {
  font-size: var(--text-lg);
  font-weight: 600;
  color: var(--text-primary);
}
.panel-hint {
  margin-top: calc(var(--space-3) * -1 + 2px);
  font-size: var(--text-xs);
  line-height: 1.55;
  color: var(--text-muted);
  max-width: 68ch;
}
.panel-body { display: flex; flex-direction: column; gap: var(--space-3); }
.panel-empty {
  padding: var(--space-4);
  border: 1px dashed var(--border);
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
  color: var(--text-muted);
}

/* Flex, not grid: the delete button must stay button-sized, and a grid
   track would stretch it to a full column. */
.list-row {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--space-3);
  padding: var(--space-3);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-sm);
  background: rgba(255, 255, 255, 0.015);
}
.list-row > .form-field,
.list-row > .form-group { flex: 1 1 150px; min-width: 0; }
.list-row--wide > .form-field,
.list-row--wide > .form-group { flex: 1 1 128px; }
.list-row > .form-field--inline {
  flex: 0 0 auto;
  align-self: center;
  padding-bottom: 8px;
}
.icon-del {
  flex: 0 0 auto;
  align-self: flex-end;
  min-width: 34px;
  min-height: 34px;
  padding: 0;
  color: var(--text-muted);
  border-color: var(--border);
}
.icon-del:hover { color: var(--danger-hover); border-color: var(--danger); background: rgba(225, 29, 72, 0.1); }

.order-btns {
  display: flex;
  flex: 0 0 auto;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  align-self: center;
}
.order-btn {
  width: 26px;
  height: 24px;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: transparent;
  color: var(--text-muted);
  font-size: 11px;
  line-height: 1;
  cursor: pointer;
}
.order-btn:hover:not(:disabled) { background: var(--surface-2); color: var(--text-primary); }
.order-btn:disabled { opacity: 0.3; cursor: not-allowed; }
.order-index { font-size: 11px; color: var(--text-muted); }

/* ── Check ─────────────────────────────────────────────────── */
/* Status reads from the surface tint and the marker above the title, not
   from a coloured stripe down one edge. */
.verdict {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-5);
  border: 1px solid var(--status);
  border-radius: var(--radius-lg);
  background: color-mix(in oklab, var(--status) 9%, var(--surface-1));
}
.verdict--clear   { --status: var(--accent-bright); }
.verdict--warn    { --status: var(--warn); }
.verdict--blocked { --status: var(--danger-hover); }
.verdict-title {
  font-size: var(--text-xl);
  font-weight: 600;
}
.verdict-title::before {
  content: '';
  display: inline-block;
  width: 9px;
  height: 9px;
  margin-right: var(--space-2);
  border-radius: 50%;
  background: var(--status);
  vertical-align: 0.12em;
}
.verdict-line { font-size: var(--text-sm); line-height: 1.6; color: var(--text-secondary); max-width: 70ch; }

.finding {
  display: flex;
  flex-direction: column;
  gap: 5px;
  padding: var(--space-4);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-sm);
  background: rgba(255, 255, 255, 0.015);
}
.finding-top { display: flex; align-items: baseline; gap: var(--space-2); flex-wrap: wrap; }
.finding-where {
  padding: 1px 7px;
  border-radius: 20px;
  background: var(--surface-2);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.finding--blocker .finding-where { background: rgba(225, 29, 72, 0.18); color: var(--danger-soft); }
.finding-title { font-size: var(--text-base); font-weight: 600; color: var(--text-primary); }
.finding-detail { font-size: var(--text-sm); line-height: 1.6; color: var(--text-secondary); max-width: 74ch; }
/* The question is the payload of a finding, so it gets its own inset surface
   rather than an accent rule down its left edge. */
.finding-q {
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  background: color-mix(in oklab, var(--accent) 14%, transparent);
  font-size: var(--text-sm);
  font-style: italic;
  color: var(--text-primary);
}

/* A finding is the control that takes you to the thing it is about, so it
   needs the affordances of one: pointer, hover, focus ring. */
.finding--go {
  width: 100%;
  /* A button used as a card inherits neither the page's text colour nor its
     font: the UA hands it canvas text, which is near-black on this background.
     The gotcha is called out at the top of this file; setting both here is the
     fix it prescribes. */
  color: var(--text-primary);
  font-family: var(--font);
  text-align: left;
  cursor: pointer;
  transition: border-color var(--dur), background-color var(--dur);
}
.finding--go:hover {
  border-color: var(--border-strong);
  background: var(--surface-2);
}
.finding-go {
  margin-left: auto;
  flex: 0 0 auto;
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--accent-bright);
  opacity: 0;
  transition: opacity var(--dur);
}
.finding--go:hover .finding-go,
.finding--go:focus-visible .finding-go { opacity: 1; }

/* Landing marker after a jump. Outline rather than a colour change, so it
   does not read as a state the element is now in. */
@keyframes flashRing {
  from { box-shadow: 0 0 0 2px var(--accent-bright), 0 0 0 7px color-mix(in oklab, var(--accent) 34%, transparent); }
  to   { box-shadow: 0 0 0 2px transparent, 0 0 0 7px transparent; }
}
.is-flash {
  animation: flashRing 1.5s var(--ease-out) both;
  border-radius: var(--radius-sm);
}

/* ── Align controls ────────────────────────────────────────── */
.align-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 4px;
}
.align-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 30px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface-1);
  color: var(--text-muted);
  cursor: pointer;
  transition: background-color var(--dur), color var(--dur), border-color var(--dur);
}
.align-btn:hover {
  background: var(--surface-2);
  border-color: var(--border-strong);
  color: var(--text-primary);
}
.align-btn svg { width: 17px; height: 17px; }

/* ── Keyboard sheet ────────────────────────────────────────── */
.keys-group + .keys-group {
  margin-top: var(--space-6);
  padding-top: var(--space-4);
  border-top: 1px solid var(--border-subtle);
}
.keys-group-title {
  margin-bottom: var(--space-2);
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.keys-list {
  display: grid;
  grid-template-columns: max-content 1fr;
  align-items: baseline;
  gap: var(--space-2) var(--space-4);
}
.keys-combo { display: flex; align-items: center; gap: 3px; }
.keys-plus { font-size: 10px; color: var(--text-muted); }
.keys-list kbd {
  display: inline-block;
  min-width: 22px;
  padding: 2px 6px;
  border: 1px solid var(--border-strong);
  border-bottom-width: 2px;
  border-radius: 4px;
  background: var(--surface-2);
  font-family: inherit;
  font-size: 11px;
  font-weight: 600;
  line-height: 1.4;
  text-align: center;
  color: var(--text-primary);
}
.keys-label { font-size: var(--text-sm); color: var(--text-secondary); }

/* Empty states carry the action, not just the diagnosis. */
.rail-empty { display: flex; flex-direction: column; gap: var(--space-3); align-items: flex-start; }
.rail-empty p { font-size: var(--text-xs); line-height: 1.5; color: var(--text-muted); }
.panel-empty { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3); }
.panel-empty p { margin: 0; flex: 1 1 260px; }

/* ── Export ────────────────────────────────────────────────── */
.manifest { list-style: none; display: flex; flex-direction: column; gap: 2px; }
.manifest-row {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-3);
  padding: 7px var(--space-3);
  border-radius: var(--radius-sm);
  background: rgba(255, 255, 255, 0.02);
}
.manifest-name {
  flex: 0 0 auto;
  min-width: 15ch;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: var(--text-xs);
  color: var(--accent-bright);
}
.manifest-what { font-size: var(--text-xs); color: var(--text-muted); }
.toolbar--gap { gap: var(--space-3); }

.brief-preview {
  max-height: 460px;
  overflow: auto;
  padding: var(--space-4);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-sm);
  background: #070b16;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 12px;
  line-height: 1.65;
  color: var(--text-secondary);
  white-space: pre-wrap;
  word-break: break-word;
  tab-size: 2;
}

/* ── Responsive ────────────────────────────────────────────── */
@media (max-width: 1180px) {
  .workspace { grid-template-columns: 208px minmax(0, 1fr) 280px; }
}
@media (max-width: 980px) {
  /* Below this the three columns stop being readable side by side, so the
     stage takes the width and the rails become stacked sections. */
  main#main { overflow: auto; }
  .view.is-active { min-height: auto; }
  .workspace {
    grid-template-columns: 1fr;
    min-height: auto;
  }
  .stage-wrap { order: -1; }
  /* The rails become ordinary stacked sections, but the stage keeps its own
     scroller: a board wider than a phone must pan inside its pane, never
     push the page sideways. */
  .rail, .inspector { overflow: visible; }
  .stage-scroll {
    height: 58vh;
    padding: var(--space-3);
    overflow: auto;
  }
  .rail, .inspector {
    border: none;
    border-top: 1px solid var(--border-subtle);
  }
  .kind-grid { grid-template-columns: repeat(auto-fit, minmax(110px, 1fr)); }
  .scroll-pane { overflow: visible; }
}
