/*
 * efr-intelligence — live event scoring.
 * Shares the elbflorace design language: 60% black / 30% white / 10% orange,
 * pure grays without blue tint.
 */

/* ─── DESIGN TOKENS ─────────────────────────────────────── */
:root {
  /* Surfaces — pure black/gray, no blue tint */
  --bg:   #0a0a0a;
  --s1:   #111111;   /* sidebar */
  --s2:   #161616;   /* card */
  --s3:   #1c1c1c;   /* elevated / hover */
  --s4:   #222222;   /* input, deepest */

  /* Borders */
  --b1: rgba(255,255,255,0.06);
  --b2: rgba(255,255,255,0.09);
  --b3: rgba(255,255,255,0.15);

  /* Text */
  --t1: #f0f0f0;
  --t2: #888888;
  --t3: #505050;

  /* Accent */
  --orange:     #ff630f;
  --orange-dim: #c44e0b;
  --orange-bg:  rgba(255,99,15,0.08);
  --orange-glow:rgba(255,99,15,0.18);

  /* Semantic */
  --danger: #ef4444;
  --ok:     #22c55e;
  --info:   #3b82f6;
  --warn:   #f59e0b;

  /* Layout */
  --sidebar-w: 224px;

  /* Radii */
  --r-xs: 4px;
  --r-sm: 6px;
  --r:    10px;
  --r-lg: 14px;

  /* Shadows */
  --sh1: 0 1px 3px rgba(0,0,0,.4);
  --sh2: 0 4px 16px rgba(0,0,0,.5);
  --sh3: 0 10px 36px rgba(0,0,0,.6);

  --mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}

/* ─── RESET ─────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html, body {
  min-height: 100vh;
  background: var(--bg);
  color: var(--t1);
  font-family: "Inter", "Poppins", system-ui, -apple-system, "Segoe UI", sans-serif;
  line-height: 1.5;
  font-size: 15px;
  -webkit-font-smoothing: antialiased;
}
a { color: inherit; text-decoration: none; }
h1, h2, h3, h4 {
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--t1);
  line-height: 1.2;
}
h1 { font-size: 1.6rem; }
h2 { font-size: 1.2rem; }
h3 { font-size: 1rem; }
h4 { font-size: 0.875rem; }

/* ─── APP SHELL ──────────────────────────────────────────── */
.app-shell {
  display: flex;
  min-height: 100vh;
}
#sidebar-root {
  width: var(--sidebar-w);
  flex-shrink: 0;
}
.app-body {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
}
.content {
  flex: 1;
  min-width: 0;
  padding: 2rem 2.25rem;
  max-width: 1400px;
  width: 100%;
}
/* Nothing may push the page sideways; wide content scrolls inside its own
   container instead. */
.app-shell { max-width: 100%; }

/* ─── SIDEBAR ────────────────────────────────────────────── */
.topbar-mobile { display: none; }
.sidebar-overlay { display: none; }

