/* ==================================================================
   /3d  "Ein Modell läuft"
   A dark control room: charcoal ground, one lit window, a row of keys.
   Sections below are named exactly like the data-sid values in 3d.html:
   GRUND · NAVFUSS (nav and footer on the dark ground) · BUEHNE (kopf, fenster, blende,
   tasten, anzeige) · ZWECK · KONTAKT
   Loads AFTER css/werk.css, which styles only the injected nav and footer here.
   ================================================================== */

/* ---------- GRUND: fonts, tokens, reset ---------- */

/* Archivo for the few headlines, Martian Mono for every readout. Both are the
   studio's house faces and css/werk.css already declares them (same files, same
   ranges), so there is no second @font-face here. */

:root{
  --grund:#0E1113;        /* the room */
  --pult:#151A1D;         /* raised surfaces: keys, readout */
  --pult-kante:#06080A;   /* the dark edge under a key, what makes it look pressable */
  --linie:rgba(206,224,232,.13);
  --text:#DCE3E6;
  --text-leise:#93A0A6;
  --kalt:#86DDF7;         /* the ONE accent: the active piece and the lit frame. Nothing else gets it. */
  --kalt-tief:#0B2A33;
  --studie:#C9B38A;       /* only for the "invented brand" note, so it never reads as a real product */
  --mono:'Martian Mono','Courier New',monospace;
  --sans:'Archivo',Arial,sans-serif;
  --rand:clamp(1rem,3.4vw,3rem);
  --leiste:2.1rem;        /* height of the status strip on top of the window */
}

*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
html{-webkit-text-size-adjust:100%}
body{background:var(--grund);color:var(--text);font-family:var(--sans);font-size:1.02rem;line-height:1.6;-webkit-font-smoothing:antialiased;overflow-x:clip}
img{display:block;max-width:100%}
a{color:inherit}
button{font:inherit;color:inherit;background:none;border:0;cursor:pointer}
[hidden]{display:none !important}
:focus-visible{outline:2px solid var(--kalt);outline-offset:3px}
::selection{background:var(--kalt);color:var(--grund)}

/* ---------- NAVFUSS: the site's own nav and footer on this dark ground ----------
   css/werk.css draws them in cream paper tokens (--ink is the page, --bone the text).
   Re-pointing the tokens HERE, on this page's body only, turns the injected nav, footer
   and contact bar dark without touching werk.css or any other page. The accent is this
   page's cold cyan, so the header pill and the focus rings match the lit window. */
body[data-page="3d"]{
  --ink:var(--grund);--ink-2:var(--pult);
  --bone:var(--text);--bone-dim:var(--text-leise);
  --line:var(--linie);--line-soft:rgba(206,224,232,.08);
  --brass:var(--kalt);
  --nav-h:3.7rem;         /* the fixed header; the stage starts below it */
}
/* The header is fixed, so the page starts under it. On a phone the brand block wraps to
   three lines and the bar is taller (measured 75px at 412 wide). */
main{padding-top:var(--nav-h)}
@media (max-width:700px){body[data-page="3d"]{--nav-h:4.8rem}}
/* While a model runs on a phone it takes the screen; the contact bar steps back
   and returns with the still. */
body[data-page="3d"]:has(.fenster[data-zustand="live"]) .sticky-cta{display:none}

/* ---------- BUEHNE: the stage section ----------
   Desktop: headline on top, window left, readout right, keys under both.
   The window is sized from the viewport HEIGHT so that headline, window and
   keys all sit in the first screen: the start action must never be below the fold.
   22.4rem = the old 21.6rem + the 0.8rem by which the fixed header is taller than
   the draft's thin top strip was. */

.buehne{
  display:grid;grid-template-columns:clamp(30rem,calc((100svh - 22.4rem) * 1.6),calc(100% - 22rem)) minmax(0,1fr);
  grid-template-areas:"kopf kopf" "fenster anzeige" "tasten tasten";
  gap:1.1rem clamp(1rem,2.4vw,2rem);
  padding:1.3rem var(--rand) 2.6rem;max-width:1500px;margin:0 auto;
}

