/* Joyful marketing site — brand tokens from input/design/design.md */

/* One variable file instead of the former static 600 + 700, so the hero can use
   the Light kicker / Regular headline the design calls for. Subset from the
   upstream Fraunces VF to the same latin range Google serves, keeping the opsz,
   wght and WONK axes and pinning SOFT to 0. WONK defaults to 0 — the landing
   opts into WONK 1 further down, matching the design file. */
@font-face {
  font-family: "Fraunces";
  src: url("../assets/fonts/fraunces-var.woff2") format("woff2");
  font-weight: 100 900;
  font-display: swap;
}
@font-face {
  font-family: "Inter";
  src: url("../assets/fonts/inter-400.woff2") format("woff2");
  font-weight: 400;
  font-display: swap;
}
@font-face {
  font-family: "Inter";
  src: url("../assets/fonts/inter-500.woff2") format("woff2");
  font-weight: 500;
  font-display: swap;
}
@font-face {
  font-family: "Inter";
  src: url("../assets/fonts/inter-600.woff2") format("woff2");
  font-weight: 600;
  font-display: swap;
}

:root {
  --beige: #f6e7c0;
  --beige-deep: #f0dca6;
  --beige-hell: #fff4d6;
  --creme: #fcf2d9;
  --rosa: #f89fc0;
  --gelb: #f5c518;
  --gelb-soft: #f7e9b0;
  --limette: #edf2ad;
  --schwarz: #131313;
  --ink-soft: #4a453b;
  --white: #fffffe;
  --gruen: #7ac54a;
  --blau: #3fa9e0;
  --dunkelblau: #2e63c9;
  --rot: #f0431e;
  --orange: #f5663c;

  --font-display: "Fraunces", Georgia, "Times New Roman", serif;
  --font-body: "Inter", "Helvetica Neue", Arial, sans-serif;

  --radius-card: 24px;
  --radius-pill: 999px;
  --maxw: 1080px;
  --shadow-card: 0 6px 24px rgba(19, 19, 19, 0.07);
}

* { box-sizing: border-box; }

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

html {
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
  overflow-x: clip;
}

body {
  margin: 0;
  background: var(--beige);
  color: var(--schwarz);
  font-family: var(--font-body);
  font-size: 17px;
  line-height: 1.6;
}

/* ---------- Seitenwechsel ----------
   Cross-document View Transitions: der Browser blendet selbst zwischen zwei
   Seiten über. Reines CSS — kein Skript, das laden, blockieren oder an der CSP
   scheitern könnte, und in Browsern ohne Unterstützung passiert schlicht das,
   was vorher passierte: ein normaler Seitenwechsel.
   Kurz gehalten (140/220 ms): ein Seitenwechsel, den man bemerkt, ist zu lang. */
@view-transition { navigation: auto; }

@keyframes page-out { to { opacity: 0; } }
@keyframes page-in { from { opacity: 0; transform: translateY(8px); } }

::view-transition-old(root) { animation: page-out 140ms ease both; }
::view-transition-new(root) { animation: page-in 220ms cubic-bezier(0.2, 0.75, 0.3, 1) both; }

@media (prefers-reduced-motion: reduce) {
  ::view-transition-old(root),
  ::view-transition-new(root) { animation: none; }
}

img, svg { display: block; max-width: 100%; }

h1, h2, h3 {
  font-family: var(--font-display);
  line-height: 1.12;
  margin: 0 0 0.5em;
  letter-spacing: -0.01em;
  text-wrap: balance;
}

h1 { font-size: clamp(2.4rem, 6.5vw, 4.2rem); font-weight: 700; }
.hero h1 { font-size: clamp(2.8rem, 6.6vw, 4.8rem); }
h2 { font-size: clamp(1.8rem, 4.5vw, 2.6rem); font-weight: 700; }
h3 { font-size: clamp(1.3rem, 3vw, 1.6rem); font-weight: 600; }

p { margin: 0 0 1em; text-wrap: pretty; }

a { color: inherit; }

.container {
  max-width: var(--maxw);
  margin: 0 auto;
  padding: 0 24px;
}

/* ---------- Header ---------- */

.site-header {
  position: sticky;
  top: 0;
  z-index: 40;
  background: rgba(244, 235, 217, 0.92);
  backdrop-filter: blur(6px);
  border-bottom: 1px solid rgba(19, 19, 19, 0.06);
}

.site-header .container {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-top: 12px;
  padding-bottom: 12px;
}

/* Landing header floats over the hero art with no plate of its own. It only
   grows a background once the pinned hero has scrolled past (JS toggles
   .is-solid), so it stays readable over the cream funding section + footer.
   Fixed rather than sticky: sticky reserves flow space, which would push the
   pinned hero stage down by the header height and clip it at the bottom. */
.hero-landing .site-header {
  position: fixed;
  left: 0;
  right: 0;
  background: none;
  backdrop-filter: none;
  border-bottom: 0;
  transition: background 0.25s ease, border-color 0.25s ease;
}

.hero-landing .site-header.is-solid {
  background: rgba(244, 235, 217, 0.92);
  backdrop-filter: blur(6px);
  border-bottom: 1px solid rgba(19, 19, 19, 0.06);
}

.logo { display: inline-flex; align-items: center; gap: 8px; text-decoration: none; }
.logo img { height: 34px; width: auto; }

.header-nav { display: flex; align-items: center; gap: 20px; font-size: 15px; font-weight: 500; }
.header-nav a { text-decoration: none; }
.header-nav a:hover { text-decoration: underline; text-underline-offset: 4px; }
.header-nav a.lang-switch:hover, .header-nav a.header-cta:hover { text-decoration: none; }

/* ---------- Mobile menu toggle ---------- */

.menu-toggle {
  display: none;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: 5px;
  width: 40px;
  height: 40px;
  padding: 0;
  border: none;
  background: transparent;
  cursor: pointer;
}

.menu-toggle-bar {
  display: block;
  width: 22px;
  height: 2.5px;
  background: var(--schwarz);
  border-radius: 2px;
  transition: transform 0.25s ease, opacity 0.2s ease;
}

.menu-toggle[aria-expanded="true"] .menu-toggle-bar:nth-child(1) { transform: translateY(7.5px) rotate(45deg); }
.menu-toggle[aria-expanded="true"] .menu-toggle-bar:nth-child(2) { opacity: 0; }
.menu-toggle[aria-expanded="true"] .menu-toggle-bar:nth-child(3) { transform: translateY(-7.5px) rotate(-45deg); }

@media (max-width: 640px) {
  .menu-toggle { display: flex; }

  nav.header-nav {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    flex-direction: column;
    align-items: stretch;
    justify-content: center;
    gap: 10px;
    background: var(--gelb);
    border-bottom: 1px solid rgba(19, 19, 19, 0.08);
    padding: 16px 24px 24px;
    box-shadow: 0 12px 20px rgba(19, 19, 19, 0.1);
    font-family: var(--font-display);
    font-weight: 600;
    font-size: 32px;
    height: 0;
    overflow: hidden;
    pointer-events: none;
    opacity: 0;
    transform: translateY(-8px);
    transition: height 0.3s ease, opacity 0.25s ease, transform 0.25s ease;
  }

  /* svh, not vh: on iOS 100vh is the height with the address bar *collapsed*, so
     the panel is taller than what is actually on screen. With the items centred
     that pushes the last one (the language switch) under the browser chrome and
     it reads as cut off. svh is the small viewport — always visible.
     The extra bottom padding clears the home indicator. */
  .header-nav.is-open {
    height: calc(100svh - var(--header-h, 90px));
    /* `safe` matters: with plain `center`, content taller than the panel is
       centred and then clipped at BOTH ends, and no amount of scrolling reaches
       the first and last item — on a short screen the top link and the language
       row simply disappeared. `safe` falls back to flex-start when it overflows. */
    justify-content: safe center;
    padding-bottom: calc(24px + env(safe-area-inset-bottom, 0px));
    overflow-y: auto;
    pointer-events: auto;
    opacity: 1;
    transform: none;
  }

  .header-nav a { padding: 14px 2px; border-bottom: 1px solid rgba(19, 19, 19, 0.12); }
  /* .lang-switch is a <button> inside .lang-picker now, so the old a.-scoped
     selectors no longer bite — target the wrapper instead. */
  .header-nav .lang-picker,
  .header-nav a.btn,
  .header-nav a.header-cta {
    align-self: flex-start;
    margin-top: 6px;
  }

  /* `.header-nav a` gives every link a 1px row divider. These are pills, not
     rows — but cancelling it with `border-bottom: none` also strips the pill's
     OWN bottom edge, and the button then reads as sliced off at the bottom.
     Restore each one's real border instead of removing it. */
  .header-nav a.header-cta { border-bottom: 2px solid var(--schwarz); }
  .header-nav a.btn { border-bottom: 2.5px solid var(--schwarz); }
  .header-nav .lang-picker .lang-switch, .header-nav a.header-cta {
    font-family: var(--font-body);
    font-weight: 600;
    padding: 8px 26px;
    font-size: 18px;
  }

  /* No floating menu inside the panel: it is positioned absolutely, and the
     panel is its own scroll container, so anything hanging below the picker got
     clipped by that overflow. In a full-screen menu there is room to just show
     both languages as a row — which also means one tap instead of two, and no
     JS needed to reach the other language here.
     The .is-open variant has to be listed too: .lang-picker.is-open .lang-menu
     sits later in the file at equal specificity and would otherwise win. */
  .header-nav .lang-picker .lang-switch { display: none; }

  .header-nav .lang-picker .lang-menu,
  .header-nav .lang-picker.is-open .lang-menu {
    display: flex;
    gap: 8px;
    position: static;
    min-width: 0;
    padding: 0;
    background: transparent;
    border: 0;
    box-shadow: none;
  }

  .header-nav .lang-menu a {
    padding: 8px 22px;
    border: 2px solid var(--schwarz);
    border-bottom: 2px solid var(--schwarz);
    border-radius: var(--radius-pill);
    font-family: var(--font-body);
    font-size: 16px;
    font-weight: 600;
  }
  /* the open menu panel is already --gelb, so the yellow CTA needs to invert */
  .header-nav a.header-cta { background: var(--white); }

  /* the bar joins the yellow panel while the menu is open, on every page — the
     landing needs it because its header is transparent, the others because
     theirs is beige, and either way the seam shows */
  .site-header:has(.header-nav.is-open) { background: var(--gelb); }
}