.sidebar {
  width: var(--sidebar-w);
  background: var(--s1);
  border-right: 1px solid var(--b1);
  display: flex;
  flex-direction: column;
  position: fixed;
  top: 0;
  left: 0;
  height: 100vh;
  overflow-y: auto;
  z-index: 100;
}
.sb-brand {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  padding: 1.25rem 1rem 1rem;
  border-bottom: 1px solid var(--b1);
  flex-shrink: 0;
}
.sb-brand img { height: 26px; width: auto; }
.sb-brand-text { display: flex; flex-direction: column; }
.sb-brand-title {
  font-weight: 700;
  font-size: 1rem;
  color: var(--t1);
  letter-spacing: -0.01em;
}
.sb-brand-title span { color: var(--orange); }
.sb-brand-sub {
  font-size: 0.7rem;
  color: var(--t3);
  text-transform: uppercase;
  letter-spacing: 0.08em;
}
.sb-section { padding: 1rem 0.75rem 0.25rem; }
.sb-section.grow { flex: 1; }
.sb-section-label {
  font-size: 0.65rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--t3);
  padding: 0 0.5rem;
  margin-bottom: 0.35rem;
  margin-top: 0.75rem;
}
.sb-section-label:first-child { margin-top: 0; }
.sb-item {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  padding: 0.5rem 0.65rem;
  border-radius: var(--r-sm);
  color: var(--t2);
  font-size: 0.875rem;
  font-weight: 500;
  cursor: pointer;
  border: none;
  background: none;
  width: 100%;
  text-align: left;
  transition: background 0.12s, color 0.12s;
  position: relative;
}
.sb-item:hover { background: rgba(255,255,255,0.04); color: var(--t1); box-shadow: none; }
.sb-item.active {
  background: var(--orange-bg);
  color: var(--orange);
}
.sb-item.active::before {
  content: '';
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  height: 60%;
  width: 2px;
  background: var(--orange);
  border-radius: 0 2px 2px 0;
}
.sb-item svg { flex-shrink: 0; opacity: 0.8; }
.sb-item.active svg { opacity: 1; }
.sb-footer {
  padding: 0.75rem;
  border-top: 1px solid var(--b1);
  flex-shrink: 0;
}
.sb-user-pill {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.5rem 0.5rem;
  margin-bottom: 0.4rem;
  border-radius: 6px;
  color: inherit;
  text-decoration: none;
}
.sb-avatar {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: var(--orange-bg);
  border: 1px solid var(--orange-glow);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.75rem;
  font-weight: 700;
  color: var(--orange);
  flex-shrink: 0;
}
.sb-user-info { min-width: 0; flex: 1; }
.sb-user-name {
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--t1);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.sb-user-email {
  font-size: 0.7rem;
  color: var(--t3);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.sb-user-role {
  font-size: 0.7rem;
  color: var(--orange);
  font-weight: 600;
  margin-top: 0.1rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

/* ─── FEED STATUS PILL ───────────────────────────────────── */
/* Sits above the user pill in the sidebar footer. */
.feed-pill {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.4rem 0.6rem;
  margin-bottom: 0.5rem;
  border-radius: var(--r-sm);
  background: var(--s2);
  border: 1px solid var(--b1);
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--t2);
  cursor: default;
}
.feed-pill .led {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--t3);
  flex-shrink: 0;
}
.feed-pill.connected { color: var(--ok); border-color: rgba(34,197,94,0.25); }
.feed-pill.connected .led { background: var(--ok); box-shadow: 0 0 0 3px rgba(34,197,94,0.15); }
.feed-pill.connecting { color: var(--warn); border-color: rgba(245,158,11,0.25); }
.feed-pill.connecting .led { background: var(--warn); animation: pulse-dot 1.2s ease-in-out infinite; }
.feed-pill.stale { color: var(--warn); border-color: rgba(245,158,11,0.25); }
.feed-pill.stale .led { background: var(--warn); }
.feed-pill.disconnected, .feed-pill.error { color: #fca5a5; border-color: rgba(220,38,38,0.3); }
.feed-pill.disconnected .led, .feed-pill.error .led { background: var(--danger); }
.feed-pill.disabled .led { background: var(--t3); }

/* ─── PAGE HEADER ────────────────────────────────────────── */
.page-header {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  margin-bottom: 1.75rem;
  gap: 1rem;
  flex-wrap: wrap;
}
.page-header h1 { line-height: 1; }
.page-header .sub {
  color: var(--t2);
  font-size: 0.85rem;
  margin-top: 0.25rem;
}
.page-actions {
  display: flex;
  gap: 0.5rem;
  align-items: center;
  flex-wrap: wrap;
}
.page-actions select { width: auto; }

/* ─── CARDS ──────────────────────────────────────────────── */
.card {
  position: relative;
  background: var(--s2);
  border: 1px solid var(--b1);
  border-radius: var(--r);
  padding: 1.25rem 1.5rem;
  margin-bottom: 1rem;
  transition: border-color 0.15s;
}
.card:last-child { margin-bottom: 0; }
.card h2 { font-size: 1.05rem; margin-bottom: 0.35rem; }
.card h3 { font-size: 0.95rem; }
.card-title {
  font-size: 0.8rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--t2);
  margin-bottom: 1rem;
}
.card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  flex-wrap: wrap;
  margin-bottom: 1rem;
}
.card-head h2 { margin-bottom: 0; }

/* A card whose whole body is a table: let the table meet the card edges. */
.card.table-card { padding: 0; overflow: hidden; }
.card.table-card .card-head {
  padding: 1rem 1.25rem;
  margin-bottom: 0;
  border-bottom: 1px solid var(--b1);
}

