/* =============================================================
   Offkey.Studio — Basis-Styles
   Tokens, Schrift, Animationen, Formularelemente.
   Layout und Abstände kommen aus Tailwind (vendor/tailwind.js).
   ============================================================= */

/* --- Schrift: lokal ausgeliefert, keine externen Requests --- */
@font-face {
  font-family: 'Space Grotesk';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('fonts/space-grotesk-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Space Grotesk';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('fonts/space-grotesk-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* =====================================================================
   Farbtokens — Off-White und Anthrazit.

   Alle Werte stehen als RGB-Kanaele ohne rgb(), damit Tailwind seine
   Transparenzen darauf anwenden kann (bg-surface/60, border-accent/40).
   Die Namen sind bewusst rollenbezogen, nicht farbbezogen:
     ink    = der Grund, auf dem alles liegt
     bone   = die Schrift darauf
     accent = der staerkste Wert, fuer Schaltflaechen und Marker
   Im Dunkelmodus tauschen Grund und Schrift die Plaetze — mehr passiert
   nicht, deshalb muss kein einziges Markup angefasst werden.
   ===================================================================== */
:root {
  /* Off-White mit Papierwaerme. Deutlich genug, um nicht als Weiss
     durchzugehen: 94 % Helligkeit statt 96, spuerbar mehr Gelbanteil.
     Wer es heller will, setzt hier 245 244 241 zurueck. */
  --ink: 241 237 229;        /* #F1EDE5  Off-White        */
  --surface: 249 246 240;    /* #F9F6F0  Karten, heller als der Grund */
  --line: 219 213 201;       /* #DBD5C9  Linien           */
  --bone: 26 29 32;          /* #1A1D20  Schrift          */
  --muted: 84 90 96;         /* #545A60  Nebenschrift     */
  --faint: 138 144 150;      /* #8A9096  Beiwerk          */
  --accent: 43 47 51;        /* #2B2F33  Anthrazit        */
  --accent-hover: 26 29 32;  /* #1A1D20  dunkler beim Hover */

  --grain-o: 0.05;
  --glow-o: 0.05;
  --nav-bg: 241 237 229;

  color-scheme: light;
}

/* --- Dunkelmodus: Grund und Schrift tauschen. --- */
:root[data-theme='dark'] {
  --ink: 26 29 32;           /* #1A1D20  Anthrazit        */
  --surface: 35 39 43;       /* #23272B  Karten           */
  --line: 52 57 62;          /* #343A3E  Linien           */
  --bone: 245 244 241;       /* #F5F4F1  Off-White        */
  --muted: 160 166 172;      /* #A0A6AC  Nebenschrift     */
  --faint: 108 114 120;      /* #6C7278  Beiwerk          */
  --accent: 245 244 241;     /* #F5F4F1  Off-White        */
  --accent-hover: 255 255 255;

  --grain-o: 0.03;
  --glow-o: 0.07;
  --nav-bg: 26 29 32;

  color-scheme: dark;
}

/* Ohne gespeicherte Wahl entscheidet das Betriebssystem.
   Das Skript setzt data-theme, sobald der Nutzer selbst waehlt. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) {
    --ink: 26 29 32;
    --surface: 35 39 43;
    --line: 52 57 62;
    --bone: 245 244 241;
    --muted: 160 166 172;
    --faint: 108 114 120;
    --accent: 245 244 241;
    --accent-hover: 255 255 255;

    --grain-o: 0.03;
    --glow-o: 0.07;
    --nav-bg: 26 29 32;

    color-scheme: dark;
  }
}

/* Waehrend des Umschaltens kurz die Farben ueberblenden. */
:root.theme-shifting,
:root.theme-shifting body,
:root.theme-shifting * {
  transition:
    background-color 0.28s ease,
    border-color 0.28s ease,
    color 0.28s ease !important;
}

/* --- Basis. Steht bewusst vor Tailwind, damit nichts falsch aufblitzt. --- */
html {
  background: rgb(var(--ink));
  scroll-behavior: smooth;
  /* Platz fuer den Scrollbalken immer freihalten. Ohne das ist eine
     kurze Seite (Impressum) breiter als eine lange (Ratgeber), und die
     zentrierte Kopfleiste springt beim Seitenwechsel um die halbe
     Balkenbreite. Genau das war das Wackeln. */
  scrollbar-gutter: stable;
}
body {
  background: rgb(var(--ink));
  color: rgb(var(--bone));
  font-family: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto,
    'Helvetica Neue', Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}
::selection {
  background: rgb(var(--accent) / 0.35);
  color: rgb(var(--ink));
}

/* --- Sichtbarer Fokus. Pflicht, nicht Kür. --- */
:focus-visible {
  outline: 2px solid rgb(var(--accent));
  outline-offset: 3px;
  border-radius: 3px;
}
.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
}
.skip-link:focus {
  left: 1rem;
  top: 1rem;
  padding: 0.75rem 1.25rem;
  background: rgb(var(--accent));
  color: rgb(var(--ink));
  border-radius: 0.5rem;
}

/* --- Feines Korn. Nimmt der dunklen Fläche die Leere. --- */
.grain::after {
  content: '';
  position: fixed;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  opacity: var(--grain-o, 0.04);
  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.9' numOctaves='3'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* --- Scroll-Reveal. Zurückhaltend: Einblenden, leichter Versatz. --- */
.reveal {
  opacity: 0;
  transform: translateY(20px);
  transition:
    opacity 0.75s cubic-bezier(0.16, 1, 0.3, 1),
    transform 0.75s cubic-bezier(0.16, 1, 0.3, 1);
  transition-delay: var(--reveal-delay, 0ms);
}
.reveal.is-visible {
  opacity: 1;
  transform: none;
}

/* --- „Offkey": bewusst leicht schief. Dezent, nicht albern. --- */
.tilt-left { transform: rotate(-1.1deg); }
.tilt-right { transform: rotate(0.9deg); }
.tilt-micro { transform: rotate(-0.4deg); }

/* Handgezogener Akzentstrich unter einzelnen Wörtern */
.underline-off {
  position: relative;
  white-space: nowrap;
}
.underline-off::after {
  content: '';
  position: absolute;
  left: -0.06em;
  right: -0.06em;
  bottom: 0.04em;
  height: 0.09em;
  background: rgb(var(--accent));
  transform: rotate(-0.7deg);
  transform-origin: left center;
  opacity: 0.9;
}

/* --- Sehr weicher Akzentschimmer statt Bildmaterial --- */
.glow {
  position: relative;
  isolation: isolate;
}
.glow::before {
  content: '';
  position: absolute;
  z-index: -1;
  top: -20%;
  left: 50%;
  width: min(1100px, 130%);
  aspect-ratio: 1 / 1;
  transform: translateX(-50%);
  background: radial-gradient(
    circle,
    rgb(var(--accent) / var(--glow-o, 0.05)) 0%,
    rgb(var(--accent) / calc(var(--glow-o, 0.05) * 0.4)) 38%,
    transparent 68%
  );
  pointer-events: none;
}

/* --- Formularelemente --- */
.field {
  width: 100%;
  background: rgb(var(--surface));
  border: 1px solid rgb(var(--line));
  border-radius: 0.625rem;
  padding: 0.875rem 1rem;
  color: rgb(var(--bone));
  font-size: 1rem;
  line-height: 1.5;
  transition: border-color 0.2s ease, box-shadow 0.2s ease, background 0.2s ease;
}
.field::placeholder { color: rgb(var(--faint)); }
.field:hover { border-color: rgb(var(--faint)); }
.field:focus {
  outline: none;
  border-color: rgb(var(--accent));
  background: rgb(var(--surface));
  box-shadow: 0 0 0 3px rgb(var(--accent) / 0.16);
}
select.field {
  appearance: none;
  padding-right: 2.75rem;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='9' viewBox='0 0 14 9' fill='none'%3E%3Cpath d='M1 1L7 7L13 1' stroke='%23A1A1AA' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 1rem center;
  cursor: pointer;
}
textarea.field {
  resize: vertical;
  min-height: 8rem;
}
.field-label {
  display: block;
  font-size: 0.8125rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: rgb(var(--muted));
  margin-bottom: 0.5rem;
}
.field-label .req { color: rgb(var(--accent)); }

/* Eigene Checkbox, damit sie im Dunkeln nicht wie ein Fremdkörper wirkt */
.checkbox {
  appearance: none;
  flex: 0 0 auto;
  width: 1.25rem;
  height: 1.25rem;
  margin-top: 0.1rem;
  border: 1px solid rgb(var(--line));
  border-radius: 0.3rem;
  background: rgb(var(--surface));
  cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease;
}
.checkbox:checked {
  background: rgb(var(--accent));
  border-color: rgb(var(--accent));
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='10' viewBox='0 0 12 10' fill='none'%3E%3Cpath d='M1 5L4.5 8.5L11 1.5' stroke='white' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: center;
}

/* --- Karten --- */
.card {
  background: rgb(var(--surface));
  border: 1px solid rgb(var(--line));
  transition: border-color 0.35s ease, transform 0.35s ease;
}
.card:hover {
  border-color: rgb(var(--accent) / 0.45);
  transform: translateY(-3px);
}

/* --- Sprachumschalter --- */
.lang-btn {
  color: rgb(var(--faint));
  transition: color 0.2s ease;
}
.lang-btn:hover { color: rgb(var(--bone)); }
.lang-btn[aria-pressed='true'] { color: rgb(var(--bone)); }

/* --- Bewegung respektieren --- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .reveal {
    opacity: 1;
    transform: none;
    transition: none;
  }
  .card:hover { transform: none; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}

/* --- Navigationsleiste: transparent, beim Scrollen mit Blur --- */
/* Die Leiste ist immer Glas. Beim Scrollen wird sie nur dichter, damit
   der Text darunter nicht durchschlaegt. Position und Groesse aendern
   sich dabei nicht - die Leiste soll zwischen Seiten stillstehen. */
#site-nav {
  background: rgb(var(--nav-bg) / 0.55);
  border-bottom: 1px solid rgb(var(--bone) / 0.06);
  transition: background 0.3s ease, border-color 0.3s ease, box-shadow 0.3s ease;
  text-shadow: 0 1px 2px rgb(var(--ink) / 0.5);
}
@supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  #site-nav {
    background: rgb(var(--nav-bg) / var(--glass-tint));
    -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(180%);
    backdrop-filter: blur(var(--glass-blur)) saturate(180%);
  }
  #site-nav.is-scrolled {
    background: rgb(var(--nav-bg) / calc(var(--glass-tint) + 0.24));
  }
}
/* Die Leiste hat nur eine Kante - unten. Dort sitzt der Glanz, dort
   bricht das Bild. Ein umlaufender Rahmen waere bei voller Breite falsch. */
