/*
 * Käsekästchen: Teilung, Brett, Linien, Griffe, der Knopf „Ziehen“, die Leiste „Zurücknehmen“, der Pop eines geholten
 * Kästchens und der Katasterplan, auf dem das alles steht. Anzeigeleiste, Brettrand, Tafel und der Tisch darunter
 * (`TISCHE.plan`) stehen als Rahmen des Spielfelds in css/arena.css.
 *
 * Die Teilung ist die Breite eines Kästchens. Das Brett ist so breit, wie Breite UND Höhe es erlauben, und hat um die
 * äußeren Punkte eine Luft von 0,3 Teilungen je Seite. Jede Regel hängt an [data-ar-spiel='kaesekaestchen'] oder an den
 * Klassen ar-kk und ar-g-kk.
 */

/*
 * Was neben dem Brett im Bild steht, rechnet der Rahmen als --ar-reserve; dazu kommt hier der Knopf „Ziehen“. Die
 * Untergrenze der Teilung ist keine Tippfläche wie die Kachel von Kettenreaktion: Das Brett ist eine Fläche, auf der
 * jede Linie ihren eigenen Griff hat, und der wächst mit der Teilung mit. Mit 40 px ragte ein 5 × 5 samt Knopf auf
 * 667 × 375 unter den Falz.
 */
.ar-spielfeld[data-ar-spiel='kaesekaestchen'] {
  --ar-spalten: 5;
  --ar-zeilen: 5;
  --ar-ziehen-hoehe: 0px;
  /* 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-teilung: clamp(30px, min((100vw - 2 * var(--ar-luft) - 2 * (var(--ar-brettrand) + var(--ar-brettluft))) / (var(--ar-spalten) + 0.6), (100vh - var(--ar-reserve) - var(--ar-hauskopf) - var(--ar-ziehen-hoehe)) / (var(--ar-zeilen) + 0.6)), 112px);
  --ar-brettbreite: calc((var(--ar-spalten) + 0.6) * var(--ar-teilung) + 2 * (var(--ar-brettrand) + var(--ar-brettluft)));
  --ar-einheit: var(--ar-teilung);
}

@supports (width: 1cqw) and (height: 1dvh) {
  .ar-spielfeld[data-ar-spiel='kaesekaestchen'] {
    --ar-teilung: clamp(30px, min((100cqw - 2 * (var(--ar-brettrand) + var(--ar-brettluft))) / (var(--ar-spalten) + 0.6), (100dvh - var(--ar-reserve) - var(--ar-hauskopf) - var(--ar-ziehen-hoehe)) / (var(--ar-zeilen) + 0.6)), 112px);
  }

  /*
   * Auf dem Schreibtisch darf die Teilung bis 140 px wachsen; --ar-feld ist die Breite der Bühne. Meist deckelt die Höhe:
   * Das Brett samt „Ziehen“ endet über dem Falz. Telefon und flaches Querformat erreichen diese Regel nicht.
   */
  @media (min-width: 64rem) and (min-height: 30.0625rem) {
    .ar-spielfeld[data-ar-spiel='kaesekaestchen'] {
      --ar-teilung: clamp(30px, min((var(--ar-feld) - 2 * (var(--ar-brettrand) + var(--ar-brettluft))) / (var(--ar-spalten) + 0.6), (100dvh - var(--ar-reserve) - var(--ar-hauskopf) - var(--ar-ziehen-hoehe)) / (var(--ar-zeilen) + 0.6)), 160px);
    }
  }

  /*
   * 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.
   *
   * DER DECKEL IST NICHT DER ENGPASS AUF EINEM BREITEN 16:9-SCHIRM. Auf 1920 × 1080 blieb rings um das quadratische
   * Brett reichlich Naturpapier-Schwarz übrig — nicht, weil hier ein Deckel griff (die Teilung lag deutlich darunter),
   * sondern weil ein quadratisches Fünf-mal-fünf-Raster auf einem Querformat-Schirm von der HÖHE begrenzt wird, sobald
   * es ohne Scrollbalken bleiben soll (Abschnitt 10: kein vertikaler Scroll). Angehoben ist hier trotzdem die
   * Obergrenze, für hohe oder quadratische Schirme, auf denen die Höhe mehr hergibt — eine echte Lösung für das
   * 16:9-Schwarz bräuchte einen kleineren Reserve-Etat oder Begleitinhalt neben dem Brett, beides nicht in diesem
   * Durchlauf angefasst.
   */
  @media (min-width: 100rem) and (min-height: 48rem) {
    .ar-spielfeld[data-ar-spiel='kaesekaestchen'] {
      --ar-teilung: clamp(30px, min((var(--ar-feld) - 2 * (var(--ar-brettrand) + var(--ar-brettluft))) / (var(--ar-spalten) + 0.6), (100dvh - var(--ar-reserve) - var(--ar-hauskopf) - var(--ar-ziehen-hoehe)) / (var(--ar-zeilen) + 0.6)), 290px);
    }
  }
}

