/*
 * Kettenreaktion: Kachelmaß, Raster, Kachel, Funken und der Sprengplan, auf dem alles steht. Anzeigeleiste, Brettrand,
 * Knallbild, Abzeichen, Tafel und der Tisch darunter (`TISCHE.plan`) stehen als Rahmen des Spielfelds in
 * css/arena.css.
 *
 * Die Kachel ist so groß, wie Breite UND Höhe es erlauben, und nie kleiner als eine Tippfläche: vier Spalten auf
 * 375 Pixeln sind rund 80 Pixel je Kachel, fünf rund 63. Die Einzelbilder schaltet step-end, nie eine Kurve.
 *
 * Jede Regel auf der gemeinsamen Fläche hängt an [data-ar-spiel='kettenreaktion']: Die Stilblätter aller Spiele gelten
 * gleichzeitig, und bei gleicher Spezifität entschiede sonst die Reihenfolge der Dateien.
 */

/* Was neben dem Brett im Bild steht, rechnet der Rahmen als --ar-reserve; was darüber klebt, zieht --ar-hauskopf ab. */
.ar-spielfeld[data-ar-spiel='kettenreaktion'] {
  --ar-spalten: 4;
  --ar-zeilen: 5;
  --ar-fuge: 4px;
  /* Der Rand des Plans um die Kammern: Rahmenlinie und Reißnägel liegen darin. */
  --ar-kr-blatt: 0.9rem;
  /* Die Luft des Rahmens (--ar-brettluft) liegt innerhalb des Bretts und gehört in die Breite: Ohne sie ragte die letzte Spalte über die Kante des Bretts hinaus. */
  --ar-kachel: clamp(44px, min((100vw - 2 * var(--ar-luft) - 2 * (var(--ar-brettrand) + var(--ar-brettluft)) - (var(--ar-spalten) - 1) * var(--ar-fuge) - 2 * var(--ar-kr-blatt)) / var(--ar-spalten), (100vh - var(--ar-reserve) - var(--ar-hauskopf) - (var(--ar-zeilen) - 1) * var(--ar-fuge) - 2 * var(--ar-kr-blatt)) / var(--ar-zeilen)), 112px);
  --ar-brettbreite: calc(var(--ar-spalten) * var(--ar-kachel) + (var(--ar-spalten) - 1) * var(--ar-fuge) + 2 * var(--ar-kr-blatt) + 2 * (var(--ar-brettrand) + var(--ar-brettluft)));
  --ar-einheit: var(--ar-kachel);
}

/* 100vw zählt eine klassische Scrollleiste mit, und dann schob das Brett die Seite um 17 Pixel seitwärts. Wo es geht,
   rechnet die Kachel deshalb mit der Breite der Bühne (siehe .ar-buehne) und mit der sichtbaren Höhe. */
