:root {
  --ink: #111820;
  --ink-2: #1a242e;
  --panel: #eef1f2;
  --paper: #f8f9f9;
  --line: #d6dadd;
  --muted: #69747d;
  --white: #ffffff;
  --signal: #ff665c;
  --signal-dark: #d94c45;
  --blue: #59c7f5;
  --shadow: 0 18px 48px rgba(6, 13, 20, .24);
  /* Brand accent: sky blue (Aug 18 2026 — replaced an earlier red-accent pass per
     direct feedback), the single interactive/selected/primary-action colour (see the
     override block near the end of this file). --signal/--signal-dark stay red on
     purpose: those drive the recording/live indicators (REC dot, the pulsing "CLIP"
     capture border, Start analysis clip) — that's a "this is recording" signal, a
     different concern from brand colour, and every video editor keeps it red
     regardless of theme. The shot-map's own on-target blue is a third, separate
     concern (data-viz legend) and is intentionally a different shade from this one. */
  --signal-chrome: #3fa9f0;
  --signal-chrome-dark: #2680b8;
  --signal-light: #8ed4ff;
  --font-display: "Bebas Neue", "Arial Narrow", "Segoe UI", sans-serif;
  --font-athletic: "Barlow Condensed", "Arial Narrow", "Segoe UI", sans-serif;
  --font-body: "DM Sans", "Segoe UI", Arial, sans-serif;
  --font-mono: Consolas, ui-monospace, "SF Mono", monospace;

  /* ---- Semantic control-desk palette (visual refresh, Sep 2026) --------------
     A committed single dark identity — this is a video workstation, the footage
     is the ground. Surfaces run deepest→raised; blue is interaction, coral is
     record/destructive, white is the strongest output, yellow lives on the
     canvas. The old --signal* / --blue names below alias onto this set so every
     existing rule inherits it without a call-site sweep. */
  --chrome:          #0b0e12;   /* header, workspace ground */
  --canvas-surround: #050607;   /* around the video only — pure, so footage advances */
  --panel:           #121820;   /* raised regions: rail, inspector, dock */
  --control:         #19222c;   /* buttons, inputs, list rows */
  --control-hover:   #202c37;
  --border:          #29343e;
  --border-strong:   #3a4854;
  --text:            #f2f5f7;
  --text-secondary:  #b1bac2;
  --text-muted:      #8d9aa5;
  --interaction:       #42a9eb;
  --interaction-hover: #68bdf1;
  --record:            #ff615b;
  --record-hover:      #ff7772;
  --annotation-yellow: #ffd34d;
  --radius: 4px;
  --t: 140ms;
}

@font-face {
  font-family: "Bebas Neue";
  src: url("../fonts/BebasNeue-Regular.ttf") format("truetype");
  font-weight: 400;
  font-display: swap;
}
@font-face {
  font-family: "DM Sans";
  src: url("../fonts/DMSans-Regular.ttf") format("truetype");
  font-weight: 400;
  font-display: swap;
}
@font-face {
  font-family: "DM Sans";
  src: url("../fonts/DMSans-Medium.ttf") format("truetype");
  font-weight: 500;
  font-display: swap;
}
@font-face {
  font-family: "DM Sans";
  src: url("../fonts/DMSans-Bold.ttf") format("truetype");
  font-weight: 700;
  font-display: swap;
}
@font-face {
  font-family: "Barlow Condensed";
  src: url("../fonts/BarlowCondensed-Black.ttf") format("truetype");
  font-weight: 800;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Barlow Condensed";
  src: url("../fonts/BarlowCondensed-Black-Italic.ttf") format("truetype");
  font-weight: 800;
  font-style: italic;
  font-display: swap;
}

