/*
  Lights Out Events — shared design system.
  F1-inspired: dark carbon fiber, LED timing digits, glass panels, red accent.
  Every page (home, register, leaderboard, admin tools) builds on this file
  plus design-tokens.css (loaded first — see base.html). Nothing below
  should hardcode a color/size/radius/shadow that has a token; see
  DESIGN_SYSTEM.md and CLAUDE_UI_RULES.md.
*/

* {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  padding: 0;
  background: var(--f1-bg);
  color: var(--f1-text);
  font-family: var(--f1-font);
  min-height: 100vh;
}

/* Carbon fiber texture — pure CSS, no image asset needed. The internal
   gradient stops are a deliberate decorative micro-palette (not tokenized)
   — forcing them onto --f1-black/--f1-black-2 would flatten the texture. */
.carbon-bg {
  position: fixed;
  inset: 0;
  z-index: -2;
  background-color: var(--f1-black);
  background-image:
    linear-gradient(27deg, #0d0d11 5px, transparent 5px),
    linear-gradient(207deg, #0d0d11 5px, transparent 5px),
    linear-gradient(27deg, #0d0d11 5px, transparent 5px),
    linear-gradient(207deg, #0d0d11 5px, transparent 5px),
    linear-gradient(90deg, #16161c 10px, transparent 10px),
    linear-gradient(#161b1c 25%, #0a0a0d 25%, #0a0a0d 50%, #161616 50%, #161616 75%, #0a0a0d 75%, #0a0a0d);
  background-size: 20px 20px;
}

.vignette {
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background: radial-gradient(ellipse at center, transparent 40%, rgba(0, 0, 0, 0.65) 100%);
}

/* ── Cards / panels ───────────────────────────────────────────────────
   .card-f1 (alias: .glass-panel, kept for the many existing templates
   that already use it) auto-adapts to whichever theme is active via the
   semantic tokens. .card-glass / .card-flat force one look regardless of
   ambient theme, for the rare case a page needs to mix them. */
.card-f1,
.glass-panel {
  background: var(--f1-panel);
  border: 1px solid var(--f1-border);
  border-radius: var(--f1-radius-panel);
  backdrop-filter: blur(var(--f1-blur));
  -webkit-backdrop-filter: blur(var(--f1-blur));
  box-shadow: var(--f1-shadow-lg);
}

.card-f1.card-glass {
  background: var(--f1-panel-glass);
  border-color: var(--f1-border-glass);
  border-radius: var(--f1-radius-lg);
  backdrop-filter: blur(18px);
  -webkit-backdrop-filter: blur(18px);
}

.card-f1.card-flat {
  background: var(--f1-panel-solid);
  border-color: var(--f1-border-solid);
  border-radius: var(--f1-radius-md);
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  box-shadow: var(--f1-shadow-md);
}

/* LED-style monospace timing digits */
.led-digits {
  font-family: var(--f1-mono);
  letter-spacing: 0.03em;
  font-variant-numeric: tabular-nums;
}

.text-f1-red {
  color: var(--f1-red);
}

.accent-underline {
  position: relative;
  display: inline-block;
}
.accent-underline::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -8px;
  height: 3px;
  background: linear-gradient(90deg, var(--f1-red), transparent);
}

::selection {
  background: var(--f1-red);
  color: #fff;
}

::-webkit-scrollbar {
  width: 10px;
  height: 10px;
}
::-webkit-scrollbar-track {
  background: var(--f1-black-2);
}
::-webkit-scrollbar-thumb {
  background: var(--f1-border-solid-bright);
  border-radius: var(--f1-radius-sm);
}
::-webkit-scrollbar-thumb:hover {
  background: var(--f1-red);
}

@keyframes pulse-glow {
  0%, 100% { box-shadow: 0 0 12px var(--f1-red-glow); }
  50% { box-shadow: 0 0 28px var(--f1-red-glow); }
}

.status-live {
  display: inline-flex;
  align-items: center;
  gap: var(--f1-space-2);
  color: var(--f1-green);
  font-weight: var(--f1-weight-bold);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  font-size: var(--f1-text-sm);
}
.status-live::before {
  content: "";
  width: 8px;
  height: 8px;
  border-radius: var(--f1-radius-full);
  background: var(--f1-green);
  animation: pulse-glow 1.4s infinite;
}

/* ═══════════════════════════════════════════════════════════════════
   Buttons — ONE base class, opt into variants. Base = neutral bordered
   button (works on both themes automatically). Add --primary for the
   red-gradient CTA look, --danger for destructive actions, --ghost for
   a border-less minimal button. --sm/--lg/--block resize.
   ═══════════════════════════════════════════════════════════════════ */
.btn-f1 {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--f1-space-2);
  background: var(--f1-surface);
  border: 1px solid var(--f1-border);
  color: var(--f1-text);
  border-radius: var(--f1-radius-sm);
  padding: var(--f1-space-3) var(--f1-space-4);
  font-family: var(--f1-font);
  font-weight: var(--f1-weight-bold);
  letter-spacing: 0.02em;
  font-size: var(--f1-text-md);
  text-decoration: none;
  cursor: pointer;
  transition: transform 0.15s ease, box-shadow 0.15s ease, background 0.15s ease, border-color 0.15s ease;
}
.btn-f1:hover:not(:disabled) {
  transform: translateY(-1px);
  background: var(--f1-surface-strong);
  border-color: var(--f1-border-solid-bright);
}
.btn-f1:active:not(:disabled) {
  transform: translateY(0);
}
.btn-f1:disabled {
  opacity: 0.5;
  cursor: not-allowed;
  transform: none;
}

.btn-f1--primary {
  background: linear-gradient(135deg, var(--f1-red), var(--f1-red-dark));
  border-color: transparent;
  color: #fff;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  box-shadow: var(--f1-shadow-glow);
}
.btn-f1--primary:hover:not(:disabled) {
  background: linear-gradient(135deg, #ff1a12, var(--f1-red));
  border-color: transparent;
  box-shadow: 0 8px 28px var(--f1-red-glow);
  color: #fff;
}

.btn-f1--danger {
  background: transparent;
  border-color: rgba(255, 82, 82, 0.4);
  color: var(--f1-danger);
}
.btn-f1--danger:hover:not(:disabled) {
  background: rgba(255, 82, 82, 0.1);
  border-color: rgba(255, 82, 82, 0.4);
}

.btn-f1--ghost {
  background: transparent;
  border-color: transparent;
}
.btn-f1--ghost:hover:not(:disabled) {
  background: var(--f1-surface);
  border-color: transparent;
}

.btn-f1--sm {
  padding: var(--f1-space-2) var(--f1-space-3);
  font-size: var(--f1-text-sm);
}
.btn-f1--lg {
  padding: var(--f1-space-4) var(--f1-space-6);
  font-size: var(--f1-text-lg);
}
.btn-f1--block {
  width: 100%;
}

/* ═══════════════════════════════════════════════════════════════════
   Inputs & selects — ONE base class, theme-aware automatically.
   ═══════════════════════════════════════════════════════════════════ */
.input-f1 {
  width: 100%;
  background: var(--f1-surface);
  border: 1px solid var(--f1-border);
  border-radius: var(--f1-radius-sm);
  color: var(--f1-text);
  padding: var(--f1-space-3) var(--f1-space-4);
  font-family: var(--f1-font);
  font-size: var(--f1-text-md);
  transition: border-color 0.2s ease, box-shadow 0.2s ease;
}
.input-f1:focus {
  outline: none;
  border-color: var(--f1-red);
  box-shadow: 0 0 0 3px var(--f1-red-glow);
}
select.input-f1 {
  cursor: pointer;
  /* Hide the native dropdown arrow (which rendered flush against the
     border with no control over its spacing) and draw our own chevron-down
     with real breathing room instead — same glyph as icon-chevron-down in
     the shared sprite, hand-matched here since a background-image data URI
     can't reference currentColor/CSS custom properties, only literal
     values (the #9a9aa4 below is --f1-text-dim's own hex, not a new color). */
  appearance: none;
  -webkit-appearance: none;
  padding-right: calc(var(--f1-space-4) + 22px);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%239a9aa4' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='5 9 12 16 19 9'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right var(--f1-space-4) center;
  background-size: 14px;
}

/* The dropdown's OPEN option list is rendered natively by the OS/browser —
   CSS can't restyle its padding, borders, or hover color, but Chromium
   (this is a Windows kiosk running Chrome/Edge) does respect background/
   color set directly on <option>, so at least the list reads dark instead
   of the browser's stark default white. #151515 is --f1-surface-solid's
   own hex — same data-URI-style constraint as the arrow above. */
select.input-f1 option {
  background: #151515;
  color: var(--f1-text);
}

/* Large, centered, uppercase hero field — register/login name+password
   entry. A deliberate size variant, not a second input system. */
.form-help-f1 {
  font-size: var(--f1-text-xs);
  color: var(--f1-text-dim);
  margin-top: var(--f1-space-1);
}

.input-f1--hero {
  text-align: center;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-weight: var(--f1-weight-bold);
  font-size: var(--f1-text-lg);
  padding: var(--f1-space-4) var(--f1-space-5);
}

/* ═══════════════════════════════════════════════════════════════════
   Modal — hidden by default via the native `hidden` attribute (see
   templates/components/_modal.html + static_common/core/js/modal.js for
   the open/close wiring). No page currently uses a modal; this is a
   from-scratch component, not extracted from an existing pattern.
   ═══════════════════════════════════════════════════════════════════ */
.modal-f1 {
  position: fixed;
  inset: 0;
  z-index: var(--f1-z-modal);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--f1-space-4);
}
.modal-f1[hidden] {
  display: none;
}
.modal-f1-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.65);
  backdrop-filter: blur(4px);
}
.modal-f1-dialog {
  position: relative;
  background: var(--f1-panel);
  border: 1px solid var(--f1-border);
  border-radius: var(--f1-radius-lg);
  backdrop-filter: blur(var(--f1-blur));
  -webkit-backdrop-filter: blur(var(--f1-blur));
  box-shadow: var(--f1-shadow-lg);
  width: 100%;
  max-width: 480px;
  max-height: 90vh;
  overflow-y: auto;
}
.modal-f1-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--f1-space-4);
  padding: var(--f1-space-4) var(--f1-space-5);
  border-bottom: 1px solid var(--f1-border);
}
.modal-f1-title {
  font-size: var(--f1-text-lg);
  font-weight: var(--f1-weight-black);
  letter-spacing: 0.02em;
  margin: 0;
}
.modal-f1-close {
  background: none;
  border: none;
  color: var(--f1-text-dim);
  font-size: var(--f1-text-xl);
  line-height: 1;
  cursor: pointer;
  padding: 0;
}
.modal-f1-close:hover {
  color: var(--f1-text);
}
.modal-f1-body {
  padding: var(--f1-space-5);
}