@media (prefers-reduced-motion: reduce) {
  .menu-toggle-bar { transition: none; }
  .header-nav { transition: none; }
}

/* ---------- Buttons ---------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  font-family: var(--font-body);
  font-size: 17px;
  font-weight: 700;
  color: var(--schwarz);
  background: var(--gelb);
  border: 2.5px solid var(--schwarz);
  border-radius: var(--radius-pill);
  padding: 15px 30px;
  min-height: 48px;
  text-decoration: none;
  cursor: pointer;
  box-shadow: 3px 4px 0 var(--schwarz);
  transform: rotate(-2deg);
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}

.btn:hover { transform: rotate(-2deg) translateY(-2px); box-shadow: 4px 6px 0 var(--schwarz); }
.btn:active { transform: rotate(-2deg) translate(2px, 3px); box-shadow: 1px 1px 0 var(--schwarz); }
.btn:focus-visible { outline: 3px solid var(--dunkelblau); outline-offset: 3px; }
.btn[disabled] { opacity: 0.55; cursor: default; transform: none; box-shadow: none; }

.btn-outline {
  background: transparent;
  border: 2.5px solid var(--schwarz);
}

/* Header nav CTA — never tilted, so it stays crisp at compact header size */
.btn-flat, .btn-flat:hover, .btn-flat:active { transform: none; }
.btn-flat:hover { box-shadow: 4px 6px 0 var(--schwarz); }
.btn-flat:active { box-shadow: 1px 1px 0 var(--schwarz); }

/* ---------- Hero ---------- */

.hero {
  position: relative;
  min-height: calc(100svh - 59px); /* full viewport minus sticky header */
  display: flex;
  align-items: center;
  padding: 48px 0 72px;
  overflow: hidden;
}

.hero .container {
  /* wider than the shared container so the bigger illustration has room */
  max-width: 1320px;
}

.hero-inner {
  position: relative;
  z-index: 2;
  display: grid;
  grid-template-columns: 1.18fr 1fr;
  gap: 40px;
  align-items: center;
  width: 100%;
}

.hero-copy { text-align: left; }

.hero-copy h1 { max-width: 12em; }

.hero .sub {
  font-size: clamp(1.1rem, 2.6vw, 1.4rem);
  color: var(--ink-soft);
  max-width: 26em;
  margin: 0 0 30px;
}

.deal-note {
  margin-top: 14px;
  font-size: 15px;
  font-weight: 500;
  color: var(--ink-soft);
}

.deal-pill {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 4px 8px;
  background: var(--gelb-soft);
  border: 1.5px solid var(--schwarz);
  border-radius: var(--radius-pill);
  padding: 8px 18px;
  font-size: 14px;
  font-weight: 500;
  color: var(--schwarz);
  box-shadow: 0 3px 10px rgba(19, 19, 19, 0.08);
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.deal-pill:hover { transform: translateY(-1px); box-shadow: 0 5px 16px rgba(19, 19, 19, 0.14); }
.deal-pill strong { color: var(--rot); }

/* right-hand illustration: mascot on a soft blob with sticky notes.
   Sized directly off viewport width (not the grid column) so it scales
   proportionally with the screen, per the reference layout. */
.hero-visual {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: clamp(380px, 46vw, 600px);
}

.hero-blob {
  position: absolute;
  width: clamp(430px, 48vw, 650px);
  aspect-ratio: 1 / 0.86;
  background: var(--gelb-soft);
  border-radius: 48% 52% 55% 45% / 52% 48% 52% 48%;
  transform: rotate(-6deg);
}

.hero .mascot {
  position: relative;
  width: clamp(255px, 34vw, 400px);
  animation: bob 3.4s ease-in-out infinite;
}

@keyframes bob {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-8px); }
}

.hero-note {
  position: absolute;
  background: var(--white);
  border-radius: 14px;
  box-shadow: 0 4px 14px rgba(19, 19, 19, 0.12);
  padding: 12px 16px;
  font-size: 13.5px;
  font-weight: 500;
  line-height: 1.45;
  max-width: 168px;
  color: var(--ink-soft);
}

.hero-note .note-star { color: var(--rot); }

.note-1 { top: 6%; left: -2%; transform: rotate(-5deg); }
.note-2 { bottom: 8%; right: -2%; transform: rotate(4deg); }

.scroll-hint {
  position: absolute;
  bottom: 22px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 3;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 46px;
  height: 46px;
  border-radius: 50%;
  border: 2px solid var(--schwarz);
  background: var(--white);
  text-decoration: none;
  font-size: 20px;
  animation: nudge 2.2s ease-in-out infinite;
}

@keyframes nudge {
  0%, 100% { transform: translate(-50%, 0); }
  50% { transform: translate(-50%, 6px); }
}

/* scattered sticker shapes */
.sticker {
  position: absolute;
  pointer-events: none;
  z-index: 1;
}

/* ---------- Section scaffolding ---------- */

section { padding: 84px 0; scroll-margin-top: 59px; }

/* full-viewport storytelling sections, content vertically centered */
.story,
.waitlist,
.survey {
  min-height: 100svh;
  display: flex;
  align-items: center;
}

.story .container,
.waitlist .container,
.survey .container { width: 100%; }

/* Reads as the line above the headline, not as a badge stuck on it — no pill,
   no tilt, sentence case. */
.section-kicker {
  display: block;
  font-family: var(--font-body);
  font-size: clamp(15px, 1.9vw, 18px);
  font-weight: 600;
  letter-spacing: 0.01em;
  color: var(--ink-soft);
  margin-bottom: 10px;
}

/* ---------- Features (sticky phone) ---------- */

.features { background: var(--beige-deep); }

.features-grid {
  display: grid;
  grid-template-columns: minmax(280px, 400px) 1fr;
  gap: 64px;
  align-items: start;
}

/* Explicit column assignment: once .phone-sticky becomes position:fixed (JS
   pin), it's taken out of grid flow entirely, and auto-placement would
   otherwise shove .usp-list into column 1 (where the phone used to sit),
   causing a full overlap. Pinning both to their tracks keeps this stable. */
.phone-sticky { grid-column: 1; }
.usp-list { grid-column: 2; }

.phone-sticky {
  position: sticky;
  /* base fallback for no-JS: at least sticks for part of the scroll.
     JS (main.js) upgrades this to a true fixed pin via .pin-fixed. */
  top: 59px;
  height: calc(100svh - 59px);
  display: flex;
  align-items: center;
  justify-content: center;
}

.phone-sticky.pin-fixed {
  position: fixed;
  top: 50%;
  height: auto;
  transform: translateY(-50%);
  z-index: 5;
}

/* big oval backdrop behind the phone mockup (from the wireframe sketch) */
.phone-sticky::before {
  content: "";
  position: absolute;
  width: min(150%, 560px);
  aspect-ratio: 1 / 0.72;
  background: var(--white);
  border-radius: 50%;
  transform: rotate(-8deg);
  z-index: 0;
}

.phone-sticky::after {
  content: "";
  position: absolute;
  width: min(120%, 440px);
  aspect-ratio: 1 / 0.7;
  border: 3px solid var(--rosa);
  border-radius: 50%;
  transform: rotate(6deg);
  z-index: 0;
}

/* iPhone 15 style frame: titanium-ish edge, side buttons, Dynamic Island */
.phone-frame {
  position: relative;
  z-index: 1;
  width: min(300px, 74vw);
  aspect-ratio: 390 / 844;
  background: linear-gradient(155deg, #2c2c2e 0%, #121214 45%, #050506 100%);
  border-radius: clamp(46px, 13vw, 58px);
  padding: 14px;
  box-shadow:
    0 30px 70px rgba(19, 19, 19, 0.28),
    inset 0 0 0 2px rgba(255, 255, 255, 0.07);
}

.phone-btn {
  position: absolute;
  background: #050506;
}

.phone-btn--mute   { left: -3px; top: 16%; width: 3px; height: 22px; border-radius: 2px 0 0 2px; }
.phone-btn--vol-up   { left: -3px; top: 22.5%; width: 3px; height: 42px; border-radius: 2px 0 0 2px; }
.phone-btn--vol-down { left: -3px; top: 31.5%; width: 3px; height: 42px; border-radius: 2px 0 0 2px; }
.phone-btn--power    { right: -3px; top: 25%; width: 3px; height: 68px; border-radius: 0 2px 2px 0; }

.phone-screen {
  position: relative;
  width: 100%;
  height: 100%;
  border-radius: clamp(34px, 10.5vw, 46px);
  overflow: hidden;
  background: var(--beige);
}

.dynamic-island {
  position: absolute;
  top: 3.4%;
  left: 50%;
  transform: translateX(-50%);
  width: 28%;
  max-width: 92px;
  height: 3.1%;
  min-height: 22px;
  background: #050506;
  border-radius: 999px;
  z-index: 4;
}

.home-indicator {
  position: absolute;
  bottom: 1.4%;
  left: 50%;
  transform: translateX(-50%);
  width: 34%;
  height: 4px;
  background: rgba(19, 19, 19, 0.4);
  border-radius: 4px;
  z-index: 4;
}

.phone-screen img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top;
  opacity: 0;
  transition: opacity 0.45s ease;
}

