/* ===== Design tokens =====
   Palette und Schriften bewusst identisch zur Elo-Seite, damit sich Start-
   und Unterseite wie eine Seite anfühlen. Einziger Akzent bleibt Rot; das
   warme Orange ist Lampenlicht (Material), kein zweiter Akzent. */
:root {
    --bg: #0a0d12;
    --room-near: #1d2634;
    --room-far: #080b10;

    --text: #f3f3ef;
    --text-muted: #98a2b3;
    --accent: #e32311;
    --accent-soft: rgba(227, 35, 17, 0.18);
    /* Textton des Akzents, identisch zur Elo-Seite: der volle Akzent trägt
       als Text auf Raum-Schwarz nur 4,18:1 und fällt unter AA. */
    --accent-text: #f0644f;
    --glow-warm: rgba(255, 100, 7, 0.55);

    --wood-1: #4b3627;
    --wood-2: #30221a;
    --wood-3: #1d1410;
    --matte: #16181d;
    --matte-2: #1f232a;
    --line: rgba(255, 255, 255, 0.09);

    --font-display: 'Press Start 2P', cursive;
    --font-mono: 'JetBrains Mono', ui-monospace, 'SFMono-Regular', Consolas, monospace;

    /* Ein Radius-System für die ganze Seite: 12px für Objekte,
       4px für Innenteile (Screen, Tastenfeld). */
    --radius: 12px;
    --radius-sm: 4px;

    /* Szenen-Skalierung, pro Breakpoint überschrieben. */
    --s: 1;
}

/* Registriert, damit die Kippwinkel per CSS animierbar sind (Touch-Drift
   unten) und trotzdem per JS gesetzt werden können. Ohne @property-Support
   fällt nur die Drift weg, sonst nichts. */
@property --tx {
    syntax: '<angle>';
    inherits: true;
    initial-value: 0deg;
}

@property --tz {
    syntax: '<angle>';
    inherits: true;
    initial-value: 0deg;
}

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

html {
    color-scheme: dark;
    scroll-behavior: smooth;
    /* Wie auf der Elo-Seite: die Teile, die der Browser stellt, kommen
       ebenfalls aus der Palette statt aus den Systemvorgaben. */
    scrollbar-color: var(--matte-2) var(--bg);
    accent-color: var(--accent);
}

::selection {
    background: var(--accent-soft);
    color: var(--text);
}

::-webkit-scrollbar {
    width: 11px;
    height: 11px;
}

::-webkit-scrollbar-track {
    background: var(--bg);
}

::-webkit-scrollbar-thumb {
    background: var(--matte-2);
    border-radius: 999px;
    border: 2px solid var(--bg);
}

/* Farbe sitzt auf body, nicht auf html: dieselbe Overscroll-Falle wie auf der
   Elo-Seite, siehe Kommentar in elo.css. */
body {
    min-height: 100dvh;
    overflow-x: hidden;
    color: var(--text);
    font-family: var(--font-mono);
    background-color: var(--bg);
    background-image: radial-gradient(120% 90% at 50% 62%, var(--room-near) 0%, var(--room-far) 68%);
    background-attachment: fixed;
}

/* Feines Korn über allem, damit die Verläufe nicht digital-flach wirken.
   Fixed + pointer-events:none, also kein Repaint beim Scrollen. */
body::after {
    content: "";
    position: fixed;
    inset: 0;
    z-index: 5;
    pointer-events: none;
    opacity: 0.05;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ===== Seitenraster ===== */
.page {
    min-height: 100dvh;
    max-width: 1400px;
    margin: 0 auto;
    padding: clamp(24px, 4vh, 56px) clamp(20px, 5vw, 72px) 72px;
    display: grid;
    grid-template-columns: minmax(280px, 400px) 1fr;
    align-items: center;
    gap: clamp(24px, 4vw, 64px);
}

.intro {
    max-width: 42ch;
}

.title {
    font-family: var(--font-display);
    font-size: clamp(26px, 4.4vw, 46px);
    line-height: 1.35;
    letter-spacing: -0.01em;
    text-wrap: balance;
    text-shadow: 0 6px 26px rgba(0, 0, 0, 0.55);
}

.lead {
    margin-top: 22px;
    max-width: 34ch;
    font-size: 14px;
    line-height: 1.75;
    color: var(--text-muted);
    text-wrap: pretty;
}

.foot {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 4;
    /* Auf Geräten mit Homebar/Notch säße der Link sonst unter der Systemleiste. */
    padding: 18px 18px calc(18px + env(safe-area-inset-bottom, 0px));
    text-align: center;
    font-size: 12px;
}

.foot a {
    color: var(--text-muted);
    text-decoration: none;
    border-bottom: 1px solid transparent;
    padding-bottom: 2px;
    transition: color 0.2s ease, border-color 0.2s ease;
}

.foot a:hover,
.foot a:focus-visible {
    color: var(--text);
    border-bottom-color: var(--accent-text);
}

.foot a:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 4px;
    border-radius: var(--radius-sm);
}