/* ─── STAT TILES ─────────────────────────────────────────── */
.stat-grid {
  display: grid;
  gap: 1rem;
  /* min() lets a column shrink below its preferred width on a narrow screen.
     A bare minmax(190px, 1fr) cannot, and overflows the viewport instead. */
  grid-template-columns: repeat(auto-fit, minmax(min(190px, 100%), 1fr));
  margin-bottom: 1.5rem;
}
.stat .value { overflow-wrap: anywhere; }
.stat {
  background: var(--s2);
  border: 1px solid var(--b1);
  border-radius: var(--r);
  padding: 1rem 1.25rem;
}
.stat .label {
  color: var(--t3);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  font-size: 0.68rem;
  font-weight: 600;
}
.stat .value {
  font-size: 1.75rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
  margin-top: 0.25rem;
  line-height: 1.1;
}
.stat .value.accent { color: var(--orange); }
.stat .foot { color: var(--t2); font-size: 0.8rem; margin-top: 0.15rem; }

/* ─── TABLES ─────────────────────────────────────────────── */
table { width: 100%; border-collapse: collapse; }
th, td {
  text-align: left;
  padding: 0.65rem 0.75rem;
  border-bottom: 1px solid var(--b1);
  font-size: 0.875rem;
  white-space: nowrap;
}
th {
  color: var(--t3);
  font-weight: 600;
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  background: var(--s2);
}
td { color: var(--t2); }
td strong, td .t1 { color: var(--t1); }
tr:last-child td { border-bottom: none; }
tr:hover td { background: rgba(255,255,255,0.015); }
th.num, td.num { text-align: right; font-variant-numeric: tabular-nums; }
th.center, td.center { text-align: center; }
td.mono, .mono { font-family: var(--mono); font-variant-numeric: tabular-nums; }

/* Horizontal scroll container — wide result tables never push the page. */
.table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.table-scroll thead th { position: sticky; top: 0; z-index: 1; }

/* Our own entry, wherever it appears. */
tr.own td { background: var(--orange-bg); }
tr.own td:first-child { box-shadow: inset 2px 0 0 var(--orange); }
tr.own:hover td { background: rgba(255,99,15,0.12); }
tr.own td strong { color: var(--orange); }

/* A run that does not count towards the score. */
tr.void td { color: var(--t3); }

/* ─── BUTTONS ────────────────────────────────────────────── */
button, .btn {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.55rem 1.1rem;
  border-radius: var(--r-sm);
  font-size: 0.875rem;
  font-weight: 600;
  cursor: pointer;
  border: 1px solid transparent;
  transition: background 0.12s, border-color 0.12s, box-shadow 0.12s, transform 0.08s;
  text-decoration: none;
  white-space: nowrap;
  background: var(--orange);
  color: #000;
  border-color: var(--orange);
  font-family: inherit;
  width: auto;
}
button:hover, .btn:hover {
  background: var(--orange-dim);
  border-color: var(--orange-dim);
  box-shadow: 0 0 0 3px var(--orange-glow);
}
button:active, .btn:active { transform: scale(0.98); }
button.secondary, .btn.secondary {
  background: var(--s3);
  color: var(--t1);
  border-color: var(--b2);
}
button.secondary:hover, .btn.secondary:hover {
  background: var(--s4);
  border-color: var(--b3);
  box-shadow: none;
}
button.danger, .btn.danger {
  background: rgba(220,38,38,0.15);
  color: var(--danger);
  border-color: rgba(220,38,38,0.35);
}
button.danger:hover, .btn.danger:hover {
  background: var(--danger);
  color: #fff;
  border-color: var(--danger);
  box-shadow: 0 0 0 3px rgba(220,38,38,0.2);
}
button.small, .btn.small { padding: 0.35rem 0.75rem; font-size: 0.8rem; }
button:disabled, .btn.disabled {
  background: var(--s3);
  color: var(--t3);
  border-color: var(--b1);
  cursor: not-allowed;
  box-shadow: none;
}
button:disabled:hover { transform: none; background: var(--s3); }

.row-actions { display: inline-flex; gap: 0.5rem; flex-wrap: wrap; justify-content: flex-end; }
td.actions { text-align: right; white-space: nowrap; }

