/*
 * Concept 2 — Schaad Advisors · "Private banking" hero
 * Pixel-perfect from Figma node 42:430 · Artboard 1440 × 800.
 *
 *   Layout strategy:
 *   - Hero is 100vw × 100vh (min 800), dark navy bg.
 *   - Header (logo / nav / Kontakt button) anchored to TOP of viewport.
 *   - Jakob portrait + service rings + text blocks anchored to BOTTOM
 *     of viewport. The bottom of the body paragraph (left) and the
 *     bottom of the claim/loc row (right) align on the same baseline.
 *   - --gutter horizontally centres a 1440-wide stage on viewport.
 *   - All button heights = 40px (header Kontakt and bottom CTAs).
 */

:root {
  --gutter: max(0px, calc((100vw - 1440px) / 2));
  /* `--rail-pad` is the global side-padding token defined in
     shared/tokens.css. Stepped breakpoints (80 / 32 / 20) keep header
     chrome and content edges aligned at every viewport. Don't redefine
     here — read the global token. */

  --bg-deep:   #072634;            /* Figma rgb(7,38,52) */
  --blue:      #116490;            /* brand */
  --blue-dark: #0d4f72;
  --white:     #ffffff;

  --font: 'Inter', ui-sans-serif, system-ui, -apple-system, sans-serif;
}

/* ─── Reset ─────────────────────────────────────────────────── */

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html, body { margin: 0; padding: 0; }
html { font-family: var(--font); -webkit-font-smoothing: antialiased;  overflow-x: clip; }
body {
  background: var(--bg-deep);
  color: var(--white);
  overflow-x: clip;
}
a   { text-decoration: none; color: inherit; }
ul  { list-style: none; }
img { display: block; max-width: 100%; }

/* ─── Entrance animation ─────────────────────────────────────
   fill-mode: backwards  → element starts at "from" state BEFORE
   animation begins (during delay), so it's already hidden.
   fill-mode does NOT lock the final state, so CSS transitions
   (e.g. nav hover opacity) work normally once animation ends.   */

@keyframes hero-rise {
  from { opacity: 0; transform: translateY(16px); }
  to   { opacity: 1; transform: none; }
}

/* Fade-only — for elements that have JS-set transform (indicator) */
@keyframes hero-fade {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* Ring continuous slow-spin + counter-spin to keep + upright */
@keyframes ring-spin {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}
@keyframes plus-stay {
  from { transform: translate(-50%, -50%) rotate(0deg); }
  to   { transform: translate(-50%, -50%) rotate(-360deg); }
}

/* Shared shorthand: duration ease delay fill-mode.
   Header chrome (logo, nav links, indicator, Kontakt button) stays
   static on every page load — only page content reveals. */
.hero__portrait { animation: hero-rise 1.1s cubic-bezier(0.23,1,0.32,1) 0.40s backwards; }
.hero__name     { animation: hero-rise 0.9s cubic-bezier(0.23,1,0.32,1) 0.55s backwards; }
.hero__body     { animation: hero-rise 0.9s cubic-bezier(0.23,1,0.32,1) 0.55s backwards; }
.hero__signature{ animation: hero-rise 0.9s cubic-bezier(0.23,1,0.32,1) 0.55s backwards; }
.hero__claim    { animation: hero-rise 0.9s cubic-bezier(0.23,1,0.32,1) 0.55s backwards; }
.hero__loc      { animation: hero-rise 0.9s cubic-bezier(0.23,1,0.32,1) 0.55s backwards; }
.hero__ctas     { animation: hero-rise 0.9s cubic-bezier(0.23,1,0.32,1) 0.75s backwards; }

/* Service rings — staggered */
.hero__service:nth-child(1) { animation: hero-rise 0.9s cubic-bezier(0.23,1,0.32,1) 0.80s backwards; }
.hero__service:nth-child(2) { animation: hero-rise 0.9s cubic-bezier(0.23,1,0.32,1) 0.87s backwards; }
.hero__service:nth-child(3) { animation: hero-rise 0.9s cubic-bezier(0.23,1,0.32,1) 0.94s backwards; }
.hero__service:nth-child(4) { animation: hero-rise 0.9s cubic-bezier(0.23,1,0.32,1) 1.01s backwards; }

/* ─── Hero stage ────────────────────────────────────────────── */

.hero {
  position: relative;
  width: 100vw;
  /* Compact hero — 720. Logo (full size), text and portrait fit
     without overlap; rings bleed deeper into the white Leistungen. */
  height: 720px;
  background: var(--bg-deep);              /* base; .bg-studio adds halo + grain */
  overflow: visible;                       /* rings bleed onto next section */
  z-index: 5;                              /* keep rings painted above Leistungen */
  color: var(--white);
}

/* ════════════════════════════════════════════════════════════════
 * STUDIO BACKDROP — shared utility for every dark section.
 * Generative replacement for photographic backgrounds: a soft atlas-blue
 * radial halo (the "spotlight") + an SVG turbulence noise layer in
 * `mix-blend-mode: overlay`. Same noise pattern at the same density on
 * every dark surface, regardless of section size — no rasterisation
 * scaling means identical grain everywhere.
 * Apply via `class="hero bg-studio"` / `class="cta bg-studio"`, etc.
 * ─────────────────────────────────────────────────────────────── */

.bg-studio {
  position: relative;
  isolation: isolate;
  background:
    radial-gradient(ellipse 70% 60% at 50% 35%,
      rgba(17, 100, 144, 0.22) 0%,
      transparent 65%),
    var(--color-bg-deep);
}

.bg-studio::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;                              /* sits below content but above bg */
  pointer-events: none;
  /* True film grain: feTurbulence outputs natural gray noise; feComponent-
     Transfer pushes contrast around mid-gray (0.5 → 0.5 stays, edges go
     to black/white). `mix-blend-mode: overlay` then darkens dark pixels
     and brightens light ones — average brightness of the bg is preserved,
     no whitewash. */
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 240 240'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/><feComponentTransfer><feFuncR type='linear' slope='3' intercept='-1'/><feFuncG type='linear' slope='3' intercept='-1'/><feFuncB type='linear' slope='3' intercept='-1'/></feComponentTransfer></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>");
  background-size: 240px 240px;
  background-repeat: repeat;
  mix-blend-mode: overlay;
  opacity: 0.85;
}