@supports (width: 1cqw) and (height: 1dvh) {
  .ar-spielfeld[data-ar-spiel='kettenreaktion'] {
    --ar-kachel: clamp(44px, min((100cqw - 2 * (var(--ar-brettrand) + var(--ar-brettluft)) - (var(--ar-spalten) - 1) * var(--ar-fuge) - 2 * var(--ar-kr-blatt)) / var(--ar-spalten), (100dvh - var(--ar-reserve) - var(--ar-hauskopf) - (var(--ar-zeilen) - 1) * var(--ar-fuge) - 2 * var(--ar-kr-blatt)) / var(--ar-zeilen)), 112px);
  }

  /*
   * Auf dem Schreibtisch darf die Kachel bis 140 px wachsen; --ar-feld ist die Breite der Bühne. Meist deckelt die Höhe:
   * Das Brett endet über dem Falz. Telefon und flaches Querformat erreichen diese Regel nicht.
   *
   * UND EIN TABLET QUER AUCH UNTER 1024 PIXELN. Die zweite Bedingung senkt die Breitenschwelle im Querformat auf
   * 768 Pixel — dieselbe Zahl wie beim Nagelbalken. Ohne sie blieb ein 800 oder 960 Pixel breites Tablet an der festen
   * Deckelung von 112 Pixeln hängen, obwohl 640 bis 800 Pixel Höhe für ein deutlich größeres Feld gereicht hätten:
   * eine starre Zahl, wo die Rechnung längst mehr hergab.
   */
  @media (min-width: 64rem) and (min-height: 30.0625rem),
    (orientation: landscape) and (min-width: 48rem) and (min-height: 30.0625rem) {
    .ar-spielfeld[data-ar-spiel='kettenreaktion'] {
      --ar-kachel: clamp(44px, min((var(--ar-feld) - 2 * (var(--ar-brettrand) + var(--ar-brettluft)) - (var(--ar-spalten) - 1) * var(--ar-fuge) - 2 * var(--ar-kr-blatt)) / var(--ar-spalten), (100dvh - var(--ar-reserve) - var(--ar-hauskopf) - (var(--ar-zeilen) - 1) * var(--ar-fuge) - 2 * var(--ar-kr-blatt)) / var(--ar-zeilen)), 140px);
    }
  }

  /*
   * UND AUF EINEM GROSSBILD NOCH EINMAL HÖHER. Auf 2560 × 1440 deckelte die Zahl darüber das Brett, obwohl Bühne und
   * Höhe mehr hergaben; das min() darin bleibt der Riegel, der Deckel ist nur seine Obergrenze.
   */
  @media (min-width: 100rem) and (min-height: 48rem) {
    .ar-spielfeld[data-ar-spiel='kettenreaktion'] {
      --ar-kachel: clamp(44px, min((var(--ar-feld) - 2 * (var(--ar-brettrand) + var(--ar-brettluft)) - (var(--ar-spalten) - 1) * var(--ar-fuge) - 2 * var(--ar-kr-blatt)) / var(--ar-spalten), (100dvh - var(--ar-reserve) - var(--ar-hauskopf) - (var(--ar-zeilen) - 1) * var(--ar-fuge) - 2 * var(--ar-kr-blatt)) / var(--ar-zeilen)), 180px);
    }
  }
}

/*
 * DER SPRENGPLAN IST EINE BLAUPAUSE: Preußischblau mit einer weißen Rahmenlinie um die Kammern, ein Reißnagel in jeder
 * Ecke und ein harter Schatten auf dem Filz. Er steht mitten auf dem Tisch, der den ganzen Rahmen nimmt (`TISCHE.plan`).
 */
.ar-brett__raster {
  position: relative;
  display: grid;
  grid-template-columns: repeat(var(--ar-spalten), var(--ar-kachel));
  grid-auto-rows: var(--ar-kachel);
  gap: var(--ar-fuge);
  width: fit-content;
  margin-inline: auto;
  padding: var(--ar-kr-blatt);
  background: var(--ar-plan-blau);
  box-shadow:
    inset 0 0 0 0.4rem var(--ar-plan-blau),
    inset 0 0 0 calc(0.4rem + 1.5px) var(--ar-plan-weiss),
    0.3rem 0.4rem 0 var(--ar-ku-schlagschatten);
}

/*
 * DIE KACHEL IST EINE KAMMER IM PLAN: kein eigener Grund, die Wände in der Linie des Plans. Sie ist für alle auf einer
 * Farbe ein Knopf, und ihre Wand hält gegen das Blau 3,16 : 1.
 */
.ar-kachel {
  position: relative;
  display: block;
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
  border: 2px solid var(--ar-plan-wand);
  border-radius: 0;
  background: none;
  appearance: none;
}

button.ar-kachel {
  cursor: pointer;
}

button.ar-kachel[aria-disabled='true'] {
  cursor: default;
}

.ar-kachel__bild {
  display: block;
  width: 100%;
  height: 100%;
}

/*
 * DIE ZAHL AUF DER KACHEL: Stangen und Platz, „1/2“. Sie sitzt oben rechts, wo weder die Marke (oben links) noch die
 * Stangen (ab 28 Prozent Höhe) liegen, und ersetzt keine Zeichnung: Die Halter zeigen dasselbe als Bild. Sie hat einen
 * eigenen Grund, damit sie über den Funken einer vollen Kachel lesbar bleibt. Die Größe folgt der Kachel (16 Prozent,
 * nie unter 10 Pixeln); die Kachel selbst ändert sich nicht, die Zahl liegt absolut darauf. Kreide auf Noir hält
 * 16,26:1, Kreide-2 8,80:1, der Funke 7,97:1.
 */