/* buehne-kopf: the headline and its one sub-line share a row on wide screens to save height. */
.buehne-kopf{grid-area:kopf;display:flex;align-items:baseline;justify-content:space-between;flex-wrap:wrap;gap:.4rem 2rem}
h1{font:780 clamp(1.7rem,3.3vw,2.7rem)/1.04 var(--sans);font-stretch:112%;letter-spacing:-.012em;text-wrap:balance}
.unterzeile{font:400 .78rem/1.55 var(--mono);color:var(--text-leise);max-width:44ch}

/* fenster: the lit window. A hairline in the accent colour plus a soft spill of
   light into the room. This frame is the only glow on the page. */
.fenster{
  grid-area:fenster;position:relative;
  background:#000;overflow:hidden;
  box-shadow:0 0 0 1px var(--kalt),0 0 0 5px rgba(134,221,247,.07),0 26px 80px -18px rgba(134,221,247,.2);
}
.fenster-bild{position:relative;aspect-ratio:16/10;overflow:hidden}
.fenster-bild picture,.fenster-bild img,.fenster-bild iframe{position:absolute;inset:0;width:100%;height:100%}
.fenster-bild img{object-fit:cover}
/* The pieces are laid out for a full browser window. Inside a 940 px window their
   own hero type runs out of room, so the frame renders at 125 % and is scaled back
   to 80 %: the piece sees a 1176 px viewport and keeps its desktop composition. */
