/*
 * This is a manifest file that'll be compiled into application.css.
 *
 * With Propshaft, assets are served efficiently without preprocessing steps. You can still include
 * application-wide styles in this file, but keep in mind that CSS precedence will follow the standard
 * cascading order, meaning styles declared later in the document or manifest will override earlier ones,
 * depending on specificity.
 *
 * Consider organizing styles into separate files for maintainability.
 */

:root {
  --bg: oklch(1 0 0);
  --surface: oklch(0.972 0.006 45);
  --surface-strong: oklch(0.94 0.009 45);
  --ink: oklch(0.19 0.018 40);
  --muted: oklch(0.45 0.018 40);
  --line: oklch(0.87 0.012 45);
  --primary: oklch(0.58 0.18 42);
  --primary-dark: oklch(0.49 0.17 42);
  --accent: oklch(0.42 0.12 205);
  --danger: oklch(0.52 0.19 25);
  --warning-bg: oklch(0.95 0.045 85);
  --warning-ink: oklch(0.34 0.07 70);
  --success: oklch(0.47 0.12 155);
  --control-bg: oklch(0.995 0.002 45);
  --control-hover: oklch(0.982 0.007 45);
  /* WCAG 2.1 SC 1.4.11 (non-text contrast) needs 3:1 for a control boundary.
     The old 0.76 gave 2.16:1 on white and failed. 0.62 is the LIGHTEST value that
     still clears 3:1 against the worst realistic panel (--surface-strong, 3.06:1),
     so the borders stay visually light without failing. Verified by
     test/design/token_contrast_test.rb -- do not raise this without rerunning it. */
  --control-border: oklch(0.62 0.014 45);
  /* --line stays light: it is for genuine dividers, which 1.4.11 exempts. Any
     border that is the sole boundary of an interactive control uses this instead. */
  --line-strong: oklch(0.62 0.014 45);
  --focus-ring: oklch(0.78 0.12 42 / .34);
  --danger-bg: oklch(0.965 0.028 25);
  --success-bg: oklch(0.955 0.035 155);
  --shadow-control: 0 1px 1px oklch(0.2 0.01 40 / .04), 0 1px 3px oklch(0.2 0.01 40 / .03);
  --shadow-popover: 0 14px 38px oklch(0.15 0.02 40 / .16), 0 2px 8px oklch(0.15 0.02 40 / .08);
  --ease-out: cubic-bezier(0.23, 1, 0.32, 1);
  --ease-in-out: cubic-bezier(0.77, 0, 0.175, 1);
  --z-builder-save: 15;
  /* One rink height for every surface that draws one: the segment ice map
     (which set this 22rem precedent), both diagram editors, and the drill
     detail page. Without it the editors run ~30rem and the drill page ~39rem
     at .page-wide, which is more scrolling than a rink is worth. */
  --rink-max-height: 22rem;
  /* Editor-only, deliberately NOT a change to --rink-max-height above: that
     one is also what caps a practice-session segment's ice map (see the two
     other rules reading it) and must stay where it is. */
  --editor-rink-max-height: min(72vh, 46rem);

  /* Forgejo #95. Promoted from raw literals that were hand-written in two or
     more places each. Names say what the colour is FOR, not what hue it is, so
     a future dark-mode pass has something meaningful to redefine. Values are
     byte-identical to what they replaced -- this is a pure refactor with no
     rendering change, which is what makes it safe to do with no browser here.
     --shadow-tint collapses `oklch(0 0 0 / 0.12)` and `oklch(0 0 0 / .12)`,
     the same colour that had drifted into two spellings. */
  --ice-surface: oklch(0.97 0.01 205);
  --ice-surface-alt: oklch(0.975 0.012 205);
  --diagram-line: oklch(0.87 0.028 215);
  --diagram-tab-bg: oklch(0.955 0.022 215);
  --diagram-tab-hover: oklch(0.925 0.038 215);
  --diagram-tab-active-border: oklch(0.63 0.09 220);
  --diagram-tab-ink: oklch(0.5 0.035 222);
  --diagram-tab-ink-active: oklch(0.38 0.085 222);
  --status-ready-bg: oklch(0.9 0.07 155);
  --status-ready-ink: oklch(0.32 0.09 155);
  --status-planned-bg: oklch(0.91 0.05 280);
  --status-planned-ink: oklch(0.35 0.09 280);
  --focus-ring-strong: oklch(0.85 0.08 42 / .45);
  --surface-subtle: oklch(0.987 0.006 45);
  --danger-bg-hover: oklch(0.95 0.04 25);
  /* Was 0.58 = 4.30:1 on white, below the 4.5:1 AA floor for text -- and a
     placeholder IS text (SC 1.4.3). The failure was invisible while this was a
     raw literal inside `.form-control::placeholder`; promoting it to a token is
     what surfaced it. 0.549 is the darkest-permitted... i.e. the LIGHTEST value
     that still clears 4.5:1 on --surface and --surface-subtle both. */
  --placeholder-ink: oklch(0.549 0.012 40);
  --success-bright: oklch(0.48 0.13 155);
  --immersive-bg: oklch(0.16 0.015 40);
  --scrim: oklch(0 0 0 / 0.4);
  --shadow-tint-strong: oklch(0 0 0 / 0.2);
  --shadow-tint: oklch(0 0 0 / 0.12);
  /* The 1px seam an active tab paints over its strip's bottom border, so the
     tab reads as joined to the panel below it. Five identical copies before
     #96; one meaning, so one token. */
  --shadow-tab-seam: 0 1px 0 var(--bg);
  /* The editor's overlap chooser popover. Was the file's only rgba() -- now an
     exact oklch equivalent (black is oklch(0 0 0), so this is a respelling, not
     an approximation) and a token, because token_discipline_test correctly
     refused to let the respelling land as one more raw literal. */
  --shadow-overlap-chooser: 0 .25rem .75rem oklch(0 0 0 / .15);

  /* Forgejo #96. 21 distinct border-radius values collapsed to six steps. The
     two heaviest clusters keep their own step (--radius-md at 31 call sites,
     --radius-lg at 28), so most rules did not move; 33 sites shifted, nearly
     all by 0.8px. Safe to sweep without a browser precisely because
     border-radius cannot change an element's box size -- it can never reflow
     anything, only round a corner differently. A font-size sweep CAN reflow,
     which is why the type scale was deliberately left for a pass that can look
     at a screen (see the issue). */
  --radius-xs: .25rem;
  --radius-sm: .35rem;
  --radius-md: .45rem;
  --radius-lg: .5rem;
  --radius-xl: .6rem;
  --radius-2xl: .7rem;
}

* { box-sizing: border-box; }

body.app-body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  -webkit-font-smoothing: antialiased;
}

.app-header {
  align-items: center;
  background: var(--bg);
  border-bottom: 1px solid var(--line);
  display: flex;
  height: 56px;
  padding: 0 max(1rem, calc((100vw - 80rem) / 2));
  position: sticky;
  top: 0;
  z-index: 20;
}

.app-mark {
  align-items: baseline;
  color: var(--ink);
  display: flex;
  gap: .4rem;
  margin-right: 2rem;
  text-decoration: none;
}

.app-mark span {
  background: var(--primary);
  border-radius: var(--radius-sm);
  color: white;
  font-size: .78rem;
  font-weight: 800;
  padding: .2rem .35rem;
}

.app-mark strong { font-size: .95rem; }
/* Forgejo #93. Seven items still scroll on a narrow phone, and a bare
   `overflow-x: auto` gives no hint that there is more to the right. The mask
   fades the trailing edge so the row visibly continues; it is applied only
   below the width where the nav actually fits, so it never dims a full row.
   `scrollbar-width: none` because the fade is the affordance -- a scrollbar
   over a 44px-tall row eats the touch target. */
.app-header nav {
  display: flex;
  gap: .25rem;
  overflow-x: auto;
  scrollbar-width: none;
}

.app-header nav::-webkit-scrollbar { display: none; }

@media (max-width: 900px) {
  .app-header nav {
    -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 2rem), transparent 100%);
    mask-image: linear-gradient(to right, #000 calc(100% - 2rem), transparent 100%);
  }
}
.app-header nav a {
  align-items: center;
  border-radius: var(--radius-md);
  color: var(--ink);
  display: inline-flex;
  flex-shrink: 0;
  min-height: 44px;
  padding: 0 .8rem;
  text-decoration: none;
}
.app-header nav a:hover { background: var(--surface); }
.app-header nav a.is-current { background: var(--surface-strong); color: var(--primary-dark); font-weight: 700; }
.app-header-right { align-items: center; display: flex; gap: .75rem; margin-left: auto; }
.app-user { color: var(--muted); font-size: .85rem; }
.club-switcher select { border: 1px solid var(--line-strong); border-radius: var(--radius-md); font-size: .85rem; min-height: 44px; padding: 0 .5rem; }
.app-main { min-height: calc(100vh - 56px); padding: 2rem 1rem 4rem; }

.page-wide, .page-narrow { margin: 0 auto; width: 100%; }
.page-wide { max-width: 80rem; }
.page-narrow { max-width: 48rem; }
.page-heading {
  align-items: end;
  display: flex;
  gap: 1rem;
  justify-content: space-between;
  margin-bottom: 1.75rem;
}
.page-heading h1, .builder-header h1 {
  font-size: 1.75rem;
  font-weight: 750;
  letter-spacing: -.025em;
  line-height: 1.2;
  margin: .35rem 0;
}
.page-heading p, .builder-header p, .section-heading p {
  color: var(--muted);
  margin: 0;
}

.btn-primary, .btn-secondary, .btn-danger {
  align-items: center;
  border-radius: var(--radius-md);
  cursor: pointer;
  display: inline-flex;
  font-size: .9rem;
  font-weight: 700;
  justify-content: center;
  min-height: 44px;
  padding: .65rem 1rem;
  text-decoration: none;
  transition: background-color 140ms ease, border-color 140ms ease, color 140ms ease, opacity 140ms ease, transform 140ms var(--ease-out);
}
.btn-primary { background: var(--primary); border: 1px solid var(--primary); color: white; }
.btn-primary:hover { background: var(--primary-dark); border-color: var(--primary-dark); }
.btn-secondary { background: var(--bg); border: 1px solid var(--line-strong); color: var(--ink); }
.btn-secondary:hover { background: var(--surface); }
.btn-danger { background: var(--bg); border: 1px solid var(--line-strong); color: var(--danger); }
.btn-primary:active, .btn-secondary:active, .btn-danger:active, .icon-button:active, .text-button:active { transform: scale(.97); }
.btn-primary:focus-visible, .btn-secondary:focus-visible, .btn-danger:focus-visible,
.icon-button:focus-visible, .text-button:focus-visible, .text-link:focus-visible {
  outline: 3px solid var(--focus-ring);
  outline-offset: 2px;
}
.btn-primary:disabled, .btn-secondary:disabled, .btn-danger:disabled,
.btn-primary[aria-disabled="true"], .btn-secondary[aria-disabled="true"], .btn-danger[aria-disabled="true"] {
  cursor: not-allowed;
  opacity: .52;
}
.text-link, .text-button { color: var(--primary-dark); font-weight: 650; text-decoration: none; }
.text-button { background: none; border: 0; cursor: pointer; min-height: 44px; padding: .5rem; }

/* Forgejo #1: shared action-group/icon-button components — introduced for
   #7/#9/#17/#20 to build on, not yet adopted by the feature pages those
   issues will rewrite (kept out of scope here to avoid double-touching). */
.action-group { align-items: center; display: flex; flex-wrap: wrap; gap: .5rem; }
/* Glyph-replacement icons (Forgejo icon pass): these live in buttons that
   used to hold a single text character, so they need an explicit inline box
   rather than inheriting a text baseline. */
.station-move button svg, .drill-variation-move button svg,
.drill-variation-handle svg, .segment-tab-handle svg,
.station-expand-button b svg { display: block; }
.station-add-button { gap: .4rem; }
.icon-button {
  align-items: center;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  color: var(--ink);
  cursor: pointer;
  display: inline-flex;
  height: 44px;
  justify-content: center;
  width: 44px;
}
.icon-button:hover { background: var(--surface); }
.icon-button.icon-button-danger { color: var(--danger); }
.icon-button.icon-button-danger:hover { background: var(--danger-bg-hover); }

