@charset "UTF-8";
/* ==========================================================================
   Fallblatt — Spielbrett und Bildschirmtastatur

   Vertrag mit brett.js, tastatur.js und spiel.html:

     .brettbereich                  Brett und Tastatur untereinander
     .brett[data-spalten][data-zeilen]
       .reihe[data-spalten]         eine Zeile; traegt die perspective
         .kachel[data-spalte]       ein Blatt, Buchstabe als Textinhalt

     .kachel[data-gefuellt]         getippt, noch ungewertet
     .kachel[data-aktiv]            Schreibmarke
     .kachel[data-muster="0|1|2"]   Wertung (0 grau, 1 gelb, 2 gruen)
     .reihe.klappt                  loest die gestaffelte Umdrehung aus
     .reihe.gewonnen                Huepfer nach dem Sieg
     .reihe.wackelt                 Fehleingabe
     .tastatur .tastenreihe .taste[data-muster] .taste--breit .gedrueckt

   Zwei Werte liest brett.js zur Laufzeit von :root ab, damit Ablauf und
   Anzeige nicht auseinanderlaufen: --klapp-dauer und --klapp-versatz.
   Wer sie hier aendert, aendert damit auch die Wartezeit im Java-Script.
   Der Name der Klappanimation ist ebenfalls verabredet: fallblatt-klappen.

   Die Zustandsfarben (--zustand-grund, --zustand-text, --zustand-muster)
   kommen aus basis.css und haengen an data-muster.

   Kein text-transform: uppercase auf Kacheln und Tasten. Grossschreibung
   macht aus dem scharfen s ein doppeltes S — hier ist es aber ein eigener
   Buchstabe und zaehlt als ein Zeichen. Vorlage und Java-Script liefern
   bereits Grossbuchstaben.
   ========================================================================== */

:root {
  --kachel-abstand: clamp(4px, 1.3vw, 8px);
  --kachel-max: 4.4rem;
  --kachel-radius: 12px;
  --klapp-dauer: 300ms;     /* liest brett.js */
  --klapp-versatz: 150ms;   /* liest brett.js */
  --tasten-abstand: clamp(3px, 1vw, 6px);
}

/* ------------------------------------------------------------- Bereich -- */
.brettbereich {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--raum-5);
  width: 100%;
}

/* --------------------------------------------------------------- Brett -- */
.brett {
  --spalten: 5;
  --kachel-schrift: clamp(1.35rem, 7vw, 2.2rem);
  display: grid;
  gap: var(--kachel-abstand);
  width: min(100%, calc(var(--spalten) * var(--kachel-max)
            + (var(--spalten) - 1) * var(--kachel-abstand)));
  margin-inline: auto;
  touch-action: manipulation;
}

/* Die Spaltenzahl steht als data-Attribut im Markup und wird hier
   aufgeloest: Brettbreite, Schriftgroesse und Radius haengen daran.
   Acht Buchstaben muessen auf 320 Pixel passen. */
.brett[data-spalten="4"] { --spalten: 4; --kachel-schrift: clamp(1.5rem,  8.4vw, 2.4rem);  --kachel-radius: 14px; }
.brett[data-spalten="5"] { --spalten: 5; --kachel-schrift: clamp(1.35rem, 7vw,   2.2rem);  --kachel-radius: 13px; }
.brett[data-spalten="6"] { --spalten: 6; --kachel-schrift: clamp(1.2rem,  5.9vw, 2.05rem); --kachel-radius: 11px; }
.brett[data-spalten="7"] { --spalten: 7; --kachel-schrift: clamp(1.05rem, 5vw,   1.9rem);  --kachel-radius: 9px; }
.brett[data-spalten="8"] { --spalten: 8; --kachel-schrift: clamp(.95rem,  4.3vw, 1.75rem); --kachel-radius: 8px; }

.reihe,
.brett-reihe {
  display: grid;
  gap: var(--kachel-abstand);
  grid-template-columns: repeat(5, minmax(0, 1fr));
  perspective: 900px;
}