/* Gilt für alle drei Links der Seite: kein 300ms-Delay durch Double-Tap-Zoom,
   und statt des blauen System-Highlights übernehmen die :active-Regeln weiter
   unten das Feedback - auf Touch gibt es kein :hover. */
.monitor,
.tile,
.mug-hit,
.foot a {
    touch-action: manipulation;
    -webkit-tap-highlight-color: transparent;
}

/* Nur für Screenreader: meldet das Easter Egg, das sonst rein visuell wäre. */
.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

/* ===== Bühne ===== */
/* Höhe an die Viewporthöhe gekoppelt, sonst schiebt die Bühne auf flachen
   Fenstern die Seite über 100dvh hinaus und die Startseite bekommt eine
   Scrollleiste, die sie nicht braucht. */
/* Die Szene ist absolut positioniert und aus dem Fluss genommen: ihr
   Layout-Kasten ist immer 560x360, unabhängig von --s. Im Fluss würde die
   Bühne deshalb auf kleinen Displays viel höher und breiter reservieren, als
   die skalierte Szene tatsächlich einnimmt. min-height unten entspricht der
   sichtbaren Höhe pro Breakpoint. */
.stage {
    position: relative;
    min-width: 0;
    min-height: min(480px, 60vh);
    perspective: 1500px;
    perspective-origin: 50% 44%;
}

/* Tischfläche ist 560 x 360 in Szenen-Einheiten. Alles darauf wird über
   left/bottom in dieser Ebene platziert und über translateZ angehoben.
   --rx / --rz erben die Kinder, um sich bei Bedarf gegen die Szenendrehung
   zurückzudrehen (nur Hover-Labels tun das, damit sie lesbar bleiben). */
.rig {
    --rx: calc(50deg + var(--tx, 0deg));
    --rz: calc(-18deg + var(--tz, 0deg));

    position: absolute;
    left: 50%;
    top: 50%;
    width: 560px;
    height: 360px;
    transform-style: preserve-3d;
    /* Der Monitor ragt nach oben aus der Grundfläche heraus, deshalb sitzt die
       Tischplatte etwas unterhalb der Bühnenmitte. */
    transform: translate(-50%, calc(-50% + 30px))
               scale(var(--s))
               rotateX(var(--rx))
               rotateZ(var(--rz));
}

.rig > * {
    position: absolute;
    transform-style: preserve-3d;
}

/* ===== Tisch ===== */
.desk-top {
    inset: 0;
    border-radius: var(--radius-sm);
    background:
        linear-gradient(148deg, var(--wood-1) 0%, var(--wood-2) 58%, var(--wood-3) 100%);
    box-shadow: inset 0 0 60px rgba(0, 0, 0, 0.45);
}

/* Maserung, sehr zurückhaltend. */
.desk-top::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
    opacity: 0.35;
    background-image: repeating-linear-gradient(
        104deg,
        rgba(255, 255, 255, 0.035) 0 2px,
        transparent 2px 11px
    );
}