/* Header chrome (logo · nav · Kontakt) lives in shared/site-header.css.
   Home uses the `.c-site-header--display` modifier for the full-size
   logo (clamps from 80h on mobile to 205h on ≥1440). */

/* ─── Jakob portrait · BOTTOM anchor · cut-out fills lower zone ───
      Figma 568 / 88 / 537.5 / 713  — bottom of image at y=801
      (essentially flush with hero bottom 800).                      */

/* Portrait — right-anchored, sits 12px left of the right text-block.
   Width clamps fluidly so Jakob slides toward the right rail as the
   viewport narrows; the right block follows him at a fixed 12px gap.
   Original Figma values (468w / 620h) are the upper clamp. */
/* Jakob: full Figma size (468 × 620), RIGHT-anchored at a fixed 12 px
   gap from the right text-block. Both slide together as the viewport
   narrows — one continuous, smooth motion across the entire desktop
   range. No clamp stops, no jerks. At 1440 Jakob lands exactly on the
   Figma 568 left coordinate (rail-pad 80 + right-block 312 + gap 12 +
   Jakob's own 468 = 872, so 1440 − 872 = 568). At 1070 (just before
   the tablet break) Jakob is at ~243, fully cleared the right block
   from his body. */
.hero__portrait {
  position: absolute;
  left: auto;
  right: calc(var(--rail-pad) + 312px + 12px);
  bottom: 0;
  width: 468px;
  height: 620px;
  z-index: 3;                     /* sits BEHIND service rings */
  pointer-events: none;
}
.hero__portrait img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  object-position: center bottom;
}

/* ─── Left text block · BOTTOM anchor ────────────────────────
      Figma:
        H1     y=299, h=56  → bottom-from-artboard = 800-355 = 445
        body   y=379, h=84  → bottom-from-artboard = 800-463 = 337
        CTAs   y=503, h=40  → bottom-from-artboard = 800-543 = 257
      So if we anchor the WHOLE block at bottom: 257 (CTAs flush bottom)
      and stack contents column-up from there, body bottom lands at 337,
      H1 bottom at 445. Internal margins give the Figma gaps.            */

.hero__lead {
  position: absolute;
  left:  var(--rail-pad);   /* aligns with logo + every section */
  /* Lifted +20 from Figma 220 → 240 so H1, body, buttons sit a touch
     higher and the rings strip has a bit more breathing room. Logo
     (≤180h) clears with ~36 px gap to the H1. */
  bottom: 240px;
  width: 436px;             /* Figma fixed — Jakob is no longer breathing into us */
  z-index: 7;               /* above service rings (z=6) */
}

.hero__name {
  /* Fluid H1: 56 at 1440 → 40 at 1070 (the tablet break). Single
     continuous clamp — no stops anywhere in the desktop range.
     Slope ≈ 0.0432 px/vw px (= 4.32vw − 6.2px). */
  font-size:      clamp(40px, calc(4.32vw - 6.2px), 56px);
  line-height:    1;
  font-weight:    400;
  letter-spacing: -0.005em;
  color: var(--white);
  white-space: nowrap;          /* one line at desktop; mobile reflow allows wrap */
  margin-bottom: 24px;          /* gap H1→body : 379-(299+56)=24 */
}

.hero__body {
  width: 338px;
  font-size:      16px;
  line-height:    21px;
  font-weight:    400;
  letter-spacing: 0;
  color: var(--white);
  margin-bottom: 40px;          /* gap body→CTAs : 503-(379+84)=40 */
}

/* ─── CTA button row · h=40 · gap=8 (Figma: 282-(80+194)=8) ── */

.hero__ctas { display: flex; gap: 8px; }

.hero__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 40px;
  font-size:      14px;
  line-height:    14px;
  font-weight:    400;
  letter-spacing: 0;
  text-transform: uppercase;
  white-space: nowrap;
  border-radius: 3px;
  text-decoration: none;
  transition: background 200ms ease, color 200ms ease, border-color 200ms ease;
}

/* Primary — filled blue, same as header Kontakt */
.hero__btn--primary {
  width: 194px;
  background: var(--blue);
  color: var(--white);
  border: 1px solid transparent;
}
.hero__btn--primary:hover { background: var(--blue-dark); }

/* Ghost — plain text-link, no border. Hover slightly dims, mirroring
   the nav-link affordance. Width sized to content (no fixed 114) so
   the button reads as text, not a button. */
.hero__btn--ghost {
  width: auto;
  padding: 0 12px;
  background: transparent;
  color: var(--white);
  border: 0;
  transition: color 200ms ease;
}
.hero__btn--ghost:hover {
  color: var(--color-alpine);
  background: transparent;
}

/* ─── Right text block · BOTTOM anchor (same baseline as body) ───
      Figma:
        Signature  y=318, h=58 → bottom = 376
        Claim/Loc  y=400, h=63 → bottom = 463 (= body bottom)
      Anchor block bottom at 337px (same as body bottom-from-artboard).
      Inside, claim/loc sit at the bottom; signature stacks above with a
      24px margin (400-(318+58)=24).                                      */

/* Right text-block — anchored to the right rail. Drifts together with
   the portrait as the viewport narrows; both share the same right edge.
   Lifted +20 from Figma 319 → 339 so signature.top stays aligned with
   the H1.top (both raised together by the same amount). */
.hero__right {
  position: absolute;
  left:  auto;
  right: var(--rail-pad);
  bottom: 339px;
  width: 312px;
  z-index: 7;               /* above service rings (z=6) */
  display: flex;
  flex-direction: column;
}