#site-nav::after {
  content: '';
  position: absolute;
  inset-inline: 0;
  bottom: -1px;
  height: 1px;
  pointer-events: none;
  background: linear-gradient(
    90deg,
    transparent,
    rgb(255 255 255 / var(--glass-rim)) 18%,
    rgb(255 255 255 / calc(var(--glass-rim) * 0.4)) 52%,
    rgb(255 255 255 / calc(var(--glass-rim) * 0.7)) 82%,
    transparent
  );
}
#site-nav.is-scrolled {
  border-bottom-color: rgb(var(--bone) / 0.09);
  box-shadow: 0 12px 30px -20px rgb(var(--bone) / 0.45);
}
:root[data-theme='dark'] #site-nav.is-scrolled {
  box-shadow: 0 14px 34px -20px rgb(0 0 0 / 0.85);
}

/* Gegendrehung: der Kasten steht schief, der Text darin gerade. */
.tilt-right-reset { transform: rotate(0.4deg); }


/* =====================================================================
   Bewegung & Feinschliff
   Alles hier ist Zugabe: faellt die Technik aus, bleibt die Seite heil.
   ===================================================================== */

/* --- Seitenuebergaenge: bewusst KEINE ---------------------------------
   Hier stand ein weicher Uebergang beim Navigieren (@view-transition).
   Der Browser legt dafuer ein Standbild der alten Seite ueber die neue -
   und in diesem Standbild gibt es unseren Cursor nicht. Er verschwand
   also fuer die Dauer des Uebergangs, rund eine halbe Sekunde. Genau
   das war der Aussetzer.

   Ein weicher Uebergang ist Zierrat, ein durchgehend sichtbarer Cursor
   nicht. Deshalb: harter Wechsel, Cursor bleibt stehen.               */