.phone-screen img.active { opacity: 1; }

/* generous spacing = long scroll distance per USP, so each swap gets room to breathe */
.usp-list { display: flex; flex-direction: column; gap: 55svh; padding: 16svh 0 32svh; }

.usp {
  background: var(--white);
  border-radius: var(--radius-card);
  padding: 30px 32px;
  box-shadow: var(--shadow-card);
  opacity: 0.45;
  transform: translateY(6px);
  transition: opacity 0.35s ease, transform 0.35s ease;
}

.usp.active { opacity: 1; transform: none; }

.usp .num {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: var(--gelb);
  border: 2px solid var(--schwarz);
  font-weight: 600;
  margin-bottom: 14px;
}

.usp h3 { margin-bottom: 8px; }
.usp p { margin: 0; color: var(--ink-soft); }

/* ---------- Stories ---------- */

.story .container {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 56px;
  align-items: center;
}

.story:nth-of-type(even) .story-visual { order: 2; }

.story-visual {
  position: relative;
  background: var(--white);
  border-radius: var(--radius-card);
  padding: 28px;
  box-shadow: var(--shadow-card);
}

.story-visual .frame { position: relative; aspect-ratio: 1; }

.story-visual .frame img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  transition: opacity 0.6s ease;
}

.story-visual .frame .after { opacity: 0; }
.story.is-after .frame .after { opacity: 1; }
.story.is-after .frame .before { opacity: 0; }

.story-tag {
  position: absolute;
  top: -14px;
  left: 24px;
  background: var(--rosa);
  border: 2px solid var(--schwarz);
  border-radius: var(--radius-pill);
  padding: 5px 16px;
  font-weight: 600;
  font-size: 15px;
  transform: rotate(-3deg);
  box-shadow: 2px 3px 0 var(--schwarz);
}

.story-text .usp-line {
  display: inline-block;
  background: var(--gelb-soft);
  border-radius: 14px;
  padding: 12px 18px;
  font-weight: 600;
  margin-top: 6px;
}

.story-text p.body { color: var(--ink-soft); font-size: clamp(1rem, 2vw, 1.15rem); }

/* ---------- Waitlist ---------- */

.waitlist { background: var(--gelb); }

.waitlist .container { max-width: 640px; text-align: center; }

.waitlist .sub { color: rgba(19, 19, 19, 0.75); margin-bottom: 30px; }

.waitlist form { text-align: left; }

.field-label {
  display: block;
  font-weight: 600;
  font-size: 15px;
  margin: 18px 0 8px;
}

input[type="email"] {
  width: 100%;
  font: inherit;
  padding: 14px 18px;
  border: 2px solid var(--schwarz);
  border-radius: var(--radius-pill);
  background: var(--white);
}

input[type="email"]:focus-visible { outline: 3px solid var(--dunkelblau); outline-offset: 2px; }

.chips { display: flex; flex-wrap: wrap; gap: 10px; }

.chip {
  position: relative;
  display: inline-flex;
}

.chip input {
  position: absolute;
  opacity: 0;
  inset: 0;
  cursor: pointer;
}

.chip span {
  display: inline-block;
  padding: 10px 18px;
  border: 2px solid var(--schwarz);
  border-radius: var(--radius-pill);
  background: var(--white);
  font-weight: 500;
  font-size: 15px;
  cursor: pointer;
  transition: background 0.15s ease, transform 0.15s ease;
}

.chip input:checked + span { background: var(--rosa); transform: rotate(-1.5deg); }
.chip input:focus-visible + span { outline: 3px solid var(--dunkelblau); outline-offset: 2px; }

.waitlist .btn {
  background: var(--schwarz);
  color: var(--gelb);
  width: 100%;
  margin-top: 24px;
}

.form-note { font-size: 13.5px; color: rgba(19, 19, 19, 0.65); text-align: center; margin-top: 12px; }

.form-msg { font-weight: 600; margin-top: 14px; }
.form-msg.error { color: #a02807; }
.form-msg[hidden] { display: none; }

.form-success {
  background: var(--white);
  border-radius: var(--radius-card);
  padding: 32px;
  text-align: center;
  font-size: 1.15rem;
  font-weight: 500;
}

/* ---------- Survey ---------- */

.survey .container { max-width: 640px; }

.survey-card {
  background: var(--white);
  border-radius: var(--radius-card);
  padding: 36px;
  box-shadow: var(--shadow-card);
}

.survey output {
  font-family: var(--font-display);
  font-size: 1.5rem;
  font-weight: 700;
  display: inline-block;
  min-width: 3.2em;
}

input[type="range"] { width: 100%; accent-color: var(--schwarz); min-height: 32px; }

/* ---------- Footer ---------- */

.site-footer {
  background: var(--schwarz);
  color: var(--beige);
  padding: clamp(64px, 9vh, 96px) 0 clamp(48px, 6vh, 64px);
  text-align: center;
}

.site-footer .mission {
  font-family: var(--font-display);
  font-size: clamp(1.3rem, 3vw, 1.8rem);
  font-weight: 600;
  max-width: 22em;
  margin: 0 auto 24px;
}

.site-footer .legal { font-size: 14px; opacity: 0.75; }
.site-footer .legal a { color: inherit; }
.site-footer .disclaimer { font-size: 13px; opacity: 0.6; max-width: 40em; margin: 14px auto 0; }

/* ---------- Partner page ---------- */

.partner-hero {
  min-height: 100svh;
  display: flex;
  align-items: center;
  padding: 72px 0 56px;
}
.partner-hero .sub { font-size: 1.2rem; color: var(--ink-soft); max-width: 38em; }

.cards-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; margin-top: 28px; }

.card {
  background: var(--white);
  border-radius: var(--radius-card);
  padding: 28px;
  box-shadow: var(--shadow-card);
}

.card .card-kicker { font-weight: 600; color: var(--dunkelblau); font-size: 14px; text-transform: uppercase; letter-spacing: 0.06em; }

.mechanism-steps {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 16px;
  margin: 32px 0;
}

.mechanism-steps .step {
  background: var(--white);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-card);
  padding: 24px 22px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 14px;
}

.step-num {
  display: flex;
  flex: none;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: var(--gelb);
  border: 2px solid var(--schwarz);
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 16px;
}

.step-label {
  margin: 0;
  font-weight: 600;
  font-size: 16px;
  line-height: 1.4;
  color: var(--schwarz);
}

.compare-table { width: 100%; border-collapse: collapse; background: var(--white); border-radius: var(--radius-card); overflow: hidden; box-shadow: var(--shadow-card); }
.compare-table th, .compare-table td { text-align: left; padding: 16px 20px; border-bottom: 1px solid rgba(19,19,19,0.08); font-size: 15.5px; }
.compare-table thead th { background: var(--schwarz); color: var(--beige); font-weight: 600; }
.compare-table tr.highlight { background: var(--gelb-soft); font-weight: 600; }
.compare-table tr:last-child td { border-bottom: none; }
.table-scroll { overflow-x: auto; border-radius: var(--radius-card); }

.partner-cta { background: var(--gelb); text-align: center; }
.partner-cta .container { max-width: 640px; }
.partner-cta .fallback { font-size: 14.5px; margin-top: 14px; color: rgba(19,19,19,0.7); }

/* ---------- Landing header pills ---------- */

/* Pill pair in the header. Identical box metrics on both so the yellow CTA and
   the language switch line up to the exact same height. */
.lang-switch, .header-cta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  font-family: var(--font-body);
  font-size: 15px;
  font-weight: 600;
  line-height: 24px;
  padding: 5px 12px;
  border: 2px solid var(--schwarz);
  border-radius: var(--radius-pill);
  text-decoration: none !important;
  white-space: nowrap;
}