.hero__signature {
  display: block;
  width: 312px;                 /* Signature 1 in Figma is 312×58 */
  height: auto;
  margin-bottom: 24px;          /* gap signature→claim row */
  /* Image is white-on-transparent; stays crisp on dark bg. */
}

.hero__claim-row {
  display: flex;
  gap: 75px;                    /* 219-144 = 75 between claim and loc */
  padding-left: 29px;           /* Figma: Frame 9 inset 29px inside Frame 27 */
}

.hero__claim {
  width: 144px;
  font-size:      16px;
  line-height:    21px;
  font-weight:    400;
  letter-spacing: 0;
  color: var(--white);
  white-space: nowrap;
}

.hero__loc {
  width: 64px;
  display: flex;
  flex-direction: column;
}
.hero__loc span {
  font-size:      16px;
  line-height:    21px;
  font-weight:    400;
  letter-spacing: 0;
  color: var(--white);
}

/* ─── Service rings strip · 4 cells, capped at 1440 wide ───────
      Rings fill their cell exactly → tangent (edge-to-edge, no overlap).
      vector-effect="non-scaling-stroke" keeps stroke at 1px device-px.
      Strip width is capped to 1440 (the site's content rail) and centred
      horizontally — on ultra-wide viewports the rings stop scaling instead
      of growing into giant 25vw discs that swallow the composition.
      Strip is anchored at hero bottom-70 so rings bleed onto the next
      (white) section, regardless of hero height.                        */

.hero__services {
  --strip-w: min(100vw, 1440px);
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  /* Center-anchor scaling: the strip's vertical centre stays at a
     fixed y (40 px above hero.bottom). As the rings shrink with the
     viewport, they shrink AROUND the centre — not from the top. The
     bleed onto the white Leistungen reduces gracefully on narrow
     widths, but labels (sitting on the equator of each ring) stay in
     the dark zone always. Math:
       strip.bottom_offset = -(strip_h/2) + 40
                           = 40 - strip_w / 8                       */
  bottom: calc(40px - var(--strip-w) / 8);
  width: var(--strip-w);
  height: calc(var(--strip-w) / 4);
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  z-index: 6;
  pointer-events: none;
}

.hero__service {
  position: relative;
  width:  100%;
  aspect-ratio: 1 / 1;
  pointer-events: auto;
  cursor: pointer;
}

/* Rotating wrapper — spins ring + plus together; plus counter-spins to stay upright */

.hero__service-ring-wrap {
  position: absolute;
  inset: 0;
  animation: ring-spin 70s linear infinite;
}

/* Ring SVG fills the wrapper; stroke stays 1px via non-scaling-stroke */

.hero__service-ring {
  position: absolute;
  inset: 0;
  width:  100%;
  height: 100%;
  overflow: visible;
  pointer-events: none;
  z-index: 1;
}

/* Photo overlay — same circle as the ring.
   Idle: hidden. Hover: full opacity, full colour (no dim filter). */

.hero__service-photo {
  position: absolute;
  inset: 0;
  width:  100%;
  height: 100%;
  border-radius: 50%;
  background: center / cover no-repeat;
  opacity: 0;
  pointer-events: none;
  z-index: 0;
  transition: opacity 0.9s ease-in-out;
}
.hero__service:hover .hero__service-photo,
.hero__service.is-active .hero__service-photo {
  opacity: 0.9;
  transition: opacity 0.7s ease-out;
}

/* Portrait desaturates whenever any service ring is hovered — focus
   shifts from Jakob (the constant) to the service ring (the variable).
   Modern :has() selector — supported in all current evergreen browsers. */
.hero:has(.hero__service:hover) .hero__portrait img,
.hero:has(.hero__service.is-active) .hero__portrait img {
  filter: grayscale(1);
}
.hero__portrait img {
  transition: filter 0.7s ease;
}

/* Plus mark — sits on circumference at gap midpoint.
   No background fill: it floats cleanly in the gap on the dark bg. */

.hero__service-plus {
  position: absolute;
  left: var(--plus-x-pct, 8%);
  top:  var(--plus-y-pct, 76%);
  /* base transform is overridden by plus-stay animation which includes both translate + counter-rotate */
  transform: translate(-50%, -50%);
  animation: plus-stay 70s linear infinite;
  font-size:   13px;
  line-height: 1;
  color: var(--white);         /* default: white on dark hero */
  font-weight: 300;
  z-index: 2;
  pointer-events: none;
  user-select: none;
  transition: color 200ms ease;
}
.hero__service-plus.on-light {
  color: var(--blue);          /* atlas-blue when plus visually crosses onto white Leistungen below */
}

/* Service label — centered horizontally at ring equator (≈48% height) */

.hero__service-label {
  position: absolute;
  top: 48.25%;
  left: 50%;
  transform: translateX(-50%);
  font-size:      14px;
  line-height:    14px;
  font-weight:    400;
  letter-spacing: 0;
  text-transform: uppercase;
  color: var(--white);
  white-space: nowrap;
  pointer-events: none;
  z-index: 2;
}
/* Charcoal when the label visually crosses onto the white Leistungen
   below — used on mobile for the bottom row of rings. No transition
   here on purpose: the label inherits the parent's hero-rise animation
   on first render, and a competing color transition can stall the
   computed style mid-way. The class flip is a one-off (page-load
   layout decision), so an instant swap is fine and avoids the bug. */
.hero__service-label.on-light {
  color: var(--color-charcoal);
}

/* Note: with the center-anchored rings strip above, label.y stays
   inside the hero at every desktop width — no media-query recolor
   needed any more. */

/* ════════════════════════════════════════════════════════════════
 * HERO · TABLET TREATMENT  (736–1069px)
 * ─────────────────────────────────────────────────────────────────
 * Below 1070 the right text-block (signature + claim/loc) simply
 * HIDES — it does not drop into the lead column under the buttons.
 * Once it's gone, Jakob no longer reserves the 312-px right-block
 * width on his right anchor; he re-anchors flush to the rail.
 * ════════════════════════════════════════════════════════════════ */