.panel, .builder-section, .segment, .add-segment {
  border: 1px solid var(--line);
  border-radius: var(--radius-2xl);
}
.panel { background: oklch(0.995 0.003 45); padding: clamp(1rem, 3vw, 2rem); }
.form-grid, .station-form-main {
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
.form-label { color: oklch(0.27 0.018 40); display: block; font-size: .8rem; font-weight: 740; letter-spacing: .005em; margin-bottom: .4rem; }
.form-control {
  background: var(--control-bg);
  border: 1px solid var(--control-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-control);
  color: var(--ink);
  font: inherit;
  min-height: 44px;
  padding: .65rem .75rem;
  transition: background-color 140ms ease, border-color 140ms ease, box-shadow 140ms ease, opacity 140ms ease;
  width: 100%;
}
textarea.form-control { line-height: 1.45; min-height: 5.5rem; resize: vertical; }
.form-control::placeholder { color: var(--placeholder-ink); opacity: 1; }
.form-control:hover:not(:disabled):not(:focus) { border-color: oklch(0.65 0.025 45); }
.form-control:focus, .form-control:focus-visible, .color-control:focus, .color-control:focus-visible {
  background: var(--bg);
  border-color: var(--primary);
  box-shadow: 0 0 0 3px var(--focus-ring), var(--shadow-control);
  outline: 0;
}
.form-control:disabled, .form-control[readonly] {
  background: var(--surface);
  color: var(--muted);
}
.form-control:disabled { cursor: not-allowed; opacity: .72; }
.field_with_errors .form-control, .form-control[aria-invalid="true"] {
  border-color: var(--danger);
  box-shadow: 0 0 0 2px oklch(0.72 0.15 25 / .16);
}
.form-hint { color: var(--muted); font-size: .78rem; margin: .3rem 0 0; }
.field-error { align-items: center; color: var(--danger); display: flex; font-size: .78rem; gap: .35rem; margin: .35rem 0 0; }
.field-error > span { align-items: center; background: var(--danger); border-radius: 50%; color: white; display: inline-flex; font-size: .65rem; font-weight: 800; height: 1rem; justify-content: center; width: 1rem; }
.field-optional { color: var(--muted); font-size: .72rem; font-weight: 550; margin-left: auto; }
.form-section { background: oklch(0.988 0.006 45); border: 1px solid var(--line); border-radius: var(--radius-2xl); padding: clamp(1rem, 2.5vw, 1.5rem); }
.form-section + .form-section { margin-top: 1rem; }
.form-section-heading { margin-bottom: 1rem; }
.form-section-heading h2, .form-section-heading h3 { font-size: .95rem; margin: 0; }
.form-section-heading p { color: var(--muted); font-size: .8rem; margin: .25rem 0 0; }
.form-actions { align-items: center; display: flex; flex-wrap: wrap; gap: .75rem; margin-top: 1rem; }
.save-state { align-items: center; color: var(--muted); display: inline-flex; font-size: .8rem; gap: .35rem; min-height: 1.25rem; }
.save-state:not(:empty)::before { background: var(--success); border-radius: 50%; content: ""; height: .42rem; width: .42rem; }
.input-with-suffix { position: relative; }
.input-with-suffix .form-control { padding-right: 3.25rem; }
.input-with-suffix > span { color: var(--muted); font-size: .78rem; pointer-events: none; position: absolute; right: .8rem; top: 50%; transform: translateY(-50%); }

.token-control {
  align-items: center;
  background: var(--control-bg);
  border: 1px solid var(--control-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-control);
  display: flex;
  flex-wrap: wrap;
  gap: .35rem;
  min-height: 44px;
  padding: .35rem .45rem;
  transition: border-color 140ms ease, box-shadow 140ms ease;
}
.token-control:focus-within { background: var(--bg); border-color: var(--primary); box-shadow: 0 0 0 3px var(--focus-ring), var(--shadow-control); }
.token-list { display: contents; }
.token-chip { align-items: center; background: oklch(0.93 0.04 42); border: 1px solid oklch(0.82 0.07 42); border-radius: 999px; color: var(--primary-dark); display: inline-flex; font-size: .78rem; font-weight: 650; gap: .2rem; min-height: 30px; padding: .2rem .25rem .2rem .65rem; }
.token-chip button { align-items: center; background: transparent; border: 0; border-radius: 50%; color: currentColor; cursor: pointer; display: inline-flex; font-size: 1rem; height: 1.75rem; justify-content: center; padding: 0; width: 1.75rem; }
.token-chip button:hover { background: oklch(0.8 0.08 42 / .3); }
.token-chip button:focus-visible { outline: 2px solid var(--primary); outline-offset: 1px; }
.token-entry { background: transparent; border: 0; color: var(--ink); flex: 1 1 9rem; font: inherit; min-height: 32px; min-width: 8rem; outline: 0; padding: .2rem; }
.token-entry::placeholder { color: var(--placeholder-ink); }

.token-field { position: relative; }
.token-field-suggestions {
  background: var(--bg); border: 1px solid var(--line); border-radius: var(--radius-md);
  box-shadow: 0 8px 24px var(--shadow-tint); left: 0; list-style: none; margin: .25rem 0 0;
  max-height: 12rem; overflow-y: auto; padding: .25rem; position: absolute; right: 0; z-index: 20;
}
.token-field-suggestions li { border-radius: var(--radius-sm); cursor: pointer; font-size: .9rem; padding: .5rem .6rem; }
.token-field-suggestions li.is-active { background: var(--primary); color: white; }

.segmented-control { background: var(--surface); border: 1px solid var(--line-strong); border-radius: var(--radius-xl); display: inline-flex; gap: .2rem; padding: .2rem; }
.segmented-control label { cursor: pointer; position: relative; }
.segmented-control input { height: 1px; opacity: 0; position: absolute; width: 1px; }
.segmented-control span { align-items: center; border-radius: var(--radius-md); color: var(--muted); display: inline-flex; font-size: .8rem; font-weight: 700; min-height: 36px; padding: .4rem .7rem; }
.segmented-control input:checked + span { background: var(--bg); box-shadow: 0 1px 4px oklch(0.2 0.02 40 / .1); color: var(--primary-dark); }
.segmented-control input:focus-visible + span { outline: 3px solid var(--focus-ring); outline-offset: 1px; }

.choice-chip { cursor: pointer; transition: background-color 140ms ease, border-color 140ms ease, transform 140ms var(--ease-out); }
.choice-chip:has(input:checked) { background: oklch(0.94 0.035 42); border-color: oklch(0.72 0.11 42); color: var(--primary-dark); }
.choice-chip:active { transform: scale(.98); }
.choice-chip input { accent-color: var(--primary); height: 1rem; width: 1rem; }
.color-control { border: 1px solid var(--line-strong); border-radius: var(--radius-md); height: 44px; width: 100%; }

/* Forgejo #13: compact swatch picker -- shrinks the (previously oversized,
   full-width) native color_field down to a small "custom color" escape
   hatch once the picker mounts, sitting alongside real swatch buttons. */
.color-control.color-swatch-native { height: 1.75rem; padding: 0; width: 1.75rem; }
.color-swatch-grid { align-items: center; display: flex; flex-wrap: wrap; gap: .35rem; margin-top: .4rem; }
.color-swatch {
  background: var(--swatch-color);
  border: 2px solid transparent;
  border-radius: 50%;
  cursor: pointer;
  height: 1.75rem;
  width: 1.75rem;
}
.color-swatch:hover { border-color: var(--line); }
.color-swatch:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.color-swatch.is-selected { border-color: var(--ink); }

/* Forgejo #5: per-field help trigger + essential/collapsible field groups. */
.field-label-row { align-items: center; display: flex; gap: .4rem; margin-bottom: .35rem; }
.field-label-row .form-label { margin-bottom: 0; }
.field-help { display: inline-flex; position: relative; }
.field-help-trigger {
  align-items: center;
  background: none;
  border: 0;
  border-radius: 50%;
  color: var(--muted);
  cursor: pointer;
  display: inline-flex;
  height: 24px;
  justify-content: center;
  padding: 0;
  width: 24px;
}
.field-help-trigger:hover, .field-help-trigger[aria-expanded="true"] { background: var(--surface); color: var(--primary-dark); }
.field-help-text { background: var(--surface); border-radius: var(--radius-md); margin: .35rem 0 0; padding: .5rem .6rem; }
.field-essentials { display: grid; gap: 1rem; grid-template-columns: repeat(2, minmax(0, 1fr)); margin-bottom: 1.25rem; }
.field-essentials > .field-full { grid-column: 1 / -1; }
.field-group { border-top: 1px solid var(--line); margin-top: 1rem; }
.field-group > summary {
  align-items: center;
  cursor: pointer;
  display: flex;
  font-size: .88rem;
  font-weight: 750;
  justify-content: space-between;
  list-style: none;
  min-height: 48px;
  padding: .8rem 0;
}
.field-group > summary::-webkit-details-marker { display: none; }
.field-group > summary::after { color: var(--muted); content: "+"; font-size: 1.1rem; font-weight: 500; }
.field-group[open] > summary::after { content: "−"; }
.field-group > summary small { color: var(--muted); display: block; font-size: .74rem; font-weight: 500; margin-left: auto; margin-right: .75rem; }
.field-group.form-section { border-top: 1px solid var(--line); margin-top: 1rem; }
.field-group.form-section > summary { padding: 0; }
.field-group.form-section .field-group-body { padding: 1rem 0 0; }
.field-group-body { display: grid; gap: 1rem; grid-template-columns: repeat(2, minmax(0, 1fr)); padding-bottom: 1rem; }
.field-group-body > .field-full { grid-column: 1 / -1; }

/* Forgejo #10: quick-set shortcuts alongside the native (large, keyboard-
   accessible) date input -- not a replacement for it. */
.date-quick-actions { display: flex; gap: .4rem; margin-top: .4rem; }
.date-quick-actions .btn-secondary { font-size: .8rem; min-height: 36px; padding: .4rem .7rem; }

@media (max-width: 640px) {
  .field-essentials, .field-group-body { grid-template-columns: 1fr; }
}

/* Forgejo #6: spatial rink-area picker — thumbnail grid over the (hidden
   once JS runs) real <select>, reused by every rink-area field. */
.rink-area-picker-grid {
  display: grid;
  gap: .5rem;
  grid-template-columns: repeat(auto-fill, minmax(6rem, 1fr));
  margin-top: .35rem;
}
.rink-area-picker-grid button {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  min-height: 44px;
  padding: .35rem;
  text-align: center;
}
.rink-area-picker-grid button.is-selected {
  border-color: var(--primary);
  outline: 2px solid var(--primary);
  outline-offset: -1px;
}
.rink-area-picker-grid button:focus-visible {
  outline: 3px solid var(--focus-ring-strong);
  outline-offset: 1px;
}
.rink-area-picker-grid svg {
  background: var(--ice-surface);
  border-radius: var(--radius-sm);
  display: block;
  height: 3.25rem;
  margin: 0 auto .3rem;
  width: 100%;
}
.rink-area-picker-grid span {
  display: block;
  font-size: .75rem;
  line-height: 1.2;
}

/* Forgejo #30: popover variant for the dense editor toolbar -- same grid
   styles above, just positioned as a floating panel behind a trigger
   button instead of always inline. */
.rink-view-popover { position: relative; }
.rink-view-popover-trigger { cursor: pointer; list-style: none; }
.rink-view-popover-trigger::-webkit-details-marker { display: none; }
.rink-view-popover-trigger::marker { content: ""; }
.rink-view-popover-grid {
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: 0 8px 24px var(--shadow-tint);
  max-height: 20rem;
  max-width: 22rem;
  overflow-y: auto;
  padding: .5rem;
  position: absolute;
  z-index: 20;
}

.custom-rink-area-preview {
  background: var(--ice-surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  display: block;
  height: 8rem;
  margin-top: .5rem;
  width: 100%;
}

/* Station form "Ice area" picker: a persistent full-rink SVG with hover/tap
   targets overlaid, replacing a flat 19-thumbnail grid. See
   rink_area_map_controller.js for the interaction design. */
.rink-area-map { margin-top: .35rem; }
.rink-area-map-stage {
  background: var(--ice-surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  max-width: 26rem;
  overflow: hidden;
  position: relative;
  width: 100%;
}
.rink-area-map-stage svg { display: block; height: 100%; width: 100%; }
.rink-area-map-hint { color: var(--muted); font-size: .78rem; margin: .35rem 0 0; }
.rink-area-map-highlight {
  fill: var(--primary);
  fill-opacity: .28;
  pointer-events: none;
  stroke: var(--primary);
  stroke-width: .3;
}
.rink-area-map-highlight[hidden] { display: none; }
.rink-area-map-cells { inset: 0; position: absolute; }
.rink-area-map-cell {
  background: oklch(0.55 0.15 42 / .05);
  border: 1px dashed oklch(0.55 0.15 42 / .35);
  border-radius: var(--radius-xs);
  padding: 0;
  position: absolute;
}
.rink-area-map-cell:hover, .rink-area-map-cell:focus-visible {
  background: oklch(0.55 0.15 42 / .12);
}
.rink-area-map-cell:focus-visible {
  outline: 3px solid var(--focus-ring-strong);
  outline-offset: -2px;
}
.rink-area-map-chips {
  display: flex;
  flex-wrap: wrap;
  gap: .4rem;
  margin-top: .5rem;
}
.rink-area-map-chip {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 999px;
  font-size: .8rem;
  min-height: 36px;
  padding: .35rem .8rem;
}
.rink-area-map-chip.is-selected {
  background: var(--surface-strong);
  border-color: var(--primary);
  color: var(--primary-dark);
  font-weight: 600;
}
.rink-area-map-mobile-controls { margin-top: .5rem; }
.rink-area-map-breadcrumb { color: var(--muted); font-size: .8rem; margin: 0 0 .4rem; }
.rink-area-map-mobile-actions { display: flex; gap: .5rem; }
.rink-area-map-mobile-actions [data-area-key].is-selected {
  border-color: var(--primary);
  color: var(--primary-dark);
}
.rink-area-map-extra { margin-top: .5rem; }
.rink-area-map-extra summary { cursor: pointer; font-size: .85rem; font-weight: 600; }

/* Forgejo #11: drill search combobox */
.drill-picker { position: relative; }
.drill-picker-results {
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  box-shadow: 0 8px 24px var(--shadow-tint);
  left: 0;
  list-style: none;
  margin: .25rem 0 0;
  max-height: 16rem;
  overflow-y: auto;
  padding: .25rem;
  position: absolute;
  right: 0;
  z-index: 20;
}
.drill-picker-results li {
  border-radius: var(--radius-sm);
  cursor: pointer;
  padding: .5rem .6rem;
}
.drill-picker-results li.is-active { background: var(--primary); color: white; }
.drill-picker-results li strong { display: block; font-size: .92rem; }
.drill-picker-results li span { display: block; font-size: .75rem; opacity: .8; }

.drill-preview {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  font-size: .85rem;
  padding: .75rem;
}
.drill-preview p { margin: 0 0 .4rem; }
.drill-preview .drill-preview-meta { color: var(--muted); font-weight: 700; }
.drill-preview ul { margin: 0 0 .4rem; padding-left: 1.1rem; }
.drill-preview-diagram {
  background: var(--ice-surface);
  border-radius: var(--radius-md);
  display: block;
  height: 7rem;
  margin-top: .4rem;
  width: 100%;
}
.notice-error, .conflict-warning {
  border-radius: var(--radius-lg);
  padding: .8rem 1rem;
}
.notice-error { background: var(--danger-bg-hover); color: oklch(0.37 0.14 25); }

.flash {
  border-radius: var(--radius-md);
  left: 50%;
  max-width: min(32rem, calc(100vw - 2rem));
  opacity: 1;
  padding: .7rem 1rem;
  position: fixed;
  top: 68px;
  transition: opacity 180ms var(--ease-out), transform 180ms var(--ease-out);
  transform: translateX(-50%);
  z-index: 30;
}
.flash.is-leaving { opacity: 0; transform: translate(-50%, -.35rem); }
.flash-notice { background: oklch(0.93 0.05 155); color: oklch(0.31 0.08 155); }
.flash-alert { background: oklch(0.94 0.05 25); color: oklch(0.35 0.13 25); }

.session-list { border-top: 1px solid var(--line); }
.session-row {
  align-items: center;
  border-bottom: 1px solid var(--line);
  color: var(--ink);
  display: flex;
  gap: 1rem;
  min-height: 88px;
  padding: .9rem .5rem;
  text-decoration: none;
}
.session-row:hover { background: var(--surface); }
.session-row-link {
  align-items: center; color: inherit; display: flex; flex: 1;
  gap: 1rem; min-width: 0; text-decoration: none;
}
.session-row-duplicate { flex-shrink: 0; }
.session-row-actions { flex-shrink: 0; }
.session-date { align-items: center; display: flex; flex-direction: column; width: 3.25rem; }
.session-date span { color: var(--muted); font-size: .72rem; font-weight: 750; text-transform: uppercase; }
.session-date strong { font-size: 1.45rem; }
.session-row h2 { font-size: 1rem; font-weight: 750; margin: 0; }
.session-row p { color: var(--muted); font-size: .86rem; margin: .25rem 0 0; }
.session-duration { align-items: end; display: flex; flex-direction: column; font-size: .84rem; }
.session-duration span { color: var(--muted); }
.status-badge {
  border-radius: 999px;
  font-size: .72rem;
  font-weight: 750;
  padding: .15rem .5rem;
}
.status-planned { background: var(--status-planned-bg); color: var(--status-planned-ink); }
.status-draft { background: var(--surface-strong); color: var(--muted); }
.status-published { background: var(--status-ready-bg); color: var(--status-ready-ink); }
.status-completed { background: oklch(0.91 0.05 205); color: oklch(0.32 0.09 205); }

.status-switcher { align-items: center; display: inline-flex; flex-wrap: wrap; gap: .35rem; }
.status-switcher-form { display: inline-flex; }
.status-switcher-button {
  border: 1px solid transparent;
  border-radius: 999px;
  cursor: pointer;
  font-size: .72rem;
  font-weight: 750;
  min-height: 30px;
  padding: .15rem .6rem;
}
.status-switcher-button:hover { border-color: var(--line); }
.status-switcher-button.is-active { border-color: currentColor; }
.empty-state { border-top: 1px solid var(--line); padding: 4rem 1rem; text-align: center; }
.empty-state h2 { font-size: 1.2rem; margin: 0; }
.empty-state p { color: var(--muted); margin: .5rem auto 1.5rem; max-width: 34rem; }

.library-page { max-width: 64rem; }
.library-heading { align-items: center; }
.library-search {
  background: var(--surface);
  border-radius: var(--radius-2xl);
  margin-bottom: 2rem;
  padding: 1rem;
}
.library-search-row { align-items: end; display: flex; gap: .75rem; }
.library-search-field { flex: 1; }
.library-search-field label {
  display: block;
  font-size: .82rem;
  font-weight: 750;
  margin-bottom: .35rem;
}
.library-search-field input {
  background: var(--bg);
  border: 1px solid oklch(0.67 0.018 45);
  border-radius: var(--radius-md);
  color: var(--ink);
  font: inherit;
  min-height: 46px;
  padding: .65rem .8rem;
  width: 100%;
}
.library-search-field input::placeholder { color: oklch(0.42 0.015 40); }
.library-search-field input:focus {
  border-color: var(--primary);
  outline: 3px solid var(--focus-ring-strong);
  outline-offset: 1px;
}
/* The drill library keeps its disclosure (it holds seven controls, not two),
   but its body now uses the same surface, labels and chips as .filter-bar on
   the Spieler and session listings. */
.library-filter-panel { border-top: 1px solid var(--line); margin-top: 1rem; }
.library-filter-panel > summary {
  align-items: center;
  cursor: pointer;
  display: flex;
  font-size: .88rem;
  font-weight: 750;
  justify-content: space-between;
  list-style: none;
  min-height: 48px;
}
.library-filter-panel > summary::-webkit-details-marker { display: none; }
.library-filter-panel > summary::after { content: "+"; font-size: 1.2rem; margin-left: .6rem; }
.library-filter-panel[open] > summary::after { content: "−"; }
.filter-summary { color: var(--muted); font-size: .78rem; font-weight: 500; margin-left: auto; }
.filter-count {
  background: var(--primary);
  border-radius: 999px;
  color: var(--bg);
  font-size: .72rem;
  font-weight: 700;
  margin-left: auto;
  padding: .2rem .55rem;
}
.library-filter-body {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-2xl);
  display: flex;
  flex-direction: column;
  gap: .9rem;
  margin-bottom: 1rem;
  padding: .9rem .95rem;
}
.library-filter-grid {
  display: grid;
  gap: .9rem 1.1rem;
  /* auto-fit rather than a fixed 3, because the four listings bring very
     different group counts (one status group on Sessions, seven selects on
     Drills) into the same menu. */
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
}
.favourites-filter {
  align-items: center;
  cursor: pointer;
  display: inline-flex;
  font-size: .88rem;
  font-weight: 650;
  gap: .55rem;
  min-height: 44px;
  margin-top: .75rem;
}
.favourites-filter input { height: 1.1rem; width: 1.1rem; }
.library-filter-actions { align-items: center; display: flex; gap: .6rem; justify-content: flex-end; margin-top: 0; }
.library-results-heading {
  align-items: baseline;
  display: flex;
  justify-content: space-between;
  margin-bottom: .5rem;
}
.library-results-heading h2 { font-size: 1rem; margin: 0; }
.library-results-heading p { color: var(--muted); font-size: .82rem; margin: 0; }
.drill-library-list { border-top: 1px solid var(--line); }
.drill-library-row {
  align-items: center;
  border-bottom: 1px solid var(--line);
  display: grid;
  gap: 1rem;
  grid-template-columns: minmax(0, 1fr) auto auto;
  min-height: 104px;
  padding: 1rem .25rem;
  transition: background-color 180ms ease-out;
}
.drill-library-row:hover { background: var(--surface); }
.drill-library-title { color: var(--ink); display: block; text-decoration: none; }
.drill-library-title > span { font-size: 1rem; font-weight: 760; }
.drill-library-title small {
  color: var(--muted);
  display: block;
  font-size: .84rem;
  line-height: 1.35;
  margin-top: .25rem;
  max-width: 65ch;
}
.drill-library-meta { display: flex; flex-wrap: wrap; gap: .25rem .8rem; margin-top: .55rem; }
.drill-library-meta span { color: var(--muted); font-size: .76rem; }
.drill-library-signals {
  align-items: flex-end;
  display: flex;
  flex-direction: column;
  font-size: .78rem;
  gap: .25rem;
  min-width: 5rem;
}
.drill-library-signals span:first-child { color: oklch(0.4 0.1 75); font-weight: 750; }
.drill-library-signals .signal-muted { color: var(--muted); font-weight: 500; }
.favourite-form { margin: 0; }
.favourite-button {
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  color: var(--ink);
  cursor: pointer;
  font: inherit;
  font-size: .78rem;
  font-weight: 700;
  min-height: 44px;
  padding: .55rem .7rem;
}
.favourite-button:hover { background: var(--surface-strong); }
.favourite-button.is-favourite {
  background: oklch(0.93 0.045 42);
  border-color: oklch(0.76 0.08 42);
  color: var(--primary-dark);
}
.drill-feedback {
  align-items: center;
  background: var(--surface);
  border-radius: var(--radius-2xl);
  display: flex;
  gap: 1rem;
  margin: .25rem 0 1.5rem;
  padding: .85rem 1rem;
}
.drill-feedback-summary { display: flex; flex-direction: column; margin-right: auto; }
.drill-feedback-summary strong { font-size: .9rem; }
.drill-feedback-summary span { color: var(--muted); font-size: .76rem; margin-top: .15rem; }
.rating-form { align-items: center; display: flex; gap: .5rem; }
.rating-form label { font-size: .8rem; font-weight: 700; }
.rating-form .form-control { min-width: 10rem; width: auto; }

@media (max-width: 720px) {
  .library-heading { align-items: stretch; }
  .library-heading .btn-primary { width: 100%; }
  .library-search { margin-inline: -1rem; border-radius: 0; }
  .library-search-row { align-items: stretch; flex-direction: column; }
  .library-search-row .btn-primary { width: 100%; }
  .library-filter-grid { grid-template-columns: 1fr; }
  .filter-summary { display: none; }
  .library-filter-actions > * { flex: 1; }
  .drill-library-row {
    gap: .65rem;
    grid-template-columns: minmax(0, 1fr) auto;
    padding: 1rem 0;
  }
  .drill-library-signals {
    align-items: flex-start;
    flex-direction: row;
    grid-column: 1;
    grid-row: 2;
  }
  .favourite-form { grid-column: 2; grid-row: 1 / span 2; }
  .drill-feedback { align-items: stretch; flex-direction: column; }
  .rating-form { align-items: stretch; flex-wrap: wrap; }
  .rating-form label { flex-basis: 100%; }
  .rating-form .form-control { flex: 1; min-width: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .drill-library-row { transition: none; }
}

.builder-header {
  align-items: end;
  display: flex;
  gap: 1rem;
  justify-content: space-between;
  margin-bottom: 1.5rem;
}
.builder-totals { align-items: center; display: flex; flex-wrap: wrap; gap: .75rem; }
.builder-totals > span { color: var(--muted); font-size: .82rem; }
.builder-totals > span strong { color: var(--ink); display: block; font-size: 1rem; }
.builder-totals .is-mismatch strong { color: var(--danger); }
/* Deliberately understated: a compact, right-aligned pill rather than a
   full-width banner. It is sticky, so at its old 58px full-bleed size it sat
   on top of whatever a station anchor scrolled to (see .station's
   scroll-margin-top below, which is the other half of that fix). */
.builder-save-bar {
  align-items: center;
  backdrop-filter: blur(6px);
  background: oklch(1 0 0 / .9);
  border: 1px solid var(--line);
  border-radius: 999px;
  box-shadow: var(--shadow-control);
  display: flex;
  gap: .5rem;
  margin: 0 0 .75rem auto;
  max-width: 100%;
  min-height: 42px;
  padding: .25rem .35rem .25rem .75rem;
  position: sticky;
  top: 68px;
  width: fit-content;
  z-index: var(--z-builder-save);
}
.builder-save-bar > div { align-items: baseline; display: flex; flex: 0 1 auto; gap: .4rem; min-width: 0; }
.builder-save-bar strong { font-size: .78rem; font-weight: 650; }
.builder-save-bar small { color: var(--muted); font-size: .7rem; }
.builder-save-bar .btn-primary { font-size: .78rem; min-height: 34px; padding: .35rem .8rem; }
.builder-save-indicator { background: var(--success); border-radius: 50%; height: .55rem; width: .55rem; }
[data-save-state="dirty"] .builder-save-indicator { background: var(--warning-ink); }
[data-save-state="saving"] .builder-save-indicator { background: var(--accent); }
[data-save-state="error"] .builder-save-indicator { background: var(--danger); }
[data-save-state="error"] .builder-save-bar strong { color: var(--danger); }
.builder-section { margin-bottom: 1.25rem; overflow: clip; position: relative; }
.builder-section > summary {
  align-items: center;
  cursor: pointer;
  display: flex;
  gap: .75rem;
  justify-content: space-between;
  list-style: none;
  min-height: 60px;
  padding: .8rem 1rem;
}
.builder-section > summary::-webkit-details-marker { display: none; }
.builder-section > summary:focus-visible {
  outline: 3px solid var(--focus-ring);
  outline-offset: -3px;
}
.builder-section > summary small { color: var(--muted); display: block; font-size: .8rem; }
.builder-section-body, .people-layout { border-top: 1px solid var(--line); padding: 1.25rem; }
.session-setup-overview { min-width: 0; }
.session-setup-overview small { line-height: 1.45; text-wrap: pretty; }
.session-setup-edit {
  align-items: center;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  display: inline-flex;
  flex: 0 0 auto;
  font-size: .84rem;
  font-weight: 700;
  gap: .4rem;
  justify-content: center;
  min-height: 44px;
  padding: .55rem .75rem;
}
.session-setup > summary:hover .session-setup-edit, .roster-setup > summary:hover .session-setup-edit { background: var(--surface); }
.session-setup-done-label { display: none; }
.session-setup[open] .session-setup-edit-label, .roster-setup[open] .session-setup-edit-label { display: none; }
.session-setup[open] .session-setup-done-label, .roster-setup[open] .session-setup-done-label { display: inline; }
.session-setup-actions { align-items: center; display: inline-flex; flex: 0 0 auto; gap: .5rem; }
.session-setup[open] .session-setup-quick-add { display: none; }
.session-setup-quick-add-form { display: none; }
.session-setup-content { border-top: 1px solid var(--line); }
.session-setup-content > .builder-section-body { border-top: 0; }
.people-section { border-top: 1px solid var(--line); }
.people-heading { padding: 1.25rem 1.25rem 0; }
.people-heading h2 { font-size: 1rem; margin: 0 0 .25rem; }
.people-heading p { color: var(--muted); font-size: .84rem; margin: 0; }
.people-section .people-layout { border-top: 0; }
.section-heading { align-items: end; display: flex; justify-content: space-between; padding: 1.2rem 1.25rem; }
.section-heading h2 { font-size: 1.15rem; margin: 0 0 .2rem; }
.people-layout { display: grid; gap: 2rem; grid-template-columns: 1fr 1fr; }
.people-layout h3 { font-size: .9rem; margin: 0 0 .7rem; }
.people-list > div { align-items: center; border-bottom: 1px solid var(--line); display: flex; min-height: 56px; }
.people-list i {
  background: var(--person-color);
  border-radius: 50%;
  height: .75rem;
  margin-right: .7rem;
  width: .75rem;
}
.people-list span { display: flex; flex: 1; flex-direction: column; font-size: .86rem; }
.people-list small { color: var(--muted); }
.inline-add, .add-segment { margin-top: 1rem; }
.inline-add > summary, .add-segment > summary {
  color: var(--primary-dark);
  cursor: pointer;
  font-size: .88rem;
  font-weight: 700;
  list-style: none;
  min-height: 44px;
  padding: .7rem 0;
}
.inline-add > form { border-top: 1px solid var(--line); padding-top: 1rem; }

.builder-plan { margin-top: 2rem; }
.segment-tabs-shell { border-bottom: 1px solid var(--line); }
.segment-tabs-scroll { align-items: flex-end; display: flex; gap: .35rem; overflow-x: auto; padding: .15rem .1rem 0; scrollbar-width: thin; }
.segment-tabs { display: flex; flex: 0 0 auto; gap: .35rem; list-style: none; margin: 0; padding: 0; }
.segment-tab-item, .roster-tab-item {
  align-items: center;
  background: var(--surface);
  border: 1px solid var(--line);
  border-bottom: 0;
  border-radius: var(--radius-md) var(--radius-md) 0 0;
  display: inline-flex;
  height: 40px;
  overflow: hidden;
  position: relative;
  transition: background-color 180ms var(--ease-out), border-color 180ms var(--ease-out);
}
.segment-tab-item.is-sorting { opacity: .6; }
.segment-tab-item.is-active, .roster-tab-item.is-active { background: var(--bg); box-shadow: var(--shadow-tab-seam); }
.segment-tab-item:not(.is-active):hover, .roster-tab-item:not(.is-active):hover { background: var(--control-hover); }
.segment-tab-handle {
  align-items: center;
  color: var(--muted);
  cursor: grab;
  display: inline-flex;
  font-size: .7rem;
  height: 100%;
  justify-content: center;
  touch-action: none;
  width: 24px;
}
.segment-tab, .roster-tab {
  background: transparent;
  border: 0;
  color: var(--muted);
  cursor: pointer;
  font: inherit;
  font-size: .82rem;
  font-weight: 700;
  height: 100%;
  padding: .5rem .8rem .5rem .3rem;
  white-space: nowrap;
}
.segment-tab[aria-selected="true"], .roster-tab[aria-selected="true"] { color: var(--ink); }
.segment-tab:focus-visible, .segment-add-tab:focus-visible, .segment-tab-handle:focus-visible { outline: 3px solid var(--focus-ring); outline-offset: -2px; }

/* Same visual language as .segment-tabs/.segment-tab above, but a distinct
   class -- a page-wide test asserts there is exactly one
   button.segment-tab[aria-selected="true"] on the whole builder page, so the
   roster's own tab-pair (a separate, unrelated tab group) must not share
   that literal class. */
.roster-tabs { display: flex; flex: 0 0 auto; gap: .35rem; list-style: none; margin: 0; padding: 0; }
/* Everything else (the tab's box, active/hover states, colors) is shared with
   .segment-tab-item/.segment-tab above -- the roster pair only keeps its own
   class names so a page-wide test can still count exactly one selected
   button.segment-tab. A roster tab has no drag handle to its left, so it is
   the one declaration that genuinely differs. */
.roster-tab { padding: .5rem .8rem; }
.roster-tab:focus-visible { outline: 3px solid var(--focus-ring); outline-offset: -2px; }

/* Player roster (§7/§15 amendment): "Spieler" 3-zone board + "Gruppen" Kanban. */
.roster-zones, .roster-kanban { display: flex; flex-wrap: wrap; gap: 1rem; margin: 1rem 0; }
.roster-zone {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  flex: 1 1 200px;
  list-style: none;
  margin: 0;
  min-height: 4rem;
  padding: .5rem;
}
.roster-zone-heading { color: var(--muted); font-size: .78rem; font-weight: 700; margin: 0 0 .4rem; text-transform: uppercase; }
.roster-chip {
  align-items: center;
  border-radius: var(--radius-sm);
  cursor: grab;
  display: flex;
  font-size: .86rem;
  gap: .35rem;
  justify-content: space-between;
  margin: 0 0 .35rem;
  padding: .35rem .5rem;
}
.roster-chip.is-dragging { opacity: .5; }
.roster-chip-unassigned { background: var(--control-hover); }
.roster-chip-light { background: #fef9c3; color: #713f12; }
.roster-chip-dark { background: #1f2937; color: #f9fafb; }
/* The per-chip <details> text menu was replaced by always-visible toggle
   buttons plus a trash button, so those three rules are gone with it. */
.roster-chip-number { flex: 0 0 auto; font-variant-numeric: tabular-nums; min-width: 1.4rem; opacity: .65; text-align: right; }
/* The Gruppen panel renders the same chip without a number (its columns are
   groups, not zones). The slot stays in the markup so the ERB partial and
   buildChipElement remain structurally identical, but takes no space. */
.roster-chip-number:empty { display: none; }
.roster-chip-name { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.roster-chip-controls { display: flex; flex: 0 0 auto; gap: .15rem; }
.roster-zone-button {
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  color: inherit;
  cursor: pointer;
  font: inherit;
  font-size: .74rem;
  font-weight: 700;
  line-height: 1;
  min-height: 24px;
  min-width: 24px;
  opacity: .6;
  padding: 0 .25rem;
}
.roster-zone-button:hover { opacity: 1; }
.roster-zone-button[aria-pressed="true"] { border-color: currentColor; opacity: 1; }
.roster-zone-button:focus-visible, .roster-chip-remove:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 1px; }
/* Set apart from the zone toggles, and only fully opaque on hover: a
   mis-click here during drag-heavy work deletes a roster row. */
/* Forgejo #92: deliberately NOT given the 44px hit-area overlay the other
   dense controls get, and deliberately still under 44px. This is a DESTRUCTIVE
   control sitting a few px from the chip's zone buttons and its name, inside a
   ~30px-tall chip. A centred 44px area would reach ~10px past the button on
   every side and swallow clicks meant for its siblings -- turning a
   hard-to-hit button into an easy-to-hit delete, which is strictly worse than
   the small target it was meant to fix. 30px fits the chip's existing height
   budget without growing it. Same reasoning for `.token-chip button`. */
.roster-chip-remove {
  background: transparent;
  border: 0;
  color: inherit;
  cursor: pointer;
  display: inline-flex;
  margin-left: .3rem;
  min-height: 30px;
  min-width: 30px;
  opacity: .5;
  padding: 0;
  place-items: center;
}
.roster-chip-remove:hover { color: var(--danger); opacity: 1; }
.roster-chip-remove svg { display: block; }
.segment-add-tab {
  align-items: center;
  background: var(--surface);
  border: 1px solid var(--line);
  border-bottom: 0;
  border-radius: var(--radius-md) var(--radius-md) 0 0;
  color: var(--primary-dark);
  cursor: pointer;
  display: inline-flex;
  flex: 0 0 auto;
  font: inherit;
  font-size: .78rem;
  font-weight: 700;
  gap: .35rem;
  height: 40px;
  justify-content: center;
  padding: 0 .7rem;
  transition: background-color 180ms var(--ease-out), border-color 180ms var(--ease-out);
}
.segment-add-tab:not([aria-selected="true"]):hover { background: var(--control-hover); }
.segment-add-tab[aria-selected="true"] { background: var(--bg); box-shadow: var(--shadow-tab-seam); color: var(--ink); }
.segment-workspace { border: 1px solid var(--line); border-top: 0; overflow: clip; }
.segment-workspace[hidden] { display: none; }
.segment-workspace-header {
  align-items: center;
  background: var(--surface);
  border-bottom: 1px solid var(--line);
  display: flex;
  gap: 1rem;
  justify-content: space-between;
  min-height: 72px;
  padding: .8rem 1rem;
}
.segment-workspace-header h3 { font-size: 1rem; margin: 0; }
.segment-workspace-header p { color: var(--muted); font-size: .8rem; margin: .2rem 0 0; }
.segment-workspace-toggle {
  cursor: pointer;
  transition: background-color 180ms var(--ease-out);
}
.segment-workspace-toggle:hover { background: var(--control-hover); }
.segment-header-toggle { border-radius: var(--radius-sm); outline: none; }
.segment-header-toggle:focus-visible {
  outline: 3px solid var(--focus-ring);
  outline-offset: 3px;
}
.segment-workspace-actions { align-items: center; display: flex; gap: .45rem; }
.segment-workspace-actions .btn-secondary { gap: .4rem; }
.segment-settings {
  align-items: end;
  display: grid;
  gap: .6rem;
  grid-template-columns: minmax(10rem, 2fr) repeat(3, minmax(7rem, 1fr));
}
.segment-edit-fields, .segment-new-fields { background: var(--bg); border-bottom: 1px solid var(--line); padding: 1rem; }
.segment-edit-fields[hidden] { display: none; }
.segment-edit-actions { display: flex; grid-column: 1 / -1; justify-content: flex-end; }
.segment-new-workspace .segment-workspace-header { background: var(--bg); }
.segment-new-fields { border-bottom: 0; grid-template-columns: minmax(10rem, 2fr) repeat(3, minmax(7rem, 1fr)) auto; }
.segment-stations-heading {
  align-items: center;
  border-top: 1px solid var(--line);
  display: flex;
  justify-content: space-between;
  padding: .8rem 1rem;
}
.segment-stations-heading h4 { font-size: .92rem; margin: 0; }
.segment-stations-heading p { color: var(--muted); font-size: .76rem; margin: .1rem 0 0; }
.segment-workspace [id$="-ice-context"] { padding: 1rem; }

.segment-diagram-heading {
  align-items: center;
  border-top: 1px solid var(--line);
  display: flex;
  gap: 1rem;
  justify-content: space-between;
  padding: .8rem 1rem .55rem;
}
.segment-diagram-heading h4 { font-size: .92rem; margin: 0; }
.segment-diagram-heading p { color: var(--muted); font-size: .76rem; margin: .1rem 0 0; }
.copy-diagram-control { align-items: center; display: flex; flex: 0 1 auto; gap: .4rem; }
.copy-diagram-control select { flex: 0 1 12rem; min-width: 8rem; width: auto; }
.copy-diagram-control > button { flex: 0 0 auto; }

/* One rink per segment; what is drawn on it comes from the segment's own
   show_station_overlay / show_layout_overlay switches. */
.segment-rinks { margin-top: 1rem; }
.segment-rink-switches {
  align-items: center;
  border-bottom: 1px solid var(--line);
  display: flex;
  flex-wrap: wrap;
  gap: .5rem;
  margin: 0 1rem;
  padding: 0 0 .6rem;
}
/* On the read-only session page the same switches sit inside a run-sheet
   article, which has no 1rem gutter to align to. (.no-print itself is
   already handled by the print stylesheet further down.) */
.run-sheet .segment-rink-switches { border-bottom: 0; margin: .75rem 0 0; padding: 0; }
.segment-rink-switches > .form-label { margin: 0 .25rem 0 0; }
.segment-rink-switches > small { color: var(--muted); font-size: .74rem; }
.ice-map { margin: 0; }
.ice-map svg {
  background: var(--ice-surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  display: block;
  max-height: var(--rink-max-height);
  width: 100%;
}
.ice-map-legend { display: flex; flex-wrap: wrap; gap: .35rem; margin-top: .5rem; }
.ice-map-legend > button, .ice-map-legend > span { align-items: center; background: transparent; border: 0; border-radius: var(--radius-sm); color: var(--ink); display: flex; font: inherit; font-size: .78rem; gap: .3rem; min-height: 36px; padding: .25rem .45rem; }
.ice-map-legend button { cursor: pointer; }
.ice-map-legend button:hover { background: var(--surface); }
.ice-map-legend button:focus-visible { outline: 3px solid var(--focus-ring); outline-offset: 1px; }
.ice-map-legend i { background: var(--station-color); border-radius: 50%; height: .55rem; width: .55rem; }
.ice-map-allocation[role="button"] { cursor: pointer; outline: none; }
.ice-map-allocation rect { transition: fill-opacity 180ms var(--ease-out), stroke-width 180ms var(--ease-out); }
.ice-map-allocation[role="button"]:hover rect, .ice-map-allocation[role="button"]:focus rect, .ice-map-allocation.is-selected rect { fill-opacity: .42; stroke-width: .75; }
/* Forgejo #97. The other four `outline: none` sites all pair with a real
   replacement (.form-control's 3px ring, .token-control's :focus-within ring,
   .segment-header-toggle's :focus-visible, and the editor canvas, which is
   deliberate and desktop-only). This one did not: a 1px drop-shadow in
   --focus-ring (34% alpha) is not a visible focus indicator on an SVG rect.
   Drive the rect's own stroke instead -- it is already the shape's outline and
   already has a transition, so focus reads the same way selection does. */
.ice-map-allocation:focus-visible rect {
  stroke: var(--primary);
  stroke-width: 1.4;
}

/* Segment diagram edit gate: one panel visible at a time -- the combined
   read-only preview (diagram + station allocations, .diagram-stations-panel)
   by default, the live editable canvas (.diagram-layout-panel) only once
   "Edit diagram" is clicked and the Layout tab is active. */
.segment-workspace-actions .btn-primary { gap: .4rem; }
/* Layout/Stations are a tab strip with the same shape as .segment-tabs above,
   but in a cool "ice" hue instead of the warm segment palette -- the level
   change (inside a segment, not between segments) has to be readable at a
   glance. Own class names, never .segment-tab: a page-wide controller test
   asserts exactly one selected button.segment-tab on the builder page. */
.diagram-tabs-shell { border-bottom: 1px solid var(--diagram-line); margin: 0 1rem; }
.diagram-tabs { align-items: flex-end; display: flex; gap: .35rem; list-style: none; margin: 0; padding: .2rem 0 0; }
.diagram-tab-item { display: inline-flex; }
.diagram-tab {
  background: var(--diagram-tab-bg);
  border: 1px solid var(--diagram-line);
  border-bottom: 0;
  border-radius: var(--radius-md) var(--radius-md) 0 0;
  color: var(--diagram-tab-ink);
  cursor: pointer;
  font: inherit;
  font-size: .8rem;
  font-weight: 700;
  min-height: 38px;
  padding: .35rem .95rem;
  transition: background-color 180ms var(--ease-out), color 180ms var(--ease-out);
}
.diagram-tab:hover { background: var(--diagram-tab-hover); }
.diagram-tab[aria-pressed="true"] {
  background: var(--bg);
  border-color: var(--diagram-tab-active-border);
  box-shadow: var(--shadow-tab-seam);
  color: var(--diagram-tab-ink-active);
}
.diagram-tab:focus-visible { outline: 3px solid var(--focus-ring); outline-offset: -2px; }
.diagram-workspace .diagram-layout-panel { display: none; }
.diagram-workspace[data-diagram-mode="edit"][data-diagram-view="layout"] .diagram-layout-panel { display: block; }
.diagram-workspace[data-diagram-mode="edit"][data-diagram-view="layout"] .diagram-stations-panel { display: none; }
/* Editing is desktop-only (matches editor--stage's own 1024px media-query
   gate) -- below that, only the combined read-only preview is reachable.
   The :not([hidden]) guard matters: without it this would out-cascade the
   UA's native [hidden] rule and show the Done/view-switch controls even
   while JS still has them hidden. */
[data-diagram-edit-action], [data-diagram-done-action], [data-diagram-view-switch] { display: none; }
@media (min-width: 1024px) {
  [data-diagram-edit-action]:not([hidden]), [data-diagram-done-action]:not([hidden]) { display: inline-flex; }
  [data-diagram-view-switch]:not([hidden]) { display: flex; }
}
.conflict-warning {
  align-items: baseline;
  background: var(--warning-bg);
  color: var(--warning-ink);
  display: flex;
  font-size: .83rem;
  gap: .5rem;
  margin: .8rem 0;
}
.conflict-warning ul { margin: 0; padding-left: 1.1rem; }

/* Forgejo #12: segment-level rotation matrix, replacing the old per-station
   "Group rotation" <select>. */
.rotation-matrix-section { margin: 1rem 0; }
.rotation-matrix-header {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  gap: .75rem;
  justify-content: space-between;
  margin-bottom: .6rem;
}
.rotation-matrix-header h4 { margin: 0; }
.rotation-matrix-form { overflow-x: auto; }
.rotation-matrix { border-collapse: collapse; font-size: .83rem; min-width: 100%; }
.rotation-matrix th, .rotation-matrix td { padding: .35rem .5rem; text-align: left; }
.rotation-matrix thead th { border-bottom: 1px solid var(--line); color: var(--muted); font-weight: 600; }
.rotation-matrix tbody th { border-right: 1px solid var(--line); font-weight: 600; white-space: nowrap; }
.rotation-matrix td select { min-width: 8rem; }
.duplicate-banner {
  align-items: center;
  background: var(--surface-strong);
  border-left: 3px solid var(--accent);
  display: flex;
  flex-wrap: wrap;
  font-size: .87rem;
  gap: .75rem;
  justify-content: space-between;
  margin: 0 0 1rem;
  padding: .8rem 1rem;
}

.stations-group + .stations-group { border-top: 1px solid var(--line); }
.stations-group-heading {
  color: var(--muted);
  font-size: .78rem;
  font-weight: 700;
  letter-spacing: .02em;
  margin: 0;
  padding: .75rem 1rem 0;
  text-transform: uppercase;
}
.stations { padding: 0 1rem 1rem; }
.station-arrangement-badge {
  align-items: center;
  background: var(--surface-strong);
  border-radius: var(--radius-sm);
  display: inline-flex;
  font-size: .85rem;
  height: 1.4rem;
  justify-content: center;
  margin-right: .35rem;
  width: 1.4rem;
}
.station { border-top: 1px solid var(--line); transition: background-color 180ms var(--ease-out); }
/* Clears the sticky app header plus the (now compact) .builder-save-bar, so
   clicking a station on the ice map scrolls its heading into view instead of
   under the save bar. */
.station { scroll-margin-top: 8rem; }
.station:last-child { border-bottom: 1px solid var(--line); }
.station.is-selected { background: oklch(0.97 0.025 42); }
.station-summary {
  align-items: center;
  display: flex;
  gap: .35rem;
  list-style: none;
  min-height: 68px;
  padding: .5rem .35rem;
}
.station-number {
  align-items: center;
  background: var(--surface-strong);
  border-radius: var(--radius-sm);
  display: flex;
  font-size: .8rem;
  font-weight: 800;
  height: 2rem;
  justify-content: center;
  margin-right: .75rem;
  width: 2rem;
  cursor: grab;
  touch-action: none;
}
.station-summary strong, .station-summary small { display: block; }
.station-summary small { color: var(--muted); font-size: .78rem; margin-top: .15rem; }
.station-move { display: flex; }
.station-move button {
  background: transparent;
  border: 0;
  color: var(--muted);
  cursor: pointer;
  height: 44px;
  width: 30px;
}
.station-expand-button {
  align-items: center;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  color: var(--ink);
  cursor: pointer;
  display: inline-flex;
  font: inherit;
  font-size: .78rem;
  font-weight: 700;
  gap: .35rem;
  justify-content: center;
  min-height: 40px;
  min-width: 92px;
  padding: .4rem .65rem;
}
.station-expand-button:hover { background: var(--control-hover); }
.station-expand-button:focus-visible { outline: 3px solid var(--focus-ring); outline-offset: 1px; }
.station-expand-button b { color: var(--muted); font-size: 1rem; transition: transform 180ms var(--ease-out); }
.station.is-expanded .station-expand-button b { transform: rotate(180deg); }
.station-remove { flex: 0 0 auto; }
.station-form { background: var(--surface); border-top: 1px solid var(--line); padding: 1rem; }
.station-form > * + * { margin-top: 1rem; }
/* Title and Drill are row 1's two cells; the drill preview and the optional
   disclosures span the full grid so neither gets wedged into half a column. */
.drill-preview, .station-optional-row { grid-column: 1 / -1; }
.station-new-drill { gap: .3rem; margin-top: .5rem; width: fit-content; }
.station-optional-row { display: flex; flex-wrap: wrap; gap: .75rem 1.5rem; }
.station-optional { flex: 0 1 auto; min-width: 0; }
/* Two collapsed "+ optional" summaries sit side by side; an expanded one --
   or a parallel station's always-inline ice area, which has no <details> at
   all -- takes a full row, since the rink-area picker runs up to 26rem. */
.station-optional:has(> details[open]), .station-optional:not(:has(> details)) { flex: 1 1 100%; }
.station-optional-disclosure > summary {
  align-items: center;
  color: var(--primary-dark);
  cursor: pointer;
  display: flex;
  font-size: .8rem;
  font-weight: 700;
  gap: .3rem;
  list-style: none;
  min-height: 36px;
}
.station-optional-disclosure > summary::-webkit-details-marker { display: none; }
.station-optional-disclosure > summary em { color: var(--muted); font-style: normal; font-weight: 500; }
.station-optional-disclosure > summary:hover { text-decoration: underline; }
.station-optional-disclosure > summary:focus-visible { outline: 3px solid var(--focus-ring); outline-offset: 2px; }
.station-optional-disclosure[open] > summary svg { transform: rotate(45deg); }
.station-optional-disclosure > summary svg { transition: transform 140ms var(--ease-out); }
.station-optional-disclosure .station-optional-body { padding-bottom: .25rem; }
.station-optional-body > * + * { margin-top: .6rem; }
.station-duration-input { max-width: 7rem; }
.station-form-actions { align-items: center; display: flex; flex-wrap: wrap; gap: .75rem; justify-content: flex-end; }
.choice-row { display: flex; flex-wrap: wrap; gap: .5rem; }
.choice-chip {
  align-items: center;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 999px;
  display: inline-flex;
  font-size: .8rem;
  gap: .4rem;
  min-height: 44px;
  padding: .4rem .7rem;
}
.choice-chip i {
  background: var(--chip-color);
  border-radius: 50%;
  height: .55rem;
  width: .55rem;
}

/* Forgejo #9: utilities first, Edit immediately before Run, Run dominant and
   far right (source order == visual order, no CSS `order` needed). */
.session-actions { display: flex; flex-wrap: wrap; gap: .5rem; }
.session-action { gap: .4rem; }

@media (max-width: 640px) {
  .session-actions .action-label { display: none; }
}

.session-summary { border-bottom: 1px solid var(--line); border-top: 1px solid var(--line); display: grid; grid-template-columns: repeat(4, 1fr); }
.session-summary > div { padding: 1rem; }
.session-summary span, .session-summary strong { display: block; }
.session-summary span { color: var(--muted); font-size: .75rem; }
.session-summary strong { font-size: .95rem; margin-top: .2rem; }
.session-summary .status-switcher { margin-top: .3rem; }
.session-intent { display: grid; gap: 2rem; grid-template-columns: 1fr 1fr; padding: 2rem 0; }
.session-intent h2, .run-sheet > h2, .run-sheet-heading h2 { font-size: 1rem; margin: 0 0 .5rem; }
.run-sheet-heading { align-items: baseline; display: flex; flex-wrap: wrap; gap: .5rem 1rem; justify-content: space-between; }
.rink-display-batch { align-items: center; display: flex; flex-wrap: wrap; gap: .4rem; }
.rink-display-batch > .form-label { margin: 0 .15rem 0 0; }
.rink-display-batch form { display: inline-flex; }
.session-intent p, .session-intent ul { color: var(--muted); margin: 0; }
.run-sheet { display: grid; gap: 1rem; margin-top: 1.5rem; }
.run-sheet > article {
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--radius-2xl);
  padding: 1.25rem 1.5rem;
}
.run-sheet article > header { display: flex; gap: 1rem; }
.run-sheet time { color: var(--primary-dark); font-size: .9rem; font-weight: 800; width: 4rem; }
.run-sheet h3 { font-size: 1rem; margin: 0; }
.run-sheet header p { color: var(--muted); font-size: .8rem; margin: .2rem 0; }
.run-stations { display: grid; gap: 1px; grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr)); margin-top: 1rem; }
.run-stations > div { align-items: center; background: var(--surface); display: flex; gap: .6rem; min-height: 64px; padding: .7rem; }
.run-stations > div > span { align-items: center; background: var(--ink); border-radius: 50%; color: white; display: flex; font-size: .75rem; height: 1.75rem; justify-content: center; width: 1.75rem; }
.run-stations p { display: flex; flex: 1; flex-direction: column; font-size: .8rem; margin: 0; }
.run-stations small, .muted-copy { color: var(--muted); }
/* A segment with no stations and no drills renders no rink at all, which on
   its own just looks like something failed to load -- this says what is
   missing and what it costs the plan. */
.segment-empty {
  background: var(--surface);
  border: 1px dashed var(--line);
  border-radius: var(--radius-lg);
  margin-top: 1rem;
  padding: .9rem 1rem;
}
.segment-empty p { color: var(--muted); font-size: .84rem; margin: 0 0 .4rem; }
.segment-empty p strong { color: var(--ink); }
.segment-empty p:last-of-type { margin-bottom: .6rem; }
.segment-empty .text-link { font-size: .84rem; }

@media (max-width: 767px) {
  .app-header { padding: 0 .75rem; }
  .app-mark { margin-right: .5rem; }
  .app-user { display: none; }
  .app-header nav { margin-right: -.75rem; padding-right: .75rem; scroll-padding-inline: .5rem; scrollbar-width: none; }
  .app-header nav::-webkit-scrollbar { display: none; }
  .app-header nav a { padding-inline: .7rem; }
  .app-header nav a.is-current { scroll-margin-inline: .5rem; }
  .app-main { padding: 1.25rem .75rem 5rem; }
  .page-heading, .builder-header { align-items: stretch; flex-direction: column; }
  .page-heading .btn-primary { width: 100%; }
  .form-grid, .station-form-main, .people-layout, .session-intent { grid-template-columns: 1fr; }
  .session-duration { display: none; }
  .session-row-duplicate { font-size: .78rem; padding: .35rem .6rem; }
  .builder-totals { border-top: 1px solid var(--line); padding-top: .75rem; }
  .builder-save-bar { top: 64px; }
  .builder-save-bar small { display: none; }
  .segment-settings { grid-template-columns: 1fr 1fr; }
  .segment-settings > :first-child { grid-column: 1 / -1; }
  .segment-settings .btn-secondary, .segment-settings .btn-primary { grid-column: 1 / -1; width: 100%; }
  .segment-new-fields { grid-template-columns: 1fr 1fr; }
  .segment-workspace-header { align-items: flex-start; }
  .segment-workspace-actions .btn-secondary { font-size: 0; min-width: 44px; padding-inline: .65rem; }
  .segment-workspace-actions .btn-secondary svg { margin: 0; }
  .station-summary { align-items: center; flex-wrap: wrap; }
  .station-summary > .flex-1 { min-width: calc(100% - 3.5rem); }
  .station-move { margin-left: 2.75rem; }
  .station-expand-button { flex: 1; }
  .station-expand-button span { display: inline; }
  .conflict-warning { align-items: flex-start; flex-direction: column; }
  .session-summary { grid-template-columns: 1fr 1fr; }
  .form-section { border-radius: var(--radius-2xl); padding: 1rem; }
  .form-actions .btn-primary { width: 100%; }
  .segmented-control { display: grid; grid-template-columns: repeat(3, 1fr); width: 100%; }
  .segmented-control span { justify-content: center; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    scroll-behavior: auto !important;
    transition-duration: .01ms !important;
  }
}

/* M7 — rink-side run and per-coach views */
.immersive-body { background: var(--immersive-bg); }
.immersive-main { min-height: 100vh; padding: 0; }

.visually-hidden {
  border: 0;
  clip: rect(0 0 0 0);
  height: 1px;
  margin: -1px;
  overflow: hidden;
  padding: 0;
  position: absolute;
  white-space: nowrap;
  width: 1px;
}

.practice-run {
  background: var(--bg);
  color: var(--ink);
  min-height: 100vh;
}

.run-header {
  align-items: center;
  background: var(--immersive-bg);
  color: white;
  display: grid;
  grid-template-columns: 56px 1fr 56px;
  height: 56px;
  position: sticky;
  top: 0;
  z-index: 20;
}

/* Forgejo #27: a fixed "story"-style segment marker nested inside the
   existing 56px header — never grows/animates with elapsed time. */
.run-progress {
  display: flex;
  gap: .2rem;
  left: .6rem;
  position: absolute;
  right: .6rem;
  top: .3rem;
}

.run-progress > span {
  background: oklch(1 0 0 / .25);
  border-radius: 999px;
  flex: 1;
  height: 3px;
}

.run-progress > span.is-complete { background: oklch(1 0 0 / .65); }
.run-progress > span.is-current { background: white; }

.run-header > button {
  align-items: center;
  align-self: stretch;
  background: transparent;
  border: 0;
  color: white;
  cursor: pointer;
  display: flex;
  font-size: 1.6rem;
  justify-content: center;
  min-width: 56px;
}

.run-header > button:active { background: oklch(0.28 0.018 40); }

.run-clock {
  align-items: center;
  display: grid;
  gap: .45rem;
  grid-template-columns: auto minmax(0, 1fr) auto;
  height: 56px;
  touch-action: none;
  user-select: none;
}

.run-clock > span {
  font-size: 1rem;
  font-variant-numeric: tabular-nums;
  font-weight: 750;
}

.run-clock > strong {
  font-size: .9rem;
  overflow: hidden;
  text-align: center;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.run-clock > small {
  background: var(--primary);
  border-radius: 999px;
  bottom: -1.25rem;
  color: white;
  font-size: .72rem;
  font-weight: 750;
  left: 50%;
  opacity: 0;
  padding: .2rem .55rem;
  pointer-events: none;
  position: absolute;
  transform: translateX(-50%);
  transition: opacity 180ms ease-out;
}

.practice-run.is-paused .run-clock > small { opacity: 1; }
.practice-run.is-paused .run-header { background: oklch(0.3 0.055 70); }
.run-main { margin: 0 auto; max-width: 52rem; padding-bottom: 5rem; }

.run-empty {
  align-items: center;
  display: flex;
  flex-direction: column;
  font-size: 1.125rem;
  gap: .4rem;
  justify-content: center;
  min-height: 60vh;
  padding: 2rem;
  text-align: center;
}
.run-empty span { color: var(--muted); }

.run-station-view { touch-action: pan-y; }
.run-station-heading {
  align-items: end;
  display: flex;
  justify-content: space-between;
  min-height: 86px;
  padding: 1rem;
}
.run-station-heading > div:first-child > span {
  color: var(--primary-dark);
  display: block;
  font-size: 1rem;
  font-weight: 800;
}
.run-station-heading h1 {
  font-size: 1.5rem;
  letter-spacing: -.025em;
  line-height: 1.15;
  margin: .2rem 0 0;
}
.run-phase-status { align-items: flex-end; display: flex; flex-direction: column; gap: .4rem; }
.run-phase-status > strong { font-size: .88rem; }
.run-phase-status > div { display: flex; gap: .35rem; }
.run-phase-status button {
  background: var(--surface-strong);
  border: 0;
  border-radius: 50%;
  cursor: pointer;
  height: 12px;
  padding: 0;
  width: 12px;
}
.run-phase-status button.is-current { background: var(--primary); }

/* Forgejo #14: rink-side station switcher — one obvious tap per station,
   alongside the existing swipe gesture on the diagram itself. */
.run-station-switcher {
  display: flex;
  gap: .5rem;
  overflow-x: auto;
  padding: 0 1rem .75rem;
  scroll-snap-type: x mandatory;
}
.run-station-switcher button {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-xl);
  flex: 0 0 min(14rem, calc(100vw - 6rem));
  min-height: 44px;
  padding: .5rem .65rem;
  scroll-snap-align: start;
  text-align: left;
}
.run-station-switcher button.is-current {
  background: var(--primary);
  border-color: var(--primary);
  color: white;
}
.run-station-switcher button.is-mine strong::before { content: "★ "; }
.run-station-switcher button.is-sequential { border-style: dashed; }
.run-station-switcher strong {
  display: block;
  font-size: .95rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.run-station-switcher span {
  display: block;
  font-size: .75rem;
  margin-top: .15rem;
  opacity: .8;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.run-diagram {
  background: var(--ice-surface);
  border-bottom: 1px solid var(--line);
  border-top: 1px solid var(--line);
  position: relative;
}
.run-diagram svg {
  display: block;
  max-height: 52vh;
  min-height: 13rem;
  touch-action: none;
  width: 100%;
}
.run-diagram > span {
  background: oklch(0.16 0.015 40 / .9);
  border-radius: var(--radius-sm);
  bottom: .55rem;
  color: white;
  font-size: .75rem;
  left: 50%;
  padding: .3rem .55rem;
  pointer-events: none;
  position: absolute;
  transform: translateX(-50%);
  white-space: nowrap;
}

.run-assignment {
  background: var(--surface);
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
}
.run-assignment > div { min-width: 0; padding: .75rem 1rem; }
.run-assignment span {
  color: var(--muted);
  display: block;
  font-size: .75rem;
  font-weight: 700;
}
.run-assignment strong {
  display: block;
  font-size: 1.125rem;
  margin-top: .15rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.run-instructions {
  display: grid;
  gap: 1.5rem;
  grid-template-columns: 1fr 1fr;
  padding: 1.25rem 1rem 1.75rem;
}
.run-instructions h2 {
  font-size: 1.125rem;
  margin: 0 0 .65rem;
}
.run-instructions ul {
  font-size: 1.125rem;
  line-height: 1.45;
  margin: 0;
  padding-left: 1.25rem;
}
.run-instructions li + li { margin-top: .45rem; }
.run-instructions li.is-empty { color: var(--muted); list-style: none; margin-left: -1.25rem; }
.run-instructions > p {
  background: var(--surface);
  border-radius: var(--radius-lg);
  font-size: 1.125rem;
  grid-column: 1 / -1;
  line-height: 1.45;
  margin: 0;
  padding: .85rem 1rem;
}

.run-overview {
  border-bottom: 1px solid var(--line);
  border-top: 1px solid var(--line);
  margin-top: .5rem;
}
.run-overview > summary {
  align-items: center;
  cursor: pointer;
  display: flex;
  font-size: 1.125rem;
  font-weight: 750;
  justify-content: space-between;
  list-style: none;
  min-height: 56px;
  padding: 0 1rem;
}
.run-overview > summary span { color: var(--muted); font-size: .85rem; }
.run-overview > div { border-top: 1px solid var(--line); padding: 1rem; }
.run-overview h2 { font-size: 1.125rem; margin: 0 0 .75rem; }

/* Forgejo #28: deliberately tucked away, subdued — not near prev/next. */
.run-reset {
  border-top: 1px solid var(--line);
  color: var(--danger);
  display: block;
  font-size: .85rem;
  width: 100%;
}

.coach-view {
  margin: -2rem auto -4rem;
  max-width: 52rem;
  min-height: calc(100vh - 56px);
}
.coach-view-header {
  align-items: center;
  background: var(--bg);
  border-bottom: 1px solid var(--line);
  display: grid;
  grid-template-columns: 44px minmax(0, 1fr) auto;
  height: 56px;
  position: sticky;
  top: 56px;
  z-index: 15;
}
.coach-view-header > a:first-child {
  align-items: center;
  color: var(--ink);
  display: flex;
  font-size: 1.35rem;
  height: 44px;
  justify-content: center;
  text-decoration: none;
}
.coach-view-header > div { display: flex; flex-direction: column; min-width: 0; }
.coach-view-header strong, .coach-view-header span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.coach-view-header strong { font-size: .92rem; }
.coach-view-header span { color: var(--muted); font-size: .75rem; }
.coach-run-link {
  align-items: center;
  background: var(--primary);
  border-radius: var(--radius-md);
  color: white;
  display: inline-flex;
  font-size: .8rem;
  font-weight: 750;
  min-height: 44px;
  padding: 0 .8rem;
  text-decoration: none;
}

.ice-awareness { border-bottom: 1px solid var(--line); }
.ice-awareness > summary {
  align-items: center;
  cursor: pointer;
  display: flex;
  font-size: .88rem;
  font-weight: 700;
  gap: .65rem;
  list-style: none;
  min-height: 48px;
  padding: .9rem 1rem;
}
.ice-awareness > summary span { color: var(--muted); flex: 0 0 auto; }
.ice-awareness > summary strong {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-align: right;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ice-awareness > div { background: var(--surface); padding: .75rem 1rem; }
.ice-awareness p { display: flex; flex-direction: column; font-size: .88rem; margin: 0; }
.ice-awareness p + p { margin-top: .7rem; }
.ice-awareness p span { color: var(--muted); }

.coach-timeline { padding: 1rem; }
.coach-timeline > details { position: relative; }
.coach-timeline > details::before {
  background: var(--line);
  bottom: 0;
  content: "";
  left: 5.85rem;
  position: absolute;
  top: 0;
  width: 1px;
  z-index: 0;
}
.coach-timeline > details > summary {
  align-items: center;
  cursor: pointer;
  display: grid;
  gap: .65rem;
  grid-template-columns: 4.75rem 1rem minmax(0, 1fr) 1rem;
  list-style: none;
  min-height: 74px;
  position: relative;
  z-index: 1;
}
.coach-timeline time {
  font-size: .84rem;
  font-variant-numeric: tabular-nums;
  font-weight: 750;
}
.timeline-dot {
  background: var(--coach-color);
  border: 3px solid var(--bg);
  border-radius: 50%;
  height: 1rem;
  width: 1rem;
}
.coach-timeline summary > span:nth-child(3) { min-width: 0; }
.coach-timeline summary strong, .coach-timeline summary small { display: block; }
.coach-timeline summary strong { font-size: 1rem; }
.coach-timeline summary small { color: var(--muted); font-size: .85rem; margin-top: .2rem; }
.assignment-detail {
  border-bottom: 1px solid var(--line);
  margin-left: 6.5rem;
  padding: .25rem 0 1.5rem;
}
.assignment-detail section { margin-top: 1.25rem; }
.assignment-detail h2 { font-size: 1rem; margin: 0 0 .5rem; }
.assignment-detail p, .assignment-detail ul { color: var(--muted); font-size: 1rem; line-height: 1.5; margin: 0; }
.assignment-detail li + li { margin-top: .35rem; }
.assignment-awareness {
  background: var(--surface);
  border-radius: var(--radius-lg);
  font-size: .85rem;
  padding: .65rem .75rem;
}
.assignment-awareness summary { cursor: pointer; font-weight: 700; }
.assignment-awareness p { font-size: .85rem; margin-top: .45rem; }

.coach-phases {
  display: flex;
  gap: .75rem;
  margin: 1.25rem -1rem 0 0;
  overflow-x: auto;
  padding-bottom: .5rem;
  scroll-snap-type: x mandatory;
}
.coach-phases figure {
  flex: 0 0 min(31rem, calc(100vw - 8.5rem));
  margin: 0;
  scroll-snap-align: start;
}
.coach-phases figcaption { font-size: .85rem; font-weight: 750; margin-bottom: .35rem; }
.coach-phases svg {
  background: var(--ice-surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  display: block;
  min-height: 13rem;
  touch-action: none;
  width: 100%;
}
.coach-phases figure > p { font-size: .88rem; margin-top: .5rem; }
.coach-empty { padding: 4rem 1rem; text-align: center; }
.coach-empty h1 { font-size: 1.25rem; }
.coach-empty p { color: var(--muted); }

.coach-view-links { border-top: 1px solid var(--line); margin-top: 2rem; padding-top: 1.5rem; }
.coach-view-links h2 { font-size: 1rem; margin: 0; }
.coach-view-links > p { color: var(--muted); font-size: .85rem; margin: .25rem 0 .75rem; }
.coach-view-links > div { border-top: 1px solid var(--line); }
.coach-view-links a {
  align-items: center;
  border-bottom: 1px solid var(--line);
  color: var(--ink);
  display: flex;
  min-height: 60px;
  padding: .5rem;
  text-decoration: none;
}
.coach-view-links i { background: var(--coach-color); border-radius: 50%; height: .75rem; margin-right: .75rem; width: .75rem; }
.coach-view-links span { display: flex; flex: 1; flex-direction: column; }
.coach-view-links small { color: var(--muted); }

@media (max-width: 767px) {
  .run-instructions { grid-template-columns: 1fr; }
  .run-instructions > p { grid-column: auto; }
  .coach-view { margin: -1.25rem -.75rem -5rem; }
  .coach-view-header { top: 56px; }
  .assignment-detail { margin-left: 0; padding-left: 6.5rem; }
  .coach-phases { margin-right: -1rem; }
}

@media (max-width: 420px) {
  .run-station-heading { min-height: 78px; }
  .run-station-heading h1 { font-size: 1.35rem; }
  .run-assignment > div { padding: .65rem .75rem; }
  .run-assignment strong { font-size: 1rem; }
  .run-instructions { gap: 1.25rem; padding-top: 1rem; }
  .coach-timeline { padding: .75rem; }
  .coach-timeline > details::before { left: 4.85rem; }
  .coach-timeline > details > summary {
    gap: .45rem;
    grid-template-columns: 4rem .8rem minmax(0, 1fr) .75rem;
  }
  .coach-timeline time { font-size: .75rem; }
  .assignment-detail { padding-left: 5.25rem; }
  .coach-phases figure { flex-basis: calc(100vw - 6.75rem); }
}

/* M8 — share management, public documents, and print surfaces */
.share-manager {
  border-top: 1px solid var(--line);
  margin-top: 2.5rem;
  padding-top: 1.5rem;
}
.share-manager-heading {
  align-items: center;
  display: flex;
  gap: 1rem;
  justify-content: space-between;
}
.share-manager h2, .share-manager h3 { margin: 0; }
.share-manager h2 { font-size: 1rem; }
.share-manager h3 { font-size: .88rem; }
.share-manager-heading p { color: var(--muted); font-size: .85rem; margin: .25rem 0 0; }
.share-create { border-bottom: 1px solid var(--line); margin-top: .75rem; }
.share-create > summary {
  color: var(--primary-dark);
  cursor: pointer;
  font-size: .88rem;
  font-weight: 700;
  list-style: none;
  min-height: 44px;
  padding: .75rem 0;
}
.share-form {
  align-items: end;
  display: grid;
  gap: .75rem;
  grid-template-columns: minmax(12rem, 1fr) minmax(12rem, 1fr) auto;
  padding: 0 0 1rem;
}
.coach-share-list, .share-link-list { margin-top: 1.25rem; }
.coach-share-list > div, .share-link-list > div {
  align-items: center;
  border-bottom: 1px solid var(--line);
  display: flex;
  gap: .75rem;
  min-height: 60px;
}
.coach-share-list > div > span {
  background: var(--coach-color);
  border-radius: 50%;
  height: .7rem;
  width: .7rem;
}
.coach-share-list p, .share-link-list p {
  display: flex;
  flex: 1;
  flex-direction: column;
  font-size: .86rem;
  margin: 0;
  min-width: 0;
}
.coach-share-list small, .share-link-list small { color: var(--muted); margin-top: .15rem; }
.share-link-list > div.is-revoked { color: var(--muted); min-height: 52px; }
.share-url {
  background: var(--surface);
  border: 0;
  border-radius: var(--radius-sm);
  color: var(--muted);
  font: inherit;
  font-size: .78rem;
  max-width: 20rem;
  min-height: 36px;
  padding: .45rem .6rem;
  width: 40%;
}

/* Forgejo #28 */
.share-password-field { grid-column: 1 / -1; }
.share-password-field > div { margin-top: .5rem; max-width: 16rem; }
.share-url-actions { align-items: center; display: flex; flex: 1; gap: .5rem; min-width: 0; }
.share-url-actions .share-url { flex: 1; max-width: none; width: auto; }

.public-body {
  background: var(--bg);
  color: var(--ink);
  font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  margin: 0;
  -webkit-font-smoothing: antialiased;
}
.public-main { min-height: 100vh; }
.public-document {
  margin: 0 auto;
  max-width: 68rem;
  padding: 2rem 1.25rem 5rem;
}
.public-document-header {
  align-items: flex-start;
  border-bottom: 1px solid var(--line);
  display: flex;
  gap: 1rem;
  justify-content: space-between;
  padding-bottom: 1.5rem;
}
.public-mark {
  color: var(--primary-dark);
  display: block;
  font-size: .82rem;
  font-weight: 800;
  margin-bottom: .6rem;
}
.public-document-header h1 {
  font-size: 2rem;
  letter-spacing: -.025em;
  line-height: 1.15;
  margin: 0;
  text-wrap: balance;
}
.public-document-header p { color: var(--muted); margin: .5rem 0 0; }
.public-lede {
  font-size: 1.125rem;
  line-height: 1.55;
  margin: 1.5rem 0;
  max-width: 70ch;
}
.public-facts {
  border-bottom: 1px solid var(--line);
  display: grid;
  gap: 1.5rem 2rem;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  padding: 1.5rem 0;
}
.public-facts h2, .public-phases > h2, .public-notes h2, .public-plan > h2 {
  font-size: 1rem;
  margin: 0 0 .45rem;
}
.public-facts p, .public-facts ul {
  color: var(--muted);
  line-height: 1.5;
  margin: 0;
}
.public-facts ul { padding-left: 1.15rem; }
.public-phases { padding-top: 2rem; }
.public-phases figure { margin: 0; padding: 1rem 0 2rem; }
.public-phases figure + figure { border-top: 1px solid var(--line); }
.public-phases figcaption {
  align-items: baseline;
  display: flex;
  justify-content: space-between;
  margin-bottom: .55rem;
}
.public-phases figcaption span { color: var(--muted); font-size: .8rem; }
.public-phases svg, .station-diagrams svg {
  background: var(--ice-surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  display: block;
  max-height: 32rem;
  touch-action: none;
  width: 100%;
}
.public-phases figure > p, .station-diagrams figure > p {
  color: var(--muted);
  line-height: 1.5;
  margin: .75rem 0 0;
  white-space: pre-line;
}
.public-notes {
  border-top: 1px solid var(--line);
  max-width: 70ch;
  padding-top: 1.5rem;
}
.public-notes p { color: var(--muted); line-height: 1.5; }

.public-plan { margin-top: 2rem; }
.public-plan > article { border-top: 1px solid var(--line); padding: 1.25rem 0; }
.public-plan article > header { display: flex; gap: 1rem; }
.public-plan time { color: var(--primary-dark); font-size: .9rem; font-weight: 800; width: 4rem; }
.public-plan h3 { font-size: 1rem; margin: 0; }
.public-plan header p { color: var(--muted); font-size: .82rem; margin: .25rem 0 0; }
.station-sheets { margin-top: 2rem; }
.station-sheets > h2 { font-size: 1rem; }
.station-sheet { border-top: 1px solid var(--line); padding: 2rem 0; }
.station-sheet > header {
  align-items: flex-start;
  display: flex;
  gap: 1rem;
  justify-content: space-between;
  margin-bottom: 1rem;
}
.station-sheet > header span {
  color: var(--primary-dark);
  font-size: .8rem;
  font-weight: 750;
}
.station-sheet > header h2 { font-size: 1.35rem; margin: .25rem 0; }
.station-sheet > header p, .station-sheet > header > strong {
  color: var(--muted);
  font-size: .85rem;
  margin: 0;
}
.station-sheet-body {
  align-items: start;
  display: grid;
  gap: 1.5rem;
  grid-template-columns: minmax(0, 2fr) minmax(13rem, 1fr);
}
.station-diagrams {
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr));
}
.station-diagrams figure { margin: 0; }
.station-diagrams figcaption { font-size: .82rem; font-weight: 750; margin-bottom: .35rem; }
.station-sheet aside {
  background: var(--surface);
  border-radius: var(--radius-lg);
  padding: 1rem;
}
.station-sheet aside section + section { border-top: 1px solid var(--line); margin-top: 1rem; padding-top: 1rem; }
.station-sheet h3 { font-size: .9rem; margin: 0 0 .4rem; }
.station-sheet aside p, .station-sheet aside ul, .station-custom-notes {
  color: var(--muted);
  font-size: .9rem;
  line-height: 1.45;
  margin: 0;
}
.station-sheet aside ul { padding-left: 1.1rem; }

.public-coach-view { margin: 0 auto; min-height: 100vh; }
.public-coach-header {
  align-items: center;
  background: var(--bg);
  border-bottom: 1px solid var(--line);
  display: grid;
  gap: .75rem;
  grid-template-columns: auto minmax(0, 1fr) auto;
  min-height: 64px;
  padding: .5rem 1rem;
  position: sticky;
  top: 0;
  z-index: 15;
}
.public-coach-header .public-mark { margin: 0; }
.public-coach-header > div { display: flex; flex-direction: column; min-width: 0; }
.public-coach-header > div strong, .public-coach-header > div span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.public-coach-header > div span { color: var(--muted); font-size: .78rem; }

@media (max-width: 767px) {
  .share-form { grid-template-columns: 1fr; }
  .share-form .btn-primary { width: 100%; }
  .share-link-list > div { align-items: flex-start; flex-wrap: wrap; padding: .65rem 0; }
  .share-url { max-width: none; order: 2; width: 100%; }
  .public-document { padding: 1.25rem .75rem 4rem; }
  .public-document-header h1 { font-size: 1.65rem; }
  .public-facts, .station-sheet-body { grid-template-columns: 1fr; }
  .station-sheet > header { flex-direction: column; }
  .public-coach-header { grid-template-columns: minmax(0, 1fr) auto; }
  .public-coach-header .public-mark { display: none; }
}

@media print {
  @page { margin: 12mm; size: A4 portrait; }

  :root {
    --bg: white;
    --surface: oklch(0.97 0 0);
    --surface-strong: oklch(0.93 0 0);
    --ink: black;
    --muted: oklch(0.36 0 0);
    --line: oklch(0.78 0 0);
  }
  .no-print { display: none !important; }
  .public-document { max-width: none; padding: 0; }
  .public-document-header h1 { font-size: 20pt; }
  .print-cover { break-after: page; }
  .station-sheets { margin: 0; }
  .station-sheets > .station-sheet {
    break-after: page;
    border: 0;
    min-height: 270mm;
    padding: 0;
  }
  .station-sheets > .station-sheet:last-child { break-after: auto; }
  .station-sheet-body { gap: 8mm; grid-template-columns: minmax(0, 2fr) minmax(42mm, 1fr); }
  .station-diagrams { display: block; }
  .station-diagrams figure { break-inside: avoid; margin-bottom: 5mm; }
  .station-diagrams svg { max-height: 112mm; }
  .public-phases figure { break-inside: avoid; }
  .public-phases svg { max-height: 150mm; }
  .ice-map, .public-plan > article, .station-sheet aside { break-inside: avoid; }
  .coach-timeline > details { break-inside: avoid; }
  .coach-timeline > details > .assignment-detail { display: block; }
  .coach-phases { display: block; overflow: visible; }
  .coach-phases figure { margin-bottom: 5mm; width: 100%; }
}

/* M9 — PDF extraction review */
.status-pending, .status-processing, .status-extracted {
  background: oklch(0.92 0.045 205);
  color: oklch(0.34 0.09 205);
}
.status-needs_review {
  background: var(--warning-bg);
  color: var(--warning-ink);
}
.status-accepted, .status-accepted_text_only {
  background: var(--status-ready-bg);
  color: var(--status-ready-ink);
}
.status-rejected, .status-failed {
  background: oklch(0.94 0.04 25);
  color: oklch(0.38 0.13 25);
}
.import-batch-list, .import-item-list { border-top: 1px solid var(--line); }
.import-batch-list > a, .import-item-list > a {
  align-items: center;
  border-bottom: 1px solid var(--line);
  color: var(--ink);
  display: flex;
  gap: 1rem;
  min-height: 72px;
  padding: .75rem .5rem;
  text-decoration: none;
}
.import-batch-list > a:hover, .import-item-list > a:hover { background: var(--surface); }
.import-batch-list > a > div, .import-item-list > a > div {
  display: flex;
  flex: 1;
  flex-direction: column;
  min-width: 0;
}
.import-batch-list small, .import-item-list small {
  color: var(--muted);
  font-size: .8rem;
  margin-top: .2rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.import-batch-list b { color: var(--muted); font-size: .82rem; }
.import-item-list > a > span:first-child {
  align-items: center;
  background: var(--surface-strong);
  border-radius: var(--radius-sm);
  display: flex;
  font-size: .8rem;
  font-weight: 800;
  height: 2rem;
  justify-content: center;
  width: 2rem;
}

.import-review {
  margin: 0 auto;
  max-width: 96rem;
  padding-bottom: 6rem;
}
.import-review-header {
  align-items: end;
  display: flex;
  gap: 1rem;
  justify-content: space-between;
  margin-bottom: 1.25rem;
}
.import-review-header h1 {
  font-size: 1.5rem;
  letter-spacing: -.02em;
  margin: .35rem 0;
}
.import-review-header p { color: var(--muted); margin: 0; }
.import-validation {
  background: var(--warning-bg);
  border-radius: var(--radius-lg);
  color: var(--warning-ink);
  margin-bottom: 1rem;
  padding: .85rem 1rem;
}
.import-validation ul { margin: .4rem 0 0; padding-left: 1.2rem; }
.import-review-workspace {
  display: grid;
  gap: 1.25rem;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
}
.import-source > h2, .import-extraction > h2 {
  font-size: .9rem;
  margin: 0 0 .5rem;
}
.import-source > div {
  background: oklch(0.94 0 0);
  border-radius: var(--radius-lg);
  max-height: calc(100vh - 13rem);
  overflow: auto;
}
.import-source img {
  display: block;
  height: auto;
  width: 100%;
}
.import-extraction { min-width: 0; }
.import-diagram-editor {
  border-bottom: 1px solid var(--line);
  margin-bottom: 1rem;
  padding-bottom: 1rem;
}
.import-diagram-editor > svg {
  background: white;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  width: 100%;
}
.import-diagram-editor > aside {
  align-items: start;
  display: flex;
  gap: .75rem;
  justify-content: space-between;
  margin-top: .75rem;
}
.import-diagram-editor > aside ul {
  display: flex;
  flex: 1;
  gap: .5rem;
  list-style: none;
  margin: 0;
  overflow-x: auto;
  padding: 0 0 .4rem;
}
.import-diagram-editor > aside li { flex: 0 0 9rem; }
.import-diagram-editor > aside > span { color: var(--muted); font-size: .8rem; }
.import-viewport-note {
  background: var(--warning-bg);
  border-radius: var(--radius-lg);
  color: var(--warning-ink);
  font-size: .82rem;
  margin-bottom: .75rem;
  padding: .7rem;
}
.import-json-form > * + * { margin-top: .75rem; }
.import-json-form details {
  border-bottom: 1px solid var(--line);
  border-top: 1px solid var(--line);
}
.import-json-form summary {
  cursor: pointer;
  font-size: .85rem;
  font-weight: 700;
  min-height: 44px;
  padding: .75rem 0;
}
.import-json {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: .78rem;
  line-height: 1.45;
  min-height: 28rem;
  white-space: pre;
}
.import-review-actions {
  align-items: center;
  background: var(--bg);
  border-top: 1px solid var(--line);
  bottom: 0;
  display: flex;
  gap: 1rem;
  justify-content: space-between;
  left: 0;
  min-height: 68px;
  padding: .7rem max(1rem, calc((100vw - 96rem) / 2));
  position: fixed;
  right: 0;
  z-index: 20;
}
.import-review-actions p { color: var(--muted); font-size: .82rem; margin: 0; }
.import-review-actions > div { display: flex; gap: .5rem; }

@media (max-width: 900px) {
  .import-review-workspace { grid-template-columns: 1fr; }
  .import-source > div { max-height: 55vh; }
  .import-review-actions { align-items: stretch; flex-direction: column; position: static; }
  .import-review-actions > div { flex-direction: column-reverse; }
  .import-review-actions .btn-primary,
  .import-review-actions .btn-secondary,
  .import-review-actions .btn-danger { width: 100%; }
  .import-batch-list b { display: none; }
}

/* M11 — season planning */
.season-plan-list { border-top: 1px solid var(--line); }
.season-plan-row {
  align-items: center;
  border-bottom: 1px solid var(--line);
  color: var(--ink);
  display: grid;
  gap: 1rem;
  grid-template-columns: 7rem minmax(0, 1fr) auto;
  min-height: 92px;
  padding: 1rem .5rem;
  text-decoration: none;
}
.season-plan-row:hover { background: var(--surface); }
.season-plan-year { color: var(--primary-dark); font-size: 1rem; font-weight: 800; }
.season-plan-row h2 { font-size: 1.05rem; margin: 0; }
.season-plan-row p, .season-plan-row > span { color: var(--muted); font-size: .82rem; margin: .25rem 0 0; }

.season-plan-tabs {
  border-bottom: 1px solid var(--line);
  display: flex;
  gap: 1.25rem;
  margin-bottom: .5rem;
  overflow-x: auto;
}
.season-plan-tab {
  color: var(--muted);
  font-size: .88rem;
  font-weight: 650;
  padding: .6rem .1rem;
  text-decoration: none;
  white-space: nowrap;
}
.season-plan-tab.is-active { border-bottom: 2px solid var(--primary); color: var(--ink); }

.season-mobile-note { display: none; }
.season-planner-header {
  align-items: end;
  border-bottom: 1px solid var(--line);
  display: flex;
  gap: 2rem;
  justify-content: space-between;
  padding-bottom: 1.5rem;
}
.season-planner-header h1 { font-size: 2rem; letter-spacing: -.03em; line-height: 1.1; margin: .4rem 0; }
.season-planner-header > div > p:last-child { color: var(--muted); margin: 0; }
.season-kicker {
  color: var(--primary-dark);
  font-size: .78rem;
  font-weight: 800;
  letter-spacing: .08em;
  margin: 1.5rem 0 0;
  text-transform: uppercase;
}
.season-header-actions { display: flex; gap: .6rem; }
.season-header-actions form { margin: 0; }
.season-brief {
  align-items: start;
  background: var(--surface);
  display: grid;
  gap: 2rem;
  grid-template-columns: minmax(0, 1fr) auto;
  margin: 1.5rem 0 2.5rem;
  padding: 1.25rem 1.5rem;
}
.season-brief h2 { font-size: .82rem; margin: 0 0 .35rem; text-transform: uppercase; }
.season-brief p { line-height: 1.5; margin: 0; max-width: 70ch; }
.season-focus-list { align-items: center; display: flex; flex-wrap: wrap; gap: .35rem; }
.season-focus-list span {
  background: oklch(0.91 0.045 205);
  border-radius: 999px;
  color: var(--accent);
  font-size: .73rem;
  font-weight: 700;
  padding: .25rem .55rem;
}
.season-planner-grid {
  align-items: start;
  display: grid;
  gap: 3rem;
  grid-template-columns: minmax(0, 1fr) 18rem;
}
.season-timeline .section-heading { margin-bottom: 1.5rem; }
.section-heading h2 { font-size: 1.1rem; margin: 0 0 .3rem; }
.season-block {
  display: grid;
  gap: 1rem;
  grid-template-columns: 2rem minmax(0, 1fr);
  position: relative;
}
.season-block:not(:last-of-type)::before {
  background: var(--line);
  content: "";
  left: .95rem;
  position: absolute;
  top: 2rem;
  bottom: -1rem;
  width: 2px;
}
.season-block-marker {
  align-items: center;
  background: var(--ink);
  border-radius: 50%;
  color: white;
  display: flex;
  font-size: .72rem;
  font-weight: 800;
  height: 2rem;
  justify-content: center;
  position: relative;
  width: 2rem;
  z-index: 1;
}
.season-block-content {
  border-top: 2px solid var(--ink);
  margin-bottom: 2rem;
  min-width: 0;
  padding-top: .9rem;
}
.season-block-content > header {
  align-items: start;
  display: flex;
  gap: 1rem;
  justify-content: space-between;
}
.season-block-content > header p {
  color: var(--primary-dark);
  font-size: .75rem;
  font-weight: 800;
  margin: 0 0 .25rem;
}
.season-block-content h3 { font-size: 1.25rem; margin: 0; }
.season-block-notes { color: var(--muted); font-size: .88rem; line-height: 1.5; margin: .75rem 0 0; }
.season-session-list { margin-top: 1rem; }
.season-session {
  align-items: start;
  border-top: 1px solid var(--line);
  display: grid;
  gap: .8rem;
  grid-template-columns: 2.75rem minmax(0, 1fr) auto;
  min-height: 82px;
  padding: .85rem 0;
}
.season-session-date { align-items: center; display: flex; flex-direction: column; }
.season-session-date span { color: var(--muted); font-size: .65rem; font-weight: 800; text-transform: uppercase; }
.season-session-date strong { font-size: 1.2rem; }
.season-session a { color: var(--ink); font-size: .9rem; font-weight: 750; text-decoration: none; }
.season-session a:hover { color: var(--primary-dark); }
.season-session p { color: var(--muted); font-size: .75rem; margin: .15rem 0 .4rem; }
.focus-match { color: var(--warning-ink); display: flex; flex-wrap: wrap; font-size: .72rem; gap: .25rem .65rem; }
.focus-match.is-complete { color: var(--success); }
.focus-match.is-neutral { color: var(--muted); }
.focus-match span { color: var(--muted); }
.season-empty-line { color: var(--muted); font-size: .82rem; margin: .75rem 0; }
/* Forgejo #16: Edit/Delete became peer icon buttons (Delete no longer
   hidden inside Edit's disclosure -- both are one tap away, named per
   block via aria-label). */
.season-block-header-actions { align-items: flex-start; border-top: 1px dashed var(--line); gap: .5rem; padding-top: .9rem; }
.season-block-edit { margin: 0; }
.season-add-block > summary {
  cursor: pointer;
  font-size: .82rem;
  font-weight: 750;
  min-height: 44px;
  padding: .8rem 0;
}
.season-block-form { display: grid; gap: .8rem; padding: .5rem 0 1rem; }
.season-block-form-grid { display: grid; gap: .75rem; grid-template-columns: minmax(0, 1.4fr) repeat(2, minmax(9rem, 1fr)); }
.season-block-form .notice-error { grid-column: 1 / -1; }
.season-block-form .notice-error ul { margin: 0; padding-left: 1rem; }
.season-block-edit > form:last-child { margin-bottom: 1rem; }
.season-add-block {
  background: var(--surface);
  border: 1px dashed oklch(0.7 0.02 45);
  padding: 0 1rem;
}
.season-empty { border-top: 1px solid var(--line); margin-bottom: 1rem; padding: 2rem 0; text-align: center; }
.season-empty h3 { margin: 0; }
.season-empty p { color: var(--muted); margin: .4rem 0 0; }
.season-unassigned {
  border-top: 2px solid var(--accent);
  position: sticky;
  top: 80px;
}
.season-unassigned h2 { font-size: 1rem; margin: .8rem 0 .15rem; }
.season-unassigned > p { color: var(--muted); font-size: .78rem; margin: 0 0 .8rem; }
.season-unassigned-list { border-top: 1px solid var(--line); list-style: none; margin: 0 0 1rem; padding: 0; }

/* Forgejo #16: compact rows (date/title/status + View/Add) replacing the
   old plain-link list, so a practice is viewed or assigned in at most two
   taps without leaving this aside. */
.season-unassigned-row {
  align-items: center;
  border-bottom: 1px solid var(--line);
  display: flex;
  flex-wrap: wrap;
  gap: .5rem .75rem;
  justify-content: space-between;
  padding: .7rem 0;
}
.season-unassigned-info { display: flex; flex-direction: column; gap: .2rem; min-width: 0; }
.season-unassigned-info strong { font-size: .82rem; font-weight: 700; }
.season-unassigned-date { color: var(--muted); font-size: .72rem; }
.season-unassigned-actions { align-items: center; display: flex; flex-wrap: wrap; gap: .4rem; }
.season-add-chooser { position: relative; }
.season-add-chooser > summary { list-style: none; }
.season-add-chooser > summary::-webkit-details-marker { display: none; }
.season-add-chooser ul {
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: 0 4px 12px oklch(0 0 0 / 0.08);
  list-style: none;
  margin: .3rem 0 0;
  min-width: 10rem;
  padding: .3rem;
  position: absolute;
  right: 0;
  z-index: 5;
}
.season-add-chooser li + li { margin-top: .1rem; }
.season-add-chooser .text-button { display: block; padding: .5rem; text-align: left; width: 100%; }

.season-assign-status {
  color: var(--primary-dark);
  font-size: .82rem;
  font-weight: 700;
  min-height: 1.2rem;
}

@media (max-width: 1023px) {
  .season-mobile-note {
    background: var(--warning-bg);
    color: var(--warning-ink);
    display: block;
    font-size: .82rem;
    margin: -1.25rem -.75rem 1.25rem;
    padding: .75rem;
  }
  .season-edit-only { display: none !important; }
  .season-planner-grid { grid-template-columns: 1fr; }
  .season-unassigned { position: static; }
}

@media (max-width: 640px) {
  .season-plan-row { grid-template-columns: 1fr auto; }
  .season-plan-year { grid-column: 1 / -1; }
  .season-planner-header h1 { font-size: 1.6rem; }
  .season-brief { grid-template-columns: 1fr; }
  .season-block-content > header { flex-direction: column; }
  .season-session { grid-template-columns: 2.5rem minmax(0, 1fr); }
  .season-block-form-grid { grid-template-columns: 1fr; }
}

/* M12 — integration settings */
.integrations-page { max-width: 64rem; }
.integrations-heading { border-bottom: 1px solid var(--line); margin-bottom: 0; padding-bottom: 1.5rem; }
.integration-section {
  display: grid;
  gap: 2.5rem;
  grid-template-columns: minmax(13rem, .7fr) minmax(0, 1.3fr);
  padding: 2rem 0;
}
.integration-section + .integration-section { border-top: 1px solid var(--line); }
.integration-section-intro h2 { font-size: 1.05rem; margin: 0 0 .4rem; }
.integration-section-intro p {
  color: var(--muted);
  font-size: .84rem;
  line-height: 1.5;
  margin: 0;
  max-width: 34ch;
}
.integration-content { min-width: 0; }
.integration-state {
  align-items: center;
  background: var(--surface);
  display: flex;
  gap: .6rem;
  justify-content: flex-end;
  min-height: 72px;
  padding: .8rem 1rem;
}
.integration-state > div { display: flex; flex: 1; flex-direction: column; }
.integration-state strong { font-size: .9rem; }
.integration-state span { color: var(--muted); font-size: .76rem; margin-top: .15rem; }
.integration-state form { margin: 0; }
.api-token-reveal {
  background: oklch(0.92 0.04 155);
  color: oklch(0.3 0.08 155);
  padding: 1rem;
}
.api-token-reveal > strong { font-size: .9rem; }
.api-token-reveal > p { font-size: .8rem; margin: .25rem 0 .75rem; }
.api-token-value {
  color: var(--ink);
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: .78rem;
  min-height: 4.2rem;
  overflow-wrap: anywhere;
}
.integration-reference { border-bottom: 1px solid var(--line); margin-top: .75rem; }
.integration-reference > summary {
  cursor: pointer;
  font-size: .82rem;
  font-weight: 750;
  min-height: 44px;
  padding: .8rem 0;
}
.integration-reference > div { background: var(--surface); padding: .8rem 1rem; }
.integration-reference p, .integration-reference li { color: var(--muted); font-size: .78rem; }
.integration-reference ul { margin: .6rem 0 0; padding-left: 1.2rem; }
.integration-reference code {
  color: var(--ink);
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}
.integration-import-row {
  align-items: start;
  display: grid;
  gap: 1.5rem;
  grid-template-columns: minmax(0, 1fr) minmax(17rem, .9fr);
  padding: 0 0 1.5rem;
}
.integration-import-row + .integration-import-row {
  border-top: 1px solid var(--line);
  padding-top: 1.5rem;
}
.integration-import-row h3 { font-size: .9rem; margin: 0; }
.integration-import-row p { color: var(--muted); font-size: .78rem; line-height: 1.45; margin: .3rem 0 .65rem; }
.integration-import-row form { display: grid; gap: .6rem; }
.integration-import-row input[type="file"] { font-size: .78rem; padding: .45rem; }
.integration-import-row input[type="file"]::file-selector-button {
  background: var(--surface);
  border: 0;
  border-radius: var(--radius-sm);
  color: var(--ink);
  cursor: pointer;
  font: inherit;
  font-weight: 700;
  margin-right: .65rem;
  min-height: 32px;
  padding: .35rem .6rem;
}

@media (max-width: 767px) {
  .integration-section { gap: 1rem; grid-template-columns: 1fr; }
  .integration-section-intro p { max-width: 65ch; }
  .integration-state { align-items: stretch; flex-direction: column; }
  .integration-state .btn-primary,
  .integration-state .btn-secondary,
  .integration-state .btn-danger { width: 100%; }
  .integration-import-row { grid-template-columns: 1fr; }
  .integration-import-row .btn-secondary { width: 100%; }
}

/* Forgejo #1 — auth pages (sign in, password reset) and the post-login
   dashboard: the two areas that were still raw generator/prototype markup
   with no other issue in this batch scheduled to rewrite them. */
.auth-page {
  align-items: flex-start;
  display: flex;
  justify-content: center;
  padding: clamp(2rem, 8vh, 5rem) 1rem 3rem;
}
.auth-card {
  background: oklch(0.995 0.004 45);
  border: 1px solid var(--line);
  border-radius: var(--radius-2xl);
  box-shadow: 0 16px 50px oklch(0.2 0.02 40 / .07);
  max-width: 26rem;
  padding: clamp(1.5rem, 4vw, 2.25rem);
  width: 100%;
}
.auth-mark { color: var(--primary-dark); display: block; font-size: .72rem; font-weight: 850; letter-spacing: .08em; margin-bottom: 1rem; text-transform: uppercase; }
.auth-card h1 { font-size: 1.5rem; margin: 0 0 .35rem; }
.auth-card > p { color: var(--muted); margin: 0 0 1.25rem; }
.auth-card form > * + * { margin-top: 1rem; }
.auth-card .btn-primary { width: 100%; }
.auth-card-footer { font-size: .85rem; margin-top: 1.25rem; text-align: center; }

/* Brand lockup subtext. Deliberately only on the surfaces where the product
   introduces itself (sign-in, password reset, a password-gated share link) --
   never in the persistent app header, where chrome should recede. Specificity
   has to beat `.auth-card > p`, which otherwise claims this paragraph. */
.auth-card .brand-tagline,
.public-mark + .brand-tagline {
  color: var(--muted);
  font-size: .78rem;
  letter-spacing: .01em;
  margin: -.75rem 0 1.35rem;
}

/* Forgejo #92. PRODUCT.md commits to a 44px minimum touch target. The core
   controls (.btn-*, .text-button, .app-header nav a) already honour it; these do
   not, and every one of them sits on a surface a coach uses on a phone at the
   rink. They are deliberately dense -- a chip that reads as compact is the point
   -- so the HIT AREA is expanded with a centred pseudo-element rather than by
   growing the visible box. That keeps layout byte-for-byte identical, which
   matters here because there is no browser in this environment to verify a
   reflow with (standing policy, #23).

   Deliberately excluded: every drill-editor and palette control (.palette-*,
   .phase-tab, .clear-menu-list button, .form-control-compact). The editor is
   desktop-gated below 1024px and is mouse-driven by design.

   Residual risk, NOT verified here: on the densest chip rows a 44px area can
   overlap a neighbour's, and the later element wins the overlap. Needs one pass
   on a real device. Still strictly better than a 24px target. */
.filter-chip,
.status-switcher-button,
.rink-area-map-chip,
.ice-map-legend > button,
.btn-compact,
.date-quick-actions .btn-secondary {
  position: relative;
}

.filter-chip::after,
.status-switcher-button::after,
.rink-area-map-chip::after,
.ice-map-legend > button::after,
.btn-compact::after,
.date-quick-actions .btn-secondary::after {
  content: "";
  height: max(100%, 44px);
  left: 50%;
  position: absolute;
  top: 50%;
  transform: translate(-50%, -50%);
  width: max(100%, 44px);
}

/* A pointer device does not need the expanded area, and on a chip row it is
   where the overlap risk lives. Coarse pointers keep it. */
@media (hover: hover) and (pointer: fine) {
  .filter-chip::after,
  .status-switcher-button::after,
      .rink-area-map-chip::after,
  .ice-map-legend > button::after,
  .btn-compact::after,
  .date-quick-actions .btn-secondary::after {
    height: 100%;
    width: 100%;
  }
}

.toggle-control { align-items: center; cursor: pointer; display: inline-flex; gap: .55rem; min-height: 44px; position: relative; }
.toggle-control input { height: 1px; opacity: 0; position: absolute; width: 1px; }
.toggle-control > span { background: var(--surface-strong); border: 1px solid var(--control-border); border-radius: 999px; height: 1.5rem; position: relative; transition: background-color 150ms ease, border-color 150ms ease; width: 2.7rem; }
.toggle-control > span::after { background: white; border-radius: 50%; box-shadow: 0 1px 3px oklch(0.2 0.02 40 / .25); content: ""; height: 1.1rem; left: .15rem; position: absolute; top: .14rem; transition: transform 150ms var(--ease-out); width: 1.1rem; }
.toggle-control input:checked + span { background: var(--primary); border-color: var(--primary); }
.toggle-control input:checked + span::after { transform: translateX(1.15rem); }
.toggle-control input:focus-visible + span { outline: 3px solid var(--focus-ring); outline-offset: 2px; }
.toggle-control strong { font-size: .82rem; }

input[type="file"].form-control { cursor: pointer; padding: .35rem; }
input[type="file"].form-control::file-selector-button {
  background: var(--surface);
  border: 0;
  border-radius: var(--radius-md);
  color: var(--ink);
  cursor: pointer;
  font: inherit;
  font-size: .78rem;
  font-weight: 750;
  margin-right: .65rem;
  min-height: 34px;
  padding: .4rem .65rem;
}

.dashboard-page { max-width: 40rem; }
.dashboard-welcome { align-items: center; display: flex; gap: 1rem; }
.dashboard-welcome h1 { font-size: 1.75rem; margin: 0; }
.dashboard-facts { margin-top: .5rem; }
.dashboard-facts span { color: var(--muted); }

/* Forgejo #89. The dashboard's job is to answer "what is next" before anything
   else, so the next practice is the one large, high-contrast element and every
   other block is deliberately quieter. No new colour or shape vocabulary --
   this reuses the existing panel/surface tokens. */
.dashboard-next {
  border: 1px solid var(--line);
  border-radius: var(--radius-2xl);
  margin-top: 2rem;
  padding: 1.25rem;
}

.dashboard-next h2 {
  color: var(--muted);
  font-size: .78rem;
  font-weight: 800;
  letter-spacing: .07em;
  margin: 0 0 .6rem;
  text-transform: uppercase;
}

.dashboard-next-card {
  color: var(--ink);
  display: block;
  text-decoration: none;
}

.dashboard-next-card strong {
  display: block;
  font-size: 1.4rem;
  letter-spacing: -.02em;
  line-height: 1.2;
}

.dashboard-next-card:hover strong,
.dashboard-next-card:focus-visible strong { color: var(--primary-dark); }

.dashboard-next-when {
  color: var(--primary-dark);
  display: block;
  font-size: .95rem;
  font-weight: 700;
  margin-top: .35rem;
}

.dashboard-next-meta {
  color: var(--muted);
  display: block;
  font-size: .85rem;
  margin-top: .2rem;
}

.dashboard-next-actions {
  display: flex;
  flex-wrap: wrap;
  gap: .5rem;
  margin-top: 1rem;
}

.dashboard-next-empty h2 {
  color: var(--ink);
  font-size: 1.1rem;
  letter-spacing: -.01em;
  text-transform: none;
}

.dashboard-next-empty p { color: var(--muted); margin: 0 0 1rem; }

.dashboard-section { margin-top: 2rem; }

.dashboard-section-heading {
  align-items: baseline;
  display: flex;
  gap: 1rem;
  justify-content: space-between;
}

.dashboard-section-heading h2,
.dashboard-section-title {
  font-size: 1rem;
  margin: 0 0 .6rem;
}

.dashboard-list { list-style: none; margin: 0; padding: 0; }

.dashboard-list li + li { border-top: 1px solid var(--line); }

.dashboard-list a {
  color: var(--ink);
  display: block;
  min-height: 44px;
  padding: .7rem .25rem;
  text-decoration: none;
}

.dashboard-list a:hover { background: var(--surface); }
.dashboard-list a strong { display: block; font-size: .95rem; font-weight: 700; }
.dashboard-list a span { color: var(--muted); font-size: .82rem; }

/* Pairs the colour with a real character and role="status", never colour
   alone -- same rule the season calendar's status signals follow. */
.dashboard-alert {
  align-items: baseline;
  background: var(--warning-bg);
  border-radius: var(--radius-lg);
  color: var(--warning-ink);
  display: flex;
  font-size: .88rem;
  gap: .5rem;
  margin: 0;
  padding: .75rem .9rem;
}

.dashboard-alert span[aria-hidden] { font-weight: 800; }

.dashboard-quick { display: flex; flex-wrap: wrap; gap: .5rem; }
.dashboard-actions { margin-top: 1.75rem; }

/* Forgejo #3 — unified drill authoring workspace. The canvas/toolbar/phase
   list markup itself (editor/_toolbar.html.erb, the JS-rendered phaseList
   items) is untouched — #7 owns restyling those; this is just the new
   shared container the metadata panel and phase editor sit inside. */
.phase-editor { margin-top: 1.5rem; }
.viewport-banner { display: none; }
.phase-editor-header {
  align-items: center;
  display: flex;
  gap: 1rem;
  justify-content: flex-end;
  margin-bottom: .75rem;
}
.phase-editor-header span { color: var(--muted); font-size: .85rem; font-weight: 700; }
.single-diagram-editor .phase-editor-header { flex-wrap: wrap; }
.diagram-save-status {
  align-items: center;
  color: var(--muted);
  display: flex;
  gap: .4rem;
  margin: 0 auto 0 0;
}
.diagram-save-status strong { font-size: .82rem; }
.diagram-save-status small { font-size: .74rem; }
.diagram-save-indicator { border-radius: 50%; flex: 0 0 auto; height: .5rem; width: .5rem; }
.diagram-save-status[data-save-state="saved"] { color: var(--success); }
.diagram-save-status[data-save-state="saved"] .diagram-save-indicator { background: var(--success); }
.diagram-save-status[data-save-state="dirty"] { color: var(--warning-ink); }
.diagram-save-status[data-save-state="dirty"] .diagram-save-indicator { background: var(--warning-ink); }
.diagram-save-status[data-save-state="saving"] { color: var(--accent); }
.diagram-save-status[data-save-state="saving"] .diagram-save-indicator { background: var(--accent); }
.diagram-save-status[data-save-state="error"] { color: var(--danger); }
.diagram-save-status[data-save-state="error"] .diagram-save-indicator { background: var(--danger); }
.phase-meta-fields {
  display: grid;
  gap: .75rem;
  grid-template-columns: 1fr;
  margin-bottom: 1rem;
}
.phase-editor-layout { display: flex; flex-direction: column; gap: 1.5rem; }
.phase-editor-canvas { flex: 1; min-width: 0; }
.phase-editor-sidebar h2 { font-size: .95rem; margin: 0 0 .6rem; }
.phase-list { list-style: none; margin: 0 0 .75rem; padding: 0; }
.phase-editor-duplicate { width: 100%; }

/* Forgejo #31 — contextual element inspector */
.element-inspector {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-xl);
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  margin-top: .75rem;
  padding: .85rem 1rem;
}
.element-inspector-title {
  color: var(--muted);
  flex-basis: 100%;
  font-size: .75rem;
  font-weight: 700;
  margin: 0;
  text-transform: uppercase;
}
.inspector-field-group { display: flex; flex-wrap: wrap; gap: 1rem; }
.inspector-field { min-width: 8rem; }
.inspector-field .form-control { min-height: 2.75rem; }
.inspector-field-checkbox { display: flex; min-width: auto; }
.inspector-path-attachment { display: flex; align-items: center; gap: .5rem; min-width: auto; }

/* Forgejo #39 — unsafe view-change dialog and the persistent post-crop notice */
.view-change-dialog { margin-top: .75rem; }
.view-change-dialog p { margin: 0 0 .75rem; }

/* Forgejo #38 — station preset add/replace/cancel confirmation */
.station-preset-dialog { margin-top: .75rem; }
.station-preset-dialog p { margin: 0 0 .75rem; }
.view-outside-notice { align-items: center; display: flex; flex-wrap: wrap; gap: .75rem; justify-content: space-between; margin-top: .75rem; }

/* Forgejo #41 — local draft/crash recovery banner */
.draft-recovery-banner {
  align-items: center;
  background: var(--warning-bg);
  border-radius: var(--radius-lg);
  color: var(--warning-ink);
  display: flex;
  flex-wrap: wrap;
  gap: .75rem;
  justify-content: space-between;
  margin-bottom: .75rem;
  padding: .75rem;
}

/* Forgejo #37 — inline text/label editor: a plain HTML input positioned
   (via JS, left/top in px) directly over the click/element point on the
   stage, not an SVG element — see stage_controller.js's openInlineEditor(). */
.inline-text-editor {
  background: var(--bg);
  border: 2px solid var(--primary);
  border-radius: var(--radius-sm);
  color: var(--ink);
  font-size: 1rem;
  min-width: 6rem;
  padding: .15rem .4rem;
  position: fixed;
  text-align: center;
  transform: translate(-50%, -50%);
  z-index: 40;
}
textarea.inline-text-editor { min-height: 1.6rem; resize: both; }

/* Forgejo #42: the Alt-click overlap chooser -- a plain HTML popup
   positioned (via JS, left/top in px) over the click point, same
   "outside the SVG" approach as .inline-text-editor above. */
/* Forgejo #45: the editor's export options panel -- a <details> popover,
   same visual language as .rink-view-popover, holding the content/
   background/scale radios. The Export button itself stays a sibling, always
   visible (the "Diagram only" one-click path never requires opening this). */
.export-panel { align-items: center; display: flex; gap: .5rem; position: relative; }
.export-panel-options { position: relative; }
.export-panel-options summary { cursor: pointer; list-style: none; }
.export-panel-options summary::-webkit-details-marker { display: none; }
.export-panel-options summary::marker { content: ""; }
.export-panel-options fieldset {
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: 0 8px 24px var(--shadow-tint);
  margin-top: .25rem;
  padding: .5rem .75rem;
  position: absolute;
  white-space: nowrap;
  z-index: 20;
}
.export-panel-options fieldset:nth-of-type(1) { top: 100%; }
.export-panel-options fieldset:nth-of-type(2) { top: 100%; left: 9rem; }
.export-panel-options fieldset:nth-of-type(3) { top: 100%; left: 17rem; }
.export-panel-options legend { color: var(--muted); font-size: .8rem; }
.export-panel-options label { display: block; font-size: .9rem; padding: .15rem 0; }

.overlap-chooser {
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-overlap-chooser);
  display: flex;
  flex-direction: column;
  min-width: 9rem;
  overflow: hidden;
  position: fixed;
  transform: translate(-50%, -50%);
  z-index: 40;
}

.overlap-chooser-option {
  background: none;
  border: none;
  color: var(--ink);
  cursor: pointer;
  font-size: .9rem;
  padding: .4rem .75rem;
  text-align: left;
}

.overlap-chooser-option:hover, .overlap-chooser-option:focus-visible {
  background: var(--surface);
}

/* Forgejo #37: the stage <svg> carries tabindex="-1" purely so
   closeInlineEditor() can programmatically restore focus to it after a
   commit/cancel — it is never part of the tab order, so the browser's
   default focus ring (meant for keyboard navigation) would be misleading
   noise here rather than a useful cue. */
svg[data-editor--stage-target="svg"]:focus { outline: none; }

@media (min-width: 1024px) {
  .phase-editor-layout { flex-direction: row; }
  .phase-editor-sidebar { flex: 0 0 16rem; }
  .phase-meta-fields { grid-template-columns: 1fr 2fr 1fr; }
}

/* Segment diagram edit gate: tools sit in a right-hand nav column next to
   the canvas instead of stacked below it -- scoped to .single-diagram-editor
   (added by editor/_single_diagram_editor.html.erb) so the drill phase
   editor, which reuses the same .phase-editor/.editor-toolbar classes, keeps
   its existing below-canvas layout untouched. */
@media (min-width: 1024px) {
  /* Both editors now share this shape -- the drill phase editor's toolbar
     used to sit below its canvas, which is the inconsistency this removes. */
  .single-diagram-editor .phase-editor-canvas,
  .phase-editor .phase-editor-canvas { align-items: flex-start; display: flex; gap: 1rem; }
  .single-diagram-editor .editor-rink, .phase-editor .editor-rink { flex: 0 1 auto; min-width: 0; }
  /* The rink is capped at --rink-max-height, but the tools column next to it
     runs ~41rem (an 8-tool grid, the arrange row, and the view/reset
     controls), so IT was setting the editor's height, not the rink. Capping
     it to the same height is what actually makes the editor as tall as a
     segment's. */
  .single-diagram-editor .diagram-tools-column, .phase-editor .diagram-tools-column {
    flex: 0 0 18rem;
    max-height: var(--editor-rink-max-height);
    overflow-y: auto;
    overscroll-behavior: contain;
  }
  /* ...which means an absolutely-positioned popover would be clipped by that
     new scroll container. Inside this column they open inline instead and the
     column scrolls to them -- a dropdown you cannot see is worse than one
     that pushes the controls below it down. */
  .diagram-tools-column .palette-menu-list,
  .diagram-tools-column .rink-view-popover-grid,
  .diagram-tools-column .clear-menu-list {
    box-shadow: none;
    margin-top: .35rem;
    max-width: 100%;
    min-width: 0;
    position: static;
  }
  .single-diagram-editor .editor-toolbar, .phase-editor .editor-toolbar { margin-top: 0; }

  /* The base 8-column tool grid is sized for the drill phase editor, whose
     toolbar spans the full page width below its canvas. In this column the
     container is a fixed 18rem no matter how wide the viewport is, which left
     ~1.7rem per track -- narrower than one non-shrinking 1.7rem icon plus its
     own padding, so icons overflowed or disappeared entirely. The 1180px
     override further down compensates on the viewport axis, which is the
     wrong axis here; this out-specifies it. Everything else in the column
     (tool options, popover triggers) is capped to the same 18rem. */
  .phase-editor .palette-tools .palette-grid,
  .single-diagram-editor .palette-tools .palette-grid { grid-template-columns: repeat(auto-fill, minmax(7rem, 1fr)); }
  .phase-editor .palette-tool-button,
  .single-diagram-editor .palette-tool-button { line-height: 1.2; text-align: left; }
  .phase-editor .palette-tool-button svg,
  .single-diagram-editor .palette-tool-button svg { flex: 0 0 1.5rem; height: 1.5rem; width: 1.5rem; }
  .phase-editor .editor-option-group,
  .single-diagram-editor .editor-option-group { flex-wrap: wrap; }
  .phase-editor .palette-menu-trigger,
  .single-diagram-editor .palette-menu-trigger { min-width: 0; width: 100%; }
  .phase-editor .palette-menu-list,
  .single-diagram-editor .palette-menu-list { max-width: 16rem; min-width: 0; }
  .phase-editor .editor-text-option .form-control,
  .phase-editor .editor-number-option .form-control,
  .single-diagram-editor .editor-text-option .form-control,
  .single-diagram-editor .editor-number-option .form-control { width: 100%; }
  .phase-editor .editor-toolbar-options > .palette-field,
  .phase-editor .editor-option-group > .palette-field,
  .single-diagram-editor .editor-toolbar-options > .palette-field,
  .single-diagram-editor .editor-option-group > .palette-field { flex: 1 1 7.5rem; min-width: 0; }
}

/* The split editor layout: tools in a left rail, the rink in the middle,
   a collapsed rink/surface panel plus the inspector on the right, and Edit &
   arrange / zoom / erase in one command bar above. Introduced for the drill
   phase editor (2026-09-13) and adopted by the practice-session segment and
   rink-layout editors (2026-09-14), which is why the class is .split-editor
   and not the drill-specific name it started with. Still never keyed on bare
   .phase-editor, which also matches editors that do NOT opt in. */
.editor-command-bar {
  align-items: center;
  background: var(--surface-subtle);
  border-radius: var(--radius-2xl);
  flex-wrap: wrap;
  gap: .5rem;
  margin-bottom: .75rem;
  padding: .5rem .65rem;
}
.editor-command-bar-label { color: var(--muted); font-size: .7rem; font-weight: 800; letter-spacing: .06em; text-transform: uppercase; }
.editor-command-bar-divider { align-self: stretch; border-left: 1px solid var(--line); }
.editor-command-bar .clear-menu > summary { align-items: center; display: inline-flex; }

.editor-view-panel { background: var(--surface-subtle); border-radius: var(--radius-2xl); margin-bottom: .75rem; }
.editor-view-panel-summary {
  align-items: center;
  color: var(--muted);
  cursor: pointer;
  display: flex;
  font-size: .7rem;
  font-weight: 800;
  justify-content: space-between;
  letter-spacing: .06em;
  list-style: none;
  min-height: 44px;
  padding: 0 .8rem;
  text-transform: uppercase;
}
.editor-view-panel-summary::-webkit-details-marker { display: none; }
.editor-view-panel-summary svg { color: var(--muted); transition: transform 150ms var(--ease-out); }
.editor-view-panel[open] .editor-view-panel-summary svg { transform: rotate(180deg); }
.editor-view-panel-body { display: grid; gap: .9rem; padding: 0 .8rem .8rem; }

@media (min-width: 1024px) {
  .split-editor .editor-tool-rail {
    flex: 0 0 13rem;
    /* The rail scrolls again, on purpose: tool options now expand as an
       accordion under the active tool, so the options themselves never need
       an inner scrollbar, and scrolling to reach a different tool is the
       accepted trade (owner's call). */
    max-height: var(--editor-rink-max-height);
    overflow-y: auto;
    overscroll-behavior: contain;
  }
  .split-editor .editor-tool-rail .editor-toolbar-heading { display: block; margin-bottom: .4rem; }
  /* Clamped, and with the two lines reserved whether or not they are used:
     the status text runs from "" to a full sentence, and in a 12rem rail an
     unclamped one is ~5 lines -- so every tool switch would otherwise shove
     the whole tool grid below it up or down. */
  .split-editor .editor-tool-rail .tool-status {
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    display: -webkit-box;
    font-size: .68rem;
    line-height: 1.3;
    min-height: 2.6em;
    overflow: hidden;
    text-align: left;
  }
  .split-editor .editor-tool-rail .palette-tool-button { min-height: 38px; }
  /* Option lists expand in place rather than flying out beside the rail --
     that is what makes this read as an accordion belonging to the tool above
     it. Three classes, so this out-specifies .phase-editor .palette-menu-list
     above rather than depending on source order. */
  .split-editor .editor-tool-rail .palette-menu-list {
    box-shadow: none;
    margin-top: .35rem;
    max-width: 100%;
    min-width: 0;
    position: static;
  }
}

@media (max-width: 1023px) {
  .viewport-banner {
    background: var(--warning-bg);
    border-radius: var(--radius-lg);
    color: var(--warning-ink);
    display: block;
    font-size: .82rem;
    margin-bottom: 1rem;
    padding: .75rem;
  }
}

/* Forgejo #7 — icon-first tool palette */
.palette-field { display: flex; flex-direction: column; gap: .3rem; }
.palette-label { color: var(--muted); font-size: .75rem; font-weight: 700; text-transform: uppercase; }
.palette-grid { display: flex; flex-wrap: wrap; gap: .25rem; }
.palette-button {
  align-items: center;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  cursor: pointer;
  display: flex;
  height: 2.25rem;
  justify-content: center;
  padding: .2rem;
  width: 2.25rem;
}
.palette-button:hover { background: var(--surface); }
.palette-button:focus-visible { outline: 2px solid var(--primary); outline-offset: 1px; }
.palette-button.is-selected { background: var(--surface-strong); border-color: var(--primary); }
.palette-preview-svg { height: 100%; width: 100%; }

/* Forgejo #17 — Configuration hub */
.configuration-grid {
  display: grid;
  gap: 1.25rem;
  grid-template-columns: 1fr;
}
.configuration-card-header {
  align-items: center;
  display: flex;
  justify-content: space-between;
  margin-bottom: .5rem;
}
.configuration-card-header h2 { font-size: 1.05rem; margin: 0; }
.configuration-card p { color: var(--muted); margin: 0 0 1rem; }

@media (min-width: 768px) {
  .configuration-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* Forgejo #43 — active-tool cursor, status line, disabled undo/redo, and the
   keyboard-shortcut reference dialog. Cursor is driven entirely by the
   stage's own data-tool attribute (set in syncToolFields()) rather than a
   class list — one rule per tool value, nothing to toggle on/off by hand. */
svg[data-tool] { cursor: default; }
svg[data-tool="player"], svg[data-tool="object"], svg[data-tool="overlay"],
svg[data-tool="text"], svg[data-tool="number"] { cursor: crosshair; }
svg[data-tool="pan"] { cursor: grab; }
svg.stage-panning-active { cursor: grabbing; }

.tool-status { color: var(--muted); font-size: .85rem; margin: 0 0 .5rem; min-height: 1.2em; }

button[data-editor--stage-target="undoButton"]:disabled,
button[data-editor--stage-target="redoButton"]:disabled { cursor: not-allowed; opacity: .5; }

/* 2026 form/editor overhaul — diagram-first workspace (Forgejo #56). */
.drill-workspace > .page-heading { margin-bottom: 1rem; }
.phase-editor { margin-top: 0; }
.phase-editor-header { border-bottom: 1px solid var(--line); margin: 0 0 .75rem; padding: 0 0 .65rem; }
/* Phases are the level below variations, so they take the diagram tabs' cool
   "ice" hue rather than the warm variation/segment palette -- same reason the
   segment diagram's Layout/Stations strip does. */
.phase-tabs-shell { border-bottom: 1px solid var(--diagram-line); margin-bottom: .75rem; }
.phase-tabs-scroll { align-items: flex-end; display: flex; gap: .35rem; overflow-x: auto; padding: .2rem .1rem 0; scrollbar-width: thin; }
.phase-list { display: flex; flex: 0 0 auto; gap: .25rem; list-style: none; margin: 0; padding: 0; }
.phase-tab-item { align-items: center; display: inline-flex; position: relative; }
.phase-tab-thumbnail { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-sm); flex: 0 0 auto; height: 2.1rem; margin: 0 .5rem 0 .35rem; width: 3.2rem; }
.phase-tab { background: var(--diagram-tab-bg); border: 1px solid var(--diagram-line); border-bottom: 0; border-radius: var(--radius-md) var(--radius-md) 0 0; color: var(--diagram-tab-ink); cursor: pointer; font: inherit; font-size: .8rem; font-weight: 700; min-height: 38px; padding: .45rem 1.6rem .4rem .75rem; white-space: nowrap; }
.phase-tab:hover { background: var(--diagram-tab-hover); }
.phase-tab[aria-selected="true"] { background: var(--bg); border-color: var(--diagram-tab-active-border); box-shadow: var(--shadow-tab-seam); color: var(--diagram-tab-ink-active); }
.phase-tab:focus-visible, .phase-add-tab:focus-visible, .phase-tab-remove:focus-visible { outline: 3px solid var(--focus-ring); outline-offset: -2px; }
.phase-tab-remove { background: transparent; border: 0; border-radius: 50%; color: var(--muted); cursor: pointer; font-size: 1rem; height: 1.5rem; position: absolute; right: .1rem; width: 1.5rem; }
.phase-tab-remove:hover { background: var(--danger-bg); color: var(--danger); }
.phase-add-tab { align-items: center; background: var(--diagram-tab-bg); border: 1px solid var(--diagram-line); border-bottom: 0; border-radius: var(--radius-md) var(--radius-md) 0 0; color: var(--diagram-tab-ink-active); cursor: pointer; display: inline-flex; flex: 0 0 38px; font-size: 1.15rem; height: 38px; justify-content: center; }
.phase-add-tab:hover { background: var(--diagram-tab-hover); }
/* Drill variations use the segment tab language, in their own class family
   (a builder-page test counts selected button.segment-tab page-wide). Each
   tab is a real link: switching variation rebuilds the whole editor. */
.variation-tabs { display: flex; flex: 0 0 auto; gap: .35rem; list-style: none; margin: 0; padding: 0; }
.variation-tab-item {
  align-items: center;
  background: var(--surface);
  border: 1px solid var(--line);
  border-bottom: 0;
  border-radius: var(--radius-md) var(--radius-md) 0 0;
  display: inline-flex;
  height: 40px;
  overflow: hidden;
  position: relative;
  transition: background-color 180ms var(--ease-out);
}
.variation-tab-item.is-active { background: var(--bg); box-shadow: var(--shadow-tab-seam); }
.variation-tab-item:not(.is-active):hover { background: var(--control-hover); }
.variation-tab {
  align-items: center;
  color: var(--muted);
  display: inline-flex;
  font-size: .82rem;
  font-weight: 700;
  gap: .3rem;
  height: 100%;
  padding: .5rem .8rem;
  text-decoration: none;
  white-space: nowrap;
}
.variation-tab[aria-selected="true"] { color: var(--ink); }
.variation-tab:focus-visible { outline: 3px solid var(--focus-ring); outline-offset: -2px; }
/* Marks a variation that has no diagrams of its own and is following the
   base drill's. */
.variation-tab em { color: var(--muted); font-size: .9rem; font-style: normal; }
.variation-tab-item .segment-tab-handle { padding-left: .3rem; }
.variation-add-form { display: inline-flex; }
.drill-variation-workspace { border-radius: 0 0 var(--radius-md) var(--radius-md); padding: 1rem; }
.drill-variation-workspace .phase-editor { margin-top: 0; }
.variation-attributes { border-top: 1px solid var(--line); margin-top: 1.25rem; padding-top: 1rem; }
.variation-attributes .section-heading h3 { font-size: .95rem; margin: 0; }
.variation-attributes .section-heading p { color: var(--muted); font-size: .8rem; margin: .2rem 0 0; }
.variation-fallback-notice {
  align-items: center;
  background: var(--surface);
  border: 1px dashed var(--line);
  border-radius: var(--radius-lg);
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  justify-content: space-between;
  padding: 1rem;
}
.variation-fallback-notice p { color: var(--muted); font-size: .84rem; margin: .3rem 0 0; max-width: 46rem; }
.variation-fallback-preview { margin-top: 1.25rem; }
.drill-summary { color: var(--muted); margin: 0 0 1rem; max-width: 52rem; }
.drill-attributes { display: grid; gap: .75rem 1.5rem; grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr)); margin: 0; }
.drill-attributes > div { min-width: 0; }
.drill-attributes dt { color: var(--muted); font-size: .74rem; font-weight: 800; letter-spacing: .05em; text-transform: uppercase; }
.drill-attributes dd { font-size: .88rem; margin: .2rem 0 0; }
.drill-show-diagram {
  background: var(--ice-surface-alt);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  display: block;
  height: var(--rink-max-height);
  margin-inline: auto;
  max-width: 100%;
  width: auto;
}
.drill-show-diagram.is-empty { aspect-ratio: 2 / 1; align-items: center; color: var(--muted); display: flex; font-size: .85rem; justify-content: center; }
.variation-fallback-preview h4 { color: var(--muted); font-size: .74rem; font-weight: 800; letter-spacing: .05em; margin: 0 0 .5rem; text-transform: uppercase; }

/* Height is fixed and the WIDTH follows the svg's own viewBox ratio -- no
   `aspect-ratio` here on purpose. A hardcoded 2:1 only matches the quarter_*
   views; the presets run from 0.25 (youth_cross_ice) to 2.0, so on half rink
   or an end zone the rink was drawn small and centred inside a 2:1 box,
   leaving wide dead strips. Those strips are not inert: screenToRinkPoint
   maps them to real coordinates outside the viewBox and has no clamp, so a
   click there placed an element nobody could see. With width:auto the box IS
   the rink, at every preset, so every pixel of it is live. */
/* The rink grows to whatever the column between the tool rail and the right
   panel allows, stopping only when its height would pass --editor-rink-max-
   height. width = min(available, cap x ratio) with the live aspect-ratio (both
   set by stage_controller#applyEditorViewBox) means the box is ALWAYS exactly
   the rink's own shape -- no max-height, because a max-height that engaged
   would letterbox and bring back the clickable dead strips 1fad23e removed.
   A 22.5x30 portrait crop (the 1v1 drill) was previously drawn 22rem tall and
   therefore only ~16rem wide, which is the "too small" complaint. */
.editor-rink { background: var(--ice-surface-alt); border: 0; border-radius: var(--radius-xl); box-shadow: inset 0 0 0 1px oklch(0.84 0.025 205); display: block; height: auto; margin-inline: auto; width: min(100%, calc(var(--editor-rink-max-height) * var(--rink-aspect, 2))); }
.editor-toolbar { background: var(--surface-subtle); border-radius: var(--radius-2xl); margin-top: .65rem; }
.editor-toolbar-section { padding: .7rem .8rem; }
.editor-toolbar-section + .editor-toolbar-section { border-top: 1px solid var(--line); }
.editor-toolbar-heading { align-items: center; display: flex; gap: 1rem; justify-content: space-between; margin-bottom: .55rem; }
.editor-toolbar-heading > span, .editor-toolbar-label { color: var(--muted); display: block; font-size: .7rem; font-weight: 800; letter-spacing: .06em; margin-bottom: .5rem; text-transform: uppercase; }
.editor-toolbar-heading .tool-status { margin: 0; text-align: right; }
.palette-field > select:not(.form-control) { position: absolute; height: 1px; opacity: 0; width: 1px; }
.palette-tools .palette-grid { display: grid; gap: .35rem; grid-template-columns: repeat(8, minmax(0, 1fr)); }
.palette-tool-button { align-items: center; background: var(--bg); border: 1px solid var(--line-strong); border-radius: var(--radius-lg); color: var(--ink); cursor: pointer; display: flex; font-size: .73rem; font-weight: 700; gap: .4rem; justify-content: flex-start; min-height: 44px; padding: .35rem .45rem; }
.palette-tool-button svg { flex: 0 0 1.7rem; height: 1.7rem; width: 1.7rem; }
.palette-tool-button:hover { background: var(--control-hover); }
.palette-tool-button.is-selected { background: oklch(0.94 0.04 42); border-color: var(--primary); color: var(--primary-dark); }
.palette-tool-button:focus-visible { outline: 3px solid var(--focus-ring); outline-offset: 1px; }
.editor-toolbar-options { align-items: end; display: flex; flex-wrap: wrap; gap: .65rem; }
/* View & reset: four named groups with a one-line explanation each, rather
   than one flat row where "Full rink" sat next to "Clear…". */
.editor-toolbar-view { display: grid; gap: .9rem; }
.editor-view-group { display: grid; gap: .4rem; }
.editor-view-group + .editor-view-group { border-top: 1px solid var(--line); padding-top: .8rem; }
.editor-view-group-label { color: var(--ink); font-size: .78rem; font-weight: 750; }
.editor-view-hint { color: var(--muted); font-size: .72rem; line-height: 1.35; margin: 0; }
.editor-view-group .palette-field + .palette-field { margin-top: .2rem; }
.editor-view-group .clear-menu > summary, .editor-view-group > button { width: 100%; }
.editor-toolbar-options > .editor-toolbar-label { flex-basis: 100%; margin-bottom: -.1rem; }
.editor-option-group { align-items: end; display: flex; gap: .65rem; }
.palette-menu { position: relative; }
.palette-menu > summary { list-style: none; }
.palette-menu > summary::-webkit-details-marker { display: none; }
.palette-menu-trigger { align-items: center; background: var(--bg); border: 1px solid var(--control-border); border-radius: var(--radius-lg); cursor: pointer; display: flex; gap: .4rem; min-height: 38px; min-width: 9.5rem; padding: .3rem .45rem; }
.palette-menu-trigger svg { height: 1.65rem; width: 1.65rem; }
.palette-menu-trigger > span:nth-child(2) { flex: 1; font-size: .78rem; font-weight: 700; text-align: left; }
.palette-menu-trigger > span:last-child { color: var(--muted); }
.palette-menu-trigger:focus-visible { outline: 3px solid var(--focus-ring); outline-offset: 1px; }
.palette-menu-list { background: var(--bg); border: 1px solid var(--line); border-radius: var(--radius-xl); box-shadow: var(--shadow-popover); display: grid; gap: .15rem; left: 0; max-height: 22rem; min-width: 17rem; overflow-y: auto; padding: .35rem; position: absolute; top: calc(100% + .35rem); transform-origin: top left; z-index: 30; }
.palette-menu-list { opacity: 1; transform: scale(1) translateY(0); transition: opacity 150ms var(--ease-out), transform 150ms var(--ease-out); }
@starting-style {
  .palette-menu-list { opacity: 0; transform: scale(.97) translateY(-3px); }
}
.palette-menu-option { align-items: center; background: transparent; border: 0; border-radius: var(--radius-md); color: var(--ink); cursor: pointer; display: flex; gap: .65rem; min-height: 48px; padding: .35rem .45rem; text-align: left; }
.palette-menu-option:hover, .palette-menu-option.is-selected { background: var(--surface); }
.palette-menu-option.is-selected { box-shadow: inset 2px 0 var(--primary); }
.palette-menu-option svg { flex: 0 0 2rem; height: 2rem; width: 2rem; }
.palette-menu-option > span { display: flex; flex-direction: column; }
.palette-menu-option strong { font-size: .8rem; }
.palette-menu-option small { color: var(--muted); font-size: .7rem; margin-top: .1rem; }
.form-control-compact { min-height: 38px; padding: .45rem .6rem; }
.editor-inline-control, .editor-action-row { align-items: center; display: flex; flex-wrap: wrap; gap: .35rem; }
.editor-number-option .form-control { width: 4.5rem; }
.editor-text-option .form-control { width: 10rem; }
.btn-compact { font-size: .76rem; min-height: 36px; padding: .4rem .65rem; }
.editor-icon-actions { gap: .3rem; }
.editor-icon-actions .icon-button:disabled { cursor: not-allowed; opacity: .5; }
.clear-menu { position: relative; }
.clear-menu > summary { list-style: none; }
.clear-menu > summary::-webkit-details-marker { display: none; }
.clear-menu-list { background: var(--bg); border: 1px solid var(--line); border-radius: var(--radius-xl); box-shadow: var(--shadow-popover); display: grid; min-width: 13rem; padding: .35rem; position: absolute; right: 0; top: calc(100% + .35rem); z-index: 30; }
.clear-menu-list button { background: transparent; border: 0; border-radius: var(--radius-md); color: var(--ink); cursor: pointer; font: inherit; font-size: .78rem; min-height: 38px; padding: .4rem .55rem; text-align: left; }
.clear-menu-list button:hover { background: var(--danger-bg); color: var(--danger); }
.clear-menu-list button:last-child { border-top: 1px solid var(--line); color: var(--danger); margin-top: .2rem; }
.phase-details { border-top: 1px solid var(--line); margin-top: .75rem; }
.phase-details > summary { align-items: center; cursor: pointer; display: flex; font-size: .82rem; font-weight: 750; justify-content: space-between; list-style: none; min-height: 48px; }
.phase-details > summary small { color: var(--muted); font-size: .72rem; font-weight: 500; margin-left: auto; margin-right: .75rem; }
.phase-details > summary::after { color: var(--muted); content: "+"; font-size: 1.1rem; }
.phase-details[open] > summary::after { content: "−"; }
.phase-details .phase-meta-fields { margin: 0; padding-bottom: .5rem; }
.drill-metadata-section { margin-top: 1.5rem; }

.drill-variations-section { margin-top: 1.5rem; }
.drill-variations { display: flex; flex-direction: column; gap: .75rem; }
.drill-variation { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-lg); padding: .85rem 1rem; }
.drill-variation.is-sorting { opacity: .6; }
.drill-variation-toolbar { align-items: center; display: flex; gap: .5rem; margin-bottom: .5rem; }
.drill-variation-handle { color: var(--muted); cursor: grab; padding: .4rem .35rem; touch-action: none; }
.drill-variation-move { display: flex; flex: 0 0 auto; }
.drill-variation-move button { background: transparent; border: 0; color: var(--muted); cursor: pointer; height: 40px; width: 28px; }
.drill-variation-fields { display: grid; gap: .75rem; grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr)); margin-top: .75rem; }
.drill-variation-fields > .field-full { grid-column: 1 / -1; }
.drill-variation-form-actions { display: flex; justify-content: flex-end; margin-top: .75rem; }
.drill-variation-add { margin-top: .75rem; }

@media (max-width: 1180px) and (min-width: 1024px) {
  .palette-tools .palette-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

.shortcut-dialog {
  border: 1px solid var(--line);
  border-radius: var(--radius-xl);
  box-shadow: 0 1rem 3rem var(--shadow-tint-strong);
  max-height: 80vh;
  max-width: 40rem;
  overflow-y: auto;
  padding: 1.5rem;
  width: 90vw;
}
.shortcut-dialog::backdrop { background: var(--scrim); }
.shortcut-dialog-header { align-items: center; display: flex; justify-content: space-between; margin-bottom: 1rem; }
.shortcut-dialog-header h2 { font-size: 1.1rem; margin: 0; }
.shortcut-dialog h3 { color: var(--muted); font-size: .8rem; margin: 1rem 0 .3rem; text-transform: uppercase; }
.shortcut-list { display: grid; gap: .3rem .5rem; grid-template-columns: auto 1fr; margin: 0; }
.shortcut-list dt { font-weight: 700; }
.shortcut-list dd { color: var(--muted); margin: 0; }

/* Forgejo #52 — DEB RTK knowledge review surface */
.status-raw, .status-reviewed { background: var(--surface-strong); color: var(--muted); }
.status-approved { background: var(--status-ready-bg); color: var(--status-ready-ink); }
.status-superseded { background: var(--surface-strong); color: var(--muted); }

.deb-review-filter-form { align-items: end; display: flex; flex-wrap: wrap; gap: .75rem; margin-bottom: 1rem; }
.deb-review-status-counts { display: flex; flex-wrap: wrap; gap: .5rem; margin-bottom: 1.5rem; }
.deb-review-list { display: flex; flex-direction: column; gap: .6rem; }
.deb-review-row {
  align-items: center;
  color: var(--ink);
  display: flex;
  gap: 1rem;
  text-decoration: none;
}
.deb-review-row div { min-width: 0; }
.deb-review-row strong { display: block; }
.deb-review-row small { color: var(--muted); }

.deb-review-detail { display: flex; flex-direction: column; gap: 1.25rem; margin: 0 auto; max-width: 60rem; padding-bottom: 4rem; }
.deb-provenance-record + .deb-provenance-record { border-top: 1px solid var(--line); margin-top: .75rem; padding-top: .75rem; }
.deb-provenance-record p { margin: .2rem 0; }
.deb-review-conflict-card {
  align-items: center;
  border-top: 1px solid var(--line);
  display: flex;
  gap: 1rem;
  justify-content: space-between;
  padding: .75rem 0;
}
.deb-review-actions { display: flex; flex-direction: column; gap: .75rem; }
.deb-media + .deb-media { border-top: 1px solid var(--line); margin-top: 1.25rem; padding-top: 1.25rem; }
.deb-media-frame { aspect-ratio: 16 / 9; background: #000; border-radius: var(--radius-lg); overflow: hidden; width: 100%; }
.deb-media-frame iframe { border: 0; display: block; height: 100%; width: 100%; }
.deb-media figcaption { color: var(--muted); font-size: .9rem; margin-top: .5rem; }
.deb-empty-content { color: var(--muted); }
.deb-confidence-line { border-top: 1px solid var(--line); color: var(--muted); font-size: .9rem; margin-top: 1rem; padding-top: .75rem; }
.deb-value-list { margin: 0; padding-left: 1.1rem; }
.deb-value-list li + li { margin-top: .35rem; }
.deb-value-nested { margin: 0; }
.deb-value-nested dt { color: var(--muted); font-size: .85rem; }

/* Forgejo #78 (C2): a plain <ul> of recurring slots -- no dedicated
   styling existed yet, so it fell back to raw browser bullet-list
   defaults. */
.season-recurring-slot-list { list-style: none; margin: 0 0 1rem; padding: 0; }
.season-recurring-slot-list li {
  align-items: center;
  border-bottom: 1px solid var(--line);
  display: flex;
  justify-content: space-between;
  padding: .5rem 0;
}
.season-recurring-slot-list li:last-child { border-bottom: none; }

/* Forgejo #81 (D2): Monday-first month grid. Each .month-week is its own
   CSS grid so a block bar's grid-column can be positioned against the
   same 7 columns the day cells below it use, independent of any other
   week's row. No visual browser pass was available in this environment --
   see CLAUDE.md's own #81 entry. */
.season-calendar-header {
  align-items: end;
  display: flex;
  gap: 1.5rem;
  justify-content: space-between;
  margin-bottom: 1.5rem;
}
.season-calendar-header h1 { font-size: 1.6rem; letter-spacing: -.02em; margin: .3rem 0 0; }

.month-grid { border: 1px solid var(--line); border-radius: var(--radius-xl); overflow: hidden; }
.month-grid-weekday-header {
  background: var(--surface);
  border-bottom: 1px solid var(--line);
  display: grid;
  font-size: .72rem;
  font-weight: 700;
  grid-template-columns: repeat(7, 1fr);
  padding: .4rem 0;
  text-align: center;
  text-transform: uppercase;
}
.month-week { border-bottom: 1px solid var(--line); }
.month-week:last-child { border-bottom: none; }
.month-week-blocks {
  display: grid;
  gap: .2rem;
  grid-auto-rows: 1.4rem;
  grid-template-columns: repeat(7, 1fr);
  padding: .3rem .2rem 0;
}
.month-block-bar {
  align-items: center;
  background: var(--accent);
  border: 0;
  border-radius: var(--radius-sm);
  color: white;
  cursor: pointer;
  display: flex;
  font-size: .68rem;
  font-weight: 700;
  min-height: 44px;
  overflow: hidden;
  padding: 0 .5rem;
  text-align: left;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.month-week-days { display: grid; grid-template-columns: repeat(7, 1fr); min-height: 6rem; }
.month-day { border-left: 1px solid var(--line); padding: .3rem; }
.month-day:first-child { border-left: none; }
.month-day.is-outside-month { background: var(--surface); color: var(--muted); }
.month-day.is-today .month-day-number {
  background: var(--primary);
  border-radius: 50%;
  color: white;
  display: inline-flex;
  height: 1.5rem;
  justify-content: center;
  align-items: center;
  width: 1.5rem;
}
.month-day-number { font-size: .78rem; font-weight: 700; }
.month-day-sessions { display: flex; flex-direction: column; gap: .25rem; margin-top: .3rem; }
.month-session-chip {
  align-items: center;
  border-radius: var(--radius-sm);
  display: flex;
  font-size: .65rem;
  gap: .25rem;
  min-height: 44px;
  padding: .25rem .4rem;
  text-decoration: none;
}
.month-session-chip-title { color: inherit; flex: 1; font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.month-session-chip-status { color: inherit; font-size: .6rem; opacity: .8; text-transform: uppercase; }
.month-session-chip.status-planned { background: var(--status-planned-bg); color: var(--status-planned-ink); }
.month-session-chip.status-draft { background: var(--surface-strong); color: var(--muted); }
.month-session-chip.status-published { background: var(--success-bg); color: var(--success); }
.month-session-chip.status-completed { background: var(--surface-strong); color: var(--ink); opacity: .7; }
.month-session-chip.is-faulty { background: var(--danger-bg); color: var(--danger); }
.month-session-chip.is-past:not(.is-faulty) { opacity: .65; }
.month-session-chip-projected {
  background: transparent;
  border: 1px dashed var(--line);
  color: var(--muted);
  justify-content: center;
}
.month-session-chip-projected:hover { background: var(--surface); }

.calendar-block-dialog {
  border: 1px solid var(--line);
  border-radius: var(--radius-xl);
  box-shadow: 0 1rem 3rem var(--shadow-tint-strong);
  max-width: 28rem;
  padding: 1.5rem;
  width: 90vw;
}
.calendar-block-dialog::backdrop { background: var(--scrim); }
.calendar-block-dialog-dates { color: var(--muted); font-size: .85rem; }
.calendar-block-dialog-focus { color: var(--muted); font-size: .85rem; margin-top: .5rem; }

/* Forgejo #82 (D3): week view. --hour-row-height sets the total scrollable
   height of the 06:00-23:00 axis; every session's top/height (inline
   style, from WeekGrid#position_for) is a percentage of this same height,
   so the two always agree. No visual browser pass was available in this
   environment -- see CLAUDE.md's own #82 entry. */
.week-grid { --hour-row-height: 60rem; border: 1px solid var(--line); border-radius: var(--radius-xl); overflow: hidden; }
.week-hour-axis-spacer { width: 4rem; }
.week-grid-header { border-bottom: 1px solid var(--line); display: grid; grid-template-columns: 4rem repeat(7, 1fr); }
.week-day-header { border-left: 1px solid var(--line); padding: .5rem; text-align: center; }
.week-day-header span { color: var(--muted); display: block; font-size: .68rem; text-transform: uppercase; }
.week-day-header strong { font-size: 1rem; }
.week-day-header.is-today strong { color: var(--primary-dark); }
.week-blocks-row { border-bottom: 1px solid var(--line); display: grid; grid-template-columns: 4rem 1fr; padding: .3rem 0; }
.week-blocks { display: grid; gap: .2rem; grid-auto-rows: 1.4rem; grid-template-columns: repeat(7, 1fr); }
.week-all-day-row { border-bottom: 1px solid var(--line); display: grid; grid-template-columns: 4rem 1fr; padding: .3rem 0; }
.week-all-day-row .week-hour-axis-spacer { color: var(--muted); font-size: .68rem; padding-top: .3rem; text-align: right; padding-right: .5rem; }
.week-all-day-cells { display: grid; gap: .2rem; grid-template-columns: repeat(7, 1fr); }
.week-all-day-cell { display: flex; flex-direction: column; gap: .2rem; padding: 0 .2rem; }
.week-time-body { display: grid; grid-template-columns: 4rem 1fr; }
.week-hour-axis { height: var(--hour-row-height); position: relative; }
.week-hour-label {
  color: var(--muted);
  font-size: .68rem;
  padding-right: .5rem;
  position: absolute;
  right: 0;
  text-align: right;
  transform: translateY(-50%);
}
.week-day-columns { display: grid; grid-template-columns: repeat(7, 1fr); }
.week-day-column {
  background-image: repeating-linear-gradient(to bottom, var(--line) 0, var(--line) 1px, transparent 1px, transparent calc(var(--hour-row-height) / 18));
  border-left: 1px solid var(--line);
  height: var(--hour-row-height);
  position: relative;
}
.week-session-block {
  border-radius: var(--radius-xs);
  font-size: .62rem;
  left: 2px;
  overflow: hidden;
  padding: .15rem .3rem;
  position: absolute;
  right: 2px;
  text-decoration: none;
}
.week-session-block .month-session-chip-title { display: block; }
.week-session-block.month-session-chip-projected {
  align-items: center;
  display: flex;
  gap: .2rem;
  justify-content: center;
}

/* Forgejo #83 (D4): year view. Each mini-month is one big <a> (no
   individual session click targets at this zoom level, per the project
   owner's own instruction) -- day cells are plain <span>s, never nested
   interactive elements. No visual browser pass was available in this
   environment -- see CLAUDE.md's own #83 entry. */
.year-grid { display: grid; gap: 1rem; grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr)); }
.year-mini-month {
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  color: inherit;
  display: block;
  padding: .75rem;
  text-decoration: none;
}
.year-mini-month:hover { background: var(--surface); }
.year-mini-month h2 { font-size: .85rem; margin: 0 0 .4rem; }
.year-mini-month-weekday-header {
  color: var(--muted);
  display: grid;
  font-size: .55rem;
  grid-template-columns: repeat(7, 1fr);
  text-align: center;
  text-transform: uppercase;
}
.year-mini-month-blocks { display: grid; gap: 1px; grid-template-columns: repeat(7, 1fr); height: 2px; margin-top: 1px; }
.year-mini-month-block-underline { background: var(--accent); border-radius: 1px; }
.year-mini-month-week { display: grid; grid-template-columns: repeat(7, 1fr); }
.year-mini-month-day {
  align-items: center;
  display: flex;
  flex-direction: column;
  font-size: .6rem;
  gap: 1px;
  padding: .1rem 0;
}
.year-mini-month-day.is-outside-month { visibility: hidden; }
.year-mini-month-day.is-today { color: var(--primary-dark); font-weight: 700; }
.year-mini-month-dot { border-radius: 50%; height: 4px; width: 4px; }
.year-mini-month-dot.is-session { background: var(--primary); }
.year-mini-month-dot.is-projected { background: var(--line); }

/* Forgejo #84 (D5): view switcher + prev/next/today -- plain links only,
   no client-side router. */
.season-calendar-nav { align-items: center; display: flex; flex-wrap: wrap; gap: .75rem; justify-content: space-between; margin-bottom: 1.5rem; }
.season-calendar-view-switch, .season-calendar-date-nav { display: flex; gap: .4rem; }
.season-calendar-view-switch a.is-current { background: var(--primary); border-color: var(--primary); color: white; }


/* stage_controller#dockToolOptions moves this block into the tool grid, right
   after the active tool's button, so it reads as that tool's own drawer. It is
   a grid item like the buttons around it. */
.palette-tools .editor-toolbar-options {
  background: var(--surface);
  border-left: 2px solid var(--primary);
  border-radius: 0 var(--radius-md) var(--radius-md) 0;
  display: flex;
  flex-direction: column;
  gap: .5rem;
  margin: .1rem 0 .35rem;
  padding: .5rem .55rem;
}
.palette-tools .editor-toolbar-options > .editor-toolbar-label { margin-bottom: 0; }
.palette-tools .editor-option-group { display: flex; flex-direction: column; gap: .5rem; }

/* ---------------------------------------------------------------------------
   Shared filter bar + data list (2026-09-14)

   One component for every "All" listing -- Spieler, sessions, and the drill
   library's own panel reuse these classes so the three read as one thing
   rather than three separately-invented bars.

   Chips are real <input type=checkbox> styled through :has() rather than a
   hand-rolled toggle: the native control keeps keyboard and screen-reader
   behaviour for free, and ApplicationController's `allow_browser versions:
   :modern` already requires :has support, so there is no fallback to carry.
   --------------------------------------------------------------------------- */
/* .filter-bar itself is gone: every listing now renders its groups inside
   shared/_search_filters' collapsible menu (.library-filter-body) rather
   than a standalone bar. The group/label/chip parts below are still the
   shared vocabulary those menus are built from. */
.filter-bar-group { border: 0; display: flex; flex-direction: column; gap: .35rem; margin: 0; min-width: 0; padding: 0; }
.filter-bar-label {
  color: var(--muted);
  display: block;
  font-size: .68rem;
  font-weight: 800;
  letter-spacing: .07em;
  padding: 0;
  text-transform: uppercase;
}
.filter-bar-options { display: flex; flex-wrap: wrap; gap: .3rem; }
.filter-bar-actions { align-items: center; display: flex; gap: .6rem; justify-content: flex-end; }
.filter-bar-summary { color: var(--muted); font-size: .8rem; margin: -.4rem 0 .75rem; }

.filter-chip {
  align-items: center;
  background: var(--bg);
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  color: var(--muted);
  cursor: pointer;
  display: inline-flex;
  font-size: .78rem;
  font-weight: 600;
  gap: .35rem;
  line-height: 1;
  min-height: 32px;
  padding: 0 .7rem;
  position: relative;
  /* Named properties, never `all`: only these three ever change. */
  transition: background-color 140ms var(--ease-out), border-color 140ms var(--ease-out), color 140ms var(--ease-out);
  user-select: none;
}
/* The native checkbox stays in the DOM and focusable, just not painted -- the
   chip itself is the visual control. */
.filter-chip input { height: 100%; inset: 0; margin: 0; opacity: 0; position: absolute; width: 100%; }
.filter-chip:has(input:checked) {
  background: var(--primary);
  border-color: var(--primary);
  color: var(--bg);
}
.filter-chip:has(input:focus-visible) { outline: 3px solid var(--focus-ring); outline-offset: 2px; }
.filter-chip:active { transform: scale(.97); }
@media (hover: hover) and (pointer: fine) {
  .filter-chip:hover { border-color: var(--primary); color: var(--ink); }
  .filter-chip:has(input:checked):hover { background: var(--primary-dark); color: var(--bg); }
}

/* A dense row list in the same language as .session-row, for listings whose
   rows carry editable fields rather than a single whole-row link. */
.data-list { display: flex; flex-direction: column; gap: .4rem; }
.data-row {
  align-items: end;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--radius-xl);
  display: flex;
  flex-wrap: wrap;
  gap: .5rem .9rem;
  padding: .65rem .85rem;
  transition: border-color 140ms var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .data-row:hover { border-color: var(--surface-strong); }
}
.data-row-main { flex: 1 1 11rem; min-width: 0; }
.data-row-title { font-size: .94rem; font-weight: 700; margin: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.data-row-meta { color: var(--muted); font-size: .75rem; margin: .1rem 0 0; }
.data-row-field { display: flex; flex: 0 1 9rem; flex-direction: column; gap: .2rem; min-width: 0; }
.data-row-field-wide { flex: 1 1 14rem; }
.data-row-field .form-label { font-size: .66rem; letter-spacing: .05em; }
.data-row-actions { align-items: center; display: flex; flex: 0 0 auto; gap: .5rem; margin-left: auto; }

/* Row-level save feedback. It replaces a submit button, so it has to be
   legible on its own: a colour plus real text, never colour alone. Opacity
   only -- no movement, which is also what keeps it safe under reduced
   motion. */
.inline-save-status {
  color: var(--muted);
  font-size: .72rem;
  font-weight: 700;
  min-width: 5.5rem;
  opacity: 0;
  text-align: right;
  transition: opacity 180ms var(--ease-out);
  white-space: nowrap;
}
.inline-save-status[data-state] { opacity: 1; }
.inline-save-status[data-state="saved"] { color: var(--success-bright); }
.inline-save-status[data-state="error"] { color: var(--danger); }

@media (prefers-reduced-motion: reduce) {
  .filter-chip, .data-row, .inline-save-status { transition-duration: 1ms; }
  .filter-chip:active { transform: none; }
}

/* Roster chip badges: Spielstärke and Erwachsen/Junior, so a coach can see
   what auto-assign was balancing. currentColor keeps them legible on all
   three chip backgrounds (light/dark/unassigned) without a per-zone rule. */
.roster-chip-tags { display: flex; flex: 0 0 auto; gap: .2rem; }
.roster-chip-tag {
  border: 1px solid currentColor;
  border-radius: var(--radius-xs);
  font-size: .62rem;
  font-weight: 800;
  letter-spacing: .02em;
  line-height: 1;
  opacity: .7;
  padding: .15rem .25rem;
}

/* Club-wide paste import (Spieler). The preview is the whole point of this
   flow -- it has to make "wird hinzugefügt" vs "schon im Club" readable at a
   glance, so each state pairs a colour with real words, never colour alone. */
.player-import { margin-bottom: 1rem; }
.player-import-form { display: flex; flex-direction: column; gap: .6rem; }
.import-preview { margin: .75rem 0; }
.import-preview-summary { font-size: .86rem; margin: 0 0 .5rem; }
.import-preview-list { display: flex; flex-direction: column; gap: .25rem; list-style: none; margin: 0; max-height: 18rem; overflow-y: auto; padding: 0; }
.import-preview-item {
  align-items: center;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  display: flex;
  font-size: .82rem;
  gap: .75rem;
  justify-content: space-between;
  padding: .35rem .55rem;
}
.import-preview-name { font-weight: 650; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.import-preview-state { align-items: center; display: flex; flex: 0 0 auto; font-size: .74rem; font-weight: 700; gap: .25rem; }
.import-preview-state svg { display: block; }
.import-preview-new .import-preview-state { color: var(--success-bright); }
.import-preview-new { border-color: oklch(0.82 0.09 155); }
.import-preview-existing .import-preview-state,
.import-preview-duplicate .import-preview-state { color: var(--muted); }
.import-preview-existing .import-preview-name,
.import-preview-duplicate .import-preview-name { color: var(--muted); text-decoration: line-through; }

/* Rink Layouts library rows. The preview is the reason this page exists as a
   list rather than a set of links, so it gets real space -- but it stays a
   fixed box and lets the SVG letterbox inside it, which is fine here in a way
   it is NOT in the editor: nothing maps a click back to rink coordinates on
   this page, so dead strips are inert rather than a trap. */
.rink-layout-row { align-items: center; }
.rink-layout-preview {
  align-items: center;
  background: var(--ice-surface-alt);
  border-radius: var(--radius-md);
  box-shadow: inset 0 0 0 1px oklch(0.88 0.02 205);
  display: flex;
  flex: 0 0 auto;
  height: 4.5rem;
  justify-content: center;
  overflow: hidden;
  width: 9rem;
}
.rink-layout-preview svg { display: block; height: 100%; width: 100%; }
.rink-layout-preview-empty { color: var(--muted); font-size: .74rem; font-weight: 700; }
.rink-layout-row .data-row-title a { color: inherit; text-decoration: none; }
.rink-layout-row .data-row-title a:hover { text-decoration: underline; }
.rink-layout-row .data-row-meta { align-items: center; display: flex; flex-wrap: wrap; gap: .35rem; }
.rink-layout-notes { color: var(--muted); font-size: .76rem; }

@media (max-width: 640px) {
  .rink-layout-preview { height: 3.5rem; width: 7rem; }
}