/*
 * DIE VIER MATT-TÖNE STEHEN AN DER WURZEL UND NICHT AM SPIELFELD: Dieselben Kästchen stehen im Banner, im Schild und
 * in den Bildkarten der Einweisung, also AUSSERHALB des Bretts; ein Symbol, dessen fill auf eine Variable des
 * Spielfelds zeigt, fiele dort auf Schwarz zurück. Der Präfix --ar-kk- hält sie trotzdem für sich.
 *
 * Jeder hält gegen das Blatt (--ar-noir-2) mindestens 3 : 1, wie WCAG 1.4.11 es für alles verlangt, was keine Schrift
 * ist und trotzdem etwas sagt: Rot 3,30, Blau 3,32, Gelb 4,11, Grün 3,57. Satter als die Signalfarbe darf er nicht
 * sein — auf einem vollen Brett liegt er auf jedem Kästchen.
 */
:root {
  --ar-kk-feld-rot: #b04a35;
  --ar-kk-feld-blau: #3a6f96;
  --ar-kk-feld-gelb: #857a2c;
  --ar-kk-feld-gruen: #3f7d36;
}

/* Das Blatt liegt mitten auf dem Tisch, der den ganzen Rahmen nimmt; der Knopf „Ziehen“ steht darunter. */
.ar-kk {
  display: grid;
  justify-items: center;
  gap: 0.6rem;
}

.ar-kk__flaeche {
  position: relative;
}

.ar-kk__brett {
  position: relative;
  display: block;
  width: calc((var(--ar-spalten) + 0.6) * var(--ar-teilung));
  max-width: 100%;
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  appearance: none;
  touch-action: manipulation;
}

button.ar-kk__brett {
  cursor: pointer;
}

/*
 * DAS BLATT WIRFT EINEN HARTEN SCHATTEN AUF DEN FILZ, eine Fläche ohne Unschärfe, von der Lampe weg. Der Fokusring
 * steht draußen auf dem Filz und nicht mehr auf dem Blatt: Senf auf Papier hielte keine 2 : 1.
 */
.ar-kk__brett {
  box-shadow: 0.3rem 0.4rem 0 var(--ar-ku-schlagschatten);
}

.ar-kk__brett:focus-visible {
  outline-offset: 3px;
}

/*
 * Getroffen wird nie ein Teil des Bilds. Das Brett malt sein SVG bei jedem Stand neu, auch beim Fokus; lag unter dem
 * Zeiger ein Punkt oder ein Kästchen, war es zwischen pointerdown und pointerup verschwunden, und Chromium schickte
 * kein click. Der erste Klick oder Tipp auf ein Brett ohne Fokus ging so immer verloren, auf dem Telefon nach jedem
 * „Ziehen“.
 */
.ar-kk__bild {
  display: block;
  width: 100%;
  height: auto;
  overflow: visible;
  pointer-events: none;
}

/*
 * DIE GRIFFEBENE LIEGT ÜBER DEM BILD, UND SIE IST UNSICHTBAR. Je Linie steht dort eine Fangfläche, die den Tipp annimmt
 * (`fangflaeche()` in brett.js): ungefüllt und trotzdem ein Ziel, denn `pointer-events: fill` fragt nicht nach der
 * Füllung. Gebaut wird sie einmal je Brett und danach nur noch in der Form nachgestellt: Ein Knoten, der zwischen
 * pointerdown und pointerup neu gezeichnet wird, kostet in Chromium das click — derselbe Grund wie beim Bild darunter.
 */
.ar-kk__griffe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  fill: none;
}

.ar-kk__griff {
  pointer-events: fill;
}

/*
 * DIE LEISTE „ZURÜCKNEHMEN“ LIEGT ÜBER DEM BRETT und verschiebt nichts: Solange ein getippter Zug zurückgeht, steht sie
 * über der Hälfte, die er nicht berührt (`data-ar-ort`), 48 Pixel hoch über die ganze Breite. Die Messingkante hebt sie
 * vom Knopf „Ziehen“ ab: 7,97 : 1 auf Noir, die Kreide darauf 16,26 : 1.
 */