.header-cta { background: var(--gelb); }
.header-cta:hover { background: #ffd542; }

.lang-switch .chevron { flex: none; width: 9px; height: 12px; }

/* ---------- Language picker ----------
   The button carries the language you are ON; the menu offers the others. As a
   <button> it needs the background reset explicitly — a bare .lang-switch never
   declared one, and the UA default (ButtonFace) would show through. */
.lang-picker { position: relative; display: inline-flex; }

.lang-picker .lang-switch {
  background: transparent;
  cursor: pointer;
}

.lang-picker .chevron { transition: transform 0.18s ease; }
.lang-picker.is-open .chevron { transform: rotate(180deg); }

.lang-menu {
  display: none;
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  z-index: 50;
  min-width: 150px;
  margin: 0;
  padding: 6px;
  list-style: none;
  background: var(--white);
  border: 2px solid var(--schwarz);
  border-radius: 16px;
  box-shadow: 3px 4px 0 var(--schwarz);
}

.lang-picker.is-open .lang-menu { display: block; }

.lang-menu a {
  display: block;
  padding: 9px 12px;
  border-radius: 10px;
  font-size: 15px;
  font-weight: 500;
  text-decoration: none;
  white-space: nowrap;
}

.lang-menu a:hover { background: var(--beige-hell); text-decoration: none; }
.lang-menu a:focus-visible { outline: 3px solid var(--dunkelblau); outline-offset: -2px; }
.lang-menu a[aria-current="true"] { font-weight: 700; background: var(--gelb-soft); }

@media (prefers-reduced-motion: reduce) {
  .lang-picker .chevron { transition: none; }
}

/* ---------- Pinned landing hero (two scroll beats) ----------
   .hero-pin is a tall scroll track; .hero-stage sticks to the viewport for its
   whole length. Beat 1 = Joy + "emotionale Selbstkompetenz?", beat 2 = Sara the
   sunflower blooming + "gesunde Gewohnheiten?".

   The bloom is scrubbed: js/hero.js turns the reader's position in the track
   into the sprite frame, so the track has to be long enough for 21 frames to
   have room. Hence 300svh — and the last third is the flower standing still
   while the second line types itself. */

.hero-pin {
  position: relative;
  /* vh first as the fallback: an engine without svh drops the declaration
     entirely, leaving the track at auto — shorter than the viewport, which the
     scroll maths then reads as "the hero is already behind us". */
  height: 300vh;
  height: 300svh;
}

.hero-stage {
  position: sticky;
  top: 0;
  height: 100vh;
  height: 100svh;
  display: flex;
  flex-direction: column;
  align-items: center;
  /* centred, so any height the art zone declines to take is shared top and
     bottom instead of pooling under the headline */
  justify-content: center;
  text-align: center;
  padding: calc(var(--header-h, 74px) + 2.4vh) 24px 4vh;
  overflow: hidden;
}

/* ---------- Hero paint gate ----------
   Covers the stage until js/hero.js decides the hero is ready to be looked at.
   Only under .js: without JS there is nobody to take it away again, so it must
   not exist at all there. The fixed header sits above it (z-index 40), so the
   logo stays visible and the wait reads as part of the page rather than a
   blank screen. */

.hero-loader { display: none; }

.js .hero-loader {
  display: flex;
  position: absolute;
  inset: 0;
  z-index: 3;
  align-items: center;
  justify-content: center;
  gap: 12px;
  background: var(--beige);
}

/* visibility on a delay, not display: display would kill the fade out */
.hero-stage.is-loaded .hero-loader {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 0.4s ease, visibility 0s linear 0.4s;
}

.hero-loader-dot {
  width: 13px;
  height: 13px;
  border-radius: 50%;
  border: 2px solid var(--schwarz);
  background: var(--gelb);
  animation: hero-loader-bounce 1.1s ease-in-out infinite;
}

.hero-loader-dot:nth-child(2) { background: var(--rosa); animation-delay: 0.16s; }
.hero-loader-dot:nth-child(3) { background: var(--limette); animation-delay: 0.32s; }

@keyframes hero-loader-bounce {
  0%, 72%, 100% { transform: none; opacity: 0.5; }
  36% { transform: translateY(-11px); opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .hero-loader-dot { animation: none; opacity: 1; }
  .hero-stage.is-loaded .hero-loader { transition: none; }
}

/* Opening states are opacity:0, so they may only apply where JS can undo them.
   Sara is the exception: she belongs to beat 2 only and must stay hidden without
   JS too, or the bare <video> box would paint on top of Joy. */
.js .hero-kicker,
.js .hero-orb,
.js .hero-figure--joy { opacity: 0; }

.hero-figure--sara { opacity: 0; }

/* The design file sets every Fraunces run on this page to "SOFT" 0, "WONK" 1;
   SOFT is already pinned to 0 in the subset, so only WONK has to be asked for.
   Scoped to the landing — partner/legal pages predate the design system and
   still render with the default (WONK 0) letterforms. */
.hero-landing h1,
.hero-landing h2,
.hero-landing .hero-kicker,
.hero-landing .site-footer .mission { font-variation-settings: "WONK" 1; }

.hero-kicker {
  font-family: var(--font-display);
  font-weight: 300;
  font-size: clamp(1.9rem, 4.45vw, 4rem);
  line-height: 1.18;
  letter-spacing: -0.01em;
  margin: 0;
  transform: translateY(12px);
  transition: opacity 0.7s ease, transform 0.7s ease;
}

/* Opening stagger: kicker first, then the orb, then Joy. hero.js waits out the
   whole run before it starts typing the headline. */
.hero-stage.is-ready .hero-kicker { opacity: 1; transform: none; transition-delay: 0.15s; }

/* Art zone takes whatever height is left between kicker and headline, and the
   figures are sized OFF that height (not off vw) so they can never grow into the
   text the way a viewport-width scale does on wide-but-short windows.
   flex-basis 0: the images must not contribute their intrinsic height back into
   the flex sizing, or the zone would resolve to the full 700px asset. */
.hero-art {
  flex: 1 1 0;
  min-height: clamp(150px, 20vh, 360px);
  /* deliberately uncapped: capping it on narrow screens (where the square
     figures are width-bound anyway) parks the leftover height *under* the
     headline and tears it away from the CTA that follows. Extra height here is
     just transparent air around a centred figure — harmless. */
  width: 100%;
  display: grid;
  /* an explicit single track, not the implicit auto one: a percentage height on
     a grid item only resolves against a definite row */
  grid-template: minmax(0, 1fr) / minmax(0, 1fr);
  place-items: center;
  /* so .hero-orb can size itself off this zone's *both* axes (see below) */
  container-type: size;
}

/* 54%, so the figures sit to the orb roughly as 1.8:1 like the design — a bigger
   circle reads as the subject and makes the artwork look small next to it. */
/* The figures render at min(96% of zone height, 100% of zone width). The orb has
   to follow the same two bounds at ~0.56 of that, or on a narrow window it keeps
   growing off the zone height while the artwork is already width-bound and ends
   up bigger than the flower it sits behind. Percentages can't express this — a
   height % and a width % resolve against different axes, and mixing them with
   aspect-ratio yields an ellipse — so both axes come from container units. */
.hero-orb {
  grid-area: 1 / 1;
  /* fallback for engines without container query units */
  width: min(30vh, 42vw);
  height: min(30vh, 42vw);
  width: min(54cqh, 56cqw);
  height: min(54cqh, 56cqw);
  border-radius: 50%;
  background: var(--limette);
  transform: scale(0.84);
  transition: opacity 0.8s ease, transform 0.9s cubic-bezier(0.2, 0.75, 0.3, 1);
}

.hero-stage.is-ready .hero-orb { opacity: 1; transform: none; transition-delay: 0.55s; }

/* Stacked in the same grid cell, square, bound by the same two axes as the orb.
   Container units rather than height:% + max-width, so a <div> (the sprite) and
   an <img> end up the exact same size — percentages would resolve the two axes
   against different bases and give each element a different box. */
.hero-figure {
  grid-area: 1 / 1;
  /* fallback for engines without container query units */
  width: min(52vh, 76vw);
  height: min(52vh, 76vw);
  width: min(96cqh, 100cqw);
  height: min(96cqh, 100cqw);
  object-fit: contain;
  transition: opacity 0.55s ease;
}

.hero-figure--joy { animation: bob 3.4s ease-in-out infinite; }

/* Sara's bloom, as a 7x3 sprite sheet of 21 frames. A video would be smaller,
   but VP9-with-alpha is not decoded by Safari/iOS and HEVC-with-alpha can only
   be encoded on macOS — stepping a background-position runs everywhere.

   The step itself is no longer a CSS animation: js/hero.js writes
   background-position from the scroll position, so the bloom opens and closes
   with the reader instead of playing on a timer once a threshold is crossed. */
@media (prefers-reduced-motion: no-preference) {
  .hero-sara-anim { background-image: url("../assets/sara-sprite.webp"); }
}

.hero-sara-anim {
  background-repeat: no-repeat;
  background-size: 700% 300%;
  background-position: 0% 0%;
  /* own compositing layer, so stepping the big sheet does not repaint siblings */
  transform: translateZ(0);
}

.hero-stage.is-ready .hero-figure--joy { opacity: 1; transition-delay: 0.75s; }
.hero-stage.is-phase-2 .hero-figure--joy { opacity: 0; transition-delay: 0s; }
.hero-stage.is-phase-2 .hero-sara-anim { opacity: 1; }

/* The crisp full-size bloom rides on top of the sprite's last cell. It is in the
   layout from the start (so it is decoded long before it is needed) and is
   revealed by opacity alone — toggling `hidden` here meant the browser had to
   decode a 760px image at the exact moment it became display:block, which is
   what made the end of the animation flash on iOS. */
.hero-stage.is-phase-2.is-bloomed .hero-sara-still { opacity: 1; }

.hero-headline {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(2rem, 6.67vw, 6rem);
  line-height: 1.02;
  letter-spacing: -0.008em;
  margin: 0;
  min-height: 1.02em;
  /* the shared h1 rule sets text-wrap: balance, which splits the long beat-1
     headline over two lines even at widths where it fits on one */
  text-wrap: wrap;
}

/* The line fades out while the artwork beside it takes its turn, then fades back
   in as the typing starts — so the words never compete with the animation. */
.hero-line {
  display: inline-block;
  transition: opacity 0.45s ease;
}

.hero-stage.is-line-hidden .hero-line { opacity: 0; }

.hero-caret {
  display: inline-block;
  width: 0.05em;
  height: 0.78em;
  margin-left: 0.04em;
  vertical-align: -0.06em;
  background: currentColor;
  animation: caret-blink 1.05s steps(1) infinite;
}

.hero-caret.is-idle { opacity: 0; animation: none; transition: opacity 0.4s ease; }

@keyframes caret-blink {
  0%, 49% { opacity: 1; }
  50%, 100% { opacity: 0; }
}

/* Own section below the pin, not a row inside the stage — it scrolls in normally
   and fades once it enters the viewport (IntersectionObserver in hero.js). */
/* A full screen of its own. As a short band right after the pinned hero it was
   ~320px tall and the scroll that released the hero blew straight past it. */
.hero-outro {
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: clamp(24px, 4vh, 46px);
  padding: clamp(72px, 12vh, 132px) 24px clamp(72px, 12vh, 132px);
  text-align: center;
}

.outro-title {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(2.2rem, 6.2vw, 5.2rem);
  line-height: 1.04;
  letter-spacing: -0.008em;
  margin: 0;
  max-width: 20em;
  text-wrap: balance;
}

/* the section's own focal CTA now, so it carries more weight than in the header */
.hero-outro .btn {
  font-size: clamp(17px, 1.5vw, 21px);
  padding: clamp(15px, 1.9vh, 20px) clamp(30px, 3.4vw, 44px);
}

/* Staggered on the same rhythm as the hero opening (0.7s, ~0.15s apart), so the
   headline lands, then the button, then the card.
   The rise sits on the :not(.is-in) state rather than being overridden once
   revealed. That is what lets the button join in: it carries its own
   rotate(-2deg) and a hover lift, and a `.hero-outro.is-in .btn { transform }`
   rule would outrank `.btn:hover` and flatten it for good. Written this way the
   rule simply stops matching when .is-in lands, and the button is its own
   again. */
.js .hero-outro > * {
  opacity: 0;
  transition: opacity 0.7s ease, transform 0.7s cubic-bezier(0.2, 0.75, 0.3, 1);
}

.js .hero-outro:not(.is-in) .outro-title,
.js .hero-outro:not(.is-in) .hero-card { transform: translateY(22px); }
.js .hero-outro:not(.is-in) .btn { transform: rotate(-2deg) translateY(22px); }

.hero-outro.is-in > * { opacity: 1; }
.hero-outro.is-in .outro-title { transition-delay: 0.1s; }
.hero-outro.is-in .btn { transition-delay: 0.4s; }
.hero-outro.is-in .hero-card { transition-delay: 0.62s; }

.hero-card {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  /* column gap and side padding are capped so brand + deal still share ONE line
     at 1440 (they need ~596px of the 620px available); the extra height comes
     from the vertical padding instead of from a wrap */
  gap: 8px clamp(18px, 2.8vw, 40px);
  width: min(680px, 100%);
  margin: 0;
  padding: clamp(16px, 2.1vw, 30px) clamp(20px, 2.1vw, 30px);
  background: var(--creme);
  border-radius: 20px;
}

.hero-card-brand { display: inline-flex; align-items: center; gap: 10px; }
.hero-card-brand img { height: clamp(28px, 3.7vw, 54px); width: auto; }

.hero-card-brand span {
  font-weight: 400;
  font-size: clamp(24px, 3.1vw, 45px);
  letter-spacing: -0.055em;
  line-height: 1;
}

.hero-card-deal { font-size: 14px; font-weight: 500; }
.hero-card-deal strong { color: var(--rot); font-weight: 700; }

/* ---------- Newsletter (Double-Opt-In) ----------
   Eigene Sektion hinter dem Förderhinweis. Sie sitzt zwischen der hellen
   Förder-Bank und dem schwarzen Footer, deshalb ein wärmerer Ton als Grund und
   darauf eine weiße Karte mit schwarzer Kante und hartem Schatten — dieselbe
   Handschrift wie .btn und .trust-badge. */

.newsletter-section {
  background: var(--gelb-soft);
  padding: clamp(64px, 10vh, 112px) 24px clamp(72px, 11vh, 120px);
}

.newsletter-card {
  width: min(760px, 100%);
  margin: 0 auto;
  background: var(--white);
  border: 2.5px solid var(--schwarz);
  border-radius: 32px;
  box-shadow: 6px 8px 0 var(--schwarz);
  padding: clamp(26px, 4.4vw, 56px);
  text-align: center;
}

.newsletter-kicker {
  margin: 0 0 10px;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--rot);
}

.newsletter-title {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(1.7rem, 3.6vw, 2.9rem);
  line-height: 1.08;
  letter-spacing: -0.008em;
  margin: 0 0 12px;
  text-wrap: balance;
}

.newsletter-lead {
  margin: 0 auto;
  max-width: 34em;
  font-size: clamp(15px, 1.2vw, 17px);
  color: var(--ink-soft);
}

.newsletter-perks {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(16px, 2.2vw, 26px);
  margin: clamp(24px, 3.4vw, 38px) 0;
  padding: 0;
  list-style: none;
  text-align: left;
}

.newsletter-perks li {
  display: grid;
  gap: 4px;
  padding: 20px 18px 18px;
  background: var(--beige-hell);
  border-radius: 18px;
}

.newsletter-perks strong { font-size: 15px; }
.newsletter-perks span {
  font-size: 13.5px;
  line-height: 1.5;
  color: var(--ink-soft);
}

.newsletter {
  width: min(560px, 100%);
  margin: 0 auto;
  text-align: left;
}

.newsletter-row { display: flex; flex-wrap: wrap; gap: 10px; }

.newsletter-input {
  flex: 1 1 220px;
  min-width: 0;
  font-family: var(--font-body);
  font-size: 16px;               /* under 16px iOS zooms the page on focus */
  color: var(--schwarz);
  background: var(--white);
  border: 2px solid var(--schwarz);
  border-radius: var(--radius-pill);
  padding: 13px 20px;
  min-height: 48px;
}

.newsletter-input::placeholder { color: rgba(19, 19, 19, 0.45); }
.newsletter-input:focus-visible { outline: 3px solid var(--dunkelblau); outline-offset: 2px; }

.newsletter-submit { flex: 0 0 auto; }

/* Honeypot. Off-screen rather than display:none — some bots skip hidden fields,
   and a screen reader never reaches it because the wrapper is aria-hidden. */
.newsletter-trap {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* Quiet fine-print look, but NOT the 0.55 alpha the removed fineprint used: this
   is the consent wording itself. At 12.5px that grey lands near 4:1 against the
   card and misses WCAG AA (4.5:1) — and de-emphasising the very text someone is
   agreeing to is the kind of thing Art. 7 Abs. 2 DSGVO and the EDPB dark-pattern
   guidance take issue with. 0.62 keeps the muted feel and stays legible. */
.newsletter-consent {
  display: flex;
  gap: 10px;
  margin-top: 14px;
  font-size: 12.5px;
  line-height: 1.5;
  color: rgba(19, 19, 19, 0.62);
  cursor: pointer;
}

.newsletter-consent input {
  flex: none;
  width: 20px;
  height: 20px;
  margin: 2px 0 0;
  accent-color: var(--schwarz);
  cursor: pointer;
}

.newsletter-consent a { color: var(--schwarz); text-decoration: underline; }

.newsletter-status {
  margin: 14px 0 0;
  font-size: 14px;
  font-weight: 500;
  text-align: center;
}

.newsletter-status.is-error { color: var(--rot); }

@media (max-width: 700px) {
  .newsletter-perks { grid-template-columns: 1fr; }
}

/* Ergebnisseite für Bestätigung/Abmeldung. Der Zustand kommt als Fragment aus
   der Edge Function, deshalb genügt :target — die Seite braucht kein JavaScript,
   und der Link aus dem E-Mail-Client funktioniert immer. */
.nl-result { max-width: 640px; padding-top: 24px; padding-bottom: 48px; }
.nl-state { display: none; }
.nl-state:target { display: block; }
.nl-result:has(.nl-state:target) .nl-fallback { display: none; }

@media (max-width: 640px) {
  .hero-pin { height: 260svh; }

  /* On a phone the figures are width-bound, so an art zone that grows to fill
     the stage only adds transparent air between the words and the flower. Cap
     it to the square the figure actually occupies — the stage centres the
     column, so the height that is left over goes above and below the whole
     group instead of between its parts. */
  .hero-art {
    flex: 0 1 auto;
    min-height: 0;
    height: min(calc(100vw - 48px), 46vh);
  }

  /* Two lines reserved either way: beat 1 wraps at this width and beat 2 does
     not, and with the art zone no longer able to absorb the difference the
     whole column would jump as the second line types itself. */
  .hero-headline { min-height: 2.04em; }

  /* Stack the field and the button deliberately — the row wraps at this width
     anyway, and a half-width button hanging on the left under a full-width field
     reads like a mistake.
     `flex: 1 1 auto` is not cosmetic: the base rule is `flex: 1 1 220px`, and
     once the direction flips to column that 220px basis applies to the HEIGHT.
     The input grew to 220px+ and the row fell apart vertically. Same trap as in
     .cookie-banner-text below. */
  .newsletter-row { flex-direction: column; }
  .newsletter-input { flex: 1 1 auto; }
  .newsletter-submit { width: 100%; }
  .hero-card { gap: 6px 16px; padding: 14px 18px; }
  .hero-card-deal { font-size: 13px; }
}

/* Landscape phones have no room to stage two beats — show the resolved state. */
@media (max-height: 480px) and (orientation: landscape) {
  .hero-pin { height: auto; }
  .hero-stage { position: static; height: auto; min-height: 100svh; }
}

@media (prefers-reduced-motion: reduce) {
  .hero-figure--joy { animation: none; }
  .hero-orb, .hero-figure, .hero-kicker, .hero-outro { transition-duration: 0.01ms; }
  .hero-caret { display: none; }
}

/* ---------- Legal pages ---------- */

.legal-page main .container { max-width: 720px; padding-top: 24px; padding-bottom: 24px; }
.legal-page h2 { margin-top: 1.6em; }

/* ---------- Reveal on scroll ---------- */

.reveal { opacity: 0; transform: translateY(18px); transition: opacity 0.6s ease, transform 0.6s ease; }
.reveal.in { opacity: 1; transform: none; }

/* ---------- Responsive ---------- */

@media (max-width: 860px) {
  section { padding: 60px 0; }

  .hero { min-height: 100svh; padding: 32px 0 80px; }
  .hero .container { max-width: none; }
  .hero-inner { grid-template-columns: 1fr; gap: 20px; }
  .hero-copy { text-align: center; }
  .hero-copy h1, .hero .sub { margin-left: auto; margin-right: auto; }
  .hero-visual { min-height: 320px; order: -1; }
  /* re-cap off screen width instead of the desktop vw clamp, so the
     enlarged illustration never overflows a narrow phone */
  .hero-blob { width: min(88vw, 430px); }
  .hero .mascot { width: min(58vw, 300px); }
  .hero-note { max-width: 140px; font-size: 12px; }

  .features-grid { grid-template-columns: 1fr; gap: 32px; }
  .phone-sticky, .usp-list { grid-column: 1; }
  .phone-sticky { position: relative; top: auto; height: auto; padding: 24px 0; }
  .phone-sticky::before { width: 112%; }
  .phone-sticky::after { width: 96%; }
  .usp-list { gap: 20px; padding: 0; }
  .usp { opacity: 1; transform: none; }

  .story, .waitlist, .survey { min-height: auto; }

  .story .container { grid-template-columns: 1fr; gap: 32px; }
  .story:nth-of-type(even) .story-visual { order: 0; }

  .mechanism-steps { grid-template-columns: 1fr 1fr; }
  .cards-2 { grid-template-columns: 1fr; }

  .header-nav { gap: 14px; font-size: 14px; }
}

@media (max-width: 480px) {
  .mechanism-steps { grid-template-columns: 1fr; }
  .hero { padding: 48px 0 64px; }
  .logo img { height: 28px; }
  /* scattered stickers add clutter at phone width — the blob + notes carry the collage */
  .hero > .sticker { display: none; }

  /* pill-shaped badge reads oddly once its text wraps to 2-3 lines — drop the flex
     layout (which puts every text fragment on its own line) for plain wrapped text
     in a rounded card, so words wrap naturally at the available width */
  .deal-pill {
    display: block;
    border-radius: 18px;
    padding: 12px 22px;
    text-align: center;
    max-width: 300px;
    margin: 0 auto;
  }

  /* the base h1/h2 clamps floor out around 38px/29px on phones (min never
     shrinks below that), wrapping headlines like the partner-hero into
     4-5 lines — give phones a lower floor that still scales with viewport */
  h1 { font-size: clamp(1.9rem, 9vw, 2.6rem); }
  h2 { font-size: clamp(1.5rem, 7vw, 2rem); }

  .section-kicker { margin-bottom: 8px; }
  .partner-hero { padding: 48px 0 40px; }

  /* same pill-wraps-badly issue as .deal-pill — plain wrapped text in a rounded card */
  .trust-badge {
    display: block;
    border-radius: 18px;
    padding: 12px 18px;
    text-align: center;
    max-width: 280px;
    margin-left: auto;
    margin-right: auto;
  }
  .trust-badge-dot { display: none; }
  .trust-badge .chevron { display: inline-block; margin-left: 4px; }
}

/* ---------- Reduced motion ---------- */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .hero .mascot { animation: none; }
  .scroll-hint { animation: none; }
  .reveal { opacity: 1; transform: none; transition: none; }
  .usp { opacity: 1; transform: none; transition: none; }
  .phone-screen img { transition: none; }
  .story-visual .frame img { transition: none; }
  /* creatures rest in their happy after-state */
  .story .frame .after { opacity: 1; }
  .story .frame .before { opacity: 0; }
  .btn, .chip span { transition: none; }
}

/* ---------- No-JS fallback ---------- */

.no-js .phone-screen img { position: static; opacity: 1; height: auto; }
.no-js .phone-frame { aspect-ratio: auto; }
.no-js .usp { opacity: 1; transform: none; }
.no-js .reveal { opacity: 1; transform: none; }
.no-js .story .frame .after { opacity: 1; }
.no-js .story .frame .before { opacity: 0; }
.no-js .js-only { display: none; }

/* ---------- Print (partner page in clinic decks) ---------- */

@media print {
  .site-header, .site-footer, .partner-cta .btn, .sticker, .cookie-banner, .cookie-modal-overlay { display: none; }
  body { background: #fff; color: #000; }
  section { padding: 18px 0; }
  .card, .survey-card, .compare-table { box-shadow: none; border: 1px solid #ccc; }
}

/* ---------- Trust badge (lightweight "backed by EXIST" signal) ---------- */
/* Text-only — the official EXIST/BMWE/EU lockup is never cropped or reused
   here, only shown whole and unaltered in .funding-section below. */

.trust-badge {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 6px 9px;
  background: var(--gelb-soft);
  border: 2px solid var(--schwarz);
  border-radius: var(--radius-pill);
  box-shadow: var(--shadow-card);
  padding: 10px 20px;
  margin-top: 18px;
  font-size: 15px;
  font-weight: 600;
  color: var(--schwarz);
  text-decoration: none;
  cursor: pointer;
  transition: transform 0.15s ease, box-shadow 0.15s ease, background 0.15s ease;
}

.trust-badge:hover {
  background: var(--gelb);
  transform: translateY(-1px);
  box-shadow: 0 6px 16px rgba(19, 19, 19, 0.15);
}

.trust-badge:focus-visible { outline: 3px solid var(--dunkelblau); outline-offset: 3px; }

.trust-badge-dot {
  flex: none;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--rot);
}

.trust-badge strong { color: var(--schwarz); }

.trust-badge .chevron { transition: transform 0.15s ease; }
.trust-badge:hover .chevron { transform: translateY(2px); }

/* ---------- Funding compliance section ---------- */
/* Each funder's mark (BMWK / EU / EXIST) sits in its own white rounded card;
   the descriptive sentence, "Gefördert durch:" label and the Bundestag line
   are real HTML text on the section's cream background around the cards. */

/* Lighter than the page beige so it reads as its own band rather than more of
   the hero — matches #fff4d6 in the design file. */
.funding-section {
  background: var(--beige-hell);
  padding: clamp(64px, 11vh, 112px) 24px clamp(56px, 9vh, 96px);
}

.funding-section .container {
  max-width: 720px;
  text-align: center;
}

.funding-section h2 { margin-bottom: 20px; }

.funding-text {
  font-size: 13.5px;
  color: var(--ink-soft);
  max-width: 46em;
  margin: 0 auto 34px;
}

.funding-label {
  font-weight: 600;
  margin-bottom: 20px;
}

.funding-cards {
  display: flex;
  gap: 16px;
  justify-content: center;
  align-items: stretch;
  flex-wrap: wrap;
  margin-bottom: 30px;
}

.funding-card {
  background: var(--white);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-card);
  padding: 18px 22px;
  display: flex;
  align-items: center;
  justify-content: center;
  height: 110px;
  flex: 0 1 200px;
}

.funding-card img {
  display: block;
  max-width: 100%;
  max-height: 100%;
  width: auto;
  height: auto;
}

.funding-bundestag {
  font-size: 12.5px;
  color: var(--ink-soft);
}

.funding-note {
  margin-top: 30px;
  font-size: 1.05rem;
  font-weight: 600;
  color: var(--dunkelblau);
  color: var(--ink-soft);
}

/* Auf dem Telefon stehen die drei Karten ohnehin untereinander — dann dürfen
   sie auch die Breite nutzen. Vorher blieben sie bei 200px stehen und wirkten
   neben der digitalHUB-Karte darunter wie Briefmarken. */
@media (max-width: 520px) {
  /* Feste Höhe für alle drei: Das exist-Zeichen ist ein flacher Schriftzug und
     würde seine Karte sonst halb so hoch machen wie die beiden anderen. */
  .funding-card {
    flex: 1 1 100%;
    height: 200px;
    padding: 22px 26px;
  }

  .funding-card img {
    width: 100%;
    height: auto;
    max-height: 100%;
  }

  /* Das EU-Zeichen ist als einziges hochkant — es füllt die Höhe statt der
     Breite, sonst würde es die Karte sprengen. */
  .funding-card img[src*="funding-eu"] {
    width: auto;
    height: 100%;
  }
}

/* ---------- Netzwerk (digitalHUB Aachen) ---------- */
/* Bewusst eine eigene Section unter dem Förderhinweis. Die Mitgliedschaft ist
   keine Förderung: Sie darf weder in der EXIST-Logoleiste stehen noch so
   aussehen, als gehöre sie dazu. Getrennt halten sie eigene Überschrift,
   Haarlinie und eine Karte statt einer Logoreihe. */

/* Gleicher Grund wie der Förderhinweis darüber — die beiden Bänder laufen
   ineinander. Getrennt hält sie die Haarlinie, nicht die Farbe. */
.network-section {
  background: var(--beige-hell);
  padding: 0 24px clamp(112px, 18vh, 192px);
}

.network-section .container {
  max-width: 720px;
  text-align: center;
  border-top: 1px solid rgba(19, 19, 19, 0.1);
  padding-top: clamp(36px, 5vh, 56px);
}

/* Gleiche Überschrift wie „Unterstützt durch": das normale h2 der Seite,
   nur der Abstand darunter kommt aus dem Förderblock. */
.network-title { margin-bottom: 20px; }

.network-card {
  display: inline-flex;
  align-items: center;
  gap: 20px;
  max-width: 560px;
  text-align: left;
  text-decoration: none;
  background: var(--white);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-card);
  padding: 18px 26px;
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}

