/* Bebas Neue: the wordmark's face (vendor/fonts, from @fontsource/bebas-neue). */
@font-face {
  font-family: 'Bebas Neue';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/vendor/fonts/bebas-neue-latin-400-normal.woff2') format('woff2'),
       url('/vendor/fonts/bebas-neue-latin-400-normal.woff') format('woff');
}

/* ── Tarmac Spec — organizer console layer ──
   Loaded LAST on the admin app, after admin.css / judge.css /
   admin-kinetic.css. Same identity as the marketing site
   (css/landing-tarmac.css): deep violet-black surfaces, Space Grotesk
   headings, Chivo body, JetBrains Mono for data, purple accent.

   Works through tokens only. Light mode keeps the kinetic light tokens
   (admin-kinetic.css) with the purple accent; dark mode retunes the dark
   set below. The header toggle switches <html data-theme>; components keep
   their markup and class names. Corners stay square: Tarmac's
   DESIGN.md calls for sharp 0px containers, which the kinetic layer
   already enforces.

   Accent: a show's own accent (Settings > General) still themes the
   console. Only a show still on the stock accent gets the brand purple,
   via html[data-accent-stock] (set by the head script in admin/index.html). */

/* Fonts load once, from the <link> in admin/index.html. */

html[data-theme="dark"] {
  --bg-base:         #131117;
  --bg-card:         #1a1720;
  --bg-card-alt:     #1e1b24;
  --bg-inset:        rgba(255, 255, 255, 0.035);
  --bg-nav:          #0e0c12;

  --border:          #2a2631;
  --border-dim:      #211e27;
  --border-mid:      #383242;
  --border-strong:   var(--accent);

  --text-primary:    #f5f2f9;
  --text-secondary:  #cec3e3;
  --text-muted:      #a99fbe;

  --modal-bg:        #1e1b24;
  --input-bg:        #0e0c12;
  --ticker-bg:       #0e0c12;
  --ticker-div:      #2a2631;
  --row-alt:         rgba(255, 255, 255, 0.02);
  --row-hover:       rgba(var(--accent-rgb, 139, 92, 246), 0.08);
  --toggle-off:      #332e3b;
  --toggle-border:   #433c4d;

  --shadow:          0 4px 14px rgba(0, 0, 0, 0.35);
  --shadow-lg:       0 16px 40px rgba(0, 0, 0, 0.55);

  /* Ink on dark surfaces: the accent pipeline derives --accent-ink for the
     light console (darkened toward #EEEEEF), which is far too dim on
     violet-black. Lift it toward white instead, whatever the accent. */
  --accent-ink:      color-mix(in srgb, var(--accent) 68%, #ffffff) !important;
  --warning:         color-mix(in srgb, var(--accent) 68%, #ffffff) !important;

  --font-body:       'Chivo', system-ui, sans-serif;
  --font-label:      'Space Grotesk', system-ui, sans-serif;
  --font-display:    'Space Grotesk', system-ui, sans-serif;
  --font-mono:       'JetBrains Mono', ui-monospace, monospace;

  color-scheme: dark;
}

/* Stock accent → brand purple. !important so it outranks the inline
   tokens config.js / applyAdminAccent write onto <html>. */
html[data-accent-stock] {
  /* Pit Wall Violet (DESIGN.md). White on it is 5.4:1. */
  --accent:        #7154ce !important;
  --primary:       #7154ce !important;
  --accent-rgb:    113, 84, 206 !important;
  --accent-hover:  #5a43a4 !important;
  --accent-dim:    rgba(113, 84, 206, 0.10) !important;
  --accent-glow:   rgba(113, 84, 206, 0.25) !important;
  --on-accent:     #ffffff !important;
}
/* Violet as text: Signal Ink per mode (7.1:1 on white, 5.8:1 on night). */
html[data-theme="light"][data-accent-stock] { --accent-ink: #5a43a4 !important; --warning: #5a43a4 !important; }
html[data-theme="dark"][data-accent-stock]  { --accent-ink: #9281e1 !important; --warning: #9281e1 !important; }

/* ── Type: one notch more specific than admin-kinetic's !important rules ── */
html[data-theme] body,
html[data-theme] input,
html[data-theme] textarea,
html[data-theme] select {
  font-family: 'Chivo', system-ui, -apple-system, sans-serif !important;
}
html[data-theme] h1, html[data-theme] h2,
html[data-theme] h3, html[data-theme] h4,
html[data-theme] .stat-value,
html[data-theme] .login-title,
html[data-theme] .nav-show-name,
html[data-theme] .modal-title,
html[data-theme] .section-title,
html[data-theme] [class*="-title"] {
  font-family: 'Space Grotesk', system-ui, sans-serif !important;
  letter-spacing: 0.01em !important;
}
html[data-theme] .stat-value { letter-spacing: -0.02em !important; }
html[data-theme] .stat-label,
html[data-theme] .label,
html[data-theme] [class*="-label"]:not([class*="-labels"]):not(label) {
  font-family: 'Space Grotesk', system-ui, sans-serif !important;
  font-weight: 600 !important;
  letter-spacing: 0.06em !important;
}
html[data-theme] .btn,
html[data-theme] button,
html[data-theme] [class*="-btn"]:not(input) {
  font-family: 'Space Grotesk', system-ui, sans-serif !important;
  letter-spacing: 0.02em !important;
}
/* The wordmark stays Archivo Black, as on every EntryLane surface. */
html[data-theme] .kw-entry,
html[data-theme] .kw-lane,
html[data-theme] [class*="wordmark"] { font-family: 'Bebas Neue', 'Archivo Black', 'Archivo', sans-serif !important; font-weight: 400 !important; letter-spacing: 0.02em !important; }
html[data-theme] .admin-nav-title { font-size: 1.9rem; }
/* Show name under the wordmark stays on ONE line: admin.js shrinks it to fit
   the wordmark's width, and anything still too long ellipsizes rather than
   wrapping onto a second row.
   Console only (#nav-show-name). The public pages that share this bar
   (results, class list, voting, the show map) have no script to shrink the
   name, so there this rule cut "Riverside Cruise-In" down to "RIVERSIDE CR…";
   they keep wrapping onto a second line as they always did. */
html[data-theme] .admin-nav-title .kw-show#nav-show-name {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  overflow-wrap: normal;
  word-break: normal;
}

/* ── Surfaces admin.css hardcodes white ── */
html[data-theme="dark"] .awards-toplist,
html[data-theme="dark"] .awards-class-card,
html[data-theme="dark"] .awards-preview-empty--soft,
html[data-theme="dark"] .class-row .class-name-static { background: var(--bg-card-alt); }
/* QR codes must keep a white quiet zone to scan. */
html[data-theme="dark"] .qr-container { background: #ffffff; }

/* ── Chrome: header lift in dark mode. No accent glows (DESIGN.md No Glow). */
html[data-theme="dark"] .admin-nav,
html[data-theme="dark"] nav.top-nav,
html[data-theme="dark"] header.nav {
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.6);
}
html[data-theme="dark"] ::selection { background: var(--accent); color: var(--on-accent); }

/* Form controls render dark (native date/number pickers follow color-scheme). */
html[data-theme="dark"] input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="color"]),
html[data-theme="dark"] select,
html[data-theme="dark"] textarea {
  background-color: var(--input-bg);
  color: var(--text-primary);
  border-color: var(--border-mid);
}
html[data-theme="dark"] input::placeholder,
html[data-theme="dark"] textarea::placeholder { color: var(--text-muted); }

/* The wordmark's LANE takes the console accent everywhere, footer included. */
html[data-theme] .kw-lane { color: var(--accent) !important; }
/* On the day console the raw accent is large-text only at best (stock blue on
   the white login card: 2.8:1). The wordmark takes the derived ink instead,
   which is Signal Ink day for the stock violet and the AA ink for a custom one. */
html[data-theme="light"] .kw-lane { color: var(--accent-ink, var(--accent)) !important; }

/* ── Light mode (the kinetic light console, in purple) ── */
html[data-theme="light"] {
  --border-strong: var(--accent);
  --font-body:     'Chivo', system-ui, sans-serif;
  --font-label:    'Space Grotesk', system-ui, sans-serif;
  --font-display:  'Space Grotesk', system-ui, sans-serif;
  color-scheme: light;
}

/* Header toggle sits with the other header buttons. */
.mode-toggle-btn { white-space: nowrap; }

/* ── Contrast fixes (critique 2026-10-29) ── */
/* The stat band stays dark in both modes: accent hints use the night ink. */
html[data-theme] .stats-row :is(.stat-num.accent, .stat-pct, .stat-sub, .stat-tap-hint) { color: #9281e1 !important; }
html[data-theme]:not([data-accent-stock]) .stats-row :is(.stat-num.accent, .stat-pct, .stat-sub, .stat-tap-hint) { color: color-mix(in srgb, var(--accent) 60%, #ffffff) !important; }
html[data-theme] .stats-row .stat-label { color: rgba(255, 255, 255, 0.72) !important; }
/* The band used to bleed 24px past the content on both sides (a full-width
   ticker). Once the shell hits its max width that bleed reads as misalignment
   against the setup cards above and the toolbar below, so it now sits on the
   same edges as everything else at every window size. */
html[data-theme] .stats-row { margin-left: 0 !important; margin-right: 0 !important; }
html[data-theme] .reg-muted { color: var(--text-muted); }
html[data-theme] td small.reg-muted { color: var(--text-secondary); }
html[data-theme="dark"] .btn-delete-row { color: #f87171; }
html[data-theme="dark"] .badge-no { color: #fca5a5; }
html[data-theme="light"] .rev-tag--black { color: #065f46; }
/* "Not judged yet" is a normal state, not an error: neutral tag. */
html[data-theme] .badge-notyet { background: var(--bg-inset); color: var(--text-secondary); border: 1px solid var(--border-mid); }

/* ── Side stripes → full hairline + tint (DESIGN.md bans 3px colored rails) ── */
html[data-theme] :is(.fm-venue, .jr-stat, .jr-judge.is-open, .club-row--assigned, .ar-card--open) {
  border-left-width: 1px !important;
  border: 1px solid color-mix(in srgb, var(--accent) 40%, transparent) !important;
  background-color: var(--accent-dim);
}
html[data-theme] :is(.jr-gap, .dq-warn) {
  border: 1px solid var(--error-border) !important;
  background-color: var(--error-bg);
}
html[data-theme] :is(.ar-clear, .ar-card--done) {
  border: 1px solid var(--success-border) !important;
  background-color: var(--success-dim);
}
html[data-theme] .vendor-card { border-left-width: 1px !important; }
html[data-theme] .fm-zone { border: 1px solid var(--zc, var(--accent)) !important; }

/* ── Show-day layout (critique 2026-10-29): roster first, insights after ── */
html[data-theme] .awards-grid-title {
  grid-column: 1 / -1; margin: 2rem 0 0.25rem;
  font-family: 'Space Grotesk', system-ui, sans-serif !important;
  font-size: 1.35rem; letter-spacing: 0.01em !important; color: var(--text-primary);
}
#awards-grid.grid--day-zero .awards-grid-title { display: none; }

/* Check-in / Free entry toggles. Desktop: the bare checkbox (label text is
   for phones). Phone cards: full-width 48px buttons, check-in first. */
.cell-toggle { display: inline-flex; align-items: center; gap: 0.5rem; cursor: pointer; }
.cell-toggle-txt { display: none; }
@media (max-width: 760px) {
  #reg-table tr { display: flex; flex-direction: column; }
  #reg-table td.col-regnum { order: -2; }
  #reg-table td.col-checkin { order: -1; padding: 0 0 0.6rem; }
  #reg-table td.col-checkin::before, #reg-table td.col-free::before { display: none !important; }
  #reg-table td.col-checkin, #reg-table td.col-free { grid-column: 1 / -1; width: 100%; }
  #reg-table .cell-toggle {
    position: relative; display: flex; justify-content: center; width: 100%; min-height: 52px; padding: 0 1rem;
    background: var(--accent); color: var(--on-accent);
    font-family: 'Space Grotesk', system-ui, sans-serif; font-weight: 700; font-size: 1rem;
    letter-spacing: 0.04em; text-transform: uppercase;
  }
  #reg-table .cell-toggle input { position: absolute; opacity: 0; width: 1px; height: 1px; }
  #reg-table .cell-toggle-txt { display: inline; }
  #reg-table .cell-toggle .t-on { display: none; }
  #reg-table .cell-toggle:has(input:checked) { background: var(--success-dim); color: var(--success-ink); box-shadow: inset 0 0 0 2px var(--success-border); }
  #reg-table .cell-toggle:has(input:checked) .t-on { display: inline; }
  #reg-table .cell-toggle:has(input:checked) .t-off { display: none; }
  #reg-table .cell-toggle:has(input:checked) .t-on::before { content: "\2713  "; }
  #reg-table .cell-toggle:has(input:focus-visible) { outline: 2px solid var(--accent); outline-offset: 2px; }
  #reg-table .cell-toggle:has(input:disabled) { opacity: 0.6; }
  #reg-table .cell-toggle--quiet { min-height: 48px; background: var(--bg-card-alt); color: var(--text-primary); box-shadow: inset 0 0 0 1px var(--border-mid); font-size: 0.85rem; }
  #reg-table .cell-toggle--quiet:has(input:checked) { background: var(--accent-dim); color: var(--accent-ink); box-shadow: inset 0 0 0 1px var(--accent); }
  /* Judging is the second job at the car: a quiet button, not the loudest one. */
  #reg-table td.col-actions .btn-judge-car {
    background: var(--bg-card-alt) !important; color: var(--accent-ink) !important;
    border: 1px solid var(--border-mid) !important;
  }
}

/* Phone header: the wordmark gets its own row and the controls a row under
   it, so they can't collide; and the bar scrolls away instead of pinning
   ~110px over the Setup tab strip. */
@media (max-width: 520px) {
  html[data-theme] .admin-nav { position: relative; flex-wrap: wrap; row-gap: 0.5rem; padding-bottom: 0.6rem; }
  html[data-theme] .admin-nav-title { flex: 1 1 100%; }
  html[data-theme] .admin-nav-right { flex: 1 1 100%; justify-content: flex-start; }
  html[data-theme] .admin-nav-right .btn-settings { min-height: 44px; }
}

/* Judge / voting / results pages share this layer: their rails become
   hairlines too. */
html[data-theme] .judge-assignment { border: 1px solid color-mix(in srgb, var(--accent) 40%, transparent) !important; background: var(--accent-dim); }
html[data-theme] .judge-void { border: 1px solid var(--error-border) !important; background: var(--error-bg); }

/* ── Show Setup side menu ──
   The section list on /admin/setup is a panel of its own: a tinted surface
   beside the white page, sections gathered under named groups that fold,
   an icon on every section, and type a size up from the tab strip it used
   to be (Jeff, 2026-11-09: easier to scan, visibly broken into parts).
   Still square, still one accent, and the active section is a stamped tint,
   never a side stripe. The group buttons and icons exist only here: in the
   dashboard modal and below 961px the strip is a single row of tabs. */
.modal-tab-group { display: none; }
.modal-tab .tab-ico { display: none; }
@media (min-width: 961px) {
  body.setup-page #classes-modal .modal-card {
    grid-template-columns: 16rem minmax(0, 1fr);
    column-gap: 2.25rem;
  }
  body.setup-page #classes-modal .modal-tabs {
    gap: 0.1rem;
    margin-top: 1rem;
    padding: 0.85rem 0.6rem 1rem;
    /* The panel tone: page surface pulled 6% toward ink, so it sits a clear
       step off the page in day and night alike, and stays opaque for the
       scroll cues below. */
    --rail-bg: color-mix(in srgb, var(--text-primary) 6%, var(--modal-bg));
    /* When the menu is longer than the window, a soft edge at the top or
       bottom says there is more that way. The two cover layers scroll with
       the content and hide the edge once you reach that end. */
    background:
      linear-gradient(var(--rail-bg) 40%, transparent) top / 100% 2rem no-repeat local,
      linear-gradient(transparent, var(--rail-bg) 60%) bottom / 100% 2rem no-repeat local,
      linear-gradient(color-mix(in srgb, var(--text-primary) 16%, transparent), transparent) top / 100% 0.6rem no-repeat scroll,
      linear-gradient(transparent, color-mix(in srgb, var(--text-primary) 16%, transparent)) bottom / 100% 0.6rem no-repeat scroll,
      var(--rail-bg);
    border: 1px solid var(--border);
    /* A long menu on a short window scrolls inside the panel instead of
       running off the bottom of a sticky box. */
    max-height: calc(100vh - var(--nav-h, 64px) - var(--setup-head-h, 0px) - 2rem);
    /* One column, always: the strip's own flex-wrap would otherwise send
       the overflow into a second column instead of scrolling. */
    flex-wrap: nowrap;
    overflow-x: hidden;
    overflow-y: auto;
    overscroll-behavior: contain;
    scrollbar-width: thin;
  }

  /* Group name: a button that folds its sections. Sentence case and ink
     grey so it reads as a label, with the chevron in the accent. */
  body.setup-page #classes-modal .modal-tab-group {
    display: flex; align-items: center; justify-content: space-between; gap: 0.5rem;
    width: 100%;
    margin: 0.85rem 0 0.15rem; padding: 0.35rem 0.6rem;
    background: transparent; border: 0; border-radius: 0; cursor: pointer;
    font-family: 'Space Grotesk', system-ui, sans-serif;
    font-size: 0.86rem; font-weight: 700; letter-spacing: 0.01em;
    text-transform: none; text-align: left;
    color: var(--text-secondary);
  }
  body.setup-page #classes-modal .modal-tab-group:first-child { margin-top: 0; }
  body.setup-page #classes-modal .modal-tab-group,
  body.setup-page #classes-modal .modal-tabs > .modal-tab { flex: none; }
  body.setup-page #classes-modal .modal-tab-group::after {
    content: ''; flex: none;
    width: 0.5rem; height: 0.5rem; margin-right: 0.2rem;
    border-right: 2px solid var(--accent-ink, var(--accent));
    border-bottom: 2px solid var(--accent-ink, var(--accent));
    transform: translateY(-2px) rotate(45deg);
    transition: transform 0.16s ease;
  }
  body.setup-page #classes-modal .modal-tab-group[aria-expanded="false"]::after {
    transform: translateX(-2px) rotate(-45deg);
  }
  body.setup-page #classes-modal .modal-tab-group:hover { color: var(--text-primary); }
  body.setup-page #classes-modal .modal-tab-group:focus-visible {
    outline: 2px solid var(--accent); outline-offset: -2px; color: var(--text-primary);
  }

  /* Section: icon, then the name in full-strength ink. */
  body.setup-page #classes-modal .modal-tab {
    display: flex; align-items: center; gap: 0.75rem;
    padding: 0.48rem 0.6rem;
    font-size: 0.97rem; font-weight: 500; line-height: 1.25;
    color: var(--text-primary);
    transition: background-color 0.14s ease, color 0.14s ease, border-color 0.14s ease;
  }
  body.setup-page #classes-modal .modal-tab .tab-ico {
    display: block; flex: none;
    width: 1.2rem; height: 1.2rem;
    fill: none; stroke: currentColor; stroke-width: 2;
    stroke-linecap: round; stroke-linejoin: round;
  }
  body.setup-page #classes-modal .modal-tab .vendor-badge { margin-left: auto; }
  body.setup-page #classes-modal .modal-tab:hover {
    background: color-mix(in srgb, var(--text-primary) 7%, transparent);
  }
  body.setup-page #classes-modal .modal-tab--active,
  body.setup-page #classes-modal .modal-tab--active:hover {
    background: var(--accent-dim);
    border-color: var(--accent);
    color: var(--accent-ink, var(--accent));
    font-weight: 700;
  }
  /* A folded group keeps the section you are on in view. */
  body.setup-page #classes-modal .modal-tab--folded:not(.modal-tab--active) { display: none; }
}
@media (min-width: 961px) and (prefers-reduced-motion: reduce) {
  body.setup-page #classes-modal .modal-tab-group::after,
  body.setup-page #classes-modal .modal-tab { transition: none; }
}