.ar-kk__zurueck {
  position: absolute;
  right: 0;
  left: 0;
  z-index: 2;
  min-height: 48px;
  border-color: var(--ar-funke);
  background: var(--ar-noir);
}

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

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

.ar-kk__ziehen {
  display: none;
  min-height: 47px;
  margin: 0 0.6rem 0.6rem;
}

/*
 * DER KNOPF GEHÖRT DER TASTATUR. Er stand unter jedem groben Zeiger (`any-pointer: coarse`), weil ein Tipp mit Finger
 * oder Stift auf einem kleinen Brett nur ein Visier legte und die Linie danach niemand sonst zog. Das Visier gibt es
 * nicht mehr; ein Tipp zieht. Übrig bleibt der Weg, dem man seinen Griff nicht ansieht: Ein Brett, das ein einziger
 * Knopf ist, sagt niemandem, dass Enter die gewählte Linie zieht — der Knopf sagt es, und zwar nur dem, der mit der
 * Tastatur darauf steht. Ob das gerade jemand tut, sagt `data-ar-tastatur` (`brett.js`) und nicht `:focus-visible`:
 * Der Grund steht dort, und er ist gemessen — am Fokus selbst war der Knopf nicht antabbar.
 */
.ar-kk[data-ar-tastatur] .ar-kk__ziehen {
  display: block;
}

/*
 * DIE HÖHE STEHT BEREIT, WO EINE TASTATUR IST, und nicht erst, wenn jemand sie benutzt. Sie hing einmal am selben
 * Merkmal wie der Knopf, und dann schrumpfte das Brett in dem Augenblick, in dem man es antabbte: auf 375 × 667 von
 * 333 auf 317 Pixel, im flachen Querformat von 234 auf 168 — jede Linie wanderte unter dem Cursor weg. Wer einen feinen
 * Zeiger hat, hat auch eine Tabulatortaste; ein reines Touchgerät hat keine und bekommt die Höhe deshalb zurück, die es
 * vor dem Umbau für einen Knopf zahlte, den es nicht mehr braucht. Er kostet seine Höhe und die Fuge davor und
 * darunter: Mit nur einer Fuge standen 10 Pixel zu wenig in der Rechnung.
 */
@media (any-pointer: fine) {
  .ar-spielfeld[data-ar-spiel='kaesekaestchen'] {
    --ar-ziehen-hoehe: calc(48px + 1.2rem);
  }
}

/*
 * „Ziehen“ steht im Streifen unter dem Feld, und die Tafel deckte einmal nur 84 Prozent der Bretthöhe: Auf 375 × 740
 * lugte die Hälfte des Worts unter ihrer Kante hervor. Solange sie steht, ist das Brett ohnehin inert; der Knopf behält
 * seinen Platz, damit nichts springt.
 */
.ar-spielfeld:has(> .ar-tafelplatz:not([hidden])) .ar-kk__ziehen {
  visibility: hidden;
}

/* Steht der Cursor nicht auf einer freien Linie, ist der Knopf still, aber da: Ein Tipp darauf sagt, was fehlt. */
.ar-kk__ziehen[aria-disabled='true'] {
  border-color: var(--ar-kante-griff);
  background: var(--ar-noir-2);
  color: var(--ar-kreide-2);
}

/* Die zuletzt gezogene Linie trägt einen roten Saum unter der Tusche: im Kataster die Farbe des Nachgetragenen. */
.ar-kk-letzte {
  stroke: var(--ar-plan-rot);
  stroke-width: 11;
  stroke-linecap: round;
}

/* Die Linie unter dem Tastaturcursor und die unter der Maus: beide gestrichelt, die Tastatur heller. */
.ar-kk-cursor-linie,
.ar-kk-vorschau {
  stroke-width: 8;
  stroke-linecap: square;
}

.ar-kk-cursor-linie {
  stroke: var(--ar-plan-tusche);
  stroke-dasharray: 14 8;
}

.ar-kk-vorschau {
  stroke: var(--ar-plan-tusche-2);
  stroke-dasharray: 5 11;
}

.ar-kk-cursor,
.ar-kk-stich {
  fill: none;
  stroke: var(--ar-plan-rot);
}

.ar-kk-cursor {
  stroke-width: 5;
  stroke-dasharray: 10 6;
}

.ar-kk-stich {
  stroke-width: 9;
}

.ar-kk-nein {
  fill: none;
  stroke: var(--ar-plan-rot);
  stroke-width: 9;
  paint-order: stroke;
}