.ar-kr-zahl {
  position: absolute;
  top: 0;
  right: 0;
  padding: 0 0.2em;
  border: 1px solid transparent;
  background: var(--ar-noir);
  color: var(--ar-kreide);
  font-family: var(--ar-schrift-mono);
  font-size: clamp(10px, calc(var(--ar-kachel) * 0.16), 24px);
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  line-height: 1.15;
  hyphens: none;
  white-space: nowrap;
}

.ar-kachel[data-ar-besitz='leer'] .ar-kr-zahl {
  color: var(--ar-kreide-2);
}

.ar-kachel[data-ar-besitz='rot'] {
  --ar-wischfarbe: var(--ar-rot);
  border-bottom: var(--ar-farbkante) solid var(--ar-rot);
}

.ar-kachel[data-ar-besitz='blau'] {
  --ar-wischfarbe: var(--ar-blau);
  border-bottom: var(--ar-farbkante) solid var(--ar-blau);
}

.ar-kachel[data-ar-besitz='gelb'] {
  --ar-wischfarbe: var(--ar-gelb);
  border-bottom: var(--ar-farbkante) solid var(--ar-gelb);
}

.ar-kachel[data-ar-besitz='gruen'] {
  --ar-wischfarbe: var(--ar-gruen);
  border-bottom: var(--ar-farbkante) solid var(--ar-gruen);
}

/*
 * EIN SPERRFELD IST KEIN BEDIENELEMENT. Es steht als <div> im Markup, trägt keinen Tabstopp und bekommt deshalb
 * auch keine Griffkante: dunkler Grund, ein zurückgenommener Rahmen, keine Wischfarbe, kein Zeiger. Was es ist,
 * sagt der Tresor darauf — die Kante sagt nur, dass hier nichts zu holen ist.
 */
.ar-kachel[data-ar-besitz='tresor'] {
  border: 2px dashed var(--ar-plan-wand);
  border-bottom: 2px dashed var(--ar-plan-wand);
  background: var(--ar-plan-blau-tief);
  cursor: default;
}

/*
 * SETZBAR HEISST HELLER GRUND UND VOLLE KREIDE, und nur am eigenen Zug (`setzbarStellen()` in brett.js): Wer drankommt,
 * sieht das Brett aufleuchten, ohne Schein — die Kante wird hell, der Grund eine Stufe heller. Die Unterkante behält die
 * Farbe des Besitzers.
 *
 * DIE KANTE STAND AUF KREIDE-2, und gegen die Griffkante einer fremden Kachel hielt sie 1,99 : 1, der Grund daneben
 * 1,16 : 1. Welche Kachel man antippen darf, stand damit in einem Grauton unter den 3 : 1, die eine Kante tragen muss,
 * wenn sie etwas sagt. Auf der Blaupause ist es das Weiß des Plans: 3,14 : 1 gegen die Wand daneben und 8,4 : 1 auf dem
 * helleren Blau der setzbaren Kammer.
 */
.ar-kachel[data-ar-setzbar] {
  border-color: var(--ar-plan-weiss);
  border-bottom-color: var(--ar-wischfarbe, var(--ar-plan-weiss));
  background: var(--ar-plan-blau-licht);
}

/*
 * Heller als volle Kreide geht nicht: Unter der Maus zieht deshalb eine zweite Kreidekante innen nach, hart und ohne
 * Unschärfe wie der Glut-Rand weiter unten. Eine volle Kachel behält ihren Glut-Rand; er sagt dort mehr.
 */
@media (hover: hover) {
  .ar-kachel[data-ar-setzbar]:not([data-ar-voll]):hover {
    box-shadow: inset 0 0 0 2px var(--ar-plan-weiss);
  }
}

.ar-kachel:focus-visible {
  z-index: 1;
  outline-offset: -2px;
}

.ar-kachel[data-ar-zunder] {
  border-color: var(--ar-funke);
}

/* Der Wisch in der neuen Farbe steht genau ein Bild lang: ein Halbtonraster, kein Verlauf. */
.ar-kachel[data-ar-wisch] {
  background-image: radial-gradient(circle, var(--ar-wischfarbe) 34%, transparent 36%);
  background-size: 9px 9px;
}

.ar-kachel[data-ar-nein]::before,
.ar-kachel[data-ar-nein]::after {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 72%;
  height: 14%;
  border: 3px solid var(--ar-noir);
  background: var(--ar-kreide);
  content: '';
  translate: -50% -50%;
  rotate: 45deg;
}

