/* ==========================================================================
   Silas Pittner - Art Director Portfolio (v6 — all-light pass)

   Rebuilt on the visual language of sthetikstudio.de (thick uniform-width
   outlines, big corner radii, confident bento-grid "brand board" showcases,
   a floating pill nav + persistent side contact-tab, and its uniform-size
   client-card grid under "Projekte"). v5 tried a dark→light→dark bookend —
   rejected: the reference runs entirely on cream whitespace, no dark
   sections anywhere, and that's the correct read. v6 goes fully light,
   corrects Charcoal's role (never the logo or header — it's a secondary
   accent, an occasional card fill, and the ink used for running text/
   headings instead of flat black), and fixes the type-role mapping to match
   Silas' own precise brief. The only two places that still run dark are the
   lightbox scrim and an on-photo badge chip — both are transient UI
   overlays, not page sections, the same convention any light-themed site
   uses for a modal backdrop.

   Type (Marathon/STHETIK's own commercial stack, mapped to free faces):
   Space Grotesk = Headings (all of them — stands in for Marathon Shapiro
   65). JetBrains Mono = Body Text + HUD (stands in for PP Fraktion Mono —
   this is now the running body copy too, not just UI chrome, a deliberate
   full commitment to the mono "spec sheet" voice). Martian Mono = Some
   Text + HUD (KH Interference — stat-rail numerals, credential years).
   Fraunces = Character/Project Names only (IvyPresto — Silas' own name in
   the nav, and each project/client title in the work grid) — never generic
   section headings, which belong to Space Grotesk.
   ========================================================================== */

:root {
  /* Brand colors — cream/orange system, plus Brown (the exact tone from
     Silas' own "name-vertical-brown" logo file, swapped in for the old
     Charcoal) scoped the same way Charcoal was: secondary accent,
     occasional card fill, and the site's text ink instead of flat black.
     Grey (from the matching "name-vertical-grey" file) is the newer,
     third neutral — used specifically for dimmed/secondary text, so the
     hierarchy reads Orange (accent) → Brown (ink/primary) → Grey
     (secondary), instead of secondary text just being diluted ink. */
  --c-cream:      #edead4;
  --c-cream-dim:  #b7ad98;
  --c-orange:     #f97c30;
  --c-orange-2:   #ffb46a;
  --c-orange-dim: #c85f22;
  --c-rust:       #7a2c10;
  --c-rust-deep:  #2c130a;

  --c-brown:      #37352b;
  --c-brown-deep: #211f19;
  --c-brown-2:    color-mix(in srgb, var(--c-brown) 55%, white);
  --c-grey:       #606060;

  /* Accessibility fix: plain --c-orange (2.2:1) and --c-orange-dim (3.4:1)
     both fail WCAG AA against the cream ground for anything that isn't
     large display text — used site-wide for small bold labels (eyebrows,
     credential/bento headings) and for orange text set INSIDE large
     headlines, which only needs the 3:1 large-text minimum but still
     didn't clear it. This darker shade (4.6:1) is for every case where
     orange is the actual text/icon color on cream, not a button
     background — --c-orange itself is untouched everywhere it's a solid
     fill behind dark ink text, which already passed. */
  --c-orange-text: #a2511f;

  /* Paper ground + ink. --c-ink is Brown doing its "text instead of
     black" job — used everywhere EXCEPT the header/logo, which keep a
     plain near-black (--c-header-ink) specifically so Brown never ends
     up branding the identity, per the explicit "nicht für Logo oder
     Header" instruction. --c-ink-dim (all secondary/body-dim text
     site-wide) is Grey-based rather than a diluted --c-ink, so muted text
     reads as a distinct neutral tone instead of a lighter version of the
     brand ink. */
  --c-paper:       var(--c-cream);
  --c-ink:         var(--c-brown);
  --c-ink-dim:     color-mix(in srgb, var(--c-grey) 94%, var(--c-paper));
  --c-header-ink:  #1c1712;
  --c-paper-line:    color-mix(in srgb, var(--c-ink) 16%, var(--c-paper));
  --c-paper-line-hi: color-mix(in srgb, var(--c-orange) 65%, var(--c-ink) 8%);

  --c-text:      var(--c-ink);
  --c-text-dim:  var(--c-ink-dim);
  --c-accent:    var(--c-orange);

  /* Deep near-black, kept ONLY for the two legitimate dark-UI exceptions
     (lightbox scrim, on-photo badge chip) — never a page/section ground. */
  --c-deep:        #120f0d;
  --c-deep-raised: #1d1712;

  /* Thick, uniform-width outline — the single most repeated signature of the
     reference: every card/nav/button/frame gets the same border weight. */
  --c-border:      var(--c-paper-line);
  --c-border-hi:   var(--c-paper-line-hi);
  --border-w: 2px;

  --font-display: "Space Grotesk", "Arial Narrow", sans-serif;
  --font-serif: "Fraunces", "Iowan Old Style", Georgia, serif;
  --font-body: "JetBrains Mono", ui-monospace, "SFMono-Regular", Menlo, monospace;
  --font-mono: "JetBrains Mono", ui-monospace, "SFMono-Regular", Menlo, monospace;
  --font-mono-tech: "Martian Mono", var(--font-mono);

  --container: 1400px;
  --gutter: clamp(1.25rem, 4vw, 3.5rem);

  /* Radii pushed hard toward the reference's rounded-everything system. */
  --radius-sm: 20px;
  --radius-md: 32px;
  --radius-lg: 46px;
  --radius-pill: 999px;

  --ease-out: cubic-bezier(.16,1,.3,1);
  --ease-in-out: cubic-bezier(.65,0,.35,1);

  color-scheme: light;
}

/* ---- Reset ---- */
*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: auto; } /* Lenis drives smooth scroll, avoid double handling */
body, h1, h2, h3, h4, p, figure, blockquote { margin: 0; }
img, svg { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
ul { list-style: none; margin: 0; padding: 0; }
button { font: inherit; color: inherit; background: none; border: none; cursor: pointer; }
input, textarea { font: inherit; }

html, body {
  background: var(--c-cream);
  color: var(--c-text);
}

body {
  font-family: var(--font-body);
  font-size: 16px;
  /* Matches STHETIK's own ~1.4 line-height ratio for running text
     (their 17px body copy sets 23.8px line-height). */
  line-height: 1.4;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

.container {
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

/* Fluid type scale. Space Grotesk is the bold geometric display face — used
   only at headline sizes, never for running text. */
/* Sizes/line-heights tuned to match sthetikstudio.de's own scale (checked
   via computed styles at desktop width): headlines run tight, close to
   1:1 line-height with slightly negative tracking, and noticeably more
   restrained in size than a typical "hero-sized" display face. */
.h-display {
  font-family: var(--font-display);
  font-weight: 700;
  letter-spacing: -0.01em;
  line-height: 1.04;
}
.h-xl   { font-size: clamp(2.25rem, 6vw, 5.4rem); font-weight: 700; }
.h-lg   { font-size: clamp(1.7rem, 3.2vw, 2.75rem); font-weight: 700; }
.h-md   { font-size: clamp(1.15rem, 2vw, 1.7rem); }

/* Serif accent voice (IvyPresto stand-in) — scoped strictly to Character/
   Project Names per the precise font-role brief: the nav wordmark and each
   work-card title use it directly in their own component rules. NOT used
   as a class on generic section headings anymore — those are Space
   Grotesk (.h-display), full stop. Kept as a utility in case a future
   named element needs it. */
.h-serif {
  font-family: var(--font-serif);
  font-weight: 600;
  font-style: italic;
  letter-spacing: -0.01em;
  line-height: 1.05;
}

/* All UI chrome AND running body copy — labels, tags, nav, buttons,
   paragraphs — runs on the mono face. This is "PP Fraktion Mono: Body
   Text + HUD" taken literally: a full commitment to the mono voice rather
   than switching to a humanist sans for readability. */
.eyebrow {
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: 0.75rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--c-orange);
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
}
.eyebrow::before {
  content: "";
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--c-orange);
  flex-shrink: 0;
}

.lede {
  font-size: clamp(1rem, 1.3vw, 1.25rem);
  color: var(--c-text-dim);
  max-width: 42ch;
  /* STHETIK's running/intro text sits at a ~1.4 line-height ratio
     regardless of size — looser than the headlines, tighter than v6's 1.55. */
  line-height: 1.4;
}

/* Grain / noise overlay */
.grain {
  position: fixed;
  inset: 0;
  z-index: 998;
  pointer-events: none;
  opacity: 0.05;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ---- Custom cursor ---- */
body.fine-pointer { cursor: none; }
body.fine-pointer a, body.fine-pointer button { cursor: none; }
.cursor-dot, .cursor-ring {
  position: fixed;
  top: 0; left: 0;
  pointer-events: none;
  border-radius: 50%;
  z-index: 999;
  transform: translate(-50%, -50%);
  will-change: transform;
}
.cursor-dot { width: 7px; height: 7px; background: var(--c-orange); }
.cursor-ring {
  width: 34px; height: 34px;
  border: 2px solid var(--c-orange);
  opacity: 0.55;
  transition: width 0.25s var(--ease-out), height 0.25s var(--ease-out), opacity 0.25s var(--ease-out), border-color 0.25s;
}
.cursor-ring.is-hover { width: 64px; height: 64px; opacity: 0.9; border-color: var(--c-ink); background: color-mix(in srgb, var(--c-orange) 18%, transparent); }
@media (hover: none), (pointer: coarse) {
  .cursor-dot, .cursor-ring { display: none; }
  body.fine-pointer { cursor: auto; }
}
@media (prefers-reduced-motion: reduce) {
  .cursor-dot, .cursor-ring { display: none; }
  body.fine-pointer { cursor: auto; }
}

/* ---- Skip link ---- */
.skip-link {
  position: absolute;
  left: -999px;
  top: 0;
  background: var(--c-orange);
  color: var(--c-ink);
  padding: 0.75rem 1.25rem;
  z-index: 1000;
  font-weight: 700;
  font-family: var(--font-mono);
  border-radius: 0 0 var(--radius-sm) 0;
}
.skip-link:focus { left: 0; top: 0; }

:focus-visible {
  outline: 2px solid var(--c-orange);
  outline-offset: 3px;
}

/* ---- Buttons: pill + trailing circular arrow badge + real outline ---- */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.85rem;
  padding: 0.4rem 0.4rem 0.4rem 1.75rem;
  background: var(--c-orange);
  color: var(--c-ink);
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: 0.92rem;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  border: var(--border-w) solid var(--c-orange);
  border-radius: var(--radius-pill);
  transition: background 0.25s var(--ease-out), color 0.25s var(--ease-out), border-color 0.25s;
  white-space: nowrap;
}
.btn .btn-arrow {
  width: 2.6rem;
  height: 2.6rem;
  flex-shrink: 0;
  border-radius: 50%;
  background: var(--c-brown);
  color: var(--c-cream);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: transform 0.35s var(--ease-out), background 0.25s;
}
.btn .btn-arrow svg { width: 1.05rem; height: 1.05rem; }
.btn:hover { background: var(--c-brown); color: var(--c-cream); }
.btn:hover .btn-arrow { transform: rotate(45deg); background: var(--c-orange); color: var(--c-ink); }
.btn:active .btn-arrow { transform: rotate(45deg) scale(0.92); }

.btn-ghost {
  background: transparent;
  color: var(--c-ink);
  border: var(--border-w) solid var(--c-border);
  padding-left: 1.5rem;
}
.btn-ghost .btn-arrow { background: color-mix(in srgb, var(--c-ink) 8%, var(--c-paper)); color: var(--c-ink); }
/* Bug fix: .btn:hover sets color:var(--c-cream) and this rule used to only
   override background, leaving that cream text color untouched — invisible
   cream-on-cream the instant a light-ground ghost button was hovered.
   Redeclaring color here closes that gap for good. */
.btn-ghost:hover { border-color: var(--c-orange); background: transparent; color: var(--c-ink); }
.btn-ghost:hover .btn-arrow { background: var(--c-orange); color: var(--c-ink); }

/* Secondary text-link with arrow */
.link-arrow {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: 0.85rem;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  border-bottom: var(--border-w) solid var(--c-orange);
  padding-bottom: 0.2rem;
}
.link-arrow svg { width: 1rem; height: 1rem; transition: transform 0.25s var(--ease-out); }
.link-arrow:hover svg { transform: translate(3px,-3px); }

/* ==========================================================================
   Nav — a full-bleed solid slab instead of a floating pill: sharp corners,
   a thick Orange rule along the bottom, cream ground, serif wordmark next
   to the mark. Charcoal is deliberately kept OUT of the header entirely
   (logo mark, rule and wordmark all use the original orange/near-black
   identity, per the explicit "nicht für Logo oder Header" note) — Charcoal
   does its work everywhere else on the page instead. Same fixed structure/
   IDs script.js already hooks (#siteNav[data-scrolled], #navToggle,
   #mobileMenu) so none of the scroll/menu JS needed to change.
   ========================================================================== */
.site-nav {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 900;
  height: 84px;
  display: flex;
  align-items: center;
  background: var(--c-paper);
  border-bottom: 3px solid var(--c-orange);
  transition: height 0.3s var(--ease-out), box-shadow 0.3s var(--ease-out);
}
.site-nav[data-scrolled="true"] {
  height: 68px;
  box-shadow: 0 12px 30px -18px rgba(0,0,0,0.45);
}

.site-nav .container {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
}

.nav-brand { display: flex; align-items: center; gap: 0.65rem; }
/* Only the name-vertical wordmark now — the separate icon mark next to it
   was removed from the header markup, so the logo is the sole brand element
   here (a touch bigger than before to carry that weight on its own), in the
   near-black header-ink used everywhere else in the header — never Orange
   or Charcoal, per the "not for logo or header" rule above. */
.nav-brand-logo {
  height: 36px;
  width: auto;
  transition: height 0.3s var(--ease-out);
}
.site-nav[data-scrolled="true"] .nav-brand-logo { height: 30px; }
@media (max-width: 420px) { .nav-brand-logo { height: 30px; } }

.nav-links {
  display: flex;
  align-items: center;
  gap: 2rem;
}
.nav-links a {
  font-family: var(--font-mono);
  font-size: 0.82rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--c-header-ink);
  position: relative;
  padding: 0.25rem 0;
}
.nav-links a::after {
  content: "";
  position: absolute;
  left: 0; right: 100%;
  bottom: 0;
  height: 2px;
  background: var(--c-orange);
  transition: right 0.3s var(--ease-out);
}
.nav-links a:hover::after { right: 0; }