/* Das Attribut darf am Brett stehen oder an der einzelnen Reihe. */
.brett[data-spalten="4"] .reihe, .reihe[data-spalten="4"],
.brett[data-spalten="4"] .brett-reihe, .brett-reihe[data-spalten="4"] {
  grid-template-columns: repeat(4, minmax(0, 1fr));
}
.brett[data-spalten="5"] .reihe, .reihe[data-spalten="5"],
.brett[data-spalten="5"] .brett-reihe, .brett-reihe[data-spalten="5"] {
  grid-template-columns: repeat(5, minmax(0, 1fr));
}
.brett[data-spalten="6"] .reihe, .reihe[data-spalten="6"],
.brett[data-spalten="6"] .brett-reihe, .brett-reihe[data-spalten="6"] {
  grid-template-columns: repeat(6, minmax(0, 1fr));
}
.brett[data-spalten="7"] .reihe, .reihe[data-spalten="7"],
.brett[data-spalten="7"] .brett-reihe, .brett-reihe[data-spalten="7"] {
  grid-template-columns: repeat(7, minmax(0, 1fr));
}
.brett[data-spalten="8"] .reihe, .reihe[data-spalten="8"],
.brett[data-spalten="8"] .brett-reihe, .brett-reihe[data-spalten="8"] {
  grid-template-columns: repeat(8, minmax(0, 1fr));
}

/* -------------------------------------------------------------- Kachel -- */
.kachel {
  position: relative;
  aspect-ratio: 1 / 1;
  min-width: 0;
  display: grid;
  place-items: center;
  border: 2px solid var(--zustand-grund, var(--kachel-rand));
  border-radius: var(--kachel-radius);
  background-color: var(--zustand-grund, var(--kachel-grund));
  color: var(--zustand-text, var(--text));
  font-size: var(--kachel-schrift, clamp(1.35rem, 7vw, 2.2rem));
  font-weight: 700;
  line-height: 1;
  letter-spacing: .01em;
  overflow: hidden;
  user-select: none;
  -webkit-user-select: none;
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
}

/* Naht und Woelbung — der namensgebende Teil. */
.kachel::before {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--blatt-glanz);
  pointer-events: none;
}

/* Musterebene. Ohne Wertung ist sie leer, ausserhalb des Farbenblind-Modus
   wird sie nicht gezeichnet. */
.kachel::after,
.taste::after {
  content: "";
  position: absolute;
  inset: 0;
  background-image: none;
  background-repeat: no-repeat;
  pointer-events: none;
}
:root[data-farbmodus="muster"] .kachel::after,
:root[data-farbmodus="muster"] .taste::after {
  background-image: var(--zustand-muster, none);
  background-size: var(--zustand-muster-groesse, 30% 30%);
  background-position: var(--zustand-muster-lage, 7% 7%);
}

.kachel[data-gefuellt] {
  border-color: var(--linie-stark);
  animation: kachel-tippen 110ms ease-out;
}

/* Schreibmarke: die Stelle, an der der naechste Buchstabe landet. */
.kachel[data-aktiv] {
  border-color: var(--akzent);
  box-shadow: 0 0 0 2px var(--akzent-zart);
}

@keyframes kachel-tippen {
  from { transform: scale(.88); }
  to   { transform: scale(1); }
}

/* ------------------------------------------------- Fallblatt-Animation --
   Die Kachel klappt um die waagerechte Achse. Genau in der Senkrechten,
   wenn niemand hineinsehen kann, wechselt sie die Farbe. data-muster darf
   deshalb schon vor dem Start gesetzt sein: bis zur Mitte ueberschreibt die
   Animation es wieder mit dem Ruhezustand, davor haelt das
   Rueckwaerts-Fuellen (animation-fill-mode: both) denselben Zustand. */
@keyframes fallblatt-klappen {
  0% {
    transform: rotateX(0deg);
    background-color: var(--kachel-grund);
    border-color: var(--kachel-rand);
    color: var(--text);
  }
  49.99% {
    transform: rotateX(-90deg);
    background-color: var(--kachel-grund);
    border-color: var(--kachel-rand);
    color: var(--text);
  }
  50% {
    transform: rotateX(-90deg);
    background-color: var(--zustand-grund, var(--kachel-grund));
    border-color: var(--zustand-grund, var(--kachel-rand));
    color: var(--zustand-text, var(--text));
  }
  100% {
    transform: rotateX(0deg);
    background-color: var(--zustand-grund, var(--kachel-grund));
    border-color: var(--zustand-grund, var(--kachel-rand));
    color: var(--zustand-text, var(--text));
  }
}