/* ─── FORMS & INPUTS ─────────────────────────────────────── */
label {
  display: block;
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--t2);
  margin-bottom: 0.35rem;
  letter-spacing: 0.02em;
}
input[type="text"], input[type="email"], input[type="password"],
input[type="number"], input[type="url"], input[type="search"],
select, textarea {
  width: 100%;
  background: var(--s4);
  color: var(--t1);
  border: 1px solid var(--b2);
  border-radius: var(--r-sm);
  padding: 0.55rem 0.75rem;
  font-size: 0.875rem;
  font-family: inherit;
  transition: border-color 0.15s, box-shadow 0.15s;
  outline: none;
}
input:focus, select:focus, textarea:focus {
  border-color: var(--orange);
  box-shadow: 0 0 0 3px var(--orange-glow);
}
input::placeholder, textarea::placeholder { color: var(--t3); }
input:disabled, select:disabled { opacity: 0.5; cursor: not-allowed; }
select {
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' stroke='%23888' stroke-width='1.5' fill='none' stroke-linecap='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.75rem center;
  padding-right: 2rem;
}
input[type="checkbox"] {
  width: 1rem; height: 1rem; cursor: pointer;
  accent-color: var(--orange);
}
code {
  background: var(--s3);
  color: var(--t1);
  padding: 0.1rem 0.4rem;
  border-radius: var(--r-xs);
  font-family: var(--mono);
  font-size: 0.85em;
}

/* Numeric cell editors inside result tables. */
.cell-input {
  /* Wide enough for the longest value these cells actually hold — a negative
     points deduction, a reference time with decimals — rather than for the
     shortest. A cut-off number in a rules table is a number nobody can check. */
  width: 7rem;
  min-width: 7rem;
  padding: 0.35rem 0.55rem;
  text-align: right;
  font-family: var(--mono);
  font-size: 0.85rem;
}

/* The native number spinner sits *over* the text in a narrow right-aligned
   field, hiding the last digit. Typing is how these get edited anyway, so the
   arrows go and the width is the value's. */
.cell-input[type="number"]::-webkit-outer-spin-button,
.cell-input[type="number"]::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}
.cell-input[type="number"] {
  -moz-appearance: textfield;
  appearance: textfield;
}

.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0.85rem; }
.form-grid .full { grid-column: 1 / -1; }
.field { display: flex; flex-direction: column; }

