/*
 * Dark is the default, unconditionally. It does not follow the visitor's
 * operating system preference, so a laptop set to light mode still gets the
 * dark page. Light is opt in: put data-theme="light" on the <html> element.
 */
:root {
  color-scheme: dark;

  --sw-blue: #044EF4;
  --sw-fuchsia: #F72A72;
  --sw-turquoise: #40E0D0;

  --bg-page: #0e0e18;
  --bg-surface: #181a28;
  --bg-surface-raised: #222436;

  --fg-default: #f0f0f4;
  --fg-secondary: #e8e8ec;
  --fg-muted: #a0a0aa;
  --fg-headings: #f0f0f4;

  --border-default: rgba(255, 255, 255, 0.12);
  --border-strong: rgba(255, 255, 255, 0.15);

  --shadow-md: 0 4px 16px rgba(0, 0, 0, 0.5);

  /*
   * Bars cycle these three SignalWire hues. Each is stepped for the surface
   * the bars actually sit on (--bg-surface) and clears 3:1 against it: the
   * brand blue only reaches 2.79:1 there and the brand turquoise is far too
   * bright beside the other two, so both get a step of their own here. The
   * slot a contestant gets is fixed by their ballot number, never by their
   * rank, so a bar keeps its color as it overtakes another.
   */
  --series-1: #2F6BFF;
  --series-2: #F72A72;
  --series-3: #2FC9BC;
  --bar-track: var(--bg-surface-raised);

  /* Fire. Also the masthead's ember rule and the leader badge. */
  --fire-1: #FFE29A;
  --fire-2: #FFB13D;
  --fire-3: #FF6A1A;
  --fire-4: #F72A72;
  --fire-glow: rgba(255, 110, 30, 0.45);

  --font-body: 'Lexend', system-ui, sans-serif;
  --font-code: 'JetBrains Mono', ui-monospace, monospace;

  --radius-md: 8px;
  --radius-lg: 14px;
  --radius-full: 100px;

  --bar-thickness: 22px;
  --page-max: 1680px;
  --gutter: 1rem;
}

/* Light mode, applied only when explicitly requested. */
:root[data-theme="light"] {
  color-scheme: light;

  --bg-page: #FAFBFC;
  --bg-surface: #F3F4F6;
  --bg-surface-raised: #E8EAF0;

  --fg-default: #1A1A18;
  --fg-secondary: #3A3A38;
  --fg-muted: #737371;
  --fg-headings: #070c2d;

  --border-default: rgba(0, 0, 0, 0.1);
  --border-strong: rgba(0, 0, 0, 0.18);

  --shadow-md: 0 4px 16px rgba(0, 0, 0, 0.08);

  /* The same three hues, stepped for the light card instead. */
  --series-1: #044EF4;
  --series-2: #F72A72;
  --series-3: #0E9C90;

  /* Pale flame colors vanish on white, so the fire darkens with the theme. */
  --fire-1: #E85D04;
  --fire-2: #DC2F02;
  --fire-3: #C1121F;
  --fire-4: #B5179E;
  --fire-glow: rgba(220, 47, 2, 0.28);
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--bg-page);
  color: var(--fg-default);
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.7;
}

/* ---------- masthead ---------- */

.masthead {
  position: relative;
  padding: 1.75rem var(--gutter) 1.5rem;
  background: var(--bg-page);
}

/* An ember rule instead of a flat border. */
.masthead::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 2px;
  background: linear-gradient(
    90deg,
    transparent,
    var(--fire-3) 18%,
    var(--fire-2) 38%,
    var(--fire-4) 62%,
    var(--fire-3) 82%,
    transparent
  );
  opacity: 0.85;
}

.masthead__inner {
  max-width: var(--page-max);
  margin-inline: auto;
  display: flex;
  flex-wrap: wrap;
  gap: 1rem 3rem;
  align-items: flex-start;
  justify-content: space-between;
}

.masthead__identity {
  flex: 1 1 34rem;
  min-width: 0;
}

.masthead__aside {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 0.85rem;
  flex-shrink: 0;
}

.kicker {
  margin: 0;
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--sw-turquoise);
}

/* ---------- the burning title ---------- */

.brand {
  position: relative;
  display: inline-block;
  margin-top: 0.15rem;
  isolation: isolate;
}

