/* ===========================================================================
   Vierte Optik: „Physik"
   ===========================================================================

   Alles hier hängt an html[data-optik="physik"]. Ist das Attribut nicht
   gesetzt, kostet diese Datei nichts — genau wie styles-salon.css und
   styles-azur.css. Zurück ist ein Knopfdruck im Menü.

   Anders als die anderen beiden ist diese Optik nicht nur Farbe: Sie kippt den
   Filz in die Tiefe und macht aus den Würfeln echte Körper. Den Flug rechnet
   wuerfelphysik.js, gezeichnet wird er von physik-ansicht.js.

   Das übrige Aussehen (Block, Kopfzeile, Menü) bleibt das klassische.
   ======================================================================== */

html[data-optik="physik"] {
  --kipp: 40deg;          /* am Gerät gewählt: bei 40° bleiben die Augen lesbar */
  /* Die Würfel sind hier KLEINER als in den flachen Optiken — sonst wirken sie
     neben dem Becher wie Bauklötze. Der Becher hängt weiter an `--kante` und
     behält seine Größe; nur die Würfel bekommen ein eigenes Maß.
     Die Physik zieht automatisch nach: `messen()` liest die tatsächliche
     Würfelbreite und leitet daraus die Pixel je Meter ab. Das Spielfeld wird
     dadurch in Metern größer — die Würfel haben mehr Platz, nicht weniger. */
  --wuerfelkante: calc(var(--kante) * 0.8);
}

/* --- Die Bühne ----------------------------------------------------------- */
html[data-optik="physik"] .wurfflaeche {
  perspective: 1500px;
  perspective-origin: 50% 46%;
  overflow: hidden;
  /* Ohne preserve-3d drückt der Browser alle 3D-Kinder flach — der Becher
     läge dann als Scheibe auf dem Filz. */
  transform-style: preserve-3d;
}

/* Der Filz ist die gekippte Bodenebene. Alles, was darauf liegt, ist sein
   Kind — dadurch teilen Würfel, Becher und Schatten dasselbe Koordinatensystem
   und können nicht auseinanderlaufen. */
html[data-optik="physik"] .streufeld,
html[data-optik="physik"] .becherbuehne {
  position: absolute;
  inset: 0;
  transform: rotateX(var(--kipp));
  transform-style: preserve-3d;
  border-radius: 10px;
}
/* Eine zweite Ebene, exakt so gekippt wie der Filz — für Becher und seine
   Schatten. Warum nicht einfach in den Filz legen? Weil `renderWuerfel()` das
   Streufeld per innerHTML neu schreibt; der Becher wäre nach dem ersten Wurf
   verschwunden. Und warum überhaupt eine eigene Ebene? Weil der Becher sonst
   um seinen eigenen Fuß kippt statt um die Filzmitte und aus dem Bild
   wandert — gemessen: linke Kante bei −45 px. */
html[data-optik="physik"] .becherbuehne {
  pointer-events: none;
}
html[data-optik="physik"] .becherbuehne .becher { pointer-events: auto; }

/* --- Die Würfel ---------------------------------------------------------- */
html[data-optik="physik"] .streufeld .wuerfel {
  position: absolute;
  width: var(--wuerfelkante); height: var(--wuerfelkante);
  background: none;
  border: 0;
  padding: 0;
  box-shadow: none;
  border-radius: 0;
  transform-style: preserve-3d;
  will-change: transform;
  /* Die Lage setzt physik-ansicht.js über `transform`; left/top bleiben 0.
     Kein `transition`: Zwischen zwei Bildern der Simulation darf der Browser
     nicht interpolieren, sonst schwimmt die Bewegung. */
  transition: none;
}

/* Der Schatten liegt AUF dem Filz und wandert mit der Flughöhe (--hoch) nach
   rechts unten, weil das Licht von links oben kommt. Ohne ihn schweben die
   Würfel, egal wie gut sie sonst aussehen. */