@media (min-width: 736px) and (max-width: 1069.98px) {

  /* Right text-block hides — keeps the layout uncluttered. */
  .hero__right { display: none; }

  /* Jakob anchors directly to the right rail (no 312-px reservation). */
  .hero__portrait {
    right: var(--rail-pad);
  }
}


/* ════════════════════════════════════════════════════════════════
 * HERO · MOBILE REFLOW  (<736px)
 * ─────────────────────────────────────────────────────────────────
 * At the structural breakpoint (same as nav→burger), the absolute
 * 1440-frame composition collapses into a single vertical column:
 *   header · h1 · body · CTAs · claim/loc · portrait · 4 rings 2×2.
 * Every absolute child resets to `position: static` and the hero's
 * fixed 720px height becomes auto so content drives the height.
 * ════════════════════════════════════════════════════════════════ */

@media (max-width: 735.98px) {

  .hero {
    height: auto;
    padding: 96px var(--rail-pad) 0;     /* clears the 80h logo + 16 gap */
    display: flex;
    flex-direction: column;
    overflow: visible;
  }

  /* Reset lead/right back into normal flow.
     The rings strip (.hero__services) is re-anchored below as
     position: absolute so it can span the hero/Leistungen boundary. */
  .hero__lead,
  .hero__right {
    position: static;
    left: auto;
    right: auto;
    bottom: auto;
    width: 100%;
    z-index: auto;
    transform: none;
  }
  .hero__portrait {
    position: static;
    left: auto;
    right: auto;
    bottom: auto;
    z-index: auto;
    transform: none;
  }

  /* ─── 1. Lead (h1 + body + buttons) ──────────────────────── */

  .hero__lead {
    order: 1;
    margin-bottom: 24px;
  }
  .hero__name {
    font-size: 40px;
    line-height: 1.05;
    white-space: normal;
    margin-bottom: 16px;
  }
  .hero__body {
    /* Cap line length on mobile/tablet so the body text doesn't sprawl
       across the full viewport width — readable line length stays
       around the desktop 338-px sweet spot. On narrow phones (≤338
       content) the cap doesn't apply and the text fills naturally. */
    width: auto;
    max-width: 338px;
    margin-bottom: 24px;
  }
  .hero__ctas {
    flex-wrap: wrap;
    gap: 8px;
  }
  /* Buttons sized by content on mobile (the fixed 194/114 widths
     come from the Figma 1440 row and don't survive narrowing). */
  .hero__btn--primary,
  .hero__btn--ghost {
    width: auto;
    padding: 0 18px;
  }

  /* ─── 2. Claim + locator block · HIDDEN on mobile per client ─── */

  .hero__right { display: none; }
  .hero__signature { display: none; }
  .hero__claim-row {
    padding-left: 0;
    gap: clamp(40px, 12vw, 95px);     /* Figma 375: gap = 95 */
  }
  .hero__claim {
    /* Let the natural 16px line-height + <br> tags carry the rhythm */
    width: auto;
  }

  /* ─── 3. Jakob portrait · scaled-down on mobile ─────────────
     Mobile-only override: 340 × 450 (same 468:620 desktop aspect,
     just smaller). Keeps the head-and-shoulders crop intact via
     object-fit: cover. Bottom margin is 0 so Jakob's feet are flush
     with the hero's bottom edge — the ring strip below (absolutely
     positioned) overlaps that boundary. */
  .hero__portrait {
    order: 3;
    width: 340px;
    height: 450px;
    aspect-ratio: auto;
    margin: 0 auto;                  /* flush with hero.bottom */
    flex-shrink: 0;
    align-self: center;
  }
  .hero__portrait img {
    object-fit: cover;
    object-position: center top;
  }

  /* ─── 4. Service rings · 2 × 2 grid, spans hero/Leistungen boundary ─
     Strip is taken OUT of the flex flow and absolutely anchored to
     the hero bottom. The TOP ROW reproduces the desktop bleed exactly:
     ring centre lands 40 px ABOVE hero.bottom (= bottom of Jakob), so
     the upper half (label included) sits on the blue Jakob area, the
     lower half spills onto the white Leistungen below. The BOTTOM ROW
     stacks directly under it and falls fully onto the white surface.
     Math:
       row_h            = 50vw          (each ring 50vw × 50vw)
       strip.height     = 100vw         (2 rows × 50vw)
       top_row.center   = hero.bottom − 40
       strip.top        = top_row.center − 25vw  = hero.bottom − 40 − 25vw
     so `top: calc(100% − 40px − 25vw)`. */
  .hero__services {
    position: absolute;
    left: 0;
    right: auto;
    top: calc(100% - 40px - 25vw);
    bottom: auto;
    transform: none;
    width: 100%;
    --strip-w: 100vw;
    height: 100vw;                   /* 2 rows × 50vw */
    grid-template-columns: 1fr 1fr;
    margin: 0;
    z-index: 6;
  }
  .hero__service { aspect-ratio: 1 / 1; }
}


/* ════════════════════════════════════════════════════════════════
 * SECTION 2 · LEISTUNGEN  —  Numbered dark circles (client-approved)
 *
 * Each card opens with a 48px filled charcoal disc holding the index
 * (01–06) in white, in the natural flow above the title. Plain white
 * page; the visual weight comes from the circles. Crop-mark variant
 * lives in /sandbox/ for reference.
 * ─────────────────────────────────────────────────────────────── */

.leistungen {
  background: var(--color-paper);
  color: var(--color-charcoal);
  /* Top padding includes a +64 buffer below the hero rings strip so the
     "Dienstleistungen" eyebrow clears the bleeding ring strokes. */
  padding: clamp(136px, 14vw, 184px) 0 clamp(72px, 10vw, 120px);
}

.leistungen__inner {
  padding: 0 var(--rail-pad);
}

