/* VYNTH — base styles that must apply even before Tailwind's JS runs.
   Plain CSS only; Tailwind utilities live in the @theme block in each page. */

/* ---------------------------------------------------------------- */
/* Self-hosted fonts (SIL OFL) — no Google Fonts network requests.
   Space Grotesk ships as one variable file per subset (400–700);
   IBM Plex Mono as static 400/500 cuts. Latin-ext covers ä ö ü ß.  */
/* ---------------------------------------------------------------- */

@font-face {
  font-family: "Space Grotesk";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("../assets/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("../assets/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;
}

@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../assets/fonts/ibm-plex-mono-latin-400.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: "IBM Plex Mono";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../assets/fonts/ibm-plex-mono-latin-ext-400.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;
}

@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("../assets/fonts/ibm-plex-mono-latin-500.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: "IBM Plex Mono";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("../assets/fonts/ibm-plex-mono-latin-ext-500.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;
}

/* FOUC guard: page is dark from the first painted frame, with or without JS.
   Font lives on html (not body) so Tailwind font utilities on body can win —
   un-layered body rules would beat layered utilities. */
html {
  background: #080808;
  color: #f0ede8;
  font-family: "Space Grotesk", ui-sans-serif, system-ui, sans-serif;
}

body {
  margin: 0;
}

/* Native smooth scrolling for the anchor nav — no libraries. */
html {
  scroll-behavior: smooth;
}

/* Contact form fields: underline only, brand colors, no browser chrome. */
.field {
  width: 100%;
  background: transparent;
  border: 0;
  border-bottom: 1px solid rgb(240 237 232 / 0.3);
  border-radius: 0;
  padding: 0.5rem 0;
  color: inherit;
  font: inherit;
  font-size: 1.125rem;
  resize: vertical;
}
.field:focus {
  outline: none;
  border-bottom-color: #f0ede8;
}

/* Accessibility floor: visible keyboard focus everywhere. */
:focus-visible {
  outline: 2px solid #f0ede8;
  outline-offset: 3px;
}

::selection {
  background: #f0ede8;
  color: #080808;
}

/* ---------------------------------------------------------------- */
/* Film grain overlay — brand-critical texture across the whole page.
   SVG fractal noise tile, jittered with a stepped transform so it
   reads as animated grain (~12 fps), never interpolated motion.     */
/* ---------------------------------------------------------------- */

body::after {
  content: "";
  position: fixed;
  top: -100%;
  left: -100%;
  width: 300%;
  height: 300%;
  z-index: 9999;
  pointer-events: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='256' height='256'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  background-repeat: repeat;
  opacity: 0.06;
  animation: grain 8s steps(10) infinite;
}

/* Jitter stays within ±25% so the oversized layer always covers the viewport. */
@keyframes grain {
  0%, 100% { transform: translate(0, 0); }
  10% { transform: translate(-5%, -10%); }
  20% { transform: translate(-15%, 5%); }
  30% { transform: translate(7%, -25%); }
  40% { transform: translate(-5%, 25%); }
  50% { transform: translate(-15%, 10%); }
  60% { transform: translate(15%, 0%); }
  70% { transform: translate(0%, 15%); }
  80% { transform: translate(3%, 25%); }
  90% { transform: translate(-10%, 10%); }
}

/* ---------------------------------------------------------------- */
/* Hero line reveal — the page's single orchestrated entrance.
   Each line rises once out of a clipped wrapper on load; nothing
   else on the page animates on scroll.                              */
/* ---------------------------------------------------------------- */

.hero-line {
  display: block;
  overflow: hidden;
}

.hero-line > span {
  display: block;
  transform: translateY(115%);
  animation: hero-reveal 0.8s cubic-bezier(0.16, 0.65, 0.1, 1) forwards;
}

.hero-line:nth-child(2) > span {
  animation-delay: 0.12s;
}

@keyframes hero-reveal {
  to { transform: translateY(0); }
}

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

  /* Grain freezes to a static texture — no motion, brand texture stays. */
  body::after {
    animation: none;
  }

  /* Hero lines render in place, no entrance. */
  .hero-line > span {
    animation: none;
    transform: none;
  }
}

/* Legal pages (Datenschutz): generated HTML, styled here because Tailwind's
   preflight strips list bullets and heading sizes. */
.legal { overflow-wrap: anywhere; hyphens: auto; }
.legal h1 { margin-bottom: 2rem; }
.legal h2 { margin: 2.5rem 0 0.75rem; font-size: 0.9375rem; font-weight: 500; }
.legal h3 { margin: 1.5rem 0 0.5rem; font-weight: 500; color: rgb(240 237 232 / 0.7); }
.legal p { margin-bottom: 0.75rem; }
.legal ul { margin-bottom: 0.75rem; padding-left: 1.25rem; list-style: disc; }
.legal ul.index { padding-left: 0; list-style: none; }
.legal li { margin-bottom: 0.375rem; }
.legal a { text-decoration: underline; }
.legal a:hover { color: rgb(240 237 232 / 0.8); }
.legal .seal { margin-top: 2rem; color: rgb(240 237 232 / 0.5); }