/* Die Musterecke erst ab der Senkrechten zeigen — sonst verraet sie die
   Wertung, bevor die Kachel gedreht hat. */
@keyframes fallblatt-muster {
  0%   { opacity: 0; }
  50%  { opacity: 1; }
  100% { opacity: 1; }
}

/* Staffelung: --index kommt aus der Stellung in der Reihe. Beide Wege
   fuehren zum selben Wert, data-spalte und :nth-child. */
.kachel { --index: 0; --verzoegerung: calc(var(--index, 0) * var(--klapp-versatz)); }
.kachel[data-spalte="0"] { --index: 0; }
.kachel[data-spalte="1"] { --index: 1; }
.kachel[data-spalte="2"] { --index: 2; }
.kachel[data-spalte="3"] { --index: 3; }
.kachel[data-spalte="4"] { --index: 4; }
.kachel[data-spalte="5"] { --index: 5; }
.kachel[data-spalte="6"] { --index: 6; }
.kachel[data-spalte="7"] { --index: 7; }
.reihe .kachel:nth-child(1), .brett-reihe .kachel:nth-child(1) { --index: 0; }
.reihe .kachel:nth-child(2), .brett-reihe .kachel:nth-child(2) { --index: 1; }
.reihe .kachel:nth-child(3), .brett-reihe .kachel:nth-child(3) { --index: 2; }
.reihe .kachel:nth-child(4), .brett-reihe .kachel:nth-child(4) { --index: 3; }
.reihe .kachel:nth-child(5), .brett-reihe .kachel:nth-child(5) { --index: 4; }
.reihe .kachel:nth-child(6), .brett-reihe .kachel:nth-child(6) { --index: 5; }
.reihe .kachel:nth-child(7), .brett-reihe .kachel:nth-child(7) { --index: 6; }
.reihe .kachel:nth-child(8), .brett-reihe .kachel:nth-child(8) { --index: 7; }

/* Die Klasse haengt an der Reihe; einzelne Kacheln gehen auch. */
.reihe.klappt .kachel,
.brett-reihe.klappt .kachel,
.kachel.klappt {
  animation: fallblatt-klappen var(--klapp-dauer) ease-in-out
             var(--verzoegerung) both;
}
.reihe.klappt .kachel::after,
.brett-reihe.klappt .kachel::after,
.kachel.klappt::after {
  animation: fallblatt-muster var(--klapp-dauer) step-end
             var(--verzoegerung) both;
}

/* ------------------------------------------------- Wackeln und Huepfen -- */
@keyframes brett-wackeln {
  0%, 100% { transform: translateX(0); }
  15% { transform: translateX(-6px); }
  30% { transform: translateX(5px); }
  45% { transform: translateX(-4px); }
  60% { transform: translateX(3px); }
  80% { transform: translateX(-2px); }
}
.reihe.wackelt,
.brett-reihe.wackelt,
.brett.wackelt {
  animation: brett-wackeln 420ms cubic-bezier(.36, .07, .19, .97) both;
}

@keyframes kachel-huepfer {
  0%   { transform: translateY(0); }
  35%  { transform: translateY(-22%); }
  55%  { transform: translateY(6%); }
  75%  { transform: translateY(-5%); }
  100% { transform: translateY(0); }
}

/* Sieg. Der Huepfer wartet, bis das letzte Blatt liegt: forwards statt both,
   damit er waehrend der Wartezeit die Klappbewegung nicht ueberschreibt. */
.reihe.gewonnen .kachel,
.brett-reihe.gewonnen .kachel {
  animation: kachel-huepfer 520ms ease
             calc(var(--sieg-warten, 0ms) + var(--index, 0) * 70ms) forwards;
}
.reihe.klappt.gewonnen .kachel,
.brett-reihe.klappt.gewonnen .kachel {
  animation:
    fallblatt-klappen var(--klapp-dauer) ease-in-out var(--verzoegerung) both,
    kachel-huepfer 520ms ease
      calc(var(--verzoegerung) + var(--klapp-dauer) + var(--index, 0) * 70ms)
      forwards;
}