/* Mobile: pad Leistungen down so its eyebrow clears the bottom row of
   service rings, which (per the mobile rule above) is anchored to the
   hero bottom and extends 75vw − 40 below it. */
@media (max-width: 735.98px) {
  .leistungen { padding-top: calc(75vw - 40px + 64px); }
}

.leistungen__head {
  /* Capped at ~1.5 grid columns at desktop, scaling down on narrower
     viewports so the head never runs the full content rail. The long
     German title now wraps inside the cap (the markup uses nbsp before
     the dash and a real space after, so the dash never hangs alone). */
  max-width: clamp(360px, 45vw, 580px);
  margin-bottom: 80px;
}

.leistungen__eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 14px;
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--blue);
  margin-bottom: 28px;
}

.leistungen__eyebrow::before {
  content: "";
  width: 32px;
  height: 1px;
  background: var(--blue);
  flex-shrink: 0;
}

.leistungen__title {
  font-size: var(--text-h2);
  font-weight: 600;
  letter-spacing: -0.022em;
  line-height: 1.06;
  color: var(--color-charcoal);
}
.leistungen__title br { display: none; }
@media (min-width: 1024px) { .leistungen__title br { display: inline; } }

/* 3 × 2 grid with generous gaps so circles + body breathe */

/* Grid · zero gap — tiles flush, edge-to-edge, classic Swiss surface.
   Hover white emerges from the paper-grey neighbours by colour alone. */
.leistungen__grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0;
  list-style: none;
  padding-left: 0;
  margin: 0 -24px;                        /* offset the tile padding so content
                                             aligns with the eyebrow above */
}

@media (max-width: 980px) {
  .leistungen__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 560px) {
  .leistungen__grid { grid-template-columns: 1fr; }
}

/* Tile surface · transparent over paper-grey section bg by default;
   hover swaps to pure white. Clean Swiss surface change — no shadow,
   no scale, no border. The 220 ms ease-out matches the site rhythm. */
.leistung {
  position: relative;
  padding: 24px;                           /* 8-grid · breathing room for hover surface */
  background: transparent;
  transition: background 220ms ease-out;
}
.leistung:hover { background: var(--color-white); }

/* Dark filled circle in the natural flow, ABOVE the title, left-aligned.
   48px disc, white "01"–"06" inside, tabular nums. */

.leistung__num {
  display: grid;
  place-items: center;
  width: 48px;
  height: 48px;
  border-radius: 999px;
  background: var(--color-atlas);          /* brand atlas blue — rhymes with hero rings */
  color: var(--color-white);
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.04em;
  font-variant-numeric: tabular-nums;
  margin-bottom: 28px;
  transition: background 220ms ease-out;
}
.leistung:hover .leistung__num { background: var(--color-atlas-dk); }

.leistung__title {
  font-size: clamp(20px, 1.8vw, 24px);
  font-weight: 600;
  letter-spacing: -0.005em;
  line-height: 1.25;
  color: var(--color-charcoal);
  margin-bottom: 18px;
}

.leistung__desc {
  font-size: 16px;
  line-height: 1.65;
  color: var(--color-mute);
}



/* ════════════════════════════════════════════════════════════════
 * SECTION 3 · CTA  —  Editorial Spread (canonical, with photo bg)
 *
 * 3-col grid on dark navy with a photo overlay (same `04 copy.webp`
 * stack as the rings variant): 4 hairline-outline tag pills flank
 * a centred copy column with the primary button. Section is capped
 * to 1440px (Figma artboard) and centred so the photo bg does not
 * bleed past the content rail on wider viewports.
 * ─────────────────────────────────────────────────────────────── */

.cta {
  position: relative;
  /* Studio backdrop comes from the .bg-studio utility class (halo + grain).
     We deliberately don't set a `background` here so .bg-studio cascade wins. */
  color: var(--color-white);
  padding: clamp(72px, 10vw, 120px) 0;
  overflow: hidden;
}

.cta__inner {
  padding: 0 var(--rail-pad);
  display: grid;
  /* Match the FAQ grid (5fr / 7fr) so the tag column's left edge lines
     up with the FAQ accordion column one section below. */
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  gap: clamp(48px, 6vw, 96px);
  align-items: start;
}
@media (max-width: 980px) {
  .cta__inner { grid-template-columns: 1fr; gap: 40px; }
}

/* Tags — single vertical stack, pills sized to content, left-aligned at
   the start of the right grid column. */

.cta__tags {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 12px;
  list-style: none;
  margin: 0;
  padding: 0;
}
.cta__tags li {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 38px;
  padding: 0 20px;
  border: 1px solid var(--color-alpine);
  border-radius: 999px;
  font-family: var(--font-sans);
  font-size: 14px;
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--color-alpine);
  white-space: nowrap;
}
@media (max-width: 980px) {
  .cta__tags { flex-direction: row; flex-wrap: wrap; gap: 8px; }
}

.cta__lead { text-align: left; }

.cta__eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 14px;
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--color-alpine);
  margin-bottom: 28px;
}
.cta__eyebrow::before {
  content: "";
  width: 32px;
  height: 1px;
  background: var(--color-alpine);
  flex-shrink: 0;
}

.cta__title {
  font-size: var(--text-h2);
  font-weight: 600;
  letter-spacing: -0.022em;
  line-height: 1.06;
  color: var(--color-white);
  margin-bottom: 24px;
  text-wrap: balance;
}

.cta__body {
  font-size: 16px;
  line-height: 1.65;
  color: rgba(255, 255, 255, 0.78);
  margin-bottom: 36px;
  max-width: 560px;
}

/* Button moved to shared/buttons.css → .btn-cta primitive (single
   source of truth). Both home and /ueber-mich/ use it identically. */

/* ════════════════════════════════════════════════════════════════
 * SECTION 4 · FAQ  —  Editorial 2-col on paper
 *
 * Soft off-white (paper) bg breaks the rhythm after the dark CTA.
 * Editorial 2-col: title left, accordion right. Active item rises
 * onto a clean white plate against the paper background — minimal
 * Swiss-grid contrast.
 * Native <details>/<summary> for accessibility and zero JS.
 * ─────────────────────────────────────────────────────────────── */