/* --- Lesefortschritt --------------------------------------------------
   Reine CSS-Scrollanimation. Browser ohne animation-timeline lassen den
   Balken auf scaleX(0) - also unsichtbar statt kaputt.                 */
.scroll-progress {
  position: fixed;
  inset-block-start: 0;
  inset-inline: 0;
  z-index: 60;
  height: 2px;
  background: rgb(var(--accent));
  transform: scaleX(0);
  transform-origin: 0 50%;
  pointer-events: none;
}
@supports (animation-timeline: scroll()) {
  .scroll-progress {
    animation: scroll-progress linear both;
    animation-timeline: scroll(root block);
  }
}
@keyframes scroll-progress {
  to { transform: scaleX(1); }
}


/* --- Eigener Cursor ---------------------------------------------------
   Nur fuer echte Mauszeiger. Touch und Stift behalten das System.      */
.cursor-dot,
.cursor-ring {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 70;
  pointer-events: none;
  border-radius: 9999px;
  opacity: 0;
  transition: opacity 0.25s ease;
  will-change: transform;
}
.cursor-dot {
  width: 6px;
  height: 6px;
  margin: -3px 0 0 -3px;
  background: rgb(var(--accent));
}
.cursor-ring {
  width: 34px;
  height: 34px;
  margin: -17px 0 0 -17px;
  border: 1px solid rgb(var(--accent) / 0.55);
  transition:
    opacity 0.25s ease,
    width 0.25s cubic-bezier(0.16, 1, 0.3, 1),
    height 0.25s cubic-bezier(0.16, 1, 0.3, 1),
    margin 0.25s cubic-bezier(0.16, 1, 0.3, 1),
    background 0.25s ease,
    border-color 0.25s ease;
}
.has-cursor .cursor-dot,
.has-cursor .cursor-ring { opacity: 1; }