/* ── Settings cards + jump strip (Show Setup → Flyer & Awards → Awards) ──
   A long page of unrelated groups reads better as separate panels: each
   group is a bordered card with a tinted header band (the side menu's tone)
   and its rows beneath, and a strip of jump buttons at the top names every
   card this show can see. */
.settings-jump { display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem; margin: 0 0 1.1rem; }
.settings-jump:empty { display: none; }
.settings-jump-label {
  font-family: 'Space Grotesk', system-ui, sans-serif; font-size: 0.8rem; font-weight: 700;
  color: var(--text-secondary); margin-right: 0.25rem;
}
.settings-jump-btn {
  padding: 0.4rem 0.75rem; background: transparent; border: 1px solid var(--border-mid); border-radius: 0;
  font-family: var(--font-body); font-size: 0.85rem; font-weight: 500; color: var(--text-primary); cursor: pointer;
  transition: border-color 0.14s ease, color 0.14s ease, background-color 0.14s ease;
}
.settings-jump-btn:hover { border-color: var(--accent); color: var(--accent-ink, var(--accent)); background: var(--accent-dim); }
.settings-jump-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.settings-card {
  margin: 0 0 1.25rem; border: 1px solid var(--border-mid); background: var(--modal-bg);
  /* Jump targets land clear of the pinned nav and Show Setup header. */
  scroll-margin-top: calc(var(--nav-h, 64px) + var(--setup-head-h, 0px) + 1rem);
}
.settings-card > .settings-section-head,
.settings-card > .settings-section-head--flush {
  margin: 0; padding: 0.85rem 1.25rem 0.95rem;
  border-top: 0; border-bottom: 1px solid var(--border-mid);
  background: color-mix(in srgb, var(--text-primary) 6%, var(--modal-bg));
}
.settings-card .settings-section-title { font-size: 1.08rem; letter-spacing: 0.04em; }
.settings-card .settings-section-sub { color: var(--text-secondary); }
.settings-card > .settings-row { margin-left: 1.25rem; margin-right: 1.25rem; }
.settings-card > :not(.settings-section-head):not(.settings-row) { padding-left: 1.25rem; padding-right: 1.25rem; }
.settings-card > .settings-section-head + .settings-row { border-top: 0; }
/* The jump button and the search box both mark where they landed. */
.settings-card.is-landed,
.settings-row.is-landed,
.settings-section-head.is-landed { animation: setup-landed 1.8s ease-out 1; }
@keyframes setup-landed {
  0%, 35% { box-shadow: 0 0 0 2px var(--accent); background-color: var(--accent-dim); }
  100%    { box-shadow: 0 0 0 2px transparent; }
}
@media (prefers-reduced-motion: reduce) {
  .settings-card.is-landed, .settings-row.is-landed, .settings-section-head.is-landed {
    animation: none; box-shadow: 0 0 0 2px var(--accent);
  }
}
@media (max-width: 640px) {
  .settings-card > .settings-section-head { padding-left: 0.85rem; padding-right: 0.85rem; }
  .settings-card > .settings-row { margin-left: 0.85rem; margin-right: 0.85rem; }
  .settings-card > :not(.settings-section-head):not(.settings-row) { padding-left: 0.85rem; padding-right: 0.85rem; }
}