.nav-cta {
  display: none;
  background: var(--c-orange);
  border-color: var(--c-orange);
  color: var(--c-ink);
  /* Scoped override, not a global .btn change — this is the one button in
     the header, so it stays visibly smaller than the page's regular CTAs. */
  padding: 0.25rem 0.25rem 0.25rem 1.15rem;
  font-size: 0.78rem;
  gap: 0.6rem;
}
.nav-cta .btn-arrow {
  width: 2rem;
  height: 2rem;
  /* Resting state stays cream (never dark) — matches every other btn-arrow's
     "cream circle at rest" look instead of the header-ink circle it had. */
  background: var(--c-cream);
  color: var(--c-header-ink);
}
.nav-cta .btn-arrow svg { width: 0.85rem; height: 0.85rem; }
.nav-cta:hover { background: transparent; border-color: var(--c-header-ink); color: var(--c-header-ink); }
.nav-cta:hover .btn-arrow { background: var(--c-orange); color: var(--c-header-ink); }
@media (min-width: 900px) { .nav-cta { display: inline-flex; } }

.nav-toggle {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 5px;
  padding: 0.5rem;
  min-width: 44px;
  min-height: 44px;
}
.nav-toggle span { width: 22px; height: 2px; background: var(--c-header-ink); transition: transform 0.3s, opacity 0.3s; }
@media (min-width: 900px) { .nav-toggle { display: none; } }
@media (max-width: 899px) { .nav-links { display: none; } }

/* Mobile menu overlay — part of the header/nav system, so it follows the
   same "no Charcoal, no dark ground" rule as the bar itself: full-screen
   cream, not a dark takeover. */
.mobile-menu {
  position: fixed;
  inset: 0;
  background: var(--c-cream);
  z-index: 950;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 1.5rem;
  padding: var(--gutter);
  transform: translateY(-100%);
  transition: transform 0.45s var(--ease-in-out);
}
.mobile-menu[data-open="true"] { transform: translateY(0); }
.mobile-menu a {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 2.35rem;
  color: var(--c-header-ink);
}
.mobile-menu a:hover { color: var(--c-orange); }
.mobile-menu-close {
  position: absolute; top: 26px; right: var(--gutter);
  border: var(--border-w) solid var(--c-border);
  border-radius: 50%;
  padding: 0.6rem;
  color: var(--c-header-ink);
}

/* Floating vertical KONTAKT tab, pinned to the right edge — a persistent,
   always-reachable CTA independent of scroll position (the reference's
   "KONTAKT" ribbon), on top of everything except the lightbox/mobile menu.
   Not part of the header, so its hover state is a legitimate place for
   Charcoal to do its "secondary accent" job. */
.kontakt-tab {
  position: fixed;
  right: 0;
  top: 50%;
  transform: translateY(-50%) rotate(180deg);
  writing-mode: vertical-rl;
  z-index: 890;
  background: var(--c-orange);
  color: var(--c-ink);
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: 0.78rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  padding: 1.5rem 0.65rem;
  border: var(--border-w) solid var(--c-orange);
  /* The 180deg rotate() below flips the box visually, so the side that
     needs to end up flat against the viewport edge (no border, no radius)
     has to be authored as the OPPOSITE side pre-rotation. Round + bordered
     on the left here renders as rounded-and-bordered on the inward side
     after rotation, flat-and-borderless on the edge side. */
  border-left: none;
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  transition: background 0.25s, color 0.25s, padding-right 0.25s var(--ease-out);
}
.kontakt-tab:hover { background: var(--c-brown); color: var(--c-orange); padding-right: 0.95rem; }
@media (max-width: 640px) {
  .kontakt-tab { font-size: 0.7rem; padding: 1.1rem 0.5rem; }
}

/* ==========================================================================
   Hero — light ground, portrait kept in natural color, modeled on STHETIK's
   own hero (explicitly called out as better than the v5 dark-blend version).
   Structure/JS hooks unchanged (.hero-portrait, .hero-exit-veil, h1 .line
   span, .hero-id, .hero-foot).
   ========================================================================== */
.hero {
  position: relative;
  /* Vorher starr 100dvh — auf großen/hohen Monitoren blieb dadurch bei
     kurzen Hero-Texten sehr viel Leerraum unter dem (jetzt vertikal
     mittigen) Text übrig, bevor die nächste Sektion kommt. Gedeckelt,
     damit der Hero nicht unbegrenzt mitwächst. */
  min-height: min(100dvh, 860px);
  display: flex;
  /* Einheitlich auf allen Hero-Seiten vertikal mittig statt (vorher) am
     unteren Rand nur auf der Startseite — Text sitzt jetzt überall auf
     derselben Höhe wie Bild und die Seiten wirken gleich aufgebaut. */
  align-items: center;
  padding-top: clamp(7.5rem, 15vw, 10rem);
  padding-bottom: clamp(3rem, 6vw, 5rem);
  overflow: hidden;
  isolation: isolate;
  background: var(--c-cream);
}

.hero-portrait {
  position: absolute;
  z-index: -1;
  /* Rechte Kante bei JEDER Breite exakt an der Linie vom "Projekt
     anfragen"-Button im Header verankert — per JS gemessen, siehe
     script.js, Suche "hero-edge-inset". Der Fallback-Wert (6rem) greift nur
     für den einen Frame vor dem ersten JS-Lauf bzw. ganz ohne JS. */
  right: var(--hero-edge-inset, 6rem);
  bottom: 0;
  /* War min(96vh, 980px) — bei quadratischen Bildern (z.B. Projekte) so
     breit, dass es jetzt, seit es nicht mehr über den Container-Rand
     hinausragt, in den Fließtext links daneben hineinragen würde. Kleiner
     gesetzt, damit innerhalb des 1400px-Containers immer Luft zum Text
     bleibt. */
  height: min(78vh, 740px);
  width: auto;
  -webkit-mask-image: radial-gradient(ellipse 62% 78% at 62% 42%, black 93%, transparent 100%);
  mask-image: radial-gradient(ellipse 62% 78% at 62% 42%, black 93%, transparent 100%);
  will-change: transform;
}
.hero-portrait img {
  height: 100%;
  width: auto;
  object-fit: cover;
  filter: contrast(1.05) saturate(1.05);
}
.hero-portrait::after {
  content: "";
  position: absolute; inset: 0;
  background: linear-gradient(200deg, color-mix(in srgb, var(--c-cream) 30%, transparent), transparent 55%);
  mix-blend-mode: normal;
}
/* Startseiten-Hero: etwas kleiner als der Standard, und statt einem
   gleichmäßigen Rand-Fade faden hier gezielt die vier ECKEN stärker aus als
   die geraden Kanten (zwei sich kreuzende lineare Gradients, multipliziert:
   an einer Kante wirkt nur eine Achse, in der Ecke beide zusammen). */
