/*
 * asteroids-ml — the site's identity, and it is its own.
 *
 * THEME COLOUR  #a78bfa   indigo, taken by nothing else in the family
 * BACKGROUND    #050a12   a near-black of the same hue
 * DRAWING       three soft glows over a slow base (3 radial + 2 linear), and a
 *               separate layer painting the ball's own geometry: a diamond mesh
 *               with wide vertical rails, faded by a mask — the lattice a rally
 *               draws across the court when you watch one for a while.
 *               Measured signature: 4 radial + 5 linear + masked. No site in the
 *               register shares it. There is no gradient anywhere else in this
 *               file, and no `background-size` in pixels, because both would
 *               change that signature by accident.
 *
 * The pattern is its OWN layer rather than another entry in the base gradient
 * stack: a mask on the base would fade the page's own colour with the pattern.
 */

:root {
  --bg: #050a12;
  --panel: rgba(21, 16, 48, 0.72);
  --panel-solid: #151030;
  --accent: #a78bfa;
  --accent-lit: #c4b5fd;
  --accent-deep: #5b21b6;
  --pale: #ddd6fe;
  --text: #e9ecff;
  --muted: #a3abd4;
  --hairline: rgba(167, 139, 250, 0.24);
  --danger: #fb7185;
  --radius: 14px;
  --container: 1080px;
  --consent-height: 0px;
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

[hidden] {
  display: none !important;
}

html {
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  min-height: 100vh;
  padding-bottom: calc(var(--consent-height) + 8px);
  background-color: var(--bg);
  background-image:
    radial-gradient(58% 42% at 18% 4%, rgba(167, 139, 250, 0.3) 0%, rgba(167, 139, 250, 0) 68%),
    radial-gradient(52% 40% at 84% 12%, rgba(124, 58, 237, 0.26) 0%, rgba(124, 58, 237, 0) 70%),
    radial-gradient(70% 52% at 50% 104%, rgba(196, 181, 253, 0.16) 0%, rgba(196, 181, 253, 0) 66%),
    linear-gradient(168deg, rgba(44, 28, 86, 0.9) 0%, rgba(10, 7, 36, 0) 62%),
    linear-gradient(0deg, rgba(167, 139, 250, 0.05) 0%, rgba(167, 139, 250, 0) 55%);
  background-attachment: fixed;
  color: var(--text);
  font-family: system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

/* The drawing. Its own fixed layer, masked so it dissolves rather than stopping.
   THE DRAWING IS CONCENTRIC ORBITS. Rings of rock, seen from above, with one lattice to
   measure them by — not a chequerboard and not a lattice on its own, because the point of
   this layer is that a visitor can tell this site from its siblings at a glance. */
.dvs-pattern {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-image:
    repeating-radial-gradient(circle at 50% 38%, rgba(167, 139, 250, 0.13) 0 1px, transparent 1px 118px),
    repeating-linear-gradient(90deg, rgba(196, 181, 253, 0.09) 0 1px, transparent 1px 118px);
  mask-image: radial-gradient(96% 78% at 50% 26%, #000 0%, rgba(0, 0, 0, 0.5) 46%, transparent 82%);
  -webkit-mask-image: radial-gradient(96% 78% at 50% 26%, #000 0%, rgba(0, 0, 0, 0.5) 46%, transparent 82%);
}

a {
  color: var(--accent-lit);
}

/* ------------------------------------------------------------------ the bar */

.top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  position: sticky;
  top: 0;
  z-index: 10;
  padding: 12px 20px;
  background: rgba(10, 7, 36, 0.82);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--hairline);
}

.brand {
  display: flex;
  align-items: center;
  gap: 10px;
  text-decoration: none;
  color: var(--text);
}

.brand .mark {
  width: 26px;
  height: 26px;
  display: block;
  flex: none;
}

.brand b {
  display: block;
  font-size: 15px;
  line-height: 1.1;
  letter-spacing: 0.2px;
}

.brand small {
  display: block;
  font-size: 11.5px;
  line-height: 1.2;
  letter-spacing: 0.4px;
  text-transform: uppercase;
  color: var(--muted);
}

/* --------------------------------------------------------------- the column */

main {
  position: relative;
  z-index: 1;
  max-width: var(--container);
  margin: 0 auto;
  padding: 30px 20px 56px;
}

section + section {
  margin-top: 34px;
}

h1 {
  font-size: clamp(1.9rem, 5.2vw, 3rem);
  line-height: 1.1;
  letter-spacing: -0.02em;
  margin: 0 0 14px;
}

h2 {
  font-size: clamp(1.25rem, 2.8vw, 1.6rem);
  line-height: 1.2;
  margin: 0 0 12px;
}

h3 {
  font-size: 1rem;
  margin: 0 0 6px;
}

p {
  margin: 0 0 14px;
}

.lede {
  font-size: 1.09rem;
  color: var(--text);
  max-width: 62ch;
}

.sub {
  color: var(--muted);
  max-width: 68ch;
}

.belief {
  color: var(--pale);
}

.card {
  background: var(--panel);
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
  padding: 22px;
}

.card + .card {
  margin-top: 16px;
}

/* ----------------------------------------------------------------- the court */

.court-card {
  padding: 16px;
}

.court-frame {
  position: relative;
  width: 100%;
  /* SQUARE, because the arena is. One world unit is one drawing unit and there is no aspect
     ratio to correct — a wide court would mean a stretched ship or letterbox bars pretending
     to be space. */
  aspect-ratio: 1 / 1;
  max-width: 760px;
  margin: 0 auto;
  border-radius: 10px;
  overflow: hidden;
  background: var(--bg);
  border: 1px solid var(--hairline);
}

#court {
  display: block;
  width: 100%;
  height: 100%;
}

.hud {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(112px, 1fr));
  gap: 12px 18px;
  margin: 18px 0 4px;
}