.faq {
  background: var(--color-paper);
  color: var(--color-charcoal);
  padding: clamp(72px, 10vw, 120px) 0;
}

.faq__inner {
  padding: 0 var(--rail-pad);
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  gap: clamp(48px, 6vw, 96px);
  align-items: start;
}

@media (max-width: 980px) {
  .faq__inner { grid-template-columns: 1fr; gap: 40px; }
}

.faq__head { position: sticky; top: 80px; }
@media (max-width: 980px) { .faq__head { position: static; } }

.faq__eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 14px;
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--color-atlas);
  margin-bottom: 28px;
}
.faq__eyebrow::before {
  content: "";
  width: 32px;
  height: 1px;
  background: var(--color-atlas);
  flex-shrink: 0;
}

.faq__title {
  font-size: var(--text-h2);
  font-weight: 600;
  letter-spacing: -0.022em;
  line-height: 1.06;
  color: var(--color-charcoal);
}
.faq__title br { display: none; }
@media (min-width: 1024px) { .faq__title br { display: inline; } }

/* Accordion list — top + bottom hairlines + inner dividers */

.faq__list {
  display: flex;
  flex-direction: column;
  border-top: 1px solid var(--color-border);
}

.faq__item {
  border-bottom: 1px solid var(--color-border);
  background: transparent;
  transition: background 280ms ease;
}

/* Active item — clean white plate against paper bg */
.faq__item[open] {
  background: var(--color-white);
}

.faq__q {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  padding: 24px clamp(20px, 2vw, 28px);
  font-family: var(--font-sans);
  font-size: clamp(16px, 1.3vw, 18px);
  font-weight: 500;
  letter-spacing: -0.005em;
  line-height: 1.4;
  color: var(--color-charcoal);
  transition: color 200ms ease;
}
.faq__q::-webkit-details-marker { display: none; }
.faq__q::marker { display: none; }

.faq__q-text { flex: 1; }

.faq__chevron {
  flex-shrink: 0;
  width: 20px;
  height: 20px;
  color: var(--color-pewter);
  transition: transform 280ms var(--ease-out, ease), color 200ms ease;
}

.faq__item[open] .faq__q { color: var(--color-atlas); }
.faq__item[open] .faq__chevron {
  transform: rotate(180deg);
  color: var(--color-atlas);
}

.faq__item:hover:not([open]) .faq__q { color: var(--color-atlas); }
.faq__item:hover:not([open]) .faq__chevron { color: var(--color-atlas); }

.faq__a {
  padding: 0 clamp(20px, 2vw, 28px) 28px;
  font-size: 16px;
  line-height: 1.65;
  color: var(--color-mute);
  max-width: 720px;
}

/* ════════════════════════════════════════════════════════════════
 * SECTION 5 · LINKEDIN  —  Stimme & Standpunkt (curated voice)
 *
 * White plate (rhymes with the wireframe and Leistungen above), paper-
 * tinted cards floating on it — a Swiss-grid "advisory memo" feel
 * rather than a social-feed widget. Date is the first element of every
 * card (memo stamp), even when an image follows below.
 * Horizontal scroll-snap rail with 5 cards (3 text-only + 2 with image
 * placeholder). Pagination underneath: arrow ← • • • → arrow.
 *   - Desktop ≥980px: 3 cards visible per page
 *   - Tablet 640–980px: 2 cards visible per page
 *   - Mobile <640px: 1 card visible per page
 * Section closes with the inherited primary CTA "Auf LinkedIn vernetzen"
 * — same visual weight as the wireframe's original LinkedIn CTA.
 * ─────────────────────────────────────────────────────────────── */

.linkedin {
  background: var(--color-atlas);
  color: var(--color-white);
  padding: clamp(72px, 10vw, 120px) 0;
}

.linkedin__inner {
  padding: 0 var(--rail-pad);
}

/* Head as a 3-column grid that mirrors the card rail below.
   Eyebrow spans the top row. Title-row (bug + h2) takes columns 1-2.
   Sub-paragraph sits in column 3, bottom-aligned with the h2 — frees
   vertical space and visually anchors with the third post-card. */
.linkedin__head {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  column-gap: clamp(20px, 2.4vw, 32px);   /* matches card rail gap */
  align-items: end;                        /* sub bottom-aligns with title */
  margin-bottom: clamp(48px, 6vw, 72px);
}

.linkedin__eyebrow {
  grid-column: 1 / -1;
  display: inline-flex;
  align-items: center;
  gap: 14px;
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--color-alpine);
  margin-bottom: 28px;
  align-self: start;
}
.linkedin__eyebrow::before {
  content: "";
  width: 32px;
  height: 1px;
  background: var(--color-alpine);
  flex-shrink: 0;
}

/* Title row spans the first two card columns. Bug LEFT, h2 RIGHT.
   `align-items: baseline` lines the bug bottom with the h2 baseline,
   so the 40px mark visually sits on the first line of the headline. */
.linkedin__title-row {
  grid-column: 1 / 3;
  display: flex;
  align-items: baseline;
  gap: clamp(12px, 1.4vw, 18px);   /* tighter — bug now sits closer to the title */
}

.linkedin__brand-mark {
  display: inline-block;
  color: var(--color-white);
  flex-shrink: 0;
  line-height: 0;
  /* Sit the bug just inside the cap-line of the heading. +4 from the
     baseline anchor — slightly raised from the previous +10 so the
     bug optically sits a touch higher next to the now-tighter heading. */
  align-self: baseline;
  transform: translateY(4px);
}
.linkedin__brand-mark svg {
  display: block;
  width: 40px;
  height: 40px;
}

.linkedin__title {
  margin: 0;
  font-size: var(--text-h2);
  font-weight: 600;
  letter-spacing: -0.022em;
  line-height: 1.06;
  color: var(--color-white);
}
.linkedin__title br { display: none; }
@media (min-width: 1024px) { .linkedin__title br { display: inline; } }