/* Projekte-Hero: etwas höher als der Standard (der am unteren Rand hängt),
   damit es nicht so tief im Screen sitzt. */
#arbeiten .hero-portrait {
  bottom: clamp(1.5rem, 5vw, 3.5rem);
}

#top .hero-portrait {
  right: var(--hero-edge-inset, 4rem);
  /* Zurück auf 860px (war kurz auf 360px gedeckelt, um Überlappung mit der
     Headline auf sehr breiten 24-27"-Monitoren zu vermeiden — das hat das
     Bild aber im Normalfall viel zu klein/verloren in der Ecke wirken
     lassen). Der Überlapp-Fall betrifft nur sehr breite Screens; dafür
     bräuchte es eine eigene, breiten-abhängige Lösung statt eines pauschal
     kleineren Bildes. */
  height: min(88vh, 860px);
  -webkit-mask-image:
    linear-gradient(to right, transparent 0%, black 16%, black 84%, transparent 100%),
    linear-gradient(to bottom, transparent 0%, black 12%, black 88%, transparent 100%);
  -webkit-mask-composite: source-in, source-in;
  mask-image:
    linear-gradient(to right, transparent 0%, black 16%, black 84%, transparent 100%),
    linear-gradient(to bottom, transparent 0%, black 12%, black 88%, transparent 100%);
  mask-composite: intersect;
}

/* Backstage-Hero: das Foto ist ein Querformat (Plattenspieler-Setup auf
   Marmorsockel), deutlich kompakter als die Hochformat-Portraits der
   anderen Seiten, sonst würde es bei gleicher Höhe viel zu breit werden
   und in den Text hineinragen. Vertikale Ausrichtung/Padding kommt jetzt
   einheitlich von .hero (siehe oben) — vorher hatte diese Seite (und
   Projekte) ein eigenes, deutlich größeres padding-bottom, das den
   Abstand zur nächsten Sektion unnötig aufgeblasen hat. */
#backstage .hero-portrait {
  height: min(80vh, 780px);
  right: var(--hero-edge-inset, 5rem);
  /* Bild ist deutlich kürzer als die Hero-Höhe — statt wie das
     Standard-.hero-portrait am unteren Rand zu hängen (dann läge sein
     Mittelpunkt zu tief unter dem vertikal zentrierten Text), wird es
     hier selbst vertikal zentriert. */
  top: 50%;
  bottom: auto;
  transform: translateY(-50%);
  /* Noch mal deutlich stärkerer Rand-Fade als vorher (78% -> 55%, Ellipse
     etwas kleiner) — rundherum gleichmäßig statt der kopf-lastigen
     Standard-Ellipse. */
  -webkit-mask-image: radial-gradient(ellipse 60% 66% at 50% 50%, black 55%, transparent 100%);
  mask-image: radial-gradient(ellipse 60% 66% at 50% 50%, black 55%, transparent 100%);
}

.hero-exit-veil {
  position: absolute;
  inset: 0;
  z-index: 5;
  background: var(--c-cream);
  opacity: 0;
  pointer-events: none;
}

/* ==========================================================================
   Mobile Hero — kein Sticky-/Zoom-/Blur-Trick mehr: das Bild ist ein ganz
   normales, statisches Bild oben in der Sektion und scrollt stinknormal mit
   der Seite mit, wie bei jeder anderen mobilen Website auch. Direkt darunter
   folgt der Text im normalen Dokumentfluss. Gilt einheitlich für jeden
   .hero-Block (Startseite, Projekte, Backstage) UND für den eigenen
   .about-hero-Aufbau der Über-mich-Seite.
   ========================================================================== */
@media (max-width: 900px) {
  .hero {
    display: block;
    min-height: 0;
    padding: clamp(6.5rem, 26vw, 7.5rem) 0 clamp(2.5rem, 8vw, 3.5rem);
    overflow: visible;
  }
  .hero-portrait,
  #top .hero-portrait,
  #backstage .hero-portrait {
    position: static;
    z-index: auto;
    right: auto;
    bottom: auto;
    top: auto;
    left: auto;
    transform: none;
    height: auto;
    width: min(88%, 380px);
    margin: 0 auto clamp(2rem, 7vw, 2.75rem);
    box-sizing: border-box;
    padding: 0;
    opacity: 1;
    -webkit-mask-image: none;
    mask-image: none;
  }
  /* Backstage-Hero-Bild am Handy deutlich größer als die anderen. */
  #backstage .hero-portrait { width: min(94%, 440px); }
  .hero-portrait img {
    width: 100%;
    height: auto;
    object-fit: cover;
    display: block;
    border-radius: var(--radius-lg);
  }
  .hero-portrait::after { display: none; }
  .hero-exit-veil { display: none; }
  .hero-inner {
    position: relative;
    z-index: 2;
    margin-top: 0;
  }
  #arbeiten.hero { padding-bottom: clamp(2.5rem, 8vw, 3.5rem); }
  #backstage.hero { padding-bottom: clamp(2.5rem, 8vw, 3.5rem); }
}

/* Über-mich intro — dasselbe bleeding-portrait-fades-into-cream Treatment
   wie beim Hero, Höhe wird per JS an die Höhe des Intro-Textblocks
   angeglichen (siehe script.js, Suche nach "about-portrait"). */
.about-hero { overflow: hidden; isolation: isolate; }
.about-portrait {
  position: absolute;
  z-index: -1;
  /* Rechte Kante wie überall exakt an der Button-Linie verankert (siehe
     script.js, "hero-edge-inset"). */
  right: var(--hero-edge-inset, 13rem);
  top: clamp(3.5rem, 7vw, 5.5rem);
  height: var(--about-text-h, min(52vh, 480px));
  width: auto;
  -webkit-mask-image: radial-gradient(ellipse 60% 70% at 55% 45%, black 55%, transparent 100%);
  mask-image: radial-gradient(ellipse 60% 70% at 55% 45%, black 55%, transparent 100%);
}
.about-portrait img {
  height: 100%;
  width: auto;
  object-fit: cover;
  filter: contrast(1.05) saturate(1.05);
}
.about-portrait::after {
  content: "";
  position: absolute; inset: 0;
  background: linear-gradient(200deg, color-mix(in srgb, var(--c-cream) 30%, transparent), transparent 55%);
}
/* Mobil bekommt Über-mich denselben Aufbau wie jeder andere Hero: normales
   statisches Bild oben, Text folgt direkt im normalen Dokumentfluss darunter
   — kein Sticky/Zoom/Blur mehr (siehe Kommentar beim allgemeinen
   Mobile-Hero-Block weiter oben). */
@media (max-width: 900px) {
  .about-hero {
    display: block;
    min-height: 0;
    padding-top: clamp(6.5rem, 26vw, 7.5rem) !important;
    overflow: visible;
  }
  .about-portrait {
    display: block;
    position: static;
    right: auto;
    left: auto;
    bottom: auto;
    top: auto;
    transform: none;
    height: auto;
    width: min(88%, 380px);
    margin: 0 auto clamp(2rem, 7vw, 2.75rem);
    box-sizing: border-box;
    padding: 0;
    -webkit-mask-image: none;
    mask-image: none;
  }
  .about-portrait img {
    width: 100%;
    height: auto;
    object-fit: cover;
    display: block;
    border-radius: var(--radius-lg);
  }
  .about-portrait::after { display: none; }
  .about-intro {
    position: relative;
    z-index: 2;
    margin-top: 0;
  }
}

/* Faint oversized watermark word — set in the mono face for a "printed
   spec sheet" texture. */
.watermark {
  position: absolute;
  z-index: -1;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  font-family: var(--font-display);
  font-weight: 700;
  text-transform: uppercase;
  font-size: clamp(6rem, 22vw, 20rem);
  line-height: 1;
  color: transparent;
  -webkit-text-stroke: 1.5px color-mix(in srgb, var(--c-ink) 10%, transparent);
  white-space: nowrap;
  pointer-events: none;
  user-select: none;
}

.hero-inner { position: relative; width: 100%; }

.hero-id {
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: 0.8rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--c-ink-dim);
  margin-bottom: 1.5rem;
  display: inline-block;
  padding: 0.5rem 1rem;
  border: var(--border-w) solid var(--c-border);
  border-radius: var(--radius-pill);
}
.hero-id b { color: var(--c-orange); font-weight: 700; }

.hero h1 { max-width: 18ch; will-change: transform, opacity, filter; }
.hero h1 .line { display: block; overflow: hidden; }
.hero h1 .line span { display: inline-block; will-change: transform; }
.hero h1 em { font-style: normal; color: var(--c-orange); -webkit-text-stroke: 0; }

.hero-foot {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 1.85rem;
  /* Näher an die Headline ran (war 2.75rem). */
  margin-top: 1.5rem;
}
/* "Arbeiten ansehen" matches the header CTA's color logic exactly: cream
   circle at rest (never a dark one), transparent/ink-outline on hover
   instead of the default .btn's solid-brown hover fill. */
.hero-foot .btn .btn-arrow { background: var(--c-cream); color: var(--c-header-ink); }
.hero-foot .btn:hover { background: transparent; border-color: var(--c-header-ink); color: var(--c-header-ink); }
.hero-foot .btn:hover .btn-arrow { background: var(--c-orange); color: var(--c-header-ink); }

/* ==========================================================================
   Marquee — one continuous row of pill chips. This is the "occasional card
   background" Charcoal was asked for: the band itself stays light, and
   each chip is its own small Charcoal card.
   ========================================================================== */
.marquee-band {
  border-block: var(--border-w) solid var(--c-paper-line);
  background: var(--c-cream);
}
.marquee { overflow: hidden; padding-block: 1.1rem; }
.marquee-track {
  display: flex;
  align-items: center;
  width: max-content;
  animation: marquee 38s linear infinite;
}
.marquee-track--logos {
  animation-duration: 46s;
}
.marquee-logo {
  height: clamp(1.6rem, 3vw, 2.35rem);
  width: auto;
  margin-inline: clamp(1.4rem, 3.2vw, 2.6rem);
  flex-shrink: 0;
  opacity: 0.55;
  filter: grayscale(1);
  transition: opacity 0.2s ease;
}
.marquee-logo:hover { opacity: 0.85; }
.marquee-track span {
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: clamp(0.8rem, 1.3vw, 0.95rem);
  letter-spacing: 0.03em;
  text-transform: uppercase;
  padding: 0.6rem 1.35rem;
  margin-inline: 0.4rem;
  border-radius: var(--radius-pill);
  border: var(--border-w) solid var(--c-orange);
  background: transparent;
  color: var(--c-ink);
  display: flex;
  align-items: center;
  gap: 0.6rem;
  white-space: nowrap;
}
.marquee-track span::before {
  content: "";
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--c-orange);
  display: inline-block;
  flex-shrink: 0;
}
@keyframes marquee {
  from { transform: translateX(0); }
  to { transform: translateX(-50%); }
}
@media (prefers-reduced-motion: reduce) {
  .marquee-track { animation: none; }
}

