/* ============================================================================
   Planetpeters -- Tic Tac Toe, vier in einer Reihe
   Ein Brett auf einer Ebene, das im Raum steht: Perspektive, Parallaxe,
   Kacheln mit echter Tiefe. Reines CSS, keine Fremdquellen, kein PHP.
   ========================================================================= */

/* ---------------------------------------------------------------------------
   1. GRUNDWERTE
   Farben nach dem Vorbild der Apple-Systemfarben. Helle Ansicht als
   Ausgangspunkt, die dunkle taucht weiter unten nur die Werte um -- jede
   Farbe ist also genau einmal hier oben definiert.
   ------------------------------------------------------------------------ */
:root{
  color-scheme:light dark;

  /* Flaechen */
  --bg:#f2f2f7;                       /* systemGroupedBackground */
  --bg-deep:#e7e7ee;
  --tint-a:rgba(0,122,255,.16);       /* die beiden Lichter im Hintergrund */
  --tint-b:rgba(255,45,85,.12);

  --material:rgba(255,255,255,.72);   /* durchscheinende Flaechen */
  --material-solid:#fff;
  --plate:rgba(118,118,128,.11);
  --tile:rgba(255,255,255,.92);
  --tile-hi:rgba(255,255,255,1);
  --fill-quiet:rgba(118,118,128,.12); /* systemFill */
  --fill-hover:rgba(118,118,128,.2);

  /* Schrift */
  --label:#1d1d1f;
  --label-2:rgba(60,60,67,.6);        /* secondaryLabel */
  --label-3:rgba(60,60,67,.36);

  /* Linien */
  --hairline:rgba(60,60,67,.14);
  --hairline-2:rgba(60,60,67,.08);

  /* Akzente */
  --blue:#007aff;
  --blue-2:#5ac8fa;
  --pink:#ff2d55;
  --pink-2:#ff9f0a;

  /* Schatten -- gestaffelt, nicht ein einzelner harter Wurf */
  --sh-tile:0 1px 2px rgba(0,0,0,.07),0 5px 12px rgba(0,0,0,.07);
  --sh-lift:0 2px 4px rgba(0,0,0,.06),0 14px 30px rgba(0,0,0,.13);
  --sh-plate:0 2px 6px rgba(0,0,0,.05),0 30px 60px rgba(0,0,0,.11);
  --sh-sheet:0 10px 30px rgba(0,0,0,.12),0 50px 100px rgba(0,0,0,.2);

  /* Masse */
  --n:6;                              /* Felder je Kante */
  --cell:clamp(34px,min(11.6vw,7.4vh),66px);
  --gap:clamp(5px,1.1vw,10px);
  --r-tile:clamp(9px,2vw,16px);
  --r-plate:clamp(20px,4vw,30px);
  --r-sheet:26px;

  /* Bewegung */
  --ease:cubic-bezier(.32,.72,0,1);   /* ruhig auslaufend */
  --spring:cubic-bezier(.34,1.4,.64,1);

  /* Neigung des Bretts. Der Grundwinkel steht fest, die beiden Zeiger-
     anteile setzt das Skript. So bleibt die Rechnung an einer Stelle. */
  --tilt:11deg;
  --px:0deg;
  --py:0deg;
  --shift:0px;          /* seitlicher Versatz des Bodenschattens */
}

@media (prefers-color-scheme:dark){
  :root{
    --bg:#000;
    --bg-deep:#0a0a0c;
    --tint-a:rgba(10,132,255,.26);
    --tint-b:rgba(255,55,95,.16);

    --material:rgba(28,28,30,.72);
    --material-solid:#1c1c1e;
    --plate:rgba(255,255,255,.05);
    --tile:rgba(255,255,255,.08);
    --tile-hi:rgba(255,255,255,.14);
    --fill-quiet:rgba(118,118,128,.24);
    --fill-hover:rgba(118,118,128,.36);

    --label:#f5f5f7;
    --label-2:rgba(235,235,245,.6);
    --label-3:rgba(235,235,245,.3);

    --hairline:rgba(255,255,255,.12);
    --hairline-2:rgba(255,255,255,.06);

    --blue:#0a84ff;
    --blue-2:#64d2ff;
    --pink:#ff375f;
    --pink-2:#ffd60a;

    --sh-tile:0 1px 1px rgba(0,0,0,.5),0 4px 12px rgba(0,0,0,.4);
    --sh-lift:0 2px 6px rgba(0,0,0,.5),0 16px 34px rgba(0,0,0,.55);
    --sh-plate:0 2px 8px rgba(0,0,0,.5),0 34px 70px rgba(0,0,0,.6);
    --sh-sheet:0 10px 30px rgba(0,0,0,.5),0 50px 110px rgba(0,0,0,.7);
  }
}

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