/* Der Schatten ist ein EIGENES Element auf dem Filz, kein ::after des
   Würfels.

   Als Kind erbt er dessen komplette Transformation und taumelt mit: Ein
   Würfel, der sich beim Fallen dreht, hätte einen Schatten, der sich
   mitdreht — und weil er im Stapelkontext seines Würfels liegt, legt er
   sich obendrein über die Nachbarn. Genau das sah am Gerät falsch aus.

   Jetzt liegen alle Schatten VOR den Würfeln im Dokument und damit unter
   ihnen, jeder flach auf dem Filz, ohne jede Drehung. */
/* Nur zum Messen: trägt die Würfelkante als Breite, zeigt nichts an.
   Ein aufgelöstes Maß bekommt man aus einer CSS-Variablen sonst nicht. */
html[data-optik="physik"] .kantenmass {
  position: absolute;
  width: var(--wuerfelkante);
  height: 0;
  visibility: hidden;
  pointer-events: none;
}

html[data-optik="physik"] .wuerfelschatten {
  position: absolute;
  left: 0; top: 0;
  border-radius: 50%;
  background: radial-gradient(ellipse at 50% 50%,
    rgba(0,0,0,.46) 0%, rgba(0,0,0,.34) 46%, rgba(0,0,0,.10) 74%, rgba(0,0,0,0) 100%);
  pointer-events: none;
  will-change: transform, opacity;
}

/* Solange der Becher schüttelt, stecken die Würfel darin */
html[data-optik="physik"] .streufeld .wuerfel.imBecher { opacity: 0; }

/* Die sechs Flächen.
   ACHTUNG, hier steckt der Achsentausch: Die Normalen in wuerfelphysik.js
   stehen im Physiksystem (+Y oben), die CSS-Flächen liegen im System der
   gekippten Bodenebene (+Z oben). s0 ist deshalb OHNE Drehung und nicht
   rotateX(90deg). Wer das verwechselt, bekommt eine Oberseite mit der
   Beschriftung und der Helligkeit der Vorderseite — sah im Prototyp aus wie
   „mal von oben, mal von der Seite beleuchtet" und kostete drei Runden. */