/* ── Explanations: two lines, then "More" ──
   Many switches carry a paragraph. Show the first two lines so a page of
   settings can be scanned, and keep the rest one click away (admin.js,
   tightenExplanations). Short explanations are left exactly as they were. */
.sub-wrap { display: block; }
.sub-clamp {
  display: -webkit-box !important; -webkit-box-orient: vertical;
  -webkit-line-clamp: 2; line-clamp: 2; overflow: hidden;
}
.sub-more {
  display: inline-block; margin-top: 0.2rem; padding: 0.15rem 0; background: none; border: 0; border-radius: 0; cursor: pointer;
  font-family: 'Space Grotesk', system-ui, sans-serif; font-size: 0.78rem; font-weight: 700; letter-spacing: 0.02em;
  color: var(--accent-ink, var(--accent)); text-decoration: underline; text-underline-offset: 3px;
}
.sub-more[hidden] { display: none; }
.sub-more:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ── Find a setting (top bar) ──
   The bar is dark in day and night mode alike, so the field is drawn for a
   dark surface; the results list is an ordinary console surface under it. */
.nav-search { position: relative; flex: 0 1 19rem; min-width: 12rem; margin: 0 1rem; }
.nav-search-ico {
  position: absolute; left: 0.7rem; top: 50%; width: 1rem; height: 1rem; transform: translateY(-50%);
  fill: none; stroke: rgba(255, 255, 255, 0.7); stroke-width: 2; stroke-linecap: round; pointer-events: none;
}
html[data-theme] .nav-search-input {
  width: 100%; height: 2.5rem; padding: 0 2.2rem 0 2.2rem; border-radius: 0;
  background: rgba(255, 255, 255, 0.08); border: 1px solid rgba(255, 255, 255, 0.22);
  color: #fff; font-family: var(--font-body); font-size: 0.92rem;
  -webkit-appearance: none; appearance: none;
}
html[data-theme] .nav-search-input::placeholder { color: rgba(255, 255, 255, 0.66); }
html[data-theme] .nav-search-input::-webkit-search-cancel-button { -webkit-appearance: none; }
html[data-theme] .nav-search-input:focus { outline: none; border-color: var(--accent); background: rgba(255, 255, 255, 0.12); box-shadow: 0 0 0 1px var(--accent); }
.nav-search-key {
  position: absolute; right: 0.55rem; top: 50%; transform: translateY(-50%);
  min-width: 1.25rem; padding: 0.05rem 0.3rem; text-align: center;
  border: 1px solid rgba(255, 255, 255, 0.3); color: rgba(255, 255, 255, 0.7);
  font-family: var(--font-mono); font-size: 0.7rem; line-height: 1.3; pointer-events: none;
}
.nav-search-input:focus ~ .nav-search-key { display: none; }
.nav-search-results {
  position: absolute; top: calc(100% + 6px); left: 0; z-index: var(--z-menu, 60);
  width: max(100%, 27rem); max-height: min(70vh, 30rem); overflow-y: auto;
  margin: 0; padding: 0.3rem; list-style: none;
  background: var(--modal-bg); border: 1px solid var(--border-mid); box-shadow: var(--shadow-lg);
  /* The bar sets its children in tracked capitals; results read as sentences. */
  text-transform: none; letter-spacing: 0; text-align: left;
}
.nav-search-results.hidden { display: none; }
.nav-search-opt { display: flex; align-items: center; gap: 0.75rem; padding: 0.5rem 0.65rem; cursor: pointer; border: 1px solid transparent; }
.nav-search-opt-text { flex: 1 1 auto; min-width: 0; }
/* What the setting is set to right now: On in the accent, anything else quiet. */
.nav-search-opt-state {
  flex: none; max-width: 45%; padding: 0.12rem 0.45rem; border: 1px solid var(--border-mid);
  font-family: var(--font-mono); font-size: 0.72rem; line-height: 1.4; color: var(--text-secondary);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; text-transform: none; letter-spacing: 0;
}
.nav-search-opt-state.is-on { border-color: var(--accent); color: var(--accent-ink, var(--accent)); background: var(--accent-dim); }
.nav-search-opt-name { display: block; font-family: var(--font-body); font-size: 0.93rem; font-weight: 600; color: var(--text-primary); text-transform: none; letter-spacing: 0; }
.nav-search-opt-crumb { display: block; margin-top: 0.1rem; font-family: var(--font-body); font-size: 0.78rem; color: var(--text-secondary); }
.nav-search-opt[aria-selected="true"] { background: var(--accent-dim); border-color: var(--accent); }
.nav-search-opt[aria-selected="true"] .nav-search-opt-name { color: var(--accent-ink, var(--accent)); }
.nav-search-empty { padding: 0.7rem 0.65rem; font-size: 0.88rem; color: var(--text-secondary); }
@media (max-width: 1080px) { .nav-search { display: none; } }

