/* ==========================================================================
   PIXELHERZ – Seitenstil.
   Zwei Materialien, bewusst gegeneinander gesetzt:
   die harte Pixeloberfläche im Bild, echtes Papier für die Worte, die zählen.
   ========================================================================== */

* { margin: 0; padding: 0; box-sizing: border-box; }

html, body {
  height: 100%;
  overflow: hidden;
  background: #08060E;
  overscroll-behavior: none;
  touch-action: none;
  -webkit-user-select: none; user-select: none;
  -webkit-tap-highlight-color: transparent;
  -webkit-text-size-adjust: 100%;
}

body {
  /* Ein warmer Lichtschein hinter dem Gerät – der Rand soll nicht tot sein. */
  background:
    radial-gradient(120% 80% at 50% 42%, #241B33 0%, #120E1C 55%, #08060E 100%);
}

/* Fester Messrahmen. Das Spielfeld kann ihn nicht aufblähen, also stimmen
   die Maße auch dann, wenn der Inhalt kurzzeitig zu groß gerechnet wird. */
#buehne {
  position: fixed;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  padding: env(safe-area-inset-top) env(safe-area-inset-right)
           env(safe-area-inset-bottom) env(safe-area-inset-left);
}

#wrap {
  position: relative;
  line-height: 0;
  /* Schmale Goldfassung – dieselbe Geste wie auf den Pixelkästen. */
  box-shadow:
    0 0 0 1px rgba(232, 178, 92, 0.22),
    0 18px 50px -12px rgba(0, 0, 0, 0.85),
    0 2px 0 rgba(255, 255, 255, 0.03) inset;
}

#stage {
  display: block;
  image-rendering: pixelated;
  image-rendering: crisp-edges;
  background: #0E0B16;
  touch-action: none;
}

/* ==========================================================================
   Die Papierkarte
   ========================================================================== */

#overlay {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
  opacity: 0;
  pointer-events: none;
  transition: opacity 260ms ease;
  background: rgba(10, 7, 18, 0.55);
  padding: 2.6em 2.2em;
}

#overlay.an {
  opacity: 1;
  pointer-events: auto;
}

.blatt {
  position: relative;
  width: 100%;
  max-height: 100%;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 2.4em 2.1em 2em;
  transform: translateY(0.9em) scale(0.985);
  transition: transform 320ms cubic-bezier(.2, .9, .25, 1);

  font-family: Georgia, 'Iowan Old Style', 'Palatino Linotype', Palatino,
               'Noto Serif', 'Times New Roman', serif;
  color: #3B2E2A;
  background: #F4E8D6;
  box-shadow:
    0 0 0 1px #C9AE7E,
    0 0 0 3px rgba(20, 14, 30, 0.55),
    0 10px 26px -8px rgba(0, 0, 0, 0.7);
}

#overlay.an .blatt { transform: translateY(0) scale(1); }

/* Feine Faserung statt glatter Fläche. */
.blatt::before {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0.5;
  background-image:
    repeating-linear-gradient(0deg, rgba(150, 120, 80, 0.045) 0 1px, transparent 1px 3px),
    radial-gradient(80% 60% at 20% 10%, rgba(255, 255, 255, 0.5), transparent 70%);
}

/* Innen umlaufende Haarlinie – der teure Teil ist immer die Fassung. */
.blatt::after {
  content: '';
  position: absolute;
  inset: 0.7em;
  pointer-events: none;
  border: 1px solid rgba(180, 145, 90, 0.4);
}

.blatt > * { position: relative; z-index: 1; }

#kTitel {
  font-size: 1.9em;
  font-weight: normal;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: #8A6A32;
  text-align: center;
  margin-bottom: 0.5em;
}

/* Goldstrich unter dem Titel */
#kTitel::after {
  content: '';
  display: block;
  width: 3.2em;
  height: 1px;
  margin: 0.7em auto 0;
  background: linear-gradient(90deg, transparent, #B9903F, transparent);
}

#kText {
  font-size: 1.72em;
  line-height: 1.62;
  text-align: center;
}

#kText p { margin: 0; }
#kText p.luft { height: 0.85em; }

#kSig {
  margin-top: 1.5em;
  font-size: 1.62em;
  font-style: italic;
  text-align: right;
  color: #6A5240;
}
#kSig::before { content: '— '; }

#kFuss {
  margin-top: 1.8em;
  font-size: 1.28em;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  text-align: center;
  color: #A08C6C;
  animation: atmen 2.6s ease-in-out infinite;
}

@keyframes atmen {
  0%, 100% { opacity: 0.45; }
  50%      { opacity: 1; }
}

/* ---- Varianten ---------------------------------------------------------- */