html[data-optik="physik"] .wuerfel .seite {
  position: absolute; inset: 0;
  background: radial-gradient(circle at 50% 46%, #fffefb 0%, #f6efe1 62%, #ece0ca 100%);
  border-radius: 14%;
  box-shadow: inset 0 0 0 1px rgba(120,100,70,.25), inset 0 2px 5px rgba(255,255,255,.9);
  backface-visibility: hidden;
}
html[data-optik="physik"] .wuerfel .seite svg { width: 100%; height: 100%; display: block; }
html[data-optik="physik"] .wuerfel .seite circle { fill: #2b2118; }

html[data-optik="physik"] .wuerfel .s0 { transform: translateZ(calc(var(--wuerfelkante) / 2)); }
html[data-optik="physik"] .wuerfel .s1 { transform: rotateY(180deg) translateZ(calc(var(--wuerfelkante) / 2)); }
html[data-optik="physik"] .wuerfel .s2 { transform: rotateX(90deg)  translateZ(calc(var(--wuerfelkante) / 2)); }
html[data-optik="physik"] .wuerfel .s3 { transform: rotateX(-90deg) translateZ(calc(var(--wuerfelkante) / 2)); }
html[data-optik="physik"] .wuerfel .s4 { transform: rotateY(90deg)  translateZ(calc(var(--wuerfelkante) / 2)); }
html[data-optik="physik"] .wuerfel .s5 { transform: rotateY(-90deg) translateZ(calc(var(--wuerfelkante) / 2)); }

/* In der Halteleiste liegen die Würfel flach — dort ist keine Physik im
   Spiel, und sie sollen wie bisher antippbar und lesbar sein. */
html[data-optik="physik"] .halteleiste .wuerfel .seite:not(.s0) { display: none; }
html[data-optik="physik"] .halteleiste .wuerfel .s0 { transform: none; }
html[data-optik="physik"] .halteleiste .wuerfel { transform-style: flat; }

/* --- Der Becher ---------------------------------------------------------- */
/* Ein Zylinder aus Segmenten, kein flaches Rechteck: Als Platte verschwindet
   er beim Ausgießen zu einem Strich. */
html[data-optik="physik"] .becher {
  /* Die RUHELAGE steht hier, nicht im JavaScript.
     Vorher kam die Position ausschliesslich aus --bx/--by, die erst beim
     Messen gesetzt werden. Griff die Messung nicht — etwa weil der
     Spielbildschirm beim Aufbau noch verborgen war —, blieben die Variablen
     leer und der Becher sass in der oberen linken Ecke, halb aus dem Bild
     und nicht mehr zu treffen. Jetzt steht er auch ohne eine Zeile
     JavaScript an der richtigen Stelle; --dx/--dy/--dz verschieben ihn nur
     waehrend des Wurfs. */
  left: auto; top: auto;
  right: calc(var(--kante) * 0.25);
  bottom: calc(var(--kante) * 0.45);
  width: calc(var(--kante) * 1.35);
  height: calc(var(--kante) * 1.95);
  background: none;
  transform-origin: 50% 100%;
  transform-style: preserve-3d;
  transform:
    translate3d(var(--dx, 0px), var(--dy, 0px), var(--dz, 0px))
    rotateX(-90deg)
    rotateZ(var(--neige, 0deg));
  transition: none;
  will-change: transform;
  /* Der Becher ist und bleibt der Wurfknopf — er muss anfassbar sein. */
  pointer-events: auto;
  touch-action: none;
  z-index: 4;
}

html[data-optik="physik"] .becher .becherleib {
  position: absolute; inset: 0;
  transform-style: preserve-3d;
  background: none;
  box-shadow: none;
  border-radius: 0;
}
html[data-optik="physik"] .becher .becherwort { display: none; }
/* Die runde Innenscheibe der klassischen Optik — hier übernehmen das die
   Innensegmente und die Bodenscheibe. */
html[data-optik="physik"] .becher .becherleib::before { display: none; }

/* ===========================================================================
   DIE Regel dieser Optik: KEIN `filter` auf dem Becherleib. Niemals.
   ===========================================================================
   Ein Filter ungleich `none` zwingt `transform-style` auf `flat` — und zwar
   still: `getComputedStyle()` meldet unverändert „preserve-3d", während der
   Browser sämtliche Kinder in EINE Ebene drückt. Aus dem Zylinder wird eine
   Reihe von Segmenten nebeneinander.

   Im Stand fällt das nicht auf: Die flache Reihe steht frontal, Öffnung und
   Boden sind runde Scheiben, und das Auge ergänzt einen Becher. Erst beim
   Kippen zeigt sich die Wahrheit — eine schnurgerade Platte, eine dunkle
   Raute. Das war das „Der Becher ist beim Schütteln eckig", das drei Runden
   lang jemand anderem angelastet wurde (Nähte, massive Innenwand, Segmente
   auf dem Umkreis — alles real, aber alles nicht die Ursache).

   Die Filter kommen aus styles.css: `.wartet` blendet den Becher ab,
   `.gegriffen` hellt ihn auf. Beides ist für die klassische Optik gedacht,
   wo der Becher eine Scheibe ist. Hier bleibt der Zustand am Zeiger ablesbar
   — und während eines Wurfs ist der Becher ohnehin in Bewegung.

   NACHGEMESSEN statt geschätzt: Liegen die Mittelpunkte aller Segmente auf
   einer Geraden, ist der Becher flach. Mit Filter war die kleine Halbachse
   0,05 px, ohne ihn 16,87 px.
   ======================================================================== */
html[data-optik="physik"] .becher .becherleib,
html[data-optik="physik"] .becher.wartet .becherleib,
html[data-optik="physik"] .becher.gegriffen .becherleib {
  filter: none;
}
/* Aus demselben Grund kein `scale` auf dem Leib: Es staucht den ganzen
   Zylinder samt Tiefe, statt den Becher zu drücken. */
html[data-optik="physik"] .becher:not(.wartet):active .becherleib {
  transform: none;
}

/* Ein Becher ist HOHL. Ohne Innenwand sieht man beim Kippen die Rückseite
   der äusseren Segmente — also Leder, wo der Innenraum sein müsste. Der
   Becher wirkt dann wie ein massiver Block, und genau das sah am Gerät beim
   Schütteln „rechteckig" aus. Deshalb zwei Lagen: aussen Leder, innen dunkel,
   beide nur von ihrer jeweiligen Seite sichtbar. */
html[data-optik="physik"] .becher .seg,
html[data-optik="physik"] .becher .seg-innen {
  backface-visibility: hidden;
}
/* Die Innenwand ist HELL genug, um als Wand erkennbar zu sein. Vorher war sie
   fast schwarz — beim Blick in den Becher sah man ein Loch statt eines
   Hohlraums, und der ganze Becher wirkte wie eine dunkle Scheibe. Das fällt
   erst auf, wenn er hoch über dem Tisch steht und man von oben hineinsieht;
   am Boden verdeckt der Rand ohnehin fast alles. */
html[data-optik="physik"] .becher .seg-innen {
  position: absolute; top: 0; height: 100%; left: 50%;
  background-color: #5a3a1c;
  background-image:
    linear-gradient(var(--schleier, transparent), var(--schleier, transparent)),
    linear-gradient(to bottom, #6b4726 0%, #4a2f16 52%, #24140700 100%),
    linear-gradient(to bottom, #6b4726 0%, #3a2410 60%, #1c0f05 100%);
}
html[data-optik="physik"] .becher .seg {
  position: absolute; top: 0; height: 100%; left: 50%;
  /* Nur Verläufe von OBEN NACH UNTEN und zufällige Strukturen. Ein quer
     laufender Verlauf wird von jedem Segment neu gezeichnet — an jeder Fuge
     springt dann die Farbe, und aus dem Zylinder wird eine kannelierte Säule.
     Die Rundung macht allein die Helligkeit je Segment (siehe app.js). */
  background-color: #5c3717;
  background-image:
    /* Der Lichtschleier als erste Lage — ersetzt filter: brightness(), das
       aus jedem Segment eine eigene Ebene mit sichtbaren Rändern machte. */
    linear-gradient(var(--schleier, transparent), var(--schleier, transparent)),
    linear-gradient(to bottom,
      rgba(255,238,210,.10) 0%, rgba(255,238,210,.03) 12%,
      rgba(0,0,0,.10) 55%, rgba(0,0,0,.40) 92%, rgba(0,0,0,.55) 100%),
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='140' height='140'><filter id='n' x='0' y='0' width='100%25' height='100%25'><feTurbulence type='fractalNoise' baseFrequency='1.1' numOctaves='4' seed='11'/><feColorMatrix type='matrix' values='0 0 0 0 0.06  0 0 0 0 0.03  0 0 0 0 0.01  0.55 0.55 0.55 0 -0.28'/></filter><rect width='140' height='140' filter='url(%23n)'/></svg>"),
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='300' height='300'><filter id='g' x='0' y='0' width='100%25' height='100%25'><feTurbulence type='fractalNoise' baseFrequency='0.22' numOctaves='3' seed='4'/><feColorMatrix type='matrix' values='0 0 0 0 0.08  0 0 0 0 0.04  0 0 0 0 0.01  0.4 0.4 0.4 0 -0.2'/></filter><rect width='300' height='300' filter='url(%23g)'/></svg>");
  background-size: 100% 100%, 100% 100%, 42px auto, 90px auto;
}

/* Öffnung und Boden sind WAAGERECHTE Scheiben, keine senkrechten Ovale. Als
   Oval an der Oberkante sieht die Öffnung aus wie ein aufgemalter Halbmond;
   die perspektivische Verkürzung muss die Kamera machen. */
html[data-optik="physik"] .becher .mund,
html[data-optik="physik"] .becher .boden {
  position: absolute; left: 0;
  width: 100%; height: 0;
  padding-bottom: 100%;
  border-radius: 50%;
}
/* Die Öffnung ist ein RING, keine Scheibe. Als gefüllte dunkle Fläche
   verdeckte sie den Innenraum: Wer von oben hineinsah — und das tut man,
   sobald der Becher zum Ausgießen angehoben ist — sah eine schwarze Platte
   statt einer Becherwand. Jetzt geht der Blick hindurch auf Innenwand und
   Boden, und der Becher wirkt hohl. */
html[data-optik="physik"] .becher .mund {
  top: 0;
  transform: translateY(-50%) rotateX(90deg);
  background: none;
  box-shadow:
    inset 0 0 0 3px #6b4322,
    inset 0 0 0 5px rgba(255,222,172,.18),
    inset 0 0 16px 7px rgba(0,0,0,.5);
}
/* Der Boden wird jetzt von innen gesehen — also hell genug, dass man ihn als
   Boden erkennt, mit dem Licht von links vorn wie überall sonst. */
html[data-optik="physik"] .becher .boden {
  bottom: 0;
  transform: translateY(50%) rotateX(90deg);
  background: radial-gradient(ellipse at 42% 38%, #6b4526 0%, #40260f 55%, #241406 100%);
}

/* Zwei Schatten: einer für das Licht, einer für die Berührung. Ein weicher
   Fleck allein trägt keinen Kontakt — dann schwebt der Becher. */
html[data-optik="physik"] .becherschatten,
html[data-optik="physik"] .becherfuss {
  position: absolute; left: 0; top: 0;
  border-radius: 50%;
  pointer-events: none;
}
html[data-optik="physik"] .becherschatten,
html[data-optik="physik"] .becherfuss {
  position: absolute;
  left: auto; top: auto;
  right: calc(var(--kante) * 0.25);
  bottom: calc(var(--kante) * 0.45);
  border-radius: 50%;
  pointer-events: none;
}
html[data-optik="physik"] .becherschatten {
  width: calc(var(--kante) * 1.35 * (1 + var(--hoch, 0) * 0.55));
  height: calc(var(--kante) * 1.35 * (1 + var(--hoch, 0) * 0.55) * 0.42);
  transform: translate3d(
    calc(var(--dx, 0px) + var(--kante) * (0.2 + var(--hoch, 0) * 0.76) + var(--kante) * 0.18),
    calc(var(--dy, 0px) + var(--kante) * (0.2 + var(--hoch, 0) * 0.76) * 0.55 + var(--kante) * 0.2),
    0.1px);
  background: radial-gradient(ellipse at 50% 50%,
    rgba(0,0,0,.6) 0%, rgba(0,0,0,.42) 48%, rgba(0,0,0,0) 100%);
  filter: blur(calc(4px + var(--hoch, 0) * 9px));
  opacity: calc(0.5 - var(--hoch, 0) * 0.3);
}
html[data-optik="physik"] .becherfuss {
  width: calc(var(--kante) * 1.3);
  height: calc(var(--kante) * 0.39);
  transform: translate3d(
    calc(var(--dx, 0px) + var(--kante) * var(--hoch, 0) * 0.6 + var(--kante) * 0.02),
    calc(var(--dy, 0px) + var(--kante) * 0.2),
    0.12px);
  background: radial-gradient(ellipse at 50% 50%,
    rgba(0,0,0,.82) 0%, rgba(0,0,0,.6) 55%, rgba(0,0,0,0) 100%);
  filter: blur(1.5px);
  opacity: calc(0.75 - var(--hoch, 0) * 2.6);
}

/* Der Tischhinweis schwebt über der gekippten Ebene — aber er darf KEINE
   Berührung abfangen. Mit z-index 5 lag er über dem Becher, und jeder Tipp
   darauf landete im Hinweistext statt im Wurfknopf: Der Becher war sichtbar,
   aber tot. Ein reiner Hinweis nimmt nie Eingaben entgegen. */
html[data-optik="physik"] .tischhinweis {
  z-index: 2;
  pointer-events: none;
}

/* „Bewegung reduzieren": Der Becherweg bleibt — er ist die Rückmeldung, dass
   geworfen wurde. Nur der Flug der Würfel entfällt, die Endlage steht sofort. */
@media (prefers-reduced-motion: reduce) {
  html[data-optik="physik"] .streufeld .wuerfel { transition: none !important; }
}