/* ==========================================================================
   Stat rail — pinned, scroll-scrubbed counter. Numbers build up in a
   vertical stack and push upward as each new one arrives (not side by
   side), with no border frame and no progress dots — nothing but the
   numbers themselves.
   ========================================================================== */
.stat-rail { position: relative; }
.stat-rail-pin {
  height: 100dvh;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  position: relative;
  background: var(--c-cream);
}
.stat-rail-pin::before {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(ellipse 65% 55% at 50% 45%, var(--rail-tint, transparent), transparent 70%);
  opacity: 0.8;
  transition: background 0.5s var(--ease-out);
}
.stat-rail-pin[data-stat="0"] { --rail-tint: color-mix(in srgb, var(--c-orange) 35%, transparent); }
.stat-rail-pin[data-stat="1"] { --rail-tint: color-mix(in srgb, var(--c-brown) 22%, transparent); }
.stat-rail-pin[data-stat="2"] { --rail-tint: color-mix(in srgb, var(--c-rust) 30%, transparent); }

/* Every item is absolutely positioned from the same anchor point and placed
   purely by transform (see script.js) — no flex/grid flow to fight with,
   so growing one number never reflows its neighbors, and the fixed
   per-item spacing means two items can never overlap. */
.stat-rail-row {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: 640px;
  margin-inline: auto;
  height: clamp(230px, 34vw, 360px);
}
.stat-rail-item {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  opacity: 0;
  will-change: transform;
}
.stat-rail-item .n-wrap {
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: visible;
}
.stat-rail-item .n {
  display: block;
  font-family: var(--font-mono-tech);
  font-weight: 700;
  font-size: clamp(2.25rem, 4.5vw, 3.75rem);
  line-height: 0.95;
  color: var(--c-ink);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.stat-rail-item .l {
  display: block;
  margin-top: 0.75rem;
  max-width: 9em;
  font-family: var(--font-mono);
  font-size: clamp(0.7rem, 1.1vw, 0.85rem);
  font-weight: 700;
  line-height: 1.4;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--c-ink-dim);
  opacity: 0;
}
/* Static fallback for reduced motion / no GSAP */
.stat-rail-static { display: none; padding-block: clamp(3.5rem, 7vw, 5.5rem); }
.stat-rail-static .container {
  display: grid;
  grid-template-columns: 1fr;
  gap: 2.25rem;
  text-align: center;
}
@media (min-width: 700px) {
  .stat-rail-static .container { grid-template-columns: repeat(3, 1fr); }
}
.stat-rail-static .item {
  border: var(--border-w) solid var(--c-border);
  border-radius: var(--radius-md);
  padding: clamp(1.5rem, 3vw, 2.25rem) 1rem;
}
.stat-rail-static .num {
  font-family: var(--font-mono-tech);
  font-weight: 700;
  font-size: clamp(2rem, 4vw, 2.75rem);
  color: var(--c-orange);
  display: block;
}
.stat-rail-static .lbl {
  font-family: var(--font-mono);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-size: 0.78rem;
  color: var(--c-text-dim);
  font-weight: 600;
  margin-top: 0.5rem;
  display: block;
}

@media (prefers-reduced-motion: reduce) {
  .stat-rail { display: none; }
  .stat-rail-static { display: block; }
}

/* ==========================================================================
   Section rhythm
   ========================================================================== */
section { position: relative; }
.section-pad { padding-block: clamp(5rem, 10vw, 9rem); }
.section-head { max-width: 60ch; margin-bottom: clamp(2.5rem, 6vw, 4.5rem); }
.section-head .eyebrow { display: flex; margin-bottom: 1.1rem; }

/* ==========================================================================
   About
   ========================================================================== */
.about-statement {
  font-family: var(--font-display);
  font-weight: 650;
  font-size: clamp(1.8rem, 4vw, 3.2rem);
  line-height: 1.12;
  max-width: 21ch;
  color: var(--c-ink);
}
.about-statement em {
  font-style: normal;
  color: var(--c-orange);
}
.about-copy { margin-top: 2rem; max-width: 58ch; }

.credentials {
  margin-top: clamp(3.5rem, 7vw, 5.5rem);
  display: grid;
  grid-template-columns: 1fr;
  gap: 1.75rem;
}
@media (min-width: 800px) {
  .credentials { grid-template-columns: 1fr 1fr; gap: 1.75rem; }
}
@media (max-width: 900px) {
  /* Mehr Luft zwischen der Erfahrung-Karte und "Signatur" darunter — die
     nächste Sektion kommt mit padding-top:0 (verlässt sich komplett auf
     den Abstand von hier), das war am Handy zu knapp. */
  .credentials { margin-bottom: clamp(1.5rem, 8vw, 3rem); }
}
.credential-group {
  border: var(--border-w) solid var(--c-border);
  border-radius: var(--radius-md);
  padding: clamp(1.75rem, 3vw, 2.5rem);
  transition: border-color 0.3s;
}
.credential-group:hover { border-color: var(--c-border-hi); }
.credential-group h2 {
  font-family: var(--font-mono);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-size: 0.8rem;
  color: var(--c-orange);
  margin-bottom: 1.5rem;
}
.credential-row {
  display: grid;
  grid-template-columns: 4.5rem 1fr;
  gap: 1.25rem;
  padding-block: 1rem;
  border-top: 1px solid color-mix(in srgb, var(--c-ink) 12%, var(--c-paper));
}
.credential-row:last-child { padding-bottom: 0; }
.credential-row .yr {
  font-family: var(--font-mono-tech);
  font-weight: 600;
  color: var(--c-ink-dim);
  font-size: 1rem;
}
.credential-row .lbl { font-weight: 600; }
.credential-row .sub { color: var(--c-text-dim); font-size: 0.9rem; margin-top: 0.15rem; }

/* ==========================================================================
   Signature / brand-board — a self-referential bento grid showing off
   Silas' own visual system (color, type, form, tone), directly modeled on
   the reference site's "Logovarianten / Formsprache / Farbgebung /
   Typografie" showcase — new content, but built only from things already
   true of this site (its real tokens, its real headline face, its real
   copy voice), nothing invented.
   ========================================================================== */
.bento-grid {
  display: grid;
  /* minmax(0, 1fr) statt nur 1fr: eine reine "1fr"-Spalte darf nie schmaler
     werden als der breiteste Inhalt einer Karte (Grid-Default), und genau
     das hat auf schmalen Screens die "Farbgebung"-Karte (4 Farbfelder
     nebeneinander, siehe .bento-swatches) über den Container-Rand hinaus
     nach rechts gesprengt — samt allen anderen Karten in derselben Spalte,
     weil eine Grid-Spalte für alle Zeilen gleich breit ist. */
  grid-template-columns: minmax(0, 1fr);
  gap: 1.5rem;
}
@media (min-width: 720px) {
  .bento-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
.bento-card {
  border: var(--border-w) solid var(--c-border);
  border-radius: var(--radius-md);
  padding: clamp(1.75rem, 3vw, 2.5rem);
  display: flex;
  flex-direction: column;
  min-height: 15rem;
  min-width: 0;
  transition: border-color 0.3s;
}
.bento-card:hover { border-color: var(--c-border-hi); }
.bento-card h3 {
  font-family: var(--font-mono);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-size: 0.78rem;
  color: var(--c-orange);
  margin-bottom: auto;
  padding-bottom: 1.5rem;
}

/* Formsprache: a live demo of the site's own corner-radius language */
.bento-shape {
  align-self: center;
  justify-self: center;
  width: 100%;
  max-width: 220px;
  aspect-ratio: 1.3;
  border: var(--border-w) dashed color-mix(in srgb, var(--c-ink) 30%, transparent);
  border-radius: var(--radius-lg);
  position: relative;
  background: color-mix(in srgb, var(--c-orange) 12%, transparent);
}
.bento-shape::after {
  content: "";
  position: absolute; left: -2px; top: -2px;
  width: 46%; height: 46%;
  border-top: var(--border-w) solid var(--c-orange);
  border-left: var(--border-w) solid var(--c-orange);
  border-radius: var(--radius-lg) 0 0 0;
}

/* Farbgebung: real token swatches with hex labels */
.bento-swatches { display: flex; gap: 1rem; margin-top: auto; }
.bento-swatch {
  flex: 1;
  /* min-width:0 — ohne das erzwingt ein Flex-Kind standardmäßig mindestens
     seine Inhalts-Breite (hier der Hex-Code, z.B. "#F97C30"), wodurch die
     vier Farbfelder in Summe breiter werden wollten als die Karte selbst
     und (weil Grid-Spalten sich am breitesten Inhalt orientieren, siehe
     .bento-grid) den ganzen Signatur-Bereich auf schmalen Screens nach
     rechts über den Seitenrand hinaus gesprengt haben. */
  min-width: 0;
  border-radius: var(--radius-sm);
  padding: 1.1rem;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  aspect-ratio: 1;
  border: var(--border-w) solid var(--c-border);
}
.bento-swatch b {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  display: block;
}
.bento-swatch span {
  font-family: var(--font-mono);
  font-size: 0.68rem;
  opacity: 0.75;
  display: block;
  margin-top: 0.2rem;
  overflow-wrap: anywhere;
}
.bento-swatch.is-orange { background: var(--c-orange); color: var(--c-ink); }
.bento-swatch.is-cream { background: color-mix(in srgb, var(--c-ink) 5%, var(--c-paper)); color: var(--c-ink); }
.bento-swatch.is-brown { background: var(--c-brown); color: var(--c-cream); }
.bento-swatch.is-grey { background: var(--c-grey); color: var(--c-cream); }

/* Typografie: big live specimen in the actual headline face */
.bento-specimen {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(3.5rem, 8vw, 5.5rem);
  line-height: 1;
  color: var(--c-ink);
  margin-top: auto;
}
.bento-caption {
  font-family: var(--font-mono);
  font-size: 0.78rem;
  color: var(--c-text-dim);
  margin-top: 0.75rem;
}

/* Tonalität: one confident statement. Headings font, not the serif — the
   serif face is scoped strictly to Character/Project Names now (nav
   wordmark, work-card titles), not generic voice/tagline text. */
.bento-voice {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(2rem, 5vw, 3.1rem);
  color: var(--c-orange);
  line-height: 1.1;
  margin-top: auto;
}

/* ==========================================================================
   Services — numbered bento cards with an icon-in-circle (was a plain
   editorial row list)
   ========================================================================== */
.services-list {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1.5rem;
}
@media (min-width: 700px) {
  .services-list { grid-template-columns: repeat(3, 1fr); }
}
.service-row {
  border: var(--border-w) solid var(--c-border);
  border-radius: var(--radius-md);
  padding: clamp(1.75rem, 3vw, 2.25rem);
  position: relative;
  transition: border-color 0.3s var(--ease-out), transform 0.3s var(--ease-out);
  /* Same alignment logic as .tile: headline/text top-aligned, the
     "kann umfassen" tags always flush with the card's bottom edge. */
  display: flex;
  flex-direction: column;
}
.service-row:hover { border-color: var(--c-border-hi); transform: translateY(-4px); }
.service-icon {
  width: 3rem; height: 3rem;
  border-radius: 50%;
  border: var(--border-w) solid var(--c-border);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--c-orange);
  margin-bottom: 1.5rem;
}
.service-icon svg { width: 1.4rem; height: 1.4rem; }
.service-num {
  display: block;
  font-family: var(--font-mono);
  font-weight: 700;
  color: var(--c-ink-dim);
  font-size: 0.78rem;
  letter-spacing: 0.06em;
  margin-bottom: 0.6rem;
}
.service-row h3 {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(1.25rem, 2vw, 1.5rem);
  line-height: 1.15;
  letter-spacing: -0.01em;
  margin-bottom: 0.75rem;
  min-height: 2.5em;
}
/* Garantierter Mindestabstand zum Tag-Block darunter, selbst wenn diese
   Card die höchste in der Reihe ist und .service-subhead's margin-top:auto
   dadurch keinen übrigen Platz zum Verteilen hat (gleiche Logik wie bei
   .tile p). */