html,body{height:100%}

body{
  margin:0;
  min-height:100svh;
  display:flex;
  flex-direction:column;
  background:var(--bg);
  color:var(--label);
  /* Auf Apple-Geraeten ist das San Francisco, sonst die jeweilige
     Systemschrift -- nichts wird nachgeladen. */
  font-family:-apple-system,BlinkMacSystemFont,"SF Pro Text","Segoe UI",system-ui,Roboto,"Helvetica Neue",Arial,sans-serif;
  font-size:17px;
  line-height:1.47;
  letter-spacing:-.01em;
  -webkit-font-smoothing:antialiased;
  -moz-osx-font-smoothing:grayscale;
  overflow-x:hidden;
}

/* Zwei weiche Lichter geben der Flaeche Tiefe, ohne Muster oder Bild. */
body::before{
  content:"";
  position:fixed;
  inset:0;
  z-index:-1;
  background:
    radial-gradient(70% 55% at 50% -8%,var(--tint-a) 0%,transparent 62%),
    radial-gradient(60% 50% at 88% 106%,var(--tint-b) 0%,transparent 64%),
    linear-gradient(180deg,var(--bg) 0%,var(--bg-deep) 100%);
}

/* ---------------------------------------------------------------------------
   2. KOPFZEILE
   ------------------------------------------------------------------------ */
.top{
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:16px;
  padding:clamp(14px,2.4vh,22px) clamp(16px,4vw,36px);
}

.brand{display:flex;align-items:center;gap:10px}