.title {
  position: relative;
  z-index: 1;
  margin: 0;
  font-size: clamp(2.5rem, 7vw, 5rem);
  font-weight: 800;
  line-height: 1.05;
  letter-spacing: -0.03em;
  color: var(--fire-3);
}

/* The gradient rides the letters themselves; the drop-shadow is the heat. */
@supports ((background-clip: text) or (-webkit-background-clip: text)) {
  .title {
    background: linear-gradient(
      180deg,
      var(--fire-1) 0%,
      var(--fire-2) 34%,
      var(--fire-3) 68%,
      var(--fire-4) 100%
    );
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
    filter: drop-shadow(0 0 22px var(--fire-glow));
  }
}

.fire {
  position: absolute;
  z-index: 0;
  left: -0.35em;
  right: -0.35em;
  bottom: 0.06em;
  height: 1.15em;
  font-size: clamp(2.5rem, 7vw, 5rem);
  pointer-events: none;
}

/*
 * Each flame is a rounded teardrop with one sharp corner, rotated so the point
 * faces up, then blurred. Layered at different sizes and speeds they read as
 * fire without a single image request.
 */
.flame {
  position: absolute;
  bottom: 0;
  width: 0.5em;
  height: 0.5em;
  border-radius: 0 50% 50% 50%;
  background: linear-gradient(to top right, var(--fire-4), var(--fire-3) 45%, var(--fire-2) 78%, var(--fire-1));
  filter: blur(7px);
  opacity: 0.85;
  transform: rotate(-45deg);
  transform-origin: bottom center;
  animation: flicker 1.9s ease-in-out infinite alternate;
}

/* A brighter core inside each flame, so the fire has depth rather than fog. */
.flame::after {
  content: "";
  position: absolute;
  inset: 32% 32% 8% 8%;
  border-radius: 0 50% 50% 50%;
  background: linear-gradient(to top right, var(--fire-2), var(--fire-1));
  opacity: 0.9;
}

.flame:nth-child(1) { left: 2%;  width: 0.62em; height: 0.62em; animation-duration: 2.3s; animation-delay: -0.2s; }
.flame:nth-child(2) { left: 16%; width: 0.9em;  height: 0.9em;  animation-duration: 1.7s; animation-delay: -0.9s; }
.flame:nth-child(3) { left: 31%; width: 0.55em; height: 0.55em; animation-duration: 2.1s; animation-delay: -1.4s; }
.flame:nth-child(4) { left: 46%; width: 1em;    height: 1em;    animation-duration: 1.5s; animation-delay: -0.5s; }
.flame:nth-child(5) { left: 62%; width: 0.6em;  height: 0.6em;  animation-duration: 2.4s; animation-delay: -1.1s; }
.flame:nth-child(6) { left: 76%; width: 0.85em; height: 0.85em; animation-duration: 1.8s; animation-delay: -0.3s; }
.flame:nth-child(7) { left: 90%; width: 0.52em; height: 0.52em; animation-duration: 2.2s; animation-delay: -1.7s; }

@keyframes flicker {
  0%   { transform: rotate(-45deg) scale(1)               translate(0, 0);         opacity: 0.72; }
  35%  { transform: rotate(-45deg) scale(1.12, 1.22)      translate(2%, -6%);      opacity: 0.95; }
  70%  { transform: rotate(-45deg) scale(0.94, 1.08)      translate(-2%, -2%);     opacity: 0.8; }
  100% { transform: rotate(-45deg) scale(1.08, 1.3)       translate(1%, -9%);      opacity: 0.92; }
}

.ember {
  position: absolute;
  bottom: 0.3em;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--fire-2);
  box-shadow: 0 0 8px var(--fire-3);
  opacity: 0;
  animation: ember-rise 4.5s ease-out infinite;
}

.ember:nth-of-type(1) { left: 12%; animation-duration: 4.2s; animation-delay: -0.4s; }
.ember:nth-of-type(2) { left: 28%; animation-duration: 5.4s; animation-delay: -2.1s; }
.ember:nth-of-type(3) { left: 44%; animation-duration: 3.8s; animation-delay: -3.2s; }
.ember:nth-of-type(4) { left: 59%; animation-duration: 5.1s; animation-delay: -1.3s; }
.ember:nth-of-type(5) { left: 73%; animation-duration: 4.6s; animation-delay: -2.8s; }
.ember:nth-of-type(6) { left: 88%; animation-duration: 5.8s; animation-delay: -0.9s; }