.service-row p { color: var(--c-text-dim); margin-bottom: 1.75rem; }

/* "Kann zum Beispiel umfassen" sub-items — mirrors STHETIK's numbered-tier
   pattern of listing concrete deliverables under each service. */
.service-subhead {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--c-ink-dim);
  margin-top: auto;
  margin-bottom: 0.6rem;
}
.service-subitems { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.service-subitems span {
  font-family: var(--font-mono);
  font-size: 0.74rem;
  font-weight: 600;
  padding: 0.35rem 0.75rem;
  border-radius: var(--radius-pill);
  border: 1px solid var(--c-paper-line);
  color: var(--c-ink-dim);
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
}
.service-subitems svg { width: 0.95rem; height: 0.95rem; flex-shrink: 0; stroke: currentColor; }

/* ==========================================================================
   Work — filterable grid. Cards now carry the full thick-outline treatment;
   filter/gallery/tilt behavior in script.js is untouched.
   ========================================================================== */
.work-filter {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-bottom: clamp(2rem, 4vw, 3rem);
}
.filter-btn {
  padding: 0.6rem 1.4rem;
  border-radius: var(--radius-pill);
  border: var(--border-w) solid var(--c-border);
  background: transparent;
  color: var(--c-text-dim);
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  transition: background 0.25s var(--ease-out), border-color 0.25s, color 0.25s;
}
.filter-btn:hover { border-color: var(--c-border-hi); color: var(--c-ink); }
.filter-btn.is-active { background: var(--c-orange); border-color: var(--c-orange); color: var(--c-ink); }

/* v5: every card in the grid is now the same size — is-featured used to
   span a bigger grid area, which is exactly the "warum sind meine Cards
   alle unterschiedlich groß" bug. Uniform aspect-ratio image + fixed body
   layout for every card, filter category or not (matches the reference's
   own client grid, where every card is identical regardless of content). */
.work-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(1.25rem, 2.5vw, 1.75rem);
}
@media (max-width: 1000px) {
  .work-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 640px) {
  .work-grid { grid-template-columns: 1fr; }
}
.work-card.is-filtered-out { display: none; }

.work-card {
  border-radius: var(--radius-md);
  background: transparent;
  border: var(--border-w) solid var(--c-border);
  overflow: hidden;
  perspective: 900px;
  display: flex;
  flex-direction: column;
  transition: transform 0.3s var(--ease-out), border-color 0.3s;
}
.work-card:hover { transform: translateY(-6px); border-color: var(--c-border-hi); }

.work-card-media { aspect-ratio: 4/5; overflow: hidden; position: relative; }
.work-card-media img {
  width: 100%; height: 100%;
  object-fit: cover;
  filter: grayscale(0.4);
  transition: filter 0.4s var(--ease-out), transform 0.5s var(--ease-out);
}
.work-card:hover .work-card-media img { filter: grayscale(0); transform: scale(1.04); }

.work-card-body { padding: clamp(1.25rem, 2vw, 1.75rem); display: flex; flex-direction: column; flex: 1; }

.work-tag {
  display: inline-block;
  align-self: flex-start;
  font-family: var(--font-mono);
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--c-ink);
  background: var(--c-orange);
  padding: 0.4rem 0.85rem;
  border-radius: var(--radius-pill);
  margin-bottom: 0.85rem;
}
/* Project/client titles — Character/Project Names get the serif face
   (IvyPresto stand-in), the one place Fraunces is used outside the nav
   wordmark, per the precise font-role brief. */