.ar-kachel[data-ar-nein]::after {
  rotate: -45deg;
}

/*
 * DIE ZISCHENDE LUNTE: ein heller Punkt auf dunkler Schnur, der von der Spitze zur Stange wandert.
 *
 * ER GLÜHT NICHT, ER IST HELL. „Terminals leuchten durch Kontrast, nicht durch Schein" gilt auch für eine Zündschnur:
 * kein Filter, kein Halo, kein Weichzeichner — ein Punkt in Senf mit Tuschekante auf der Schnur aus Kreide.
 *
 * ER BRENNT NUR, SOLANGE GEZÜNDET WIRD, und nicht in einer eigenen Schleife: Der Zündpfad setzt `data-ar-zunder` für
 * genau die Zeit, die der Server als Zünden ausgibt (`--ar-zuenden` aus sp.takt), und eine Bildfolge, die erst mit dem
 * `display` beginnt, steht damit bei allen vier Browsern im selben Bild. Eine Schleife, die von selbst liefe, hinge an
 * der Uhr des Browsers, und vier Tische zeigten vier verschiedene Funken.
 *
 * DIE DREI BILDER SIND DIE BAHN DER LUNTE, abgegriffen an ihrem Bogen im Dynamit-Symbol (js/grafik.js). Wer die Kurve
 * dort ändert, rechnet sie hier nach.
 */
.ar-kr-lunte {
  display: none;
}

.ar-kachel[data-ar-zunder] .ar-kr-lunte {
  display: inline;
}

.ar-kr-lunte__funke {
  fill: var(--ar-funke);
  stroke: var(--ar-noir);
  stroke-width: 1.2;
  animation: ar-kr-lunte var(--ar-zuenden, 180ms) step-end 1 both;
}

@keyframes ar-kr-lunte {
  0% { translate: 14px 2px; }
  33.3% { translate: 13.9px 7.2px; }
  66.6% { translate: 11.5px 10.5px; }
  100% { translate: 10px 15px; }
}

/*
 * DIE WURFSTANGEN EINER WELLE: Je Nachbarfeld fliegt eine Stange im Bogen hinüber — drei harte Bilder in der Länge
 * einer Welle, also dieselben neunzig Millisekunden wie das Knallbild darunter. Sie federn nicht und wippen nicht
 * nach; die Drehung springt mit.
 */
.ar-kr-wurf {
  transform-box: fill-box;
  transform-origin: 50% 50%;
  animation: ar-kr-wurf var(--ar-welle) step-end 1 both;
}

@keyframes ar-kr-wurf {
  0% {
    rotate: 0deg;
    translate: 0 0;
  }

  33.3% {
    rotate: 70deg;
    translate: calc(var(--ar-zx) * 0.333) calc(var(--ar-zy) * 0.333 - var(--ar-hoch) * 0.89);
  }

  66.6% {
    rotate: 140deg;
    translate: calc(var(--ar-zx) * 0.667) calc(var(--ar-zy) * 0.667 - var(--ar-hoch) * 0.89);
  }

  100% {
    opacity: 0;
    rotate: 210deg;
    translate: var(--ar-zx) var(--ar-zy);
  }
}

/* Wer wenig Bewegung bestellt hat, bekommt keine: Beide tragen keine Auskunft, die nicht auch auf der Kachel steht. */
@media (prefers-reduced-motion: reduce) {
  .ar-kr-wurf {
    display: none;
  }

  .ar-kr-lunte__funke {
    animation: none;
    translate: 14px 2px;
  }
}

/* Zwei gleich helle Sterne im Wechsel, zweimal je Sekunde: Das Feld lebt, ohne zu blitzen. */
.ar-funke__a {
  animation: ar-funke-a 500ms step-end infinite;
}

.ar-funke__b {
  opacity: 0;
  animation: ar-funke-b 500ms step-end infinite;
}

@keyframes ar-funke-a {
  0% { opacity: 1; }
  50% { opacity: 0; }
}

@keyframes ar-funke-b {
  0% { opacity: 0; }
  50% { opacity: 1; }
}