/* ═══════════════════════════════════════════════════════════════════
   Small caption link — "← BACK", "LOG OUT →" style navigation text.
   Shared across pages/themes (unlike leaderboard's .lb-clock-label,
   which is that page's specific caption typography, this is generic).
   --stacked = its own line with a small top gap, for two stacked links.
   ═══════════════════════════════════════════════════════════════════ */
.caption-link-f1 {
  font-size: var(--f1-text-xs);
  letter-spacing: 0.2em;
  color: var(--f1-red);
  text-decoration: none;
}
.caption-link-f1--stacked {
  display: block;
  margin-top: 2px;
}

/* ═══════════════════════════════════════════════════════════════════
   Page header — generic title(+subtitle, +back-link) block for simple
   pages (see templates/components/_page_header.html). The leaderboard/
   records/my-races header (.lb-header) stays its own bespoke component —
   it carries a logo, wordmark, live clock and session status that don't
   generalize — this is for plainer pages like operator profile/settings.
   ═══════════════════════════════════════════════════════════════════ */
.page-header-f1 {
  margin-bottom: var(--f1-space-4);
}
.page-header-f1-back {
  display: inline-block;
  margin-bottom: var(--f1-space-2);
}
.page-header-f1-title {
  font-size: var(--f1-text-xl);
  font-weight: var(--f1-weight-black);
  letter-spacing: 0.02em;
}
.page-header-f1-subtitle {
  margin-top: var(--f1-space-1);
  color: var(--f1-text-dim);
  font-size: var(--f1-text-md);
}