/* Ueber Klickbarem wird der Ring groesser und fuellt sich leicht. */
.cursor-ring.is-active {
  width: 56px;
  height: 56px;
  margin: -28px 0 0 -28px;
  background: rgb(var(--accent) / 0.12);
  border-color: rgb(var(--accent) / 0.9);
}

/* Ueber dem Laufband: Ring wird breiter und flacher - er sieht aus wie
   etwas, das man seitlich schieben kann. Beim Zupacken zieht er zusammen. */
.cursor-ring.is-grab {
  width: 74px;
  height: 34px;
  margin: -17px 0 0 -37px;
  border-radius: 9999px;
  background: rgb(var(--accent) / 0.08);
  border-color: rgb(var(--accent) / 0.75);
}
.cursor-ring.is-grabbing {
  width: 52px;
  height: 26px;
  margin: -13px 0 0 -26px;
  background: rgb(var(--accent) / 0.2);
  border-color: rgb(var(--accent));
}

/* Systemcursor ausblenden, solange der eigene laeuft.
   cursor wird zwar vererbt, aber Links, Knoepfe und aufklappbare
   Elemente bringen vom Browser ein eigenes Zeigersymbol mit. Genau die
   muessen einzeln genannt werden - sonst blitzt die Hand auf, sobald
   man ueber die Leiste faehrt. */
.has-cursor,
.has-cursor a,
.has-cursor button,
.has-cursor summary,
.has-cursor label,
.has-cursor [role='button'],
.has-cursor [tabindex],
.has-cursor .card { cursor: none; }

/* Eingabefelder behalten den Textcursor - sonst tippt man blind. */
.has-cursor input,
.has-cursor textarea,
.has-cursor select { cursor: auto; }


/* =====================================================================
   Liquid Glass

   Drei Schichten uebereinander, das macht den Apple-Eindruck aus:
     1. eine halbdurchlaessige Flaeche, die den Hintergrund weichzeichnet
        und die Farben darunter kraeftiger zieht (saturate)
     2. eine helle Kante oben innen - das Licht, das auf der Kante bricht
     3. ein weicher Schlagschatten aussen, der das Element abhebt

   Ohne backdrop-filter (aeltere Browser) bleibt eine schlicht
   halbtransparente Flaeche uebrig - lesbar, nur ohne Milchglas.
   ===================================================================== */
/* Steuerwerte an einer Stelle, damit sich der Eindruck feinjustieren
   laesst, ohne durch alle Regeln zu gehen. */
:root {
  --glass-tint: 0.28;   /* wie stark die Eigenfarbe durchkommt   */
  --glass-blur: 15px;   /* Streuung. Kosten steigen mit dem Radius */
  --glass-rim: 0.85;    /* Helligkeit der Glanzkante             */
  --glass-lens: 1.28;   /* Brechung am Rand                      */
}
:root[data-theme='dark'] {
  --glass-tint: 0.34;
  --glass-rim: 0.30;
  --glass-lens: 1.5;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) {
    --glass-tint: 0.34;
    --glass-rim: 0.30;
    --glass-lens: 1.5;
  }
}

.glass {
  position: relative;
  isolation: isolate;
  background: rgb(var(--surface) / 0.62);
  border: 1px solid rgb(var(--bone) / 0.08);
  box-shadow:
    0 1px 2px -1px rgb(var(--bone) / 0.16),
    0 14px 34px -16px rgb(var(--bone) / 0.3);
}

@supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .glass {
    background: rgb(var(--surface) / var(--glass-tint));
    /* Nicht nur weichzeichnen: Farben darunter kraeftiger ziehen und
       eine Spur aufhellen. Das trennt Glas von blossem Nebel. */
    -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(180%);
    backdrop-filter: blur(var(--glass-blur)) saturate(180%);
  }

  /* Schicht 1 - Brechung am Rand.
     Frueher lag hier ein zweiter backdrop-filter. Zwei gestapelte
     Weichzeichner bedeuten zwei volle Durchgaenge ueber allem, was
     dahinterliegt - das war der teuerste Posten der Seite und der Grund
     fuer das Ruckeln. Der Linseneindruck entsteht jetzt ueber einen
     Helligkeitsverlauf am Rand: optisch fast identisch, aber ohne
     zusaetzlichen Durchgang. */
  .glass::before {
    content: '';
    position: absolute;
    inset: 0;
    z-index: -1;
    border-radius: inherit;
    pointer-events: none;
    background:
      radial-gradient(
        140% 100% at 50% 0%,
        rgb(255 255 255 / calc((var(--glass-lens) - 1) * 0.5)) 0%,
        transparent 42%
      ),
      radial-gradient(
        120% 90% at 50% 100%,
        rgb(255 255 255 / calc((var(--glass-lens) - 1) * 0.22)) 0%,
        transparent 46%
      );
  }
}

/* Schicht 2 - Glanzkante.
   Kein gleichmaessiger Rahmen, sondern ein Lichtverlauf: oben links
   faengt die Kante das Licht, unten rechts glimmt ein zweiter Reflex. */
.glass::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  pointer-events: none;
  padding: 1px;
  background: linear-gradient(
    145deg,
    rgb(255 255 255 / var(--glass-rim)) 0%,
    rgb(255 255 255 / 0.08) 26%,
    transparent 52%,
    rgb(255 255 255 / 0.05) 74%,
    rgb(255 255 255 / calc(var(--glass-rim) * 0.55)) 100%
  );
  -webkit-mask:
    linear-gradient(#000 0 0) content-box,
    linear-gradient(#000 0 0);
  mask:
    linear-gradient(#000 0 0) content-box,
    linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
}

:root[data-theme='dark'] .glass {
  border-color: rgb(var(--bone) / 0.1);
  box-shadow:
    0 1px 2px -1px rgb(0 0 0 / 0.6),
    0 18px 40px -18px rgb(0 0 0 / 0.8);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) .glass {
    border-color: rgb(var(--bone) / 0.1);
    box-shadow:
      0 1px 2px -1px rgb(0 0 0 / 0.6),
      0 18px 40px -18px rgb(0 0 0 / 0.8);
  }
}

/* Schicht 3 - Lesbarkeit.
   Auf Glas steht Text vor wechselndem Untergrund. Ein sehr weicher
   Schatten in der Grundfarbe haelt ihn lesbar, ohne sichtbar zu sein. */
.glass,
.glass-text {
  text-shadow: 0 1px 2px rgb(var(--ink) / 0.55);
}

/* --- Glasknopf: dasselbe Prinzip, kleiner und reaktiv --------------- */
.glass-btn {
  position: relative;
  overflow: hidden;
  transition:
    transform 0.18s cubic-bezier(0.16, 1, 0.3, 1),
    box-shadow 0.25s ease,
    background 0.25s ease,
    border-color 0.25s ease;
}
.glass-btn:hover {
  transform: translateY(-1px);
  background: rgb(var(--surface) / 0.72);
  box-shadow:
    inset 0 1px 0 0 rgb(255 255 255 / 0.6),
    0 16px 36px -14px rgb(var(--bone) / 0.34),
    0 3px 8px -3px rgb(var(--bone) / 0.14);
}
.glass-btn:active { transform: translateY(0) scale(0.985); }

/* Der Hauptknopf bleibt gefuellt - sonst verliert er seine Aufgabe.
   Er bekommt aber dieselbe Lichtfuehrung: heller Grat oben, dunkle
   Kante unten, darunter ein enger Kontakt- und ein weiter Streuschatten.
   Genau diese Staffelung laesst einen Knopf koerperlich wirken. */
.solid-glass {
  position: relative;
  isolation: isolate;
  box-shadow:
    inset 0 1px 0 0 rgb(255 255 255 / 0.26),
    inset 0 -1px 0 0 rgb(0 0 0 / 0.18),
    0 1px 2px 0 rgb(var(--bone) / 0.3),
    0 10px 22px -10px rgb(var(--bone) / 0.45);
  transition:
    transform 0.18s cubic-bezier(0.16, 1, 0.3, 1),
    box-shadow 0.28s ease,
    background 0.25s ease;
}
/* Ein Glanzstreifen, der ueber die obere Haelfte laeuft. */
.solid-glass::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  pointer-events: none;
  background: linear-gradient(
    170deg,
    rgb(255 255 255 / 0.16) 0%,
    rgb(255 255 255 / 0.04) 42%,
    transparent 62%
  );
}
.solid-glass:hover {
  transform: translateY(-1px);
  box-shadow:
    inset 0 1px 0 0 rgb(255 255 255 / 0.34),
    inset 0 -1px 0 0 rgb(0 0 0 / 0.2),
    0 2px 4px 0 rgb(var(--bone) / 0.3),
    0 16px 30px -12px rgb(var(--bone) / 0.5);
}
.solid-glass:active {
  transform: translateY(0) scale(0.985);
  box-shadow:
    inset 0 2px 4px 0 rgb(0 0 0 / 0.22),
    0 1px 2px 0 rgb(var(--bone) / 0.28);
}