.network-card:hover {
  transform: translateY(-2px);
  box-shadow: 0 8px 22px rgba(19, 19, 19, 0.12);
}

.network-card:focus-visible { outline: 3px solid var(--dunkelblau); outline-offset: 3px; }

/* Das Badge ist ein geschlossenes Zeichen: nur skalieren, nie beschneiden. */
.network-card img {
  flex: none;
  width: 104px;
  height: auto;
  display: block;
}

.network-body { display: flex; flex-direction: column; gap: 4px; }
.network-name { font-weight: 700; }
.network-text { font-size: 14px; color: var(--ink-soft); }
.network-link { font-size: 14px; font-weight: 600; color: var(--dunkelblau); }

.network-link .chevron { display: inline-block; transition: transform 0.15s ease; }
.network-card:hover .network-link .chevron { transform: translateX(3px); }

@media (max-width: 520px) {
  .network-card {
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 14px;
    padding: 22px;
  }
  .network-body { align-items: center; }
}

/* ---------- Cookie consent ---------- */

.cookie-banner {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 300;
  padding: 16px;
  transform: translateY(120%);
  transition: transform 0.3s ease;
}

.cookie-banner.is-visible { transform: translateY(0); }

.cookie-banner-inner {
  max-width: 760px;
  margin: 0 auto;
  background: var(--white);
  border: 2px solid var(--schwarz);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-card);
  padding: 16px 20px;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px 24px;
}