/* TWO SCOREBOARDS, ONE RALLY. The table is the two learners; the grid above it is the
   rally they are taking part in, which is one number rather than two. */
.sides {
  width: 100%;
  border-collapse: collapse;
  margin: 6px 0 10px;
  font-variant-numeric: tabular-nums;
}

.sides caption {
  caption-side: top;
  text-align: left;
  font-size: 0.8rem;
  color: var(--muted);
  padding-bottom: 6px;
}

.sides th,
.sides td {
  text-align: right;
  padding: 7px 10px;
  border-bottom: 1px solid var(--hairline);
}

.sides thead th {
  font-size: 0.7rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
}

.sides tbody th {
  text-align: left;
  font-weight: 500;
  color: var(--muted);
  font-size: 0.85rem;
}

.sides td {
  font-size: 1.1rem;
}

.sides thead th:first-child {
  text-align: left;
}

.stat-k {
  display: block;
  font-size: 0.7rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
}

.stat-v {
  display: block;
  font-size: 1.25rem;
  font-variant-numeric: tabular-nums;
  line-height: 1.25;
}

.status-line {
  color: var(--muted);
  margin: 0 0 16px;
}

.controls {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 16px;
  padding-top: 4px;
  border-top: 1px solid var(--hairline);
  margin-top: 12px;
}

.field {
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-size: 0.78rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
}

.field-wide {
  flex: 1 1 320px;
  min-width: 240px;
}

.field output {
  color: var(--text);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0;
  text-transform: none;
  font-size: 0.95rem;
}

select,
input[type='range'] {
  font: inherit;
  color: var(--text);
  background: var(--panel-solid);
  border: 1px solid var(--hairline);
  border-radius: 9px;
  padding: 7px 10px;
}

input[type='range'] {
  width: 100%;
  accent-color: var(--accent-lit);
  padding: 0;
  border: 0;
  background: transparent;
}

.slider-track {
  position: relative;
  height: 22px;
}

.slider-track .cap-marker {
  position: absolute;
  top: 15px;
  width: 2px;
  height: 9px;
  background: var(--pale);
  opacity: 0.8;
  transform: translateX(-1px);
  pointer-events: none;
}

.btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font: inherit;
  font-size: 0.9rem;
  color: var(--text);
  background: var(--accent-deep);
  border: 1px solid transparent;
  border-radius: 9px;
  padding: 9px 15px;
  cursor: pointer;
}

.btn:hover {
  background: var(--accent);
}

.btn-ghost {
  background: transparent;
  border-color: var(--hairline);
  color: var(--muted);
}

.btn-ghost:hover {
  background: rgba(99, 102, 241, 0.14);
  color: var(--text);
}

.hint {
  font-size: 0.86rem;
  color: var(--muted);
  margin: 14px 0 0;
}

.hint:empty {
  display: none;
}

/* ------------------------------------------------------------------ the rest */

.ledger {
  margin: 0;
  padding-left: 1.1rem;
}

.ledger li {
  margin-bottom: 8px;
}

.ledger b {
  color: var(--pale);
  font-weight: 600;
}

.derivation {
  color: var(--muted);
  font-size: 0.94rem;
}

/* ------------------------------------------------- the charts, five of them */

/* ONE COLUMN ON A PHONE, TWO ON ANYTHING WIDER. A line chart 200 pixels across is not a chart, it
   is a scribble, so the minimum is set where the axes still read — and the count is fixed at two
   rather than left to "as many as fit", because the four smaller charts at three columns leave an
   orphan. The progress chart takes the whole width above them: it is the one a reader should meet
   first, and a wide axis is what lets a slow climb be read as a climb. */
.charts {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 18px;
  margin: 6px 0 12px;
}

@media (max-width: 720px) {
  .charts {
    grid-template-columns: 1fr;
  }
}

.chart-box {
  margin: 0;
}

.chart-box--wide {
  grid-column: 1 / -1;
}

.chart-box figcaption {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin-bottom: 6px;
  font-size: 0.8rem;
  line-height: 1.45;
  color: var(--muted);
}

.chart-box figcaption b {
  font-size: 0.92rem;
  color: var(--text);
}

/* The number beside the title, so the current value is readable without tracing a line to the axis —
   the same readout the sibling project puts on its landing-rate chart. */
.chart-value {
  font-size: 1.25rem;
  font-variant-numeric: tabular-nums;
  color: var(--text);
  letter-spacing: 0.01em;
}