/* ── Top bar (dashboard + Show Setup): compact chrome ──
   The 48px boxed slabs come from the judge field nav, where gloved thumbs
   need them. On a mouse they read as four primary actions competing with
   the roster. Here they're quiet text buttons that fill on hover; Judge
   Mode keeps a hairline because it leaves the console. Touch screens keep
   the 44px targets. */
@media (pointer: fine) {
  html[data-theme] #dashboard .admin-nav-right { gap: 0.4rem; }
  html[data-theme] #dashboard .admin-nav-user { margin-right: 0.6rem; color: rgba(255, 255, 255, 0.6); }
  /* One size, one border for every control in the bar (Jeff, 2026-10-29):
     Switch Show, Judge Mode, Dark mode, Logout and the tier badge all sit
     on a 36px hairline box. */
  html[data-theme] #dashboard .admin-nav-right :is(.btn-settings, .btn-logout, .admin-tier-badge) {
    box-sizing: border-box;
    min-height: 36px !important;
    padding: 0 0.85rem !important;
    font-family: 'Space Grotesk', system-ui, sans-serif !important;
    font-size: 0.8rem !important;
    font-weight: 600 !important;
    line-height: 1 !important;
    background: transparent !important;
    border: 1px solid rgba(255, 255, 255, 0.22) !important;
    border-radius: 0 !important;
    color: rgba(255, 255, 255, 0.85) !important;
    margin: 0 !important;
  }
  html[data-theme] #dashboard .admin-nav-right :is(.btn-settings, .btn-logout):hover {
    background: rgba(255, 255, 255, 0.08) !important;
    border-color: var(--accent) !important;
    color: #ffffff !important;
  }
  html[data-theme] #dashboard .admin-nav-right .btn-logout:hover { border-color: rgba(252, 165, 165, 0.6) !important; color: #fca5a5 !important; }
}
/* Touch screens: the same box at 44px, every control alike. */
@media (pointer: coarse) {
  html[data-theme] #dashboard .admin-nav-right :is(.btn-settings, .btn-logout, .admin-tier-badge) {
    box-sizing: border-box; min-height: 44px !important; padding: 0 0.8rem !important;
    border: 1px solid rgba(255, 255, 255, 0.22) !important; border-radius: 0 !important; margin: 0 !important;
    font-size: 0.82rem !important; line-height: 1.2 !important; background: rgba(255, 255, 255, 0.05) !important;
  }
}