/* Der Brief: wärmeres Papier, angedeutete Falz. */
.blatt.brief {
  background:
    linear-gradient(180deg, rgba(0, 0, 0, 0.05) 0 1px, transparent 1px) 0 50% / 100% 100% no-repeat,
    #F6EBDA;
}
.blatt.brief #kText { text-align: left; }

/* Der Gutschein: dunkle Karte mit Gold – wie eine Eintrittskarte. */
.blatt.gutschein {
  background: #221A2E;
  color: #F0E4D2;
  box-shadow:
    0 0 0 1px #B9903F,
    0 0 0 3px rgba(10, 7, 18, 0.7),
    0 10px 26px -8px rgba(0, 0, 0, 0.8);
}
.blatt.gutschein::before { opacity: 0.25; }
.blatt.gutschein::after { border-color: rgba(232, 178, 92, 0.45); }
.blatt.gutschein #kTitel { color: #E8B25C; }
.blatt.gutschein #kFuss { color: #9A8A72; }

/* Kleine Bildschirme: etwas mehr Luft nach innen wegnehmen. */
@media (max-height: 620px) {
  #overlay { padding: 1.6em 1.6em; }
  .blatt { padding: 1.8em 1.6em 1.5em; }
  #kText { font-size: 1.6em; }
}

@media (prefers-reduced-motion: reduce) {
  .blatt, #overlay { transition: none; }
  #kFuss { animation: none; opacity: 0.8; }
}

/* Fehlermeldung – sichtbar statt stumm. */
#fehler {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  margin: 0;
  padding: 0.8em;
  max-height: 45%;
  overflow: auto;
  font: 1.2em/1.45 ui-monospace, Consolas, monospace;
  white-space: pre-wrap;
  color: #FFD9DF;
  background: rgba(120, 24, 48, 0.94);
  border-top: 1px solid #E4576B;
  z-index: 20;
}

/* ==========================================================================
   DAS GERAET

   Ein Handheld um die Buehne herum - so gewuenscht ("wie ein Game-Boy-
   Template auszen herum"). Alles hier ist SCHMUCK: nichts davon laesst
   sich druecken. Alles Bedienbare steht im Bild (assets/hud.js), denn nur
   dort kann es sich aendern, ohne dass zwei Wahrheiten entstehen.

   JEDE Zahl unten ist in SPIELPIXELN gerechnet: `calc(var(--zoom) * Npx)`.
   `--zoom` setzt assets/gfx.js bei jeder Groeszenaenderung, und die
   Randmasze stehen dort als GEHAEUSE. Ein Rand von "12 CSS-Pixeln" waere
   auf einem Telefon mit dreifacher Punktdichte ein Drittel so breit wie
   auf einem Rechner - er gehoerte dann nicht zum Bild, sondern lag daneben.

   Die Farbe ist nicht das Grau des Vorbilds, sondern das Lavendel der
   Figur (#DDD5DE / #766DAA aus dem Premium-Blatt). Ein graues Geraet um
   einen warmen Garten herum sind zwei Welten; dieselbe Farbfamilie macht
   daraus ein Ding.
   ========================================================================== */

:root { --zoom: 1; }

#geraet {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  /* Die vier Zahlen kommen aus `GEHAEUSE` in gfx.js und werden beim
     Anpassen der Leinwand hierher geschrieben. Die Notwerte dahinter
     gelten nur, bis das Skript einmal gelaufen ist - ohne sie stuende das
     Geraet im ersten Bild ohne Rand da. */
  --geh-links: 12px; --geh-rechts: 12px; --geh-oben: 14px;
  --geh-unten: 40px; --geh-blende: 8px;
  padding: calc(var(--zoom) * var(--geh-oben))
           calc(var(--zoom) * var(--geh-rechts))
           calc(var(--zoom) * var(--geh-unten))
           calc(var(--zoom) * var(--geh-links));
  border-radius: calc(var(--zoom) * 10px) calc(var(--zoom) * 10px)
                 calc(var(--zoom) * 28px) calc(var(--zoom) * 10px);
  background:
    linear-gradient(158deg, #E6E0EA 0%, #D2CBDA 26%, #BDB4CC 62%, #A79DBC 100%);
  box-shadow:
    /* die Fase oben links und der Schatten unten rechts - daraus liest
       das Auge "aus einem Stueck gegossen" statt "Rechteck mit Farbe" */
    inset calc(var(--zoom) * 1px) calc(var(--zoom) * 1px) 0 rgba(255,255,255,0.75),
    inset calc(var(--zoom) * -1px) calc(var(--zoom) * -2px) 0 rgba(80,68,104,0.55),
    0 calc(var(--zoom) * 10px) calc(var(--zoom) * 26px) rgba(0,0,0,0.55),
    0 calc(var(--zoom) * 2px) 0 rgba(0,0,0,0.35);
}