@keyframes ember-rise {
  0%   { transform: translate(0, 0) scale(1);        opacity: 0; }
  12%  {                                             opacity: 0.9; }
  60%  { transform: translate(6px, -2.1em) scale(0.7); opacity: 0.55; }
  100% { transform: translate(-4px, -3.4em) scale(0.2); opacity: 0; }
}

.subtitle {
  margin: 0.5rem 0 1.15rem;
  font-size: 15px;
  color: var(--fg-muted);
}

.dial {
  display: inline-block;
  font-family: var(--font-code);
  font-size: clamp(1.5rem, 4vw, 2.25rem);
  font-weight: 500;
  letter-spacing: 0.01em;
  color: var(--fg-default);
  text-decoration: none;
  border-bottom: 2px solid transparent;
  transition: border-color 0.2s ease;
  white-space: nowrap;
}

.dial:hover { border-bottom-color: var(--sw-fuchsia); }

.vanity__word {
  color: var(--sw-fuchsia);
  font-weight: 600;
}

/* The dialable number has to be readable from the back of the room, so it is
   nearly as large as the vanity spelling rather than a muted footnote. */
.dial__full {
  margin: 0.25rem 0 0;
  font-family: var(--font-code);
  font-size: clamp(1.25rem, 2.6vw, 2rem);
  font-weight: 500;
  letter-spacing: 0.01em;
  color: var(--fg-secondary);
}

.dial__hint {
  margin: 0.5rem 0 0;
  max-width: 38rem;
  font-size: 15px;
  color: var(--fg-secondary);
}

/* Deliberately light in both themes: inverted QR codes scan unreliably.
   Sized to be scannable from a few rows back, and it shrinks on a phone. */
.qr {
  display: block;
  width: clamp(190px, 19vw, 300px);
  height: clamp(190px, 19vw, 300px);
  padding: 10px;
  background: #FAFBFC;
  border-radius: var(--radius-md);
  border: 1px solid var(--border-default);
  flex-shrink: 0;
}

.qr svg { display: block; width: 100%; height: 100%; }

.qr:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px rgba(4, 78, 244, 0.3);
}

.status {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.35rem 0.85rem;
  background: var(--bg-surface-raised);
  border-radius: var(--radius-full);
  font-size: 13px;
  color: var(--fg-secondary);
}

.status__dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--fg-muted);
  flex-shrink: 0;
}

.status[data-state="live"] .status__dot {
  background: var(--sw-turquoise);
  box-shadow: 0 0 0 0 rgba(64, 224, 208, 0.5);
  animation: pulse 2.4s ease-out infinite;
}

.status[data-state="down"] .status__dot { background: var(--sw-fuchsia); }

@keyframes pulse {
  70% { box-shadow: 0 0 0 7px rgba(64, 224, 208, 0); }
  100% { box-shadow: 0 0 0 0 rgba(64, 224, 208, 0); }
}

/* ---------- layout ---------- */

main {
  max-width: var(--page-max);
  margin-inline: auto;
  padding: 1.75rem var(--gutter) 4rem;
}

.banner {
  margin: 0 0 1.5rem;
  padding: 0.7rem 1.1rem;
  background: rgba(247, 42, 114, 0.12);
  border: 1px solid var(--sw-fuchsia);
  border-radius: var(--radius-md);
  color: var(--fg-default);
  font-weight: 600;
  text-align: center;
}

.banner[hidden] { display: none; }

/* Chart and ticker side by side once there is room for both. */
.deck {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 1.25rem;
  align-items: start;
}

/* ---------- stat tiles ---------- */

.stats {
  display: flex;
  flex-wrap: wrap;
  gap: 1.25rem;
  margin-bottom: 1.25rem;
}

.stat {
  flex: 1 1 12rem;
  padding: 1.1rem 1.4rem;
  background: var(--bg-surface);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-lg);
}

.stat--hero { flex: 2 1 20rem; }

.stat__label {
  margin: 0;
  font-size: 13px;
  color: var(--fg-muted);
}

.stat__value {
  margin: 0.1rem 0 0;
  font-size: 2.25rem;
  font-weight: 600;
  line-height: 1.15;
  color: var(--fg-default);
}

/* Proportional figures on purpose: tabular digits look loose this large. */
.stat--hero .stat__value { font-size: clamp(3rem, 7vw, 5rem); }

/* ---------- the chart ---------- */