/* ═══════════════════════════════════════════════════════════════════
   Toggle switch — labeled checkbox used for operator on/off settings
   (leaderboard's operator bar, Live Control's header toggles). Generic
   enough to live in the shared stylesheet rather than a page-specific one.
   ═══════════════════════════════════════════════════════════════════ */
.toggle-f1 {
  display: inline-flex;
  align-items: center;
  gap: var(--f1-space-2);
  font-size: var(--f1-text-sm);
  font-weight: var(--f1-weight-bold);
  letter-spacing: 0.02em;
  color: var(--f1-text-dim);
  cursor: pointer;
  user-select: none;
  white-space: nowrap;
}
.toggle-f1 input[type="checkbox"] {
  accent-color: var(--f1-red);
  width: 1rem;
  height: 1rem;
  cursor: pointer;
}
.toggle-f1 input[type="checkbox"]:checked ~ span {
  color: var(--f1-text);
}

/* ═══════════════════════════════════════════════════════════════════
   Tables — ONE class, sticky header, consistent cell padding.
   ═══════════════════════════════════════════════════════════════════ */
.table-f1-wrap {
  overflow-x: auto;
  padding: var(--f1-space-2);
}

.table-f1 {
  width: 100%;
  border-collapse: collapse;
}
.table-f1 thead th {
  position: sticky;
  top: 0;
  z-index: var(--f1-z-raised);
  text-align: left;
  font-size: var(--f1-text-xs);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--f1-text-dim);
  padding: var(--f1-space-2) var(--f1-space-3);
  border-bottom: 2px solid var(--f1-border);
  background: var(--f1-panel);
  backdrop-filter: blur(var(--f1-blur));
  -webkit-backdrop-filter: blur(var(--f1-blur));
  white-space: nowrap;
}
.table-f1 tbody tr {
  border-bottom: 1px solid var(--f1-border);
  transition: background-color 0.2s ease;
}
.table-f1 tbody tr:hover {
  background: var(--f1-surface);
}
.table-f1 tbody tr:last-child td {
  border-bottom: none;
}
.table-f1 td {
  padding: var(--f1-space-2) var(--f1-space-3);
  vertical-align: middle;
}
.table-f1-empty {
  text-align: center;
  color: var(--f1-text-dim);
  padding: var(--f1-space-8) var(--f1-space-4);
}