.locator-controls { margin-top: 16px; color: var(--text, #f2f5f7); font: 13px/1.45 "DM Sans", sans-serif; }
.locator-hint, .locator-palette p { color: #9daab5; font-size: 12px; margin: 0 0 12px; }
.locator-field { display: flex; flex-direction: column; gap: 6px; margin: 12px 0; }
.locator-field small { color: #9daab5; font-size: 11px; }
.locator-field select, .locator-field input { width: 100%; height: 38px; border: 1px solid #35434e; border-radius: 4px; padding: 0 10px; background: #111820; color: #f2f5f7; font: inherit; }
.locator-presets { display: grid; grid-template-columns: repeat(4, 1fr); gap: 5px; }
.locator-presets button { min-height: 40px; padding: 5px 2px; border: 1px solid #35434e; border-radius: 4px; color: #dbe3e9; background: #19222c; font: 500 12px "DM Sans", sans-serif; }
.locator-presets button::before { content: ''; display: block; width: 16px; height: 6px; border-radius: 50%; margin: 0 auto 5px; background: var(--preset-color); }
.locator-presets button[aria-pressed="true"] { border-color: #42a9eb; background: #233747; }
.locator-slider { display: grid; grid-template-columns: 55px minmax(50px, 1fr) 44px; align-items: center; gap: 8px; margin: 16px 0; }
.locator-slider input { width: 100%; accent-color: #42a9eb; }
.locator-slider output { text-align: right; font-variant-numeric: tabular-nums; font-size: 12px; }
.locator-palette { padding-top: 10px; border-top: 1px solid #29343e; }
.locator-palette summary { cursor: pointer; padding: 6px 0; }
.locator-palette > div { display: flex; gap: 18px; margin: 10px 0; }
.locator-palette label { display: flex; align-items: center; gap: 8px; }
.locator-palette input { width: 40px; height: 32px; border: 0; padding: 2px; background: #19222c; cursor: pointer; }
* { box-sizing: border-box; }
html, body { height: 100%; }
body { margin: 0; overflow: hidden; color: var(--ink); background: #cfd5d8; font-family: var(--font-body); }
button, input, textarea, select { font: inherit; }
button { cursor: pointer; }
button:focus-visible, input:focus-visible, textarea:focus-visible, select:focus-visible, summary:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }
[hidden], .legacy-hidden { display: none !important; }

.app-shell { height: 100%; display: flex; flex-direction: column; }
.topbar { height: 58px; flex: 0 0 58px; display: grid; grid-template-columns: 230px minmax(220px, 1fr) auto; align-items: center; gap: 24px; padding: 0 18px; color: white; background: var(--ink); border-bottom: 1px solid #2a3540; }
.brand { display: flex; align-items: center; gap: 11px; }
.brand-slash { width: 5px; height: 28px; display: block; background: var(--signal-chrome); transform: skew(-13deg); }
.brand div { display: flex; flex-direction: column; line-height: 1; }
.brand strong { font-family: "Arial Narrow", "Segoe UI", sans-serif; font-size: 15px; letter-spacing: .16em; }
.brand span:last-child { margin-top: 5px; color: #8997a2; font: 700 11px/1 Consolas, monospace; letter-spacing: .13em; }
.project-name { max-width: 390px; display: flex; align-items: center; gap: 10px; }
.project-name span { color: #788690; font: 700 11px/1 Consolas, monospace; letter-spacing: .12em; }
.project-name input { width: 100%; padding: 7px 2px; border: 0; border-bottom: 1px solid #394550; color: #dfe5e8; background: transparent; font-size: 12px; }
.header-actions { display: flex; align-items: center; gap: 6px; }
.header-actions button { height: 31px; border: 1px solid #34414c; border-radius: 3px; color: #c2cbd1; background: transparent; font-size: 10px; font-weight: 700; }
.header-actions button:hover { color: white; border-color: #5a6975; }
.header-actions .icon-button { width: 31px; padding: 0; font-size: 17px; }
.header-actions .quiet-button { padding: 0 11px; }
.header-actions .export-button { display: flex; align-items: center; gap: 9px; padding: 0 13px; color: var(--ink); border-color: white; background: white; }
/* UX review (Aug 18 2026): .header-actions button:hover's `color: white` beat this
   element's own ink-on-white by specificity, so the label went white-on-white on
   hover — invisible on the app's single most prominent CTA. */
.header-actions .export-button:hover { color: var(--ink); border-color: #d8dde0; background: #f2f4f5; }
/* Dimmed until there's a frame to export — see updateSourceUI(). */
.header-actions .export-button:disabled,
.header-actions .export-button:disabled:hover {
  color: #6b7681; border-color: #33404b; background: #1b232b; cursor: not-allowed;
}

.workspace { flex: 1; min-height: 0; display: grid; grid-template-columns: 104px minmax(600px, 1fr) 310px; background: #dce1e3; }
.tool-rail { min-height: 0; padding: 16px 10px 12px; color: #9da9b1; background: #161f28; border-right: 1px solid #2a3540; }
.rail-label { margin: 0 8px 11px; color: #8a98a2; font: 700 11px/1 Consolas, monospace; letter-spacing: .14em; }
.tool-list { display: grid; grid-template-columns: 1fr 1fr; gap: 5px; }
.tool { position: relative; min-height: 60px; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 5px; padding: 5px 2px; border: 1px solid transparent; border-radius: 4px; color: #87949e; background: transparent; font-size: 11px; font-weight: 700; }
.tool:hover { color: white; background: #202c37; }
.tool.active { color: white; border-color: #465460; background: #273440; box-shadow: inset 2px 0 var(--signal); }
.tool-icon { height: 22px; display: grid; place-items: center; }
/* One icon system. Each symbol carries its own fill/stroke (currentColor), so
   .ico only sizes and positions — forcing fill/stroke here would blank the
   solid glyphs (play triangle, spotlight dot). */
.ico { display: block; flex: none; width: 20px; height: 20px; color: inherit; }
.tool-icon .ico { width: 21px; height: 21px; }
.icon-button .ico { width: 17px; height: 17px; }
.play-button .ico { width: 15px; height: 15px; }
.export-button .ico { width: 15px; height: 15px; }
.tool .text-icon { font-weight: 700; }
.tool kbd { position: absolute; top: 4px; right: 5px; color: #596772; background: none; font: 700 11px/1 Consolas, monospace; }
.rail-tip { margin: 14px 6px 0; color: #62707a; font-size: 11px; line-height: 1.45; }

.stage-section { min-width: 0; min-height: 0; display: flex; flex-direction: column; background: #dce1e3; }
.stage-toolbar { height: 48px; flex: 0 0 48px; display: flex; align-items: center; justify-content: space-between; padding: 0 18px; background: #f3f5f5; border-bottom: 1px solid #cbd2d5; }
.source-switch { display: flex; align-items: center; gap: 7px; }
.source-switch button { height: 29px; border: 1px solid #bdc6ca; border-radius: 3px; color: #48545d; background: white; font-size: 11px; font-weight: 700; }
.source-switch .load-video-button { padding: 0 12px; color: white; border-color: var(--ink); background: var(--ink); }
.load-video-button span { margin-right: 5px; color: #ff958e; }
.source-switch .image-button { color: #77828a; background: transparent; }
.frame-status { display: flex; align-items: center; gap: 8px; color: #7a858d; font: 700 11px/1 Consolas, monospace; }
.frame-status strong { color: #333f48; }
.live-dot { width: 6px; height: 6px; border-radius: 50%; background: #9fa8ad; }
.video-mode .live-dot { background: var(--signal); box-shadow: 0 0 0 3px rgba(255,102,92,.12); }

.canvas-bay { flex: 1; min-height: 0; display: grid; place-items: center; padding: 14px 22px; background: #cfd5d8; }
.canvas-frame { position: relative; width: min(100%, calc((100vh - 162px) * 16 / 9)); aspect-ratio: 16 / 9; overflow: hidden; background: #0d141a; box-shadow: var(--shadow), 0 0 0 1px rgba(4, 10, 15, .55); }
.video-mode .canvas-frame { width: min(100%, calc((100vh - 260px) * 16 / 9)); }
canvas { position: relative; z-index: 2; width: 100%; height: 100%; display: block; touch-action: none; cursor: crosshair; }
canvas[data-tool="select"] { cursor: default; }
canvas.is-dragging { cursor: grabbing; }
.stage-section.is-playing canvas { pointer-events: none; cursor: default; }
#sourceVideo { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.empty-stage { position: absolute; inset: 0; z-index: 3; display: flex; flex-direction: column; align-items: center; justify-content: center; color: #7f8b93; background: radial-gradient(circle at 50% 44%, #1a252e, #0d141a 58%); pointer-events: none; }
.empty-stage[hidden] { display: none; }
.empty-stage-mark { width: 48px; height: 48px; display: grid; place-items: center; margin-bottom: 15px; padding-left: 3px; border: 1px solid #3a4853; border-radius: 50%; color: #e3e8ea; font-size: 17px; }
.empty-stage strong { color: #e1e6e8; font: 700 17px/1 "Arial Narrow", "Segoe UI", sans-serif; letter-spacing: .04em; }
.empty-stage p { margin: 8px 0 0; font-size: 11px; }
.freeze-badge { position: absolute; z-index: 4; top: 14px; left: 14px; display: flex; align-items: center; gap: 8px; padding: 7px 9px; color: white; background: rgba(12,19,25,.88); border-left: 3px solid var(--signal); pointer-events: none; }
.freeze-badge span, .freeze-badge strong { font: 700 11px/1 Consolas, monospace; letter-spacing: .1em; }

/* Stays visible over the video no matter which inspector tab is open — the sidebar
   hint alone disappears the moment you're not on Annotate, which is exactly the
   confusion this exists to fix. */
/* Bottom-center, not top-right — top-right is already the pause/CLIP indicator's
   corner (body.analysis-active.analysis-paused .canvas-frame::after), and the two
   were overlapping there. */
.formation-badge { position: absolute; z-index: 4; left: 50%; bottom: 14px; transform: translateX(-50%); display: flex; align-items: center; gap: 8px; padding: 7px 9px; color: white; background: rgba(12,19,25,.88); border-left: 3px solid var(--signal); }
.formation-badge span { font: 700 11px/1 Consolas, monospace; letter-spacing: .1em; }
.formation-badge button { display: flex; align-items: center; gap: 5px; padding: 4px 8px; color: #dfe6ea; border: 1px solid #3d4b56; border-radius: 3px; background: #232f39; font: 700 11px/1 Consolas, monospace; letter-spacing: .06em; }
.formation-badge button:hover { border-color: var(--signal-chrome); }
.formation-badge kbd { padding: 1px 5px; color: #9aa7ae; background: #16202a; border-radius: 2px; font: 700 11px/1 Consolas, monospace; }

/* UX review (Aug 18 2026): this never got migrated when the base chrome moved to
   the true-black system — it sat on the old blue-tinted var(--ink) while the
   toolbar above the video (.stage-toolbar) and everything else moved to #101214.
   The strip holding Start-analysis/Play/Finish, i.e. the controls used constantly,
   was the one visibly still on the old palette. */
.video-dock { flex: 0 0 104px; padding: 8px 14px 7px; color: white; background: #101214; border-top: 1px solid #27333d; }
.analysis-strip { display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: 16px; overflow-x: auto; }
.analysis-main-actions { display: flex; align-items: center; gap: 6px; flex-shrink: 0; }
/* .analysis-strip already scrolls (overflow-x: auto) when this row doesn't fit — but
   without nowrap, flex items shrink and wrap their text first, so "Start analysis
   clip" was breaking across 2-3 lines inside a fixed-height button instead of the
   row ever reaching that scroll. flex-shrink: 0 keeps each button at its natural
   width so the row's real width is what decides whether it scrolls. */
.analysis-main-actions button { height: 34px; border-radius: 3px; font-size: 11px; font-weight: 800; white-space: nowrap; flex-shrink: 0; }
.start-analysis { display: flex; align-items: center; gap: 7px; padding: 0 13px; color: white; border: 1px solid var(--signal-dark); background: var(--signal); }
.start-analysis:disabled { opacity: .42; cursor: default; }
.record-dot { width: 7px; height: 7px; border: 1px solid white; border-radius: 50%; background: white; }
.analysis-active .start-analysis { color: #93a0a9; border-color: #36434e; background: #1c2731; }
/* White is reserved for Export. Play is the obvious playback control, not an
   output action — a raised dark surface with the interaction-blue glyph. */
.play-button { width: 38px; padding: 0; color: var(--interaction); border: 1px solid var(--border-strong); background: var(--control); font-size: 13px !important; }
/* UX review (Aug 18 2026): probably the single most-clicked control in the app,
   and it had zero hover feedback while every other button cluster does. */
.play-button:hover { color: var(--interaction-hover); background: var(--control-hover); border-color: var(--interaction); }
.finish-analysis { padding: 0 12px; color: #eef2f4; border: 1px solid #56636d; background: transparent; }
.finish-analysis:not(:disabled):hover { color: var(--ink); background: white; }
.finish-analysis:disabled { opacity: .35; cursor: default; }
.analysis-state { min-width: 150px; display: flex; flex-direction: column; gap: 3px; }
.analysis-state strong { color: #e5eaed; font-size: 10px; }
.analysis-state span { color: #71808b; font-size: 11px; }
.analysis-paused .analysis-state strong { color: #ffd8d5; }
/* tabular-nums is belt-and-braces on top of the monospace stack: if Consolas is
   ever missing and this falls back to a proportional face, fixed-width digits
   still stop the readout's width changing as the numbers tick over. */
.timecode { display: flex; align-items: baseline; gap: 5px; color: #8a98a2; font: 700 11px/1 Consolas, monospace; font-variant-numeric: tabular-nums; }
.timecode strong { color: white; font-size: 13px; }
.timeline-row { height: 46px; display: grid; grid-template-columns: 72px 1fr; align-items: center; gap: 12px; }
.frame-steps { display: flex; gap: 4px; }
.frame-steps button { width: 34px; height: 25px; border: 1px solid #34424d; border-radius: 3px; color: #83919b; background: #1a252f; font: 700 11px/1 Consolas, monospace; }

/* Retroactive clip marking — for the "I've already seen it, now mark it" case
   that Start/Finish analysis clip doesn't cover (that flow only ever marks the
   START at the moment you press it, then plays forward — no way to go back and
   bracket something you spotted a moment ago). Set out works before Set in, in
   either order; Export clip in the header renders whatever window this leaves. */
.clip-controls { display: flex; gap: 4px; flex-shrink: 0; }
.clip-controls button { padding: 0 10px; height: 25px; border: 1px solid #34424d; border-radius: 3px; color: #83919b; background: #1a252f; font: 700 11px/1 Consolas, monospace; white-space: nowrap; }
.clip-controls button:hover { color: white; border-color: var(--signal-chrome, #59c7f5); }
#clearClipBtn { color: #6b7680; }
/* The two clip-marking flows would fight over state.clipStart/clipEnd if both
   were live at once — Start/Finish analysis clip already owns that window
   while a clip is being recorded, so these step back rather than collide. */
body.analysis-active .clip-controls button { opacity: .35; pointer-events: none; }
.timeline-wrap { min-width: 0; }
.timeline-track { position: relative; height: 23px; display: flex; align-items: center; }
#videoScrubber { width: 100%; height: 3px; margin: 0; appearance: none; background: linear-gradient(to right, var(--signal) var(--progress, 0%), #3b4853 var(--progress, 0%)); cursor: pointer; }
#videoScrubber::-webkit-slider-thumb { width: 10px; height: 10px; appearance: none; border: 2px solid white; border-radius: 50%; background: var(--signal); }
.event-markers { position: absolute; inset: 0 5px; pointer-events: none; }
.timeline-event { position: absolute; top: 7px; width: 2px; height: 9px; padding: 0; border: 0; background: #f4d35e; pointer-events: auto; }
.timeline-event.touch-event-marker { background: var(--blue); }
.timeline-event.touch-event-marker.active { width: 4px; background: white; }
.timeline-event.freeze-event-marker { top: 15px; width: 6px; height: 3px; background: var(--signal); }
.timeline-labels { display: flex; justify-content: space-between; margin-top: 2px; color: #8a98a2; font: 700 11px/1 Consolas, monospace; letter-spacing: .06em; }
.stage-footer { height: 26px; flex: 0 0 26px; display: flex; align-items: center; gap: 18px; padding: 0 18px; color: #7b878e; background: #f3f5f5; border-top: 1px solid #cbd2d5; font: 700 11px/1 Consolas, monospace; letter-spacing: .08em; }
.stage-footer span:last-child { margin-left: auto; }

.inspector { min-height: 0; overflow: auto; color: #26323a; background: var(--paper); border-left: 1px solid #c7ced1; }
.moment-panel { padding: 16px; border-bottom: 1px solid var(--line); }
.panel-heading { display: flex; align-items: flex-start; justify-content: space-between; }
.panel-heading span, .label-row, .comment-composer label, .style-row > span, .style-row > label, .selected-controls > label { color: #7a858d; font: 700 11px/1 Consolas, monospace; letter-spacing: .1em; }
.panel-heading h2 { margin: 6px 0 0; font-family: "Arial Narrow", "Segoe UI", sans-serif; font-size: 17px; font-stretch: condensed; }
.selection-badge { padding: 4px 6px; color: #717e87; background: #e7ebed; border-radius: 2px; font: 700 11px/1 Consolas, monospace; }
.pause-prompt { display: flex; gap: 10px; margin: 15px 0 13px; padding: 11px; color: #62707a; background: #e9edef; border-left: 3px solid #9aa6ad; }
.pause-prompt > span { color: #89959c; font-size: 10px; }
.pause-prompt p { margin: 0; font-size: 11px; line-height: 1.45; }
.pause-prompt strong { color: #34414a; }
.analysis-paused .pause-prompt { color: #6d4947; background: #fff0ef; border-left-color: var(--signal); }
.analysis-paused .pause-prompt > span { color: var(--signal); }
.comment-composer { margin-bottom: 14px; }
.comment-composer textarea { width: 100%; margin-top: 7px; padding: 9px; resize: vertical; border: 1px solid #cbd2d5; border-radius: 3px 3px 0 0; color: var(--ink); background: white; font-size: 10px; line-height: 1.4; }
.comment-composer button { width: 100%; height: 30px; margin-top: -1px; border: 1px solid var(--ink); border-radius: 0 0 3px 3px; color: white; background: var(--ink); font-size: 11px; font-weight: 800; }
.comment-composer button:disabled { opacity: .35; cursor: default; }
.style-controls { padding: 12px 0; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
.style-row { min-height: 30px; display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.swatches { display: flex; align-items: center; gap: 6px; }
.swatch, .custom-color { width: 21px; height: 21px; display: grid; place-items: center; padding: 0; border: 1px solid #b8c0c5; border-radius: 50%; background: var(--swatch); }
.swatch.active { box-shadow: 0 0 0 2px var(--paper), 0 0 0 3px #53616b; }
.custom-color { position: relative; color: #75818a; background: transparent; }
.custom-color input { position: absolute; width: 1px; height: 1px; opacity: 0; }
.width-row { margin-top: 8px; }
.width-row output { width: 31px; color: #5d6972; font: 700 11px/1 Consolas, monospace; text-align: right; }
.range { flex: 1; height: 3px; appearance: none; background: linear-gradient(to right, var(--ink) var(--fill, 33%), #d3d9dc var(--fill, 33%)); }
.range::-webkit-slider-thumb { width: 11px; height: 11px; appearance: none; border: 2px solid white; border-radius: 50%; background: var(--ink); box-shadow: 0 0 0 1px #64717a; }
.selected-controls { margin-top: 12px; }
.text-field { width: 100%; height: 31px; margin-top: 7px; padding: 0 8px; border: 1px solid #cbd2d5; border-radius: 3px; font-size: 11px; }
.selected-actions { display: flex; gap: 5px; margin-top: 6px; }
.selected-actions button { flex: 1; height: 28px; border: 1px solid #c3cbd0; border-radius: 3px; color: #53616a; background: white; font-size: 11px; font-weight: 700; }
.selected-actions .danger { color: #b94c47; }
.selected-actions button:disabled { opacity: .4; cursor: default; }
.hold-row { display: grid; grid-template-columns: 85px 1fr; gap: 6px; margin-top: 11px; }
.hold-row label { height: 29px; display: flex; align-items: center; gap: 4px; padding: 0 6px; border: 1px solid #cbd2d5; border-radius: 3px; color: #68757d; font-size: 11px; }
.hold-row input { width: 32px; border: 0; background: transparent; font: 700 11px/1 Consolas, monospace; }
.hold-row button { border: 1px solid #c3cbd0; border-radius: 3px; color: #4d5a63; background: white; font-size: 11px; font-weight: 700; }
.hold-row button:disabled { opacity: .4; cursor: default; }
.freeze-list { display: flex; flex-direction: column; gap: 4px; margin-top: 6px; }
.freeze-item { display: grid; grid-template-columns: 42px 1fr auto; align-items: center; gap: 6px; padding: 6px; color: #65727b; background: #edf0f1; font: 700 11px/1 Consolas, monospace; }
.freeze-item button { border: 0; color: #8b969d; background: transparent; }

.layer-section { padding: 13px 16px; border-bottom: 1px solid var(--line); }
.label-row { display: flex; align-items: center; justify-content: space-between; }
.layer-list { margin-top: 8px; display: flex; flex-direction: column; gap: 4px; }
.empty-layers { padding: 10px 0; color: #8a959c; font-size: 11px; line-height: 1.4; }
.empty-layers p { margin: 0; }
.layer-item { width: 100%; min-height: 31px; display: grid; grid-template-columns: 8px 1fr auto; align-items: center; gap: 8px; padding: 0 8px; border: 1px solid #d4dade; border-radius: 3px; color: #5a6670; background: white; text-align: left; font-size: 11px; }
.layer-item.active { color: var(--ink); border-color: #8f9ba3; }
.layer-color { width: 7px; height: 7px; border-radius: 50%; background: var(--layer-color); box-shadow: 0 0 0 1px #aab3b9; }
.layer-index { color: #9ba4aa; font: 700 11px/1 Consolas, monospace; }

.drawer { border-bottom: 1px solid var(--line); }
.drawer summary { display: flex; align-items: center; justify-content: space-between; padding: 13px 16px; list-style: none; cursor: pointer; }
.drawer summary::-webkit-details-marker { display: none; }
.drawer summary span { color: #34414a; font-size: 10px; font-weight: 700; }
.drawer summary small { color: #8b959c; font-size: 11px; }
.drawer[open] summary { background: #eef1f2; }
.drawer-body { padding: 12px 16px 16px; background: #f3f5f5; }
.data-import-button, .wide-control, .article-pack-button { width: 100%; min-height: 32px; display: flex; align-items: center; justify-content: space-between; padding: 0 10px; border: 1px solid #c5cdd1; border-radius: 3px; color: #39464f; background: white; font-size: 11px; font-weight: 700; }
.data-import-row { display: flex; gap: 6px; align-items: stretch; }
.data-import-row .data-import-button { flex: 1; }
.clear-data-button { flex-shrink: 0; min-height: 32px; padding: 0 11px; border: 1px solid #c5cdd1; border-radius: 3px; color: #8a5a52; background: white; font-size: 11px; font-weight: 700; }
.data-status, .batch-status, .sync-copy { margin: 8px 0; color: #7c878e; font-size: 11px; line-height: 1.45; }
.review-workspace { margin-top: 11px; }
.review-selects { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }
.review-selects label, .event-filter-label, .article-options label { display: flex; flex-direction: column; gap: 4px; color: #7a858d; font: 700 11px/1 Consolas, monospace; }
select, .review-window input { min-width: 0; height: 28px; padding: 0 6px; border: 1px solid #c7cfd3; border-radius: 3px; color: #34414a; background: white; font-size: 11px; }
.event-filter-label { margin-top: 7px; }
.touch-summary { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; margin-top: 7px; }
.touch-summary div { padding: 8px; background: white; border: 1px solid #d2d8db; }
.touch-summary strong, .touch-summary span { display: block; }
.touch-summary strong { font: 700 14px/1 "Arial Narrow", sans-serif; }
.touch-summary span { margin-top: 4px; color: #89939a; font: 700 11px/1 Consolas, monospace; }
.review-window { margin-top: 7px; display: grid; grid-template-columns: 1fr 1fr; gap: 5px; }
.review-window > span { grid-column: 1/-1; color: #7b868d; font: 700 11px/1 Consolas, monospace; }
.review-window label { display: flex; align-items: center; gap: 4px; color: #6d7981; font-size: 11px; }
.review-window input { width: 38px; }
.review-controls, .decision-controls, .article-actions { display: grid; grid-template-columns: repeat(3, 1fr); gap: 5px; margin-top: 7px; }
.review-controls button, .decision-controls button, .article-actions button { min-height: 29px; border: 1px solid #c4ccd0; border-radius: 3px; color: #56636c; background: white; font-size: 11px; font-weight: 700; }
.review-controls .review-play { color: white; border-color: var(--ink); background: var(--ink); }
.article-queue { margin-top: 10px; padding-top: 10px; border-top: 1px solid #d2d8db; }
.article-queue-head { display: flex; justify-content: space-between; color: #76828a; font: 700 11px/1 Consolas, monospace; }
.article-queue textarea, #eventInput, #matchdayFeedback { width: 100%; margin-top: 7px; padding: 7px; resize: vertical; border: 1px solid #c7cfd3; border-radius: 3px; font-size: 11px; }
.article-options { display: grid; grid-template-columns: 1fr 1fr; gap: 7px; margin-top: 7px; }
.poster-option { justify-content: end; }
.article-actions { grid-template-columns: 1fr 1fr; }
.article-pack-button { margin-top: 6px; justify-content: center; color: white; border-color: var(--ink); background: var(--ink); }
.touch-list, .sync-events { max-height: 180px; overflow: auto; margin-top: 8px; display: flex; flex-direction: column; gap: 3px; }
.touch-item, .sync-event { width: 100%; display: grid; grid-template-columns: 42px 1fr auto; align-items: center; gap: 6px; padding: 6px; border: 1px solid #d2d8db; color: #5e6b73; background: white; text-align: left; font-size: 11px; }
.touch-item.active { border-color: #77848d; }
.kickoff-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }
.kickoff-grid button { padding: 8px; border: 1px solid #c8d0d4; border-radius: 3px; color: #5d6972; background: white; }
.kickoff-grid span, .kickoff-grid strong { display: block; font: 700 11px/1 Consolas, monospace; }
.kickoff-grid strong { margin-top: 5px; color: var(--ink); }
.toast { position: fixed; z-index: 20; left: 50%; bottom: 18px; padding: 9px 13px; color: white; background: rgba(12,19,25,.94); border-left: 3px solid var(--signal); box-shadow: 0 8px 25px rgba(0,0,0,.28); opacity: 0; transform: translate(-50%, 10px); transition: .18s ease; pointer-events: none; font-size: 11px; }
.toast.show { opacity: 1; transform: translate(-50%, 0); }

/* ===========================================================================
   Control-desk skin. Everything from here down is the live (dark) interface.
   The aliases point the historical token names at the semantic palette so the
   rules below — and the hundreds of call sites — resolve to one system. */
:root {
  --ink:   var(--chrome);
  --ink-2: #141c25;
  --paper: var(--panel);
  --line:  var(--border);
  --muted: var(--text-muted);
  --white: #ffffff;
  --signal:             var(--record);
  --signal-dark:        #d64a44;
  --signal-chrome:      var(--interaction);
  --signal-chrome-dark: #2f86c0;
  --signal-light:       var(--interaction-hover);
  --blue:               var(--interaction);
  --shadow: 0 16px 42px rgba(0, 0, 0, .5);
}

/* Focused video-editor skin: quiet chrome, one task per view. */
.topbar { height: 54px; flex-basis: 54px; background: var(--chrome); border-color: var(--border); }
.workspace { grid-template-columns: 76px minmax(600px, 1fr) 288px; background: var(--chrome); }
.tool-rail { padding: 14px 8px; background: var(--chrome); border-color: var(--border); }
.rail-label { margin: 0 0 10px; text-align: center; font-size: 11px; }
.tool-list { grid-template-columns: 1fr; gap: 4px; }
.tool { min-height: 52px; gap: 4px; border-radius: 5px; }
.tool:hover { background: #17222c; }
.tool.active { border-color: #354553; background: #1a2631; box-shadow: inset 3px 0 var(--interaction-hover); }
.tool kbd { color: #50606d; }
/* UX review (Aug 18 2026): this was blanket-hiding every .rail-tip, not just the
   tool rail's — it also silently killed the Season tab's only explanation of what
   folder structure it expects (index.html's Season panel reuses the same class).
   Scoped to just the icon-only tool rail, where dropping the hint for space was
   presumably the original intent. */
.tool-rail .rail-tip { display: none; }

.stage-section { background: var(--chrome); }
.stage-toolbar { height: 44px; flex-basis: 44px; padding: 0 15px; background: var(--panel); border-color: var(--border); }
.source-switch .load-video-button { color: #e9eff2; border-color: #3a4955; background: #1b2731; }
.source-switch .load-video-button:hover { border-color: var(--interaction-hover); }
.frame-status { color: var(--text-muted); }
.frame-status strong { color: #aeb9c0; }
.canvas-bay { padding: 10px 15px; background: #050506; }
.canvas-frame { box-shadow: 0 16px 45px rgba(0,0,0,.52), 0 0 0 1px #26323b; }
.video-mode .canvas-frame { width: min(100%, calc((100vh - 238px) * 16 / 9)); }
.empty-stage { background: radial-gradient(circle at 50% 44%, var(--control), var(--chrome) 62%); }
.empty-stage-mark { border-color: var(--border-strong); }
.stage-footer { color: var(--text-muted); background: var(--chrome); border-color: var(--border); }

.inspector { color: var(--text); background: var(--panel); border-color: var(--border); }
.inspector-top { position: sticky; top: 0; z-index: 6; display: grid; grid-template-columns: minmax(0, 1fr) 74px; min-height: 44px; padding: 6px; gap: 5px; background: var(--chrome); border-bottom: 1px solid var(--border); }
.inspector-tabs { display: grid; grid-template-columns: 1fr 1fr; min-width: 0; }
.inspector-tabs button { position: relative; border: 0; border-radius: 4px; color: var(--text-muted); background: transparent; font-size: 11px; font-weight: 750; }
.inspector-tabs button:hover { color: var(--text-secondary); }
.inspector-tabs button.active { color: var(--text); background: #19242e; }
.inspector-tabs button.active::after { content: ""; position: absolute; left: 30%; right: 30%; bottom: -6px; height: 2px; background: var(--interaction-hover); }
.popout-controls { display: grid; grid-template-columns: auto 1fr; align-items: center; gap: 5px; padding: 0 7px; border: 1px solid #35444f; border-radius: 4px; color: var(--interaction-hover); background: var(--control); font-size: 12px; cursor: pointer; }
.popout-controls:hover { color: #eef7ff; border-color: var(--interaction-hover); background: #1b2a35; }
.popout-controls strong { overflow: hidden; font-size: 11px; font-weight: 750; text-overflow: ellipsis; white-space: nowrap; }
.inspector-view[hidden] { display: none; }
.moment-panel, .layer-section { border-color: var(--border); }
.moment-panel { padding: 15px; }
.panel-heading span, .label-row, .comment-composer label, .style-row > span, .style-row > label, .selected-controls > label { color: #71808b; }
.panel-heading h2 { color: #f0f4f6; font-weight: 650; }
.selection-badge { color: #8ca0ae; background: #1b2731; }
.pause-prompt { color: #91a0aa; background: #17222b; border-left-color: #435562; }
.pause-prompt strong { color: var(--text-secondary); }
.analysis-paused .pause-prompt { color: #ffc5c0; background: #291c1d; border-left-color: var(--signal); }
.analysis-paused .pause-prompt strong { color: #fff0ef; }
.comment-composer textarea, .text-field, .article-queue textarea, #eventInput, #matchdayFeedback { color: var(--text); border-color: var(--border-strong); background: var(--chrome); }
.comment-composer textarea::placeholder, .text-field::placeholder, .article-queue textarea::placeholder, #eventInput::placeholder { color: #586873; }
.comment-composer button { color: #071018; border-color: var(--interaction-hover); background: var(--interaction-hover); }
.style-controls { border-color: var(--border); }
.swatch, .custom-color { border-color: #53616b; }
.swatch.active { box-shadow: 0 0 0 2px var(--panel), 0 0 0 3px var(--text-muted); }
/* UX review (Aug 18 2026): the colour chips were the one control cluster in the
   Annotate panel with no hover feedback at all. Ring rather than a size change,
   so the row doesn't reflow on hover. */
.swatch:hover, .custom-color:hover { border-color: var(--text-secondary); box-shadow: 0 0 0 2px var(--panel), 0 0 0 3px var(--signal-chrome); }
.swatch.active:hover { box-shadow: 0 0 0 2px var(--panel), 0 0 0 3px var(--signal-chrome); }
.custom-color { display: none; }
.width-row output { color: #96a4ad; }
.range { background: linear-gradient(to right, #dfe8ed var(--fill, 33%), #34414b var(--fill, 33%)); }
.range::-webkit-slider-thumb { border-color: var(--panel); background: var(--text); box-shadow: 0 0 0 1px #82919b; }
.selected-actions button, .hold-row button { color: #9daab2; border-color: var(--border-strong); background: var(--control); }
.selected-actions .danger { color: #ff8981; }
.empty-layers { color: var(--text-muted); }
.layer-item { color: var(--text-muted); border-color: #2f3b45; background: var(--control); }
.layer-item.active { color: #eef3f5; border-color: #607582; background: #1a2731; }
.layer-color { box-shadow: 0 0 0 1px #596872; }

.drawer { border-color: var(--border); }
.drawer summary { background: var(--panel); }
.drawer[open] summary { background: var(--control); }
.drawer summary span { color: var(--text-secondary); }
.drawer summary small { color: var(--text-muted); }
.drawer-body { background: var(--chrome); }
.event-guide { height: 28px; display: flex; align-items: center; justify-content: center; gap: 8px; margin-bottom: 9px; color: var(--text-muted); background: var(--panel); border: 1px solid var(--border); border-radius: 3px; font: 600 11px/1 var(--font-body); }
.event-guide i { color: #42535f; font-style: normal; }
.event-guide strong { color: var(--interaction-hover); }
.data-import-button, .wide-control, .article-pack-button { color: var(--text-secondary); border-color: #36434e; background: var(--control); }
.data-import-button:hover, .wide-control:hover { border-color: var(--interaction-hover); }
.clear-data-button { color: #e0a49b; border-color: #4a3430; background: var(--control); }
.clear-data-button:hover { color: #ffb3a8; border-color: #a85c50; }
.data-status, .batch-status, .sync-copy { color: var(--text-muted); }
.review-selects label, .event-filter-label, .article-options label { color: var(--text-muted); }
select, .review-window input { color: var(--text); border-color: var(--border-strong); background: var(--control); }
.touch-summary div { background: var(--control); border-color: #303c46; }
.touch-summary strong { color: #f0f4f6; }
.review-window > span, .review-window label { color: var(--text-muted); }
.review-controls button, .decision-controls button, .article-actions button { color: #a5b0b7; border-color: #35434d; background: var(--control); }
.review-controls .review-play, .article-pack-button { color: #071018; border-color: var(--interaction-hover); background: var(--interaction-hover); }
.review-controls { grid-template-columns: 66px 1fr 66px; }
.review-controls button { min-height: 34px; }
.review-controls .review-play { white-space: nowrap; }
.touch-list { max-height: 210px; margin: 8px 0 0; overflow: auto; display: flex; flex-direction: column; gap: 4px; }
.touch-row { width: 100%; min-height: 43px; display: grid; grid-template-columns: 43px 1fr 18px; align-items: center; gap: 7px; padding: 5px 7px; color: #8f9ca5; border: 1px solid #2d3943; border-radius: 3px; background: var(--control); text-align: left; }
.touch-row:hover { color: #dbe3e7; border-color: #455764; background: var(--control); }
.touch-row.active { color: #eef4f6; border-color: var(--interaction-hover); box-shadow: inset 2px 0 var(--interaction-hover); }
.touch-row time { color: var(--interaction-hover); font: 700 11px/1 Consolas, monospace; }
.touch-row strong, .touch-row small { display: block; }
.touch-row strong { font-size: 11px; }
.touch-row small { margin-top: 3px; overflow: hidden; color: var(--text-muted); font-size: 11px; text-overflow: ellipsis; white-space: nowrap; }
.touch-row > span { width: 7px; height: 7px; justify-self: center; border-radius: 50%; background: #71808a; }
.touch-row > span.bad { background: #ff766d; }
.touch-row .decision-mark { width: 16px; height: 16px; display: grid; place-items: center; color: #071018; background: var(--interaction-hover); border-radius: 2px; font: 800 11px/1 Consolas, monospace; }
.touch-row .decision-mark.reject { color: #ffd9d6; background: #4a2527; }
.touch-row.kept { border-left-color: var(--interaction-hover); }
.touch-row.rejected { opacity: .55; }
.touch-list-empty { padding: 12px 8px; color: #71808a; border: 1px dashed #33414c; border-radius: 3px; font-size: 11px; line-height: 1.45; }

/* EVENTS | POSSESSIONS toggle + possession filters ------------------------- */
.level-toggle { display: grid; grid-template-columns: 1fr 1fr; gap: 0; margin-top: 8px; border: 1px solid var(--border-strong); border-radius: 3px; overflow: hidden; }
.level-toggle button { padding: 6px 4px; color: var(--text-muted); border: 0; background: var(--control); font: 800 11px/1 var(--font-body); letter-spacing: .04em; text-transform: uppercase; cursor: pointer; }
.level-toggle button + button { border-left: 1px solid var(--border-strong); }
.level-toggle button:hover { color: var(--text-secondary); }
.level-toggle button.active { color: #071018; background: var(--interaction-hover); }
.possession-filters { display: none; margin-top: 7px; }
body.possession-level .possession-filters { display: block; }
body.possession-level .event-filter-label { display: none; }
.poss-filter-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }
.poss-filter-grid label { min-width: 0; display: flex; flex-direction: column; gap: 4px; color: var(--text-muted); font: 700 11px/1 Consolas, monospace; }
.poss-filter-grid select, .poss-filter-grid input { min-width: 0; width: 100%; }
.poss-advanced { margin-top: 7px; }
.poss-advanced .drawer-body { padding-top: 8px; }
.touch-row.possession { grid-template-columns: 62px 1fr 18px; align-items: start; }
.touch-row.possession time { line-height: 1.3; }
.poss-tags { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 4px; }
.poss-tags i { padding: 1px 5px; color: var(--interaction-hover); border: 1px solid var(--border-strong); border-radius: 2px; font: 700 10px/1.4 Consolas, monospace; font-style: normal; }
.clip-source.possession { color: var(--interaction-hover); }

/* Stats-tab drawers (passing network, pitch zones) ----------------------- */
.stats-drawer { margin-top: 8px; }
.stats-drawer > summary small { color: var(--interaction-hover); font: 700 11px/1 Consolas, monospace; }
.stats-drawer .drawer-body { padding-top: 10px; }

/* Type-in-place text ------------------------------------------------------ */
/* Paints nothing — the canvas draws the text and the caret. This only has to sit
   over the mark so it takes the keystrokes and mobile keyboards anchor sensibly. */
.canvas-text-input {
  position: absolute; z-index: 6; margin: 0; padding: 0; border: 0; outline: none;
  appearance: none; -webkit-appearance: none; box-shadow: none; border-radius: 0;
  background: transparent; color: transparent; caret-color: transparent;
  font-family: "Arial Narrow", "Segoe UI", sans-serif; font-weight: 700;
  -webkit-text-fill-color: transparent;
  /* Fully invisible, not merely transparent: the UA still painted the field's own
     edges over the footage. It stays focusable, so keystrokes and mobile keyboards
     are unaffected. */
  opacity: 0;
  /* A textarea, so a caption can be a title and two or three points. It never
     wraps on its own — line breaks are the analyst's, and the canvas draws them. */
  resize: none; overflow: hidden; white-space: pre;
}
.canvas-text-input::selection { background: rgba(66, 169, 235, .35); }
body.editing-text .canvas-frame { cursor: text; }

/* Pitch zones ------------------------------------------------------------- */
.zone-map-section { margin-top: 12px; }
.zone-filter-label { display: flex; flex-direction: column; gap: 4px; margin-bottom: 8px; color: var(--text-muted); font: 700 11px/1 Consolas, monospace; }
.zone-filter-label select { width: 100%; min-width: 0; }
.zone-map-grid { margin-top: 8px; display: grid; grid-template-columns: repeat(3, 1fr); grid-auto-rows: 1fr; gap: 2px; aspect-ratio: 3 / 2; border: 1px solid var(--border-strong); background: var(--border-strong); }
.zone-cell { position: relative; display: grid; place-items: center; color: var(--text-secondary); border: 0; background: var(--control); background-image: linear-gradient(rgba(66, 169, 235, calc(var(--heat, 0) * 0.55)), rgba(66, 169, 235, calc(var(--heat, 0) * 0.55))); cursor: pointer; }
.zone-cell:hover:not(:disabled) { outline: 2px solid var(--interaction-hover); outline-offset: -2px; color: #eef4f6; }
.zone-cell:disabled { color: var(--text-muted); cursor: default; }
.zone-cell b { font: 800 15px/1 Consolas, monospace; }

/* Team sheet as navigation ----------------------------------------------- */
.team-sheet { margin-top: 7px; }
.ts-body { display: flex; flex-direction: column; gap: 6px; padding-top: 8px; }
.ts-line { display: grid; grid-template-columns: 34px 1fr; align-items: start; gap: 7px; }
.ts-line > span { padding-top: 4px; color: var(--text-muted); font: 700 10px/1 Consolas, monospace; }
.ts-line > div { display: flex; flex-wrap: wrap; gap: 4px; }
.ts-chip { display: inline-flex; align-items: center; gap: 5px; padding: 3px 7px; color: var(--text-secondary); border: 1px solid #2d3943; border-radius: 3px; background: var(--control); font: 600 11px/1.2 var(--font-body); cursor: pointer; }
.ts-chip:hover { color: #eef4f6; border-color: #455764; }
.ts-chip i { color: var(--text-muted); font: 700 10px/1 Consolas, monospace; font-style: normal; }
.ts-chip.is-active { color: #071018; border-color: var(--interaction-hover); background: var(--interaction-hover); }
.ts-chip.is-active i { color: #071018; }
.ts-chip.is-empty { opacity: .45; }
.ts-subs > span { color: #6b7680; }

/* Natural-language filter assistant --------------------------------------- */
.nl-filter { display: grid; grid-template-columns: 1fr auto; gap: 5px; margin-bottom: 7px; }
.nl-filter input { min-width: 0; height: 30px; padding: 0 8px; color: var(--text); border: 1px solid var(--border-strong); border-radius: 3px; background: var(--control); font-size: 12px; }
.nl-filter input::placeholder { color: var(--text-muted); }
.nl-filter input:focus { outline: none; border-color: var(--interaction-hover); }
.nl-filter button { height: 30px; padding: 0 12px; color: #071018; border: 1px solid var(--interaction-hover); border-radius: 3px; background: var(--interaction-hover); font: 800 11px/1 var(--font-body); letter-spacing: .04em; text-transform: uppercase; cursor: pointer; }
.nl-filter-echo { margin: -2px 0 8px; padding: 6px 9px; color: var(--text-secondary); border: 1px solid var(--border-strong); border-left: 2px solid var(--interaction-hover); border-radius: 3px; background: var(--control); font-size: 11px; line-height: 1.4; }
.nl-filter-echo strong { color: #eef4f6; }
.nl-filter-echo em { color: var(--text-muted); font-style: normal; }

/* Drill-through banner (passing network -> events) --------------------------- */
.custom-filter-banner { width: 100%; margin-top: 7px; padding: 6px 9px; display: block; color: var(--interaction-hover); border: 1px solid var(--border-strong); border-radius: 3px; background: var(--control); font: 700 11px/1.3 var(--font-body); text-align: left; cursor: pointer; }
.custom-filter-banner:hover { border-color: var(--interaction-hover); background: var(--control-hover); }

/* Passing network ---------------------------------------------------------- */
.passnet-section { margin-top: 12px; }
.passnet-list { margin-top: 8px; display: flex; flex-direction: column; gap: 3px; }
.passnet-row { position: relative; width: 100%; display: grid; grid-template-columns: 1fr auto; align-items: center; gap: 8px; padding: 6px 9px; overflow: hidden; color: var(--text-secondary); border: 1px solid #2d3943; border-radius: 3px; background: var(--control); text-align: left; cursor: pointer; }
.passnet-row:hover { color: #eef4f6; border-color: #455764; }
.passnet-bar { position: absolute; inset: 0 auto 0 0; width: var(--w, 0%); background: rgba(66, 169, 235, .14); pointer-events: none; }
.passnet-names { position: relative; font: 600 12px/1 var(--font-body); }
.passnet-names i { color: var(--text-muted); font-style: normal; }
.passnet-row b { position: relative; color: var(--interaction-hover); font: 800 13px/1 Consolas, monospace; }
.article-queue { border-color: #2b3741; }
.article-queue-head { color: var(--text-muted); }
.touch-item, .sync-event { color: var(--text-muted); border-color: #303c46; background: var(--control); }
.touch-item.active { color: white; border-color: var(--interaction-hover); }
.kickoff-grid button { color: var(--text-muted); border-color: var(--border-strong); background: var(--control); }
.kickoff-grid strong { color: #eef3f5; }

@media (max-width: 1080px) {
  .workspace { grid-template-columns: 72px minmax(540px, 1fr) 270px; }
  .topbar { grid-template-columns: 190px 1fr auto; }
  .header-actions .quiet-button { display: none; }
}

@media (max-width: 820px) {
  body { overflow: auto; }
  .app-shell { min-height: 100%; height: auto; }
  .workspace { display: grid; grid-template-columns: 76px 1fr; }
  .inspector { grid-column: 1 / -1; overflow: visible; }
  .topbar { grid-template-columns: 1fr auto; }
  .project-name { display: none; }
  .canvas-frame, .video-mode .canvas-frame { width: 100%; }
}

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

/* Second-screen mode: the live inspector moves to a small companion window. */
body.controls-detached .workspace { grid-template-columns: 76px minmax(600px, 1fr); }
body.controls-detached .stage-section { grid-column: 2; }

body.panel-window { height: 100vh; overflow: hidden; color: var(--text); background: var(--chrome); }
.panel-window #panelMount { height: 100%; }
.panel-window .inspector { width: 100%; height: 100%; overflow: auto; border: 0; }
.panel-window .inspector-top { grid-template-columns: minmax(0, 1fr) 84px; }
.panel-window .popout-controls strong { font-size: 11px; }

@media (max-width: 820px) {
  body.controls-detached { overflow: hidden; }
  body.controls-detached .app-shell { height: 100%; min-height: 0; }
  body.controls-detached .workspace { grid-template-columns: 76px minmax(0, 1fr); }
}

/* Readable analyst controls: comfortable targets without turning the panel into a dashboard. */
.topbar { height: 60px; flex-basis: 60px; }
.header-actions button { height: 38px; padding: 0 13px; font-size: 11px; }
.source-switch button { height: 36px; padding: 0 13px; font-size: 11px; }
.analysis-main-actions button { height: 40px; font-size: 11px; }
.frame-steps button { width: 38px; height: 32px; font-size: 12px; }
.workspace { grid-template-columns: 80px minmax(560px, 1fr) 320px; }
.tool { min-height: 56px; font-size: 12px; }
.rail-label { font-size: 11px; }

.inspector-top { grid-template-columns: minmax(0, 1fr) 88px; min-height: 56px; padding: 7px; gap: 7px; }
.inspector-tabs button { min-height: 40px; font-size: 11px; }
.inspector-tabs button.active::after { bottom: -8px; }
.popout-controls { min-height: 40px; padding: 0 9px; font-size: 13px; }
.popout-controls strong, .panel-window .popout-controls strong { font-size: 12px; }

.moment-panel { padding: 18px; }
.panel-heading span, .label-row, .comment-composer label, .style-row > span, .style-row > label, .selected-controls > label { font-size: 11px; }
.pause-prompt p { font-size: 11px; }
.comment-composer textarea { min-height: 76px; font-size: 12px; }
.comment-composer button { height: 42px; font-size: 11px; }
.style-row { min-height: 38px; }
.swatches { gap: 8px; }
.swatch, .custom-color { width: 27px; height: 27px; }
.width-row output { font-size: 12px; }
.range::-webkit-slider-thumb { width: 16px; height: 16px; }
.text-field { height: 38px; padding: 0 10px; font-size: 11px; }
.selected-actions button { height: 38px; font-size: 12px; }
.empty-layers { font-size: 12px; }
.layer-item { min-height: 40px; font-size: 12px; }

.drawer summary { min-height: 54px; padding: 14px 16px; }
.drawer summary span { font-size: 12px; }
.drawer summary small { font-size: 11px; }
.drawer-body { padding: 14px 16px 18px; }
.event-guide { height: 36px; margin-bottom: 11px; font-size: 11px; }
.data-import-button, .wide-control, .article-pack-button, .clear-data-button { min-height: 42px; padding: 0 12px; font-size: 11px; }
.data-status, .batch-status, .sync-copy { margin: 10px 0; font-size: 12px; line-height: 1.5; }
.review-workspace { margin-top: 14px; }
.review-selects { gap: 8px; }
.review-selects label, .event-filter-label, .article-options label { gap: 6px; font-size: 11px; }
select, .review-window input { height: 38px; padding: 0 9px; font-size: 11px; }
.event-filter-label { margin-top: 10px; }
.touch-summary { gap: 8px; margin-top: 10px; }
.touch-summary div { padding: 11px; }
.touch-summary strong { font-size: 18px; }
.touch-summary span { font-size: 11px; }
.review-window { gap: 8px; margin-top: 10px; }
.review-window > span { font-size: 11px; }
.review-window label { font-size: 12px; }
.review-window input { width: 46px; }
.review-controls, .decision-controls, .article-actions { gap: 7px; margin-top: 10px; }
.review-controls { grid-template-columns: 78px 1fr 78px; }
.review-controls button, .decision-controls button, .article-actions button { min-height: 42px; padding: 0 8px; font-size: 12px; }
.article-queue { margin-top: 14px; padding-top: 14px; }
.article-queue-head { font-size: 11px; }
.article-queue textarea, #eventInput, #matchdayFeedback { min-height: 70px; padding: 10px; font-size: 11px; line-height: 1.45; }
.article-options { gap: 10px; margin-top: 10px; }
.article-pack-button { margin-top: 8px; }
.touch-list { max-height: 260px; }
.touch-row { min-height: 52px; padding: 7px 9px; }
.touch-row time { font-size: 12px; }
.touch-row strong { font-size: 12px; }
.touch-row small { font-size: 11px; }
.touch-list-empty { padding: 14px 10px; font-size: 12px; }
.kickoff-grid { gap: 8px; }
.kickoff-grid button { min-height: 54px; padding: 10px; }
.kickoff-grid span { font-size: 11px; }
.kickoff-grid strong { font-size: 11px; }

button:focus-visible, select:focus-visible, input:focus-visible, textarea:focus-visible, summary:focus-visible { outline: 2px solid var(--interaction-hover); outline-offset: 2px; }

body.controls-detached .workspace { grid-template-columns: 80px minmax(560px, 1fr); }
.panel-window .inspector-top { grid-template-columns: minmax(0, 1fr) 96px; }

@media (max-width: 1080px) {
  .workspace { grid-template-columns: 76px minmax(500px, 1fr) 300px; }
  body.controls-detached .workspace { grid-template-columns: 76px minmax(500px, 1fr); }
}

@media (max-width: 820px) {
  .workspace { grid-template-columns: 76px 1fr; }
  body.controls-detached .workspace { grid-template-columns: 76px minmax(0, 1fr); }
}

/* Match navigation and output review. */
.header-actions .review-window-button { display: flex; align-items: center; gap: 8px; color: #d8e2e8; border-color: #435563; background: #17222b; }
.review-window-button b { min-width: 19px; height: 19px; display: grid; place-items: center; padding: 0 5px; color: #071018; background: var(--interaction-hover); border-radius: 10px; font: 800 11px/1 Consolas, monospace; }
.screenshot-analysis { padding: 0 12px; color: #b9c7cf; border: 1px solid #4b5b67; background: var(--control); }
.screenshot-analysis:hover { color: white; border-color: var(--interaction-hover); }
.timeline-row { grid-template-columns: 202px minmax(0, 1fr); }
.frame-steps { gap: 5px; }
.frame-steps .jump-button { width: 52px; color: var(--text-secondary); border-color: var(--border-strong); background: #202d37; }
.import-help { margin: 11px 0 0; padding: 10px 11px; color: #8f9ea8; background: #141f28; border-left: 3px solid var(--interaction-hover); font-size: 12px; line-height: 1.5; }
.import-help strong { color: #e2e9ed; }
.import-help code { color: var(--interaction-hover); font: 700 12px/1 Consolas, monospace; }

/* Exported clips list (Annotate tab) — same .layer-item row shape as Marks on video,
   plus a two-button action cell since a clip row needs Download and Remove. */
.clip-item-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.clip-item-name small { display: block; margin-top: 2px; color: var(--text-muted); font-size: 11px; }
.clip-item-actions { display: flex; gap: 4px; }
.clip-item-actions button { width: 22px; height: 22px; padding: 0; color: inherit; border: 1px solid #3c4b56; border-radius: 3px; background: transparent; font-size: 11px; }
.clip-item-actions button:hover { border-color: var(--interaction-hover); }
@keyframes flash-highlight { 0%, 100% { box-shadow: none; } 30%, 70% { box-shadow: 0 0 0 2px var(--signal-chrome, var(--interaction-hover)); } }
.flash-highlight { animation: flash-highlight 1.2s ease-in-out; }

/* Readable event review and explicit sync diagnostics. */
.workspace { grid-template-columns: 80px minmax(560px, 1fr) 350px; }
.drawer summary span { font-size: 13px; }
.drawer summary small { font-size: 12px; }
.data-status, .batch-status, .sync-copy { font-size: 11px; }
.review-selects label, .event-filter-label, .article-options label { font-size: 12px; }
select, .review-window input { font-size: 12px; }
.touch-summary strong { font-size: 20px; }
.touch-summary span { font-size: 12px; }
.review-window > span { font-size: 12px; }
.review-window label { font-size: 11px; }
.review-controls button, .decision-controls button, .article-actions button { font-size: 11px; }
.clip-window-preview { margin-top: 8px; padding: 9px 10px; color: #b9c8d1; background: var(--control); border: 1px solid #334550; border-radius: 3px; font: 600 12px/1.5 var(--font-body); }
.event-offset-control { display: grid; grid-template-columns: 1fr auto; align-items: center; gap: 12px; margin-top: 8px; padding: 10px; border: 1px solid var(--border); border-radius: 3px; background: var(--panel); }
.event-offset-control strong, .event-offset-control small { display: block; }
.event-offset-control strong { color: #9eb0bc; font: 750 11px/1 Consolas, monospace; letter-spacing: .08em; }
.event-offset-control small { margin-top: 5px; color: #71828e; font-size: 12px; }
.event-offset-control label { display: flex; align-items: center; gap: 5px; color: #80919c; font-size: 12px; }
.event-offset-control input { width: 58px; height: 38px; padding: 0 7px; color: #e7edf0; border: 1px solid #43545f; border-radius: 3px; background: var(--control); font-size: 12px; }
.touch-list { max-height: 320px; }
.touch-row { min-height: 60px; grid-template-columns: 50px 1fr 18px; padding: 8px 10px; }
.touch-row time { font-size: 12px; }
.touch-row strong { font-size: 11px; }
.touch-row small { font-size: 12px; line-height: 1.35; }
.analysis-state strong { font-size: 12px; }
.analysis-state span { font-size: 12px; }
.timecode { font-size: 12px; }
.timecode strong { font-size: 15px; }
.timeline-labels { font-size: 11px; }
.stage-footer { font-size: 11px; }

/* Pop-out leaves a marker behind, so the panel never just vanishes. */
.controls-parked { display: none; }
body.controls-detached .workspace { grid-template-columns: 80px minmax(560px, 1fr) 52px; }
body.controls-detached .controls-parked {
  grid-column: 3; display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 10px; padding: 16px 6px; color: var(--text-muted); background: var(--panel);
  border: 0; border-left: 1px solid var(--border); cursor: pointer;
}
body.controls-detached .controls-parked:hover { color: var(--text); background: #16212a; }
.controls-parked span { font-size: 17px; }
.controls-parked strong, .controls-parked small { writing-mode: vertical-rl; font-weight: 700; letter-spacing: .07em; }
.controls-parked strong { font-size: 11px; }
.controls-parked small { color: var(--text-muted); font-size: 12px; font-weight: 400; }

/* Live five-step guide: sync is a real step, so it gets a real slot. */
.event-guide { height: auto; flex-wrap: wrap; justify-content: flex-start; gap: 4px 5px; padding: 8px 6px; font-size: 12px; }
.event-guide [data-step] { padding: 3px 5px; border-radius: 2px; color: var(--text-muted); transition: color .15s, background .15s; }
.event-guide [data-step].is-done { color: #7fd8a4; }
.event-guide [data-step].is-done::before { content: "✓ "; }
.event-guide [data-step].is-next { color: #071018; background: var(--interaction-hover); }
.event-guide i { color: var(--border-strong); }

/* Readable annotate panel — the section labels were 8-9px uppercase monospace. */
.panel-heading span, .comment-composer label, .style-row > span, .width-row label,
.selected-controls label, .label-row span { font-size: 11px; letter-spacing: .06em; }
.panel-heading h2 { font-size: 19px; }
.selection-badge { font-size: 12px; }
.pause-prompt p { font-size: 12px; line-height: 1.5; }
.rail-label { font-size: 12px; letter-spacing: .06em; }
.rail-tip { font-size: 12px; line-height: 1.45; }
.layer-item { font-size: 11px; }
.layer-index { font-size: 12px; }
.empty-layers p { font-size: 11px; line-height: 1.5; }
.text-field, .selected-actions button { font-size: 12px; }
.inspector-tabs button { font-size: 12px; }
.width-row output { font-size: 11px; }

/* A stalled export leaves the recorder waiting on a 'timeupdate' that will never
   come if the video gets paused any other way, so lock out the controls that could
   pause it while renderVideoClip is running (JS guards do the same; this is belt
   and braces so it's visible, not just blocked). */
body.export-in-progress .play-button,
body.export-in-progress .start-analysis,
body.export-in-progress #videoScrubber,
body.export-in-progress #stepBackBtn,
body.export-in-progress #stepForwardBtn,
body.export-in-progress .jump-button,
body.export-in-progress #eventMarkers,
body.export-in-progress #touchList,
body.export-in-progress #freezeList,
body.export-in-progress #syncEvents { opacity: .45; pointer-events: none; }

/* Shot map — click a dot to jump into the normal review flow at that shot. */
.shot-map-legend { display: flex; flex-wrap: wrap; gap: 10px 14px; margin-bottom: 10px; }
.shot-map-key { display: flex; align-items: center; gap: 5px; color: var(--text-muted); font-size: 12px; }
.shot-map-key i { width: 9px; height: 9px; border-radius: 50%; border: 1.5px solid; display: inline-block; }
.shot-map-key.goal i { border-color: var(--annotation-yellow); background: var(--annotation-yellow); }
.shot-map-key.on-target i { border-color: var(--interaction-hover); background: var(--interaction-hover); }
.shot-map-key.off-target i { border-color: #6b7b86; background: transparent; }
.shot-map-key.blocked i { border-color: #8b6bd9; background: transparent; }
.shot-map { border-radius: 4px; overflow: hidden; background: #0e2a17; box-shadow: inset 0 0 0 1px #1c4a28; }
.shot-map svg { display: block; width: 100%; height: auto; aspect-ratio: 50 / 100; }
.pitch-outline { fill: #123a20; }
.pitch-line-shape { fill: none; stroke: rgba(255, 255, 255, .28); stroke-width: .35; }
.pitch-goal { fill: none; stroke: rgba(255, 255, 255, .55); stroke-width: .5; }
.pitch-spot { fill: rgba(255, 255, 255, .28); }
.shot-dot { stroke-width: .5; cursor: pointer; transition: r .1s, opacity .1s; }
.shot-dot.goal { fill: var(--annotation-yellow); stroke: #6b5524; }
.shot-dot.on-target { fill: var(--interaction-hover); stroke: #1f4a63; }
.shot-dot.off-target { fill: rgba(198, 208, 214, .5); stroke: rgba(255, 255, 255, .35); }
.shot-dot.blocked { fill: #8b6bd9; stroke: #3a2c5c; }
.shot-dot:hover, .shot-dot:focus-visible { r: 2.6; opacity: 1; }
/* UX review (Aug 18 2026): a Tab-focused dot used to look pixel-identical to a
   mouse-hovered one (outline: none, same growth rule for both) — a keyboard user
   had no way to tell which dot was actually focused. */
.shot-dot:focus-visible { outline: 1.5px solid var(--signal-chrome); outline-offset: 1px; }
.shot-dot.is-blocked { opacity: .35; stroke-dasharray: .6 .6; cursor: not-allowed; }
.shot-map-empty { padding: 34px 16px; color: #6f8878; text-align: center; font-size: 11px; }
.shot-map-caption { margin-top: 8px; padding: 8px 10px; color: var(--text-muted); background: var(--panel); border: 1px solid var(--border); border-radius: 3px; font-size: 11px; min-height: 1.4em; }

/* Second-half kickoff missing: advisory when browsing, blocking on the selected event. */
.sync-warning { margin-top: 8px; padding: 10px 11px; color: #f0d9a4; background: #241d0f; border: 1px solid #6b5524; border-left-width: 3px; border-radius: 3px; font-size: 11px; line-height: 1.5; cursor: pointer; }
.sync-warning strong { display: block; margin-bottom: 3px; color: var(--annotation-yellow); font-size: 11px; }
.sync-warning u { text-underline-offset: 2px; }
.sync-warning:hover { background: #2c2413; border-color: #8a6d2e; }
.sync-warning.is-blocking { color: #ffd9d5; background: #2a1613; border-color: #8c3a32; }
.sync-warning.is-blocking strong { color: #ff9d93; }
.sync-warning.is-blocking:hover { background: #341b17; border-color: #ab463c; }

@media (max-width: 1080px) {
  .workspace { grid-template-columns: 76px minmax(480px, 1fr) 320px; }
}

@media (max-width: 820px) {
  .workspace { grid-template-columns: 76px 1fr; }
}

/* Real branded type, self-hosted (no network dependency — "nothing leaves this
   device" holds either way). Two voices, not one: Barlow Condensed 800 italic is
   the hero voice — wordmark, section headings, big numerals, the moments that
   should feel loud — and Bebas Neue (upright, quieter) is the structural voice for
   tabs, rail labels, and drawer headers, the chrome you look at constantly rather
   than glance at. DM Sans carries everything else. (Aug 18 2026 — swapped the
   wordmark/headings/numerals off Bebas-everywhere per direct feedback that one
   upright display face read as flat; the italic is the same family used across the
   AFC hub / YSM site work, so this also brings Touchline in line with that system.) */
.brand strong, .panel-heading h2, .empty-stage strong,
.touch-summary strong {
  font-family: var(--font-athletic); font-weight: 800; font-style: italic; font-stretch: normal; letter-spacing: 0;
}
.brand strong { font-size: 21px; }
/* .timecode strong (the live playhead readout) deliberately stays out of the hero
   voice above — it updates dozens of times a second during playback, and Barlow
   Condensed's digits aren't fixed-width, so the element's own width flickered
   every frame and shook everything next to it. Every video editor uses a
   monospace timecode for exactly this reason; it already inherits Consolas from
   .timecode's own font shorthand, this just stops overriding that. */
.inspector-tabs button { font-family: var(--font-display); font-weight: 400; letter-spacing: .02em; }
.drawer summary span { font-family: var(--font-display); font-weight: 400; letter-spacing: .015em; }
.rail-label { font-family: var(--font-display); font-weight: 400; letter-spacing: .16em; }

/* Brand accent unification: red (the wordmark's colour) replaces blue as the single
   interactive/selected/primary colour throughout the chrome. The shot-map's own
   legend keeps its blue — that's a data-viz set, a different concern from branding. */
.tool.active { box-shadow: inset 3px 0 var(--signal-chrome); }
.source-switch .load-video-button:hover { border-color: var(--signal-chrome); }
.inspector-tabs button.active::after { background: var(--signal-chrome); }
.popout-controls { color: var(--signal-light); }
.popout-controls:hover { border-color: var(--signal-chrome); }
.comment-composer button { color: #1a0d0c; border-color: var(--signal-chrome); background: var(--signal-chrome); }
.event-guide strong { color: var(--signal-light); }
.data-import-button:hover, .wide-control:hover { border-color: var(--signal-chrome); }
.review-controls .review-play, .article-pack-button { color: #1a0d0c; border-color: var(--signal-chrome); background: var(--signal-chrome); }
.touch-row.active { color: #eef4f6; border-color: var(--signal-chrome); box-shadow: inset 2px 0 var(--signal-chrome); }
.touch-row time { color: var(--signal-light); }
.touch-row .decision-mark { color: #1a0d0c; background: var(--signal-light); }
.touch-row.kept { border-left-color: var(--signal-light); }
.touch-item.active { border-color: var(--signal-chrome); }
button:focus-visible, select:focus-visible, input:focus-visible, textarea:focus-visible, summary:focus-visible { outline-color: var(--signal-chrome); }
.review-window-button b { color: #1a0d0c; background: var(--signal-light); }
.screenshot-analysis:hover { border-color: var(--signal-chrome); }
.import-help { border-left-color: var(--signal-chrome); }
.import-help code { color: var(--signal-light); }
.event-guide [data-step].is-next { color: #1a0d0c; background: var(--signal-chrome); }
.timeline-event.touch-event-marker { background: var(--signal-light); }

/* .start-analysis previously set white text on the (fairly light, saturated) red
   fill — 2.87:1, fails WCAG AA. Dark ink on that same red is 6.22:1, matching how
   every other filled-red/filled-chrome button here already handles it. */
.start-analysis { color: #1a0d0c; }

/* Zero-radius throughout — circles (dots, swatches, slider thumbs, the play-circle
   mark, the exports-count badge) stay circular; every rectangular control goes flat. */
.header-actions button, .tool, .source-switch button, .analysis-main-actions button,
.frame-steps button, .selection-badge, .comment-composer textarea, .comment-composer button,
.text-field, .selected-actions button, .hold-row label, .hold-row button, .layer-item,
.data-import-button, .wide-control, .article-pack-button, .clear-data-button, select, .review-window input,
.review-controls button, .decision-controls button, .article-actions button,
.article-queue textarea, #eventInput, .kickoff-grid button, .inspector-tabs button,
.popout-controls, .event-guide, .touch-row, .touch-row .decision-mark, .touch-list-empty,
#matchdayFeedback, .clip-item-actions button,
.clip-window-preview, .event-offset-control, .event-offset-control input, .event-guide [data-step],
.shot-map, .shot-map-caption, .sync-warning, .formation-badge button, .formation-badge kbd {
  border-radius: 0;
}

/* Contrast fixes — computed against the actual backgrounds they sit on. */
.analysis-state span { color: var(--text-muted); }
.panel-heading span, .label-row, .comment-composer label, .style-row > span, .style-row > label, .selected-controls > label { color: var(--text-muted); }
.event-guide { color: #7c8d97; }
.data-status, .batch-status, .sync-copy { color: #8996a0; }
.review-selects label, .event-filter-label, .article-options label { color: #8996a0; }

/* The blocked shot-dot was the one legend colour without real edge definition —
   mid-tone purple fill on a mid-dark pitch, dark stroke on top of that (3.82:1).
   Lightened to match how the other three states pair a bright fill with a dark rim. */
.shot-dot.blocked { fill: #a688f0; stroke: #3a2c5c; }
.shot-map-key.blocked i { border-color: #a688f0; }

/* The Annotate tab got a readability pass earlier this session; the Filter & clip /
   events tab was still running on an older, more conservative bump (10-13px, with
   several outliers still at 8-10px) — this is the "I don't see the change" tab.
   One consistent scale in its place, not another one-off nudge. */
.drawer summary span { font-size: 15px; font-weight: 700; color: #f0f4f6; }
.drawer summary small { font-size: 11px; font-weight: 600; }
.kickoff-grid span, .review-window > span, .touch-summary span,
.event-filter-label, .review-selects label { font-size: 12px; font-weight: 700; letter-spacing: .08em; }
.sync-copy, .data-status, .import-help, .batch-status { font-size: 13px; line-height: 1.5; }
.kickoff-grid strong, .touch-row time { font-size: 13px; font-weight: 700; }
.data-import-button, .wide-control, .article-pack-button, .clear-data-button,
.review-controls button, .decision-controls button, .article-actions button { font-size: 12px; font-weight: 700; letter-spacing: .02em; }
.touch-row strong { font-size: 12px; font-weight: 600; }
.touch-row small { font-size: 11px; }
.event-guide [data-step] { font-size: 11px; font-weight: 700; letter-spacing: .04em; }

/* Setting a kickoff anchor is "pause here, note this exact video time" — the action
   and the timecode it depends on were two different regions of the screen (sidebar
   drawer vs. video-dock toolbar). Now they're one instrument. */
.analysis-strip { grid-template-columns: auto 1fr auto auto; }
.kickoff-inline { display: flex; align-items: stretch; gap: 1px; padding-left: 16px; border-left: 1px solid var(--border); }
.kickoff-inline button {
  min-width: 60px; padding: 4px 9px; display: flex; flex-direction: column; align-items: flex-start; justify-content: center;
  gap: 2px; border: 1px solid var(--border-strong); background: #161f28; color: #7c8b96;
}
.kickoff-inline button span { font-size: 11px; font-weight: 700; letter-spacing: .08em; }
.kickoff-inline button strong { font-family: var(--font-display); font-size: 14px; font-weight: 400; color: #c7d1d7; }
.kickoff-inline button:hover { border-color: var(--signal-chrome); color: var(--text-secondary); }
.kickoff-inline button.is-set { border-color: var(--signal-chrome-dark); background: #1c1310; }
.kickoff-inline button.is-set strong { color: var(--signal-light); }

/* The ANNOTATE row reuses .review-window's layout (matches CLIP WINDOW above it),
   but its first control is a checkbox, not a number — .review-window input's 46px
   box-style width doesn't apply to that. */
.hold-toggle input[type="checkbox"] { width: 15px; height: 15px; margin: 0; accent-color: var(--signal-chrome); }

/* Line-up / formation tool: click-per-player draft, and its fill toggle. */
.fill-row input[type="checkbox"] { width: 16px; height: 16px; margin: 0; accent-color: var(--signal-chrome); }
.formation-hint { margin: 10px 16px 0; padding: 9px 11px; color: #b9c8d1; background: var(--control); border: 1px solid #334550; border-left-width: 3px; border-left-color: var(--signal-chrome); font-size: 12px; line-height: 1.5; }
.formation-hint kbd { padding: 1px 5px; color: var(--text); background: var(--control-hover); border: 1px solid var(--border-strong); font: 600 12px/1 var(--font-body); }

/* Reclaiming the dead space either side of the video.

   The frame is 16:9 and height-constrained, so its width is capped by whatever
   vertical space the chrome leaves — widening the stage alone only adds more empty
   background beside it. Two levers, applied together: take height back from chrome
   that was not earning it, and let the panel absorb the width that remains.

   Height back: the footer row is gone (it read "LOCAL WORKSPACE · 16:9 · 1280x720",
   decoration apart from the save status, which now sits in the stage toolbar beside
   the filename), the toolbar is tighter, and the canvas bay padding is trimmed.
   Every vertical pixel here returns ~1.78 horizontal ones to the frame. */
.stage-footer { display: none; }
.stage-toolbar { height: 40px; flex-basis: 40px; }
.canvas-bay { padding: 6px 10px; }
.video-dock { padding: 6px 14px 5px; }
.frame-status-sep { opacity: .4; }

/* Width absorbed: the panel takes the leftover rather than leaving it as background,
   which also gives the events tab the room it was short of. */
.workspace { grid-template-columns: 80px minmax(520px, 1fr) 430px; }
body.controls-detached .workspace { grid-template-columns: 80px minmax(520px, 1fr) 52px; }
.video-mode .canvas-frame { width: min(100%, calc((100vh - 232px) * 16 / 9)); }
.canvas-frame { width: min(100%, calc((100vh - 118px) * 16 / 9)); }

@media (max-width: 1280px) {
  .workspace { grid-template-columns: 80px minmax(460px, 1fr) 370px; }
  body.controls-detached .workspace { grid-template-columns: 80px minmax(460px, 1fr) 52px; }
}

/* Bigger, plainer controls. The panel had drifted to lots of small buttons carrying
   wide-tracked micro-caps, which reads as busy and is fiddly to hit mid-match. One
   height, one text size, normal tracking. The video dock grows to match, so the
   canvas height calc below has to give back the same amount. */
.header-actions button,
.source-switch button,
.analysis-main-actions button,
.data-import-button, .wide-control, .article-pack-button, .clear-data-button,
.review-controls button, .decision-controls button, .article-actions button,
.selected-actions button, .hold-row button, .comment-composer button,
.kickoff-inline button {
  min-height: 46px;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0;
}
.header-actions .icon-button { width: 46px; font-size: 19px; }
.header-actions .icon-button .ico { width: 19px; height: 19px; }
.header-actions .quiet-button, .header-actions .export-button { padding: 0 16px; }
.play-button { width: 50px; font-size: 15px !important; }
.play-button .ico { width: 17px; height: 17px; }
.frame-steps button { height: 38px; font-size: 12px; }
.frame-steps .jump-button { width: 58px; }
.clip-controls button { height: 38px; font-size: 11px; padding: 0 12px; }
.tool { min-height: 62px; font-size: 12px; }
.tool-icon { height: 24px; }
.tool-icon .ico { width: 22px; height: 22px; }
.inspector-tabs button { min-height: 46px; font-size: 13px; }
.drawer summary { min-height: 60px; }
select, .review-window input, .text-field, .event-offset-control input { height: 44px; font-size: 13px; }
.review-controls { grid-template-columns: 92px 1fr 92px; }
.kickoff-inline button { min-width: 72px; }
.kickoff-inline button strong { font-size: 16px; }
.condensed-toggle { font-size: 13px; }

/* Decorative glyphs on buttons: keep them as quiet affordances, not competing labels. */
.data-import-button strong, .wide-control strong, .export-button span[aria-hidden] { opacity: .55; font-weight: 400; }

.video-dock { flex: 0 0 118px; }

/* Clip mode needs to be obvious at a glance — it's easy to forget you're recording a
   clip rather than just watching the match back. Red rail while marking, pulsing
   while paused to annotate. */
body.analysis-active .canvas-frame { box-shadow: 0 16px 45px rgba(0,0,0,.52), 0 0 0 2px var(--signal); }
body.analysis-active .canvas-frame::after {
  content: "● CLIP"; position: absolute; z-index: 5; top: 12px; right: 12px;
  padding: 5px 9px; color: #fff; background: rgba(216,60,52,.92);
  font: 600 11px/1 var(--font-body); pointer-events: none;
}
body.analysis-active.analysis-paused .canvas-frame::after { content: "❚❚ ANNOTATE"; background: rgba(20,28,36,.92); color: var(--signal-light); }
body.analysis-active.analysis-paused .canvas-frame { animation: clip-paused-pulse 1.8s ease-in-out infinite; }
@keyframes clip-paused-pulse {
  0%, 100% { box-shadow: 0 16px 45px rgba(0,0,0,.52), 0 0 0 2px var(--signal); }
  50% { box-shadow: 0 16px 45px rgba(0,0,0,.52), 0 0 0 3px var(--signal-light); }
}
@media (prefers-reduced-motion: reduce) {
  body.analysis-active.analysis-paused .canvas-frame { animation: none; }
}

/* Per-freeze duration: some moments need three seconds, some need ten. */
.hold-section { margin-top: 14px; padding-top: 13px; border-top: 1px solid var(--border); }
.hold-hint { margin: 7px 0 9px; color: #8996a0; font-size: 11px; line-height: 1.45; }
.hold-row { grid-template-columns: 96px 1fr; }
.hold-row label { height: 46px; color: var(--text-muted); border-color: var(--border-strong); background: var(--control); font-size: 13px; }
.hold-row label input { width: 52px; color: #e7edf0; font: 700 15px/1 Consolas, monospace; }
.hold-row button { min-height: 46px; color: var(--text-secondary); border-color: var(--border-strong); background: var(--control); font-size: 13px; font-weight: 700; }
.hold-row button:hover:not(:disabled) { border-color: var(--signal-chrome); }
.hold-row button.is-active { color: var(--signal-light); border-color: var(--signal-chrome-dark); background: #1c1310; }
.freeze-item { grid-template-columns: 58px 1fr auto; padding: 11px 10px; color: var(--text-muted); background: var(--control); border: 1px solid #2d3943; font: 600 12px/1 var(--font-body); }
.freeze-item.active { color: #eef4f6; border-color: var(--signal-chrome); }
.freeze-item time { color: var(--signal-light); }
.freeze-item button { color: #8b969d; font-size: 17px; padding: 0 4px; }

/* Pasted clip ranges ("24:10-24:38, Label") vs. the original point markers. */
.timeline-event-range { background: var(--signal-light); opacity: .6; }
.sync-copy-tight { margin-top: -4px; }
.sync-copy a { color: var(--interaction); text-decoration: none; font-weight: 600; }
.sync-copy a:hover { color: var(--interaction-hover); text-decoration: underline; }
.sync-copy-tight code { padding: 1px 5px; color: var(--text); background: var(--control-hover); border: 1px solid var(--border-strong); font: 700 11px/1 Consolas, monospace; }
.sync-event.is-range { border-left: 3px solid var(--signal-chrome); }
.sync-event.is-range time { color: var(--signal-light); }

/* Condensed playback: skip the stoppages WhoScored already tags for us. */
.condensed-toggle { display: flex; align-items: center; gap: 7px; padding: 0 15px; color: #b9c7cf; border: 1px solid #4b5b67; background: var(--control); }
.condensed-toggle:hover { color: white; border-color: var(--signal-chrome); }
.condensed-toggle.is-on { color: #1a0d0c; border-color: var(--signal-chrome); background: var(--signal-chrome); }

/* Playback speed — a small mutually-exclusive group, same visual language as the
   condensed-playback toggle so it doesn't read as a new control system. */
/* One segmented control, not three boxed buttons. */
.speed-controls { display: inline-flex; flex-shrink: 0; border: 1px solid var(--border-strong); border-radius: 4px; overflow: hidden; background: var(--control); }
.speed-btn { padding: 0 10px; color: var(--text-secondary); border: 0; border-left: 1px solid var(--border-strong); background: transparent; font: 600 12px/1 var(--font-body); }
.speed-btn:first-child { border-left: 0; }
.speed-btn:hover { color: var(--text); background: var(--control-hover); }
.speed-btn.is-on { color: var(--chrome); background: var(--interaction); }
.timeline-dead { position: absolute; top: 9px; height: 5px; background: repeating-linear-gradient(90deg, var(--border-strong) 0 3px, transparent 3px 6px); pointer-events: none; }

/* Second screen: given a display of its own the panel has width to spare, so the
   events tab runs in two columns and stops being one long scroll. */
.panel-window .inspector { max-width: none; }
@media (min-width: 700px) {
  .panel-window #eventsView { display: grid; grid-template-columns: 1fr 1fr; align-items: start; gap: 0 18px; padding: 0 4px; }
  .panel-window #eventsView > .drawer:first-child { grid-column: 1; }
  .panel-window #eventsView > .drawer:nth-child(n+2) { grid-column: 2; }
  .panel-window .touch-list { max-height: 46vh; }
  .panel-window .shot-map svg { max-height: 52vh; width: auto; margin: 0 auto; }
  .panel-window #annotateView { display: grid; grid-template-columns: 1fr 1fr; align-items: start; gap: 0 18px; }
  .panel-window .layer-list { max-height: 40vh; overflow: auto; }
}

/* Reopen-last-match sits beside Load, quieter than the primary action. */
.reopen-video-button { padding: 0 14px; color: var(--text-secondary); border: 1px solid var(--border-strong); background: var(--control); }
.reopen-video-button:hover { color: #fff; border-color: var(--signal-chrome); }

/* Shot map half filter. */
.shot-map-halves { display: grid; grid-template-columns: repeat(3, 1fr); gap: 5px; margin-bottom: 10px; }
.shot-map-halves button { min-height: 38px; color: #96a4ad; border: 1px solid var(--border); background: var(--control); font-size: 12px; font-weight: 700; }
.shot-map-halves button:hover { color: var(--text); border-color: #45565f; }
.shot-map-halves button.active { color: #1a0d0c; border-color: var(--signal-chrome); background: var(--signal-chrome); }
.shot-map-halves button:disabled { opacity: .4; cursor: not-allowed; }
.shot-map-halves button:disabled:hover { color: #96a4ad; border-color: var(--border); }
.shot-map-toggles { display: flex; flex-direction: column; gap: 6px; margin-bottom: 10px; }
.shot-map-toggles .shot-map-halves { margin: 0; }
.shot-map-toggles .shot-map-side { grid-template-columns: repeat(2, 1fr); }
.shot-map-halves button { white-space: nowrap; }

/* Match Notes (Aug 19 2026) — one complete pass rather than the older multi-pass
   redeclare-later-in-the-file pattern this file otherwise has; every rule below is
   final as written. */
.match-notes-section .rail-tip { display: block; margin: 0 0 10px; }
.match-note-composer { margin-top: 8px; }
.match-note-composer input { width: 100%; height: 42px; padding: 0 12px; color: var(--text); border: 1px solid var(--border-strong); background: #0d151c; font-size: 12px; }
.match-note-composer input:focus-visible { outline: 2px solid var(--signal-chrome); outline-offset: -1px; }
.match-notes-list { display: flex; flex-direction: column; gap: 4px; margin-top: 8px; max-height: 320px; overflow: auto; }
.match-note-row { display: grid; grid-template-columns: 54px 1fr auto; align-items: center; gap: 8px; padding: 7px 9px; border: 1px solid #2d3943; background: var(--control); }
.match-note-row > [data-action="jump"] { border: 0; padding: 0; color: var(--signal-light); background: transparent; text-align: left; }
.match-note-row time { font: 700 12px/1 Consolas, monospace; }
.match-note-text { border: 0; padding: 0; color: var(--text); background: transparent; text-align: left; font-size: 12px; line-height: 1.4; overflow-wrap: anywhere; }
.match-note-text:hover { color: #fff; text-decoration: underline; }
.match-note-actions { display: flex; gap: 4px; }
.match-note-actions button { min-height: 28px; padding: 0 8px; color: var(--text-muted); border: 1px solid var(--border-strong); background: var(--control); font-size: 12px; font-weight: 700; }
.match-note-actions button:hover { border-color: var(--signal-chrome); }
.match-note-actions button.active { color: #1a0d0c; border-color: var(--signal-chrome); background: var(--signal-chrome); }
.match-note-filter-row { display:flex; align-items:center; gap:5px; flex-wrap:wrap; margin-top:10px; padding:7px 8px; border:1px solid var(--border); background:var(--control); }
.match-note-filter-row > span { margin-right:auto; color:var(--text-muted); font:700 11px/1 Consolas,monospace; text-transform:uppercase; letter-spacing:.06em; }
.match-note-filter-row button, .note-rating { min-height:26px; padding:0 7px; border:1px solid var(--border-strong); border-radius:2px; color:var(--text-muted); background:transparent; font:800 10px/1 Inter,sans-serif; letter-spacing:.03em; }
.match-note-filter-row button:hover, .match-note-filter-row button.active { color:var(--text); border-color:var(--signal-chrome); background:rgba(255,255,255,.08); }
.match-note-filter-row button.good, .note-rating.good { color:#5fca93; }
.match-note-filter-row button.bad, .note-rating.bad { color:#f27b78; }
.match-note-filter-row button.good.active, .note-rating.good.active { color:#071018; border-color:#36c77f; background:#36c77f; }
.match-note-filter-row button.bad.active, .note-rating.bad.active { color:#fff; border-color:#dc5a57; background:#dc5a57; }
.note-rating { min-height:25px !important; padding:0 6px !important; }

/* Saved filter presets. */
.filter-presets { margin-top: 8px; }
.filter-presets-list { display: flex; flex-direction: column; gap: 4px; margin-top: 6px; }
.filter-preset-row { display: grid; grid-template-columns: 1fr auto; align-items: center; gap: 8px; padding: 6px 9px; border: 1px solid #2d3943; background: var(--control); }
.filter-preset-row > [data-action="apply-preset"] { border: 0; padding: 0; color: var(--text); background: transparent; text-align: left; font-size: 12px; }
.filter-preset-row > [data-action="apply-preset"]:hover { color: var(--signal-light); }
.filter-preset-row > [data-action="delete-preset"] { min-height: 24px; padding: 0 8px; color: var(--text-muted); border: 1px solid var(--border-strong); background: var(--control); font-size: 12px; }
.filter-preset-row > [data-action="delete-preset"]:hover { border-color: var(--signal-chrome); }

/* Kept clips with a caption already written get a visible ring on the K mark, so a
   kept-but-uncaptioned clip reads differently from one ready to export. */
.touch-row .decision-mark.has-note { box-shadow: 0 0 0 1.5px var(--signal-light); }

/* ===========================================================================
   Workspace hierarchy pass.
   VIDEO -> LARGE TIMELINE -> EVENTS | STATS | NOTES | CLIPS.
   Appended last on purpose: these rules win over the earlier layers without
   editing them, so nothing already working gets disturbed.
   =========================================================================== */

/* --- Annotation is a mode, not a permanent column -------------------------
   The tool rail used to hold an 80px strip of the screen open for every minute
   of a 90-minute review, whether or not anything was being drawn. It now
   collapses to nothing until Annotate is on. Only the column width changes:
   the rail keeps its markup, listeners and tools exactly as they were. */
.workspace { grid-template-columns: 0 minmax(520px, 1fr) 430px; transition: grid-template-columns .16s ease; }
body.annotate-mode .workspace { grid-template-columns: 80px minmax(520px, 1fr) 430px; }
body.controls-detached .workspace { grid-template-columns: 0 minmax(520px, 1fr) 52px; }
body.controls-detached.annotate-mode .workspace { grid-template-columns: 80px minmax(520px, 1fr) 52px; }
.tool-rail { overflow-x: hidden; overflow-y: auto; }
body:not(.annotate-mode) .tool-rail { padding-left: 0; padding-right: 0; border-right: 0; }

.annotate-mode-button {
  display: inline-flex; align-items: center; gap: 7px; height: 30px; padding: 0 14px;
  color: #cfd8de; background: var(--control); border: 1px solid var(--border-strong); border-radius: 3px;
  font: 800 12px/1 Inter, sans-serif; letter-spacing: .02em; cursor: pointer;
}
.annotate-mode-button:hover { color: #fff; border-color: #4b5c6a; }
.annotate-mode-button.active { color: var(--chrome); background: var(--signal, var(--interaction)); border-color: var(--signal, var(--interaction)); }

/* ---- Present mode -------------------------------------------------------------
   A full-screen walkthrough: chrome gone, video maxed, one floating control bar.
   Built for screen-recording a narrated pass over the clips. */
.present-button {
  display: inline-flex; align-items: center; gap: 7px; height: 30px; padding: 0 13px; margin-left: 8px;
  color: #cfd8de; background: var(--control); border: 1px solid var(--border-strong); border-radius: 3px;
  font: 800 12px/1 Inter, sans-serif; letter-spacing: .02em; cursor: pointer;
}
.present-button:hover { color: #fff; border-color: var(--signal-chrome, var(--interaction)); }
.present-button:disabled { opacity: .4; cursor: not-allowed; }
.present-button .ico { width: 15px; height: 15px; }

body.presenting .topbar,
body.presenting .tool-rail,
body.presenting .inspector,
body.presenting .stage-toolbar,
body.presenting .video-dock,
body.presenting .controls-parked { display: none !important; }
body.presenting .workspace { grid-template-columns: 1fr !important; }
body.presenting .stage-section { background: #000; }
body.presenting .canvas-bay { padding: 0; background: #000; }
body.presenting #telestrationCanvas { cursor: crosshair; }
/* Present mode gets screen-recorded: no editor badges, and the cursor goes when idle. */
body.presenting .freeze-badge,
body.presenting .canvas-frame::after { display: none !important; }
body.present-idle #telestrationCanvas { cursor: none; }

.present-bar {
  position: fixed; z-index: 40; left: 50%; bottom: 22px; transform: translateX(-50%);
  display: flex; align-items: center; gap: 4px; padding: 7px 9px;
  background: rgba(10, 13, 16, .82); border: 1px solid var(--border); border-radius: 8px;
  backdrop-filter: blur(6px); box-shadow: 0 10px 34px rgba(0,0,0,.5);
  opacity: 1; transition: opacity .3s ease;
}
.present-bar[hidden] { display: none; }
body.present-idle .present-bar { opacity: 0; pointer-events: none; }
.present-bar button {
  height: 36px; min-width: 36px; padding: 0 9px; display: inline-flex; align-items: center; justify-content: center;
  color: var(--text); background: transparent; border: 0; border-radius: 5px; cursor: pointer;
  font: 700 15px/1 Inter, sans-serif;
}
.present-bar button:hover { background: #1e2a34; color: #fff; }
.present-bar button.present-seek { font-size: 13px; letter-spacing: .01em; }
.present-bar button.on { color: var(--chrome); background: var(--signal-chrome, var(--interaction)); }
.present-bar .ico { width: 18px; height: 18px; }
.present-bar .present-exit .ico { width: 16px; height: 16px; }
.present-sep { width: 1px; align-self: stretch; margin: 4px 5px; background: var(--border); }
.present-clip {
  padding: 0 10px; color: #9aa7b0; white-space: nowrap;
  font: 700 12px/1 "Barlow Condensed", Inter, sans-serif; letter-spacing: .02em;
}
.present-color-chip { width: 15px; height: 15px; border-radius: 50%; border: 2px solid rgba(255,255,255,.7); background: #fff; display: block; }

/* --- Top-level Match / Season -------------------------------------------- */
.level-switch { display: inline-flex; gap: 2px; padding: 2px; background: #161f28; border: 1px solid var(--border); border-radius: 4px; }
.level-switch button {
  padding: 6px 18px; color: var(--text-muted); background: transparent; border: 0; border-radius: 3px; cursor: pointer;
  font: 800 11px/1 Inter, sans-serif; letter-spacing: .02em;
}
.level-switch button.active { color: var(--chrome); background: var(--text); }

/* --- The timeline is an analysis surface, not a browser progress bar ------
   Roughly triple the previous height, with a hit area spanning the whole band
   rather than a 3px line, so a precise seek in a 90-minute match is
   comfortable with a mouse. */
/* clip-controls (Start clip/End clip/Full video) added a 3rd item to this row
   without a reserved track — it was landing as an implicit auto column with no
   guaranteed space, squeezing (or on a narrow window, crowding out) the
   scrubber unpredictably. Named explicitly so it always gets real width.
   First column was also still 202px from when frame-steps held 4 buttons
   (-30s/-1f/+1f/+30s) — the two added ±10s buttons (4×58px jump-buttons +
   2×34px frame buttons + gaps ≈ 325px) were overflowing it silently, which is
   why +30s had quietly vanished off the edge. */
.timeline-row { height: 96px; grid-template-columns: 340px minmax(0, 1fr) auto; align-items: center; gap: 14px; }
.timeline-track { height: 62px; padding: 0; background: #12181e; border: 1px solid #263039; border-radius: 4px; }
#videoScrubber {
  position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; appearance: none; cursor: pointer;
  background: linear-gradient(to right, rgba(63,169,240,.20) var(--progress, 0%), transparent var(--progress, 0%));
}
#videoScrubber::-webkit-slider-runnable-track { height: 100%; background: transparent; }
#videoScrubber::-webkit-slider-thumb {
  width: 3px; height: 62px; margin-top: 0; appearance: none; border: 0; border-radius: 0;
  background: #fff; box-shadow: 0 0 0 1px rgba(0,0,0,.55), 0 0 9px rgba(255,255,255,.5);
}
.timeline-track::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 3px;
  background: linear-gradient(to right, var(--signal, var(--interaction)) var(--progress, 0%), #2c3841 var(--progress, 0%));
  pointer-events: none;
}

/* Marker hierarchy: filtered events sit quietly in their own lane, the things
   the analyst deliberately made (notes, freezes) read louder, and the current
   event is unmistakable. */
.event-markers { inset: 0 4px; }
.timeline-event { top: 8px; width: 2px; height: 18px; border-radius: 1px; opacity: .55; transition: opacity .12s ease, height .12s ease; }
.timeline-event:hover { opacity: 1; height: 24px; }
.timeline-event.touch-event-marker { background: var(--blue, var(--interaction)); }
.timeline-event.touch-event-marker.active {
  width: 4px; height: 46px; top: 8px; opacity: 1; background: #fff;
  box-shadow: 0 0 10px rgba(255,255,255,.65);
}
.timeline-event.freeze-event-marker { top: 34px; width: 8px; height: 7px; border-radius: 2px; opacity: .95; background: var(--signal, var(--interaction)); }
.timeline-event.note-event-marker { top: 44px; width: 8px; height: 7px; border-radius: 2px; opacity: .95; background: var(--annotation-yellow); }
.timeline-labels { margin-top: 6px; font-size: 11px; }

/* --- Match identity: the file becomes the match --------------------------- */
.match-identity { grid-column: 1 / -1; display: flex; align-items: baseline; gap: 10px; padding: 0 0 8px; flex-wrap: wrap; }
.match-identity strong { font: 800 17px/1 Inter, sans-serif; letter-spacing: .02em; }
.match-identity span { color: var(--text-muted); font: 600 11px/1 var(--font-body); }
.afc-matchid-field { margin-left: auto; display: flex; align-items: center; gap: 6px; }
.afc-matchid-field span { color: var(--text-muted); font: 600 10px/1 var(--font-body); text-transform: uppercase; letter-spacing: .05em; }
.afc-matchid-field input { width: 92px; background: var(--control); border: 1px solid var(--border); color: var(--text); font: 600 12px/1 var(--font-mono, monospace); padding: 5px 7px; }
.afc-matchid-field input:focus { outline: 1px solid var(--interaction); }

.inspector-tabs button b {
  margin-left: 5px; padding: 1px 5px; border-radius: 8px;
  color: var(--chrome); background: var(--text-muted); font: 600 11px/1.4 var(--font-body);
}
.inspector-tabs button.active b { background: var(--signal, var(--interaction)); }

/* --- Stats: numbers that are doors back to the footage -------------------- */
.stats-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px; }
.stat-cell {
  display: flex; flex-direction: column; gap: 3px; padding: 11px 8px; cursor: pointer; text-align: left;
  color: inherit; background: rgba(127,140,152,.10); border: 1px solid rgba(127,140,152,.22); border-radius: 3px;
}
.stat-cell:hover { border-color: var(--signal, var(--interaction)); background: rgba(63,169,240,.12); }
.stat-cell strong { font: 800 20px/1 Inter, sans-serif; }
.stat-cell span { font: 600 11px/1.25 var(--font-body); opacity: .72; }
.stats-foot { margin: 9px 0 0; font: 600 12px/1.4 Inter, sans-serif; opacity: .62; }

/* --- Clip Library --------------------------------------------------------- */
.kept-clip { display: flex; align-items: center; gap: 10px; padding: 9px 10px; border-bottom: 1px solid rgba(127,140,152,.18); }
.kept-clip:hover { background: rgba(63,169,240,.09); }
.kept-clip-main { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; cursor: pointer; }
.kept-clip-main strong { font: 800 12px/1 Consolas, monospace; }
.kept-clip-main span { font: 600 11px/1.3 Inter, sans-serif; }
.kept-clip-main small { font: 500 12px/1.3 Inter, sans-serif; opacity: .62; }
.kept-clip-main em { font: 500 12px/1.35 Inter, sans-serif; opacity: .85; }
.kept-clip-jump {
  flex: 0 0 auto; width: 30px; height: 30px; cursor: pointer;
  color: inherit; background: rgba(127,140,152,.14); border: 1px solid rgba(127,140,152,.28); border-radius: 3px;
}
.kept-clip-jump:hover { color: var(--chrome); background: var(--signal, var(--interaction)); border-color: var(--signal, var(--interaction)); }

/* --- Laptop: protect the video and the timeline, collapse everything else -- */
@media (max-height: 900px) {
  .timeline-row { height: 82px; }
  .timeline-track { height: 52px; }
  #videoScrubber::-webkit-slider-thumb { height: 52px; }
  .timeline-event.touch-event-marker.active { height: 38px; }
  .timeline-event.freeze-event-marker { top: 28px; }
  .timeline-event.note-event-marker { top: 38px; }
}
@media (max-width: 1400px) {
  .workspace { grid-template-columns: 0 minmax(460px, 1fr) 366px; }
  body.annotate-mode .workspace { grid-template-columns: 80px minmax(460px, 1fr) 366px; }
  .stats-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 820px) {
  .workspace { grid-template-columns: 0 1fr; }
  body.annotate-mode .workspace { grid-template-columns: 76px 1fr; }
}

/* The topbar is a grid with an explicit column per child. Adding the Match/Season
   switch made a fourth child, which wrapped onto an implicit second row and landed
   on top of the stage toolbar — the Export button ended up underneath the Annotate
   button and stopped receiving clicks. Give the level switch its own column. */
.topbar { grid-template-columns: 230px minmax(160px, 1fr) auto auto; }
@media (max-width: 1400px) { .topbar { grid-template-columns: 190px minmax(120px, 1fr) auto auto; } }
@media (max-width: 1180px) { .topbar { grid-template-columns: 1fr auto auto; } .project-name { display: none; } }

/* The tab strip was wrapping to two rows once it carried four tabs plus Pop out,
   which read as two separate control groups. One row, always. */
.inspector-top { grid-template-columns: minmax(0, 1fr) auto; row-gap: 6px; }
.inspector-tabs { display: flex; flex-wrap: nowrap; gap: 2px; min-width: 0; }
.inspector-tabs button { flex: 1 1 0; min-width: 0; padding-left: 6px; padding-right: 6px; white-space: nowrap; font-size: 12px; letter-spacing: .06em; }
.popout-controls { flex: 0 0 auto; }

/* The event list is the point of the Events tab: it sits directly under the filter
   and the transport, with clip window / timing correction folded into a drawer
   underneath rather than pushing the list below the fold. */
.touch-list { max-height: min(46vh, 460px); overflow: auto; }
.analysis-settings { margin-top: 10px; }

/* Where a retained moment came from — a WhoScored event or a match note. Both are
   already merged by the long-form export; the Library just says which is which. */
.clip-source { padding: 1px 5px; border-radius: 2px; font: 800 11px/1.5 Consolas, monospace; font-style: normal; letter-spacing: .08em; vertical-align: 1px; }
.clip-source.event { color: var(--chrome); background: var(--blue, var(--interaction)); }
.clip-source.note { color: var(--chrome); background: var(--annotation-yellow); }

/* Day-two resume: the stage says what is waiting rather than "load a match". */
.empty-stage-resume {
  margin-top: 14px; padding: 11px 22px; cursor: pointer;
  color: var(--chrome); background: var(--signal, var(--interaction)); border: 0; border-radius: 3px;
  font: 800 12px/1 Inter, sans-serif; letter-spacing: .02em;
}
.empty-stage-resume:hover { filter: brightness(1.1); }

/* Cold open: the stage carries the primary call to action, not a small button
   tucked in the toolbar corner. Hidden the moment a video or a resume prompt
   takes over (JS toggles it). The empty-stage itself is pointer-events:none so
   marks stay clickable through it — the button opts back in. */
.empty-stage-load {
  margin-top: 20px; padding: 13px 26px; cursor: pointer; pointer-events: auto;
  display: inline-flex; align-items: center; gap: 9px;
  color: var(--chrome); background: var(--signal-chrome, var(--interaction)); border: 0; border-radius: 3px;
  font: 800 13px/1 Inter, sans-serif; letter-spacing: .02em;
}
.empty-stage-load span { font-size: 16px; font-weight: 400; }
.empty-stage-load:hover { filter: brightness(1.08); }
.empty-stage-load[hidden] { display: none; }

/* Resume screen only: a quiet way out of reopening the saved project. */
.empty-stage-new {
  margin-top: 12px; padding: 6px 10px; cursor: pointer; pointer-events: auto;
  color: var(--text-muted, #8d9aa5); background: transparent; border: 0;
  font: 600 12px/1 var(--font-body); letter-spacing: .01em;
  text-decoration: underline; text-underline-offset: 3px;
}
.empty-stage-new:hover { color: var(--text, #f2f5f7); }
.empty-stage-new[hidden] { display: none; }

/* --- Make the stage fit the window instead of guessing at it ----------------
   .canvas-frame was sized from a hard-coded "everything else is 232px tall"
   constant. Growing the timeline invalidated that number, and the whole column
   ended up ~5px inside the viewport on a good day and clipped on a real one —
   the timeline getting cut off at the bottom of the window.

   Size it from the space actually left over instead: the bay flexes, the frame
   fills whatever height remains at 16:9, and the video-dock keeps its own
   height. No constant to fall out of date the next time a row changes. */
.stage-section { overflow: hidden; }
/* container-type:size makes cqw/cqh resolve against THIS box's own width and
   height, so the frame below can pick whichever dimension is actually tight —
   height alone left free horizontal space unused (e.g. after popping the
   controls panel out to a second window widens this column, but does nothing
   taller), so the video never grew even though there was visibly more room. */
.canvas-bay { flex: 1 1 auto; min-height: 0; display: flex; align-items: center; justify-content: center; container-type: size; }
.canvas-frame,
.video-mode .canvas-frame {
  aspect-ratio: 16 / 9;
  width: min(100cqw, 100cqh * 16 / 9);
  height: min(100cqh, 100cqw * 9 / 16);
}
/* The dock holds the transport strip plus the taller timeline; give it the room
   it actually needs so it can never be squeezed into the video's space. */
.video-dock { flex: 0 0 auto; }

/* Speed controls + the ±10s buttons pushed the transport strip past the point
   overflow-x: auto (the original design for "too many buttons") was tolerable —
   scrolling a busy toolbar sideways to find Preview/Screenshot is worse than the
   row just being two lines. video-dock is already auto-height (above), so
   wrapping here costs nothing structurally; only the button cluster needs it,
   not the whole 3/4-column strip, so the status text and timecode never
   scroll off with it. */
.analysis-strip { overflow-x: visible; row-gap: 6px; }
.analysis-main-actions { flex-wrap: wrap; row-gap: 6px; }

/* Momentum sits behind the markers on the same x-axis, so a swing in the band is
   directly above the events that caused it. Off by default — it is context, not
   something to compete with the markers you actually click. */
.momentum-layer { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; z-index: 0; }
/* Order matters: the band is background, the scrubber takes clicks that land in
   the gaps, and the markers sit on top so they stay clickable. Putting the
   scrubber above the markers silently swallowed every marker click. */
.timeline-track #videoScrubber { z-index: 1; }
.timeline-track .event-markers { z-index: 2; }
.momentum-toggle {
  margin-left: 10px; padding: 2px 7px; cursor: pointer;
  color: var(--text-muted); background: transparent; border: 1px solid var(--border-strong); border-radius: 2px;
  font: 600 11px/1.5 var(--font-body);
}
.momentum-toggle:hover { color: var(--text); border-color: #55697a; }
.momentum-toggle.active { color: var(--chrome); background: var(--signal, var(--interaction)); border-color: var(--signal, var(--interaction)); }
.timeline-labels { align-items: center; }

/* Play straight through: the difference between reviewing a filtered list and
   pressing play forty-three times. */
.autoplay-row { display: flex; align-items: center; gap: 9px; padding: 10px 0 2px; cursor: pointer; font: 600 11px/1.35 Inter, sans-serif; }
.autoplay-row input { width: 15px; height: 15px; flex: 0 0 auto; }

/* Escape hatch from an event's clip window, next to the transport where playback
   lives. Only present while there is a window to escape from. */
.back-to-match {
  height: 38px; padding: 0 15px; cursor: pointer; white-space: nowrap;
  color: var(--text); background: var(--control); border: 1px solid var(--border-strong); border-radius: 3px;
  font: 700 11px/1 Inter, sans-serif;
}
.back-to-match:hover { color: #fff; border-color: var(--signal, var(--interaction)); background: var(--control-hover); }

/* Preview: watch the clip exactly as it will export, without recording it. */
.preview-clip { height: 38px; padding: 0 15px; cursor: pointer; color: var(--text); background: var(--control); border: 1px solid var(--border-strong); border-radius: 3px; font: 700 11px/1 Inter, sans-serif; }
.preview-clip:hover { color: #fff; border-color: var(--signal, var(--interaction)); }
.preview-clip.active { color: var(--chrome); background: var(--signal, var(--interaction)); border-color: var(--signal, var(--interaction)); }
.preview-badge {
  position: absolute; top: 14px; left: 14px; display: flex; align-items: baseline; gap: 8px;
  padding: 7px 12px; border-radius: 3px; color: var(--chrome); background: var(--signal, var(--interaction));
  font: 800 12px/1 Inter, sans-serif; letter-spacing: .02em; z-index: 4;
}
.preview-badge strong { font: 600 11px/1 var(--font-body); text-transform: none; opacity: .8; }
body.previewing .canvas-frame { box-shadow: 0 16px 45px rgba(0,0,0,.52), 0 0 0 2px var(--signal, var(--interaction)); }

/* One export dialog: the settings every export path used to hard-code. */
.export-dialog { position: fixed; inset: 0; z-index: 60; display: flex; align-items: center; justify-content: center; background: rgba(4, 8, 12, .72); }
.export-dialog[hidden] { display: none; }
.export-dialog-panel { width: min(460px, calc(100vw - 40px)); padding: 26px 26px 22px; color: var(--text); background: #141a20; border: 1px solid #2c3a46; border-radius: 5px; box-shadow: 0 30px 80px rgba(0,0,0,.6); }
.export-dialog-panel h2 { margin: 0 0 6px; font: 800 20px/1 Inter, sans-serif; letter-spacing: .02em; }
.export-range { margin: 0 0 20px; color: #8fa0ad; font: 600 12px/1.5 var(--font-body); }
.export-field { display: block; margin-bottom: 14px; }
.export-field span { display: block; margin-bottom: 5px; color: var(--text-muted); font: 600 11px/1 var(--font-body); }
.export-field select { width: 100%; height: 40px; padding: 0 10px; color: var(--text); background: var(--control); border: 1px solid #35434f; border-radius: 3px; font: 600 13px/1 Inter, sans-serif; }
.export-note { margin: 16px 0 20px; color: #7d8b96; font: 500 11px/1.45 Inter, sans-serif; }
.export-dialog-actions { display: flex; gap: 10px; justify-content: flex-end; }
.export-dialog-actions .quiet-button { height: 40px; padding: 0 18px; }
.export-dialog-actions .export-button { height: 40px; padding: 0 20px; }

/* The dialog's buttons were falling back to native UA chrome: .quiet-button and
   .export-button are only ever defined under .header-actions, so inside the modal
   they matched nothing and rendered as grey system buttons on the dark panel. */
.export-dialog-actions .quiet-button {
  height: 40px; padding: 0 18px; cursor: pointer; border-radius: 3px;
  color: #cfd8de; background: var(--control); border: 1px solid #35434f; font: 700 12px/1 Inter, sans-serif;
}
.export-dialog-actions .quiet-button:hover { color: #fff; border-color: #4b5c6a; }
.export-dialog-actions .export-button {
  display: flex; align-items: center; gap: 9px; height: 40px; padding: 0 20px; cursor: pointer;
  color: var(--ink, var(--panel)); background: #fff; border: 1px solid #fff; border-radius: 3px;
  font: 800 12px/1 Inter, sans-serif;
}
.export-dialog-actions .export-button:hover { border-color: #d8dde0; background: #f2f4f5; }

/* ===========================================================================
   Visual refresh (Sep 2026) — overrides appended last so they win the cascade.
   Brief: footage is the ground; blue = interaction, coral = record; display
   face for the brand only; monospace for timecodes only; sentence-case labels;
   quiet chrome. */

/* Display face (Bebas, a caps-only design) had leaked onto minor labels and the
   kickoff readout — that's why "Tools" and "not set" rendered ALL CAPS. */
.rail-label { font-family: var(--font-body); font-weight: 600; letter-spacing: .04em; color: var(--text-muted); }
.kickoff-inline button strong { font-family: var(--font-mono); font-variant-numeric: tabular-nums; letter-spacing: 0; }

/* Section labels read as quiet metadata, not shouted headers. */
.panel-heading span, .label-row, .label-row > span,
.comment-composer label, .style-row > span, .style-row > label,
.drawer summary span, .event-guide {
  font-family: var(--font-body); font-weight: 600; letter-spacing: .02em; text-transform: none;
}

/* The one interaction blue everywhere it means "selected / primary". */
.inspector-tabs button.active { background: transparent; }
.inspector-tabs button.active::after { background: var(--interaction); }
.tool.active { border-color: transparent; background: var(--control); box-shadow: inset 3px 0 var(--interaction); }
.level-switch button.active { color: var(--chrome); background: var(--text-secondary); }

/* Quiet header actions: no resting border, surface appears on hover / focus. */
.header-actions .quiet-button,
.review-window-button {
  border-color: transparent; background: transparent; color: var(--text-secondary);
}
.header-actions .quiet-button:hover,
.review-window-button:hover { background: var(--control); color: var(--text); }
.header-actions .icon-button { border-color: transparent; background: transparent; }
.header-actions .icon-button:hover { background: var(--control); }

/* Transport: consistent quiet buttons, coarse-seek group visually softer. */
.frame-steps .jump-button { color: var(--text-muted); }
.finish-analysis:not(:disabled) { border-color: var(--interaction); color: var(--interaction-hover); }

/* Tabs are functional navigation, not headings — body face, sentence case
   already comes from the markup. One active treatment: the blue underline. */
.inspector-tabs button { font-family: var(--font-body); font-weight: 650; letter-spacing: .01em; }

/* Review sits with the other quiet header actions. */
.header-actions .review-window-button { border-color: transparent; background: transparent; color: var(--text-secondary); }
.header-actions .review-window-button:hover { background: var(--control); color: var(--text); }

/* Header clusters: history icons | project file (Open/Save) | Review | Export.
   A hairline separates the groups so the loose text buttons read as one unit. */
.hdr-group { display: flex; align-items: center; gap: 6px; }
.hdr-divider { width: 1px; align-self: stretch; margin: 5px 3px; background: var(--border); }
@media (max-width: 1080px) { .hdr-divider { display: none; } }

/* ===========================================================================
   Transport rebuild (Sep 2026) — one video console, three semantic zones:
   playback | timeline | clip actions. Timeline takes the width. Appended last
   so it wins over .analysis-strip / .timeline-row / .frame-steps. */
.video-dock { flex: 0 0 auto; padding: 11px 16px 13px; background: var(--panel); border-top: 1px solid var(--border); }
/* Timeline spans the full width on its own row; the button zones sit beneath,
   playback left, clip right. One integrated console, not stacked button rows. */
.transport {
  display: grid;
  grid-template-columns: auto 1fr;
  grid-template-areas: "timeline timeline" "playback clip";
  gap: 9px 20px;
  align-items: center;
}
.tp-timeline { grid-area: timeline; }
.tp-playback { grid-area: playback; }
.tp-clip     { grid-area: clip; justify-self: end; }
.tp-zone { display: flex; align-items: center; gap: 6px; }

/* zone 1 · playback */
.tp-playback { flex: none; gap: 8px; }
.tp-frame { display: inline-flex; border: 1px solid var(--border-strong); border-radius: 4px; overflow: hidden; }
.tp-frame button { height: 34px; padding: 0 10px; border: 0; border-left: 1px solid var(--border-strong); color: var(--text-secondary); background: var(--control); font: 500 12px/1 var(--font-mono); }
.tp-frame button:first-child { border-left: 0; }
.tp-frame button:hover { color: var(--text); background: var(--control-hover); }

/* zone 2 · timeline (widest) */
.tp-timeline { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.tp-time { display: flex; align-items: baseline; gap: 10px; font: 500 13px/1 var(--font-mono); font-variant-numeric: tabular-nums; color: var(--text); }
.tp-time-sep, .tp-time #durationTimecode { color: var(--text-muted); }
.tp-clipreadout { font: 400 11px/1 var(--font-body); color: var(--text-muted); }
.tp-timeline .kickoff-inline { margin-left: auto; display: flex; gap: 6px; }
.tp-timeline .timeline-wrap { width: 100%; }
.tp-below { display: flex; align-items: center; gap: 12px; }
.tp-seek { display: inline-flex; flex: none; border: 1px solid var(--border); border-radius: 4px; overflow: hidden; }
.tp-seek button { height: 26px; padding: 0 9px; border: 0; border-left: 1px solid var(--border); color: var(--text-muted); background: transparent; font: 500 11px/1 var(--font-mono); }
.tp-seek button:first-child { border-left: 0; }
.tp-seek button:hover { color: var(--text-secondary); background: var(--control); }
.tp-kbdhint { margin-left: auto; font: 400 11px/1 var(--font-body); color: var(--text-muted); white-space: nowrap; }

/* zone 3 · clip actions */
.tp-clip { display: flex; align-items: center; gap: 14px; min-width: 0; }
.tp-clip-status { text-align: right; max-width: 150px; }
.tp-clip-status strong { display: block; font: 650 12px/1.35 var(--font-body); color: var(--text); }
.tp-clip-status #analysisHint { font: 400 11px/1.35 var(--font-body); color: var(--text-muted); }
.tp-clip-range, .tp-clip-actions { display: flex; gap: 6px; flex-wrap: wrap; }
.tp-clip-range button { height: 30px; padding: 0 11px; border: 1px solid var(--border); border-radius: 4px; color: var(--text-muted); background: transparent; font: 600 12px/1 var(--font-body); }
.tp-clip-range button:hover { color: var(--text); border-color: var(--border-strong); background: var(--control); }
.tp-clip-actions button { height: 32px; }
.tp-clip-actions .preview-clip, .tp-clip-actions .screenshot-analysis { padding: 0 10px; font-size: 11px; }

/* Start analysis clip: coral only while it IS recording; a quiet button at rest. */
.tp-clip-actions .start-analysis { color: var(--record); border: 1px solid var(--border-strong); background: var(--control); }
.tp-clip-actions .start-analysis .record-dot { background: var(--record); border-color: var(--record); }
.tp-clip-actions .start-analysis:hover:not(:disabled) { border-color: var(--record); background: var(--control-hover); }
.analysis-active .tp-clip-actions .start-analysis { color: #fff; border-color: var(--signal-dark); background: var(--record); }
/* Finish & export: the "do it" action once a clip is valid. */
.finish-analysis:not(:disabled) { color: var(--chrome); border-color: var(--interaction); background: var(--interaction); }
.finish-analysis:not(:disabled):hover { background: var(--interaction-hover); border-color: var(--interaction-hover); }

.back-to-match, .condensed-toggle { align-self: flex-end; }

@media (max-width: 1240px) {
  .transport { grid-template-columns: 1fr; gap: 12px; }
  .tp-clip { align-items: stretch; }
  .tp-clip-status { text-align: left; }
  .tp-clip-range, .tp-clip-actions { flex-wrap: wrap; }
}

/* The transport lives in the centre column, which is far narrower than the
   viewport once the annotate rail and inspector are open. Stack it on its OWN
   width, not the window's, so playback + clip never collide at ~1280 desktop. */
.video-dock { container-type: inline-size; container-name: dock; }
@container dock (max-width: 780px) {
  .transport { grid-template-columns: 1fr; grid-template-areas: "timeline" "playback" "clip"; gap: 12px; }
  .tp-clip { justify-self: stretch; align-items: flex-start; flex-wrap: wrap; }
  .tp-clip-status { text-align: left; }
  .tp-clip-range, .tp-clip-actions { flex-wrap: wrap; }
}

/* Transport polish: no wrapped labels; kickoff sits with the seek row; the
   play control has real presence. */
.tp-clip button, .tp-frame button, .tp-seek button, .tp-playback .speed-btn { white-space: nowrap; }
.tp-clip-status { max-width: none; white-space: nowrap; }
.tp-clip-status strong { white-space: normal; }
.tp-time .kickoff-inline { display: none; }          /* moved below, by the seek row */
.tp-below .kickoff-inline { display: flex; gap: 6px; margin-left: 4px; }
.tp-below .kickoff-inline button { height: 26px; min-width: 0; padding: 0 8px; display: flex; align-items: center; gap: 5px; border: 1px solid var(--border); border-radius: 4px; color: var(--text-muted); background: transparent; }
.tp-below .kickoff-inline button span { font: 600 10px/1 var(--font-body); letter-spacing: .04em; }
.tp-below .kickoff-inline button strong { font: 500 11px/1 var(--font-mono); }
.tp-below .kickoff-inline button.is-set { border-color: var(--interaction); color: var(--text-secondary); background: transparent; }
.play-button { width: 44px; height: 34px; }
.play-button .ico { width: 17px; height: 17px; }
.tp-kbdhint { font-size: 10px; }
/* Keep the whole playback zone one height — play, speed toggle, frame steps. */
.speed-controls, .tp-frame { height: 34px; }
.speed-btn { display: inline-flex; align-items: center; }

/* The clip row was overflowing its cell and bleeding over playback. Trim it:
   one compact status word, no secondary hint, tighter buttons. It also has a lot
   of buttons (range + actions + back/condensed) — let them wrap within the cell
   instead of overflowing left across the playback zone. */
.tp-clip { gap: 10px 12px; overflow: hidden; flex-wrap: wrap; justify-content: flex-end; row-gap: 8px; }
.tp-clip-status { max-width: none; }
.tp-clip-status strong { font: 600 11px/1.2 var(--font-body); white-space: nowrap; }
.tp-clip-status #analysisHint { display: none; }
.tp-clip-range button { height: 30px; padding: 0 10px; font-size: 11px; }
.tp-clip-actions button { height: 32px; padding: 0 12px; font-size: 12px; }
.tp-clip-actions .preview-clip, .tp-clip-actions .screenshot-analysis { padding: 0 10px; font-size: 11px; }
.tp-clip-actions .start-analysis { padding: 0 12px; gap: 6px; }
@media (max-width: 1480px) {
  .tp-clip-status { display: none; }        /* the readout up top carries it */
}

/* Play control: a quiet bordered control that matches the speed toggle and
   frame steps beside it — just a blue triangle, not a filled slab. */
.play-button { color: var(--interaction); background: var(--control); border: 1px solid var(--border-strong); border-radius: 4px; }
.play-button:hover { color: var(--interaction-hover); background: var(--control-hover); border-color: var(--interaction); }
.play-button:active { background: var(--control); }

/* ===========================================================================
   Inspector progressive disclosure (Sep 2026, brief step 6).
   No mark selected → the frame instruction, the default colour + weight, and
   the marks list. Select a mark → the comment field, copy/paste/duplicate/
   delete, freeze controls and mark-specific settings appear. */
#annotateView .comment-composer,
#annotateView .selected-controls,
#annotateView .hold-section { display: none; }
body.has-selection #annotateView .comment-composer,
body.has-selection #annotateView .selected-controls,
body.has-selection #annotateView .hold-section { display: block; }
body.has-selection #annotateView .selected-actions { display: flex; }
body.has-selection #annotateView .pause-prompt { display: none; }

/* Delete stays visually apart from the ordinary edit actions. */
#annotateView .selected-actions { gap: 6px; }
#annotateView .selected-actions .danger { margin-left: auto; }

/* Swatches: bigger targets, clearer selected state (brief). */
#annotateView .swatch { width: 26px; height: 26px; }
#annotateView .style-row { align-items: center; gap: 12px; }

/* Shortcut hints live in the tooltip (title="Select (V)"), not as tiny corner
   letters on every tool. */
.tool kbd { display: none; }

/* Final review — cut one treatment that carries no meaning: the hollow bordered
   box around the scrubber, plus the second horizontal line. The box framed an
   empty input; the track had two rules (a plain rail at bottom AND the progress
   fill) drawing parallel lines. Keep ONE line — the progress track — and lift it
   to centre so it reads as the scrubber itself. Height stays for the marker lanes. */
.tp-timeline .timeline-track { height: 44px; background: transparent; border: 0; border-radius: 0; }
.tp-timeline .timeline-track::after {
  top: 50%; bottom: auto; transform: translateY(-50%); height: 2px; border-radius: 1px;
}
.tp-timeline #videoScrubber::-webkit-slider-thumb { height: 44px; }

/* ===========================================================================
   Right-panel void (brief-flagged). On cold open the inspector holds one short
   card and then ~500px of flat --panel fill that read as "unfinished". Drop the
   panel base to --chrome (same as the workspace surround and the drawer bodies)
   so the empty space below the last card is clearly just chrome, not a truncated
   surface. Drawer summary bars stay on --panel and now read as section headers
   sitting on the dark, which is the intent. A quiet footer anchors the bottom
   and doubles as the privacy line Gavin wants to lead with. */
.inspector { background: var(--chrome); display: flex; flex-direction: column; }
.inspector-top { flex: 0 0 auto; }
.inspector-view:not([hidden]) { flex: 1 0 auto; }
.inspector-foot {
  flex: 0 0 auto; padding: 12px 16px; border-top: 1px solid var(--border);
  font: 400 11px/1.4 var(--font-body); color: var(--text-muted);
}
.inspector-foot strong { color: var(--text-secondary); font-weight: 600; }
.inspector-foot .dot { margin: 0 6px; opacity: .5; }
.inspector-foot a { color: var(--interaction); text-decoration: none; font-weight: 600; }
.inspector-foot a:hover { color: var(--interaction-hover); }
/* The companion tools were unreachable from the app — you had to know the URL. */
.foot-privacy { margin-top: 5px; }

/* ===========================================================================
   Reel export — the whole filtered playlist as one continuous video with a
   title card. Sits under the touch list, in the review workspace. */
.reel-export { margin-top: 10px; padding: 11px 12px; background: var(--panel); border: 1px solid var(--border); border-radius: 4px; }
.reel-export[hidden] { display: none; }
.reel-row { display: flex; align-items: center; gap: 10px; }
.reel-row .wide-control { flex: 1; margin: 0; }
.reel-len { flex: none; display: inline-flex; align-items: center; gap: 5px; font: 600 11px/1 var(--font-body); color: var(--text-muted); white-space: nowrap; }
.reel-len input { width: 46px; height: 30px; padding: 0 6px; text-align: center; color: var(--text); background: var(--control); border: 1px solid var(--border-strong); border-radius: 4px; font: 600 12px/1 var(--font-mono); }
.reel-accent { display: flex; align-items: center; gap: 8px; margin-top: 9px; }
.reel-accent > span { font: 600 11px/1 var(--font-body); color: var(--text-muted); margin-right: 2px; }
#reelStatus { margin-top: 8px; }
.reel-export.is-working { border-color: var(--interaction); }
#exportReelBtn.is-cancel { color: #fff; border-color: var(--record); background: var(--record); }
#exportReelBtn.is-cancel:hover { background: var(--record-hover); border-color: var(--record-hover); }
#exportQueueReelBtn.is-cancel { color: #fff; border-color: var(--record); background: var(--record); }
#exportQueueReelBtn.is-cancel:hover { background: var(--record-hover); border-color: var(--record-hover); }

/* Keep the review decision next to navigation; export options follow the list. */
.article-decision { margin-top: 8px; padding: 9px 10px 10px; background: var(--panel); border: 1px solid var(--border-strong); border-radius: 4px; }
.article-decision .article-queue-head { align-items: center; font: 650 12px/1.25 var(--font-body); }
.article-decision .article-queue-head > span { color: var(--text); }
.article-decision .decision-controls { margin-top: 8px; }
.article-decision .decision-controls button { min-height: 36px; }
.article-decision #keepTouchBtn.active { color: #071810; border-color: #5fca93; background: #5fca93; }
.article-decision #rejectTouchBtn.active { color: #fff; border-color: #c75555; background: #a94040; }
.article-decision .decision-controls button:focus-visible, .reel-export summary:focus-visible { outline: 2px solid var(--interaction); outline-offset: 2px; }
.article-output { margin-top: 10px; }
.article-output > label { color: var(--text-muted); font: 650 12px/1.3 var(--font-body); }
.reel-export summary { cursor: pointer; color: var(--text); font: 700 12px/1.35 var(--font-body); }
.reel-export summary small { display: block; margin: 2px 0 0 17px; color: var(--text-muted); font: 500 11px/1.3 var(--font-body); }
.reel-export-body { margin-top: 12px; }

/* A note is the primary review item: give its observation a line of its own. */
.match-note-row { display: grid; grid-template-columns: 72px minmax(0, 1fr); align-items: start; gap: 8px 9px; padding: 11px; }
.match-note-row > [data-action="jump"] { grid-column: 1; padding-top: 2px; }
.match-note-text { grid-column: 2; min-width: 0; font-size: 13px; line-height: 1.4; text-align: left; white-space: normal; }
.match-note-actions { grid-column: 1 / -1; display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.match-note-actions button { min-height: 30px; }
.match-note-actions [data-action="clip"] { flex: 1 1 70px; color: var(--text); border-color: var(--interaction); }
.match-note-actions [data-action="queue"].active { color: #071018; border-color: var(--interaction); background: var(--interaction); }
.match-note-actions [data-action="delete"] { padding-inline: 7px; }
#queueAllShownNotesBtn[hidden] { display: none; }

/* A disabled export button has to LOOK disabled — otherwise clicking a dead
   button just does nothing with no explanation (the old long-form-pack trap). */
.article-pack-button:disabled, .wide-control:disabled { opacity: .4; cursor: not-allowed; }

/* Season review is a separate workspace. Its own player never changes the
   current Match project until the analyst explicitly chooses Open in Match. */
.season-stage[hidden], .season-screen-empty[hidden], #seasonQuerySection[hidden] { display: none !important; }
body.season-level .stage-toolbar,
body.season-level .canvas-bay,
body.season-level .video-dock,
body.season-level .tool-rail,
body.season-level .project-name,
body.season-level .header-actions,
body.season-level .inspector-tabs [data-inspector-tab]:not(#seasonTab) { display: none !important; }
body.season-level .workspace { grid-template-columns: minmax(520px, 1fr) 430px; }
body.season-level .topbar { grid-template-columns: 1fr auto; }
body.season-level .level-switch { grid-column: 2; }
body.season-level .stage-section { grid-column: 1; }
body.season-level .inspector { grid-column: 2; }
#seasonView:not([hidden]) { display: flex; flex-direction: column; }
#seasonView .moment-panel { order: 0; }
#seasonView #seasonQuerySection { order: 1; }
#seasonView #seasonAttentionSection,
#seasonView #seasonQueueSection,
#seasonView #seasonCalibratedSection { order: 2; }
#seasonView .layer-item { display: flex; justify-content: space-between; gap: 12px; min-height: 36px; padding: 7px 10px; line-height: 1.3; }
#seasonView .layer-item > span:first-child { min-width: 0; overflow-wrap: anywhere; }
#seasonView .layer-index { flex: none; }
.season-stage { flex: 1; min-height: 0; display: flex; flex-direction: column; background: #050607; }
.season-screen { flex: 1; min-height: 0; position: relative; display: grid; place-items: center; padding: 16px; }
.season-screen video { display: block; max-width: 100%; max-height: 100%; width: auto; height: auto; aspect-ratio: 16 / 9; background: #050607; }
.season-screen-empty { position: absolute; inset: 16px; display: grid; place-items: center; color: var(--text-muted); border: 1px dashed var(--border-strong); font: 600 15px/1.4 var(--font-body); text-align: center; }
.season-player-bar { flex: none; display: grid; gap: 11px; padding: 12px 18px; color: var(--text); background: var(--panel); border-top: 1px solid var(--border); }
.season-player-bar > div:first-child { display: grid; gap: 4px; }
.season-player-bar strong { font: 700 14px/1.25 var(--font-body); }
.season-player-bar span { color: var(--text-muted); font: 500 12px/1.35 var(--font-body); }
.season-player-actions { display: flex; flex-wrap: wrap; gap: 7px; }
.season-player-actions button { min-height: 36px; padding: 0 12px; color: var(--text); background: var(--control); border: 1px solid var(--border-strong); border-radius: 4px; font: 650 12px/1 var(--font-body); cursor: pointer; }
.season-player-actions button:hover { border-color: var(--interaction); }
.season-player-actions button:disabled { opacity: .4; cursor: not-allowed; }
#seasonKeepBtn:not(:disabled) { color: var(--interaction); }
#seasonOpenMatchBtn:not(:disabled) { color: #08131a; background: var(--interaction); border-color: var(--interaction); }
.season-filter-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.season-window-grid { margin-top: 8px; }
.season-window-grid input { width: 100%; min-height: 36px; padding: 0 9px; color: var(--text); background: var(--control); border: 1px solid var(--border-strong); border-radius: 4px; font: 650 12px/1 var(--font-mono); }
.season-results { display: grid; gap: 5px; margin-top: 10px; max-height: 320px; overflow-y: auto; }
.season-kept-results { display: grid; gap: 5px; margin-top: 8px; max-height: 160px; overflow-y: auto; }
.season-result { width: 100%; display: grid; gap: 5px; padding: 10px 11px; color: var(--text); background: var(--control); border: 1px solid var(--border); border-radius: 4px; text-align: left; cursor: pointer; }
.season-result:hover, .season-result.active { border-color: var(--interaction); background: var(--control-hover); }
.season-result > span { display: flex; align-items: baseline; gap: 10px; }
.season-result strong { flex: none; color: var(--interaction); font: 700 12px/1 var(--font-mono); }
.season-result b { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font: 650 13px/1.2 var(--font-body); }
.season-result em { margin-left: auto; color: #6ad39a; font: 700 10px/1 var(--font-mono); font-style: normal; }
.season-result small { color: var(--text-muted); font: 500 11px/1.3 var(--font-body); }
.season-no-results { margin: 8px 0 12px; color: var(--text-muted); font: 500 12px/1.4 var(--font-body); }
@media (max-width: 900px) {
  body.season-level .workspace { display: flex; flex-direction: column; overflow: auto; }
  body.season-level .stage-section { min-height: 360px; }
  body.season-level .inspector { min-height: 430px; }
}