/* ── Judged-column tags ──
   One line, one shape. Dark mode drops the solid red DQ slab and the
   brown-mustard Display Only for tinted chips in the same family as
   Yes/Paid: faint fill, hairline border, bright ink (all >= 7:1 on the
   night card). DQ stays loudest through a stronger fill and full-red
   border. */
html[data-theme] .badge { white-space: nowrap; line-height: 1.4; }
html[data-theme] .badge-dq { white-space: normal; text-wrap: balance; }
html[data-theme="dark"] .badge-judged,
html[data-theme="dark"] .badge-paid { background: rgba(52, 211, 153, 0.10); color: #6ee7b7; border-color: rgba(52, 211, 153, 0.36); }
html[data-theme="dark"] .badge-nonjudged { background: rgba(250, 204, 21, 0.08); color: #fde68a; border-color: rgba(250, 204, 21, 0.34); }
html[data-theme="dark"] :is(.badge-no, .badge-failed) { background: rgba(248, 113, 113, 0.10); color: #fca5a5; border-color: rgba(248, 113, 113, 0.36); }
html[data-theme="dark"] .badge.badge-dq { background: rgba(248, 113, 113, 0.20); color: #fee2e2; border-color: #f87171; }

/* Show Setup header: Export / Import are occasional file chores, not the
   page's work. Compact hairline buttons so the section title leads. */
@media (pointer: fine) and (min-width: 761px) {
  html[data-theme] body.setup-page #classes-modal .setup-header-actions { gap: 0.35rem; }
  html[data-theme] body.setup-page #classes-modal .setup-header-actions .btn-add {
    min-height: 32px !important; padding: 0 0.7rem !important;
    font-size: 0.78rem !important; font-weight: 600 !important;
    background: transparent !important; color: var(--text-secondary) !important;
    border: 1px solid var(--border-mid) !important; box-shadow: none !important;
  }
  html[data-theme] body.setup-page #classes-modal .setup-header-actions .btn-add:hover {
    color: var(--text-primary) !important; border-color: var(--accent) !important;
  }
}

/* ═══════════════════════════════════════════════════════════
   2026-10-29 console polish (impeccable critique, 29/40)
   P1 phone fold · P1 check-in feedback · P1 voting-window state
   P2 badge unification (light) · P3 focus rings
═══════════════════════════════════════════════════════════ */

/* Desktop Here / Free entry: a labelled pill instead of the 13px native box.
   Same component the phone cards already use, at table scale. */
@media (min-width: 761px) {
  #reg-table .cell-toggle {
    position: relative; justify-content: center; min-height: 32px; min-width: 96px; padding: 0 0.7rem;
    background: var(--bg-card-alt); color: var(--text-primary);
    box-shadow: inset 0 0 0 1px var(--border-mid);
    font-family: 'Space Grotesk', system-ui, sans-serif; font-weight: 700; font-size: 0.72rem;
    letter-spacing: 0.06em; text-transform: uppercase; white-space: nowrap;
    transition: background 0.15s, box-shadow 0.15s, color 0.15s;
  }
  #reg-table .cell-toggle input { position: absolute; opacity: 0; width: 1px; height: 1px; margin: 0; }
  #reg-table .cell-toggle-txt { display: inline; }
  #reg-table .cell-toggle .t-on { display: none; }
  #reg-table .cell-toggle:hover { box-shadow: inset 0 0 0 1px var(--accent); }
  #reg-table .cell-toggle:has(input:checked) { background: var(--success-dim); color: var(--success-ink); box-shadow: inset 0 0 0 1px var(--success-border); }
  #reg-table .cell-toggle:has(input:checked) .t-on { display: inline; }
  #reg-table .cell-toggle:has(input:checked) .t-off { display: none; }
  #reg-table .cell-toggle:has(input:checked) .t-on::before { content: "\2713  "; }
  #reg-table .cell-toggle:has(input:focus-visible) { outline: 2px solid var(--accent); outline-offset: 2px; }
  #reg-table .cell-toggle:has(input:disabled) { opacity: 0.6; }
  #reg-table .cell-toggle--quiet { min-width: 0; font-size: 0.66rem; color: var(--text-secondary); }
  #reg-table .cell-toggle--quiet:has(input:checked) { background: var(--accent-dim); color: var(--accent-ink); box-shadow: inset 0 0 0 1px var(--accent); }
  #reg-table td.col-checkin, #reg-table td.col-free { text-align: center; }
}

/* Save feedback: dimmed while the request is out, one pulse when it lands.
   The turnout readout pulses with it so a tap deep in the roster still
   registers up top. */
#reg-table .cell-toggle.is-saving { cursor: progress; }
#reg-table .cell-toggle.is-saved { animation: el-toggle-saved 0.9s cubic-bezier(0.22, 1, 0.36, 1); }
@keyframes el-toggle-saved {
  0%   { transform: scale(1); }
  25%  { transform: scale(1.04); box-shadow: inset 0 0 0 2px var(--success-ink), 0 0 0 6px var(--success-dim); }
  100% { transform: scale(1); }
}
.checkin-count.is-bumped { animation: el-count-bump 0.7s cubic-bezier(0.22, 1, 0.36, 1); color: var(--success-ink); }
@keyframes el-count-bump {
  0%   { transform: translateY(0); }
  30%  { transform: translateY(-3px); }
  100% { transform: translateY(0); }
}
@media (prefers-reduced-motion: reduce) {
  #reg-table .cell-toggle.is-saved, .checkin-count.is-bumped { animation: none; }
}

/* Voting-window chip (Participant Voting): open / closes at / closed. */
.voting-window-chip {
  display: inline-flex; align-items: center; gap: 0.45rem; min-height: 32px;
  font-family: var(--font-mono, 'JetBrains Mono', monospace); font-size: 0.72rem; font-weight: 700;
  letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-secondary); white-space: nowrap;
}
.voting-window-chip[hidden] { display: none; }
.voting-window-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--success-ink); flex: 0 0 auto; }
.voting-window-chip[data-state="scheduled"] .voting-window-dot { background: var(--accent); }
.voting-window-chip[data-state="closed"] .voting-window-dot { background: var(--error); }
.voting-window-chip[data-state="closed"] { color: var(--error); }
.voting-window-link { color: var(--accent-ink); text-decoration: underline; text-underline-offset: 3px; padding: 0.3rem 0; }
.voting-window-link:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* Phone: search + Add stay at hand on every scroll, not only on show day.
   The utilities collapse to one swipeable row underneath. */