.brand-mark{
  width:22px;height:22px;
  border-radius:7px;
  background:linear-gradient(150deg,var(--blue-2),var(--blue) 62%,#0040dd);
  box-shadow:0 1px 2px rgba(0,0,0,.14),0 4px 12px rgba(0,122,255,.34);
  position:relative;
}

/* Ein kleines Kreuz im Zeichen -- dasselbe Motiv wie im Spiel. */
.brand-mark::before,
.brand-mark::after{
  content:"";
  position:absolute;
  left:50%;top:50%;
  width:11px;height:2.6px;
  border-radius:2px;
  background:#fff;
}
.brand-mark::before{transform:translate(-50%,-50%) rotate(45deg)}
.brand-mark::after{transform:translate(-50%,-50%) rotate(-45deg)}

.brand-name{
  font-size:16px;
  font-weight:600;
  letter-spacing:-.015em;
}

/* Punktestand als Kapsel im Material der Systemleisten. */
.score{
  display:flex;
  align-items:center;
  gap:9px;
  padding:6px 14px;
  border-radius:99px;
  background:var(--material);
  box-shadow:inset 0 0 0 .5px var(--hairline),0 1px 3px rgba(0,0,0,.05);
  backdrop-filter:saturate(180%) blur(20px);
  -webkit-backdrop-filter:saturate(180%) blur(20px);
  font-variant-numeric:tabular-nums;
}

.score-part{display:flex;align-items:center;gap:6px}
.score-part b{font-size:17px;font-weight:600;letter-spacing:-.02em}
#scoreYou{color:var(--blue)}
#scoreMe{color:var(--pink)}

.score-tag{
  font-size:11px;
  font-weight:590;
  letter-spacing:.01em;
  color:var(--label-2);
}

.score-sep{color:var(--label-3)}

/* ---------------------------------------------------------------------------
   3. RUMPF
   ------------------------------------------------------------------------ */
.wrap{
  flex:1;
  display:flex;
  flex-direction:column;
  align-items:center;
  padding:0 clamp(16px,4vw,36px);
  min-height:0;
}

.intro{text-align:center;max-width:34ch;margin:0 0 clamp(2px,1vh,10px)}

.intro h1{
  margin:0;
  font-size:clamp(26px,4.6vw,40px);
  font-weight:700;
  line-height:1.1;
  letter-spacing:-.03em;
}

.intro h1 em{
  font-style:normal;
  font-weight:700;
  background:linear-gradient(120deg,var(--blue),var(--blue-2) 60%,var(--pink));
  -webkit-background-clip:text;
  background-clip:text;
  color:transparent;
}

.lead{
  margin:9px auto 0;
  max-width:32ch;
  font-size:15px;
  line-height:1.5;
  color:var(--label-2);
}

/* ---------------------------------------------------------------------------
   4. DIE BUEHNE
   Die Perspektive sitzt aussen, das Brett dreht sich darin. Alles, was
   Tiefe hat, liegt in einer preserve-3d-Kette -- reisst die ab, wird die
   Szene flach.
   ------------------------------------------------------------------------ */
.stage{
  position:relative;
  flex:1;
  width:100%;
  display:flex;
  align-items:center;
  justify-content:center;
  padding:clamp(12px,2.6vh,28px) 0;
  perspective:1200px;
  perspective-origin:50% 46%;
}

/* Traeger der Neigung. Grundwinkel plus die beiden Anteile vom Zeiger. */
.deck{
  position:relative;
  width:calc(var(--n) * var(--cell) + (var(--n) - 1) * var(--gap));
  height:calc(var(--n) * var(--cell) + (var(--n) - 1) * var(--gap));
  transform-style:preserve-3d;
  transform:rotateX(calc(var(--tilt) + var(--px))) rotateY(var(--py));
  transition:transform .45s var(--ease);
  will-change:transform;
}

/* Waehrend der Zeiger laeuft, darf die Nachfuehrung nicht nachhinken. */
.deck.is-tracking{transition:transform .12s linear}

/* Die Platte liegt hinter den Kacheln, nicht darunter im Papierstapel,
   sondern wirklich weiter hinten im Raum. Das ist der Trick, der die
   Ebene raeumlich macht. */
.plate{
  position:absolute;
  inset:calc(-1 * var(--gap) - 8px);
  border-radius:var(--r-plate);
  background:var(--plate);
  box-shadow:inset 0 0 0 .5px var(--hairline),var(--sh-plate);
  backdrop-filter:saturate(180%) blur(24px);
  -webkit-backdrop-filter:saturate(180%) blur(24px);
  transform:translateZ(-26px);
}

/* Ein Glanz auf der Platte, der beim Neigen wandert. Die Verschiebung
   kommt aus denselben Zeigerwerten wie die Drehung. */
.plate::after{
  content:"";
  position:absolute;
  inset:0;
  border-radius:inherit;
  pointer-events:none;
  background:linear-gradient(
    calc(120deg + var(--py) * 3),
    rgba(255,255,255,.5) 0%,
    rgba(255,255,255,0) 42%);
  opacity:.55;
}

@media (prefers-color-scheme:dark){
  .plate::after{background:linear-gradient(calc(120deg + var(--py) * 3),rgba(255,255,255,.14) 0%,rgba(255,255,255,0) 46%)}
}

/* Der Schatten des Bretts auf dem Boden. Er liegt noch weiter hinten und
   wandert gegenlaeufig mit -- ohne ihn schwebt nichts, es klebt nur. */
.floor{
  position:absolute;
  left:6%;
  right:6%;
  top:14%;
  bottom:-16%;
  border-radius:50%;
  background:radial-gradient(50% 50% at 50% 50%,rgba(0,0,0,.3) 0%,transparent 70%);
  filter:blur(26px);
  opacity:.5;
  transform:translateZ(-90px) translateX(var(--shift)) rotateX(calc(var(--tilt) * -1));
  pointer-events:none;
}

@media (prefers-color-scheme:dark){
  .floor{background:radial-gradient(50% 50% at 50% 50%,rgba(0,0,0,.85) 0%,transparent 70%);opacity:.8}
}

.grid{
  position:absolute;
  inset:0;
  display:grid;
  /* repeat() nimmt keine Variable als Anzahl -- deshalb steht die Sechs
     hier ausgeschrieben. Sie und --n gehoeren zusammen. */
  grid-template-columns:repeat(6,var(--cell));
  grid-template-rows:repeat(6,var(--cell));
  gap:var(--gap);
  transform-style:preserve-3d;
}

/* ---------------------------------------------------------------------------
   5. EINE KACHEL
   ------------------------------------------------------------------------ */
.cell{
  position:relative;
  margin:0;
  padding:0;
  border:0;
  border-radius:var(--r-tile);
  background:var(--tile);
  box-shadow:inset 0 0 0 .5px var(--hairline),var(--sh-tile);
  font:inherit;
  color:inherit;
  cursor:pointer;
  transform-style:preserve-3d;
  transform:translateZ(0);
  transition:
    transform .34s var(--ease),
    box-shadow .34s var(--ease),
    background .34s var(--ease),
    opacity .34s var(--ease);
  -webkit-tap-highlight-color:transparent;
}

/* Die feine helle Oberkante -- der Lichtsaum, an dem man bei Apple die
   erhabene Flaeche erkennt. */
.cell::before{
  content:"";
  position:absolute;
  inset:0;
  border-radius:inherit;
  pointer-events:none;
  background:linear-gradient(180deg,rgba(255,255,255,.6),rgba(255,255,255,0) 45%);
  opacity:.7;
}

@media (prefers-color-scheme:dark){
  .cell::before{background:linear-gradient(180deg,rgba(255,255,255,.16),rgba(255,255,255,0) 45%)}
}

@media (hover:hover){
  .cell:not(:disabled):hover{
    background:var(--tile-hi);
    transform:translateZ(18px);
    box-shadow:inset 0 0 0 .5px var(--hairline),var(--sh-lift);
  }
}

.cell:not(:disabled):active{transform:translateZ(8px) scale(.97)}

.cell:focus-visible{
  outline:3px solid var(--blue);
  outline-offset:3px;
}

.cell:disabled{cursor:default}

/* ---------------------------------------------------------------------------
   6. DIE ZEICHEN
   Sie liegen flach in der Ebene. Bei elf Grad Neigung bleibt das gut
   lesbar -- und weil sie mitkippen, gehoeren sie sichtbar zum Brett.
   Ein Stueck vor der Kachel schweben sie trotzdem.
   ------------------------------------------------------------------------ */
.mark{
  position:absolute;
  inset:0;
  display:grid;
  place-items:center;
  pointer-events:none;
  transform:translateZ(8px);
}

.mark-face{
  position:relative;
  width:52%;
  height:52%;
  animation:mark-in .44s var(--spring) both;
}

@keyframes mark-in{
  from{opacity:0;transform:scale(.4)}
  to{opacity:1;transform:none}
}

/* Das Kreuz des Besuchers */
.mark-x::before,
.mark-x::after{
  content:"";
  position:absolute;
  left:50%;top:50%;
  width:104%;
  height:calc(var(--cell) * .115);
  border-radius:99px;
  background:linear-gradient(90deg,var(--blue-2),var(--blue) 70%);
  box-shadow:0 2px 8px rgba(0,122,255,.4);
}
.mark-x::before{transform:translate(-50%,-50%) rotate(45deg)}
.mark-x::after{transform:translate(-50%,-50%) rotate(-45deg)}

/* Der Ring des Gegners */
.mark-o::before{
  content:"";
  position:absolute;
  inset:0;
  border:calc(var(--cell) * .115) solid var(--pink);
  border-radius:50%;
  box-shadow:0 2px 8px rgba(255,45,85,.34);
}

/* ---------------------------------------------------------------------------
   7. DIE SIEGREIHE
   Die vier Kacheln steigen nacheinander aus der Ebene -- die Verzoegerung
   kommt aus --i, das beim Setzen der Klasse vergeben wird.
   ------------------------------------------------------------------------ */
.grid.is-over .cell{opacity:.32;transform:translateZ(0)}

.grid.is-over .cell.is-win{
  opacity:1;
  transform:translateZ(36px);
  transition-delay:calc(var(--i,0) * .09s);
}

.grid.is-win-you .cell.is-win{
  background:linear-gradient(160deg,rgba(90,200,250,.3),rgba(0,122,255,.22));
  box-shadow:inset 0 0 0 1px rgba(0,122,255,.5),0 20px 50px rgba(0,122,255,.36);
}

.grid.is-win-me .cell.is-win{
  background:linear-gradient(160deg,rgba(255,159,10,.26),rgba(255,45,85,.22));
  box-shadow:inset 0 0 0 1px rgba(255,45,85,.5),0 20px 50px rgba(255,45,85,.32);
}

/* ---------------------------------------------------------------------------
   8. BEDIENLEISTE
   ------------------------------------------------------------------------ */
.hud{
  display:flex;
  flex-direction:column;
  align-items:center;
  gap:clamp(10px,1.8vh,16px);
  padding:0 0 clamp(10px,2vh,20px);
}

.status{
  margin:0;
  min-height:1.5em;
  font-size:15px;
  color:var(--label-2);
  text-align:center;
}

.status b{color:var(--label);font-weight:600}

/* Der Segmentschalter -- das Bedienelement, an dem man iOS sofort
   erkennt: eine Rinne, darin ein heller Reiter mit weichem Schatten. */
.seg{
  display:inline-flex;
  padding:2px;
  gap:2px;
  border-radius:99px;
  background:var(--fill-quiet);
}

.seg button{
  appearance:none;
  border:0;
  padding:7px 16px;
  border-radius:99px;
  background:transparent;
  color:var(--label-2);
  font:inherit;
  font-size:13px;
  font-weight:590;
  letter-spacing:-.005em;
  cursor:pointer;
  transition:background .22s var(--ease),color .22s var(--ease),transform .16s var(--ease);
}

.seg button:hover{color:var(--label)}
.seg button:active{transform:scale(.95)}

.seg button[aria-pressed="true"]{
  background:var(--material-solid);
  color:var(--label);
  box-shadow:0 0 0 .5px rgba(0,0,0,.04),0 1px 3px rgba(0,0,0,.14);
}

.seg button:focus-visible{outline:3px solid var(--blue);outline-offset:2px}

.controls{display:flex;gap:10px;flex-wrap:wrap;justify-content:center}

.btn{
  appearance:none;
  padding:10px 22px;
  border:0;
  border-radius:99px;
  background:var(--fill-quiet);
  color:var(--label);
  font:inherit;
  font-size:15px;
  font-weight:590;
  letter-spacing:-.01em;
  cursor:pointer;
  text-decoration:none;
  display:inline-flex;
  align-items:center;
  justify-content:center;
  transition:background .2s var(--ease),transform .16s var(--ease),box-shadow .2s var(--ease);
}

.btn:hover{background:var(--fill-hover)}
.btn:active{transform:scale(.96)}
.btn:focus-visible{outline:3px solid var(--blue);outline-offset:2px}

.btn-quiet{
  background:transparent;
  color:var(--label-2);
  font-weight:500;
}
.btn-quiet:hover{background:var(--fill-quiet);color:var(--label)}

.btn-primary{
  padding:13px 30px;
  font-size:17px;
  font-weight:600;
  color:#fff;
  background:var(--blue);
  box-shadow:0 1px 2px rgba(0,0,0,.12),0 8px 24px rgba(0,122,255,.34);
}
.btn-primary:hover{background:#0a84ff;box-shadow:0 1px 2px rgba(0,0,0,.12),0 10px 30px rgba(0,122,255,.44)}

/* ---------------------------------------------------------------------------
   9. FUSSZEILE
   ------------------------------------------------------------------------ */
.foot{
  display:flex;
  align-items:center;
  justify-content:center;
  gap:8px;
  padding:10px 20px 18px;
  font-size:12px;
  color:var(--label-3);
}

/* ---------------------------------------------------------------------------
   10. DIE EINBLENDUNG NACH DEM SPIEL
   Aufgebaut wie ein Blatt in iOS: abgerundetes Material, grosse Ueber-
   schrift, eine klare Handlung.
   ------------------------------------------------------------------------ */
.overlay{
  position:fixed;
  inset:0;
  z-index:20;
  display:flex;
  align-items:center;
  justify-content:center;
  padding:24px;
  background:rgba(0,0,0,.22);
  backdrop-filter:blur(20px) saturate(150%);
  -webkit-backdrop-filter:blur(20px) saturate(150%);
  animation:veil-in .34s var(--ease) both;
}

.overlay[hidden]{display:none}

@media (prefers-color-scheme:dark){
  .overlay{background:rgba(0,0,0,.5)}
}

@keyframes veil-in{from{opacity:0}to{opacity:1}}

.overlay-panel{
  width:min(92vw,420px);
  padding:clamp(28px,5vw,40px) clamp(24px,5vw,36px) clamp(22px,4vw,30px);
  border-radius:var(--r-sheet);
  background:var(--material);
  box-shadow:inset 0 0 0 .5px var(--hairline),var(--sh-sheet);
  backdrop-filter:saturate(180%) blur(30px);
  -webkit-backdrop-filter:saturate(180%) blur(30px);
  text-align:center;
  animation:panel-in .5s var(--spring) both;
}

@keyframes panel-in{
  from{opacity:0;transform:translateY(20px) scale(.94)}
  to{opacity:1;transform:none}
}

.ov-kicker{
  margin:0;
  font-size:15px;
  color:var(--label-2);
  animation:rise .4s var(--ease) .1s both;
}

.ov-headline{
  margin:4px 0 clamp(20px,3.4vw,28px);
  font-size:clamp(34px,7.4vw,52px);
  font-weight:700;
  line-height:1.05;
  letter-spacing:-.035em;
  background:linear-gradient(120deg,var(--blue-2),var(--blue) 70%);
  -webkit-background-clip:text;
  background-clip:text;
  color:transparent;
  animation:headline-in .6s var(--spring) .16s both;
}

.overlay.is-lose .ov-headline{
  background:linear-gradient(120deg,var(--pink-2),var(--pink) 70%);
  -webkit-background-clip:text;
  background-clip:text;
}

.overlay.is-draw .ov-headline{
  background:none;
  -webkit-background-clip:border-box;
  background-clip:border-box;
  color:var(--label);
}

.ov-actions{display:flex;flex-direction:column;gap:6px;align-items:stretch;animation:rise .4s var(--ease) .34s both}

@keyframes rise{
  from{opacity:0;transform:translateY(12px)}
  to{opacity:1;transform:none}
}

@keyframes headline-in{
  from{opacity:0;transform:translateY(14px) scale(.86)}
  to{opacity:1;transform:none}
}

/* Der Konfettivorhang liegt ueber der Seite, faengt aber keine Klicks ab. */
.fx{
  position:fixed;
  inset:0;
  z-index:25;
  pointer-events:none;
  opacity:0;
  transition:opacity .45s linear;
}
.fx.is-live{opacity:1}

/* ---------------------------------------------------------------------------
   11. DIE FEHLERSEITE
   Zwei Abweichungen vom Rumpf der Spielseite. Sie stehen hier und nicht als
   style-Attribut im HTML: die Inhaltsrichtlinie des Servers erlaubt kein
   unsafe-inline, ein Attribut wuerde also stillschweigend verworfen.
   ------------------------------------------------------------------------ */
.wrap-mitte{justify-content:center}
.hud-luft{padding-top:22px}

/* ---------------------------------------------------------------------------
   12. KLEINE BILDSCHIRME
   ------------------------------------------------------------------------ */
@media (max-width:600px){
  /* Auf dem Telefon ist Hoehe da, Breite nicht. Deshalb duerfen die
     Kacheln hier breiter ausfallen -- unter 44 Punkten wird eine
     Schaltflaeche mit dem Daumen unzuverlaessig. */
  :root{--cell:clamp(38px,min(12.9vw,8.4vh),64px)}
  .top{padding:14px 18px}
  .wrap{padding:0 12px}
  .lead{font-size:14px}
  .foot{display:none}
}

@media (max-height:640px){
  .intro{display:none}
}

/* ---------------------------------------------------------------------------
   13. RUECKSICHT AUF REDUZIERTE BEWEGUNG
   Wer im Betriebssystem weniger Bewegung eingestellt hat, bekommt die
   Seite ohne Animation. Die Raeumlichkeit bleibt, das Zappeln entfaellt.
   ------------------------------------------------------------------------ */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{
    animation-duration:.01ms !important;
    animation-iteration-count:1 !important;
    transition-duration:.01ms !important;
  }
}