/* ─── ALERTS ─────────────────────────────────────────────── */
.alert {
  display: flex;
  align-items: flex-start;
  gap: 0.65rem;
  padding: 0.75rem 1rem;
  border-radius: var(--r-sm);
  margin-bottom: 1rem;
  font-size: 0.875rem;
  border: 1px solid transparent;
}
.alert:last-child { margin-bottom: 0; }
.alert.error { background: rgba(220,38,38,0.1);  color: #fca5a5; border-color: rgba(220,38,38,0.3); }
.alert.ok    { background: rgba(22,163,74,0.1);  color: #86efac; border-color: rgba(22,163,74,0.3); }
.alert.info  { background: var(--orange-bg);     color: #f6b48a; border-color: rgba(255,99,15,0.28); }
.alert.warn  { background: rgba(245,158,11,0.10);color: #f4c26a; border-color: rgba(245,158,11,0.35); }

/* ─── BADGES ─────────────────────────────────────────────── */
.badge {
  display: inline-block;
  padding: 0.1rem 0.55rem;
  font-size: 0.68rem;
  font-weight: 700;
  border-radius: 999px;
  vertical-align: middle;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  background: var(--s3);
  color: var(--t2);
  border: 1px solid var(--b2);
}
.badge.accent { color: var(--orange); background: var(--orange-bg); border-color: rgba(255,99,15,0.3); }
.badge.ok     { color: #86efac; background: rgba(22,163,74,0.14); border-color: rgba(22,163,74,0.35); }
.badge.bad    { color: #fca5a5; background: rgba(220,38,38,0.14); border-color: rgba(220,38,38,0.3); }
.badge.warn   { color: #f4c26a; background: rgba(245,158,11,0.10); border-color: rgba(245,158,11,0.35); }

/* ─── MUTED / EMPTY / DIVIDERS ───────────────────────────── */
.muted { color: var(--t2); font-size: 0.85rem; }
.dim   { color: var(--t3); }
.empty { color: var(--t3); text-align: center; padding: 2.5rem 1rem; font-size: 0.9rem; }
.divider { height: 1px; background: var(--b1); margin: 1rem 0; }
.sub-line { font-size: 0.75rem; color: var(--t3); margin-top: 0.1rem; }

/* ─── LOGIN SHELL ────────────────────────────────────────── */
.login-shell {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  background:
    radial-gradient(ellipse 80% 60% at 20% 120%, rgba(255,99,15,0.06) 0%, transparent 70%),
    radial-gradient(ellipse 60% 50% at 80% 0%,   rgba(255,99,15,0.04) 0%, transparent 70%),
    var(--bg);
  padding: 2rem 1rem;
}
.login-card {
  background: var(--s2);
  border: 1px solid var(--b1);
  border-radius: var(--r-lg);
  padding: 2.5rem;
  width: 100%;
  max-width: 420px;
  box-shadow: var(--sh3);
}
.login-logo { display: block; margin: 0 auto 1.5rem; height: 60px; width: auto; }
.login-title { text-align: center; font-size: 1.35rem; font-weight: 700; margin-bottom: 0.35rem; }
.login-sub { text-align: center; color: var(--t2); font-size: 0.85rem; margin-bottom: 1.75rem; }

details summary { list-style: none; }
details summary::-webkit-details-marker { display: none; }

/* ─── FILTER CHIPS ───────────────────────────────────────── */
.chip-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin-bottom: 1rem;
}
.chip {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.4rem 0.8rem;
  background: var(--s3);
  color: var(--t2);
  border: 1px solid var(--b2);
  border-radius: 999px;
  font-size: 0.82rem;
  font-weight: 600;
  cursor: pointer;
  user-select: none;
  font-family: inherit;
  white-space: nowrap;
  /* Comfortable to hit with a thumb. */
  min-height: 38px;
}
.chip:hover { background: var(--s4); color: var(--t1); box-shadow: none; border-color: var(--b3); }
.chip.selected {
  background: var(--orange-bg);
  color: var(--orange);
  border-color: rgba(255,99,15,0.35);
}
.chip .count {
  font-variant-numeric: tabular-nums;
  font-weight: 500;
  opacity: 0.7;
  font-size: 0.75rem;
}

/* ─── SCHEDULE ───────────────────────────────────────────── */
.day-head {
  display: flex;
  align-items: baseline;
  gap: 0.6rem;
  margin: 1.5rem 0 0.6rem;
}
.day-head:first-child { margin-top: 0; }
.day-head h2 { font-size: 1rem; }
.day-head .count { color: var(--t3); font-size: 0.78rem; }

.sched-list { display: flex; flex-direction: column; gap: 0.4rem; }

.sched-item {
  display: grid;
  grid-template-columns: 6.5rem 1fr auto;
  gap: 0.5rem 0.9rem;
  align-items: center;
  padding: 0.7rem 0.9rem;
  background: var(--s2);
  border: 1px solid var(--b1);
  border-left: 3px solid var(--b2);
  border-radius: var(--r-sm);
}
.sched-item .when {
  font-family: var(--mono);
  font-variant-numeric: tabular-nums;
  font-size: 0.85rem;
  color: var(--t1);
  white-space: nowrap;
}
.sched-item .when .till { color: var(--t3); }
.sched-item .what { color: var(--t1); font-weight: 500; min-width: 0; }
.sched-item .where { color: var(--t2); font-size: 0.8rem; margin-top: 0.1rem; }
.sched-item .tags { display: flex; align-items: center; gap: 0.4rem; white-space: nowrap; }

/* On now — the thing the page exists to answer. */
.sched-item.live {
  background: var(--orange-bg);
  border-color: rgba(255,99,15,0.3);
  border-left-color: var(--orange);
}
.sched-item.live .what { color: var(--orange); font-weight: 600; }
.sched-item.past { opacity: 0.45; }
.sched-item.past .what { font-weight: 400; }

.live-tag {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.1rem 0.5rem;
  border-radius: 999px;
  background: var(--orange);
  color: #000;
  font-size: 0.65rem;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.live-tag::before {
  content: "";
  width: 6px; height: 6px;
  border-radius: 50%;
  background: #000;
  animation: pulse-dot 1.2s ease-in-out infinite;
}

/* The organiser's own category code, tinted with their own colour. */
.cat-chip {
  display: inline-block;
  min-width: 1.9rem;
  padding: 0.1rem 0.4rem;
  border-radius: var(--r-xs);
  font-size: 0.68rem;
  font-weight: 800;
  text-align: center;
  color: #000;
  background: var(--s4);
}

/* ─── ANIMATIONS ─────────────────────────────────────────── */
@keyframes fade-in  { from { opacity: 0; } to { opacity: 1; } }
@keyframes slide-up { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: translateY(0); } }
@keyframes shimmer  { 0% { background-position: -200% 0; } 100% { background-position: 200% 0; } }
@keyframes pulse-dot { 0%, 100% { opacity: 1; } 50% { opacity: 0.45; } }

.skeleton {
  background: linear-gradient(90deg, var(--s3) 25%, var(--s4) 50%, var(--s3) 75%);
  background-size: 200% 100%;
  animation: shimmer 1.4s infinite;
  border-radius: var(--r-sm);
  color: transparent;
  user-select: none;
  height: 14px;
  margin-bottom: 0.5rem;
}
.fade-in { animation: fade-in 0.2s ease; }
.slide-up { animation: slide-up 0.25s ease; }

/* ─── RESPONSIVE ─────────────────────────────────────────── */
@media (max-width: 900px) {
  .content { padding: 1.5rem 1.25rem; }
}

@media (max-width: 768px) {
  #sidebar-root { width: 0; }
  .sidebar {
    left: -100%;
    transition: left 0.25s ease;
    z-index: 300;
  }
  .sidebar.open { left: 0; }
  .sidebar-overlay {
    display: block;
    position: fixed;
    inset: 0;
    background: rgba(0,0,0,0.5);
    z-index: 299;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.2s;
  }
  .sidebar-overlay.visible { opacity: 1; pointer-events: auto; }
  .app-body { padding-top: 52px; }
  .topbar-mobile {
    display: flex;
    position: fixed;
    top: 0; left: 0; right: 0;
    height: 52px;
    background: var(--s1);
    border-bottom: 1px solid var(--b1);
    align-items: center;
    padding: 0 1rem;
    gap: 1rem;
    z-index: 200;
  }
  .topbar-mobile .mb-brand {
    flex: 1;
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-weight: 700;
    font-size: 0.95rem;
    color: var(--t1);
  }
  .topbar-mobile .mb-brand span { color: var(--orange); }
  .topbar-mobile .mb-brand img { height: 22px; }
  .hamburger {
    background: none;
    border: none;
    padding: 0.4rem;
    cursor: pointer;
    color: var(--t2);
    display: flex;
    align-items: center;
    justify-content: center;
  }
  .hamburger:hover { color: var(--t1); box-shadow: none; background: none; }

  .content { padding: 1rem 0.85rem; }
  .card { padding: 1rem; }
  h1 { font-size: 1.3rem; }
  h2 { font-size: 1.05rem; }

  .form-grid { grid-template-columns: 1fr; }
  .stat-grid { gap: 0.6rem; }
  .stat { padding: 0.75rem 0.9rem; }
  .stat .value { font-size: 1.4rem; }

  .page-actions { width: 100%; }
  .page-actions select { flex: 1; }

  th, td { padding: 0.5rem 0.55rem; }
  .login-card { padding: 1.75rem 1.25rem; }

  /* Touch targets: inputs and buttons need to be comfortably tappable, and
     a 16px font stops iOS zooming the page on focus. */
  input[type="text"], input[type="email"], input[type="password"],
  input[type="number"], input[type="url"], input[type="search"],
  select, textarea {
    font-size: 16px;
    padding: 0.65rem 0.75rem;
  }
  button, .btn { padding: 0.65rem 1.1rem; min-height: 42px; }
  button.small, .btn.small { min-height: 36px; }
  input[type="checkbox"] { width: 1.35rem; height: 1.35rem; }

  .page-actions { width: 100%; }
  .page-actions > * { flex: 1 1 140px; min-width: 0; }
  .page-actions select,
  .page-actions button,
  .page-actions .btn { width: 100%; justify-content: center; }

  .sched-item { grid-template-columns: 1fr auto; }
  .sched-item .when { grid-column: 1 / -1; }
  .sched-item .what { overflow-wrap: anywhere; }

  .stat-grid { grid-template-columns: repeat(auto-fit, minmax(min(150px, 100%), 1fr)); }
}

/* ─── SECTION INTROS ─────────────────────────────────────── */
/* A heading card belongs to the table that follows it, but equal gaps above
   and below make it read as the tail of the section above instead. Proximity
   decides grouping, so the space above opens up and the space below closes. */
.card.section-intro {
  margin-top: 2.5rem;
  margin-bottom: 0.45rem;
}
.card.section-intro:first-child,
#notice + .card.section-intro { margin-top: 0; }

/* ─── INFO TIPS ──────────────────────────────────────────── */
.info-wrap { position: relative; display: inline-flex; vertical-align: middle; }

.info-btn {
  /* Overrides the global button styling: this is a glyph, not a control. */
  width: 15px;
  height: 15px;
  min-height: 0;
  padding: 0;
  margin-left: 0.3rem;
  border-radius: 50%;
  border: 1px solid var(--b3);
  background: transparent;
  color: var(--t2);
  font-size: 9px;
  font-weight: 700;
  font-family: var(--mono);
  line-height: 1;
  text-transform: none;
  letter-spacing: 0;
  cursor: pointer;
  box-shadow: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.info-btn:hover,
.info-wrap.open .info-btn {
  background: var(--orange-bg);
  border-color: var(--orange);
  color: var(--orange);
  box-shadow: none;
}

/* The same glyph, drawn inline in prose to point at the real ones. */
.info-inline {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 15px;
  height: 15px;
  border-radius: 50%;
  border: 1px solid var(--b3);
  color: var(--t2);
  font-family: var(--mono);
  font-size: 9px;
  font-weight: 700;
  vertical-align: middle;
}

.info-bubble {
  position: absolute;
  top: calc(100% + 7px);
  left: 50%;
  transform: translateX(-50%);
  z-index: 20;
  display: none;
  width: max-content;
  max-width: 15rem;
  padding: 0.5rem 0.65rem;
  background: var(--s3);
  border: 1px solid var(--b3);
  border-radius: var(--r-sm);
  box-shadow: var(--sh2);
  color: var(--t1);
  font-size: 0.75rem;
  font-weight: 400;
  line-height: 1.45;
  text-align: left;
  text-transform: none;
  letter-spacing: 0;
  white-space: normal;
}
/* Hover and keyboard focus on a pointer; the .open class is what a tap sets. */
.info-wrap:hover .info-bubble,
.info-wrap:focus-within .info-bubble,
.info-wrap.open .info-bubble { display: block; }

/* Sticky headers sit above the rows, so a bubble inside one has to outrank
   them or it opens behind the table. */
.table-scroll thead th:has(.info-wrap.open) { z-index: 3; }

@media (max-width: 640px) {
  /* Bigger tap target than the glyph needs, without moving the layout. */
  .info-btn { width: 20px; height: 20px; font-size: 11px; }
  .info-bubble { max-width: 12rem; }
}

/* ─── MODAL ──────────────────────────────────────────────── */
.modal-backdrop {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1rem;
  background: rgba(0, 0, 0, 0.65);
}
.modal {
  width: 100%;
  max-width: 26rem;
  padding: 1.35rem;
  background: var(--s2);
  border: 1px solid var(--b2);
  border-radius: var(--r);
  box-shadow: var(--sh3);
}
.modal h2 { font-size: 1.05rem; margin-bottom: 0.5rem; }
.modal p { margin-bottom: 1rem; }
.modal .modal-error:empty { display: none; }
.modal-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  /* Save sits on the right, where the primary action belongs. */
  justify-content: flex-end;
}
.modal-actions button { flex: 0 1 auto; }
button.danger, .btn.danger { color: #f0a0a0; border-color: rgba(239, 68, 68, 0.35); }
button.danger:hover, .btn.danger:hover {
  background: rgba(239, 68, 68, 0.12);
  border-color: rgba(239, 68, 68, 0.5);
  color: #ffc4c4;
}

@media (max-width: 480px) {
  /* Thumb-sized targets, and the safe option furthest from a stray tap. */
  .modal-actions { flex-direction: column-reverse; }
  .modal-actions button { width: 100%; justify-content: center; }
}

/* ─── CHARTS ─────────────────────────────────────────────── */
/* The plot is drawn at the container's own pixel size and redrawn on resize,
   so nothing here scales it — this only positions the overlay. */
.chart-frame { position: relative; }
.chart-wrap {
  position: relative;
  width: 100%;
  overflow: hidden;
}
.chart-wrap svg { display: block; max-width: 100%; }

.chart-tip {
  position: absolute;
  display: none;
  z-index: 5;
  pointer-events: none;
  min-width: 8.5rem;
  padding: 0.5rem 0.65rem;
  background: var(--s3);
  border: 1px solid var(--b3);
  border-radius: var(--r-sm);
  box-shadow: var(--sh2);
  font-size: 0.78rem;
  color: var(--t2);
}
.chart-tip .tip-title {
  color: var(--t1);
  font-weight: 600;
  margin-bottom: 0.3rem;
  font-size: 0.82rem;
}
.chart-tip .tip-row { display: flex; justify-content: space-between; gap: 1rem; }
.chart-tip .tip-row strong { color: var(--t1); font-variant-numeric: tabular-nums; }
.chart-tip .tip-foot { color: var(--t3); margin-top: 0.3rem; font-size: 0.7rem; }

.chart-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem 1rem;
  margin-top: 0.75rem;
  font-size: 0.75rem;
  color: var(--t2);
}
.chart-legend .key { display: inline-flex; align-items: center; gap: 0.35rem; }
.chart-legend .dot {
  width: 9px; height: 9px; border-radius: 50%;
  background: rgba(240,240,240,0.5);
}
.chart-legend .dot.own { background: var(--orange); }
.chart-legend .dot.hollow { background: none; border: 1.5px solid rgba(240,240,240,0.6); }
.chart-legend .line { width: 16px; height: 0; border-top: 2px solid var(--warn); }
.chart-legend .line.air { border-top-style: dashed; border-top-color: #6b7280; }
.chart-legend .swatch {
  width: 14px; height: 10px; border-radius: 2px;
  background: rgba(59,130,246,0.16);
  border: 1px solid rgba(59,130,246,0.35);
}

/* ─── MOBILE CARD TABLES ─────────────────────────────────── */
/* A wide results table cannot be read by scrolling sideways on a phone, so
   tables opt in to a stacked card layout. Each cell prints its own header
   from data-label, and the row becomes a card. */
@media (max-width: 640px) {
  table.cards-on-mobile,
  table.cards-on-mobile thead,
  table.cards-on-mobile tbody,
  table.cards-on-mobile tr,
  table.cards-on-mobile td {
    display: block;
    width: 100%;
  }
  table.cards-on-mobile thead { position: absolute; left: -9999px; top: -9999px; }
  table.cards-on-mobile tr {
    border: 1px solid var(--b1);
    border-radius: var(--r-sm);
    background: var(--s2);
    margin-bottom: 0.6rem;
    padding: 0.7rem 0.85rem;
  }
  table.cards-on-mobile tr:hover td { background: transparent; }
  table.cards-on-mobile tr.own {
    border-color: rgba(255,99,15,0.35);
    background: var(--orange-bg);
  }
  table.cards-on-mobile tr.own td,
  table.cards-on-mobile tr.own td:first-child {
    background: transparent;
    box-shadow: none;
  }
  table.cards-on-mobile td {
    border-bottom: none;
    padding: 0.2rem 0;
    text-align: left;
    font-size: 0.9rem;
    white-space: normal;
  }
  table.cards-on-mobile td.num { text-align: left; }
  table.cards-on-mobile td[data-label]::before {
    content: attr(data-label);
    display: inline-block;
    min-width: 6.5rem;
    color: var(--t3);
    font-size: 0.68rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    margin-right: 0.5rem;
    font-weight: 700;
  }
  /* Cells that carry the row's identity read as a title, not a field. */
  table.cards-on-mobile td.row-title {
    font-size: 1rem;
    font-weight: 600;
    color: var(--t1);
    padding-bottom: 0.35rem;
    margin-bottom: 0.35rem;
    border-bottom: 1px solid var(--b1);
  }
  table.cards-on-mobile td.row-title::before { content: none; }
  /* Zero-value cells are noise once every row is a card. */
  table.cards-on-mobile td.hide-empty:empty { display: none; }
  table.cards-on-mobile td input { width: 100% !important; max-width: none; text-align: left; }

  .card.table-card { padding: 0.75rem; }
  .card.table-card .card-head { padding: 0 0 0.6rem; }
  /* Only the tables that turn into cards stop needing to scroll sideways.
     A table that stays a table — the rules grids — still needs it, and
     without this scope it overflowed the page instead. Where :has() is
     missing the scrollbar simply stays, which harms nothing. */
  .table-scroll:has(table.cards-on-mobile) { overflow-x: visible; }
}