/* Sub sits in column 3 — same width as the third post-card. */
.linkedin__sub {
  grid-column: 3;
  margin: 0;
  font-size: 16px;
  line-height: 1.65;
  color: var(--color-alpine);
}

/* Below tablet (2-cards-per-view), collapse the head grid: title-row
   takes col 1, sub-paragraph takes col 2 (aligned with card 2 below). */
@media (max-width: 980px) {
  .linkedin__head {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .linkedin__title-row { grid-column: 1; }
  .linkedin__sub      { grid-column: 2; }
}

/* Mobile (1-card-per-view): single column, sub flows below title with
   a comfortable gap so it reads as the section's lede. */
@media (max-width: 640px) {
  .linkedin__head {
    grid-template-columns: 1fr;
    row-gap: 24px;
  }
  .linkedin__title-row { grid-column: 1; }
  .linkedin__sub      { grid-column: 1; }
}

/* Viewport + rail — transform-driven slider (NOT overflow-scroll).
   Programmatic scrollLeft on overflow-scroll containers is unreliable
   when scroll-snap is engaged in some Chromium contexts; transforms
   are deterministic. Viewport clips horizontally and vertical-pads so
   the hover lift (-4px Y) doesn't get cropped. JS sets `translateX`
   on the rail; touchstart/touchend handlers add swipe on touch devices. */

.linkedin__viewport {
  position: relative;
  margin: 0 0 clamp(28px, 3vw, 40px);
  padding: 12px 0;
  overflow-x: clip;
  overflow-y: visible;
}
.linkedin__viewport:focus { outline: none; }
.linkedin__viewport:focus-visible {
  outline: 2px solid var(--color-atlas);
  outline-offset: -2px;
  border-radius: 4px;
}

.linkedin__rail {
  display: flex;
  gap: clamp(20px, 2.4vw, 32px);
  list-style: none;
  padding: 0;
  margin: 0;
  transform: translate3d(0, 0, 0);
  transition: transform 420ms cubic-bezier(0.16, 1, 0.3, 1);
  will-change: transform;
  touch-action: pan-y;            /* lets vertical page scroll pass through */
}

/* Each card occupies (100% − 2·gap) / 3 on desktop so 3 fit per page;
   2 per page on tablet, full width on mobile. */

.linkedin__rail > li {
  flex: 0 0 calc((100% - 2 * clamp(20px, 2.4vw, 32px)) / 3);
  min-width: 0;
  display: flex;
}
@media (max-width: 980px) {
  .linkedin__rail > li {
    flex: 0 0 calc((100% - clamp(20px, 2.4vw, 32px)) / 2);
  }
}
@media (max-width: 640px) {
  .linkedin__rail > li {
    flex: 0 0 100%;
  }
}

/* Card surface — white plate on atlas-blue section. The whole card is
   a clickable link via `.post-card__stretched` covering the full bbox;
   inner content (avatar img, time tag) doesn't trap pointer events. */

.post-card {
  position: relative;                /* anchor the stretched link */
  display: flex;
  flex-direction: column;
  width: 100%;
  background: var(--color-white);
  border-radius: 4px;
  padding: clamp(22px, 2.4vw, 32px);
  color: var(--color-charcoal);
  transition:
    transform 280ms cubic-bezier(0.16, 1, 0.3, 1),
    box-shadow 280ms cubic-bezier(0.16, 1, 0.3, 1);
}

.post-card:hover {
  transform: translateY(-4px);
  box-shadow: 0 16px 32px -22px rgba(7, 38, 52, 0.5);
}

/* External-link arrow · inline at the end of the comment text.
   Diagonal slash + two perpendicular L-corner lines (the "open in
   new tab" convention). Sits at line-height size with thin strokes
   so it reads as a quiet glyph, not a button. Default colour matches
   body-mute; on card hover it shifts up-right AND turns atlas-blue. */
.post-card__external {
  display: inline-block;
  width: 16px;
  height: 16px;
  margin-left: 4px;
  vertical-align: -3px;
  color: var(--color-mute);
  transition: transform 220ms ease, color 220ms ease;
  pointer-events: none;
}
.post-card__external path {
  stroke-width: 1.2;
  vector-effect: non-scaling-stroke;
}
.post-card:hover .post-card__external {
  color: var(--color-atlas);
  transform: translate(2px, -2px);
}

/* Stretched link · invisible, covers the entire card bounding-box.
   Sits BELOW the visible content (z 1) so text remains selectable
   and the avatar img doesn't intercept it. */
.post-card__stretched {
  position: absolute;
  inset: 0;
  z-index: 1;
  border-radius: inherit;
  text-decoration: none;
}
.post-card__stretched:focus-visible {
  outline: 2px solid var(--color-white);
  outline-offset: 3px;
}

/* Image / placeholder block — only present in `.post-card--has-media`.
   16:10 ratio sits comfortably with both photo posts and infographic
   previews. Sits at the top of the card; text follows below. */

.post-card__media {
  position: relative;
  margin: 0 0 20px;
  aspect-ratio: 16 / 10;
  overflow: hidden;
  border-radius: 2px;
  background: linear-gradient(135deg, #DBE4EC 0%, #C6D4E0 100%);
  display: grid;
  place-items: center;
}
.post-card__media img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.post-card__media span {
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--color-pewter);
}

.post-card__text {
  font-size: 16px;
  line-height: 1.65;
  color: var(--color-charcoal);
  margin: 0 0 24px;
  flex: 1;        /* push the author footer to the bottom of every card */
}

/* Divider · horizontal hairline with a small V-notch above where the
   avatar↔name boundary will be. Reads as a speech-bubble pointer:
   "the person below said the text above". Implemented as an inline
   SVG (fixed-width with the notch baked in) plus a flex-1 hairline
   that fills the rest of the row — the notch keeps its physical size
   regardless of card width. */

.post-card__divider {
  display: flex;
  align-items: flex-start;          /* anchor to top so the line and tail align */
  margin-top: auto;
  margin-bottom: 12px;
  height: 18px;                     /* line at top + 16px drop tail */
  color: var(--color-border);
}
.post-card__divider svg {
  display: block;
  flex-shrink: 0;
}
.post-card__divider::after {
  content: "";
  flex: 1;
  height: 1px;
  background: currentColor;
  align-self: flex-start;           /* sit at the SVG line's level */
}

/* Author footer — avatar (44px circle from 03.webp) + name with the
   small gold LinkedIn bug + date. This is the "LinkedIn-flavoured"
   meta-row but rendered with our typography and gold accent. */

.post-card__author {
  display: flex;
  align-items: flex-start;
  gap: 12px;
}

.post-card__avatar {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  object-fit: cover;
  object-position: center top;     /* keep face visible on tight crops */
  background: var(--color-paper);
  flex-shrink: 0;
}

.post-card__by {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.post-card__name {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin: 0;
  font-size: 14px;
  line-height: 1.2;
  font-weight: 600;
  color: var(--color-charcoal);
}

.post-card__bug {
  width: 14px;
  height: 14px;
  flex-shrink: 0;
  color: var(--color-gold);        /* SVG path uses currentColor */
}

/* LinkedIn-style author headline — single line, truncated with
   ellipsis. Sits between the name and the date, like LinkedIn's
   author byline beneath the profile name. */
.post-card__headline {
  display: block;
  margin: 0;
  font-size: 10px;
  line-height: 1.3;
  font-weight: 400;
  color: var(--color-mute);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
}

.post-card__date {
  display: block;
  font-size: 12px;
  line-height: 1.4;
  font-weight: 400;
  letter-spacing: 0;
  text-transform: none;
  color: var(--color-mute);
  font-variant-numeric: tabular-nums;
}

/* Bottom row — same 3-column grid as the card rail above (`.linkedin__rail`).
   CTA sits in column 1, pager in column 3, middle column empty. So the
   pager has exactly the width of one card (the third one) and its left/
   right edges line up with the third card above it. Vertically centred
   against the 48-px CTA. */

.linkedin__bottom {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(20px, 2.4vw, 32px);
  align-items: center;
  margin-top: clamp(40px, 5vw, 64px);
}
.linkedin__bottom .linkedin__pager {
  grid-column: 3;
}
@media (max-width: 980px) {
  .linkedin__bottom {
    grid-template-columns: 1fr;
    gap: clamp(28px, 4vw, 40px);
    align-items: stretch;
  }
  .linkedin__bottom .linkedin__pager {
    grid-column: auto;
  }
}

/* Pager — hairline track between two chevron buttons. No chrome:
   the chevrons are naked SVG glyphs that change colour on hover and
   fade on disabled. The track is a 1-px paper-grey line with a
   2-px atlas-blue thumb whose width = (cardsPerView / total cards)
   and whose left position tracks the current scroll index. Clicking
   anywhere on the track seeks to the proportional position. */

.linkedin__pager {
  display: flex;
  align-items: center;
  gap: clamp(20px, 2.4vw, 32px);
  margin: 0;
  width: 100%;
}

.linkedin__pager-btn {
  display: inline-grid;
  place-items: center;
  width: 28px;
  height: 28px;
  background: transparent;
  border: 0;
  padding: 0;
  color: var(--color-white);
  cursor: pointer;
  flex-shrink: 0;
  transition: color 200ms ease, opacity 200ms ease;
}
.linkedin__pager-btn svg {
  width: 100%;
  height: 100%;
  display: block;
}
.linkedin__pager-btn:hover:not([disabled]) { color: var(--color-alpine); }
.linkedin__pager-btn[disabled] {
  opacity: 0.3;
  cursor: not-allowed;
}
.linkedin__pager-btn:focus-visible {
  outline: 2px solid var(--color-white);
  outline-offset: 4px;
  border-radius: 1px;
}

.linkedin__pager-track {
  flex: 1 1 auto;
  position: relative;
  height: 1px;
  background: rgba(255, 255, 255, 0.22);
  cursor: pointer;
}

.linkedin__pager-thumb {
  position: absolute;
  top: -0.5px;
  left: 0;
  height: 2px;
  width: 33.333%;            /* updated by JS at runtime */
  background: var(--color-white);
  transition:
    left  360ms cubic-bezier(0.16, 1, 0.3, 1),
    width 360ms cubic-bezier(0.16, 1, 0.3, 1);
}

/* Section CTA — primary button mirroring the original wireframe's
   "Auf LinkedIn vernetzen". Sits between the rail and the pager so
   it stays the section's primary action while the pager hangs at the
   foot of the section like a quiet scroll-progress hairline. */

.linkedin__cta {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  height: 48px;
  padding: 0 26px;
  background: var(--color-white);
  color: var(--color-atlas);
  font-size: 14px;
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  text-decoration: none;
  border-radius: 3px;
  justify-self: start;
  transition: background 200ms ease, color 200ms ease;
}
.linkedin__cta:hover {
  background: var(--color-alpine);
  color: var(--color-atlas-dk);
}
.linkedin__cta-arrow { display: inline-block; transition: transform 200ms ease; }
.linkedin__cta:hover .linkedin__cta-arrow { transform: translateX(4px); }
.linkedin__cta:focus-visible {
  outline: 2px solid var(--color-white);
  outline-offset: 3px;
}

/* Mobile · CTA stretches the full content width under the post card,
   matches the post-card's prominence at small viewports. Arrow nudges
   to the right edge so the button reads as a "next step" affordance. */
@media (max-width: 735.98px) {
  .linkedin__cta {
    display: flex;
    width: 100%;
    justify-self: stretch;
    justify-content: space-between;
  }
}

/* .site-footer · moved to shared/site-footer.css (loaded via <link>). */

/* ─── Reduced motion ────────────────────────────────────────── */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
}