.work-card-body h3 {
  font-family: var(--font-serif);
  font-style: italic;
  font-weight: 600;
  font-size: 1.3rem;
  margin-bottom: 0.5rem;
}
.work-card-body p {
  color: var(--c-text-dim);
  font-size: 0.92rem;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.work-card-body .link-arrow { margin-top: 1.1rem; }

/* Gallery cards */
.gallery-badge {
  position: absolute;
  top: 0.9rem; right: 0.9rem;
  padding: 0.35rem 0.75rem;
  border-radius: var(--radius-pill);
  background: color-mix(in srgb, var(--c-deep) 65%, transparent);
  backdrop-filter: blur(6px);
  color: var(--c-cream);
  font-family: var(--font-mono);
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  border: 1px solid color-mix(in srgb, var(--c-cream) 20%, transparent);
}
.gallery-open {
  background: none; border: none; padding: 0; cursor: pointer;
  font: inherit;
}

/* Video-category cards: title list instead of running text */
.work-video-list {
  margin-top: 0.9rem;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}
.work-video-list li {
  font-family: var(--font-mono);
  font-size: 0.8rem;
  color: var(--c-text-dim);
  padding-left: 1.1rem;
  position: relative;
  line-height: 1.4;
}
.work-video-list li::before {
  content: "";
  position: absolute;
  left: 0; top: 0.5em;
  width: 5px; height: 5px;
  border-radius: 50%;
  background: var(--c-orange);
}

/* ==========================================================================
   Lightbox — Grafikdesign galleries
   ========================================================================== */
.lightbox {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: flex;
  align-items: center;
  justify-content: center;
  background: color-mix(in srgb, var(--c-deep) 92%, transparent);
  backdrop-filter: blur(10px);
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.3s var(--ease-out), visibility 0.3s;
  padding: clamp(1rem, 5vw, 4rem);
}
.lightbox.is-open { opacity: 1; visibility: visible; }

.lightbox-figure {
  margin: 0;
  max-width: min(1100px, 92vw);
  max-height: 86vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1rem;
}
.lightbox-figure img {
  max-width: 100%;
  max-height: 76vh;
  width: auto; height: auto;
  border-radius: var(--radius-sm);
  border: var(--border-w) solid var(--c-border);
  box-shadow: 0 30px 80px -20px rgba(0,0,0,0.6);
  opacity: 0;
  transform: scale(0.98);
  transition: opacity 0.25s var(--ease-out), transform 0.25s var(--ease-out);
}
.lightbox-figure img.is-loaded { opacity: 1; transform: scale(1); }
.lightbox-figure figcaption {
  font-family: var(--font-mono);
  color: var(--c-cream-dim);
  font-size: 0.8rem;
  letter-spacing: 0.02em;
}

.lightbox-close, .lightbox-nav {
  position: fixed;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 48px; height: 48px;
  border-radius: 50%;
  border: var(--border-w) solid color-mix(in srgb, var(--c-cream) 25%, transparent);
  background: color-mix(in srgb, var(--c-deep-raised) 80%, transparent);
  color: var(--c-cream);
  cursor: pointer;
  transition: background 0.25s, border-color 0.25s, transform 0.2s;
}
.lightbox-close:hover, .lightbox-nav:hover {
  background: var(--c-orange);
  border-color: var(--c-orange);
  color: var(--c-ink);
}
.lightbox-close { top: clamp(1rem, 3vw, 2rem); right: clamp(1rem, 3vw, 2rem); }
.lightbox-nav { top: 50%; transform: translateY(-50%); }
.lightbox-nav:hover { transform: translateY(-50%); }
.lightbox-prev { left: clamp(0.75rem, 2.5vw, 2rem); }
.lightbox-next { right: clamp(0.75rem, 2.5vw, 2rem); }
@media (max-width: 640px) {
  .lightbox-close, .lightbox-nav { width: 40px; height: 40px; }
}

/* ==========================================================================
   Contact — stays on the same light ground as the rest of the page now
   (no dark bookend). A bordered "framed" panel, slightly lifted off the
   page background, keeps it reading as its own moment.
   ========================================================================== */
.contact-section {
  position: relative;
  isolation: isolate;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
  margin-bottom: clamp(3rem, 7vw, 5.5rem);
  overflow: hidden;
  display: grid;
  /* Wieder etwas größere Bild-Spalte (42% -> 46%) für ein größeres Bild. */
  grid-template-columns: minmax(0, 1fr) minmax(0, 46%);
  /* Zurück auf center — der Text-Höhen-Abgleich (JS) ist hier wieder raus,
     das Bild ist jetzt eine fixe, großzügige Größe statt exakt an den
     (eher kurzen) Kontakt-Text gekoppelt zu sein. */
  align-items: center;
  min-height: clamp(26rem, 40vw, 34rem);
}
.contact-section .container { grid-column: 1 / 2; grid-row: 1; width: 100%; max-width: none; padding-inline: 0; margin-inline: 0; }
.contact-copy { max-width: 30rem; }
.contact-copy h2 em { font-style: normal; color: var(--c-orange); }

/* Mini-Hero-Bild: groß, mit Fade zum Rand, eigene Grid-Spalte rechts. Fixe,
   großzügige Höhe statt an den (kurzen) Kontakt-Text gekoppelt — das hatte
   das Bild zuletzt zu klein wirken lassen. Mit margin-right wieder etwas
   vom rechten Rand eingerückt statt komplett flush an der Kante. */
.contact-portrait {
  grid-column: 2 / 3;
  grid-row: 1;
  /* Rechte Kante wie überall exakt an der Button-Linie verankert — kein
     margin-right mehr, das hat das Bild bewusst von der Linie weg nach
     innen gerückt. */
  justify-self: end;
  height: min(82vh, 760px);
  width: auto;
  aspect-ratio: 1 / 1;
  margin-block: clamp(1.5rem, 4vw, 2.5rem);
  /* Weniger Fade am rechten Rand: Ellipse-Zentrum etwas nach rechts
     verschoben (42% -> 48%) und Fade-Start später (55% -> 66%), damit die
     rechte Bildhälfte nicht mehr vorzeitig ausfaded. */
  -webkit-mask-image:
    radial-gradient(ellipse 58% 70% at 48% 44%, black 66%, transparent 100%),
    linear-gradient(to right, black 99%, transparent 100%);
  -webkit-mask-composite: source-in, source-in;
  mask-image:
    radial-gradient(ellipse 58% 70% at 48% 44%, black 66%, transparent 100%),
    linear-gradient(to right, black 99%, transparent 100%);
  mask-composite: intersect;
}
.contact-portrait img { height: 100%; width: 100%; object-fit: cover; display: block; filter: contrast(1.05) saturate(1.05); }
@media (max-width: 900px) {
  .contact-section { display: block; padding-block: clamp(3rem, 9vw, 4.5rem); }
  .contact-portrait {
    justify-self: center;
    height: auto;
    width: min(100%, 420px);
    aspect-ratio: 1;
    margin: 0 auto clamp(1.5rem, 5vw, 2rem);
    /* Gleicher rechteckiger Rand-Fade wie bei den anderen Hero-Bildern
       mobile, statt der ovalen Vignette. */
    -webkit-mask-image:
      linear-gradient(to right, transparent 0%, black 12%, black 88%, transparent 100%),
      linear-gradient(to bottom, transparent 0%, black 12%, black 88%, transparent 100%);
    -webkit-mask-composite: source-in, source-in;
    mask-image:
      linear-gradient(to right, transparent 0%, black 12%, black 88%, transparent 100%),
      linear-gradient(to bottom, transparent 0%, black 12%, black 88%, transparent 100%);
    mask-composite: intersect;
  }
  .contact-portrait img { width: 100%; }
  .contact-copy { max-width: none; }
}

/* ==========================================================================
   Backstage — "Sonst noch so": dasselbe Zwei-Spalten-Muster wie .contact-section
   (Text links, Bild als eigene Spalte rechts daneben), hier für das Flat-Lay,
   das vorher oben im Hero saß.
   ========================================================================== */
.sonst-section {
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
  display: grid;
  /* Bild-Spalte nochmal etwas größer (60% -> 64%), Bild soll noch mehr
     Gewicht bekommen. */
  grid-template-columns: minmax(0, 1fr) minmax(0, 64%);
  align-items: start;
  gap: clamp(1rem, 2.5vw, 2rem);
}
.sonst-section .container { grid-column: 1 / 2; grid-row: 1; width: 100%; max-width: none; padding-inline: 0; margin-inline: 0; }
/* Textspalte ist trotz kleinerer Spaltenbreite (Bild wurde größer) nicht
   mehr über eine ch-Obergrenze künstlich eingeengt — Lede/H2 füllen jetzt
   die volle verfügbare Spaltenbreite (wie der Fließtext im Hero), dadurch
   deutlich weniger Zeilenumbrüche statt der vorherigen ~8 Zeilen. */
.sonst-section .lede { max-width: none; }
.sonst-section h2 { max-width: none; }
.sonst-section .service-subitems { max-width: 27rem; }
.sonst-portrait {
  grid-column: 2 / 3;
  grid-row: 1;
  /* Rechtsbündig — das Bild reicht bis zum selben rechten Rand wie jedes
     andere Element auf der Seite. Größe kommt jetzt direkt aus der
     (größeren) Spaltenbreite statt aus dem Textblock daneben — JS setzt
     nur noch den vertikalen Versatz, damit die Bildmitte auf derselben
     Höhe wie die Mitte von Headline+Fließtext liegt (siehe script.js,
     Suche "syncSonstPortrait"). Da das Bild deutlich höher ist als der
     Text, rückt es dadurch bewusst über die Headline hinaus nach oben. */
  justify-self: end;
  width: 100%;
  height: auto;
  margin-top: 0px;
  aspect-ratio: 2471 / 2056;
  -webkit-mask-image: radial-gradient(ellipse 65% 65% at 50% 50%, black 22%, transparent 100%);
  mask-image: radial-gradient(ellipse 65% 65% at 50% 50%, black 22%, transparent 100%);
}
.sonst-portrait img { width: 100%; height: 100%; object-fit: cover; display: block; filter: contrast(1.05) saturate(1.05); }
@media (max-width: 900px) {
  .sonst-section { display: block; }
  .sonst-portrait { width: min(100%, 380px); height: auto; margin: 0 auto clamp(1.5rem, 5vw, 2rem); }
  .sonst-section .lede { max-width: none; }
  .sonst-section h2 { max-width: 26ch; }
}

.contact-email {
  font-family: var(--font-display);
  font-weight: 650;
  font-size: clamp(1.15rem, 2.8vw, 2.1rem);
  color: var(--c-ink);
  display: inline-block;
  line-height: 1.1;
  white-space: nowrap;
  position: relative;
}
.contact-email::after {
  content: "";
  position: absolute;
  left: 0; right: 100%;
  bottom: 0.06em;
  height: clamp(2px, 0.4vw, 6px);
  background: var(--c-orange);
  transition: right 0.4s var(--ease-out);
}
.contact-email:hover::after { right: 0; }
.contact-email:hover { color: var(--c-orange); }

.contact-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 2rem 3rem;
  margin-top: clamp(2.5rem, 5vw, 4rem);
  padding-top: clamp(2rem, 4vw, 3rem);
  border-top: var(--border-w) solid var(--c-border);
}
.contact-meta .grp h3 {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--c-text-dim);
  margin-bottom: 0.5rem;
}
.contact-meta .grp p, .contact-meta .grp a { font-weight: 600; }
.contact-meta .grp .social-row { margin-top: 1.7rem; }
.social-row { display: flex; gap: 0.9rem; }
.social-row a {
  width: 44px; height: 44px;
  display: flex; align-items: center; justify-content: center;
  border: var(--border-w) solid var(--c-border);
  border-radius: 50%;
  color: var(--c-ink);
  transition: border-color 0.25s, background 0.25s, color 0.25s;
}
/* Charcoal doing its "occasional card/element background" job again. */
.social-row a:hover { border-color: var(--c-brown); background: var(--c-brown); color: var(--c-cream); }
.social-row svg { width: 18px; height: 18px; }

/* ==========================================================================
   Footer
   ========================================================================== */
.site-footer {
  background: var(--c-cream);
  border-top: var(--border-w) solid var(--c-paper-line);
  padding-block: 2.5rem;
}
.site-footer .container {
  display: flex;
  flex-wrap: wrap;
  gap: 1.5rem;
  align-items: center;
  justify-content: space-between;
}
.footer-legal { display: flex; gap: 1.75rem; font-family: var(--font-mono); }
.footer-legal a { font-size: 0.8rem; color: var(--c-text-dim); text-transform: uppercase; letter-spacing: 0.03em; }
.footer-legal a:hover { color: var(--c-ink); }
.footer-brand { display: flex; align-items: center; gap: 0.75rem; color: var(--c-text-dim); font-family: var(--font-mono); font-size: 0.8rem; }
.footer-brand svg { width: 20px; height: auto; }

/* ==========================================================================
   Legal pages (impressum / datenschutz)
   ========================================================================== */
.legal-hero { padding-top: clamp(8rem, 16vw, 11rem); padding-bottom: 3rem; }
.legal-body { max-width: 70ch; }
.legal-body h2 {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1.5rem;
  margin-top: 3rem;
  margin-bottom: 1rem;
  color: var(--c-orange);
}
.legal-body p, .legal-body li { color: var(--c-text-dim); margin-bottom: 0.9rem; }
.legal-body a { color: var(--c-ink); text-decoration: underline; text-underline-offset: 3px; }
.legal-body ul { padding-left: 1.25rem; list-style: disc; }

/* Placeholder card face — used where a project has no real still yet
   (the Videografie cards: 18 real titles, no per-video thumbnails to scrape).
   Honest "Vorschau folgt" treatment instead of stretching a generic stock
   photo across four different cards. */
.work-placeholder-media {
  aspect-ratio: 4/3;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.75rem;
  background: repeating-linear-gradient(135deg, color-mix(in srgb, var(--c-ink) 6%, var(--c-paper)) 0 14px, color-mix(in srgb, var(--c-ink) 3%, var(--c-paper)) 14px 28px);
  border-bottom: var(--border-w) solid var(--c-paper-line);
}
.work-placeholder-media svg { width: 2.75rem; height: 2.75rem; color: color-mix(in srgb, var(--c-ink) 35%, transparent); }
.work-placeholder-note {
  font-family: var(--font-mono);
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--c-ink-dim);
}
/* ==========================================================================
   Brand-explainer — "warum das wichtig ist", 3 benefit tiles right after
   the stat rail (mirrors STHETIK's own post-hero explainer block).
   Reused as a generic .tile system for Prozess/Perspektive/Kurzcheck too.
   ========================================================================== */
.tile-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1.5rem;
}
@media (min-width: 700px) {
  .tile-grid.cols-3 { grid-template-columns: repeat(3, 1fr); }
  .tile-grid.cols-2 { grid-template-columns: repeat(2, 1fr); }
}
.tile {
  border: var(--border-w) solid var(--c-border);
  border-radius: var(--radius-md);
  padding: clamp(1.75rem, 3vw, 2.25rem);
  transition: border-color 0.3s var(--ease-out), transform 0.3s var(--ease-out);
  /* Flex column so every card in a row lines its headline/text/CTA up on
     the same lines, whatever the row's tallest card and each card's own
     text length happen to be (grid stretch already equalizes the card
     height; this decides how that extra space gets used inside it). */
  display: flex;
  flex-direction: column;
}
.tile:hover { border-color: var(--c-border-hi); transform: translateY(-4px); }
.tile .tile-num {
  display: block;
  font-family: var(--font-mono);
  font-weight: 700;
  color: var(--c-ink-dim);
  font-size: 0.78rem;
  letter-spacing: 0.06em;
  margin-bottom: 0.9rem;
}
.tile h3 {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(1.2rem, 2vw, 1.45rem);
  line-height: 1.15;
  letter-spacing: -0.01em;
  margin-bottom: 0.65rem;
  /* Reserves 2 lines' worth of space so a one-line title and a two-line
     title still leave the body copy starting on the same line as its
     neighbors in the row. */
  min-height: 2.6em;
  /* Mittig im reservierten Block statt oben — auf gleicher Höhe wie das
     Logo in .tile-logo-wrap (dieselbe min-height, dasselbe align-items). */
  display: flex;
  align-items: center;
}
.tile p {
  color: var(--c-text-dim);
  /* Guaranteed minimum gap above the CTA even when this card is the
     tallest in its row and the flex "margin-top: auto" below has no
     leftover space to distribute — previously that case left the button
     touching the text directly. */
  margin-bottom: 1.5rem;
}
/* The CTA (button or text-link) is always the tile's last element and
   always sits flush with the card's bottom edge, regardless of how much
   headline/body text sits above it. */
