  /* ─── tokens ─────────────────────────────────────────────── */
  /* Design tokens now come from /css/tokens.css (the shared
   * ketchup-site-design package, vendored into frontend/css/ and linked
   * above). They used to be an inline :root block here, which drifted:
   * this file called them --fg/--line/--error while every other studio
   * site called the same values --text/--border/--danger. No build step
   * was added, these are plain <link> tags. */

  /* Box-sizing, body base, ::selection, :focus/:focus-visible, scrollbar,
   * and prefers-reduced-motion come from ketchup-base in tokens.css.
   * Only sortof-specific overrides live here. */
  html, body { margin: 0; padding: 0; }
  body {
    font-size: 16px;
    font-feature-settings: "ss01", "cv11";
  }
  .shell { position: relative; }

  /* Screen-reader-only text / live regions: not in the shared package. */
  .visually-hidden {
    position: absolute;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
  }

  a {
    color: var(--info);
    text-decoration: underline;
    text-decoration-thickness: 1px;
    text-underline-offset: 2px;
  }
  a:hover { color: var(--text); text-decoration-thickness: 2px; }

  /* ─── header / footer ─── */
  .shell {
    min-height: 100vh;
    display: grid;
    grid-template-rows: auto 1fr auto;
  }
  /* --header-h is the studio-wide bar height. The banner scales to fit it;
   * the bar does not grow to fit the banner. See ketchup-site-design
   * DESIGN.md section 6. */
  header.app {
    border-bottom: 1px solid var(--border);
    padding-inline: var(--page-padding);
    height: var(--header-h);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
  }
  .brand-mark-link {
    display: inline-flex;
    align-items: center;
    gap: 12px;
    text-decoration: none;
    min-width: 0;
  }
  .brand-mark-link:hover { background: transparent; }
  /* Sized against the 50px banner rather than the studio's standard 14x28,
     which is calibrated for a 15px Sora wordmark. Same mark, same 33:64
     ratio, scaled to this header's own type. */
  .brand-icon {
    height: 34px;
    width: auto;
    display: block;
    flex-shrink: 0;
    transition: opacity .18s var(--ease-out);
  }
  .brand-mark-link:hover .brand-icon { opacity: 0.88; }
  .brand-banner {
    height: 42px;
    width: auto;
    max-width: 380px;
    object-fit: contain;
    display: block;
    transition: opacity .18s var(--ease-out);
  }
  .brand-mark-link:hover .brand-banner { opacity: 0.88; }
  .brand-logo {
    display: flex;
    align-items: center;
    gap: 12px;
    text-decoration: none;
    color: var(--text);
    min-width: 0;
  }
  .brand-logo:hover { background: transparent; }
  .brand-logo-wordmark {
    font-family: var(--font-display);
    font-weight: 600;
    font-size: 22px;
    letter-spacing: -0.02em;
    line-height: 1;
    color: var(--text);
  }
  .brand-logo-wordmark .dot { color: var(--brand); }
  /* The two studio credits are .brand-footer-credit / .org-footer-credit from
   * components.css now, so the local .footer-link-brand/-org and .org-badge
   * rules that used to build them here are gone. This one stays: the "based
   * on" attribution is sortof's own link, not a studio credit. */
  .footer-link             { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 2px; }
  .footer-link-info        { color: var(--info); }
  .footer-link-info:hover  { color: var(--text); }
  /* Tagline ("sorted. sort of.") in --fg-muted, italic per brief. */
  .tagline {
    font-family: var(--font-display);
    font-style: italic;
    font-size: 12px;
    color: var(--text-muted);
    line-height: 1;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  .head-right {
    display: flex;
    align-items: center;
    gap: 4px;
  }
  /* Header chrome links (github, docs). Per brief: --fg-muted in Sora 400,
   * underline on hover only. */
  .icon-btn {
    appearance: none;
    border: 1px solid transparent;
    background: transparent;
    color: var(--text-muted);
    height: 32px;
    padding: 0 12px;
    border-radius: var(--radius-panel);
    font-family: var(--font-display);
    font-weight: 400;
    font-size: 13px;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    text-decoration: none;
    transition: color .15s var(--ease-out), background .15s var(--ease-out);
  }
  .icon-btn:hover {
    color: var(--text);
    background: var(--bg-elevated);
  }
  .icon-btn svg { width: 14px; height: 14px; opacity: .85; }
  /* Header CTA: distinct accent so the report-broken-mod button reads as an
   * action, not a docs/github link. Hover ramps to filled brand color. */
  .icon-btn.report {
    color: var(--brand);
    border: 1px solid var(--brand);
    background: transparent;
    cursor: pointer;
    font-family: var(--font-mono);
    transition: background .15s var(--ease-out), color .15s var(--ease-out), transform .1s var(--ease-out);
  }
  .icon-btn.report:hover {
    background: var(--brand);
    color: var(--brand-ink);
    border-color: var(--brand);
    text-decoration: none;
  }
  .icon-btn.report:active,
  .icon-btn:active { transform: scale(0.96); }
  /* Jump links under the status strip: how-it-works / faq anchors below the
   * fold, plus a wiki help link. Compact, bordered, same family as icon-btn. */
  .jump-links {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 10px;
  }
  .jump-link {
    appearance: none;
    height: 28px;
    padding: 0 10px;
    border: 1px solid var(--border);
    background: transparent;
    color: var(--text-muted);
    border-radius: var(--radius-panel);
    font-family: var(--font-mono);
    font-size: 12px;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    text-decoration: none;
    transition: color .15s var(--ease-out), background .15s var(--ease-out), border-color .15s var(--ease-out);
  }
  .jump-link:hover {
    color: var(--text);
    background: var(--bg-elevated);
    border-color: var(--text-muted);
  }
  .jump-link:active { transform: scale(0.96); }

  /* ── Help modal ──────────────────────────────────────────────────────── */
  .modal-overlay {
    position: fixed;
    inset: 0;
    background: color-mix(in srgb, var(--bg) 82%, transparent);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 1000;
    padding: 24px;
  }
  .modal-box {
    background: var(--bg-surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-panel);
    box-shadow: var(--shadow-card);
    padding: 28px 32px 32px;
    max-width: 680px;
    width: 100%;
    max-height: 90vh;
    overflow-y: auto;
    position: relative;
  }
  .modal-close {
    position: absolute;
    top: 14px;
    right: 16px;
    appearance: none;
    background: none;
    border: none;
    color: var(--text-muted);
    font-size: 16px;
    cursor: pointer;
    padding: 4px 8px;
    border-radius: var(--radius-xs);
    line-height: 1;
    transition: color .12s;
  }
  .modal-close:hover { color: var(--text); }
  .modal-title {
    font-family: var(--font-mono);
    font-size: 15px;
    font-weight: 600;
    color: var(--text);
    margin: 0 0 20px;
  }
  .help-steps {
    margin: 0;
    padding: 0;
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: 24px;
    counter-reset: help-step;
  }
  .help-steps li {
    counter-increment: help-step;
    display: flex;
    flex-direction: column;
    gap: 10px;
    font-size: 14px;
    color: var(--text-muted);
  }
  .help-steps li::before {
    content: counter(help-step);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    background: var(--bg-elevated);
    border: 1px solid var(--border);
    border-radius: 50%;
    font-family: var(--font-mono);
    font-size: 11px;
    font-weight: 600;
    color: var(--text);
    flex-shrink: 0;
  }
  .help-steps strong { color: var(--text); }
  .help-steps code {
    font-family: var(--font-mono);
    font-size: 12px;
    background: var(--bg-elevated);
    padding: 1px 5px;
    border-radius: 3px;
    color: var(--info);
  }
  .help-screenshot {
    width: 100%;
    border-radius: var(--radius-md);
    border: 1px solid var(--border);
    display: block;
  }
  .modal-footnote {
    margin: 20px 0 0;
    padding-top: 16px;
    border-top: 1px solid var(--border);
    font-size: 13px;
    color: var(--text-muted);
  }

  /* ── First-visit onboarding hint ─────────────────────────────────────── */
  .onboarding-hint {
    background: var(--bg-elevated);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    padding: 10px 14px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    flex-wrap: wrap;
    font-size: 13px;
  }
  .onboarding-steps {
    display: flex;
    align-items: center;
    gap: 6px;
    flex-wrap: wrap;
    color: var(--text-muted);
    font-family: var(--font-mono);
    font-size: 12px;
  }
  .onboarding-sep { color: var(--border); }
  .onboarding-actions {
    display: flex;
    gap: 8px;
    align-items: center;
    flex-shrink: 0;
  }
  .onboarding-help {
    appearance: none;
    background: none;
    border: 1px solid var(--border);
    color: var(--text-muted);
    font-family: var(--font-display);
    font-size: 12px;
    padding: 3px 10px;
    border-radius: var(--radius-xs);
    cursor: pointer;
    transition: color .12s, border-color .12s;
  }
  .onboarding-help:hover { color: var(--text); border-color: var(--text-muted); }
  .onboarding-dismiss {
    appearance: none;
    background: none;
    border: none;
    color: var(--text-muted);
    font-family: var(--font-display);
    font-size: 12px;
    padding: 3px 6px;
    cursor: pointer;
    text-decoration: underline;
    text-underline-offset: 2px;
    transition: color .12s;
  }
  .onboarding-dismiss:hover { color: var(--text); }

  /* ── Reported broken mods view ─────────────────────────────────────── */
  .reports-panel {
    display: block;
    max-width: 1100px;
    margin: 16px auto;
    padding: 0 16px;
  }
  .reports-head {
    background: var(--bg-elevated);
    border: 1px solid var(--border);
    border-radius: var(--radius-panel);
    padding: 16px 20px;
    margin-bottom: 16px;
  }
  .reports-title {
    font-family: var(--font-display);
    font-size: 22px;
    color: var(--text);
    margin-bottom: 4px;
  }
  .reports-blurb {
    font-family: var(--font-mono);
    font-size: 12px;
    color: var(--text-muted);
    margin-bottom: 12px;
    line-height: 1.5;
  }
  .reports-form {
    display: flex;
    gap: 8px;
    align-items: stretch;
    flex-wrap: wrap;
    margin-bottom: 8px;
  }
  .reports-form .field {
    flex: 1 1 220px;
    min-height: 36px;
    font-family: var(--font-mono);
    font-size: 13px;
  }
  .reports-form select.field { flex: 0 0 auto; min-width: 240px; }
  .reports-form .sort-btn { flex: 0 0 auto; min-width: 120px; }
  .reports-error {
    color: var(--danger);
    font-family: var(--font-mono);
    font-size: 12px;
    margin-bottom: 8px;
  }
  .reports-search { width: 100%; margin-top: 4px; }
  .reports-meta {
    font-family: var(--font-mono);
    font-size: 11.5px;
    color: var(--text-muted);
    margin-top: 8px;
  }
  .reports-list {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 6px;
  }
  .reports-empty {
    font-family: var(--font-mono);
    font-size: 13px;
    color: var(--text-muted);
    padding: 24px 16px;
    text-align: center;
    border: 1px dashed var(--border);
    border-radius: var(--radius-md);
  }
  /* Each row is a 6-cell grid: name | wsid | version | date | up | down.
   * Wraps cleanly on narrow viewports - the votes column stays right-anchored. */
  .report-row {
    display: grid;
    grid-template-columns: minmax(0, 1.6fr) 110px 130px 150px auto auto;
    align-items: center;
    gap: 10px;
    padding: 10px 14px;
    background: var(--bg-surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-panel);
    font-family: var(--font-mono);
    font-size: 13px;
  }
  .report-row:hover { border-color: var(--border); }
  .report-name {
    color: var(--text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .report-wsid { color: var(--text-muted); font-size: 12px; }
  .report-ver .ver-pill {
    background: var(--bg-surface);
    color: var(--text-muted);
    border: 1px solid var(--border);
    padding: 2px 8px;
    border-radius: 3px;
    font-size: 11.5px;
    white-space: nowrap;
  }
  .report-date { color: var(--text-muted); font-size: 12px; white-space: nowrap; }
  .report-votes {
    display: inline-flex;
    gap: 6px;
    align-items: center;
  }
  .vote-btn {
    appearance: none;
    border: 1px solid var(--border);
    background: transparent;
    color: var(--text-muted);
    font-family: var(--font-mono);
    font-size: 12px;
    padding: 4px 10px;
    border-radius: var(--radius-md);
    cursor: pointer;
    transition: color .12s, background .12s, border-color .12s;
    min-width: 54px;
  }
  .vote-btn.up:hover:not([disabled])   { color: var(--success); border-color: var(--success); }
  .vote-btn.down:hover:not([disabled]) { color: var(--danger); border-color: var(--danger); }
  .vote-btn.up.voted   { color: var(--success); border-color: var(--success); background: var(--success-bg); }
  .vote-btn.down.voted { color: var(--danger); border-color: var(--danger); background: var(--danger-bg); }
  .vote-btn[disabled]:not(.voted) { opacity: 0.45; cursor: not-allowed; }
  @media (max-width: 720px) {
    .report-row {
      grid-template-columns: 1fr 1fr;
    }
    .report-name { grid-column: 1 / -1; }
    .report-votes { justify-content: flex-end; }
  }

  footer.app {
    border-top: 1px solid var(--border);
    padding: var(--footer-pad-y) var(--page-padding);
    display: flex;
    flex-wrap: wrap;
    gap: 8px 24px;
    align-items: center;
    justify-content: space-between;
    color: var(--text-muted);
    font-size: 13.5px;
    font-family: var(--font-mono);
  }
  footer.app .left, footer.app .right {
    display: flex; flex-wrap: wrap; gap: 4px 16px; align-items: center;
  }

  /* ─── main grid ─── */
  main.app {
    padding: var(--section-y) var(--page-padding) clamp(40px, 6vw, 64px);
    display: flex;
    flex-direction: column;
    gap: 28px;
    max-width: 1480px;
    width: 100%;
    margin: 0 auto;
  }
  /* main-content (input + results) stacks with the rail on mobile via
   * display:contents, then becomes its own two-column grid on desktop so
   * the rail can dock hard right as a fixed-width flex sibling. */
  .main-content {
    display: contents;
  }
  /* Desktop: input+results grow to fill the freed space (wider, more
   * centered), the info rail becomes a fixed-width column hard against the
   * right edge, separated by a small gap plus a hairline divider. */
  @media (min-width: 1024px) {
    main.app {
      flex-direction: row;
      align-items: flex-start;
      gap: 20px;
      max-width: 1700px;
    }
    .main-content {
      display: grid;
      grid-template-columns: minmax(300px, 4fr) minmax(0, 6fr);
      gap: 28px;
      flex: 1 1 auto;
      min-width: 0;
    }
    .info-rail {
      flex: 0 0 300px;
      border-left: 1px solid var(--border);
      padding-left: 20px;
    }
  }
  @media (min-width: 1400px) {
    main.app {
      gap: 24px;
      max-width: 1900px;
    }
    .main-content {
      grid-template-columns: minmax(340px, 4fr) minmax(0, 6fr);
      gap: 32px;
    }
    .info-rail {
      flex: 0 0 320px;
      padding-left: 24px;
    }
  }

  .col {
    display: flex;
    flex-direction: column;
    gap: 20px;
    min-width: 0;
  }

  /* ─── shared bits ─── */
  .label-row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 6px;
  }
  .label {
    font-family: var(--font-mono);
    font-size: 12px;
    text-transform: lowercase;
    letter-spacing: 0.02em;
    color: var(--text-muted);
  }
  .label-meta {
    font-family: var(--font-mono);
    font-size: 11.5px;
    color: var(--text-muted);
  }

  /* field: base definition in components.css. Sortof-specific overlays only. */
  textarea.field, input.field { resize: vertical; }
  textarea.field:focus-visible, input.field:focus-visible {
    outline: 2px solid var(--info);
    outline-offset: 2px;
  }

  .input-main { min-height: 220px; }
  .input-rules { min-height: 110px; }

  details.collapsible > summary {
    list-style: none;
    cursor: pointer;
    font-family: var(--font-mono);
    font-size: 12px;
    font-weight: 600;
    color: var(--text);
    user-select: none;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 6px 14px;
    border: 1px solid var(--border);
    background: var(--bg-surface);
    border-radius: var(--radius-md);
    transition: color .15s var(--ease-out), border-color .15s var(--ease-out), background .15s var(--ease-out);
  }
  details.collapsible > summary::-webkit-details-marker { display: none; }
  details.collapsible > summary::before {
    content: "▸";
    color: var(--info);
    font-size: 12px;
    transition: transform .12s;
    display: inline-block;
    width: 9px;
  }
  details.collapsible[open] > summary::before { transform: rotate(90deg); }
  details.collapsible > summary:hover {
    color: var(--info);
    border-color: var(--info);
    background: var(--info-bg);
  }
  details.collapsible[open] > summary { margin-bottom: 8px; }

  /* ── Buttons ───────────────────────────────────────────────── */

  /* sort-btn: mapped to .btn.btn-primary in task 4.1.
   * Full definition in components.css; sortof-specific overlays only. */
  .sort-btn { width: 100%; }
  .sort-btn.sort-pending {
    box-shadow: inset 0 0 0 1.5px var(--info), var(--shadow-panel);
    animation: sort-pending-pulse 2s var(--ease-in-out) infinite;
  }
  @keyframes sort-pending-pulse {
    0%, 100% { box-shadow: inset 0 0 0 1.5px var(--info), var(--shadow-panel); }
    50%      { box-shadow: inset 0 0 0 3px var(--info), 0 2px 12px color-mix(in srgb, var(--info) 25%, transparent), var(--shadow-panel); }
  }
  .sort-btn[disabled] {
    cursor: not-allowed;
    background: var(--bg-surface);
    color: var(--text-muted);
    box-shadow: none;
    border: 1px solid var(--border);
    transform: none;
  }
  .sort-btn .btn-glyph { font-size: 11px; line-height: 1; display: inline-block; min-width: 11px; text-align: center; }
  .sort-btn .spin {
    width: 12px; height: 12px;
    border: 1.5px solid currentColor;
    border-top-color: transparent;
    border-radius: 50%;
    animation: sp 0.7s linear infinite;
  }
  @keyframes sp { to { transform: rotate(360deg); } }

  /* clear-btn: mapped to .btn.btn-secondary in task 4.1. No local overlay needed. */

  /* ── Phase 2: entry & stagger animations ──────────────────── */

  /* Fade-up entrance for output blocks. Applied via JSX class toggle on mount.
   * The element starts invisible and fades up into place. No scale(0); Emil
   * Kowalski rule: nothing appears from nothing. */
  @keyframes fadeUp {
    from { opacity: 0; transform: translateY(12px); }
    to   { opacity: 1; transform: translateY(0); }
  }
  @keyframes fadeIn {
    from { opacity: 0; }
    to   { opacity: 1; }
  }

  /* Output blocks stagger in when they appear. The JSX assigns these classes
   * in order so children of .stagger-group animate one after another. */
  .stagger-group > .stagger-item {
    opacity: 1; /* visible by default, animation only on first mount */
  }
  .stagger-group.stagger-enter > .stagger-item {
    animation: fadeUp 0.35s var(--ease-out) both;
  }
  .stagger-group.stagger-enter > .stagger-item:nth-child(1) { animation-delay: 0ms; }
  .stagger-group.stagger-enter > .stagger-item:nth-child(2) { animation-delay: 60ms; }
  .stagger-group.stagger-enter > .stagger-item:nth-child(3) { animation-delay: 120ms; }
  .stagger-group.stagger-enter > .stagger-item:nth-child(4) { animation-delay: 180ms; }

  /* Entry animation for the output column itself (right column). When sort
   * results arrive, the entire column fades in subtly. */
  .col-results-enter {
    animation: fadeIn 0.25s var(--ease-out);
  }

  /* Universal button press physics: all interactive elements get a subtle
   * scale-down on :active for tactile feedback. Applied via the :active
   * pseudo-class so no JSX changes needed. Individual button styles above
   * (sort-btn, clear-btn, copy-btn, icon-btn) each have their own :active
   * transform that overrides this base. */
  button:active:not(:disabled),
  .warn-action:active,
  .vote-btn:active:not(:disabled),
  .branch-affordance:active,
  .diff-toggle:active,
  .auto-fix-btn:active,
  .warn-branch-btn:active,
  .build-toggle-btn:active {
    transform: scale(0.97);
  }

  /* Smooth collapse/expand for warnings and collapsible sections. The JSX
   * controls height via a wrapper, but the transition on the list itself
   * makes the open/close feel intentional. */
  .warn-list, .branch-panel-inner {
    transition: opacity .15s var(--ease-out);
  }

  /* status strip */
  .status-strip {
    display: flex; flex-wrap: wrap; align-items: center;
    gap: 4px 12px;
    font-family: var(--font-mono);
    font-size: 11.5px;
    color: var(--text-muted);
    padding: 8px 0 0;
    min-height: 24px;
  }
  .status-pill {
    display: inline-flex; align-items: center; gap: 6px;
  }
  /* Glyph carries the state semantically (paired with a text label). The
   * color reinforces the same meaning for sighted-but-not-CVD users. The
   * old dot-led is preserved as a generic class for legacy callers; new
   * pills use status-glyph. */
  .status-glyph {
    display: inline-block;
    min-width: 12px;
    text-align: center;
    font-weight: 600;
    line-height: 1;
  }
  .dot-led {
    width: 6px; height: 6px; border-radius: 50%;
    background: var(--text-faint);
  }
  /* State pill colors - explicit (color × glyph × label) per brief mapping.
   * Each state gets a distinct hue from the Okabe-Ito palette so no two
   * states collapse to the same color under deuteranopia/protanopia. */
  .status-pill.idle      { color: var(--text-muted); }
  .status-pill.done      { color: var(--success); }
  .status-pill.queued    { color: var(--info); }
  .status-pill.queued    .status-glyph { animation: bl 1.2s ease-in-out infinite; }
  .status-pill.working,
  .status-pill.draining  { color: var(--info); }
  .status-pill.working   .status-glyph,
  .status-pill.draining  .status-glyph { animation: bl 1.2s ease-in-out infinite; }
  .status-pill.warning   { color: var(--warning); }
  .status-pill.failed    { color: var(--danger); }
  .status-pill.muted     { color: var(--text-muted); }
  /* Legacy classes (still referenced by some pills + callers) - alias to the
   * new state colors so old code keeps working. */
  .status-pill.cached    { color: var(--success); }
  .status-pill.parse     { color: var(--info); }
  .status-pill.parse     .status-glyph { animation: bl 1.2s ease-in-out infinite; }
  .status-pill.unknown   { color: var(--danger); }
  .status-pill.nonmod    { color: var(--text-muted); }
  .status-pill.expanding { color: var(--info); }
  .status-pill.expanding .status-glyph { animation: bl 1.2s ease-in-out infinite; }
  /* Dot-led background recolor (legacy callers) */
  .status-pill.done      .dot-led,
  .status-pill.cached    .dot-led { background: var(--success); }
  .status-pill.queued    .dot-led,
  .status-pill.working   .dot-led,
  .status-pill.draining  .dot-led,
  .status-pill.parse     .dot-led,
  .status-pill.expanding .dot-led { background: var(--info); animation: bl 1.2s ease-in-out infinite; }
  .status-pill.warning   .dot-led { background: var(--warning); }
  .status-pill.failed    .dot-led,
  .status-pill.unknown   .dot-led { background: var(--danger); }
  .status-pill.muted     .dot-led,
  .status-pill.nonmod    .dot-led { background: var(--text-muted); }

  .cancel-btn {
    appearance: none;
    border: 1px solid var(--border);
    background: transparent;
    color: var(--text-muted);
    border-radius: var(--radius-panel);
    font-family: var(--font-mono);
    font-size: 12px;
    cursor: pointer;
    transition: color .15s var(--ease-out), border-color .15s var(--ease-out), background .15s var(--ease-out), transform .1s var(--ease-out);
  }
  .cancel-btn:hover { color: var(--danger); border-color: var(--danger); background: var(--danger-bg); }
  .cancel-btn:active { transform: scale(0.97); }
  @keyframes bl { 0%, 100% { opacity: 0.35; } 50% { opacity: 1; } }
  .progress-bar {
    flex: 1 1 100%;
    height: 2px;
    background: var(--bg-surface);
    border-radius: 1px;
    overflow: hidden;
    margin-top: 4px;
  }
  .progress-bar > i {
    display: block;
    height: 100%;
    background: var(--info);
    transform-origin: left;
    transition: transform .35s ease;
  }

  /* card / section panels - shadow defines the container, not a hard border.
   * The 1px border is replaced by subtle background differentiation against
   * the atmosphere layer. Interactive children (warn-head, tbl-head) handle
   * their own hover states with background tint alone. */
  /* panel: base in components.css. Sortof needs border:none and overflow:hidden
   * for full-bleed warn-head/tbl-head rows inside the radius clip. */
  .panel {
    border: 0;
    overflow: hidden;
  }

  /* code-block: base in components.css. Sortof overlays for pre body only. */
  .code-block pre {
    color: var(--text);
    white-space: pre-wrap;
    word-break: break-all;
    min-height: 44px;
  }

  .copy-btn {
    appearance: none;
    border: 1px solid var(--info);
    background: var(--info-bg);
    color: var(--info);
    height: 28px;
    padding: 0 12px;
    border-radius: 6px;
    font-family: var(--font-mono);
    font-size: 12px;
    font-weight: 600;
    cursor: pointer;
    display: inline-flex; align-items: center; gap: 6px;
    transition: color .15s var(--ease-out), background .15s var(--ease-out), border-color .15s var(--ease-out), transform .1s var(--ease-out);
  }
  .copy-btn:hover { color: var(--brand-ink); background: var(--info); border-color: var(--info); }
  .copy-btn:active { transform: scale(0.97); }
  .copy-btn.copied { color: var(--success); border-color: var(--success); background: var(--success-bg); }
  .copy-btn.copied:hover { color: var(--brand-ink); background: var(--success); }
  .copy-btn svg { width: 11px; height: 11px; }
  .share-btn { border-color: var(--brand); color: var(--brand); }
  .share-btn:hover { color: var(--brand-ink); background: var(--brand); border-color: var(--brand); }

  /* Spec H: share banner */
  .share-banner {
    display: flex; align-items: center; gap: 8px;
    padding: 8px 10px; margin-bottom: 10px;
    background: var(--info-bg); border: 1px solid var(--info); border-radius: 6px;
    font-size: 12.5px;
  }
  .share-banner-text { flex: 1; color: var(--info); }
  .share-banner-close {
    background: none; border: none; color: var(--text-muted); cursor: pointer;
    font-size: 14px; line-height: 1; padding: 2px 4px;
  }
  .share-banner-close:hover { color: var(--text); }

  /* multi-branch picker (Spec A) */
  .branch-affordance {
    appearance: none;
    border: 1px solid var(--border);
    background: transparent;
    color: var(--info);
    font-family: var(--font-mono);
    font-size: 12px;
    padding: 1px 6px;
    border-radius: 3px;
    cursor: pointer;
  }
  .branch-affordance:hover { color: var(--text); border-color: var(--border); background: var(--bg-surface); }

  .branch-panel {
    background: var(--bg-surface);
    border-top: 1px dashed var(--border);
    border-bottom: 1px dashed var(--border);
    padding: 0;
  }
  .branch-panel-inner {
    padding: 8px 12px 10px;
    font-family: var(--font-mono);
    font-size: 12px;
  }
  .branch-panel-meta { color: var(--text-muted); margin-bottom: 6px; letter-spacing: 0.04em; }

  .branch-row {
    display: grid;
    grid-template-columns: 18px 220px 1fr 70px 1fr 60px;
    gap: 10px 10px;
    align-items: center;
    padding: 4px 0;
    border-top: 1px solid var(--border);
    cursor: pointer;
  }
  .branch-row:hover { background: var(--bg-surface); }
  /* Picked row: --info per brief, not the brand green (status, not brand). */
  .branch-row.is-checked .branch-modid { color: var(--info); font-weight: 600; }
  .branch-input { accent-color: var(--info); }
  .branch-modid { color: var(--text); }
  .branch-name  { color: var(--text-muted); }
  .branch-deps  { color: var(--text-muted); font-size: 11.5px; }
  .branch-pos   { color: var(--text-muted); font-size: 11.5px; text-align: right; }
  /* Spec C §4.6 D/G hint text: italic line under the mod_id row. */
  .branch-hint  {
    grid-column: 2 / -1;
    color: var(--warning);
    font-size: 11.5px;
    font-style: italic;
    margin-top: -2px;
    padding-bottom: 2px;
  }

  /* diff panel (Spec follow-up: show what changed since last sort) */
  .diff-toggle-row { display: flex; justify-content: flex-end; padding: 4px 0 2px; }
  .diff-toggle {
    appearance: none;
    border: 1px solid var(--border);
    background: transparent;
    color: var(--text-muted);
    font-family: var(--font-mono);
    font-size: 12px;
    font-weight: 600;
    padding: 3px 10px;
    border-radius: var(--radius-md);
    cursor: pointer;
    transition: color .12s, border-color .12s, background .12s;
  }
  .diff-toggle:hover:not(:disabled) {
    color: var(--info);
    border-color: var(--info);
    background: var(--info-bg);
  }
  .diff-toggle.open {
    color: var(--info);
    border-color: var(--info);
    background: var(--info-bg);
  }
  .diff-toggle:disabled { opacity: 0.4; cursor: not-allowed; }
  .diff-panel {
    border: 1px solid var(--border);
    background: var(--bg-surface);
    border-radius: var(--radius-panel);
    padding: 12px 16px;
    margin: 4px 0 12px;
    font-family: var(--font-mono);
    font-size: 12px;
  }
  .diff-head {
    display: flex; align-items: center; gap: 10px;
    padding-bottom: 8px; border-bottom: 1px solid var(--border);
    margin-bottom: 8px;
  }
  .diff-title { color: var(--text); font-weight: 600; }
  .diff-summary { display: flex; gap: 6px; margin-left: auto; }
  .diff-stat { padding: 1px 6px; border-radius: 3px; font-weight: 600; }
  .diff-stat.add { color: var(--success); background: var(--success-bg); }
  .diff-stat.rm  { color: var(--danger);   background: var(--danger-bg); }
  .diff-stat.mv  { color: var(--warning); background: var(--warning-bg); }
  .diff-close {
    appearance: none;
    border: 1px solid var(--border);
    background: transparent;
    color: var(--text-muted);
    font-family: var(--font-mono);
    font-size: 11.5px;
    padding: 2px 8px;
    border-radius: 4px;
    cursor: pointer;
  }
  .diff-close:hover { color: var(--text); border-color: var(--border); }
  .diff-section { padding: 6px 0; }
  .diff-label { color: var(--text-muted); font-size: 11.5px; text-transform: uppercase; letter-spacing: .04em; padding-bottom: 4px; }
  .diff-row {
    padding: 2px 0; display: flex; gap: 8px; align-items: baseline;
    color: var(--text);
  }
  .diff-row.diff-add { color: var(--success); }
  .diff-row.diff-rm  { color: var(--danger);   }
  .diff-row.diff-mv  { color: var(--warning); }
  .diff-arrow { width: 10px; text-align: center; }
  .diff-pos   { color: var(--text-muted); font-size: 11.5px; margin-left: auto; }
  .diff-empty { color: var(--text-muted); font-style: italic; padding: 6px 0; }
  .diff-more  { color: var(--text-muted); font-size: 11.5px; padding: 4px 0; }

  /* build toggle (B41 / B42) */
  .build-toggle {
    display: inline-flex; align-items: center; gap: 8px;
    padding: 4px 0 8px;
    font-family: var(--font-mono);
    font-size: 11.5px;
    color: var(--text-muted);
  }
  .build-toggle-label { letter-spacing: .04em; text-transform: lowercase; }
  .build-toggle-btn {
    appearance: none;
    border: 1px solid var(--border);
    background: var(--bg-surface);
    color: var(--text-muted);
    height: 24px;
    min-height: 24px;
    padding: 0 9px;
    border-radius: 4px;
    font-family: var(--font-mono);
    font-size: 11.5px;
    cursor: pointer;
    transition: color .12s, background .12s, border-color .12s;
  }
  .build-toggle-btn:hover { color: var(--text); border-color: var(--border); background: var(--bg-surface); }
  .build-toggle-btn.is-active {
    color: var(--success);
    border-color: var(--success);
    background: var(--success-bg);
  }
  .cg-build { color: var(--text-muted); }
  /* Pre-paste build picker: sits at the top of the input column so the user
   * sets the target build BEFORE pasting wsids. Backend uses pz_build to
   * emit build-mismatch warnings on tagged mods that don't support it. */
  .build-prepick {
    display: flex; align-items: center; flex-wrap: wrap;
    gap: 10px; padding-bottom: 6px;
  }
  .build-prepick .build-toggle { padding: 0; }
  .build-prepick-hint {
    font-family: var(--font-mono);
    font-size: 11.5px;
    color: var(--text-muted);
  }

  /* warnings */
  .warn-section .warn-head {
    display: flex; align-items: center; gap: 8px;
    font-family: var(--font-mono);
    font-size: 11.5px;
    cursor: pointer;
    user-select: none;
    color: var(--text);
    padding: 10px 12px;
  }
  .warn-section .warn-head .warn-count {
    display: inline-flex; align-items: center; justify-content: center;
    min-width: 18px; height: 18px; padding: 0 6px;
    border-radius: 9px;
    font-size: 11.5px;
    font-weight: 600;
    background: var(--warning-bg);
    color: var(--warning);
    border: 1px solid var(--warning);
  }
  .warn-section .warn-head .warn-count.red {
    background: var(--danger-bg);
    color: var(--danger);
    border-color: var(--danger);
  }
  .warn-section .warn-head .chev {
    margin-left: auto;
    color: var(--text-muted);
    font-size: 10px;
  }
  .warn-list {
    list-style: none;
    margin: 0;
    padding: 0;
    border-top: 1px solid var(--border);
  }
  .warn-list li {
    display: grid;
    grid-template-columns: 80px 1fr;
    gap: 12px;
    padding: 10px 12px;
    font-family: var(--font-mono);
    font-size: 12px;
    border-bottom: 1px solid var(--border);
  }
  .warn-list li:last-child { border-bottom: 0; }
  .warn-list .w-tag {
    color: var(--text-muted);
    font-size: 11.5px;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    padding-top: 1px;
  }
  /* Tag-label colours mirror the row's primary action button (set per-warning
     by warnAccent in the JSX): amber=branches, red=remove, blue=add,
     green=swap. */
  .warn-list .w-tag.amber { color: var(--warning); }
  .warn-list .w-tag.red { color: var(--danger); }
  .warn-list .w-tag.blue { color: var(--info); }
  .warn-list .w-tag.green { color: var(--success); }
  .warn-list .w-tag.info { color: var(--text-muted); }
  .switch-build-banner {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    padding: 10px 14px;
    background: color-mix(in oklch, var(--warning) 10%, var(--bg-surface));
    border: 1px solid color-mix(in oklch, var(--warning) 35%, transparent);
    border-radius: 6px;
    margin-bottom: 6px;
  }
  .switch-build-msg {
    flex: 1 1 0;
    font-size: 13px;
    color: var(--text);
    line-height: 1.4;
  }
  .switch-build-btn {
    flex-shrink: 0;
    padding: 5px 13px;
    font-size: 13px;
    font-weight: 600;
    background: var(--warning);
    color: var(--bg);
    border: none;
    border-radius: 4px;
    cursor: pointer;
    white-space: nowrap;
  }
  .switch-build-btn:hover { filter: brightness(1.12); }
  .switch-build-btn:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
  .warn-info-sub { border-top: 1px solid var(--border); }
  .warn-info-toggle {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 7px 14px;
    font-size: 12px;
    color: var(--text-muted);
    cursor: pointer;
    user-select: none;
  }
  .warn-info-toggle:hover { color: var(--text); }
  .warn-info-toggle:focus-visible { outline: 2px solid var(--brand); outline-offset: -2px; }
  .warn-head.warn-head-info { cursor: pointer; }
  .warn-head.warn-head-info:hover { background: var(--bg-elevated); }
  .warn-list .w-content {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px 8px;
    line-height: 1.55;
  }
  /* Message takes the full row so every action button wraps onto the line(s)
     below it, left-aligned - consistent placement regardless of message
     length (short messages no longer keep their button inline on the right). */
  .warn-list .w-msg { color: var(--text); flex: 1 1 100%; }
  .warn-list .w-msg em { color: var(--info); font-style: normal; }
  .warn-action {
    appearance: none;
    border: 1px solid var(--info);
    background: var(--info-bg);
    color: var(--info);
    font-family: var(--font-mono);
    font-size: 12px;
    font-weight: 600;
    padding: 3px 10px;
    min-height: 24px;            /* WCAG 2.5.8 target size (24x24) */
    display: inline-flex;
    align-items: center;
    border-radius: var(--radius-md);
    cursor: pointer;
    transition: color .12s, border-color .12s, background .12s, transform .08s;
  }
  .warn-action:hover {
    background: var(--info);
    color: var(--brand-ink);
  }
  .warn-action:active { transform: translateY(1px); }
  .warn-action.expand {
    border-color: var(--warning);
    background: var(--warning-bg);
    color: var(--warning);
  }
  .warn-action.expand:hover {
    background: var(--warning);
    color: var(--brand-ink);
    border-color: var(--warning);
  }
  /* External-link variant: search Steam Workshop when we can't auto-add. */
  .warn-action.search {
    border-color: var(--border);
    background: transparent;
    color: var(--text-muted);
    text-decoration: none;
  }
  .warn-action.search:hover {
    color: var(--info);
    border-color: var(--info);
    background: var(--info-bg);
  }
  /* Swap variant: distinct accent (success/green) since swapping is a
   * deterministic resolution to a build-mismatch - strictly better than
   * leaving the wrong-build wsid in the input. */
  .warn-action.swap {
    border-color: var(--success);
    background: var(--success-bg);
    color: var(--success);
  }
  .warn-action.swap:hover {
    background: var(--success);
    color: var(--brand-ink);
  }
  /* Remove variant: error-toned. Destructive in user-perception (drops a
   * wsid from the input) but actually safer than leaving a wrong-build
   * mod in. Hover flips to filled so accidental clicks are loud. */
  .warn-action.remove {
    border-color: var(--danger);
    background: transparent;
    color: var(--danger);
  }
  .warn-action.remove:hover {
    background: var(--danger);
    color: var(--brand-ink);
    border-color: var(--danger);
  }
  .action-center {
    display: grid;
    gap: 8px;
    margin-bottom: 12px;
    padding: 14px;
    border: 1px solid var(--border);
    border-radius: var(--radius-panel);
    background: var(--bg-surface);
    box-shadow: var(--shadow-panel);
  }
  .action-center-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 16px;
    padding-bottom: 10px;
    border-bottom: 1px solid var(--border);
  }
  .action-center-kicker {
    color: var(--text-muted);
    font-family: var(--font-mono);
    font-size: 10px;
    font-weight: 600;
    letter-spacing: .08em;
    text-transform: uppercase;
  }
  .action-center h3 {
    margin: 2px 0 0;
    color: var(--text);
    font-size: 14px;
    line-height: 1.35;
  }
  .action-center-counts {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: 5px;
  }
  .action-center-counts span {
    padding: 2px 7px;
    border: 1px solid var(--border);
    border-radius: 999px;
    color: var(--text-muted);
    font-family: var(--font-mono);
    font-size: 10.5px;
    white-space: nowrap;
  }
  .action-center-counts .recommended { border-color: var(--info); color: var(--info); }
  .action-center-counts .decision { border-color: var(--warning); color: var(--warning); }
  .action-center-counts .failure { border-color: var(--danger); color: var(--danger); }
  .action-group {
    display: flex;
    align-items: center;
    gap: 10px;
    min-height: 38px;
    padding: 8px 10px;
    border-left: 2px solid var(--border);
    background: var(--bg-elevated);
    color: var(--text-muted);
    font-size: 12px;
  }
  .action-group strong {
    flex: 0 0 126px;
    color: var(--text);
    font-size: 12px;
  }
  .action-group.recommended { border-left-color: var(--info); }
  .action-group.decision { border-left-color: var(--warning); }
  .action-group.failure { border-left-color: var(--danger); }
  .action-group.information { border-left-color: var(--text-muted); }
  .action-group-copy {
    display: flex;
    flex: 1;
    align-items: baseline;
    gap: 10px;
  }
  .action-preview {
    color: var(--info);
    font-family: var(--font-mono);
    font-size: 11px;
  }
  .action-center-stage {
    appearance: none;
    margin-left: auto;
    padding: 7px 12px;
    border: 1px solid var(--info);
    border-radius: var(--radius-md);
    background: var(--info-bg);
    color: var(--info);
    cursor: pointer;
    font-family: var(--font-mono);
    font-size: 11.5px;
    font-weight: 600;
    transition: color .12s, background .12s, border-color .12s, transform .08s;
  }
  .action-center-stage:hover:not(:disabled) {
    background: var(--info);
    color: var(--brand-ink);
  }
  .action-center-stage:active:not(:disabled) { transform: translateY(1px); }
  .action-center-stage:disabled {
    border-color: var(--border);
    background: transparent;
    color: var(--text-muted);
    cursor: default;
  }
  @media (max-width: 640px) {
    .action-center-head,
    .action-group,
    .action-group-copy {
      align-items: flex-start;
      flex-direction: column;
    }
    .action-center-counts { justify-content: flex-start; }
    .action-group strong { flex-basis: auto; }
    .action-center-stage { margin-left: 0; }
  }

  /* Staged warning row: edit applied to input but not yet sorted. Subtle -
   * strike + dim - so the row stays readable but visibly "addressed". The
   * action button itself flips to the success palette via .warn-action.staged
   * to signal "click again to undo". */
  .warn-list li.staged .w-msg,
  .warn-list li.staged .w-tag {
    opacity: 0.55;
    text-decoration: line-through;
  }
  .warning-pending {
    display: inline-flex;
    width: max-content;
    margin-bottom: 4px;
    padding: 1px 6px;
    border: 1px solid var(--info);
    border-radius: 999px;
    color: var(--info);
    font-family: var(--font-mono);
    font-size: 10px;
    font-weight: 600;
    letter-spacing: .03em;
    text-decoration: none;
    text-transform: uppercase;
  }
  .warn-action.staged {
    border-color: var(--success);
    background: var(--success-bg);
    color: var(--success);
    opacity: 1;
    text-decoration: none;
  }
  .warn-action.staged:hover {
    background: var(--success);
    color: var(--brand-ink);
  }
  /* Inline mod-name hyperlink inside warning messages. Inherits the message
   * color so reading flow isn't disrupted; underline + brand color on hover
   * signals it's clickable. */
  .w-msg-link {
    color: inherit;
    text-decoration: none;
    text-decoration-thickness: 1px;
    text-underline-offset: 2px;
  }
  .w-msg-link:hover,
  .w-msg-link:focus-visible {
    color: var(--info);
    text-decoration: underline;
  }
  .w-msg-link::after {
    content: '↗';
    display: inline-block;
    margin-left: 2px;
    font-size: 10px;
    opacity: 0.5;
    text-decoration: none;
  }
  .w-msg-title-link {
    color: inherit;
    text-decoration: none;
    text-decoration-thickness: 1px;
    text-underline-offset: 2px;
  }
  .w-msg-title-link:hover,
  .w-msg-title-link:focus-visible {
    color: var(--info);
    text-decoration: underline;
  }
  .warn-branches {
    flex-basis: 100%;
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    margin-top: 4px;
  }
  .warn-branch-btn {
    appearance: none;
    border: 1px solid var(--border);
    background: transparent;
    color: var(--text-muted);
    font-family: var(--font-mono);
    font-size: 12px;
    padding: 2px 8px;
    min-height: 24px;            /* WCAG 2.5.8 target size (24x24) */
    display: inline-flex;
    align-items: center;
    border-radius: var(--radius-md);
    cursor: pointer;
    transition: color .12s, border-color .12s, background .12s;
  }
  .warn-branch-btn:hover {
    color: var(--warning);
    border-color: var(--warning);
  }
  .warn-branch-btn.picked {
    color: var(--success);
    border-color: var(--success);
    background: var(--success-bg);
    cursor: default;
  }

  /* mod details table */
  .table-section .tbl-head {
    display: flex; align-items: center; gap: 8px;
    font-family: var(--font-mono);
    font-size: 11.5px;
    cursor: pointer;
    user-select: none;
    color: var(--text);
    padding: 10px 12px;
  }
  .table-section .tbl-head .count {
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
  }
  .table-section .tbl-head .chev {
    margin-left: auto; color: var(--text-muted); font-size: 10px;
  }
  .mods-table {
    width: 100%;
    border-collapse: collapse;
    font-family: var(--font-mono);
    font-size: 12px;
    border-top: 1px solid var(--border);
  }
  .mods-table th, .mods-table td {
    padding: 10px 14px;
    text-align: left;
    border-bottom: 1px solid var(--border);
    vertical-align: top;
  }
  .mods-table th {
    background: var(--bg-surface);
    color: var(--text-muted);
    font-weight: 500;
    font-size: 11.5px;
    text-transform: uppercase;
    letter-spacing: 0.04em;
  }
  .mods-table tr:last-child td { border-bottom: 0; }
  .mods-table td.idx { color: var(--text-muted); width: 44px; font-variant-numeric: tabular-nums; padding-left: 6px; }
  .row-state-glyph {
    display: inline-block; min-width: 12px; margin-right: 6px;
    text-align: center; font-weight: 700;
  }
  /* Per-row state: color + left-border pattern + glyph (in idx cell). */
  .mod-row.mod-row-resolved   td:first-child { border-left: 3px solid var(--success); }
  .mod-row.mod-row-resolved   .row-state-glyph { color: var(--success); }
  .mod-row.mod-row-warning    td:first-child { border-left: 3px dotted var(--warning); }
  .mod-row.mod-row-warning    .row-state-glyph { color: var(--warning); }
  .mod-row.mod-row-unresolved td:first-child { border-left: 3px dashed var(--warning); }
  .mod-row.mod-row-unresolved .row-state-glyph { color: var(--warning); }
  .mod-row.mod-row-error      td:first-child { border-left: 3px solid var(--danger); }
  .mod-row.mod-row-error      .row-state-glyph { color: var(--danger); }
  .mods-table td .modid { color: var(--text); }
  .mods-table td .wsid { color: var(--text-muted); }
  /* The wsid cell is a deep-link to the Steam Workshop page. Inherit the
   * surrounding `.wsid` color so the row reads the same as before; only
   * an underline + brand color on hover signals it's clickable. */
  .wsid-link {
    color: inherit;
    text-decoration: none;
    text-decoration-thickness: 1px;
    text-underline-offset: 2px;
  }
  .wsid-link:hover,
  .wsid-link:focus-visible {
    color: var(--info);
    text-decoration: underline;
  }
  .mods-table td .cat {
    display: inline-block;
    padding: 1px 6px;
    border-radius: 3px;
    background: var(--bg-surface);
    color: var(--text);
    font-size: 11.5px;
  }
  .mods-table td .cat.map { background: var(--info-bg);    color: var(--info); }
  .mods-table td .cat.lib { background: var(--warning-bg); color: var(--warning); }
  /* Spec G-patch: patch pill - uses warning tone since patches load LAST and
   * may need attention. Distinct from .cat.lib (also warning-toned) by the
   * label text "patch" vs "lib" - color is reinforcement, not the carrier. */
  .mods-table td .cat.patch { background: var(--bg-surface); color: var(--text-muted); border: 1px solid var(--border); }
  .mods-table td .deps {
    color: var(--text-muted);
  }
  .mods-table td .pos {
    color: var(--text-muted);
    font-size: 11.5px;
  }
  .mods-table td .pos.first { color: var(--success); }
  .mods-table td .pos.last { color: var(--warning); }

  /* error banner */
  .err-banner {
    display: flex; align-items: flex-start; gap: 12px;
    padding: 14px 16px;
    background: var(--danger-bg);
    border: 1px solid var(--danger);
    border-radius: var(--radius-panel);
    font-family: var(--font-mono);
    font-size: 12px;
    color: var(--text);
  }
  .err-banner .err-tag {
    color: var(--danger);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    font-size: 11.5px;
    padding-top: 1px;
  }
  .err-banner .err-msg { flex: 1; line-height: 1.55; color: var(--text); }
  .err-banner .err-actions {
    display: flex; gap: 6px; margin-top: 8px;
  }

  /* cold-cache notice - matches the StatusStrip 'cold' pill (warning tone). */
  .cold-banner {
    display: flex; align-items: flex-start; gap: 12px;
    padding: 14px 16px;
    background: var(--warning-bg);
    border: 1px solid var(--warning);
    border-radius: var(--radius-panel);
    font-family: var(--font-mono);
    font-size: 12px;
  }
  .cold-banner .err-tag {
    color: var(--info);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    font-size: 11.5px;
    padding-top: 1px;
  }
  .cold-banner .err-msg { flex: 1; color: var(--text); line-height: 1.55; }

  /* empty-state docs panel - shadow-defined */
  .docs-panel {
    background: var(--bg-surface);
    border: 0;
    border-radius: var(--radius-panel);
    overflow: hidden;
    box-shadow: var(--shadow-panel);
  }
  .docs-panel .dp-head {
    padding: 12px 16px;
    border-bottom: 1px solid var(--border);
    font-family: var(--font-mono);
    font-size: 11.5px;
    color: var(--text);
    display: flex; align-items: center; justify-content: space-between;
  }
  .docs-panel .dp-body {
    padding: 14px 18px;
    font-family: var(--font-mono);
    font-size: 11.5px;
    color: var(--text);
    line-height: 1.7;
  }
  .docs-panel .dp-body ol {
    margin: 0; padding: 0 0 0 18px;
  }
  .docs-panel .dp-body li { margin-bottom: 4px; }
  .docs-panel .dp-body code {
    background: var(--bg-surface);
    color: var(--text);
    padding: 1px 5px;
    border-radius: 3px;
    font-size: 12px;
  }
  .docs-panel .dp-body .hint {
    color: var(--text-muted);
    font-size: 12px;
    margin-top: 8px;
    border-top: 1px dashed var(--border);
    padding-top: 8px;
  }

  /* empty/idle right-column placeholder - softer dashed treatment */
  .right-empty {
    border: 1px dashed var(--border);
    border-radius: var(--radius-panel);
    padding: 32px 24px;
    color: var(--text-muted);
    font-family: var(--font-mono);
    font-size: 12.5px;
    text-align: left;
    display: flex; flex-direction: column; gap: 12px;
    line-height: 1.6;
  }
  .right-empty .big {
    color: var(--text);
    font-size: 14px;
  }
  .right-empty .arrow {
    display: inline-block; margin-right: 8px; color: var(--success);
  }
  .right-empty .ex {
    background: var(--bg-surface);
    border: 1px solid var(--border);
    border-radius: 5px;
    padding: 8px 10px;
    color: var(--text);
    margin-top: 4px;
    font-size: 11.5px;
  }
  .right-empty .ex .ink-mut { color: var(--text-muted); }

  /* state label tweak - color + glyph + label per brief mapping. */
  .state-tag {
    display: inline-flex; align-items: center; gap: 6px;
    font-family: var(--font-mono); font-size: 12px;
    color: var(--text-muted);
    text-transform: lowercase;
  }
  .state-tag-glyph {
    display: inline-block; min-width: 12px; text-align: center;
    font-weight: 700; line-height: 1;
    color: var(--text-muted);
  }
  .state-tag.state-tag-idle    .state-tag-glyph { color: var(--text-muted); }
  .state-tag.state-tag-working  .state-tag-glyph,
  .state-tag.state-tag-queued   .state-tag-glyph,
  .state-tag.state-tag-draining .state-tag-glyph { color: var(--info); }
  .state-tag.state-tag-done     .state-tag-glyph { color: var(--success); }
  .state-tag.state-tag-warning  .state-tag-glyph { color: var(--warning); }
  .state-tag.state-tag-failed   .state-tag-glyph { color: var(--danger); }

  /* compact success treatment (variant b) - shadow-defined, no borders */
  .compact-grid {
    display: grid;
    grid-template-columns: 110px 1fr 28px;
    gap: 0;
    background: var(--bg-surface);
    border-radius: var(--radius-panel);
    overflow: hidden;
    box-shadow: var(--shadow-panel);
  }
  .compact-grid .cg-row {
    display: grid;
    grid-column: 1 / -1;
    grid-template-columns: subgrid;
  }
  .compact-grid .cg-row {
    display: grid;
    grid-column: 1 / -1;
    grid-template-columns: 110px 1fr 28px;
  }
  .compact-grid .cg-row > * {
    border-bottom: 1px solid var(--border);
    padding: 14px 16px;
  }
  .compact-grid .cg-row:last-child > * { border-bottom: 0; }
  .compact-grid .cg-key {
    font-family: var(--font-mono);
    font-size: 12px;
    color: var(--text-muted);
    background: var(--bg-surface);
    border-right: 1px solid transparent;
    text-transform: lowercase;
    letter-spacing: 0.02em;
    align-self: stretch;
  }
  .compact-grid .cg-val {
    font-family: var(--font-mono);
    font-size: 12.5px;
    color: var(--text);
    word-break: break-all;
    overflow-x: auto;
    line-height: 1.5;
  }
  .compact-grid .cg-cp {
    border-right: 0;
    background: var(--bg-surface);
    display: flex; align-items: center; justify-content: center;
    padding: 0;
    cursor: pointer;
    color: var(--text-muted);
    transition: color .15s var(--ease-out), background .15s var(--ease-out);
  }
  .compact-grid .cg-cp:hover { color: var(--text); background: var(--bg-surface); }
  .compact-grid .cg-cp.copied { color: var(--success); }
  .compact-grid .cg-cp svg { width: 12px; height: 12px; }

  /* numbered/labeled treatment (variant c) - shadow-defined */
  .numbered-block {
    background: var(--bg-surface);
    border: 0;
    border-radius: var(--radius-panel);
    padding: 16px 20px 14px;
    position: relative;
    font-family: var(--font-mono);
    box-shadow: var(--shadow-panel);
  }
  .numbered-block .nb-head {
    display: flex; align-items: baseline; gap: 10px;
    margin-bottom: 6px;
  }
  .numbered-block .nb-head .nb-num {
    font-size: 11.5px;
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
  }
  .numbered-block .nb-head .nb-key {
    color: var(--info);
    font-size: 12px;
    font-weight: 500;
  }
  .numbered-block .nb-head .nb-meta {
    color: var(--text-muted);
    font-size: 11.5px;
    margin-left: auto;
  }
  .numbered-block .nb-pre {
    color: var(--text);
    font-size: 13px;
    line-height: 1.55;
    word-break: break-all;
    margin: 0;
    white-space: pre-wrap;
  }
  .numbered-block .nb-cp {
    position: absolute;
    top: 10px; right: 10px;
  }

  /* tiny svg icons */
  .ico { width: 13px; height: 13px; flex-shrink: 0; }

  /* worked-example pre-fill chip on input */
  .worked-hint {
    position: absolute;
    inset: auto 0 0 0;
    padding: 6px 12px;
    font-family: var(--font-mono); font-size: 11.5px;
    color: var(--text-muted);
    pointer-events: none;
    background: linear-gradient(to top, var(--bg-surface), transparent);
    border-radius: 0 0 var(--radius-md) var(--radius-md);
  }

  /* Extracted component CSS classes (migrated from inline styles) */
  .warn-btn-picked { opacity: 0.7; cursor: default; }
  .tbl-subtitle { color: var(--text-muted); font-size: 11.5px; margin-left: 8px; }
  .cold-count { color: var(--info); }
  .parsing-msg { color: var(--text-muted); }
  .inflight-notice {
    font-family: var(--font-mono);
    font-size: 12px;
    color: var(--warning);
    padding: 4px 2px;
    display: flex;
    gap: 8px;
    align-items: center;
  }
  .inflight-dot { background: var(--warning); }
  .share-btn-wrap { margin-top: 12px; display: flex; justify-content: flex-start; }

  /* ─── info sections (how it works / faq / popular / hosting) ─── */
  .info-sections {
    border-top: 1px solid var(--border);
    padding: clamp(28px, 4vw, 48px) var(--page-padding) clamp(32px, 5vw, 56px);
    max-width: 1480px;
    width: 100%;
    margin: 0 auto;
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 24px;
  }
  @media (min-width: 1024px) {
    /* how-it-works and the faq sit side by side; the cards that used to share
     * this block now live in the right rail inside main. */
    .info-sections { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 32px; align-items: start; }
  }

  /* Tool-archetype container: a tonal step plus a soft shadow defines it,
   * not a 1px border. Same treatment as .panel elsewhere on the page. */
  .info-card {
    background: var(--bg-surface);
    border-radius: var(--radius-panel);
    padding: 20px 22px;
    box-shadow: var(--shadow-panel);
  }
  .info-h {
    font-family: var(--font-mono);
    font-size: 13px;
    font-weight: 700;
    text-transform: lowercase;
    letter-spacing: 0.04em;
    color: var(--text);
    margin: 0 0 12px;
  }
  .info-h::before {
    content: "// ";
    color: var(--brand);
  }
  .info-p {
    margin: 0 0 14px;
    font-size: 14px;
    line-height: 1.65;
    color: var(--text-muted);
  }
  .info-p-tight { margin-bottom: 10px; font-size: 13px; }
  .info-p code, .info-steps code, .faq-a code {
    font-family: var(--font-mono);
    font-size: 0.92em;
    color: var(--text);
    background: var(--bg-elevated);
    border-radius: var(--radius-xs);
    padding: 1px 4px;
  }
  .info-link, .wiki-link {
    color: var(--info);
    text-decoration: none;
    border-bottom: 1px solid transparent;
  }
  .info-link:hover, .wiki-link:hover { border-bottom-color: var(--info); }
  .info-link:focus-visible, .wiki-link:focus-visible,
  .popular-title:focus-visible, .hosting-cta:focus-visible {
    outline: 2px solid var(--info);
    outline-offset: 2px;
    border-radius: var(--radius-xs);
  }

  .info-steps {
    list-style: none;
    counter-reset: infostep;
    margin: 0 0 14px;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 12px;
  }
  .info-steps li {
    counter-increment: infostep;
    display: grid;
    grid-template-columns: 88px minmax(0, 1fr);
    gap: 4px 14px;
    align-items: baseline;
    padding-left: 26px;
    position: relative;
  }
  .info-steps li::before {
    content: counter(infostep);
    position: absolute;
    left: 0;
    top: 1px;
    font-family: var(--font-mono);
    font-size: 11px;
    color: var(--brand);
  }
  .info-steps strong {
    font-family: var(--font-mono);
    font-size: 12px;
    color: var(--text);
    text-transform: lowercase;
  }
  .info-steps span {
    font-size: 13.5px;
    line-height: 1.6;
    color: var(--text-muted);
  }
  @media (max-width: 560px) {
    .info-steps li { grid-template-columns: minmax(0, 1fr); }
  }
  .info-note {
    margin: 0;
    padding: 10px 12px;
    border-left: 2px solid var(--info);
    background: var(--info-bg);
    border-radius: 0 var(--radius-xs) var(--radius-xs) 0;
    font-size: 12.5px;
    line-height: 1.6;
    color: var(--text-muted);
  }

  .faq-list { display: flex; flex-direction: column; gap: 2px; }
  .faq-item { border-bottom: 1px solid var(--border); }
  .faq-item:last-child { border-bottom: none; }
  .faq-q {
    list-style: none;
    cursor: pointer;
    display: flex;
    align-items: baseline;
    gap: 10px;
    padding: 11px 2px;
    font-family: var(--font-mono);
    font-size: 13px;
    color: var(--text);
    user-select: none;
  }
  .faq-q::-webkit-details-marker { display: none; }
  .faq-q::before {
    content: "▸";
    color: var(--info);
    font-size: 11px;
    transition: transform .12s var(--ease-out);
    display: inline-block;
    width: 9px;
    flex: none;
  }
  .faq-item[open] > .faq-q::before { transform: rotate(90deg); }
  .faq-q:hover { color: var(--info); }
  .faq-q:focus-visible {
    outline: 2px solid var(--info);
    outline-offset: 2px;
    border-radius: var(--radius-xs);
  }
  .faq-a {
    padding: 0 2px 14px 21px;
    font-size: 13.5px;
    line-height: 1.65;
    color: var(--text-muted);
  }

  .popular-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
  }
  .popular-row {
    display: grid;
    grid-template-columns: 18px 48px minmax(0, 1fr);
    grid-template-rows: auto auto;
    gap: 2px 10px;
    align-items: start;
    padding: 10px 0;
    border-bottom: 1px solid var(--border);
  }
  .popular-row:last-child { border-bottom: none; }
  .popular-rank {
    grid-row: 1 / span 2;
    font-family: var(--font-mono);
    font-size: 11px;
    line-height: 1.5;
    color: var(--text-muted);
  }
  .popular-thumb {
    grid-row: 1 / span 2;
    width: 48px;
    height: 48px;
    border-radius: var(--radius-xs);
    border: 1px solid var(--border);
    background: var(--bg-elevated);
    object-fit: cover;
    display: block;
  }
  .popular-title {
    grid-column: 3;
    font-size: 13px;
    line-height: 1.4;
    color: var(--text);
    text-decoration: none;
    border-bottom: 1px solid transparent;
    justify-self: start;
  }
  .popular-title:hover { color: var(--info); border-bottom-color: var(--info); }
  .popular-note {
    grid-column: 3;
    font-size: 11.5px;
    line-height: 1.5;
    color: var(--text-muted);
  }
  .popular-load { margin-top: 14px; }

  .wiki-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 12px;
  }
  .wiki-link {
    display: inline-block;
    font-family: var(--font-mono);
    font-size: 12.5px;
  }
  .wiki-blurb {
    display: block;
    font-size: 12.5px;
    line-height: 1.55;
    color: var(--text-muted);
    margin-top: 2px;
  }

  .hosting-card {
    background: var(--bg-surface);
    border-radius: var(--radius-panel);
    overflow: hidden;
    box-shadow: var(--shadow-panel);
  }
  /* The source is square cover art with the wordmark at the bottom, so any
   * fixed-height crop decapitates it. Show the whole thing. */
  .hosting-art {
    display: block;
    width: 100%;
    max-width: 340px;
    margin: 0 auto;
    height: auto;
    aspect-ratio: 1 / 1;
    object-fit: contain;
  }
  .hosting-body { padding: 18px 22px 22px; }
  .hosting-head {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 8px;
  }
  .hosting-icon {
    width: 32px;
    height: 32px;
    flex: none;
    display: block;
  }
  /* Matches .info-h: same column, same heading level, same treatment. */
  .hosting-h {
    font-family: var(--font-mono);
    font-size: 13px;
    font-weight: 700;
    text-transform: lowercase;
    letter-spacing: 0.04em;
    color: var(--text);
    margin: 0;
  }
  .hosting-p {
    margin: 0 0 16px;
    font-size: 13.5px;
    line-height: 1.6;
    color: var(--text-muted);
  }
  .hosting-cta {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    background: var(--brand);
    color: var(--brand-ink);
    font-family: var(--font-mono);
    font-size: 12.5px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    text-decoration: none;
    padding: 11px 20px;
    border-radius: var(--radius-panel);
    transition: background .15s var(--ease-out), transform .08s var(--ease-out);
  }
  .hosting-cta:hover { background: var(--brand-hover); }
  .hosting-cta:active { transform: scale(0.98); }

  /* responsive */
  @media (max-width: 640px) {
    /* Keeps --header-h on phones. The tagline hides and the button labels
     * collapse to icons below, so the row still fits without wrapping;
     * wrapping here would break the fixed bar height. */
    header.app { padding-inline: 16px; gap: 10px; }
    .brand-icon { height: 28px; }
    .brand-banner { height: 34px; }
    .brand-logo { gap: 8px; }
    .brand-logo-wordmark { font-size: 18px; }
    .tagline { display: none; }
    /* Collapse the github link to its icon on phones; the aria-label keeps
     * the accessible name. */
    .head-right .icon-btn .btn-label { display: none; }
    .head-right .icon-btn svg { width: 22px; height: 22px; }
    main.app { padding: 16px; gap: 18px; }
    .compact-grid { grid-template-columns: 80px 1fr 28px; }
    .warn-list li { grid-template-columns: 1fr; gap: 4px; }
    .col { gap: 14px; }
    .info-sections { padding: 24px 16px 32px; gap: 18px; }
    .info-card { padding: 16px 16px; }
    .hosting-body { padding: 16px 16px 18px; }
  }
  @media (max-width: 480px) {
    .brand-logo-wordmark { font-size: 16px; }
    .code-block pre { padding: 12px 14px; font-size: 12px; }
    .panel .warn-head, .panel .tbl-head { padding: 10px 12px; }
    .compact-grid { grid-template-columns: 1fr; }
    .compact-grid .cg-row { grid-template-columns: 1fr; }
    .right-empty { padding: 20px 16px; }
    .build-prepick { flex-direction: column; align-items: flex-start; gap: 4px; }
  }