.fenster-bild iframe{border:0;background:#000;width:125%;height:125%;transform:scale(.8);transform-origin:0 0}
/* A piece in model-only mode is no page: it fills whatever it gets, so it runs 1:1
   and its controls keep their real size. */
.fenster-bild iframe.ist-modell{width:100%;height:100%;transform:none}
/* While a model runs the still stays underneath (no layout change), just unseen. */
.fenster[data-zustand="live"] .starten{display:none}

/* fenster-leiste: the status strip ABOVE the picture, never over it. A running piece
   brings its own header and controls into every corner; an overlay would cover one of them. */
.fenster-leiste{display:flex;align-items:center;gap:.55rem;height:var(--leiste);padding:0 .8rem;background:var(--pult);border-bottom:1px solid var(--linie);font:400 .68rem/1 var(--mono);color:var(--text)}
/* A long piece name must shorten, not wrap: the strip is one line high. */
.fenster-leiste{white-space:nowrap}
.zustand{display:flex;gap:.4rem;min-width:0;overflow:hidden}
/* The piece's name may be long; it shortens, the status word in front of it does not. */
#z-name{min-width:0;overflow:hidden;text-overflow:ellipsis}
.lampe{flex:0 0 auto;width:.5rem;height:.5rem;border-radius:50%;background:var(--text-leise)}
.fenster[data-zustand="live"] .lampe{background:var(--kalt);box-shadow:0 0 8px var(--kalt)}
.fenster-nr{margin-left:auto;color:var(--text-leise)}
.beenden{font:500 .68rem/1 var(--mono);color:var(--grund);background:var(--text);padding:.45rem .7rem;margin-right:-.4rem}
.beenden:hover{background:var(--kalt)}

/* starten: the one action of the page. Square, heavy, in the accent colour. */
.starten{position:absolute;left:clamp(.9rem,2.4vw,1.8rem);bottom:clamp(.9rem,2.4vw,1.8rem);z-index:2;display:inline-flex;align-items:center;gap:.7rem;background:var(--kalt);color:#041217;font:700 1.02rem/1 var(--sans);font-stretch:108%;text-decoration:none;padding:1rem 1.35rem;box-shadow:0 4px 0 var(--kalt-tief);transition:transform .12s ease,box-shadow .12s ease}
.starten::before{content:"";border-left:.62rem solid currentColor;border-block:.4rem solid transparent}
.starten:hover{transform:translateY(-1px);box-shadow:0 5px 0 var(--kalt-tief)}
.starten:active{transform:translateY(3px);box-shadow:0 1px 0 var(--kalt-tief)}
.starten:focus-visible{outline-color:#fff}

/* blende: THE signature moment. Two blades meet in the middle, the content
   changes behind them, they part again. 200 ms each way (BLENDE_MS in site.js).
   The seam carries the accent line, so the hand-over reads as a shutter and not a fade. */
.blende{position:absolute;left:0;right:0;height:50%;z-index:3;background:#080A0C;transition:transform .2s cubic-bezier(.6,0,.3,1);pointer-events:none}
.blende-oben{top:0;transform:translateY(-101%);border-bottom:1px solid var(--kalt)}
.blende-unten{bottom:0;transform:translateY(101%);border-top:1px solid var(--kalt)}
.fenster.ist-zu .blende{transform:none}
@media (prefers-reduced-motion:reduce){.blende{display:none}.starten{transition:none}}

/* tasten: the switcher. Keys with a dark lower edge; the active one sits pressed
   and carries the accent. On narrow screens the row scrolls sideways inside itself. */
.tasten{grid-area:tasten;display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:.6rem;padding-bottom:5px;min-width:0}
.taste{display:grid;grid-template-columns:auto 1fr;gap:.1rem .7rem;align-items:baseline;text-decoration:none;background:var(--pult);border:1px solid var(--linie);border-radius:3px;padding:.75rem .9rem .8rem;box-shadow:0 4px 0 var(--pult-kante);transition:transform .1s ease,box-shadow .1s ease,border-color .15s ease}
.taste-nr{grid-row:span 2;font:400 .68rem/1 var(--mono);color:var(--text-leise)}
.taste-name{font:680 .98rem/1.2 var(--sans);font-stretch:104%}
.taste-verb{font:400 .68rem/1.3 var(--mono);color:var(--text-leise)}
.taste:hover{border-color:rgba(206,224,232,.4)}
.taste:active,.taste[aria-current]{transform:translateY(3px);box-shadow:0 1px 0 var(--pult-kante)}
.taste[aria-current]{border-color:var(--kalt);background:var(--kalt-tief)}
.taste[aria-current] .taste-nr,.taste[aria-current] .taste-verb{color:var(--kalt)}
@media (prefers-reduced-motion:reduce){.taste{transition:none}}

/* anzeige: the readout of the active piece. Open on the room, no card around it. */
.anzeige{grid-area:anzeige;align-self:stretch;display:flex;min-width:0}
.blatt{display:flex;flex-direction:column;gap:.85rem;width:100%;border-left:1px solid var(--linie);padding-left:clamp(1rem,1.8vw,1.6rem)}
.herkunft{font:400 .68rem/1.5 var(--mono);padding-left:1rem;position:relative}
.herkunft::before{content:"";position:absolute;left:0;top:.36em;width:.45rem;height:.45rem;background:currentColor}
.herkunft-echt{color:var(--kalt)}
.herkunft-studie{color:var(--studie)}
/* werk.css gives every h2 wdth 125, tracking and balanced wrapping; this page sets its own. */
.blatt h2{font:760 clamp(1.35rem,2vw,1.75rem)/1.08 var(--sans);font-stretch:110%;font-variation-settings:normal;letter-spacing:normal;text-wrap:wrap}
.satz{color:var(--text);font-size:.98rem;line-height:1.55}
.werte{margin-top:auto;border-top:1px solid var(--linie)}
/* Figure first, label under it: the number is what a product manager scans for. */
.werte div{display:flex;flex-direction:column-reverse;gap:.25rem;padding:.8rem 0 .75rem;border-bottom:1px solid var(--linie)}
.werte dt{font:400 .68rem/1.4 var(--mono);color:var(--text-leise)}
.werte dd{font:500 clamp(1.45rem,2.1vw,1.9rem)/1 var(--mono);letter-spacing:-.02em;white-space:nowrap}
.eigene-seite{text-decoration:underline;font:400 .72rem/1.3 var(--mono);color:var(--text-leise);text-underline-offset:4px;align-self:flex-start;padding:.25rem 0}
.eigene-seite::after{content:" \2197"}
.eigene-seite:hover{color:var(--text)}

/* BUEHNE, narrow: window first and taller (4:5, the pieces need the height on a
   phone), then the keys as one sideways row, then the readout. */
@media (max-width:860px){
  .buehne{grid-template-columns:minmax(0,1fr);grid-template-areas:"kopf" "fenster" "tasten" "anzeige";padding-top:1rem}
  .blatt{border-left:0;padding-left:0}
  .werte{margin-top:.2rem}
}
/* Below 900 px five keys no longer fit side by side with readable labels. */
@media (max-width:900px){
  /* The row may be wider than the screen, the PAGE may not: overflow stays inside .tasten. */
  .tasten{display:flex;overflow-x:auto;scroll-snap-type:x proximity;scrollbar-width:none;margin-inline:calc(var(--rand) * -1);padding-inline:var(--rand);scroll-padding-inline:var(--rand)}
  .tasten::-webkit-scrollbar{display:none}
  .taste{flex:0 0 auto;min-width:9.2rem;scroll-snap-align:start}
}
@media (max-width:700px){
  /* Before a click the whole first screen has to hold: fixed header, headline, sub-line, strip,
     the window, the key row AND the fixed contact bar under it (measured 412/390/360 wide: all
     of that except the window is 330-349 px, the bar 73 px). 27rem = that fixed part plus the
     bar, so the key row ends above the bar; the window gets what is left, never under 19rem. */
  .fenster-bild{aspect-ratio:4/5;max-height:calc(100svh - 27rem - env(safe-area-inset-bottom,0px));min-height:19rem;width:100%}
  /* The narrow stills are 4:5 and the window is now often wider than that (see the max-height above).
     cover would cut the model at top or bottom, so the whole still is shown; the spare side strips
     stay the window's black. */
  .fenster-bild img{object-fit:contain}
  /* On a phone the piece already gets its phone layout at 1:1. */
  .fenster-bild iframe{width:100%;height:100%;transform:none}
  .werte{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:0 .8rem}
  .werte dd{font-size:1.25rem}
  /* A running piece shows its phone layout, which needs a phone's height. The window
     grows to the screen minus strip and key row, so the keys stay reachable under it. */
  .fenster[data-zustand="live"] .fenster-bild{aspect-ratio:auto;max-height:none;height:calc(100svh - 9.5rem - var(--nav-h))}
  /* js/3d.js brings the window's top edge to the top of the screen: below the fixed header. */
  .fenster{scroll-margin-top:var(--nav-h)}
}

/* ---------- ZWECK: what such a model is for. Plain text on the room, two columns ---------- */

.zweck{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.5fr);gap:1.5rem clamp(1.5rem,5vw,5rem);padding:clamp(3rem,8vw,6.5rem) var(--rand);max-width:1500px;margin:0 auto;border-top:1px solid var(--linie)}
.zweck h2,.kontakt h2{font:770 clamp(1.6rem,3.4vw,2.6rem)/1.06 var(--sans);font-stretch:112%;font-variation-settings:normal;letter-spacing:-.01em;text-wrap:balance}
.zweck-text{display:grid;gap:1rem;max-width:58ch;font-size:1.08rem}
.textlink{text-decoration:underline;font:400 .78rem/1.4 var(--mono);text-underline-offset:5px;text-decoration-color:var(--kalt)}
.textlink:hover{color:var(--kalt)}
@media (max-width:760px){.zweck{grid-template-columns:minmax(0,1fr)}}

/* ---------- KONTAKT: one heavy key (WhatsApp), one quiet key (fit check) ---------- */

.kontakt{padding:clamp(3rem,8vw,6.5rem) var(--rand);max-width:1500px;margin:0 auto;border-top:1px solid var(--linie)}
.kontakt-satz{margin-top:1rem;font-size:1.08rem;max-width:50ch}
.kontakt-wege{display:flex;flex-wrap:wrap;gap:.9rem;margin-top:1.8rem}
.knopf{display:inline-block;background:var(--kalt);color:#041217;font:700 1rem/1 var(--sans);font-stretch:108%;text-decoration:none;padding:1.05rem 1.4rem;box-shadow:0 4px 0 var(--kalt-tief)}
.knopf:active{transform:translateY(3px);box-shadow:0 1px 0 var(--kalt-tief)}
.knopf-still{background:var(--pult);color:var(--text);box-shadow:0 4px 0 var(--pult-kante);outline:1px solid var(--linie);outline-offset:-1px}
.knopf:focus-visible{outline:2px solid #fff;outline-offset:3px}
.absender{margin-top:2.2rem;font:400 .74rem/1.9 var(--mono);color:var(--text-leise)}