/* =====================================================================
   Klickflaechen

   Ein Textlink ist nur so hoch wie seine Schrift - rund 20 Pixel. Als
   Ziel fuer Maus oder Daumen ist das zu wenig; als Richtwert gelten 44.

   Der Trick: Innenabstand vergroessert die Flaeche, ein gleich grosser
   negativer Aussenabstand nimmt ihn aus dem Layout wieder heraus. Die
   Flaeche waechst, die Optik bleibt auf den Pixel gleich. Die Abstaende
   in der Leiste sind entsprechend verkleinert, damit der sichtbare
   Zwischenraum derselbe bleibt wie vorher.
   ===================================================================== */
.nav-link {
  display: inline-flex;
  align-items: center;
  padding: 0.75rem 0.5rem;    /* -> 44 px hoch, 16 px breiter */
  margin-block: -0.75rem;
  border-radius: 0.5rem;
  transition: color 0.2s ease, background 0.2s ease;
}
.nav-link:hover { background: rgb(var(--bone) / 0.05); }

.nav-logo {
  display: inline-flex;
  align-items: center;
  padding: 0.75rem 0.4rem;
  margin-block: -0.75rem;
  margin-inline: -0.4rem;     /* Schriftkante bleibt exakt an Ort */
  border-radius: 0.5rem;
}
.nav-logo:hover { background: rgb(var(--bone) / 0.05); }

/* Fusszeile, Brotkrumen und Rueckwege: nur in der Hoehe wachsen,
   damit sich waagerecht nichts verschiebt. */
footer a,
nav[aria-label='Breadcrumb'] a,
.faq__a a,
.back-home {
  display: inline-flex;
  align-items: center;
  padding-block: 0.55rem;
  margin-block: -0.55rem;
}

/* --- Rueckweg mit Haussymbol -----------------------------------------
   Feine Linie, gleiche Staerke wie die Schrift daneben. Das Symbol
   soll den Weg markieren, nicht um Aufmerksamkeit buhlen. */
/* Nur noch das Symbol, ohne Beschriftung. Damit es trotzdem ein
   ordentliches Ziel bleibt, ist die Flaeche 3 rem im Quadrat - deutlich
   mehr als die 44 Pixel, die als Untergrenze gelten. Der Name steht im
   aria-label, damit Screenreader und Tooltip ihn weiterhin ansagen. */
.back-home {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 3rem;
  height: 3rem;
  padding: 0;
  margin: 0;
  border: 1px solid rgb(var(--line));
  border-radius: 9999px;
  color: rgb(var(--muted));
  transition:
    color 0.2s ease,
    border-color 0.2s ease,
    background 0.25s ease,
    transform 0.25s cubic-bezier(0.16, 1, 0.3, 1);
}
.back-home svg {
  flex: none;
  width: 1.45rem;
  height: 1.45rem;
}
.back-home:hover {
  color: rgb(var(--bone));
  border-color: rgb(var(--faint));
  background: rgb(var(--bone) / 0.05);
  transform: translateY(-1px);
}

/* --- Text mit Tiefe ---------------------------------------------------
   Sehr zurueckhaltend: der Schatten soll Gewicht geben, nicht auffallen. */
.text-relief {
  text-shadow:
    0 1px 0 rgb(var(--ink) / 0.6),
    0 2px 14px rgb(var(--bone) / 0.14);
}