.cookie-banner-text {
  flex: 1 1 320px;
  margin: 0;
  font-size: 14px;
  line-height: 1.4;
  color: var(--ink-soft);
}

.cookie-banner-text a { text-decoration: underline; color: var(--schwarz); }

.cookie-banner-actions {
  display: flex;
  gap: 10px;
  flex-wrap: nowrap;
  flex: 1 1 auto;
}

.cookie-banner-actions .btn {
  padding: 10px 14px;
  min-height: 38px;
  font-size: 13.5px;
  flex: 1 1 0;
  white-space: nowrap;
}

.cookie-modal-overlay {
  position: fixed;
  inset: 0;
  z-index: 310;
  background: rgba(19, 19, 19, 0.45);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.2s ease;
}

.cookie-modal-overlay.is-visible { opacity: 1; pointer-events: auto; }

.cookie-modal {
  position: relative;
  width: 100%;
  max-width: 520px;
  max-height: 86vh;
  overflow-y: auto;
  background: var(--beige);
  border: 2px solid var(--schwarz);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-card);
  padding: 32px 28px 28px;
}

.cookie-modal h2 { margin-bottom: 10px; }

.cookie-modal-intro {
  font-size: 14.5px;
  color: var(--ink-soft);
  margin-bottom: 22px;
}