@media (max-width: 760px) {
  .toolbar {
    position: sticky; top: var(--admin-nav-h, 64px); z-index: calc(var(--z-nav, 50) - 1);
    background: var(--bg-base); padding: 0.5rem 0; margin-bottom: 0.5rem; gap: 0.5rem;
  }
  .toolbar.is-stuck { border-bottom: 1px solid var(--border); box-shadow: var(--shadow); }
  /* admin-kinetic lays the phone toolbar out as a 2-column grid of equal
     44px buttons (six rows tall with every utility shown). Re-shape it:
     search + Add on the first row, the utilities one swipeable row under. */
  [data-theme] .toolbar { grid-template-columns: minmax(0, 1fr) auto !important; }
  [data-theme] .toolbar > .search-input { grid-column: 1 !important; }
  [data-theme] .toolbar > #add-btn { grid-column: 2; width: auto !important; }
  [data-theme] .toolbar .toolbar-utils {
    display: flex !important; grid-column: 1 / -1; gap: 0.5rem;
    flex-wrap: nowrap; overflow-x: auto; -webkit-overflow-scrolling: touch;
    scrollbar-width: none; padding-bottom: 2px; margin: 0;
  }
  .toolbar-utils::-webkit-scrollbar { display: none; }
  [data-theme] .toolbar .toolbar-utils > * { flex: 0 0 auto; }
  [data-theme] .toolbar .toolbar-utils .btn-add,
  [data-theme] .toolbar .toolbar-utils .post-show-wrap { width: auto !important; }
  /* Import CSV also lives in Setup > Pre-Registration; nobody uploads a CSV
     from a phone at the gate, so it comes off the phone toolbar. */
  [data-theme] .toolbar > #import-csv-btn { display: none !important; }
}

/* Compact setup guide (show week, or any phone): one line, steps a tap away. */
[data-theme] .setup-guide--compact .setup-guide-head { border-bottom: 0; align-items: center; flex-wrap: wrap; row-gap: 0.35rem; }
[data-theme] .setup-guide-steps[hidden] { display: none !important; }
[data-theme] .setup-guide-next { font-family: 'Archivo', system-ui, sans-serif; font-size: 0.8rem; color: var(--text-secondary); }
[data-theme] .setup-guide-hide { min-height: 32px; padding: 0.25rem 0.1rem; }
[data-theme] .setup-guide-toggle { color: var(--accent-ink); }
[data-theme] .setup-guide-toggle + .setup-guide-hide { margin-left: 0.9rem; }
@media (max-width: 760px) {
  [data-theme] .setup-guide { margin-bottom: 12px; }
  [data-theme] .setup-guide-head { padding: 0.6rem 0.85rem; }
}

/* Light mode: judged / non-judged / DQ badges share one grammar (tint + ink +
   1px border), the same one dark mode already uses. DQ stays the loudest via
   the saturated border, not a solid fill. */