.desk-face {
    background: linear-gradient(#221812, var(--wood-3));
    transform-origin: 0 0;
}

.desk-front {
    left: 0;
    top: 360px;
    width: 560px;
    height: 26px;
    transform: rotateX(-90deg);
}

.desk-side {
    left: 560px;
    top: 0;
    width: 360px;
    height: 26px;
    transform: rotateZ(90deg) rotateX(-90deg);
    filter: brightness(0.78);
}

.leg {
    width: 12px;
    height: 152px;
    background: linear-gradient(#22262e, #12151a);
    transform-origin: 50% 0;
    transform: translateZ(-26px) rotateX(-90deg);
}

.leg-fl { left: 34px; top: 322px; }
.leg-fr { left: 512px; top: 322px; }
.leg-bl { left: 34px; top: 26px; }
.leg-br { left: 512px; top: 26px; }

.floor-shadow {
    left: -50px;
    top: 30px;
    width: 660px;
    height: 400px;
    border-radius: 50%;
    background: radial-gradient(closest-side, rgba(0, 0, 0, 0.62), transparent);
    filter: blur(22px);
    transform: translateZ(-178px);
}

/* ===== Lichtpfützen auf der Platte ===== */
.lamp-pool {
    left: 300px;
    bottom: 70px;
    width: 330px;
    height: 300px;
    border-radius: 50%;
    background: radial-gradient(closest-side, var(--glow-warm), transparent 72%);
    opacity: 0.5;
    transform: translateZ(2px);
    pointer-events: none;
}

.screen-pool {
    left: 165px;
    bottom: 105px;
    width: 240px;
    height: 190px;
    border-radius: 50%;
    background: radial-gradient(closest-side, rgba(227, 35, 17, 0.75), transparent 70%);
    opacity: 0.22;
    transform: translateZ(3px);
    pointer-events: none;
    transition: opacity 0.35s ease;
}

.rig.is-awake .screen-pool {
    opacity: 0.6;
}

/* ===== Monitor (Link auf den Elo-Tracker) ===== */
.monitor-foot {
    left: 220px;
    bottom: 220px;
    width: 120px;
    height: 44px;
    border-radius: 50%;
    background: linear-gradient(#2b3038, #171a1f);
    transform: translateZ(3px);
}

.monitor-neck {
    left: 250px;
    bottom: 240px;
    width: 60px;
    height: 30px;
    background: linear-gradient(#2b3038, #1b1f25);
    transform-origin: 50% 100%;
    transform: rotateX(-90deg);
}

.monitor {
    left: 155px;
    bottom: 240px;
    width: 250px;
    height: 160px;
    padding: 11px 11px 20px;
    border-radius: var(--radius);
    border: 1px solid var(--line);
    background: linear-gradient(165deg, #242a33, var(--matte));
    box-shadow: 0 18px 40px rgba(0, 0, 0, 0.55);
    text-decoration: none;
    transform-origin: 50% 100%;
    transform: translateZ(30px) rotateX(-90deg);
    transition: box-shadow 0.35s ease, border-color 0.35s ease;
}

.monitor:hover,
.monitor:focus-visible {
    border-color: rgba(227, 35, 17, 0.55);
    box-shadow: 0 18px 40px rgba(0, 0, 0, 0.55), 0 0 34px var(--accent-soft);
}

.monitor:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 6px;
}

/* Auf Touch ersetzt :active das fehlende :hover, damit der Tap quittiert wird. */
.monitor:active .monitor-screen {
    background: radial-gradient(120% 120% at 50% 30%, #2a1113, #07090d);
    box-shadow: inset 0 0 26px rgba(227, 35, 17, 0.35);
}

.monitor:active .screen-text {
    color: #ffe9e6;
}

.monitor-screen {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100%;
    border-radius: var(--radius-sm);
    background: radial-gradient(120% 120% at 50% 30%, #12161d, #05070a);
    box-shadow: inset 0 0 22px rgba(0, 0, 0, 0.8);
    transition: background 0.35s ease, box-shadow 0.35s ease;
    position: relative;
    overflow: hidden;
}

/* CRT-Zeilen, damit die Fläche nicht als leeres Rechteck liest. */
.monitor-screen::after {
    content: "";
    position: absolute;
    inset: 0;
    pointer-events: none;
    opacity: 0.5;
    background-image: repeating-linear-gradient(
        rgba(255, 255, 255, 0.045) 0 1px,
        transparent 1px 3px
    );
}

.monitor:hover .monitor-screen,
.monitor:focus-visible .monitor-screen {
    background: radial-gradient(120% 120% at 50% 30%, #2a1113, #07090d);
    box-shadow: inset 0 0 26px rgba(227, 35, 17, 0.35);
}

.screen-text {
    font-family: var(--font-display);
    font-size: 21px;
    line-height: 1.7;
    text-align: center;
    color: #6f7a8a;
    transition: color 0.35s ease, text-shadow 0.35s ease;
}

.monitor:hover .screen-text,
.monitor:focus-visible .screen-text {
    color: #ffe9e6;
    text-shadow: 0 0 14px rgba(227, 35, 17, 0.85);
}

.screen-caret {
    display: inline-block;
    width: 10px;
    height: 17px;
    margin-left: 6px;
    vertical-align: -2px;
    background: currentColor;
    animation: caret-blink 1.1s steps(1) infinite;
}

@keyframes caret-blink {
    0%, 55% { opacity: 1; }
    56%, 100% { opacity: 0; }
}

/* ===== Tastatur, Maus, Tasse, Notizbuch ===== */
.keyboard {
    left: 190px;
    bottom: 40px;
    width: 200px;
    height: 66px;
    border-radius: 8px;
    background: linear-gradient(#262b33, #171a20);
    box-shadow: 0 6px 14px rgba(0, 0, 0, 0.5);
    transform: translateZ(6px) rotateZ(2deg);
    overflow: hidden;
}

.keyboard::after {
    content: "";
    position: absolute;
    inset: 7px;
    border-radius: var(--radius-sm);
    background-image:
        repeating-linear-gradient(90deg, rgba(255, 255, 255, 0.11) 0 11px, transparent 11px 14px),
        repeating-linear-gradient(rgba(255, 255, 255, 0.11) 0 9px, transparent 9px 12px);
}

.mouse {
    left: 412px;
    bottom: 125px;
    width: 40px;
    height: 60px;
    border-radius: 50% 50% 44% 44%;
    background: linear-gradient(150deg, #2a2f38, #14171c);
    box-shadow: 0 5px 12px rgba(0, 0, 0, 0.5);
    transform: translateZ(7px) rotateZ(-6deg);
}

/* pointer-events aus, damit Klicks auf die Tasse an .mug-hit durchgereicht
   werden statt am dekorativen div hängenzubleiben. */
.mug {
    left: 56px;
    bottom: 238px;
    width: 46px;
    height: 50px;
    border-radius: 3px 3px 11px 11px;
    background: linear-gradient(100deg, #efe9df, #c9c1b5);
    pointer-events: none;
    transform-origin: 50% 100%;
    transform: rotateX(-90deg);
    transition: transform 0.25s ease;
}

.mug::after {
    content: "";
    position: absolute;
    right: -15px;
    top: 11px;
    width: 20px;
    height: 26px;
    border: 5px solid #ded6c9;
    border-left-color: transparent;
    border-radius: 50%;
}

.mug-top {
    left: 56px;
    bottom: 228px;
    width: 46px;
    height: 20px;
    border-radius: 50%;
    background: radial-gradient(closest-side, #2a1a12, #120b08);
    border: 2px solid #efe9df;
    pointer-events: none;
    transform: translateZ(50px);
}

.notebook {
    left: 388px;
    bottom: 168px;
    width: 128px;
    height: 84px;
    border-radius: var(--radius-sm);
    background: linear-gradient(140deg, #1b1f26, #101317);
    box-shadow: 0 5px 12px rgba(0, 0, 0, 0.5);
    transform: translateZ(5px) rotateZ(-7deg);
}

.notebook::after {
    content: "";
    position: absolute;
    left: 12px;
    top: 0;
    bottom: 0;
    width: 6px;
    background: var(--accent);
    opacity: 0.75;
}

/* ===== Easter Egg: Kaffee umkippen =====
   Klick auf die Tasse. Sie fällt, der Kaffee läuft über die Platte, der
   Monitor geht kurz aus und kommt mit dem Schriftzug auf dem Kopf zurück.
   Alle vier Animationen laufen 3,2s, damit sie synchron bleiben und home.js
   die Klasse nach einer einzigen Frist wieder entfernen kann. */
.mug-hit {
    left: 44px;
    bottom: 232px;
    width: 70px;
    height: 76px;
    padding: 0;
    border: 0;
    background: none;
    appearance: none;
    -webkit-appearance: none;
    cursor: pointer;
    transform-origin: 50% 100%;
    /* translateZ nach der Drehung: schiebt die Fläche entlang ihrer eigenen
       Normalen vor die Tasse, nicht nach oben. */
    transform: rotateX(-90deg) translateZ(2px);
}

.mug-hit:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 3px;
}

/* Der einzige Hinweis, dass hier etwas zu holen ist: die Tasse wackelt.
   Über :has(), weil der Button im DOM hinter der Tasse steht. Fehlt die
   Unterstützung, entfällt nur der Hinweis. */
.rig:has(.mug-hit:hover) .mug,
.rig:has(.mug-hit:focus-visible) .mug {
    transform: rotateX(-90deg) rotateZ(4deg);
}

.spill {
    left: 26px;
    bottom: 176px;
    width: 116px;
    height: 74px;
    border-radius: 46% 54% 38% 62% / 55% 42% 58% 45%;
    background:
        radial-gradient(120% 90% at 62% 28%, rgba(104, 63, 34, 0.5), transparent 58%),
        radial-gradient(closest-side, rgba(52, 29, 17, 0.97), rgba(28, 16, 10, 0.82));
    box-shadow:
        inset 0 0 14px rgba(0, 0, 0, 0.55),
        0 0 0 1px rgba(126, 82, 48, 0.32);
    opacity: 0;
    pointer-events: none;
    /* Ursprung auf der Standfläche der Tasse, damit die Lache von dort
       ausläuft und nicht aus ihrer eigenen Mitte wächst. */
    transform-origin: 46% 16%;
    transform: translateZ(1px) scale(0);
}

/* Glanzlicht der Schreibtischlampe auf der Flüssigkeit. Ohne das liest die
   Lache auf dem dunklen Holz wie ein Schatten statt wie Kaffee. */
.spill::after {
    content: "";
    position: absolute;
    left: 50%;
    top: 16%;
    width: 36%;
    height: 28%;
    border-radius: 50%;
    background: linear-gradient(122deg, rgba(255, 216, 172, 0.34), transparent 68%);
    filter: blur(2px);
}

.rig.is-glitching .mug {
    animation: mug-tip 3.2s cubic-bezier(0.3, 0.1, 0.3, 1) both;
}

.rig.is-glitching .mug-top {
    animation: mug-empty 3.2s ease both;
}

.rig.is-glitching .spill {
    animation: spill-spread 3.2s ease-out both;
}

.rig.is-glitching .monitor-screen {
    animation: screen-blackout 3.2s steps(1, end) both;
}

.rig.is-glitching .screen-text {
    animation: screen-flip 3.2s steps(1, end) both;
}

/* rotateZ steht hinter rotateX, wirkt also im aufgerichteten Eigenframe der
   Tasse und kippt sie zusätzlich zur Seite. Ohne das fällt sie exakt nach
   vorn und die Silhouette ändert sich kaum. */
@keyframes mug-tip {
    0%       { transform: rotateX(-90deg) rotateZ(0deg); }
    8%       { transform: rotateX(-97deg) rotateZ(-3deg); }
    28%      { transform: rotateX(-18deg) rotateZ(-15deg); }
    34%      { transform: rotateX(-27deg) rotateZ(-17deg); }
    40%, 80% { transform: rotateX(-16deg) rotateZ(-16deg); }
    92%      { transform: rotateX(-93deg) rotateZ(-2deg); }
    100%     { transform: rotateX(-90deg) rotateZ(0deg); }
}

@keyframes mug-empty {
    0%, 8%   { opacity: 1; }
    20%, 86% { opacity: 0; }
    100%     { opacity: 1; }
}

@keyframes spill-spread {
    0%        { opacity: 0; transform: translateZ(1px) scale(0.05); }
    14%       { opacity: 0.92; }
    45%, 80%  { opacity: 0.92; transform: translateZ(1px) scale(1); }
    100%      { opacity: 0; transform: translateZ(1px) scale(1); }
}

/* brightness(0) schwärzt Bildschirm und Text in einem Zug, ohne den
   Farbverlauf des Screens interpolieren zu müssen. */
@keyframes screen-blackout {
    0%, 9%    { filter: brightness(1); }
    11%       { filter: brightness(0); }
    29%       { filter: brightness(0.25); }
    31%, 100% { filter: brightness(1); }
}

@keyframes screen-flip {
    0%, 30%   { transform: none; }
    32%, 72%  { transform: rotate(180deg); color: #ff9d8d; text-shadow: 0 0 14px rgba(227, 35, 17, 0.9); }
    76%, 100% { transform: none; }
}

/* ===== Lampe ===== */
.lamp-base {
    left: 466px;
    bottom: 250px;
    width: 58px;
    height: 26px;
    border-radius: 50%;
    background: linear-gradient(#2b3038, #14171c);
    transform: translateZ(3px);
}

.lamp-pole {
    left: 492px;
    bottom: 263px;
    width: 6px;
    height: 118px;
    background: linear-gradient(#31373f, #1a1e24);
    transform-origin: 50% 100%;
    transform: rotateX(-90deg);
}

.lamp-shade {
    left: 458px;
    bottom: 263px;
    width: 74px;
    height: 44px;
    background: linear-gradient(#3a4048, #1e2229);
    clip-path: polygon(20% 0, 80% 0, 100% 100%, 0 100%);
    transform-origin: 50% 100%;
    transform: translateZ(118px) rotateX(-90deg);
}

.lamp-shade::after {
    content: "";
    position: absolute;
    left: 4%;
    right: 4%;
    bottom: 0;
    height: 8px;
    background: var(--glow-warm);
    filter: blur(5px);
}

/* ===== Icon-Kacheln auf dem Tisch ===== */
.tile {
    width: 92px;
    height: 92px;
    border-radius: var(--radius);
    text-decoration: none;
    transform: translateZ(4px) rotateZ(var(--yaw, 0deg));
}

/* Großzügigere Trefferfläche, ohne die Kachel optisch zu vergrößern. */
.tile::before {
    content: "";
    position: absolute;
    inset: -14px;
}

.tile-linkedin {
    left: 40px;
    bottom: 32px;
    --yaw: 8deg;
}

.tile-steam {
    left: 432px;
    bottom: 26px;
    --yaw: -11deg;
}

.tile-face {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: inherit;
    border: 1px solid var(--line);
    background: linear-gradient(155deg, var(--matte-2), #101318);
    box-shadow: 0 8px 18px rgba(0, 0, 0, 0.55);
    transform: translateZ(0);
    transition: transform 0.3s cubic-bezier(0.2, 0.8, 0.25, 1),
                box-shadow 0.3s ease,
                border-color 0.3s ease;
}

.tile-face img {
    width: 40px;
    height: 40px;
    opacity: 0.82;
    transition: opacity 0.3s ease;
}

.tile:hover .tile-face,
.tile:focus-visible .tile-face {
    transform: translateZ(28px);
    border-color: rgba(227, 35, 17, 0.5);
    box-shadow: 0 26px 34px rgba(0, 0, 0, 0.6), 0 0 26px var(--accent-soft);
}

.tile:hover .tile-face img,
.tile:focus-visible .tile-face img {
    opacity: 1;
}

/* Kachel wird beim Drücken heruntergedrückt statt angehoben: physisches
   Feedback, und auf Touch der einzige Zustand, den es überhaupt gibt. */
.tile:active .tile-face {
    transform: translateZ(10px);
    box-shadow: 0 10px 16px rgba(0, 0, 0, 0.6);
}

.tile:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 8px;
}

/* Das Label ist Bedienoberfläche, kein Möbelstück: es dreht sich mit
   --rz / --rx exakt gegen die Szene zurück und steht damit immer plan zur
   Kamera, auch während die Szene der Maus folgt. */
.tile-label {
    position: absolute;
    left: 50%;
    top: 50%;
    width: max-content;
    padding: 5px 11px;
    border-radius: var(--radius);
    border: 1px solid var(--line);
    background: rgba(10, 13, 18, 0.88);
    font-size: 11px;
    letter-spacing: 0.08em;
    color: var(--text);
    opacity: 0;
    pointer-events: none;
    transform: translate(-50%, -50%)
               translateZ(42px)
               rotateZ(calc(-1 * var(--rz)))
               rotateX(calc(-1 * var(--rx)))
               translateY(-40px);
    transition: opacity 0.25s ease;
}

.tile:hover .tile-label,
.tile:focus-visible .tile-label {
    opacity: 1;
}

/* Fällt das Icon vom CDN aus, wird die Kachel sonst zu einem leeren Quadrat.
   Die Klasse setzt home.js beim Ladefehler. Der Schriftzug rutscht dann aus
   dem schwebenden Chip flach auf die Karte, also genau dorthin, wo sonst das
   Logo liegt - eine leere Karte mit Chip darüber sieht nach Fehler aus, ein
   bedruckter Untersetzer nach Absicht. Ohne Gegendrehung, damit er wie das
   Logo in der Tischebene liegt. */
.tile.is-iconless .tile-face img {
    display: none;
}

.tile.is-iconless .tile-label {
    opacity: 1;
    padding: 0;
    border: 0;
    background: none;
    font-size: 13px;
    font-weight: 600;
    transform: translate(-50%, -50%) translateZ(2px);
    transition: transform 0.3s cubic-bezier(0.2, 0.8, 0.25, 1);
}

/* Mit der Karte anheben, sonst bliebe der Schriftzug beim Hover unten liegen. */
.tile.is-iconless:hover .tile-label,
.tile.is-iconless:focus-visible .tile-label {
    transform: translate(-50%, -50%) translateZ(30px);
}

.tile.is-iconless:active .tile-label {
    transform: translate(-50%, -50%) translateZ(12px);
}

/* ===== Touch-Geräte: sanfte Eigenbewegung statt Maus-Parallaxe ===== */
@media (hover: none) {
    .rig {
        animation: rig-drift 16s ease-in-out infinite alternate;
    }

    /* Ohne Hover müssen die Labels dauerhaft sichtbar sein, sonst ist am
       Handy nicht erkennbar, wohin die Kacheln führen. */
    .tile-label {
        opacity: 1;
    }
}

@keyframes rig-drift {
    from { --tz: -5deg; --tx: 2deg; }
    to   { --tz: 5deg;  --tx: -2deg; }
}

/* ===== Breakpoints ===== */
@media (max-width: 1180px) {
    :root { --s: 0.84; }
    .stage { min-height: min(410px, 54vh); }
}

@media (max-width: 900px) {
    :root { --s: 0.78; }

    .page {
        grid-template-columns: 1fr;
        /* Text und Szene rücken als ein Block in die Mitte, sonst klebt beides
           oben und darunter steht ein halber Bildschirm leer. */
        align-content: center;
        gap: 4px;
    }

    .intro {
        max-width: none;
    }

    .lead {
        max-width: 46ch;
    }

    .stage {
        min-height: min(380px, 44vh);
        width: 100%;
    }
}

/* Ab hier begrenzt die Tischbreite die Skalierung: die beiden Icon-Kacheln
   liegen in den vorderen Tischecken und dürfen nicht angeschnitten werden. */
@media (max-width: 620px) {
    :root { --s: 0.52; }

    .stage {
        min-height: min(265px, 32vh);
        perspective: 1100px;
    }

    .lead {
        font-size: 13px;
    }

    /* Die Trefferfläche schrumpft mit --s mit; auf dem Handy wäre die Tasse
       sonst kaum zu treffen. Sie wächst ausschließlich nach vorn: die
       Standlinie wandert Richtung Tischkante, die Oberkante bleibt bei
       y=20. Nach oben zu wachsen würde dem Monitor Trefferpunkte wegnehmen,
       nach vorn liegt nur leere Platte. */
    .mug-hit {
        left: 8px;
        bottom: 176px;
        width: 118px;
        height: 164px;
    }
}

/* Die Stufen sind so gewählt, dass die projizierte Tischbreite (unskaliert
   ~645px) samt Seitenabstand noch in den Viewport passt und die Kacheln dabei
   über 44px Kantenlänge bleiben. Die -14px-Trefferfläche aus .tile::before
   skaliert mit und kommt on top. */
@media (max-width: 400px) {
    :root { --s: 0.48; }
    .stage { min-height: min(245px, 30vh); }
}

@media (max-width: 345px) {
    :root { --s: 0.42; }
    .stage { min-height: min(215px, 27vh); }
}

/* ===== Reduced motion ===== */
@media (prefers-reduced-motion: reduce) {
    html {
        scroll-behavior: auto;
    }

    .rig {
        animation: none;
    }

    .screen-caret {
        animation: none;
    }

    /* Hover-Feedback bleibt, wird aber sofort statt animiert gesetzt. */
    .tile-face,
    .tile-label,
    .monitor,
    .monitor-screen,
    .screen-text,
    .screen-pool,
    .mug {
        transition-duration: 0.01ms;
    }

    /* Das Easter Egg bleibt auslösbar, verliert aber die Bewegung: die Tasse
       fällt nicht, die Lache wächst nicht. Blackout und der gedrehte
       Schriftzug bleiben, das sind Zustandswechsel, keine Bewegung. */
    .rig.is-glitching .mug {
        animation: none;
    }

    .rig.is-glitching .spill {
        animation: spill-hold 3.2s steps(1, end) both;
    }
}

@keyframes spill-hold {
    0%        { opacity: 0; transform: translateZ(1px) scale(1); }
    14%, 80%  { opacity: 0.92; transform: translateZ(1px) scale(1); }
    100%      { opacity: 0; transform: translateZ(1px) scale(1); }
}