.empty-state-f1-icon {
  font-size: var(--f1-text-2xl);
  margin-bottom: var(--f1-space-2);
}
.empty-state-f1-title {
  color: var(--f1-text);
  font-weight: var(--f1-weight-bold);
  font-size: var(--f1-text-md);
}
.empty-state-f1-text {
  margin-top: var(--f1-space-1);
}

/* ═══════════════════════════════════════════════════════════════════
   Alerts — ONE class + severity variants. :empty collapses to nothing,
   so JS can keep doing `errorEl.textContent = "..."` / `= ""` without
   toggling a visibility class itself.
   ═══════════════════════════════════════════════════════════════════ */
.alert-f1 {
  padding: var(--f1-space-3) var(--f1-space-4);
  border-radius: var(--f1-radius-sm);
  border: 1px solid transparent;
  font-size: var(--f1-text-sm);
  text-align: center;
}
.alert-f1:empty {
  display: none;
}
.alert-f1--danger {
  color: var(--f1-danger);
  background: rgba(255, 82, 82, 0.1);
  border-color: rgba(255, 82, 82, 0.35);
}
.alert-f1--success {
  color: var(--f1-green);
  background: rgba(0, 230, 118, 0.1);
  border-color: rgba(0, 230, 118, 0.3);
}
.alert-f1--warning {
  color: var(--f1-yellow);
  background: rgba(255, 212, 0, 0.1);
  border-color: rgba(255, 212, 0, 0.3);
}