.cookie-option {
  background: var(--white);
  border-radius: 16px;
  padding: 16px 18px;
  margin-bottom: 14px;
}

.cookie-option-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}

.cookie-option-title { font-weight: 700; }

.cookie-option-desc {
  margin: 8px 0 0;
  font-size: 13.5px;
  color: var(--ink-soft);
}

.cookie-toggle {
  position: relative;
  display: inline-block;
  width: 44px;
  height: 26px;
  flex: 0 0 auto;
}

.cookie-toggle input {
  position: absolute;
  opacity: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  cursor: pointer;
}

.cookie-toggle-track {
  position: absolute;
  inset: 0;
  background: rgba(19, 19, 19, 0.2);
  border-radius: var(--radius-pill);
  transition: background 0.15s ease;
}

.cookie-toggle-track::before {
  content: "";
  position: absolute;
  top: 3px;
  left: 3px;
  width: 20px;
  height: 20px;
  background: var(--white);
  border-radius: 50%;
  box-shadow: 0 1px 3px rgba(19, 19, 19, 0.35);
  transition: transform 0.15s ease;
}

.cookie-toggle input:checked + .cookie-toggle-track { background: var(--gruen); }
.cookie-toggle input:checked + .cookie-toggle-track::before { transform: translateX(18px); }
.cookie-toggle input:focus-visible + .cookie-toggle-track { outline: 3px solid var(--dunkelblau); outline-offset: 2px; }
.cookie-toggle-disabled { opacity: 0.7; }
.cookie-toggle-disabled input { cursor: default; }

.cookie-modal-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 22px;
}

.cookie-modal-actions .btn {
  padding: 12px 22px;
  min-height: 40px;
  font-size: 15px;
}

.cookie-modal-close {
  position: absolute;
  top: 14px;
  right: 14px;
  width: 32px;
  height: 32px;
  border: none;
  background: transparent;
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
  color: var(--schwarz);
  border-radius: 50%;
}

.cookie-modal-close:hover { background: rgba(19, 19, 19, 0.08); }

.cookie-settings-link {
  border: none;
  background: transparent;
  color: inherit;
  font: inherit;
  text-decoration: underline;
  cursor: pointer;
  padding: 0;
}

@media (max-width: 560px) {
  .cookie-banner { padding: 10px; }
  .cookie-banner-inner { flex-direction: column; align-items: stretch; padding: 14px 16px; }
  /* flex-basis: 320px means *height* once flex-direction flips to column — reset it */
  .cookie-banner-text { flex: 1 1 auto; }
  .cookie-banner-actions { width: 100%; }
  .cookie-banner-actions .btn { padding: 10px 8px; font-size: 13px; }
}

/* ---------- Career pages ----------
   `career.html` is the overview, `career-<role>.html` one page per opening, so
   each vacancy has a URL that can be posted on its own. Shared styling: same
   handwriting as .btn / .newsletter-card — white plate, black edge, hard offset
   shadow. Deliberately NOT the full-viewport treatment .partner-hero uses — on
   a career page the openings are the reason people came, and a 100svh hero
   would push them below the fold. */

/* One full screen: copy left, Sara right. 100svh minus the header, so hero and
   header together are exactly one viewport — the sticky header here takes flow
   space, unlike the landing where it is fixed and 100svh alone is right. */
.career-hero {
  min-height: calc(100vh - var(--header-h, 74px));
  min-height: calc(100svh - var(--header-h, 74px));
  display: flex;
  align-items: center;
  padding: 40px 0 48px;
}

.career-hero .container { width: 100%; }

/* Two columns only on the overview — the role pages share .career-hero but stack
   a back link, title, fact strip and nothing else, and a grid would scramble them. */
.career-hero--split .container {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
  gap: clamp(24px, 4vw, 56px);
  align-items: center;
}

.career-hero .sub { font-size: 1.2rem; color: var(--ink-soft); max-width: 34em; }

.career-hero-art { justify-self: center; }

.career-hero-art img {
  width: min(100%, 480px);
  height: auto;
}

/* The two openings, now their own section directly under the hero. */
.career-roles { padding-bottom: clamp(64px, 9vh, 104px); }

.job-picker {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 20px;
  margin-top: 28px;
}

.job-pick {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 26px 26px 22px;
  background: var(--white);
  border: 2.5px solid var(--schwarz);
  border-radius: 26px;
  box-shadow: 5px 6px 0 var(--schwarz);
  text-decoration: none;
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}

.job-pick:hover { transform: translateY(-3px); box-shadow: 6px 9px 0 var(--schwarz); }
.job-pick:active { transform: translate(2px, 3px); box-shadow: 1px 1px 0 var(--schwarz); }
.job-pick:focus-visible { outline: 3px solid var(--dunkelblau); outline-offset: 3px; }

.job-pick-title {
  font-family: var(--font-display);
  font-size: clamp(1.35rem, 2.6vw, 1.75rem);
  font-weight: 600;
  line-height: 1.15;
}

.job-pick-mwd { font-weight: 400; opacity: 0.55; font-size: 0.7em; }
.job-pick-note { font-size: 14.5px; line-height: 1.5; color: var(--ink-soft); }

/* margin-top:auto needs a flex parent that actually has spare height — the
   cards are stretched to equal height by the grid, so this pins the link to
   the bottom edge of both regardless of how long the note above wraps. */
.job-pick-more {
  margin-top: auto;
  padding-top: 14px;
  font-size: 14px;
  font-weight: 700;
  color: var(--dunkelblau);
}

/* ---------- A single opening ---------- */

.job-role {
  margin: 0 0 6px;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--rot);
}

.job h2 { margin-bottom: 0.3em; }
.job-mwd { font-weight: 400; opacity: 0.5; font-size: 0.6em; letter-spacing: 0; }

.job-lead {
  max-width: 40em;
  font-size: 1.12rem;
  line-height: 1.55;
  color: var(--ink-soft);
}

/* Facts strip as ONE plate, not four loose pills. Four separately bordered
   chips at four different widths wrapped into a ragged second row and read as
   debris under the headline; joined into a single bordered strip with hair-line
   dividers they read as what they are — a fact sheet. Label above value, so a
   long value like "Wiesbaden oder remote (innerhalb Deutschlands)" can wrap
   inside its own cell without pushing the others around. */
.job-meta {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  /* breathing room on both sides — it is the last thing in the hero, so the
     bottom margin is what keeps it off the section edge */
  margin: clamp(30px, 4.5vh, 52px) 0;
  padding: 0;
  list-style: none;
  background: var(--white);
  border: 2.5px solid var(--schwarz);
  border-radius: 22px;
  overflow: hidden;
}