/* ------------------------------------------------------------ Leiste und Abzeichen */

/*
 * DIE ZEILE „X KÄSTCHEN EROBERT“ TEILT SICH DEN FUSS DER LEISTE MIT DEM STAND. Wo beide nebeneinander passen, steht sie: in
 * der Spalte des Spieltischs neben dem Brett und über dem Brett ab 34rem Leistenbreite. Darunter, auf dem Telefon, fehlt
 * sie, und die Plakette sagt dieselbe Zahl mit ihrer Einheit; bräche die Zeile um, schöbe sie das Brett. Die 34rem sind
 * gerechnet: Der Stand zu viert mit Uhr braucht rund 315 Pixel, die Zeile mit zweistelliger Zahl rund 135.
 */
.ar-hud[data-ar-spiel='kaesekaestchen'] .ar-hud__zusatz {
  display: none;
}

@container ar-hud (min-width: 34rem) {
  .ar-hud[data-ar-spiel='kaesekaestchen'] .ar-hud__zusatz {
    display: inline-flex;
  }
}

@media (orientation: landscape) and (min-width: 40rem) {
  .ar-hud[data-ar-spiel='kaesekaestchen'] .ar-hud__zusatz {
    display: inline-flex;
  }
}

.ar-kk__erobert {
  color: var(--ar-kreide-2);
  font-size: 0.8rem;
  white-space: nowrap;
}

.ar-kk__zahl {
  color: var(--ar-kreide);
  font-variant-numeric: tabular-nums;
}

/*
 * DAS ABZEICHEN SETZT DREI ZEILEN, und die Schrift rechnet deshalb gegen die Höhe mit. Der Rahmen deckelt sie für ein
 * einzeiliges Wort auf 11,5 Prozent der Breite; drei Zeilen davon wären 0,35 Breiten hoch und stießen an die Zacken, deren
 * Mitte rund 0,26 Breiten frei lässt. Mit 7,8 Prozent sind es 0,23. Die Breite der längsten Zeile misst der Rahmen selbst
 * (`--ar-wortbreite`); zentriert wird hier, weil er ein einzeiliges Wort nie ausrichten musste.
 */
.ar-spielfeld[data-ar-spiel='kaesekaestchen'] .ar-abzeichen {
  --ar-kk-abzeichen: min(0.92 * (var(--ar-brettbreite) - 2 * var(--ar-brettrand)), 22rem);
}

.ar-spielfeld[data-ar-spiel='kaesekaestchen'] .ar-abzeichen__wort {
  font-size: min(3rem, calc(var(--ar-einheit) * 0.43), calc(0.078 * var(--ar-kk-abzeichen)), calc(0.58 * var(--ar-kk-abzeichen) / var(--ar-wortbreite, 1)));
  text-align: center;
}

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

/*
 * Das Blatt ist dunkles Papier und das Karo eine Haarlinie in der Zierkante. Kreide steht darauf mit 14,79 : 1. So steht
 * es in Schild und Bildkarten; auf dem Brett liegt der Katasterplan darüber (unten).
 *
 * EINE FREIE LINIE IST EINE NUT UND KEINE PUNKTREIHE. Sie stand in der Griffkante mit `stroke-dasharray: 0.1 11` da,
 * also als Kette winziger Punkte, und auf einem vollen Brett hat sie niemand mehr gefunden — gerade sie ist aber das,
 * worauf man tippt. Sie liegt seitdem durchgehend da, und das bleibt.
 *
 * IHRE DICKE WAR DIE NÄCHSTE ÜBERKORREKTUR. 3,5 Pixel in der Griffkante machten sie zwar sicher zu finden, aber ein
 * leeres Brett sah damit auf den ersten Blick aus wie eines, in dem schon jede Linie steht — die gesetzte Linie
 * (`.ar-g-kk-strich`, Kreideweiß, 5 Pixel, mit Lücken wie über Papier gekratzt) und die bloß mögliche unterschieden
 * sich nur in der Farbe, nicht in der Fläche. Die Hilfslinie ist jetzt ein Rem-Zehntel so breit und gedämpft: ein
 * Hinweis, wo man tippen kann, keine Behauptung, dass dort schon etwas liegt.
 */
.ar-g-kk-blatt { fill: var(--ar-noir-2); }
.ar-g-kk-karo { fill: none; stroke: var(--ar-kante); stroke-width: 1; vector-effect: non-scaling-stroke; }
.ar-g-kk-punkt { fill: var(--ar-kreide); }
.ar-g-kk-leit { fill: none; stroke: var(--ar-kante-griff); stroke-width: 1; stroke-linecap: round; opacity: 0.35; }