/* Die Blende um das Bild. Dunkles Pflaumenviolett, tiefer gelegt - ein
   Bildschirm sitzt IN einem Geraet, er klebt nicht darauf. */
/* SIE LIEGT NUR UM DEN OBEREN TEIL.

   Bis Runde 67 umschloss sie die ganze Leinwand - und damit auch das
   Steuerfeld, das die unteren 88 Spielpixel einnimmt. Kreuz und Knoepfe
   sasen dadurch HINTER der Scheibe. An einem Handheld sitzen sie daneben,
   auf dem Kunststoff, und genau das hat der Nutzer verlangt: „die
   Steuerung sollte an der Konsole sein und nicht im Screen".

   Die Hoehe steht NICHT hier. Sie stand hier - als 264, also VIEW_H minus
   PAD_H -, und beim ersten Mal, als das Steuerfeld wuchs (88 auf 104),
   blieb sie stehen: die Blende reichte 16 Punkte zu weit und schnitt in
   die Schale hinein. Genau die Sorte Zahl, die an zwei Stellen steht.
   Jetzt setzt `gfx.js` sie beim Anpassen der Leinwand - dieselbe Stelle,
   die auch PAD_H kennt.

   Gebaut als Schicht HINTER der Leinwand (::before) statt als Polster:
   ein Polster umschlieszt immer alles, was drinsteht. */
#schirm {
  /* Notwert; gfx.js setzt ihn beim Start aus VIEW_H - PAD_H.
     Er stand auf 264 und war damit zwanzig Punkte alt: 264 ist
     352 - 88, und PAD_H ist seit dem Wachsen des Steuerfelds 108.
     Zu sehen war es nur im Augenblick zwischen Seitenaufbau und
     erstem `resizeCanvas()` - ein Aufblitzen, das niemand einer
     CSS-Zeile zuordnet. */
  --schirm-hoch: 244px;
  position: relative;
  padding: 0;
}

#schirm::before {
  content: '';
  position: absolute;
  z-index: 0;
  /* DIE FASSUNG WAECHST NACH AUSZEN, nicht nach innen: sie liegt als
     Schicht HINTER der Leinwand und ragt um `--geh-blende` darueber
     hinaus. Die Buehne bleibt damit 176 x 352, und der dunkle Rahmen
     nimmt sich seinen Platz vom Gehaeuserand.

     Bis Runde 111 waren es 5 Punkte. Am Vorbild ist die Fassung
     erheblich breiter als der Rand daneben - der Bildschirm sitzt IN
     einem Geraet, und fuenf Punkte lesen sich als Kante, nicht als
     Fassung. */
  left: calc(var(--zoom) * -1 * var(--geh-blende));
  right: calc(var(--zoom) * -1 * var(--geh-blende));
  top: calc(var(--zoom) * -1 * var(--geh-blende));
  height: calc(var(--zoom) * (var(--schirm-hoch) + 2 * var(--geh-blende)));
  border-radius: calc(var(--zoom) * 4px);
  background: linear-gradient(160deg, #3A3050 0%, #2A2340 100%);
  box-shadow:
    inset 0 calc(var(--zoom) * 2px) calc(var(--zoom) * 3px) rgba(0,0,0,0.6),
    0 calc(var(--zoom) * 1px) 0 rgba(255,255,255,0.55);
}

/* Die Leinwand liegt darauf, nicht darunter. */
#geraet #wrap { position: relative; z-index: 1; box-shadow: none; }

/* --- Das Betriebslicht ---------------------------------------------------
   Links neben dem Bild, wie am Vorbild. Es leuchtet immer - ein Licht,
   das etwas anzeigt, muesste etwas anzeigen koennen, und das kann es
   nicht: der Verbindungszustand steht in der Kopfleiste, wo man ihn liest. */
/* AUF DER FASSUNG, nicht daneben (Runde 111). Am Vorbild sitzt das
   Betriebslicht auf dem dunklen Rahmen links vom Bild. Seit die Fassung
   acht Punkte breit ist, ist dort Platz: sie reicht von
   `--geh-links - --geh-blende` bis `--geh-links`, also von 4 bis 12, und
   die Lampe von 3 Punkten steht mittig darin. Vorher lag sie auf dem
   Flieder und wurde von der wachsenden Fassung halb verdeckt. */
#lampe {
  position: absolute;
  left: calc(var(--zoom) * (var(--geh-links) - var(--geh-blende) + 2px));
  top: calc(var(--zoom) * 30px);
  width: calc(var(--zoom) * 3px);
  height: calc(var(--zoom) * 3px);
  border-radius: 50%;
  background: #E4574A;
  box-shadow: 0 0 calc(var(--zoom) * 4px) calc(var(--zoom) * 1px) rgba(228,87,74,0.7);
}