/* --- FAQ zum Aufklappen -----------------------------------------------
   Bewusst <details>/<summary>: funktioniert ohne JavaScript, ist per
   Tastatur bedienbar und der Antworttext steht trotzdem im Dokument -
   Google liest ihn also weiterhin fuer das FAQ-Snippet. */
.faq {
  padding-block: 0.25rem;
}
.faq__q {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1.5rem;
  padding-block: 1.6rem;
  cursor: pointer;
  list-style: none;
  font-family: 'Space Grotesk', ui-sans-serif, system-ui, sans-serif;
  font-size: 1.125rem;
  font-weight: 700;
  line-height: 1.4;
  letter-spacing: -0.01em;
  color: rgb(var(--bone));
  transition: color 0.2s ease;
}
@media (min-width: 640px) {
  .faq__q { font-size: 1.35rem; }
}
/* Das Standard-Dreieck der Browser abschalten. */
.faq__q::-webkit-details-marker { display: none; }
.faq__q::marker { content: ''; }
.faq__q:hover { color: rgb(var(--accent)); }
.has-cursor .faq__q { cursor: none; }

/* Plus, das sich beim Oeffnen zum Minus dreht. */
.faq__icon {
  position: relative;
  flex: none;
  width: 1.4rem;
  height: 1.4rem;
  margin-top: 0.2rem;
  border-radius: 9999px;
  border: 1px solid rgb(var(--line));
  transition: transform 0.35s cubic-bezier(0.16, 1, 0.3, 1), border-color 0.2s ease;
}
.faq__icon::before,
.faq__icon::after {
  content: '';
  position: absolute;
  inset: 50% 0.32rem auto;
  height: 1px;
  background: currentColor;
  transform: translateY(-50%);
  transition: opacity 0.25s ease, transform 0.35s cubic-bezier(0.16, 1, 0.3, 1);
}
.faq__icon::after { transform: translateY(-50%) rotate(90deg); }
.faq__q:hover .faq__icon { border-color: rgb(var(--accent)); }
.faq[open] .faq__icon { transform: rotate(180deg); }
.faq[open] .faq__icon::after { opacity: 0; transform: translateY(-50%) rotate(0deg); }

.faq__a {
  padding-bottom: 1.7rem;
  padding-right: 2.9rem;
}
/* Die Antwort faehrt aus, statt zu springen. Wo das nicht geht,
   erscheint sie einfach - kein Verlust. */
@supports (interpolate-size: allow-keywords) {
  .faq__a {
    animation: faq-open 0.4s cubic-bezier(0.16, 1, 0.3, 1);
  }
}
@keyframes faq-open {
  from { opacity: 0; transform: translateY(-6px); }
  to { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .faq__a { animation: none; }
  .faq__icon, .faq__icon::before, .faq__icon::after { transition: none; }
}


/* --- Umschalter fuer den Farbmodus ------------------------------------ */
.theme-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* 44 px - dieselbe Groesse wie die Schaltflaeche daneben. */
  width: 2.75rem;
  height: 2.75rem;
  border-radius: 9999px;
  color: rgb(var(--muted));
  transition: color 0.2s ease, transform 0.18s cubic-bezier(0.16, 1, 0.3, 1),
    box-shadow 0.25s ease, background 0.25s ease;
}
.theme-btn:hover {
  color: rgb(var(--bone));
  transform: translateY(-1px);
}
.theme-icon { display: none; }

/* Angeboten wird immer der andere Modus: hell zeigt Mond, dunkel Sonne. */
.theme-icon--moon { display: block; }
:root[data-theme='dark'] .theme-icon--moon { display: none; }
:root[data-theme='dark'] .theme-icon--sun { display: block; }

@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) .theme-icon--moon { display: none; }
  :root:not([data-theme='light']) .theme-icon--sun { display: block; }
  :root[data-theme='light'] .theme-icon--moon { display: block; }
  :root[data-theme='light'] .theme-icon--sun { display: none; }
}


/* --- Laufband-Eintraege sind jetzt Links ----------------------------- */
.marquee__link {
  color: inherit;
  text-decoration: none;
  transition: color 0.2s ease;
}
.marquee__link:hover {
  color: rgb(var(--bone));
  text-decoration: underline;
  text-underline-offset: 0.18em;
  text-decoration-thickness: 0.06em;
}


/* --- Laufband ---------------------------------------------------------
   Zwei identische Spuren, die zweite ist fuer Screenreader versteckt.  */