.chart {
  padding: 1.6rem 1.75rem 1.9rem;
  background: var(--bg-surface);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-lg);
}

.chart__title,
.activity__title {
  margin: 0 0 1.35rem;
  font-size: 15px;
  font-weight: 600;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--fg-muted);
}

.chart__empty {
  margin: 0;
  color: var(--fg-muted);
  font-size: 15px;
}

.chart__empty[hidden] { display: none; }

.bars {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 1.6rem;
}

.bars:empty { display: none; }

.bar__head {
  display: flex;
  align-items: baseline;
  gap: 0.6rem;
  margin-bottom: 0.5rem;
}

.bar__ballot {
  flex-shrink: 0;
  min-width: 1.65rem;
  padding: 0 0.35rem;
  font-family: var(--font-code);
  font-size: 13px;
  line-height: 1.5;
  text-align: center;
  color: var(--fg-muted);
  background: var(--bg-surface-raised);
  border-radius: 5px;
}

.bar__name {
  font-size: clamp(1.05rem, 1.6vw, 1.5rem);
  font-weight: 600;
  color: var(--fg-default);
  overflow-wrap: anywhere;
}

.bar__badge {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  flex-shrink: 0;
  padding: 0.1rem 0.65rem;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--fire-2);
  background: rgba(255, 106, 26, 0.12);
  border: 1px solid var(--fire-3);
  border-radius: var(--radius-full);
}

.bar__badge[hidden] { display: none; }

.bar__badge-icon {
  width: 11px;
  height: 14px;
  fill: currentColor;
  flex-shrink: 0;
}

/* Values sit at the tip of the row, in text ink rather than the bar's hue. */
.bar__value {
  margin-left: auto;
  flex-shrink: 0;
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  font-variant-numeric: tabular-nums;
}

.bar__count {
  font-size: clamp(1.05rem, 1.6vw, 1.5rem);
  font-weight: 600;
  color: var(--fg-default);
}

.bar__share {
  font-family: var(--font-code);
  font-size: 13px;
  color: var(--fg-muted);
}

.bar__track {
  height: var(--bar-thickness);
  background: var(--bar-track);
  border-radius: 4px;
  overflow: hidden;
}

/* 4px rounded data-end, square where it meets the baseline on the left. */
.bar__fill {
  height: 100%;
  width: 0;
  background: var(--series-1);
  border-radius: 0 4px 4px 0;
  transition: width 0.55s cubic-bezier(0.22, 0.8, 0.3, 1);
}

/* Cycled by ballot number, so the color belongs to the contestant. */
.bar[data-slot="1"] .bar__fill { background: var(--series-2); }
.bar[data-slot="2"] .bar__fill { background: var(--series-3); }

.bar--moved .bar__count { animation: tick 0.5s ease-out; }

@keyframes tick {
  0% { transform: scale(1); }
  35% { transform: scale(1.35); color: var(--fire-2); }
  100% { transform: scale(1); }
}

.bar--entering { animation: rise 0.35s ease-out; }

@keyframes rise {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: translateY(0); }
}

/* ---------- activity ticker ---------- */

.activity {
  padding: 1.6rem 1.75rem 1.9rem;
  background: var(--bg-surface);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-lg);
}

.activity__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.event {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.5rem;
  padding: 0.5rem 0.9rem;
  background: var(--bg-page);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  font-size: 14px;
}

.event--entering { animation: rise 0.35s ease-out; }

.event__voter {
  font-family: var(--font-code);
  color: var(--fg-muted);
}

.event__text { color: var(--fg-secondary); }

.event__name { font-weight: 600; color: var(--fg-default); }

.event__time {
  margin-left: auto;
  font-family: var(--font-code);
  font-size: 13px;
  color: var(--fg-muted);
}

@media (prefers-reduced-motion: reduce) {
  .bar__fill { transition: none; }
  .flame,
  .ember,
  .bar--moved .bar__count,
  .bar--entering,
  .event--entering,
  .status[data-state="live"] .status__dot { animation: none; }
  /* Keep the fire, just still. Embers would otherwise sit mid-air at 0 opacity. */
  .ember { opacity: 0.7; }
}

@media (min-width: 768px) {
  :root { --gutter: 2rem; --bar-thickness: 24px; }
}

@media (min-width: 1180px) {
  .deck { grid-template-columns: minmax(0, 2.35fr) minmax(0, 1fr); }
}