html[data-theme="light"] .badge-nonjudged { background: rgba(202, 138, 4, 0.12); color: #713f12; border-color: rgba(202, 138, 4, 0.45); }
html[data-theme="light"] .badge.badge-dq { background: rgba(186, 26, 26, 0.12); color: #7f1d1d; border-color: var(--error); }

/* Focus rings: solid 2px accent, no glow (kinetic's --accent-glow ring was
   invisible on carbon). Only on keyboard focus. */
[data-theme] .stat-card--btn:focus { outline: none !important; }
[data-theme] .stat-card--btn:focus-visible { outline: 2px solid var(--accent) !important; outline-offset: 2px; }
html[data-theme] .search-input:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ── Minimizable insight tiles (Jeff, 2026-10-29) ──
   Each tile's title bar carries a − / + button; minimized tiles collapse to
   the bar. The section title carries Minimize all / Expand all. */
.judge-card-label--min, .judge-card-head { display: flex; align-items: center; justify-content: space-between; gap: 0.6rem; }
[data-theme] .judge-card-head { border-bottom: 1px solid var(--border); padding-right: 0.6rem; min-height: 57px; }
[data-theme] .judge-card-head .judge-card-label { flex: 1 1 auto; border-bottom: 0 !important; }
.card-min-btn {
  flex: 0 0 auto; margin-left: auto; width: 28px; height: 28px;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--border-mid); background: var(--bg-card-alt); color: var(--text-secondary);
  font-family: 'Space Grotesk', system-ui, sans-serif; font-size: 1.05rem; font-weight: 700; line-height: 1;
  letter-spacing: 0; text-transform: none; cursor: pointer; padding: 0;
}
.card-min-btn:hover { border-color: var(--accent); color: var(--accent-ink); }
.card-min-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
@media (pointer: coarse) { .card-min-btn { width: 36px; height: 36px; } }
.judge-card.is-minimized { align-self: start; }
.judge-card.is-minimized > :not(.judge-card-label):not(.judge-card-head) { display: none !important; }
[data-theme] .judge-card.is-minimized > .judge-card-label,
[data-theme] .judge-card.is-minimized > .judge-card-head { border-bottom: 0 !important; }
html[data-theme] .awards-grid-title { display: flex; align-items: center; justify-content: space-between; gap: 1rem; flex-wrap: wrap; }
.awards-grid-toggle {
  min-height: 32px; padding: 0 0.75rem; background: none; border: 1px solid var(--border-mid);
  color: var(--text-secondary); font-family: 'Space Grotesk', system-ui, sans-serif; font-size: 0.8rem; font-weight: 600;
  letter-spacing: 0.01em; cursor: pointer;
}
.awards-grid-toggle:hover { border-color: var(--accent); color: var(--accent-ink); }
.awards-grid-toggle:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ── Color dots in the header (js/admin-scheme.js): purple / orange / blue ──
   28px hit boxes with a 14px dot; the chosen one wears a white ring. */
.scheme-dots { display: inline-flex; align-items: center; gap: 2px; margin: 0 0.25rem; }
.scheme-dots button {
  width: 28px; height: 28px; padding: 0; border: 0; background: none; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center; border-radius: 50%;
}
.scheme-dots button::before {
  content: ""; width: 14px; height: 14px; border-radius: 50%; background: var(--dot);
  box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.25); transition: transform 0.12s, box-shadow 0.12s;
}
.scheme-dots button:hover::before { transform: scale(1.15); }
.scheme-dots button[aria-pressed="true"]::before { box-shadow: 0 0 0 2px #0d0d12, 0 0 0 4px #ffffff; }
.scheme-dots button:focus-visible { outline: 2px solid #ffffff; outline-offset: 1px; }
@media (pointer: coarse) { .scheme-dots button { width: 40px; height: 40px; } .scheme-dots button::before { width: 16px; height: 16px; } }

/* Stats ticker: the big count sat in a 1.0 line box with no gap, so its
   glyphs (the slash in "1 / 1" most of all) ran into the label beneath at
   larger sizes and zoom levels. Room below it at every width. */
html[data-theme] .stats-row .stat-num { line-height: 1.15 !important; margin-bottom: 0.3rem !important; }

/* ── Pre-Registration add-on (package gate) ─────────────────────────────────
   Shown in place of the Pre-Registration settings while the show's package
   doesn't carry online pre-registration. Tonal layering, square corners, the
   one accent on the price and the button only. */
.prereg-locked {
  margin: 1rem 0 0.25rem;
  padding: 1.1rem 1.2rem 1.2rem;
  background: var(--bg-card-alt);
  border: 1px solid var(--border);
}
.prereg-locked-head {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.35rem 0.6rem;
}
.prereg-locked-kicker {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 0.68rem; letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--accent-ink);
}
.prereg-locked-title {
  flex-basis: 100%;
  font-family: 'Space Grotesk', sans-serif; font-weight: 700; font-size: 1.1rem;
  color: var(--text-primary);
}
.prereg-locked-price {
  font-family: 'Space Grotesk', sans-serif; font-weight: 700; font-size: 1.75rem;
  letter-spacing: -0.02em; color: var(--accent-ink);
}
.prereg-locked-per { font-size: 0.82rem; color: var(--text-muted); }
.prereg-locked-sub { margin: 0.6rem 0 0; font-size: 0.9rem; line-height: 1.55; color: var(--text-secondary); }
.prereg-locked-sub .mono { font-family: 'JetBrains Mono', ui-monospace, monospace; font-size: 0.82em; color: var(--text-primary); }
.prereg-locked-tos {
  display: flex; align-items: flex-start; gap: 0.55rem; margin: 0.9rem 0 0;
  font-size: 0.84rem; line-height: 1.5; color: var(--text-secondary); cursor: pointer;
}
.prereg-locked-tos input { margin-top: 0.2rem; width: 1rem; height: 1rem; accent-color: var(--accent); flex-shrink: 0; }
.prereg-locked-tos a { color: var(--accent-ink); text-decoration: underline; text-underline-offset: 2px; }
.prereg-locked-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 0.75rem; margin-top: 0.9rem; }
.prereg-locked.is-included .prereg-locked-tos,
.prereg-locked.is-included .prereg-locked-actions { display: none; }


/* ── Show Map: pins (js/field-map.js) ──────────────────────────────────────
   Pins sit on the map canvas, over satellite, streets or the organizer's own
   site plan, so the marker carries fixed contrast (ink badge, bone border,
   dark ring) the way the placement handles do. Partner pins (sponsors and
   vendors) take the one accent; landmarks stay ink. The same badge repeats in
   the list beside the map, without the canvas armour. */
.fm-grid { grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }
.fm-toolbar .btn-add:disabled { opacity: 0.5; cursor: not-allowed; }

.fm-pinform {
  display: flex; flex-wrap: wrap; align-items: flex-end; gap: 0.75rem;
  padding: 0.9rem 1rem; margin-bottom: 10px;
  background: var(--bg-card-alt); border: 1px solid var(--border);
}
.fm-pinform[hidden] { display: none; }
.fm-pinform-field { flex: 0 1 13rem; min-width: 10rem; }
.fm-pinform-field--grow { flex: 1 1 16rem; }
.fm-pinform-field .settings-text-input { width: 100%; }
.fm-pinform-actions { display: flex; gap: 0.5rem; }

.fm-pin { display: flex; align-items: center; gap: 4px; cursor: grab; }
.fm-pin:active { cursor: grabbing; }
.fm-pin-g {
  flex: 0 0 auto; box-sizing: border-box; width: 26px; height: 26px;
  display: grid; place-items: center;
  font-family: 'JetBrains Mono', ui-monospace, monospace; font-weight: 700;
  font-size: 11px; line-height: 1; letter-spacing: 0;
  background: #111113; color: #F3EFE8;
  border: 2px solid #F3EFE8; box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.55);
}
.fm-pin--partner .fm-pin-g,
.fm-pinrow.is-partner .fm-pin-g { background: var(--accent); color: var(--on-accent, #fff); }
.fm-pin-l {
  max-width: 150px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  padding: 3px 6px;
  font-family: 'Chivo', system-ui, sans-serif; font-weight: 700; font-size: 11px; line-height: 1.25;
  background: rgba(17, 17, 19, 0.86); color: #F3EFE8;
}

.fm-pinrow {
  display: flex; align-items: center; gap: 9px; padding: 8px 10px; margin-bottom: 6px;
  background: var(--bg-card); border: 1px solid var(--border); cursor: pointer;
}
.fm-pinrow:hover { border-color: var(--border-strong); }
.fm-pinrow .fm-pin-g { width: 24px; height: 24px; border: 0; box-shadow: none; }
.fm-pinrow-k {
  flex: 0 0 auto; white-space: nowrap;
  font-family: 'JetBrains Mono', ui-monospace, monospace; font-size: 0.62rem;
  letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-muted);
}
.fm-pinrow--todo { cursor: default; border-style: dashed; }
.fm-pinrow--todo:hover { border-color: var(--border); }
.fm-unplaced-h {
  margin: 14px 0 6px;
  font-family: 'JetBrains Mono', ui-monospace, monospace; font-size: 0.64rem;
  letter-spacing: 0.1em; text-transform: uppercase; color: var(--text-muted);
}
.fm-pop-input { width: 100%; box-sizing: border-box; }
.fm-pop-actions { display: flex; justify-content: space-between; gap: 8px; margin-top: 12px; }

.fm-share-head { margin-top: 2rem; }
.fm-share-zones {
  display: flex; align-items: center; gap: 0.55rem; margin: 0.75rem 0 0;
  font-size: 0.9rem; color: var(--text-secondary); cursor: pointer;
}
.fm-share-zones input { width: 1rem; height: 1rem; accent-color: var(--accent); flex-shrink: 0; }

/* ── Free Entry (js/free-entry.js) ─────────────────────────────────────────
   A short form and a ledger of what was sent. Tonal card for the form, plain
   rows for the ledger; the accent only marks a pass that is still waiting. */
.fe-form {
  margin: 1rem 0 1.6rem; padding: 1.1rem 1.2rem 1.2rem;
  background: var(--bg-card-alt); border: 1px solid var(--border);
}
.fe-fields { display: grid; grid-template-columns: 1fr 1fr; gap: 0.75rem 1rem; }
.fe-field--wide { grid-column: 1 / -1; }
.fe-field .settings-text-input { width: 100%; box-sizing: border-box; }
/* "(optional)" inside a small mono label keeps the label's size, so two
   labels on one row share a baseline. */
[data-theme] .fe-field .settings-window-sublabel .optional,
[data-theme] .fm-pinform .settings-window-sublabel .optional {
  font-size: inherit !important; font-weight: inherit !important;
  letter-spacing: inherit !important; text-transform: none;
}
.fe-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 0.75rem; margin-top: 0.9rem; }
#fe-status.is-bad { color: var(--error); }