/* Die Lücken machen die Kreide: Ein Strich ohne sie ist eine Vektorlinie, einer mit ihnen hat über Papier gekratzt. */
.ar-g-kk-strich { fill: none; stroke: var(--ar-kreide); stroke-width: 5; stroke-linecap: round; stroke-dasharray: 34 3.5 21 2.5 46 4 11 3; }

/*
 * DER POP EINES GEHOLTEN KÄSTCHENS (`aufpoppen()` in brett.js): ein Bild die ganze Fläche in der vollen Farbe dessen,
 * der es geholt hat, ein Bild nur ihre Kante, je 90 ms. Satt und hart, ohne Schein — und nur im Kästchen.
 */
.ar-kk-pop--rot { --ar-kk-pop: var(--ar-rot); }
.ar-kk-pop--blau { --ar-kk-pop: var(--ar-blau); }
.ar-kk-pop--gelb { --ar-kk-pop: var(--ar-gelb); }
.ar-kk-pop--gruen { --ar-kk-pop: var(--ar-gruen); }
.ar-kk-pop { fill: var(--ar-kk-pop); }
.ar-kk-pop-kante { fill: none; stroke: var(--ar-kk-pop); stroke-width: 12; }

/* Das geholte Kästchen: Fläche in der Farbe, darauf der dunkle Fleck, damit die Marke darin ihren Kontrast behält. */
.ar-g-kk-feld--rot { fill: var(--ar-kk-feld-rot); }
.ar-g-kk-feld--blau { fill: var(--ar-kk-feld-blau); }
.ar-g-kk-feld--gelb { fill: var(--ar-kk-feld-gelb); }
.ar-g-kk-feld--gruen { fill: var(--ar-kk-feld-gruen); }
.ar-g-kk-fleck { fill: var(--ar-noir-2); }

/*
 * DER RING DES STEMPELS IST DIESELBE TINTE WIE DER FLECK: Was ein Brandzeichen umschließt, gehört zum Zeichen und
 * nicht zum Blatt. Auf dem hellsten der vier Matt-Töne (Gelb) hält er 4,2 : 1 und damit mehr als die 3 : 1, die
 * WCAG 1.4.11 für alles verlangt, was keine Schrift ist und trotzdem etwas sagt.
 *
 * DIE LÜCKEN SIND DIE STELLEN, AN DENEN DIE TINTE NICHT DURCHGEKOMMEN IST. Ein geschlossener Ring wäre gedruckt; das
 * Muster ist unregelmäßig, damit man die Wiederholung nicht abzählt.
 */
.ar-g-kk-stempel { fill: none; stroke: var(--ar-noir-2); stroke-width: 3.5; stroke-dasharray: 17 5 29 4 11 6; }

/*
 * DER KATASTERPLAN AUF DEM BRETT. Dieselben Symbole stehen dunkel in Schild und Bildkarten; nur im Bild des Bretts
 * (`.ar-kk__bild`) sind sie Papier und Tusche. Das Karo ist blaue Druckfarbe, die freie Linie eine Bleistiftspur in
 * derselben Farbe, etwas kräftiger — ein Hinweis, wo man tippen kann, keine Behauptung, dass dort schon etwas liegt.
 * Gezogen wird mit der Feder in Tusche (12,5 : 1), mit denselben Lücken wie zuvor in der Kreide und etwas schmaler: Auf
 * hellem Papier wirkt derselbe Strich breiter als auf dunklem. Die Parzellen behalten
 * ihre vier Matt-Töne: Auf dem Papier halten sie 3,2 bis 4 : 1.
 */
.ar-kk__bild .ar-g-kk-blatt { fill: var(--ar-plan-papier); stroke: var(--ar-plan-kante); stroke-width: 2; }
.ar-kk__bild .ar-g-kk-karo { stroke: var(--ar-plan-karo); }
.ar-kk__bild .ar-g-kk-punkt { fill: var(--ar-plan-tusche); }
.ar-kk__bild .ar-g-kk-leit { stroke: var(--ar-plan-leit); stroke-width: 1.6; stroke-dasharray: 7 6; opacity: 1; }
.ar-kk__bild .ar-g-kk-strich { stroke: var(--ar-plan-tusche); stroke-width: 4.2; }
.ar-kk-rahmen { fill: none; stroke: var(--ar-plan-tusche); stroke-width: 2.4; }
.ar-kk-rahmen--fein { stroke-width: 1; }