.marquee {
  position: relative;
  overflow: hidden;
  user-select: none;
  cursor: grab;
  touch-action: pan-y;   /* senkrecht scrollen bleibt moeglich */
  /* Der Systemcursor erscheint nur, wo unser eigener nicht laeuft. */
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 10%, #000 90%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 10%, #000 90%, transparent);
}
.marquee.is-dragging { cursor: grabbing; }

/* Die Bahn wird per Skript verschoben; ohne Skript steht sie einfach da. */
.marquee__inner {
  display: flex;
  width: max-content;
  align-items: center;
  will-change: transform;
}
.marquee__track {
  display: flex;
  flex: none;
  align-items: center;
  gap: 3.5rem;
  padding-inline-end: 3.5rem;
}
.marquee__item {
  display: inline-flex;
  align-items: center;
  gap: 3.5rem;
  white-space: nowrap;
  font-weight: 700;
  letter-spacing: -0.02em;
  color: rgb(var(--bone) / 0.22);
  transition: color 0.3s ease;
}
.marquee:hover .marquee__item { color: rgb(var(--bone) / 0.38); }
.marquee__dot {
  width: 7px;
  height: 7px;
  flex: none;
  border-radius: 9999px;
  background: rgb(var(--accent));
  opacity: 0.55;
}
/* Waehrend des Ziehens keine Klicks auf den Links ausloesen. */
.marquee.is-dragging .marquee__link { pointer-events: none; }

/* Laeuft der eigene Cursor, bleibt der Systemzeiger auch beim Greifen
   unsichtbar. Die Rueckmeldung uebernimmt stattdessen der Ring. */
.has-cursor .marquee,
.has-cursor .marquee:hover,
.has-cursor .marquee.is-dragging,
.has-cursor .marquee .marquee__link { cursor: none; }


/* --- Karten mit Lichtkegel -------------------------------------------
   Der Kegel folgt dem Zeiger. Ohne Skript bleibt --spot-o auf 0.       */
.card {
  position: relative;
  isolation: isolate;
}
.card::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  opacity: var(--spot-o, 0);
  transition: opacity 0.35s ease;
  background: radial-gradient(
    18rem circle at var(--spot-x, 50%) var(--spot-y, 50%),
    rgb(var(--accent) / 0.14),
    transparent 62%
  );
}


/* --- Gestaffelte Kopfzeile -------------------------------------------
   Jede Zeile laeuft einzeln ein statt der ganze Block auf einmal.      */
.stagger > * {
  display: block;
  opacity: 0;
  transform: translateY(0.36em);
  animation: line-in 0.9s cubic-bezier(0.16, 1, 0.3, 1) forwards;
  animation-delay: var(--line-delay, 0ms);
}
@keyframes line-in {
  to { opacity: 1; transform: none; }
}


/* --- Bewegung respektieren, zweiter Teil -----------------------------
   Der Block oben deckt die Altbestaende ab, dieser die Zugaben.        */
@media (prefers-reduced-motion: reduce) {
  .marquee__track { animation: none; transform: none; }
  .theme-btn { transition: none; }
  .card::before { display: none; }
  .scroll-progress { display: none; }
  .cursor-dot, .cursor-ring { display: none; }
  .stagger > * { opacity: 1; transform: none; animation: none; }
}

/* --- Bewerben-Button im Header: hüpft nach dem Laden dreimal, dann Ruhe --- */
@keyframes cta-bounce {
  0%, 100% { transform: translateY(0) scale(1); }
  35%      { transform: translateY(-14px) scale(1.04); }
  60%      { transform: translateY(0) scale(1); }
  80%      { transform: translateY(-6px) scale(1.02); }
}
#site-nav a[href$="#bewerbung"] {
  /* startet erst, wenn die Hero-Einblendung durch ist */
  animation: cta-bounce 0.7s cubic-bezier(0.3, 0.7, 0.4, 1) 1.8s 3;
}
@media (prefers-reduced-motion: reduce) {
  #site-nav a[href$="#bewerbung"] { animation: none; }
}

/* --- Wortmarke: Øffkey groß und fett, .studio kleiner und leichter (Verhältnis 1 : 1,618) --- */
.wordmark {
  display: inline-flex;
  align-items: baseline;
  gap: 0.08em;
  line-height: 0.9;
  white-space: nowrap;
}
.wordmark__name { font-weight: 700; letter-spacing: -0.028em; }
.wordmark__tld  { font-weight: 400; letter-spacing: -0.012em; font-size: 0.618em; opacity: 0.72; }
/* In Kopf- und Fußzeile etwas größer als der Fließtext, damit die Marke Präsenz hat */
.nav-logo .wordmark, footer .wordmark { font-size: 1.55rem; }