.fe-list { display: grid; gap: 6px; }
.fe-row {
  display: grid; grid-template-columns: minmax(0, 1fr) auto auto auto;
  align-items: center; gap: 0.5rem 1rem; padding: 0.7rem 0.9rem;
  background: var(--bg-card); border: 1px solid var(--border);
}
.fe-row--off { opacity: 0.7; }
.fe-who { min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.fe-name { font-weight: 600; color: var(--text-primary); overflow-wrap: anywhere; }
.fe-email, .fe-note { font-size: 0.84rem; color: var(--text-secondary); overflow-wrap: anywhere; }
.fe-note { font-style: italic; }
.fe-meta, .fe-onroster {
  font-family: 'JetBrains Mono', ui-monospace, monospace; font-size: 0.64rem;
  letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-muted);
}
.fe-code {
  font-family: 'JetBrains Mono', ui-monospace, monospace; font-size: 0.8rem;
  letter-spacing: 0.08em; color: var(--text-primary); white-space: nowrap;
}
.fe-status {
  padding: 3px 8px; white-space: nowrap; border: 1px solid var(--border-mid);
  font-family: 'JetBrains Mono', ui-monospace, monospace; font-size: 0.62rem;
  letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-muted);
}
.fe-status--sent { color: var(--accent-ink); background: var(--accent-dim); border-color: color-mix(in srgb, var(--accent) 45%, transparent); }
.fe-status--done { color: var(--success-ink); background: var(--success-dim); border-color: var(--success-border); }
.fe-row-actions { display: flex; flex-wrap: wrap; gap: 0.4rem; justify-content: flex-end; }
@media (max-width: 820px) {
  .fe-fields { grid-template-columns: 1fr; }
  .fe-row { grid-template-columns: minmax(0, 1fr) auto; }
  .fe-who { grid-column: 1 / -1; }
  .fe-row-actions { grid-column: 1 / -1; justify-content: flex-start; }
}

/* ── Score editor in the entry form ────────────────────────────────────────
   A score outside the rubric is marked where it was typed, with the reason
   in the status line underneath: the browser's own range tooltip was the only
   signal before, and it is gone in a second. */
.modal-total-only { margin: 0.1rem 0 0.75rem; }
html[data-theme] .modal-score-input.is-out {
  border-color: var(--error) !important;
  box-shadow: inset 0 0 0 1px var(--error);
}
#modal-scores-status[data-kind="warn"] { font-weight: 600; }

/* ── Social Kit (js/social-kit.js) ─────────────────────────────────────────
   A column of posts. Each one is its picture on the left and the words on
   the right; the picture is the loud thing, the chrome around it stays quiet. */
.sk-settings {
  display: flex; flex-wrap: wrap; align-items: flex-end; gap: 0.75rem 1rem;
  margin: 1rem 0 0.5rem; padding: 1rem 1.2rem 1.1rem;
  background: var(--bg-card-alt); border: 1px solid var(--border);
}
.sk-field { flex: 1 1 14rem; max-width: 22rem; }
.sk-field .settings-text-input { width: 100%; box-sizing: border-box; }
[data-theme] .sk-field .settings-window-sublabel .optional {
  font-size: inherit !important; font-weight: inherit !important;
  letter-spacing: inherit !important; text-transform: none;
}
.sk-settings-status { flex-basis: 100%; min-height: 1em; }
.sk-group {
  margin: 2rem 0 0.75rem; padding-bottom: 0.4rem; border-bottom: 1px solid var(--border);
  font-family: 'Space Grotesk', system-ui, sans-serif; font-weight: 700; font-size: 1.05rem;
  letter-spacing: 0.02em; text-transform: uppercase; color: var(--text-primary);
}
.sk-post { padding: 1rem 0 1.25rem; border-bottom: 1px solid var(--border); }
.sk-post:last-child { border-bottom: 0; }
.sk-post-head { display: flex; flex-direction: column; gap: 0.2rem; margin-bottom: 0.75rem; }
.sk-post-title { font-family: 'Space Grotesk', system-ui, sans-serif; font-weight: 700; font-size: 1rem; color: var(--text-primary); }
.sk-post-hint { font-size: 0.86rem; line-height: 1.5; color: var(--text-secondary); max-width: 62ch; }
.sk-post-body { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 1.1rem; align-items: start; }
.sk-thumbs { display: flex; gap: 0.5rem; flex-wrap: wrap; max-width: 380px; }
.sk-thumb { display: block; width: 176px; height: auto; border: 1px solid var(--border-mid); }
.sk-thumb--story { width: 124px; }
.sk-thumbs:has(.sk-thumb:nth-child(2)) .sk-thumb { width: 118px; }
.sk-caption { width: 100%; box-sizing: border-box; min-height: 9.5rem; line-height: 1.5; font-size: 0.92rem; resize: vertical; }
.sk-actions { display: flex; flex-wrap: wrap; gap: 0.4rem; margin-top: 0.6rem; }
.sk-actions [hidden] { display: none; }
.sk-wait { margin: 0; font-size: 0.9rem; line-height: 1.5; color: var(--text-muted); }
.sk-post--wait .sk-post-head { margin-bottom: 0.3rem; }
.sk-post--wait .sk-post-title { color: var(--text-secondary); }
.sk-series { border-bottom: 1px solid var(--border); }
.sk-series > summary {
  display: flex; align-items: baseline; gap: 0.75rem; padding: 1rem 0; cursor: pointer; list-style: none;
}
.sk-series > summary::-webkit-details-marker { display: none; }
.sk-series > summary::before {
  content: '+'; width: 1rem; font-family: 'JetBrains Mono', ui-monospace, monospace; color: var(--accent-ink);
}
.sk-series[open] > summary::before { content: '−'; }
.sk-series > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.sk-series-n {
  font-family: 'JetBrains Mono', ui-monospace, monospace; font-size: 0.66rem;
  letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-muted);
}
.sk-series .sk-post { padding-left: 1.75rem; }
.sk-series .sk-post:last-child { border-bottom: 0; }
@media (max-width: 760px) {
  .sk-post-body { grid-template-columns: 1fr; }
  .sk-series .sk-post { padding-left: 0; }
}

/* A demo show's classes are fixed: the row carries a quiet label where its
   Edit and Delete buttons would be. */
.class-locked-note {
  font-family: 'JetBrains Mono', ui-monospace, monospace; font-size: 0.64rem;
  letter-spacing: 0.1em; text-transform: uppercase; color: var(--text-muted);
  padding: 3px 8px; border: 1px solid var(--border-mid);
}