/* ------------------------------------------------------------ Tastatur -- */
.tastatur {
  display: flex;
  flex-direction: column;
  gap: var(--tasten-abstand);
  width: 100%;
  max-width: 34rem;
  margin-inline: auto;
  padding-bottom: env(safe-area-inset-bottom, 0px);
  user-select: none;
  -webkit-user-select: none;
}

.tastenreihe {
  display: flex;
  justify-content: center;
  gap: var(--tasten-abstand);
}
/* Platzhalter fuer halbe Einrueckungen, falls eine Reihe kuerzer wird. */
.tastenreihe .luecke { flex: .5 1 0; }

.taste {
  position: relative;
  flex: 1 1 0;
  min-width: 0;
  height: clamp(2.75rem, 8.2vw, 3.4rem);
  padding: 0 1px;
  display: grid;
  place-items: center;
  border: 1px solid var(--zustand-grund, var(--linie));
  border-radius: var(--radius-s);
  background-color: var(--zustand-grund, var(--taste-grund));
  color: var(--zustand-text, var(--text));
  font-family: var(--schrift);
  font-size: clamp(.82rem, 3vw, 1.05rem);
  font-weight: 650;
  line-height: 1;
  white-space: nowrap;
  cursor: pointer;
  overflow: hidden;
  touch-action: manipulation;
  transition: background-color var(--tempo) var(--kurve),
              color var(--tempo) var(--kurve),
              transform 80ms var(--kurve);
}
.taste:hover { border-color: var(--zustand-grund, var(--linie-stark)); }
.taste:active,
.taste.gedrueckt { transform: translateY(1px); }
.taste[disabled] { cursor: not-allowed; }
.tastatur[data-gesperrt="1"] { opacity: .62; }

/* Enter und Loeschen brauchen mehr Breite, dafuer kleinere Schrift — sonst
   passen elf Tasten nicht mehr in eine Reihe von 320 Pixeln. */
.taste--breit,
.taste--weit,
.taste[data-taste="enter"],
.taste[data-taste="loeschen"] {
  flex-grow: 1.7;
  font-size: clamp(.66rem, 2.4vw, .85rem);
  letter-spacing: .03em;
}
.taste--loeschen,
.taste[data-taste="loeschen"] { font-size: clamp(.95rem, 3.4vw, 1.15rem); }

/* --------------------------------------------------- Enge Bildschirme -- */
@media (max-width: 22.5rem) {
  :root { --kachel-abstand: 4px; --tasten-abstand: 3px; }
  .taste { font-size: .78rem; }
}

/* Flache Fenster: das Brett darf die Tastatur nicht verdraengen. */
@media (max-height: 46rem) {
  :root { --kachel-max: 3.4rem; }
}
@media (max-height: 36rem) {
  :root { --kachel-max: 2.8rem; }
  .taste { height: clamp(2.3rem, 7vw, 2.9rem); }
}

/* ------------------------------------------------- Weniger Bewegung ---- */
/* Sofortiges Umschalten statt Bewegung. Bewusst eine sehr kurze Dauer statt
   animation: none — brett.js wartet auf animationend, und dieses Ereignis
   soll weiterhin kommen. */
@media (prefers-reduced-motion: reduce) {
  .reihe.klappt .kachel,
  .brett-reihe.klappt .kachel,
  .kachel.klappt,
  .reihe.klappt.gewonnen .kachel,
  .brett-reihe.klappt.gewonnen .kachel,
  .reihe.gewonnen .kachel,
  .brett-reihe.gewonnen .kachel,
  .reihe.klappt .kachel::after,
  .brett-reihe.klappt .kachel::after,
  .kachel.klappt::after,
  .kachel[data-gefuellt],
  .reihe.wackelt,
  .brett-reihe.wackelt,
  .brett.wackelt {
    animation-duration: .01ms;
    animation-delay: 0ms;
    animation-iteration-count: 1;
  }
}