/* ═══════════════════════════════════════════════════════════════════
   Badges — ONE class. --sm = tag radius (default), --pill = fully
   rounded. Color variants cover the status-badge/role-badge use cases
   found across the site (queue status, rig state, operator role, etc).
   ═══════════════════════════════════════════════════════════════════ */
/* ═══════════════════════════════════════════════════════════════════
   Icon — inline SVG referencing the shared sprite (core/img/icons.svg,
   see templates/components/_icon.html). Always currentColor, so it
   inherits whatever color the caller sets — a nav item, a button, a
   stat label, etc. — instead of carrying its own color.
   ═══════════════════════════════════════════════════════════════════ */
.icon-f1 {
  display: inline-block;
  vertical-align: -0.15em;
  flex-shrink: 0;
  color: inherit;
}

.badge-f1 {
  display: inline-flex;
  align-items: center;
  gap: var(--f1-space-1);
  font-weight: var(--f1-weight-bold);
  letter-spacing: 0.04em;
  padding: var(--f1-space-1) var(--f1-space-2);
  font-size: var(--f1-text-xs);
  border-radius: var(--f1-radius-xs);
  background: var(--f1-surface);
  color: var(--f1-text-dim);
}
.badge-f1--sm {
  border-radius: var(--f1-radius-xs);
}
.badge-f1--pill {
  border-radius: var(--f1-radius-full);
}
.badge-f1--brand {
  background: var(--f1-red);
  color: #fff;
}
.badge-f1--success {
  color: var(--f1-green);
  background: rgba(0, 230, 118, 0.14);
}
.badge-f1--warning {
  color: var(--f1-yellow);
  background: rgba(255, 212, 0, 0.14);
}
.badge-f1--danger {
  color: var(--f1-danger);
  background: rgba(255, 82, 82, 0.14);
}

/* ═══════════════════════════════════════════════════════════════════
   Tyre-compound badge — one shared component, 24px circle, color via
   currentColor so each variant is a single declaration. Inter/Wet keep
   their real-world compound colors (green/blue) rather than reusing
   --f1-green/--f1-blue, which mean something else (success/telemetry).
   ═══════════════════════════════════════════════════════════════════ */