.job-meta li {
  padding: 24px 22px 26px;
  border-left: 1px solid rgba(19, 19, 19, 0.14);
  font-size: 15px;
  line-height: 1.4;
}

.job-meta li:first-child { border-left: 0; }

.job-meta b {
  display: block;
  margin-bottom: 5px;
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

.job-block { max-width: 46em; margin-top: 34px; }
.job-block h3 { margin-bottom: 0.45em; }
.job-block p { color: var(--ink-soft); }
.job-block p strong { color: var(--schwarz); }

/* The "please read this before applying" block — the one paragraph in the ad
   that costs everyone time if it is skimmed, so it gets its own plate. */
.job-block--flag {
  background: var(--white);
  border: 2.5px solid var(--schwarz);
  border-radius: 24px;
  box-shadow: 5px 6px 0 var(--schwarz);
  padding: 28px 30px 12px;
}

.job-list { margin: 0; padding: 0; list-style: none; }

.job-list li {
  position: relative;
  padding: 0 0 0 26px;
  margin-bottom: 12px;
  color: var(--ink-soft);
  line-height: 1.55;
}

.job-list li strong { color: var(--schwarz); }

/* Brand marker instead of a disc bullet. Positioned by top offset rather than
   a flex row so a wrapped line indents under the text, not under the dot.
   The offset centres the 9px dot on the first text line — half the leftover
   leading — instead of an eyeballed em value that drifts whenever the type
   size or line-height changes. */
.job-list li::before {
  content: "";
  position: absolute;
  left: 2px;
  top: calc((1.55em - 9px) / 2);
  width: 9px;
  height: 9px;
  border-radius: 50%;
  border: 1.5px solid var(--schwarz);
  background: var(--gelb);
}

/* "Nice to have" reads as optional at a glance: hollow marker, no fill. */
.job-list--soft li::before { background: transparent; }

.job-list--honest {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 20px;
  margin-top: 28px;
}

.job-list--honest li {
  margin: 0;
  padding: 24px 26px 24px 46px;
  background: var(--white);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-card);
  font-size: 15.5px;
}

/* Same centring, shifted down by the card's own top padding */
.job-list--honest li::before { left: 24px; top: calc(24px + (1.55em - 9px) / 2); }

/* ---------- What we offer ---------- */

.offer-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
  margin: 32px 0 0;
  padding: 0;
  list-style: none;
}

.offer-grid li {
  display: grid;
  gap: 4px;
  padding: 24px 22px 22px;
  background: var(--white);
  border-radius: 20px;
  box-shadow: var(--shadow-card);
}

.offer-icon { font-size: 26px; line-height: 1; margin-bottom: 12px; }
.offer-grid strong { font-size: 16px; }
.offer-grid span:not(.offer-icon) { font-size: 14px; line-height: 1.5; color: var(--ink-soft); }

/* ---------- Application ---------- */

.career-apply { background: var(--gelb); }
.career-apply .container { max-width: 780px; }

.apply-steps {
  counter-reset: step;
  margin: 28px 0 34px;
  padding: 0;
  list-style: none;
}

.apply-steps li {
  counter-increment: step;
  position: relative;
  padding: 0 0 0 52px;
  margin-bottom: 18px;
  line-height: 1.55;
  color: rgba(19, 19, 19, 0.78);
}

.apply-steps li strong { color: var(--schwarz); }

.apply-steps li::before {
  content: counter(step);
  position: absolute;
  left: 0;
  /* Centre the 34px circle on the first text line (17px x 1.55 = 26.35px) by
     lifting it half the difference. Written in px on purpose: the font-size
     below rebases em for this pseudo-element, so 1.55em would resolve against
     16px and land ~1.5px off. */
  top: -3.8px;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: var(--white);
  border: 2px solid var(--schwarz);
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 16px;
  color: var(--schwarz);
}


.apply-agg { margin-top: 34px; font-size: 15px; color: rgba(19, 19, 19, 0.78); max-width: 44em; }
.apply-privacy { margin: 0; font-size: 13.5px; color: rgba(19, 19, 19, 0.68); }

@media (max-width: 860px) {
  .job-picker { grid-template-columns: 1fr; }
  .job-meta { grid-template-columns: 1fr 1fr; }
  .job-meta li:nth-child(odd) { border-left: 0; }
  .job-meta li:nth-child(n+3) { border-top: 1px solid rgba(19, 19, 19, 0.14); }
  .offer-grid { grid-template-columns: 1fr 1fr; }
  .job-list--honest { grid-template-columns: 1fr; }

  /* Sara moves above the copy: on a phone the illustration is the hook, and
     below three paragraphs it would sit under the fold and never be seen. */
  .career-hero { padding: 24px 0 40px; }
  .career-hero--split .container { grid-template-columns: 1fr; gap: 18px; text-align: center; }
  .career-hero--split .sub { margin-left: auto; margin-right: auto; }
  .career-hero-art { order: -1; }
  .career-hero-art img { width: min(58vw, 250px); }
  .career-roles { padding-top: 8px; }
}

@media (max-width: 560px) {
  .offer-grid { grid-template-columns: 1fr; }
  .job-block--flag { padding: 22px 20px 6px; border-radius: 20px; }
  .job-meta { grid-template-columns: 1fr; }
  .job-meta li { border-left: 0; }
  .job-meta li + li { border-top: 1px solid rgba(19, 19, 19, 0.14); }
}

@media (prefers-reduced-motion: reduce) {
  .job-pick, .job-pick:hover, .job-pick:active { transition: none; transform: none; }
}

/* Back to the overview, above the role title on a single-opening page */
.role-back {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 18px;
  font-size: 14.5px;
  font-weight: 600;
  color: var(--ink-soft);
  text-decoration: none;
}

.role-back:hover { color: var(--schwarz); text-decoration: underline; text-underline-offset: 4px; }
.role-back:focus-visible { outline: 3px solid var(--dunkelblau); outline-offset: 3px; }

/* Apply button plus the address spelled out beside it. The visible mailto is
   not decoration: a mailto: button does nothing on a machine with no mail
   client configured (common on shared and work desktops), and without a
   readable address that candidate silently gives up. */
.apply-cta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 14px 20px;
  margin-top: 30px;
}

/* margin:0 is load-bearing, not tidiness: the global `p { margin: 0 0 1em }`
   would still count inside the flex row, and align-items:center centres the
   margin box — so the address would sit visibly higher than the button. */
.apply-cta-mail {
  margin: 0;
  font-size: 14.5px;
  line-height: 1.45;
  color: var(--ink-soft);
}

.apply-cta-mail a { font-weight: 600; color: var(--schwarz); }
.apply-cta-subject { display: block; }

/* On the yellow apply section the muted grey loses contrast against the fill */
.career-apply .apply-cta-mail { color: rgba(19, 19, 19, 0.78); }

/* .btn is yellow by default, and the apply section is yellow — on beige (the
   role-page hero) that is right, here it would be a yellow plate on a yellow
   ground held together by nothing but its border. */
.career-apply .apply-cta .btn { background: var(--white); }
.career-apply .apply-cta .btn-outline { background: transparent; }

/* Secondary route for people who live in LinkedIn rather than in a mail client.
   Outline rather than LinkedIn blue: the primary action is still the
   application mail, and a brand-blue plate would out-shout it. */
.btn-linkedin svg {
  width: 18px;
  height: 18px;
  flex: none;
  fill: currentColor;
}

.apply-alt {
  margin: 32px 0 0;
  font-size: 15px;
  color: rgba(19, 19, 19, 0.78);
}

.apply-alt + .apply-cta { margin-top: 18px; }

/* One button per role on the overview, each carrying its own subject line */
.apply-roles { display: grid; gap: 14px; margin-top: 26px; }
.apply-roles .apply-cta { margin: 0; }

@media (max-width: 560px) {
  .apply-cta { gap: 12px; }
  .apply-cta .btn { width: 100%; }
}

/* ---------- Hero-Auftritt auf den statischen Seiten ----------
   Dieselbe Bewegung wie im Landing-Outro, nur als Keyframe statt als
   Scroll-Trigger: diese Heros stehen über der Falzkante, ein
   IntersectionObserver würde ohnehin sofort feuern.

   fill-mode `backwards`, nicht `both`: `both` hält den Endwert nach dem Lauf
   fest, und eine abgelaufene Animation schlägt jede Transition — der
   rotate(-2deg) und der Hover-Lift der Buttons wären danach tot. `backwards`
   gilt nur während Verzögerung und Lauf und gibt das Element danach frei. */
@keyframes hero-rise {
  from { opacity: 0; transform: translateY(20px); }
}

@media (prefers-reduced-motion: no-preference) {
  .hero-stagger > *,
  .career-hero-art {
    animation: hero-rise 0.7s cubic-bezier(0.2, 0.75, 0.3, 1) backwards;
  }

  .hero-stagger > :nth-child(1) { animation-delay: 0.06s; }
  .hero-stagger > :nth-child(2) { animation-delay: 0.16s; }
  .hero-stagger > :nth-child(3) { animation-delay: 0.26s; }
  .hero-stagger > :nth-child(4) { animation-delay: 0.36s; }
  .hero-stagger > :nth-child(5) { animation-delay: 0.46s; }
  .hero-stagger > :nth-child(n+6) { animation-delay: 0.56s; }

  .career-hero-art { animation-delay: 0.2s; }
}