.tile > .btn, .tile > .link-arrow, .tile > .tile-links { margin-top: auto; }
/* Logo steht für sich allein über dem Titel — der Markenname taucht nur
   noch im Fließtext auf, nicht nochmal direkt neben/unter dem Logo. Der
   Wrapper reserviert exakt denselben Block wie ".tile h3" (gleiche
   Font-Size-Basis fürs em, gleiche min-height/margin-bottom), damit der
   Fließtext bei Logo- und Titel-Kacheln auf derselben Höhe startet. Das
   Logo selbst liegt per align-items mittig in diesem Block, zwischen der
   Nummer drüber und dem Fließtext drunter, statt unten am Text zu kleben. */
.tile-logo-wrap {
  display: flex;
  align-items: center;
  font-size: clamp(1.2rem, 2vw, 1.45rem);
  min-height: 2.6em;
  margin-bottom: 0.65rem;
}
.tile-logo { height: 22px; width: auto; max-width: 140px; object-fit: contain; display: block; }
/* Mehrere Links in einer Kachel (z.B. SoundCloud + Instagram) statt nur
   einem einzigen .link-arrow als direktem Kind. */
.tile-links { display: flex; flex-wrap: wrap; gap: 0.9rem 1.5rem; }
/* The one place a tile is explicitly allowed to sit on a solid accent
   background instead of the plain outlined card — used sparingly, not as
   a default. Orange fill + ink text (same pairing as the header CTA and
   the default .btn), not Charcoal. */
.tile.is-accent { background: var(--c-orange); border-color: var(--c-orange); color: var(--c-ink); }
.tile.is-accent .tile-num { color: color-mix(in srgb, var(--c-ink) 65%, transparent); }
.tile.is-accent h3 { color: var(--c-ink); }
.tile.is-accent p { color: color-mix(in srgb, var(--c-ink) 80%, transparent); }
.tile.is-accent:hover { border-color: var(--c-header-ink); }
.tile.is-accent .btn-ghost, .tile.is-accent .btn-ghost:hover { color: var(--c-ink); border-color: color-mix(in srgb, var(--c-ink) 35%, transparent); background: transparent; }
.tile.is-accent .btn-ghost .btn-arrow { background: color-mix(in srgb, var(--c-ink) 15%, transparent); color: var(--c-ink); }
.tile.is-accent .btn-ghost:hover { border-color: var(--c-header-ink); }
.tile.is-accent .btn-ghost:hover .btn-arrow { background: var(--c-header-ink); color: var(--c-cream); }
.tile.is-accent .link-arrow { border-bottom-color: var(--c-header-ink); color: var(--c-ink); }

/* ==========================================================================
   Prozess — a numbered vertical sequence, same spec-sheet language as the
   credentials rows.
   ========================================================================== */
.process-list { display: flex; flex-direction: column; }
.process-row {
  display: grid;
  grid-template-columns: 3.5rem 1fr;
  gap: 1.5rem;
  padding-block: clamp(1.5rem, 3vw, 2rem);
  border-top: 1px solid color-mix(in srgb, var(--c-ink) 12%, var(--c-paper));
}
.process-row:first-child { border-top: none; }
.process-icon {
  width: 3rem; height: 3rem;
  border-radius: 50%;
  border: var(--border-w) solid var(--c-border);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--c-orange);
  flex-shrink: 0;
}
.process-icon svg { width: 1.35rem; height: 1.35rem; }
.process-row h3 {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(1.1rem, 1.8vw, 1.35rem);
  line-height: 1.15;
  letter-spacing: -0.01em;
  margin-bottom: 0.4rem;
}
.process-row p { color: var(--c-text-dim); max-width: 55ch; }

/* ==========================================================================
   Perspektive — Instagram (real, functional) + Blog (honest placeholder)
   ========================================================================== */
.perspektive-statement {
  font-family: var(--font-display);
  font-weight: 650;
  font-size: clamp(1.6rem, 3.4vw, 2.4rem);
  line-height: 1.2;
  max-width: 46ch;
  color: var(--c-ink);
  margin-bottom: clamp(2rem, 4vw, 3rem);
}
.perspektive-statement em { font-style: normal; color: var(--c-orange); }
.tile.is-placeholder { opacity: 0.7; }
/* Invisible twin of .tile-badge — reserves the same vertical space on a
   card that has no badge of its own, so its headline still starts on the
   same line as a neighboring card that does (see Perspektive: Instagram
   has no badge, Blog does). */
.tile-badge.is-spacer { visibility: hidden; }
.tile-badge {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: 0.65rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--c-ink-dim);
  border: 1px solid var(--c-paper-line);
  border-radius: var(--radius-pill);
  padding: 0.25rem 0.7rem;
  margin-bottom: 0.9rem;
}

/* ==========================================================================
   Kurzcheck — the triple-path CTA explicitly called out as STHETIK's
   strongest section. Three doors in (ready / undecided / just looking);
   the middle one expands a short client-side qualifying quiz in place.
   ========================================================================== */
.kurzcheck-quiz {
  margin-top: clamp(2rem, 4vw, 3rem);
  border: var(--border-w) solid var(--c-border);
  border-radius: var(--radius-md);
  padding: clamp(1.75rem, 4vw, 3rem);
}
.kurzcheck-q {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(1.15rem, 2.2vw, 1.6rem);
  margin-bottom: 1.5rem;
}
.kurzcheck-progress {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--c-ink-dim);
  margin-bottom: 0.75rem;
  display: block;
}
.kurzcheck-options {
  display: flex;
  flex-wrap: wrap;
  gap: 0.85rem;
}
.kurzcheck-options button {
  padding: 0.8rem 1.4rem;
  border: var(--border-w) solid var(--c-border);
  border-radius: var(--radius-pill);
  font-family: var(--font-mono);
  font-weight: 600;
  font-size: 0.88rem;
  color: var(--c-ink);
  transition: border-color 0.25s, background 0.25s, color 0.25s;
}
.kurzcheck-options button:hover { border-color: var(--c-orange); }
.kurzcheck-options button.is-selected { background: var(--c-brown); border-color: var(--c-brown); color: var(--c-cream); }
.kurzcheck-result-text {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(1.1rem, 2vw, 1.4rem);
  margin-bottom: 1.75rem;
  max-width: 48ch;
}
.kurzcheck-result-summary {
  font-family: var(--font-mono);
  font-size: 0.82rem;
  color: var(--c-text-dim);
  margin-bottom: 1.75rem;
  line-height: 1.7;
}

/* ==========================================================================
   Reveal utility (JS toggles .is-in)
   ========================================================================== */
.reveal { opacity: 0; transform: translateY(24px); transition: opacity 0.8s var(--ease-out), transform 0.8s var(--ease-out); }
.reveal.is-in { opacity: 1; transform: translateY(0); }
@media (prefers-reduced-motion: reduce) {
  .reveal { opacity: 1; transform: none; transition: none; }
}

/* ==========================================================================
   Projekt-Anfrage — Modal, ausgelöst über "Projekt anfragen" (Nav-CTA +
   mobiles Menü). Läuft jetzt komplett auf den Site-Design-Tokens (Cream/
   Brown/Orange, dieselben Fonts, derselbe dicke Rand wie jede andere Karte
   auf der Seite) statt eines eigenen Indigo-Akzents — die Seite dahinter
   bleibt sichtbar, aber verschwommen (backdrop-filter), statt nur flach
   eingefärbt zu werden.
   ========================================================================== */

.projekt-modal {
  position: fixed;
  inset: 0;
  z-index: 950;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: clamp(1rem, 5vw, 3rem);
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.35s var(--ease-out), visibility 0.35s;
}
.projekt-modal.is-open { opacity: 1; visibility: visible; }
/* Der Blur wird als eigener Wert animiert (0 -> 10px), nicht nur über die
   Opacity des Elternelements sichtbar gemacht — sonst rendert der Browser
   (v.a. Safari) den vollen Blur oft erst ein, zwei Frames zu spät, und es
   wirkt so, als würde der Hintergrund "kurz danach" verschwommen statt
   direkt beim Erscheinen des Formulars. will-change hält die Compositing-
   Ebene vorbereitet, statt sie erst im Klickmoment neu aufzubauen. */
.projekt-modal-backdrop {
  position: absolute;
  inset: 0;
  background: color-mix(in srgb, var(--c-header-ink) 42%, transparent);
  backdrop-filter: blur(0px) saturate(1.05);
  -webkit-backdrop-filter: blur(0px) saturate(1.05);
  transition: backdrop-filter 0.35s var(--ease-out), -webkit-backdrop-filter 0.35s var(--ease-out);
  will-change: backdrop-filter;
}
.projekt-modal.is-open .projekt-modal-backdrop {
  backdrop-filter: blur(10px) saturate(1.05);
  -webkit-backdrop-filter: blur(10px) saturate(1.05);
}
.projekt-modal-panel {
  position: relative;
  width: min(100%, 640px);
  max-height: min(90vh, 900px);
  /* overflow-y sitzt jetzt NICHT mehr direkt hier, sondern auf
     .projekt-modal-scroll darunter (siehe dort) — sonst würde der
     X-Button (der als Kind hier drin lag) beim Scrollen des Formulars
     einfach mit hochscrollen und aus dem sichtbaren Bereich verschwinden.
     Panel ist jetzt nur noch der feste Rahmen: Flex-Spalte, oben drauf
     bleibt der X-Button fix stehen, darunter scrollt der Inhalt für sich. */
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background: var(--c-paper);
  border: var(--border-w) solid var(--c-border);
  border-radius: var(--radius-lg);
  transform: translateY(18px) scale(0.98);
  transition: transform 0.4s var(--ease-out);
}
.projekt-modal.is-open .projekt-modal-panel { transform: translateY(0) scale(1); }
.projekt-modal-scroll {
  overflow-y: auto;
  min-height: 0;
  flex: 1 1 auto;
  padding: clamp(2rem, 5vw, 3.25rem);
  /* Von Lenis' globalem Touch/Wheel-Hijacking ausgenommen (die Bibliothek
     prüft genau dieses Attribut, siehe assets/vendor/lenis.min.js) — sonst
     lässt sich das Formular am Handy weder scrollen, noch reagiert der
     X-Button auf Taps, solange das Modal offen ist (lenis.stop() lässt
     Lenis sonst global preventDefault() auf jedes Touch-Event feuern). */
  -webkit-overflow-scrolling: touch;
}
.projekt-modal-close {
  position: absolute;
  top: clamp(1.1rem, 3vw, 1.75rem);
  right: clamp(1.1rem, 3vw, 1.75rem);
  z-index: 2;
  width: 40px; height: 40px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 50%;
  border: var(--border-w) solid var(--c-border);
  background: var(--c-paper);
  color: var(--c-ink);
  transition: background 0.2s, color 0.2s, border-color 0.2s;
}
.projekt-modal-close:hover { background: var(--c-orange); border-color: var(--c-orange); color: var(--c-ink); }
.projekt-modal-title {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(1.5rem, 4vw, 2.1rem);
  color: var(--c-ink);
  margin-top: 0.9rem;
  margin-bottom: clamp(1.5rem, 4vw, 2.25rem);
  max-width: 20ch;
  letter-spacing: -0.01em;
}