.chart {
  display: block;
  width: 100%;
  height: 190px;
  border-radius: 8px;
  /* A flat tint rather than a border: a border changes the canvas's box, and the chart sizes its own
     drawing surface from that box. */
  background: rgba(167, 139, 250, 0.045);
}

.plain {
  color: var(--muted);
  font-size: 0.9rem;
}

.door {
  display: inline;
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  color: var(--accent-lit);
  font: inherit;
  cursor: pointer;
  text-decoration: underline;
}

/* ----------------------------------------------------------------- the gate */

.consent-bar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 30;
  background: rgba(12, 9, 42, 0.96);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border-top: 1px solid var(--hairline);
  padding: 14px 20px;
}

.consent-inner {
  max-width: var(--container);
  margin: 0 auto;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px 18px;
}

.consent-ask,
.consent-prefs {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px 18px;
  width: 100%;
}

.consent-copy {
  flex: 1 1 320px;
  margin: 0;
  font-size: 0.9rem;
  color: var(--muted);
}

.consent-actions {
  display: flex;
  gap: 12px;
}

.consent-close {
  margin-left: auto;
  background: none;
  border: 0;
  color: var(--muted);
  font-size: 1.3rem;
  line-height: 1;
  cursor: pointer;
  padding: 4px 6px;
}

.switch {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font: inherit;
  font-size: 0.9rem;
  color: var(--text);
  background: transparent;
  border: 0;
  cursor: pointer;
  padding: 0;
}

.switch-track {
  width: 42px;
  height: 24px;
  border-radius: 999px;
  border: 1px solid var(--hairline);
  background: rgba(10, 7, 36, 0.9);
  position: relative;
  flex: none;
}

.switch-track::after {
  content: '';
  position: absolute;
  top: 3px;
  left: 3px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--muted);
  transition: transform 120ms ease;
}

.switch[aria-checked='true'] .switch-track::after {
  transform: translateX(18px);
  background: var(--accent-lit);
}

.consent-word {
  min-width: 2ch;
  color: var(--muted);
}

/* ----------------------------------------------------------------- the foot */

.site-footer {
  position: relative;
  z-index: 1;
  max-width: var(--container);
  margin: 0 auto;
  padding: 26px 20px 40px;
  border-top: 1px solid var(--hairline);
  font-size: 0.88rem;
  color: var(--muted);
}

.footer-brand {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 10px;
  color: var(--text);
}

.footer-brand .mark {
  width: 22px;
  height: 22px;
  display: block;
  flex: none;
}

.footer-links {
  margin: 0 0 10px;
}

.footer-copy {
  margin: 0;
}

.footer-links a,
.footer-links .door {
  color: var(--accent-lit);
}

/* ------------------------------------------------------------------- motion */

@media (prefers-reduced-motion: reduce) {
  * {
    transition-duration: 0.001ms !important;
  }
}

@media (max-width: 640px) {
  main {
    padding: 22px 16px 48px;
  }
  .card {
    padding: 18px;
  }
  .court-card {
    padding: 12px;
  }
  .hud {
    grid-template-columns: repeat(auto-fit, minmax(96px, 1fr));
  }
}

/* ------------------------------------------------- the pilot's own instrument panel */

/* The reward, printed as arithmetic rather than as prose. A reward a reader cannot check is a
   claim they have to take on trust, and this page exists so they do not have to. */
.reward-table {
  width: 100%;
  border-collapse: collapse;
  font-variant-numeric: tabular-nums;
  margin: 6px 0 12px;
}

.reward-table th,
.reward-table td {
  text-align: left;
  padding: 7px 10px;
  border-bottom: 1px solid var(--hairline);
  font-size: 0.92rem;
}

.reward-table td:last-child {
  text-align: right;
  white-space: nowrap;
}

.reward-table th {
  font-size: 0.7rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  font-weight: 500;
}

/* The switch. One control, two states, and the page's finding hangs on it. */
.switch-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px 14px;
  margin: 10px 0 4px;
}

.switch {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  cursor: pointer;
  font-size: 0.92rem;
}

.switch input {
  inline-size: 17px;
  block-size: 17px;
  accent-color: var(--accent);
}

/* The ring key: a small drawing of the thing the court draws, so the legend needs no caption. */
.ring-key {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  color: var(--muted);
  font-size: 0.85rem;
}

.ring-key svg {
  inline-size: 34px;
  block-size: 34px;
  flex: none;
}

.plain-note {
  color: var(--muted);
  font-size: 0.9rem;
  margin: 10px 0 0;
}

/* What the examination says, in one line, with the state carried by the colour. */
.exam {
  display: inline-block;
  padding: 4px 11px;
  border-radius: 999px;
  border: 1px solid var(--hairline);
  font-size: 0.8rem;
  letter-spacing: 0.03em;
  color: var(--muted);
}

.exam[data-state='held'] {
  color: var(--pale);
  border-color: rgba(221, 214, 254, 0.55);
}

.exam[data-state='failed'] {
  color: var(--danger);
  border-color: rgba(251, 113, 133, 0.5);
}