/* --- Die Blende unten ---------------------------------------------------- */
#blende {
  position: absolute;
  left: calc(var(--zoom) * var(--geh-links));
  right: calc(var(--zoom) * var(--geh-rechts));
  bottom: calc(var(--zoom) * 9px);
  height: calc(var(--zoom) * 22px);
  display: flex;
  align-items: center;
  justify-content: space-between;
}

/* KEINE SERIFE (Runde 111).

   Hier stand Georgia. Ein Markenzug in einer Buchdruckschrift auf einem
   Handheld liest sich wie ein Aufkleber - auf jedem Geraet dieser Bauart
   ist er GEPRAEGT oder gedruckt: schmal, versal, weit gesperrt, ohne
   Serifen. Die Pixelschrift des Spiels kaeme nicht in Frage: sie wird auf
   die Leinwand GEZEICHNET, und das Gehaeuse ist HTML. */
#marke {
  font-family: 'Segoe UI', system-ui, -apple-system, 'Helvetica Neue', sans-serif;
  font-weight: 600;
  font-size: calc(var(--zoom) * 6px);
  letter-spacing: calc(var(--zoom) * 1.6px);
  color: #6B5D86;
  text-shadow: 0 calc(var(--zoom) * 1px) 0 rgba(255,255,255,0.6);
  white-space: nowrap;
}

/* --- START und SELECT ----------------------------------------------------
   Zwei schraege Pillen, wie am Vorbild. Sie sind SCHMUCK und keine
   Bedienung - deshalb `aria-hidden` und kein Zeiger darauf.

   Gekippt um dieselben 13 Grad wie die Knoepfe A und B im Steuerfeld
   (assets/input.js). Zwei Neigungen in einem Geraet waeren eine zu viel;
   das ist dieselbe Ueberlegung, mit der auch das Kreuz die Farbe der
   Knoepfe teilt.

   Beschriftet sind sie NICHT. Bei sechs Punkten Hoehe waere „SELECT" zwei
   Punkte hoch - ein grauer Fleck, der so tut, als stuende dort etwas. */
#tasten {
  display: flex;
  gap: calc(var(--zoom) * 4px);
  align-items: center;
}

#tasten i {
  display: block;
  width: calc(var(--zoom) * 13px);
  height: calc(var(--zoom) * 5px);
  border-radius: calc(var(--zoom) * 3px);
  background: linear-gradient(180deg, #8A7EA6 0%, #6E6288 100%);
  box-shadow:
    0 calc(var(--zoom) * 1px) 0 rgba(255,255,255,0.45),
    inset 0 calc(var(--zoom) * 1px) 0 rgba(255,255,255,0.30);
  transform: rotate(-13deg);
}

/* Sechs schraege Schlitze. Sie sind das einzige Stueck, an dem man dieses
   Gehaeuse ohne Nachdenken als Handheld erkennt - deshalb stehen sie da,
   obwohl kein Lautsprecher dahinter sitzt.

   Runde 111: sie sind DEUTLICHER geworden. Im Foto waren sie ein blasses
   Rechteck von 34 x 14 - Alpha 0,55 auf Flieder, aus zwei Metern nicht
   von einem Schmutzfleck zu unterscheiden. Jetzt 40 x 16, dunkler, und
   mit einem Bogen: `mask-image` schneidet die untere Ecke rund ab, so
   dass die Schlitze nach auszen kuerzer werden. Am Vorbild sitzt das
   Gitter in der abgerundeten Ecke unten rechts und folgt ihr. */
#lautsprecher {
  width: calc(var(--zoom) * 40px);
  height: calc(var(--zoom) * 16px);
  -webkit-mask-image: radial-gradient(120% 150% at 0% 0%, #000 62%, transparent 66%);
  mask-image: radial-gradient(120% 150% at 0% 0%, #000 62%, transparent 66%);
  background:
    repeating-linear-gradient(66deg,
      rgba(84,70,108,0.80) 0 calc(var(--zoom) * 1.5px),
      transparent calc(var(--zoom) * 1.5px) calc(var(--zoom) * 5px));
  border-radius: calc(var(--zoom) * 2px);
}

/* KEINE Medienabfrage, die den Rand wegnimmt.

   Hier stand eine: unter 420 Punkten Hoehe verschwanden Blende und Lampe
   und das Gehaeuse schrumpfte auf 4 Punkte Rand. Das ist genau die zweite
   Wahrheit, vor der der Kopf dieser Datei warnt: `bildmasse` in gfx.js
   reserviert weiterhin 14 oben und 40 unten, und das Bild waere damit
   KLEINER geworden als noetig - auf dem kleinsten Fenster, wo jeder Punkt
   zaehlt. Der Rand ist ohnehin proportional; auf einem 420 Punkte hohen
   Fenster ist er 14 Punkte hoch, und das stoert niemanden. */