.projekt-form {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1.1rem 1.25rem;
}
.projekt-form-hp { position: absolute; left: -9999px; }
.projekt-field { display: flex; flex-direction: column; gap: 0.5rem; }
.projekt-field-full { grid-column: 1 / -1; }
.projekt-field span {
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--c-text-dim);
}
.projekt-field input,
.projekt-field select,
.projekt-field textarea {
  border: var(--border-w) solid var(--c-border);
  border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--c-paper) 60%, white);
  padding: 0.85rem 1rem;
  font-family: var(--font-body);
  font-size: 0.95rem;
  color: var(--c-ink);
  transition: border-color 0.2s;
}
.projekt-field textarea { resize: vertical; min-height: 6rem; }
.projekt-field input:focus,
.projekt-field select:focus,
.projekt-field textarea:focus {
  outline: none;
  border-color: var(--c-orange);
}
.projekt-field select {
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2337352b' stroke-width='2'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 1rem center;
  background-size: 1.1rem;
}
.projekt-form-submit {
  grid-column: 1 / -1;
  justify-self: start;
  margin-top: 0.5rem;
}
.projekt-form.is-hidden { display: none; }
.projekt-form-success {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(1.1rem, 2.4vw, 1.4rem);
  color: var(--c-ink);
}
@media (max-width: 640px) {
  .projekt-form { grid-template-columns: 1fr; }
}

.mobile-menu-cta {
  margin-top: 1.5rem;
  padding: 0.9rem 1.6rem;
  border-radius: var(--radius-pill);
  background: var(--c-orange);
  color: var(--c-header-ink);
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: 1rem;
  text-transform: uppercase;
  letter-spacing: 0.02em;
}

/* ==========================================================================
   Case Studies — Projekt-Karten (projekte.html) + Detailseiten
   (projekte/<slug>.html, erzeugt von tools/build-cases.js). Aufbau
   angelehnt an STHETIK's Projekt-Detailseiten: Zurück-Link, Titel +
   Leitsatz, Eckdaten, dann Bild für Bild mit kurzem Text dazwischen und am
   Ende immer die nächsten Projekte.
   ========================================================================== */

/* Karten: die Cover-Slides sind (nach dem Abschneiden der nachgebauten
   Header-Leiste) ca. 16:9 — darum hier 16:9 statt des alten
   4:5-Hochformats (sonst wäre die Hälfte vom Slide abgeschnitten),
   und keine Graustufen, weil die Farbwelt Teil des Projekts ist. */
a.work-card { color: inherit; text-decoration: none; }
.work-card--case .work-card-media { aspect-ratio: 16 / 9; }
.work-card--case .work-card-media img { filter: none; }
.work-card--case.is-soon { cursor: default; }
.work-card--case.is-soon:hover { transform: none; border-color: var(--c-border); }
.work-card--case.is-soon:hover .work-card-media img { transform: none; }
.work-card--case .link-arrow { align-self: flex-start; margin-top: auto; padding-top: 1.1rem; }
.work-card--case:hover .link-arrow svg { transform: translate(3px,-3px); }

/* ---------------- Detailseite: Hero ---------------- */
.case-hero {
  padding-top: clamp(7.5rem, 14vw, 10rem);
  padding-bottom: clamp(2.5rem, 5vw, 4rem);
}
.case-back {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: 0.78rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--c-ink);
  text-decoration: none;
  margin-bottom: clamp(2rem, 5vw, 3.5rem);
}
.case-back svg { width: 1rem; height: 1rem; transition: transform 0.25s var(--ease-out); }
.case-back:hover svg { transform: translateX(-4px); }
.case-back:hover { color: var(--c-orange); }

.case-hero-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
  gap: clamp(2rem, 5vw, 5rem);
  align-items: end;
}
.case-name {
  font-family: var(--font-serif);
  font-style: italic;
  font-weight: 600;
  font-size: clamp(1.5rem, 2.4vw, 2.1rem);
  line-height: 1.1;
  margin-bottom: 0.9rem;
}
.case-claim { max-width: 14ch; }
.case-claim em,
.case-section-head h2 em,
.case-more-head h2 em { font-style: normal; color: var(--c-orange); }
.case-hero-info .lede { max-width: 46ch; }

.case-meta {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  margin-top: clamp(1.5rem, 3vw, 2rem);
  border: var(--border-w) solid var(--c-border);
  border-radius: 20px;
  overflow: hidden;
}
.case-meta > div {
  padding: 0.9rem 1.1rem;
  border-right: var(--border-w) solid var(--c-border);
  border-bottom: var(--border-w) solid var(--c-border);
  min-width: 0;
}
.case-meta > div:nth-child(2n) { border-right: 0; }
.case-meta > div:nth-last-child(-n+2):nth-child(odd),
.case-meta > div:last-child { border-bottom: 0; }
/* Ungerade Anzahl Eckdaten (z.B. ohne Live-Link): letzte Zeile volle Breite */
.case-meta > div:last-child:nth-child(odd) { grid-column: 1 / -1; border-right: 0; }
.case-meta dt {
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: 0.66rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--c-orange);
  margin-bottom: 0.3rem;
}
.case-meta dd {
  margin: 0;
  font-family: var(--font-mono);
  font-size: 0.88rem;
  color: var(--c-ink);
  overflow-wrap: anywhere;
}
.case-meta dd a { color: inherit; text-decoration: underline; text-underline-offset: 3px; text-decoration-color: var(--c-orange); }
.case-meta dd a:hover { color: var(--c-orange); }

/* ---------------- Detailseite: Slides + Text ---------------- */
.case-figure { margin-block: 0; }
.case-figure img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--radius-md);
  border: var(--border-w) solid var(--c-border);
  background: color-mix(in srgb, var(--c-ink) 4%, var(--c-paper));
}
.case-section { padding-top: clamp(4rem, 9vw, 7.5rem); }
.case-section-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(1.5rem, 5vw, 5rem);
  align-items: end;
  margin-bottom: clamp(1.75rem, 3.5vw, 2.75rem);
}
.case-section-head .eyebrow { display: flex; margin-bottom: 1rem; }
.case-section-head h2 { max-width: 16ch; }
.case-section-text {
  color: var(--c-text-dim);
  font-size: clamp(0.95rem, 1.1vw, 1.08rem);
  line-height: 1.55;
  max-width: 52ch;
}

.case-section--slide { padding-top: clamp(3.5rem, 7vw, 6rem); }
.case-caption {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(1rem, 5vw, 5rem);
  align-items: start;
  margin-bottom: clamp(1.1rem, 2vw, 1.5rem);
}
.case-caption .eyebrow { padding-top: 0.2rem; }
.case-caption .case-section-text { font-size: clamp(0.88rem, 1vw, 0.98rem); }

/* Slides per Klick/Tap groß ansehen (Lightbox, siehe script.js
   "Case-Study-Zoom") — auf dem Handy ist der Text in den Slides sonst zu
   klein zum Lesen. */
.case-figure[data-zoom] img { cursor: zoom-in; }
.case-zoom {
  position: fixed;
  top: 0; right: 0; bottom: 0; left: 0;
  z-index: 1200;
  background: color-mix(in srgb, var(--c-ink) 97%, transparent);
  overflow: auto;
  -webkit-overflow-scrolling: touch;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: clamp(0.75rem, 3vw, 2.5rem);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.25s var(--ease-out);
  cursor: zoom-out;
}
.case-zoom.is-open { opacity: 1; pointer-events: auto; }
.case-zoom img {
  display: block;
  max-width: 100%;
  max-height: 100%;
  width: auto;
  height: auto;
  border-radius: 14px;
}
.case-zoom-close {
  position: fixed;
  top: calc(env(safe-area-inset-top, 0px) + 1rem);
  right: 1rem;
  width: 2.75rem; height: 2.75rem;
  border-radius: 50%;
  border: 0;
  background: var(--c-cream);
  color: var(--c-ink);
  display: grid;
  place-items: center;
  cursor: pointer;
}
.case-zoom-close svg { width: 1.1rem; height: 1.1rem; }
/* Handy: Slide in doppelter Bildschirmbreite zeigen, seitlich scrollbar —
   so wird der Slide-Text wirklich lesbar. */
@media (max-width: 900px) {
  .case-zoom { align-items: flex-start; justify-content: flex-start; padding: 4.5rem 0.75rem 1.5rem; }
  .case-zoom img { max-width: none; max-height: none; width: 220vw; margin: auto 0; }
}

/* ---------------- Detailseite: Weitere Projekte ---------------- */
.case-more-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 1.5rem;
  margin-bottom: clamp(2rem, 4vw, 3rem);
}
.case-more-head .eyebrow { display: flex; margin-bottom: 1rem; }

@media (max-width: 900px) {
  .case-hero { padding-top: clamp(6.5rem, 26vw, 7.5rem); }
  .case-hero-grid,
  .case-section-grid,
  .case-caption { grid-template-columns: minmax(0, 1fr); align-items: start; }
  .case-caption { gap: 0.75rem; }
  .case-figure img { border-radius: 18px; }
}
@media (max-width: 360px) {
  .case-meta { grid-template-columns: minmax(0, 1fr); }
  .case-meta > div { border-right: 0; border-bottom: var(--border-w) solid var(--c-border) !important; }
  .case-meta > div:last-child { border-bottom: 0 !important; }
}