/*
 * DER GLUT-RAND EINER VOLLEN KACHEL: drei Pixel Kante innen, im Wechsel Funke und Rot, zwei harte Bilder in 1,2 Sekunden
 * — dieselbe Länge wie der Puls des Rahmens und ein anderer Takt als der Funke darüber, damit beide nicht als ein
 * Blinken gelesen werden. Es ist eine Kante und kein Schein. Er liegt unter der Zeichnung, also hinter Marke und Stangen,
 * und die Unterkante in der Farbe des Besitzers bleibt daneben stehen. Wer wenig Bewegung bestellt hat, sieht ihn
 * ruhig in Funke, und die Zahl trägt dasselbe noch einmal als Wort.
 */
.ar-kachel[data-ar-voll] {
  box-shadow: inset 0 0 0 3px var(--ar-funke);
  animation: ar-kr-glut 1200ms step-end infinite;
}

@keyframes ar-kr-glut {
  0% { box-shadow: inset 0 0 0 3px var(--ar-funke); }
  50% { box-shadow: inset 0 0 0 3px var(--ar-rot); }
}

.ar-kachel[data-ar-voll] .ar-kr-zahl {
  border-color: var(--ar-funke);
  color: var(--ar-funke);
}

/* Der Fokusring ist auch Funke; auf einer vollen Kachel wäre er von ihrem Rand nicht zu unterscheiden. */
.ar-kachel[data-ar-voll]:focus-visible {
  outline-color: var(--ar-kreide);
}

@media (prefers-reduced-motion: reduce) {
  .ar-funke__a,
  .ar-funke__b,
  .ar-kachel[data-ar-voll] {
    animation: none;
  }
}

/*
 * DIE ERKLÄRUNG EINES TIPPS, DER NICHT ANKÄME (brett.js, `warum()`): ein Streifen im Raster, in der Hälfte, die das
 * getippte Feld frei lässt. Er liegt über den Kacheln und nimmt keinen Tipp an, damit der nächste Griff darunter
 * ankommt; er geht nach anderthalb Sekunden von selbst, ohne Übergang. Der Noir-Grund hält die Kreide-Schrift auf jeder
 * Kachel darunter bei 16,26:1, die Funke-Kante hebt den Streifen ab; gesagt wird der Grund als Satz und nie durch Farbe.
 */
.ar-kr-erklaerung {
  position: absolute;
  right: 0;
  left: 0;
  z-index: 3;
  margin: 0;
  padding: 0.35rem 0.5rem;
  border: 3px solid var(--ar-funke);
  background: var(--ar-noir);
  color: var(--ar-kreide);
  font-size: 0.85rem;
  font-weight: 700;
  line-height: 1.25;
  text-align: center;
  pointer-events: none;
}

.ar-kr-erklaerung[data-ar-ort='oben'] {
  top: 0;
}

.ar-kr-erklaerung[data-ar-ort='unten'] {
  bottom: 0;
}

/* Das Schild des Frühmatch-Schutzes steht im freien Platz der Leiste, die der Rahmen zeichnet. */
.ar-hud__schutz {
  flex: none;
  width: 1.1rem;
  height: 1.1rem;
}

/* BOOM! kommt mitten in der Runde und ist deshalb kleiner als das KAWUMM! des Siegzugs. */
.ar-abzeichen[data-ar-art='boom'] {
  width: min(72%, 15rem);
}

.ar-abzeichen[data-ar-art='boom'] .ar-abzeichen__wort {
  font-size: min(2.2rem, calc(var(--ar-einheit) * 0.32));
}

/* ------------------------------------------------------------ Farben im SVG */

.ar-g-schraffurstrich { stroke: var(--ar-kr-schraffur, var(--ar-noir-3)); stroke-width: 3; }

/*
 * IM PLAN STEHT DIE SCHRAFFUR IN DER LINIE DER BLAUPAUSE, in Schild und Bildkarten bleibt sie dunkel. Gezeichnet ist sie
 * über `<use>`, und ein Selektor wie `.ar-kachel .ar-g-schraffurstrich` erreicht nichts, was dort steht (README der
 * Arena, Abschnitt 3): Die Kachel setzt deshalb eine Eigenschaft, die in das Symbol hineinerbt. Der Tresor auf einem
 * Sperrfeld bleibt Stahl.
 */
.ar-kachel { --ar-kr-schraffur: var(--ar-plan-wand); }