.tyre-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  border-radius: var(--f1-radius-full);
  background: transparent;
  border: 2px solid currentColor;
  font-family: var(--f1-mono);
  font-weight: var(--f1-weight-black);
  font-size: var(--f1-text-xs);
  line-height: 1;
}
.tyre-badge.is-tyre-hard { color: #ffffff; }
.tyre-badge.is-tyre-medium { color: var(--f1-yellow); }
.tyre-badge.is-tyre-soft { color: var(--f1-red); }
.tyre-badge.is-tyre-inter { color: #2ecc71; }
.tyre-badge.is-tyre-wet { color: #2f80ed; }

/* ═══════════════════════════════════════════════════════════════════
   Toast — floating, auto-dismissing notification (flag/incident alerts
   on the leaderboard). Structure unchanged, tokens unified.
   ═══════════════════════════════════════════════════════════════════ */
.toast-f1-container {
  position: fixed;
  top: var(--f1-space-6);
  left: 50%;
  transform: translateX(-50%);
  z-index: var(--f1-z-toast);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--f1-space-2);
  pointer-events: none;
}
.toast-f1 {
  padding: var(--f1-space-3) var(--f1-space-6);
  border-radius: var(--f1-radius-sm);
  font-weight: var(--f1-weight-black);
  letter-spacing: 0.08em;
  font-size: var(--f1-text-md);
  text-transform: uppercase;
  color: #fff;
  background: rgba(20, 20, 24, 0.92);
  border: 1px solid var(--f1-border-glass);
  box-shadow: var(--f1-shadow-lg);
  backdrop-filter: blur(8px);
  animation: toast-f1-in 0.25s ease, toast-f1-out 0.4s ease 3.6s forwards;
}
.toast-f1.severity-danger {
  border-color: var(--f1-red);
  box-shadow: var(--f1-shadow-glow);
}
.toast-f1.severity-warning {
  border-color: var(--f1-yellow);
  color: var(--f1-yellow);
}
.toast-f1.severity-info {
  border-color: rgba(255, 255, 255, 0.3);
}
@keyframes toast-f1-in {
  from { opacity: 0; transform: translateY(-16px); }
  to { opacity: 1; transform: translateY(0); }
}
@keyframes toast-f1-out {
  from { opacity: 1; }
  to { opacity: 0; transform: translateY(-10px); }
}

/* ═══════════════════════════════════════════════════════════════════
   Keyboard focus — one app-wide rule, deliberately not per-component.

   There was previously no visible focus indicator anywhere in the app
   (two :focus rules total, both on inputs, and no :focus-visible at
   all), so keyboard and switch users had no way to tell where they
   were. :focus-visible rather than :focus so a mouse click on a button
   doesn't leave a ring behind it — the browser decides when the ring is
   warranted.

   The ring is white with a dark outer edge rather than --f1-red: red on
   the app background is 3.98:1, which fails AA for a 1-2px indicator,
   and it also disappears against the red surfaces it would land on
   (.btn-f1--primary, .lc-estop, the leaderboard's red header band).
   White clears 17:1 on every surface in both themes, and the outer
   shadow keeps it visible if it ever lands on a light one.
   ═══════════════════════════════════════════════════════════════════ */
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: 2px solid #ffffff;
  outline-offset: 2px;
  border-radius: var(--f1-radius-xs);
  box-shadow: 0 0 0 4px rgba(0, 0, 0, 0.65);
}

/* Inputs already carry their own :focus treatment (border + glow); the
   ring sits outside it rather than replacing it, so a focused field
   still reads as focused for mouse users too. */
.input-f1:focus-visible {
  outline: 2px solid #ffffff;
  outline-offset: 1px;
}

/* ── Error pages (404 / 403 / 500) ──────────────────────────────────
   Shared by all three templates in templates/. Kept here rather than in
   a separate stylesheet so 500.html needs nothing beyond what base.html
   already loads — see that template's comment on staying near-static. */
.err-shell {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--f1-space-6);
}

.err-panel {
  max-width: 560px;
  width: 100%;
  padding: var(--f1-space-10) var(--f1-space-8);
  text-align: center;
}

.err-code {
  font-family: var(--f1-mono);
  font-size: var(--f1-text-3xl);
  font-weight: var(--f1-weight-black);
  line-height: 1;
  color: var(--f1-red);
  text-shadow: var(--f1-shadow-glow);
  margin-bottom: var(--f1-space-4);
}
.err-code--warn { color: var(--f1-yellow); text-shadow: none; }
.err-code--danger { color: var(--f1-danger); text-shadow: none; }

.err-title {
  font-size: var(--f1-text-xl);
  font-weight: var(--f1-weight-bold);
  color: var(--f1-text);
  margin: 0 0 var(--f1-space-4);
}

.err-text {
  font-size: var(--f1-text-md);
  line-height: 1.6;
  color: var(--f1-text-dim);
  margin: 0 0 var(--f1-space-4);
}
.err-text--muted { font-size: var(--f1-text-sm); }

.err-actions {
  display: flex;
  gap: var(--f1-space-3);
  justify-content: center;
  flex-wrap: wrap;
  margin-top: var(--f1-space-6);
}

@media (max-width: 480px) {
  .err-panel { padding: var(--f1-space-8) var(--f1-space-5); }
  .err-actions .btn-f1 { width: 100%; }
}
