@charset "UTF-8";
/* =============================================================================
   PARTANUM — style.css
   Die einzige Stylesheet-Datei der Seite. Aus Figma-Frame "Desktop" (1512 px).
   -----------------------------------------------------------------------------
   AUFBAU

     0    Schriften            @font-face, Dateien in assets/fonts/
     A1–A5  BW FRAMEWORK v3.2  liegt in @layer — Reset, Tokens, Base,
                               Layout-Primitives, Utilities
     B1–B10 PROJEKT            alle Komponenten der Seiten, ohne @layer
     C1–C2  Breakpoints, Print

   WARUM DIESE ZWEITEILUNG
   Teil A liegt komplett in @layer, Teil B bewusst ausserhalb. Ungelayerte
   Styles gewinnen in der Kaskade immer gegen gelayerte — egal wie niedrig ihre
   Spezifität ist. Was Pinegrow visuell schreibt, landet in Teil B und
   überschreibt damit automatisch das Framework. Kein !important nötig.

   Reihenfolge = Priorität (später gewinnt):
     reset < tokens < base < layout < utilities < (alles ab B1)

   WO ÄNDERE ICH WAS
     Farbe, Schriftgrösse, Abstand, Radius global   →  A2) DESIGN TOKENS
     Aussehen einer einzelnen Komponente            →  der passende B-Abschnitt
   Ab B1 steht kein einziger fest verdrahteter Wert mehr, alles kommt aus var(--…).

   Falls deine Pinegrow-Version @layer nicht sauber parst: die fünf
   "@layer x { ... }" Wrapper in Teil A entfernen, Inhalt in gleicher
   Reihenfolge stehen lassen. Die Zeile "@layer reset, tokens, …;" dann
   ebenfalls löschen.
   ============================================================================= */


/* =============================================================================
   0) SCHRIFTEN
   Die Dateien liegen in assets/fonts/ (woff2 + woff als Rückfall).
   Fehlt eine, greift still der Fallback (Helvetica Neue / Arial bzw. die
   Mono des Systems).
   Familiennamen bitte nicht ändern, darauf zeigen --font-primary/--font-heading.
   ============================================================================= */

@font-face {
  font-family: "PP Monument Normal";
  src: url("../fonts/pp-monument-normal-regular.woff2") format("woff2"),
       url("../fonts/pp-monument-normal-regular.woff") format("woff");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

/* Schreibmaschinenschrift für kleine Auszeichnungen (--font-mono).
   Der Dateiname enthält Leerzeichen, daher %20 in der Adresse. */
@font-face {
  font-family: "GT Pressura Mono";
  src: url("../fonts/gt-pressura-mono-regular.woff2") format("woff2"),
       url("../fonts/gt-pressura-mono-regular.woff") format("woff");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

/* Monument: vier Schnitte, mehr nicht: Normal Regular, Wide Light Italic, Wide Regular,
   Wide Black. Normal Black, Wide Light und Wide Black Italic sind bewusst
   entfallen (Runde 66) — nicht wieder einführen, ohne die Stellen zu prüfen. */

@font-face {
  font-family: "PP Monument Wide";
  src: url("../fonts/pp-monument-wide-light-italic.woff2") format("woff2"),
       url("../fonts/pp-monument-wide-light-italic.woff") format("woff");
  font-weight: 300;
  font-style: italic;
  font-display: swap;
}

@font-face {
  font-family: "PP Monument Wide";
  src: url("../fonts/pp-monument-wide-regular.woff2") format("woff2"),
       url("../fonts/pp-monument-wide-regular.woff") format("woff");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "PP Monument Wide";
  src: url("../fonts/pp-monument-wide-black.woff2") format("woff2"),
       url("../fonts/pp-monument-wide-black.woff") format("woff");
  font-weight: 900;
  font-style: normal;
  font-display: swap;
}


/* #############################################################################
   TEIL A — BW FRAMEWORK v3.2
   Angepasst für Partanum: ausschliesslich der Token-Block A2.
   Alles andere ist unverändert gegenüber v3.2.
   ############################################################################# */

@layer reset, tokens, base, layout, utilities;

/* =============================================================================
   A1) RESET
   ============================================================================= */
@layer reset {

  *, *::before, *::after {
    box-sizing: border-box;
  }

  /* Abstände kommen aus dem Spacing-System, nicht aus Browser-Defaults. */
  body, h1, h2, h3, h4, h5, h6,
  p, figure, blockquote, dl, dd, ul, ol {
    margin: 0;
  }

  /* Listen mit role="list" behalten Screenreader-Semantik trotz
     list-style: none (Safari/VoiceOver). */
  ul[role="list"], ol[role="list"] {
    list-style: none;
    padding: 0;
  }

  img, picture, svg, video, canvas {
    display: block;
    max-width: 100%;
    height: auto;
  }

  input, button, textarea, select {
    font: inherit;
    color: inherit;
  }

  /* Lange Komposita brechen statt überzulaufen. */
  p, li, h1, h2, h3, h4, h5, h6, dd {
    overflow-wrap: break-word;
  }

  @media (prefers-reduced-motion: no-preference) {
    html { scroll-behavior: smooth; }
  }

  /* Der Kopf klebt oben (B2) — Ankerziele müssen unter ihm anfangen. */
  html { scroll-padding-block-start: 4.5rem; }

  @media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
      animation-duration: 0.01ms !important;
      animation-iteration-count: 1 !important;
      animation-delay: 0s !important;
      transition-duration: 0.01ms !important;
      transition-delay: 0s !important;   /* sonst bliebe die Treppe des mobilen
                                            Menüs als Warterei übrig: jeder
                                            Punkt erschiene zwar sofort, aber
                                            nacheinander.                     */
      scroll-behavior: auto !important;
    }
  }
}

/* =============================================================================
   A2) DESIGN TOKENS
   Die einzige Stelle, an der Werte definiert werden.
   Für ein neues Projekt ausschliesslich diesen Block anpassen.

   ALLE WERTE HIER STAMMEN AUS DEM FIGMA-FRAME "Desktop" (1512 x 6136 px).
   ============================================================================= */
@layer tokens {

  :root {

    /* --- SCHRIFTEN -------------------------------------------------------- */
    /* Die @font-face-Deklarationen stehen oben in Abschnitt 0.
       Die Dateien liegen in assets/fonts/.                                    */
    --font-primary: "PP Monument Normal", "Helvetica Neue", Arial, sans-serif;
    --font-heading: "PP Monument Wide", "Helvetica Neue", Arial, sans-serif;
    /* Schreibmaschinenschrift für kleine Auszeichnungen: .label-mono, die
       orangen Kleinüberschriften (.eyebrow, .step__label, .fact__label).
       Schrift: GT Pressura Mono (Datei in assets/fonts/, Abschnitt 0).
       Die übrigen Namen sind nur Rückfall, falls die Datei nicht lädt. */
    --font-mono: "GT Pressura Mono", ui-monospace, "SFMono-Regular", "SF Mono",
                 Menlo, Consolas, "Liberation Mono", monospace;


    /* --- FARBEN: Rohwerte -------------------------------------------------- */
    --primary: #313c44;                     /* Markenfarbe dunkel, Hero/Leistungen/Footer */
    --primary-deep: #23262a;                /* Text auf Akzentflächen */
    --primary-soft: #2e373e;                /* Kontaktkarte (Figma: #23262a @ 25 % auf --primary) */
    --accent: #ff7057;                      /* Signalfarbe: Pfeile, Button-Fläche */
    --accent-light: #ff8570;                /* aufgehellt – Akzenttext auf DUNKLEN Flächen */
    --accent-dark: #bc4326;                 /* abgedunkelt – Akzenttext auf HELLEN Flächen */
    --paper: #eeeae7;                       /* Text und Marken-Weiss auf dunklen Flächen */
    --tint: #f5f2f0;                        /* Flächenton "Über uns" (Figma: #f1edeb @ 74 %) */
    --tint-soft: #faf9f8;                   /* Flächenton "Projekte"  (Figma: #f1edeb @ 35 %) */

    --bw-100: #ffffff;
    --bw-200: #f4f4f4;
    --bw-300: #dfdfdf;
    --bw-400: #c0c0c0;
    --bw-500: #858585;
    --bw-600: #696969;
    --bw-700: #353535;
    --bw-800: #1e1e1e;
    --bw-900: #000000;


    /* --- FARBEN: semantisch ------------------------------------------------ */
    /* Im Markup NUR diese verwenden, nie die Rohwerte darüber. */
    --color-primary: var(--primary);
    --color-primary-dark: var(--primary-deep);
    --color-on-primary: var(--paper);       /* Text auf Primary-Flächen, 9.44:1 */
    --color-bg: var(--bw-100);
    --color-surface: var(--tint);
    --color-surface-soft: var(--tint-soft);
    --color-surface-dark: var(--primary-soft);
    --color-text: var(--primary);
    --color-text-muted: #5e666c;            /* 5.33:1 auf --tint-soft.
                                               Figma hatte #313c44 @ 65 % → nur 4.0:1
                                               und damit unter WCAG 1.4.3 AA.        */
    --color-text-on-dark: var(--paper);
    --color-text-on-dark-muted: #a6a8a9;    /* 4.6:1 auf --primary.
                                               Figma hatte #eeeae7 @ 25 % (2.0:1)
                                               bzw. #ffffff @ 21 % (2.3:1).          */
    --color-accent: var(--accent);          /* nur für Flächen und Grafik (≥3:1)     */
    --color-accent-text: var(--accent-dark);  /* Akzent als TEXT und als Linie.
                                               Hier der Wert für helle Flächen (4.75:1).
                                               .section--dark und .site-header setzen ihn
                                               auf --accent-light um (4.76:1 auf dunkel).
                                               --accent selbst reicht in keinem der beiden
                                               Fälle: 2.48:1 hell / 4.15:1 dunkel.    */
    --color-on-accent: var(--primary-deep); /* Text auf --accent, 5.58:1              */

    /* Button im Hover. Auf HELLEN Flächen wird der Knopf dunkler und die
       Schrift weiss (5.29:1) – ein dunkler Knopf mit dunkler Schrift käme nur
       auf 2.87:1. .section--dark dreht beides um: dort wird der Knopf heller
       (4.75:1 gegen die Fläche) und behält die dunkle Schrift (6.40:1).      */
    --button-hover-bg: var(--accent-dark);
    --button-hover-text: var(--bw-100);
    --color-link: var(--primary);
    --color-focus: var(--primary);
    --color-focus-on-dark: var(--paper);    /* wird in style.css je Sektion gesetzt   */

    --color-border: rgb(49 60 68 / 0.15);   /* dekorative Trenner auf hellen Flächen */
    --color-border-strong: #767676;         /* Formularfelder und UI-Rahmen.
                                               ≥3:1 auf Weiss, Surface UND Tint.     */
    --color-border-on-dark: rgb(238 234 231 / 0.25);


    /* --- TYPOGRAFIE: Grössen ----------------------------------------------- */
    /* Fluid über clamp(min, vorzugswert, max). Der vorzugswert enthält immer
       einen rem-Anteil – ohne den skaliert der Browser-Zoom nicht (WCAG 1.4.4).
       Basis ist der Browser-Standard: 1rem = 16px.
       Der Maximalwert ist jeweils die Grösse aus dem Figma-Frame bei 1512 px.  */

    --text-xs: clamp(0.75rem,   0.7rem     + 0.25vw,  0.9375rem);  /* 12 → 15  Navigation, Footer, Bildunterzeilen, Projekt-Meta */
    --text-s:  clamp(0.875rem,  0.83rem    + 0.22vw,  1rem);       /* 14 → 16 */
    --text-m:  clamp(1rem,      0.9775rem  + 0.09vw,  1.0625rem);  /* 16 → 17  Button, Adresse, Kontakttext */
    --text-l:  clamp(1rem,      0.9775rem  + 0.09vw,  1.0625rem);  /* 16 → 17  Fliesstext (war 16 → 18) */
    --text-xl: clamp(1.125rem,  1.02rem    + 0.53vw,  1.375rem);   /* 18 → 22  Sektions-Label */
    --text-statement: clamp(1.5rem, 0.9rem  + 3vw,     3rem);      /* 24 → 48  grosses Statement (Unterseite) */

    --h1: clamp(2.5rem,   0.9rem   + 8vw,    5rem);       /* 40 → 80  Hero */
    --h2: clamp(1.75rem,  1.05rem  + 3.5vw,  2.625rem);   /* 28 → 42  Sektionsüberschriften.
                                                             Figma: 42 px (Über uns) und
                                                             45 px (Kontakt) → vereinheitlicht. */
    --h3: clamp(1.375rem, 0.95rem  + 2.1vw,  2rem);       /* 22 → 32  Leistungstitel */
    --h4: clamp(1.25rem,  1.05rem  + 1vw,    1.625rem);   /* 20 → 26  Kontaktdaten */
    --h5: var(--text-xl);
    --h6: var(--text-l);


    /* --- TYPOGRAFIE: Rest --------------------------------------------------- */
    --lh-base: 1.462;                       /* exakt der Wert aus dem Figma-Frame */
    --lh-heading: 1.1;
    --tracking-tight: 0em;                  /* Monument läuft im Design ohne Laufweitenkorrektur */
    --tracking-wide: 0.08em;
    --measure: 62ch;                        /* max. Lesebreite für Fliesstext */


    /* --- ABSTÄNDE ----------------------------------------------------------- */
    /* Ebenfalls fluid: Abstände wachsen mit dem Viewport mit.                  */

    --space-2xs: clamp(0.25rem, 0.21875rem + 0.25vw, 0.375rem);  /*   4 →   6 */
    --space-xs:  clamp(0.5rem,  0.4375rem  + 0.5vw,  0.75rem);   /*   8 →  12 */
    --space-s:   clamp(1rem,    0.875rem   + 1vw,    1.5rem);    /*  16 →  24 */
    --space-m:   clamp(1.5rem,  1.25rem    + 2vw,    2.5rem);    /*  24 →  40 */
    --space-l:   clamp(2.5rem,  2rem       + 4vw,    4.5rem);    /*  40 →  72  Sektionsabstand */
    --space-xl:  clamp(4rem,    3.125rem   + 7vw,    7.5rem);    /*  64 → 120 */
    --space-2xl: clamp(6rem,    4.375rem   + 11vw,  11.25rem);   /*  96 → 180 */


    /* --- LAYOUT --------------------------------------------------------------- */
    --content-width: 105rem;                                     /* 1680px – bewusst breiter als der 1512er Frame,
                                                                    damit auf grossen Monitoren links und rechts
                                                                    weniger Leerraum bleibt. Abzüglich --gutter
                                                                    ergibt das bis zu 1440px Inhalt.            */
    --gutter: clamp(1.25rem, -1.8375rem + 9.88vw, 7.5rem);       /*   20 → 120 – ergibt bei 1512 px genau den Frame */
    --inset: clamp(0rem, -9.2875rem + 19.35vw, 9rem);            /*    0 → 144 – zusätzlicher Einzug in "Über uns" und "Leistungen" */
    --inset-narrow: calc(var(--inset) / 4);                      /*    0 →  36 – schmaler Einzug: Intro-Text, Leistungen-Text */


    /* --- FORM & FLÄCHE --------------------------------------------------------- */
    --radius-s:  0.25rem;                   /*  4px */
    --radius-m:  0.5rem;                    /*  8px */
    --radius-l:  1.25rem;                   /* 20px – der Radius aus dem Design */
    --radius-xl: 2rem;                      /* 32px */
    --radius-pill: 62rem;                   /* beliebig gross */

    --shadow-s: 0 1px 2px rgb(0 0 0 / 0.06), 0 1px 3px rgb(0 0 0 / 0.08);
    --shadow-m: 0 4px 8px rgb(0 0 0 / 0.06), 0 8px 24px rgb(0 0 0 / 0.08);
    --shadow-l: 0 8px 16px rgb(0 0 0 / 0.08), 0 24px 48px rgb(0 0 0 / 0.12);


    /* --- BEWEGUNG & INTERAKTION ------------------------------------------------- */
    --ease: cubic-bezier(0.4, 0, 0.2, 1);
    --duration-fast: 150ms;
    --duration-base: 300ms;

    --tap-target: 2.75rem;                  /* 44px – Mindestzielgrösse, WCAG 2.5.8 */
    --link-line: 1px;                       /* Link-Unterstrich in Ruhe */
    --link-line-hover: 2px;                 /* Link-Unterstrich beim Hovern / Fokus */
    --focus-width: 3px;
    --focus-offset: 2px;
  }
}

/* =============================================================================
   A3) BASE
   Verdrahtet die Tokens mit den HTML-Elementen. Ab hier wirken die Variablen.
   ============================================================================= */
@layer base {

  html {
    /* Kein font-size-Reset auf dem Wurzelelement: 1rem bleibt der
       Browser-Standard (in der Regel 16px) und damit exakt die Grösse,
       die der Nutzer in seinen Einstellungen gewählt hat.
       Fremd-CSS, das inline in die Seite injiziert wird (Cookie-Banner,
       Chat-Widgets), rendert dadurch in der erwarteten Grösse. */
    -webkit-text-size-adjust: 100%;
    color-scheme: light;
  }

  body {
    min-height: 100svh;
    display: flex;
    flex-direction: column;
    font-family: var(--font-primary);
    font-size: var(--text-m);
    line-height: var(--lh-base);
    color: var(--color-text);
    background-color: var(--color-bg);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
  }

  main { flex: 1 0 auto; }

  h1, h2, h3, h4, h5, h6 {
    font-family: var(--font-heading);
    font-weight: 400;
    line-height: var(--lh-heading);
    letter-spacing: var(--tracking-tight);
    color: var(--color-primary);
    text-wrap: balance;
  }

  h1 { font-size: var(--h1); }
  h2 { font-size: var(--h2); }
  h3 { font-size: var(--h3); }
  h4 { font-size: var(--h4); }
  h5 { font-size: var(--h5); }
  h6 { font-size: var(--h6); }

  p { text-wrap: pretty; }

  a {
    color: var(--color-link);
    text-decoration-thickness: var(--link-line);
    text-underline-offset: 0.25em;
    transition: color var(--duration-fast) var(--ease);
  }

  a:hover { text-decoration-thickness: var(--link-line-hover); }

  /* Sichtbarer Fokus für Tastaturnutzer (WCAG 2.4.7 / 2.4.11).
     :focus-visible statt :focus – Mausklicks lösen keinen Ring aus. */
  :focus-visible {
    outline: var(--focus-width) solid var(--color-focus);
    outline-offset: var(--focus-offset);
    border-radius: var(--radius-s);
  }

  :target {
    scroll-margin-block-start: var(--space-l);
  }

  ul, ol { padding-inline-start: 1.5rem; }

  li + li { margin-block-start: var(--space-2xs); }

  blockquote {
    padding-inline-start: var(--space-s);
    border-inline-start: 3px solid var(--color-primary);
    font-size: var(--text-l);
  }

  figcaption {
    margin-block-start: var(--space-xs);
    font-size: var(--text-s);
    color: var(--color-text-muted);
  }

  hr {
    border: 0;
    border-block-start: 1px solid var(--color-border-strong);
    margin-block: var(--space-m);
  }

  table { width: 100%; border-collapse: collapse; }

  th, td {
    padding: var(--space-xs) var(--space-s);
    text-align: start;
    border-block-end: 1px solid var(--color-border-strong);
  }

  th { font-weight: 700; }

  caption {
    caption-side: bottom;
    padding-block-start: var(--space-xs);
    font-size: var(--text-s);
    color: var(--color-text-muted);
  }

  ::selection {
    background-color: var(--color-primary);
    color: var(--color-on-primary);
  }

  @media (forced-colors: active) {
    :focus-visible { outline-color: Highlight; }
  }
}

/* =============================================================================
   A4) LAYOUT-PRIMITIVES
   Vier Bausteine, aus denen sich fast jedes Seitenlayout zusammensetzt.
   ============================================================================= */
@layer layout {

  /* Vertikaler Rhythmus. Kein Flex-Zwang – jede Section entscheidet
     selbst über ihr inneres Layout. */
  .section { padding-block: var(--space-l); }

  .section--tight { padding-block: var(--space-m); }
  .section--loose { padding-block: var(--space-xl); }
  .section--flush { padding-block: 0; }

  /* Zentrierter Inhaltsbereich mit Seitenabstand. */
  .container {
    width: 100%;
    max-width: var(--content-width);
    margin-inline: auto;
    padding-inline: var(--gutter);
  }

  .container--narrow { max-width: 56.25rem; }   /*  900px */
  .container--wide   { max-width: 105rem; }     /* 1680px */
  .container--full   { max-width: none; }

  /* Fliesstext auf lesbare Zeilenlänge begrenzen (WCAG 1.4.8). */
  .prose { max-width: var(--measure); }

  .prose > * + *      { margin-block-start: var(--space-s); }
  .prose :is(h2, h3)  { margin-block-start: var(--space-m); }

  /* Stack – vertikaler Abstand zwischen Geschwistern. */
  .stack { display: flex; flex-direction: column; }

  .stack-2xs { gap: var(--space-2xs); }
  .stack-xs  { gap: var(--space-xs); }
  .stack-s   { gap: var(--space-s); }
  .stack-m   { gap: var(--space-m); }
  .stack-l   { gap: var(--space-l); }

  /* Cluster – horizontale Gruppe mit Umbruch. Buttons, Tags, Meta-Zeilen. */
  .cluster {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-s);
  }

  /* Grid */
  .grid { display: grid; gap: var(--space-m); }

  /* Auto-responsiv ohne Media Query: bricht um, sobald --grid-min
     nicht mehr passt. Erste Wahl für Karten- und Teaserlisten. */
  .grid--auto {
    grid-template-columns: repeat(auto-fit, minmax(min(var(--grid-min, 17.5rem), 100%), 1fr));
  }

  /* Feste Spaltenzahl nur, wenn das Design es verlangt. */
  .grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .grid--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }

  @media (width < 62em) {
    .grid--3, .grid--4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  }

  @media (width < 48em) {
    .grid--2, .grid--3, .grid--4 { grid-template-columns: minmax(0, 1fr); }
  }

  /* Split – zwei Spalten ab 768px, darunter gestapelt. Text + Bild. */
  .split { display: grid; gap: var(--space-m); align-items: center; }

  @media (width >= 48em) {
    .split { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .split--reverse > :first-child { order: 2; }
  }

  .flex-center  { display: flex; align-items: center; justify-content: center; }
  .flex-between { display: flex; flex-wrap: wrap; align-items: center;
                  justify-content: space-between; gap: var(--space-s); }
}

/* =============================================================================
   A5) UTILITIES
   Machen die Tokens in Pinegrow per Klick zuweisbar.
   ============================================================================= */
@layer utilities {

  /* --- Zugänglichkeit ------------------------------------------------------- */
  /* Für Screenreader vorhanden, visuell versteckt. */
  .visually-hidden {
    position: absolute !important;
    inline-size: 1px;
    block-size: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
  }

  /* --- Schriftgrössen -------------------------------------------------------- */
  .text-xs { font-size: var(--text-xs); }
  .text-s  { font-size: var(--text-s); }
  .text-m  { font-size: var(--text-m); }
  .text-l  { font-size: var(--text-l); }
  .text-xl { font-size: var(--text-xl); }

  /* Optik einer Überschriftenebene ohne die Semantik zu ändern.
     <h3 class="h1"> bleibt in der Hierarchie eine h3, sieht aus wie eine h1.
     So muss nie eine Ebene übersprungen werden, nur um eine Grösse zu erreichen. */
  .h1, .h2, .h3, .h4, .h5, .h6 {
    font-family: var(--font-heading);
    font-weight: 400;
    line-height: var(--lh-heading);
    letter-spacing: var(--tracking-tight);
    color: var(--color-primary);
    text-wrap: balance;
  }

  .h1 { font-size: var(--h1); }
  .h2 { font-size: var(--h2); }
  .h3 { font-size: var(--h3); }
  .h4 { font-size: var(--h4); }
  .h5 { font-size: var(--h5); }
  .h6 { font-size: var(--h6); }

  .lh-base    { line-height: var(--lh-base); }
  .lh-heading { line-height: var(--lh-heading); }
  .tracking-wide { letter-spacing: var(--tracking-wide); }
  .uppercase  { text-transform: uppercase; }

  .text-center { text-align: center; }
  .text-start  { text-align: start; }
  .text-end    { text-align: end; }

  /* --- Abstände: gap ---------------------------------------------------------- */
  .gap-2xs { gap: var(--space-2xs); }
  .gap-xs  { gap: var(--space-xs); }
  .gap-s   { gap: var(--space-s); }
  .gap-m   { gap: var(--space-m); }
  .gap-l   { gap: var(--space-l); }
  .gap-xl  { gap: var(--space-xl); }

  /* --- Abstände: padding ------------------------------------------------------ */
  .p-2xs { padding: var(--space-2xs); }
  .p-xs  { padding: var(--space-xs); }
  .p-s   { padding: var(--space-s); }
  .p-m   { padding: var(--space-m); }
  .p-l   { padding: var(--space-l); }

  .px-2xs { padding-inline: var(--space-2xs); }
  .px-xs  { padding-inline: var(--space-xs); }
  .px-s   { padding-inline: var(--space-s); }
  .px-m   { padding-inline: var(--space-m); }
  .px-l   { padding-inline: var(--space-l); }

  .py-2xs { padding-block: var(--space-2xs); }
  .py-xs  { padding-block: var(--space-xs); }
  .py-s   { padding-block: var(--space-s); }
  .py-m   { padding-block: var(--space-m); }
  .py-l   { padding-block: var(--space-l); }
  .py-xl  { padding-block: var(--space-xl); }
  .py-2xl { padding-block: var(--space-2xl); }

  /* --- Abstände: margin ------------------------------------------------------- */
  .mt-2xs { margin-block-start: var(--space-2xs); }
  .mt-xs  { margin-block-start: var(--space-xs); }
  .mt-s   { margin-block-start: var(--space-s); }
  .mt-m   { margin-block-start: var(--space-m); }
  .mt-l   { margin-block-start: var(--space-l); }
  .mt-xl  { margin-block-start: var(--space-xl); }

  .mb-2xs { margin-block-end: var(--space-2xs); }
  .mb-xs  { margin-block-end: var(--space-xs); }
  .mb-s   { margin-block-end: var(--space-s); }
  .mb-m   { margin-block-end: var(--space-m); }
  .mb-l   { margin-block-end: var(--space-l); }
  .mb-xl  { margin-block-end: var(--space-xl); }

  /* --- Farbe & Fläche --------------------------------------------------------- */
  .text-muted   { color: var(--color-text-muted); }
  .text-primary { color: var(--color-primary); }

  .bg-surface { background-color: var(--color-surface); }
  .bg-primary { background-color: var(--color-primary); color: var(--color-on-primary); }
  .bg-primary :is(h1, h2, h3, h4, h5, h6) { color: var(--color-on-primary); }

  .radius-s    { border-radius: var(--radius-s); }
  .radius-m    { border-radius: var(--radius-m); }
  .radius-l    { border-radius: var(--radius-l); }
  .radius-xl   { border-radius: var(--radius-xl); }
  .radius-pill { border-radius: var(--radius-pill); }

  .shadow-s { box-shadow: var(--shadow-s); }
  .shadow-m { box-shadow: var(--shadow-m); }
  .shadow-l { box-shadow: var(--shadow-l); }

  /* --- Sonstiges --------------------------------------------------------------- */
  .measure { max-width: var(--measure); }
  .center  { margin-inline: auto; }
}

/* #############################################################################
   TEIL B — PARTANUM KOMPONENTEN
   Ab hier ohne @layer. Diese Regeln gewinnen immer gegen Teil A.
   ############################################################################# */

/* =============================================================================
   B1) GLOBALE HILFEN
   ============================================================================= */

/* --- Skip-Link: erster Tabstopp der Seite (WCAG 2.4.1) --------------------- */
.skip-link {
  position: absolute;
  inset-block-start: 0;
  inset-inline-start: 0;
  z-index: 100;
  padding: var(--space-xs) var(--space-s);
  background-color: var(--color-accent);
  color: var(--color-on-accent);
  font-size: var(--text-xs);
  text-decoration: none;
  translate: 0 -120%;
}

.skip-link:focus {
  translate: 0 0;
}

/* --- Dunkle Sektionen ------------------------------------------------------ */
/* Setzt Textfarbe UND Fokusfarbe um. Ein schwarzer Fokusring wäre auf
   --color-primary praktisch unsichtbar (WCAG 2.4.11 / 1.4.11).               */
.section--dark {
  background-color: var(--color-primary);
  color: var(--color-text-on-dark);
  --color-focus: var(--color-focus-on-dark);
  --color-accent-text: var(--accent-light);   /* auf dunklem Grund die helle Akzentvariante */
  --button-hover-bg: var(--accent-light);
  --button-hover-text: var(--color-on-accent);
}

.section--dark :is(h1, h2, h3, h4, h5, h6) {
  color: var(--color-text-on-dark);
}

.section--dark a {
  color: var(--color-text-on-dark);
}

/* --- Unterstrich, der beim Hovern hereinläuft ------------------------------
   Ein hartes text-decoration: underline springt beim Hovern hart an und wieder
   weg. Diese Linie wächst stattdessen in --duration-base von links herein.
   Sie liegt absolut und verschiebt deshalb nichts im Layout.

   --underline-drop steuert, wie tief die Linie unter der Schrift sitzt.
   Jede Link-Art setzt sich den Wert selbst, weil sie unterschiedlich hohe
   Kästen haben (Navigation 44px Zielfläche, Fliesstextlinks nur die Zeile). */
.site-nav__link,
.site-header__cta,
.contact__value a,
.inline-list a,
.link-arrow__text,
.project__client {
  position: relative;
  transition: color var(--duration-base) var(--ease);
}

.site-nav__link::after,
.site-header__cta::after,
.contact__value a::after,
.inline-list a::after,
.link-arrow__text::after,
.project__client::after {
  content: "";
  position: absolute;
  inset-block-end: var(--underline-drop, -0.2em);
  inset-inline: 0;
  block-size: var(--link-line-hover);                   /* erscheint nur beim Hovern */
  background-color: currentColor;
  scale: 0 1;
  transform-origin: left center;
  transition: scale var(--duration-base) var(--ease);
}

.site-nav__link:hover::after,
.site-nav__link:focus-visible::after,
.site-header__cta:hover::after,
.site-header__cta:focus-visible::after,
.contact__value a:hover::after,
.contact__value a:focus-visible::after,
.inline-list a:hover::after,
.inline-list a:focus-visible::after,
.link-arrow:hover .link-arrow__text::after,
.link-arrow:focus-visible .link-arrow__text::after,
.project__link:hover .project__client::after,
.project__link:focus-visible .project__client::after {
  scale: 1 1;
}

/* --- Textlink mit Unterstrich ----------------------------------------------
   Der Unterstrich steht immer in der Akzentfarbe. Beim Hovern färbt sich
   zusätzlich der Text und ein Pfeil fährt heraus. Der Pfeil ist dieselbe SVG
   wie überall sonst, hier als Maske eingesetzt – dadurch nimmt er die
   Textfarbe an. Bei "Bewegung reduzieren" setzt das Framework die Dauer auf
   0.01ms, der Pfeil erscheint dann ohne Fahrt.                              */
.link-underline {
  position: relative;
  display: inline-flex;
  align-items: center;
  font-size: var(--text-l);
  line-height: var(--lh-base);
  text-decoration: none;
  padding-block-end: var(--space-2xs);
  transition: color var(--duration-base) var(--ease);
}

/* Die Linie liegt absolut statt als Rahmen: ein Rahmen, der von 1px auf 2px
   wechselt, verschiebt die Zeile um einen Pixel und ruckelt sichtbar.
   So wächst sie stattdessen weich nach oben. */
.link-underline::before {
  content: "";
  position: absolute;
  inset-block-end: 0;
  inset-inline: 0;
  block-size: var(--link-line);
  background-color: var(--color-accent-text);
  transform-origin: bottom center;
  transition: scale var(--duration-base) var(--ease),
              background-color var(--duration-base) var(--ease);
}

.link-underline::after {
  content: "";
  flex: 0 0 auto;
  inline-size: 0;
  block-size: 0.9em;
  opacity: 0;
  background-color: currentColor;
  /* Derselbe Pfeil wie in Assets/img/pfeil-rechts.svg, hier direkt als
     data-URI eingebettet: als Maske aus einer externen Datei blockieren
     Browser die Grafik beim direkten Öffnen über file:// (CORS). */
  -webkit-mask-image: url("data:image/svg+xml,<svg%20xmlns='http://www.w3.org/2000/svg'%20width='37'%20height='26'%20viewBox='0%200%2037%2026'><path%20fill='%23000'%20d='M31.6152%2012.2008V11.9561L22.3067%202.09396L22.7276%201.60352L35.31%2012.5456V13.1839L22.7276%2024.126L22.3067%2023.5866L31.6152%2013.7733V13.5287H1.8172V12.2041H31.6142L31.6152%2012.2008Z'/></svg>");
          mask-image: url("data:image/svg+xml,<svg%20xmlns='http://www.w3.org/2000/svg'%20width='37'%20height='26'%20viewBox='0%200%2037%2026'><path%20fill='%23000'%20d='M31.6152%2012.2008V11.9561L22.3067%202.09396L22.7276%201.60352L35.31%2012.5456V13.1839L22.7276%2024.126L22.3067%2023.5866L31.6152%2013.7733V13.5287H1.8172V12.2041H31.6142L31.6152%2012.2008Z'/></svg>");
  -webkit-mask-repeat: no-repeat;
          mask-repeat: no-repeat;
  -webkit-mask-position: center;
          mask-position: center;
  -webkit-mask-size: contain;
          mask-size: contain;
  transition: inline-size var(--duration-base) var(--ease),
              margin-inline-start var(--duration-base) var(--ease),
              opacity var(--duration-fast) var(--ease);
}

.link-underline:hover,
.link-underline:focus-visible {
  color: var(--color-accent-text);
}

/* Linie wächst beim Hovern auf --link-line-hover. Per scale, damit sie weich
   wächst; der Faktor ist --link-line-hover / --link-line (2px / 1px) und
   steht als Zahl da, weil eine Division zweier Längen in calc() noch nicht
   überall läuft. Wer die Werte ändert, passt die 2 hier und in den
   FAQ-Links mit an. */
.link-underline:hover::before,
.link-underline:focus-visible::before {
  scale: 1 2;
}

.link-underline:hover::after,
.link-underline:focus-visible::after {
  inline-size: 1.3em;
  margin-inline-start: 0.45em;
  opacity: 1;
}

/* --- Textlink mit vorangestelltem Pfeil ------------------------------------ */
.link-arrow {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  font-size: var(--text-xs);
  text-decoration: none;
  min-block-size: var(--tap-target);
}

.link-arrow__icon {
  flex: 0 0 auto;
  inline-size: 1.5rem;
  block-size: auto;
  transition: translate var(--duration-base) var(--ease);
}

.link-arrow:hover .link-arrow__icon,
.link-arrow:focus-visible .link-arrow__icon {
  translate: 0.375rem 0;
}

.link-arrow__text {
  --underline-drop: -0.25em;
}

/* --- Kleines Label in Schreibmaschinenschrift -------------------------------
   Versal, gesperrt, gedämpft. Trägt eine Zeile über einer Überschrift oder
   einem Namen, ohne ihr Gewicht zu nehmen.

   Hier steht NUR das Aussehen. Wie weit die Zeile von dem steht, was unter
   ihr kommt, entscheidet die Klasse daneben im Markup — im Team enger als
   über einer grossen Überschrift. */
.label-mono {
  display: block;
  color: var(--color-text-muted);
  font-family: var(--font-mono);
  font-size: 0.8125rem;                   /* 13px */
  font-weight: 400;
  letter-spacing: 0.06em;
  line-height: 1.2;
  text-transform: uppercase;
}

.section--dark .label-mono {
  color: var(--color-text-on-dark-muted);
}

/* --- Button ---------------------------------------------------------------- */
.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  inline-size: min(100%, 17.125rem);      /* 274px aus dem Design */
  min-block-size: 3.5625rem;              /*  57px, zugleich > --tap-target */
  padding: var(--space-xs) var(--space-m);
  background-color: var(--color-accent);
  color: var(--color-on-accent);
  font-size: var(--text-m);
  text-align: center;
  text-decoration: none;
  border: 0;
  transition: background-color var(--duration-fast) var(--ease);
}

.section--dark .button {
  color: var(--color-on-accent);
}

/* Auf hellen Flächen hat die orange Fläche für sich nur 2.44:1 gegen den
   Hintergrund – zu wenig, um den Knopf zweifelsfrei als Bedienelement zu
   erkennen (WCAG 1.4.11). Ein Haarstrich in der dunklen Akzentfarbe (4.75:1)
   löst das, ohne die Farbe anzufassen. Auf dunklen Flächen liegt die Fläche
   selbst bei 4.14:1 – dort braucht es ihn nicht.
   Wenn dir der Strich nicht gefällt: diese eine Regel löschen. */
.section-light .button {
  border: 1px solid var(--accent-dark);
}

.button:hover,
.button:focus-visible {
  background-color: var(--button-hover-bg);
  color: var(--button-hover-text);
}

/* --- Sektionskopf: Label links, Zweitlink rechts, Randstrich ganz aussen ---- */
.section-head {
  position: relative;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-s);
  margin-block-end: var(--space-l);
}

.section-label {
  font-family: var(--font-heading);                     /* auch als <p> (FAQs) */
  font-size: var(--text-xl);
  font-weight: 400;
}

.section-label em {
  font-weight: 300;
  font-style: italic;
}

/* Strich, der ohne Lücke am Browserrand beginnt und kurz vor dem Text endet.
   Die 50vw sind absichtlich zu lang – die Sektion hat overflow: clip und
   schneidet den Überstand am Fensterrand ab. Dadurch stimmt es auch dann,
   wenn das Fenster breiter ist als --content-width und der Inhalt zentriert
   in der Mitte steht. */
.edge-rule {
  position: absolute;
  inset-block-start: 0.85em;
  inset-inline-end: calc(100% + 1.8125rem);        /* 29px Luft vor dem Text */
  inline-size: 50vw;
  block-size: 1px;
  background-color: currentColor;
  opacity: 0.4;
}

/* Bei kleinem Seitenrand bliebe nur ein Stummel übrig – dann lieber weglassen. */
@media (width < 62em) {
  .edge-rule { display: none; }
}


/* =============================================================================
   B2) KOPFBEREICH + NAVIGATION
   ============================================================================= */

.site-header {
  /* Klebt oben am Fenster. Beim Scrollen nach unten fährt er aus dem Bild,
     beim Scrollen nach oben sofort wieder herein — gesteuert von
     navigation.js über die Klasse is-hidden. --header-shift ist der Weg;
     bei "Bewegung reduzieren" schaltet A1 die Dauer auf 0.01ms, dann
     erscheint und verschwindet er ohne Fahrt. */
  position: sticky;
  inset-block-start: 0;
  transition: translate var(--duration-base) var(--ease);
  z-index: 20;
  background-color: var(--color-primary);
  color: var(--color-text-on-dark);
  border-block-end: 1px solid var(--color-border-on-dark);
  --color-focus: var(--color-focus-on-dark);
  --color-accent-text: var(--accent-light);   /* auf dunklem Grund die helle Akzentvariante */

  /* Die Kopfhöhe steht hier als Variable, weil das mobile Menü sie braucht:
     Es liegt über der ganzen Fensterhöhe und muss seinen Inhalt genau um
     diesen Betrag nach unten schieben, damit Logo und Umschalter frei bleiben. */
  --header-block-size: 3.6875rem;                       /* 59px aus dem Design */

  /* Schriftgrösse der Menülinks im aufgeklappten mobilen Menü. */
  --menu-link-size: clamp(1.5rem, 1.2rem + 1.5vw, 2rem);    /* 24 → 32 */

  /* Seitenrand — derselbe Wert wie im Kopfbereich, damit das Menü bündig steht. */
  --header-gutter: clamp(1.25rem, -0.5rem + 5vw, 3.875rem); /* 20 → 62 */
}

/* Weggefahren. Das offene Menü hält den Kopf sichtbar (navigation.js). */
.site-header.is-hidden {
  translate: 0 -100%;
}

.site-header__inner {
  display: flex;
  align-items: center;
  gap: var(--space-m);
  min-block-size: var(--header-block-size);
  padding-inline: var(--header-gutter);
}

.site-header__logo {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  min-block-size: 1.5rem;                               /* 24px Zielfläche, WCAG 2.5.8 */
  line-height: 0;
}

.site-header__logo img {
  inline-size: clamp(7rem, 8.9vw, 8.5rem);              /* 112 → 136 (mobil 112, vorher 96) */
  block-size: auto;
}

.site-header__rule {
  flex: 0 0 auto;
  inline-size: 1px;
  block-size: 3.6875rem;
  background-color: var(--color-border-on-dark);
}

.site-header__panel {
  flex: 1 1 auto;
  display: flex;
  align-items: center;
  gap: var(--space-m);
}

.site-nav {
  flex: 1 1 auto;
  display: flex;
  justify-content: center;
}

.site-nav__list {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: clamp(1.5rem, 6.15vw, 5.8125rem);                /* 24 → 93 */
  margin: 0;
  padding: 0;                                           /* der Framework-Default für ul greift sonst durch */
}

.site-nav__item {
  margin: 0;
}

.site-nav__link,
.site-header__cta {
  display: flex;
  align-items: center;
  min-block-size: var(--tap-target);                    /* WCAG 2.5.8 */
  font-size: var(--text-xs);
  line-height: var(--lh-base);
  text-transform: uppercase;
  text-decoration: none;
  white-space: nowrap;
}

.site-nav__link {
  color: var(--color-text-on-dark);
}

.site-header__cta {
  flex: 0 0 auto;
  color: var(--color-accent-text);
}

/* Die Zielfläche ist 44px hoch, die Schrift steht mittig darin – deshalb
   wird die Linie von der Mitte aus nach unten gesetzt, nicht vom Kastenrand. */
.site-nav__link,
.site-header__cta {
  --underline-drop: calc(50% - 0.95em);
}

.site-nav__link:hover,
.site-nav__link:focus-visible,
.site-header__cta:hover,
.site-header__cta:focus-visible {
  color: var(--color-accent-text);
}

/* Die Seite, auf der man gerade ist: Linie dauerhaft sichtbar. */
.site-nav__link[aria-current="page"] {
  color: var(--color-accent-text);
}

.site-nav__link[aria-current="page"]::after {
  scale: 1 1;
}

/* Die Linien im Kopfbereich — Navigation UND "Projekt anfragen": nur 1px
   stark (statt 2px wie die übrigen hereinlaufenden Linien) und IMMER das
   helle Orange, auch im hellen Kopf (.site-header--light), wo die Schrift ins
   dunklere Orange wechselt. Die Linie ist Schmuck, nicht das einzige Merkmal:
   die Schrift wird beim Hovern bzw. auf der aktuellen Seite ebenfalls orange. */
.site-nav__link::after,
.site-header__cta::after {
  block-size: var(--link-line);
  background-color: var(--accent);
}

/* --- Umschalter für die mobile Navigation ---------------------------------- */
.site-header__toggle {
  display: none;                                        /* ab 62em unsichtbar */
  align-items: center;
  gap: var(--space-xs);
  margin-inline-start: auto;
  min-block-size: var(--tap-target);
  padding-inline: var(--space-xs);
  background: none;
  border: 0;
  color: var(--color-text-on-dark);
  font-size: var(--text-xs);
  text-transform: uppercase;
  cursor: pointer;
}

/* Zwei Striche, nicht drei. Das Element selbst ist nur der Kasten, die beiden
   Striche sind ::before (oben) und ::after (unten). Beim Aufklappen fahren
   sie in die Mitte und drehen sich dort zum Kreuz.
   --burger-gap ist der lichte Abstand zwischen den Strichen und damit auch
   der Weg, den jeder Strich zurücklegt. */
.site-header__burger {
  --burger-line: 2px;
  --burger-gap: 0.4375rem;                              /* 7px */
  position: relative;
  display: block;
  inline-size: 1.5rem;
  block-size: calc(2 * var(--burger-line) + var(--burger-gap));
}

.site-header__burger::before,
.site-header__burger::after {
  content: "";
  position: absolute;
  inset-inline: 0;
  block-size: var(--burger-line);
  background-color: currentColor;
  transition: translate var(--duration-fast) var(--ease),
              rotate    var(--duration-fast) var(--ease);
}

.site-header__burger::before { inset-block-start: 0; }
.site-header__burger::after  { inset-block-end:   0; }

/* Halber Weg für jeden Strich: Strichstärke + Zwischenraum, durch zwei. */
.site-header__toggle[aria-expanded="true"] .site-header__burger::before {
  translate: 0 calc((var(--burger-line) + var(--burger-gap)) / 2);
  rotate: 45deg;
}

.site-header__toggle[aria-expanded="true"] .site-header__burger::after {
  translate: 0 calc((var(--burger-line) + var(--burger-gap)) / -2);
  rotate: -45deg;
}

/* --- Kontaktdaten am Fuss des mobilen Menüs --------------------------------
   Ab 62em unsichtbar: auf dem Desktop steht der Kontakt in der Kontaktkarte
   und im Fussbereich, im Kopf wäre er doppelt.                              */
.site-header__contact {
  display: none;
}

/* --- Kopfbereich unter 992px ------------------------------------------------
   Das Menü liegt hier über der ganzen Fensterhöhe (100svh). Es ist fixiert,
   nicht absolut: so deckt es das Fenster unabhängig von der Scrollposition
   vollständig ab. Der Kopf selbst bleibt mit z-index darüber sichtbar,
   damit Logo und Umschalter erreichbar bleiben.                             */
@media (width < 62em) {

  .site-header__rule {
    display: none;
  }

  .site-header__toggle {
    display: inline-flex;
  }

  /* Liegen über dem Menü – sonst würde die Fläche den Umschalter verdecken.
     Der z-index muss auf die Geschwister des Menüs, nicht auf den gemeinsamen
     Elternkasten: das Menü steckt im __inner, ein z-index dort würde es
     mitnehmen. */
  .site-header__logo,
  .site-header__toggle {
    position: relative;
    z-index: 1;
  }

  .site-header__panel {
    /* --- Stellschrauben der Menü-Animation --------------------------------
       --menu-duration  wie lange die Fläche herunterfährt
       --menu-lead      Vorlauf, bevor der erste Menüpunkt nachkommt
       --menu-step      Abstand zwischen zwei Menüpunkten (die Treppe)
       --menu-tail      ANZAHL DER MENÜPUNKTE. Knopf und Kontaktdaten hängen
                        sich dahinter. Kirby: wächst das Menü, hier die Zahl
                        erhöhen — und unten eine nth-child-Zeile anfügen.
       --menu-ease      weicher Auslauf, bremst am Ende stärker ab als --ease */
    --menu-duration: 420ms;
    --menu-lead: 110ms;
    --menu-step: 55ms;
    --menu-tail: 4;
    --menu-ease: cubic-bezier(0.33, 1, 0.68, 1);

    position: fixed;
    z-index: 0;
    inset-block-start: 0;
    inset-inline: 0;
    block-size: 100vh;                  /* Rückfall für Browser ohne svh */
    block-size: 100svh;                 /* echte Fensterhöhe, ohne Browserleisten */
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    /* oben um die Kopfhöhe eingerückt, damit nichts unter dem Logo klebt */
    padding-block: calc(var(--header-block-size) + var(--space-m)) var(--space-m);
    padding-inline: var(--header-gutter);
    overflow-y: auto;                   /* falls die Liste einmal länger wird */
    overscroll-behavior: contain;
    background-color: var(--color-primary);
    border-block-end: 0;

    /* Geschlossen: die Fläche ist bis zur Oberkante zusammengeschoben und
       fährt beim Aufklappen unter dem Kopfbalken hervor nach unten.
       clip-path allein reicht nicht — innerhalb der weggeschnittenen Fläche
       blieben die Links tabulierbar und für Screenreader vorhanden. Deshalb
       zusätzlich visibility, aber erst NACH dem Zufahren geschaltet
       (Übergang 0s mit Verzögerung), sonst verschwindet alles sofort. */
    visibility: hidden;
    clip-path: inset(0 0 100% 0);
    transition: clip-path  var(--menu-duration) var(--menu-ease),
                visibility 0s linear var(--menu-duration);
  }

  .site-header__panel.is-open {
    visibility: visible;
    clip-path: inset(0 0 0 0);
    transition: clip-path  var(--menu-duration) var(--menu-ease),
                visibility 0s linear 0s;
  }

  /* --- Die Punkte kommen einzeln nach -------------------------------------
     Jeder Punkt steigt ein Stück auf und blendet ein. Die Verzögerung steht
     nur im aufgeklappten Zustand: beim Zuklappen gehen alle zusammen, eine
     rückwärts laufende Treppe fühlt sich zäh an.                           */
  .site-nav__item,
  .site-header__cta,
  .site-header__contact {
    opacity: 0;
    translate: 0 0.75rem;
    transition: opacity   var(--duration-base) var(--menu-ease),
                translate var(--duration-base) var(--menu-ease);
  }

  .is-open .site-nav__item,
  .is-open .site-header__cta,
  .is-open .site-header__contact {
    opacity: 1;
    translate: 0 0;
  }

  /* Eine Zeile je Menüpunkt. Mehr Punkte als Zeilen ist kein Fehler – die
     überzähligen erscheinen dann gemeinsam mit dem letzten hier gelisteten. */
  .is-open .site-nav__item:nth-child(1) { transition-delay: calc(var(--menu-lead) + 0 * var(--menu-step)); }
  .is-open .site-nav__item:nth-child(2) { transition-delay: calc(var(--menu-lead) + 1 * var(--menu-step)); }
  .is-open .site-nav__item:nth-child(3) { transition-delay: calc(var(--menu-lead) + 2 * var(--menu-step)); }
  .is-open .site-nav__item:nth-child(4) { transition-delay: calc(var(--menu-lead) + 3 * var(--menu-step)); }
  .is-open .site-nav__item:nth-child(5) { transition-delay: calc(var(--menu-lead) + 4 * var(--menu-step)); }
  .is-open .site-nav__item:nth-child(6) { transition-delay: calc(var(--menu-lead) + 5 * var(--menu-step)); }

  /* Knopf und Kontaktdaten hängen sich hinter den letzten Menüpunkt. */
  .is-open .site-header__cta {
    transition-delay: calc(var(--menu-lead) + var(--menu-tail) * var(--menu-step));
  }

  .is-open .site-header__contact {
    transition-delay: calc(var(--menu-lead) + (var(--menu-tail) + 1) * var(--menu-step));
  }

  /* Solange das Menü offen ist, scrollt die Seite dahinter nicht mit. */
  .is-menu-open,
  .is-menu-open body {
    overflow: hidden;
  }

  /* Die Seite dahinter wird festgehalten, OHNE ihre Position zu verlieren:
     navigation.js merkt sich die Scrollposition und setzt sie als negatives
     top. Nur overflow: hidden genügt nicht — der Browser springt dabei an
     den Seitenanfang. Der Kopf wird solange fest am Fensterrand verankert,
     sonst rutschte er mit dem festgehaltenen Inhalt nach oben weg. */
  .is-menu-open body {
    position: fixed;
    inset-inline: 0;
    inline-size: 100%;
  }

  .is-menu-open .site-header {
    position: fixed;
    inset-block-start: 0;
    inline-size: 100%;
  }

  /* Nicht mitwachsen lassen – der freie Platz gehört nach unten, zwischen
     Knopf und Kontaktdaten, nicht zwischen Liste und Knopf. */
  .site-nav {
    flex: 0 0 auto;
    display: block;
  }

  .site-nav__list {
    flex-direction: column;
    align-items: stretch;
    gap: 0;
  }

  .site-nav__item + .site-nav__item {
    border-block-start: 1px solid var(--color-border-on-dark);
  }

  /* Grosse Links. Die Zielfläche kommt jetzt aus Zeilenhöhe plus Polster,
     die 44px aus B2 werden dadurch deutlich übertroffen. */
  .site-nav__link {
    font-size: var(--menu-link-size);
    min-block-size: 0;
    padding-block: var(--space-xs);
    --underline-drop: calc(var(--space-xs) + 0.22em);
  }

  .site-header__cta {
    margin-block-start: var(--space-s);
    font-size: var(--text-m);
    --underline-drop: calc(50% - 0.8em);
  }

  /* Im mobilen Menü keine Linie beim Hovern – bei dieser Schriftgrösse wäre
     sie ein Balken. Die Farbe übernimmt die Rückmeldung, der Fokusring kommt
     unverändert aus A3. Die Linie der AKTUELLEN Seite bleibt: sie ist
     Zustand, nicht Hover, und darf nicht allein an der Farbe hängen
     (WCAG 1.4.1).                                                           */
  .site-nav__link:hover::after,
  .site-nav__link:focus-visible::after,
  .site-header__cta:hover::after,
  .site-header__cta:focus-visible::after {
    scale: 0 1;
  }

  /* Mobil keine Linie unter der aktuellen Seite (Kundenwunsch, Runde 72).
     Die aktuelle Seite erkennt man hier an der orangen Schrift; Screenreader
     bekommen sie über aria-current="page". */
  .site-nav__link[aria-current="page"]::after {
    scale: 0 1;
  }

  /* --- Kontaktdaten unten ---------------------------------------------------
     margin-block-start: auto schiebt den Block an den unteren Rand des
     Menüs. Kirby: dieselben Werte wie im Kontakt-Snippet – am besten aus
     einer Quelle (site.yml) ausgeben, damit sie nicht auseinanderlaufen.   */
  .site-header__contact {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-2xs);
    margin-block-start: auto;
    padding-block-start: var(--space-m);
    border-block-start: 1px solid var(--color-border-on-dark);
    font-size: var(--text-m);
  }

  .site-header__contact-link {
    display: inline-flex;
    align-items: center;
    min-block-size: var(--tap-target);
    color: var(--color-text-on-dark);
    text-decoration: none;
  }

  .site-header__contact-link:hover,
  .site-header__contact-link:focus-visible {
    color: var(--color-accent-text);
  }

  .site-header__contact-address {
    margin-block-start: var(--space-2xs);
    color: var(--color-text-on-dark-muted);
    font-style: normal;                   /* <address> kursiviert sonst */
    line-height: var(--lh-base);
  }
}

/* --- Aussenfelder der Kopfzeile (ab 992px) -----------------------------------
   Logo und "Projekt anfragen" sollen MITTIG in ihrem Feld stehen: das Logo
   zwischen Fensterrand und der ersten senkrechten Linie, der Knopf zwischen
   der zweiten Linie und dem rechten Fensterrand.

   Dafür trägt nicht mehr der Balken den Rand, sondern die beiden Elemente
   selbst: --header-gutter links UND rechts an Logo bzw. Knopf, Abstände
   (gap) dazwischen auf 0. Damit ist jedes Feld so breit wie sein Inhalt plus
   zweimal derselbe Rand — also ist der Inhalt mittig. Die Navigation hält
   sich mit einem eigenen Innenabstand von den Linien frei.                  */
@media (width >= 62em) {
  .site-header__inner {
    gap: 0;
    padding-inline: 0;
  }

  .site-header__panel {
    gap: 0;
  }

  .site-header__logo,
  .site-header__cta {
    padding-inline: var(--header-gutter);
  }

  .site-nav {
    padding-inline: var(--space-m);
  }

  /* Die Hover-Linie gehört unter den TEXT, nicht unter den neuen Rand. */
  .site-header__cta::after {
    inset-inline: var(--header-gutter);
  }
}


/* =============================================================================
   B3) HERO
   ============================================================================= */

.hero {
  /* --hero-lift steuert, wie hoch Überschrift UND Bildband über der Unterkante
     sitzen – eine Stellschraube für beide.

     Der Wert hängt an der FENSTERHÖHE, nicht an der Breite. Vorher war er fest:
     dadurch stand der Inhalt auf einem hohen Schirm bei 65 % der Herohöhe, auf
     einem flachen 14-Zoll-Notebook aber schon bei 45 % — gleicher Abstand nach
     unten, völlig anderer Eindruck. Mit 19 svh sitzt er überall an derselben
     Stelle im Bild. Die Obergrenze entspricht dem bisherigen Wert, damit sich
     auf grossen Schirmen nichts ändert.

     Die erste Zeile ist der Rückfall für Browser ohne svh. */
  --hero-lift: 15.75rem;
  --hero-lift: clamp(6rem, 19svh, 15.75rem);

  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  min-block-size: 100vh;                                /* Fallback für ältere Browser */
  min-block-size: 100svh;                               /* volle Fensterhöhe, ohne Sprung durch die mobile Browserleiste */
  padding-block-end: var(--hero-lift);
  padding-inline: var(--gutter);
  overflow: clip;
}

/* Vektor-Signet oben rechts. Datei liegt aktuell leer vor — siehe index.html. */
.hero__signet {
  position: absolute;
  inset-block-start: clamp(1.25rem, 3.4vw, 3.25rem);
  inset-inline-end: clamp(1rem, 17.5vw, 16.5625rem);
  inline-size: clamp(7rem, 15.3vw, 14.5rem);            /* 112 → 232 */
  block-size: auto;
}

/* --- Bildband hinter der Überschrift ----------------------------------------
   Vorbild: bergwerk-gestaltung.de. Eine Reihe Bilder, die endlos und sehr
   langsam nach links läuft, stark zurückgenommen, damit sie Fläche bleibt und
   nicht mit der Überschrift konkurriert.

   Drei Stellschrauben:
     --hero-band-drop   wie hoch das Band über der Unterkante des Inhalts sitzt
     --hero-band-fade   wie stark es zurückgenommen ist
     HERO_BAND_SPEED    Tempo in Pixel pro Sekunde (animations.js, Abschnitt 1d)

   Ohne JavaScript oder mit "Bewegung reduzieren" steht das Band still — es ist
   dann einfach eine ruhige Bildreihe. */
.hero__band {
  --hero-band-drop: 8rem;
  /* Wie stark das Band zurückgenommen ist. Mehr geht: bis 0.24 behält die
     Überschrift auch über dem hellsten denkbaren Bildpixel noch 4.5:1.
     Darüber wird die Fläche zu unruhig für weisse Schrift. */
  --hero-band-fade: 0.18;

  position: absolute;
  inset-inline: 0;
  inset-block-end: calc(var(--hero-lift) + var(--hero-band-drop));
  z-index: 0;
  opacity: var(--hero-band-fade);
  pointer-events: none;
  /* Bewusst OHNE eigenes overflow: clip — die Bilder fahren beim Einblenden von
     unten herein und würden sonst an der Kante abgeschnitten. Den Überstand
     nach rechts schneidet .hero ohnehin ab. */
}

.hero__band-track {
  display: flex;
  gap: clamp(0.5rem, 2vw, 1.875rem);                    /* 8 → 30 */
  inline-size: max-content;
}

.hero__band-image {
  flex: 0 0 auto;
  inline-size: clamp(17rem, 39vw, 36.5rem);             /* 272 → 584 (mobil vorher 224) */
  block-size: auto;
  aspect-ratio: 16 / 10;
  object-fit: cover;
  border-radius: var(--radius-l);
}

/* --- Bildband als eigener Abschnitt (Webdesign) ------------------------------
   Dieselbe Reihe wie .hero__band oben, aber in voller Deckkraft, im Fluss
   statt absolut hinter einer Überschrift, und von Fensterrand zu Fensterrand.
   Bewegung: animations.js, Abschnitt 1d (dasselbe Band, derselbe Takt).
   Ohne JavaScript steht es still; der Überstand rechts wird abgeschnitten. */
.image-band {
  padding-block: var(--space-l) 0;
  overflow: clip;
}

/* Mit Animation lässt sich das Band greifen und verschieben (animations.js,
   Abschnitt 1d) — der Greifhand-Zeiger zeigt das an. touch-action: pan-y
   hält senkrechtes Wischen frei, damit auf dem Handy die Seite scrollt. */
.anim .image-band {
  cursor: grab;
  touch-action: pan-y;
  user-select: none;
}

.anim .image-band.is-dragging {
  cursor: grabbing;
}

/* Sonst zieht der Browser beim Greifen das Bild als Datei aus der Seite. */
.anim .image-band img {
  -webkit-user-drag: none;
}

.image-band__track {
  display: flex;
  gap: clamp(0.5rem, 2vw, 1.875rem);                    /* wie .hero__band-track */
  inline-size: max-content;
}

.image-band__image {
  flex: 0 0 auto;
  inline-size: clamp(17rem, 39vw, 36.5rem);             /* wie .hero__band-image */
  block-size: auto;
  aspect-ratio: 16 / 10;
  object-fit: cover;
  border-radius: var(--radius-l);
}


.hero__content {
  position: relative;
  z-index: 1;
  inline-size: 100%;
  max-inline-size: 46.25rem;                            /* 740px aus dem Design */
  text-align: center;
}

.hero__title {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-s);
  color: var(--color-text-on-dark);
}

.hero__title-main {
  font-size: var(--h1);
  font-weight: 900;
  line-height: 0.99;
}

.hero__title-sub {
  font-size: var(--text-m);
  font-weight: 400;
  line-height: var(--lh-base);
}

.hero__scroll {
  position: absolute;
  inset-block-end: var(--space-xl);
  inset-inline-end: clamp(1rem, 5.42vw, 5.125rem);
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  inline-size: var(--tap-target);
  block-size: var(--tap-target);
}

.hero__scroll img {
  inline-size: clamp(1.125rem, 1.7vw, 1.625rem);        /* 18 → 26 */
  block-size: auto;
}

@media (width < 62em) {
  .hero {
    /* Mobil sitzen Überschrift und Bildband höher als die reine Formel oben
       ergäbe — der zusätzliche --space-l hebt beides gemeinsam an. */
    --hero-lift: calc(var(--space-xl) + var(--space-m) + var(--space-l));
    padding-block-start: var(--space-xl);
  }

  /* Mobil sitzt der Pfeil mittig statt am rechten Rand. */
  .hero__scroll {
    inset-inline: 0;
    margin-inline: auto;
  }
}


/* =============================================================================
   B4) ÜBER UNS + TEAM
   ============================================================================= */

.intro {
  background-color: var(--color-surface);
  padding-block: var(--space-xl);

  /* Zusätzlicher Einzug der Intro-Sektion, EINE Stellschraube für die Breite.
     Der volle --inset (bis 144px) aus dem Screendesign liess die Textspalte
     auf grossen Schirmen schmaler wirken als alles andere auf der Seite.
     Ein Viertel davon bleibt als Andeutung stehen; auf 0 gestellt steht die
     Sektion bündig mit Projekten und Leistungen. */
  --intro-inset: var(--inset-narrow);

  /* Breite der beiden Spalten INNERHALB des Rasters. Die Sektion selbst
     bleibt so breit wie sie ist — nur der Inhalt rückt zusammen.
     --intro-team-width verkleinert Portraits UND die Textspalte daneben im
     selben Verhältnis, weil beide im selben Raster liegen. */
  --intro-text-width: 90%;
  --intro-team-width: 90%;
}

.intro__inner {
  padding-inline: var(--intro-inset);
  display: grid;
  gap: var(--space-xl) clamp(1.5rem, 5.82vw, 5.5rem);   /* Spaltenabstand 24 → 88 */
}

.intro__title {
  font-size: var(--h2);
  font-weight: 900;
}

.intro__title em {
  font-weight: 300;
  font-style: italic;
}

/* Label über der grossen Überschrift. Mehr Luft als im Team, weil darunter
   eine 48-px-Zeile folgt und keine 17-px-Zeile. */
.intro__label {
  margin-block-end: var(--space-s);
}

.intro__copy {
  margin-block-start: var(--space-m);
  max-inline-size: var(--measure);
  font-size: var(--text-l);
}

.intro__copy > p + p {
  margin-block-start: var(--space-s);
}

.intro__text > .link-underline {
  margin-block-start: var(--space-m);
}

/* --- Team ------------------------------------------------------------------- */
.team {
  display: grid;
  align-content: start;
  gap: var(--space-m);
  margin: 0;
  padding: 0;
}

/* Mobil stehen die Portraits untereinander — dort braucht es mehr Luft
   zwischen den beiden Personen. */
@media (width < 62em) {
  .team {
    gap: var(--space-l);
  }
}

.team__member {
  display: grid;
  grid-template-columns: minmax(0, 236fr) minmax(0, 255fr);
  align-items: center;
  gap: clamp(0.75rem, 1.8vw, 1.6875rem);                /* 12 → 27 */
  margin: 0;
}

.team__photo {
  inline-size: 100%;
  aspect-ratio: 236 / 224;
  object-fit: cover;
  border-radius: var(--radius-l);
}

/* Tätigkeitsbereich über dem Namen. Das Aussehen kommt aus .label-mono (B1),
   hier steht nur der Abstand. */
.team__role-label {
  margin-block-end: var(--space-2xs);
  color: var(--color-accent-text);                      /* orange wie die Kleinüberschriften */
}

.team__name {
  font-size: var(--text-m);
  font-weight: 900;
}

.team__role {
  margin-block-start: var(--space-xs);
  font-size: var(--text-xs);
}

@media (width >= 62em) {
  .intro__inner {
    grid-template-columns: minmax(0, 399fr) minmax(0, 518fr);
  }

  /* Erst ab der zweispaltigen Ansicht. Darunter stehen beide untereinander
     und sollen die volle Breite haben. */
  .intro__text {
    max-inline-size: var(--intro-text-width);
  }

  /* Im Screendesign setzen die Portraits deutlich tiefer an als die Textspalte
     (im Frame 340 px unterhalb der Überschrift). */
  .team {
    max-inline-size: var(--intro-team-width);
    padding-block-start: calc(var(--space-2xl) + var(--space-xl) + var(--space-m));
  }
}

/* Unterhalb der zweispaltigen Ansicht wird die Textspalte breit – das Portrait
   soll dann nicht mitwachsen, sondern bei seiner Designgrösse bleiben. */
@media (width < 62em) {
  .team__member {
    grid-template-columns: minmax(0, 14.75rem) minmax(0, 1fr);
  }

  .team__photo {
    aspect-ratio: 1 / 1;                                /* mobil quadratisch */
  }
}

@media (width < 36em) {
  .team__member {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-s);
  }

  /* Untereinander: nicht über die volle Breite, sondern so gross wie im
     zweispaltigen Stand darüber (236px). */
  .team__photo {
    inline-size: min(100%, 14.75rem);
  }
}


/* =============================================================================
   B5) PROJEKTE
   ============================================================================= */

.projects {
  background-color: var(--color-surface-soft);
  padding-block: var(--space-xl);
  overflow: clip;                                       /* schneidet den Überstand des .edge-rule ab */
}

.project-list {
  /* Alle Kacheln sind gleich hoch – im Frame 533 px. Die Bilder füllen die
     Höhe per object-fit, unabhängig davon wie breit die Kachel ist. */
  --project-height: clamp(14rem, 35.2vw, 33.3125rem);   /* 224 → 533 */

  display: grid;
  gap: clamp(1.5rem, 4vw, 3.75rem);                     /* 24 → 60 */
  margin: 0;
  padding: 0;
}

.project {
  margin: 0;
}

.project__link {
  display: block;
  color: inherit;
  text-decoration: none;
}

.project__media {
  position: relative;
  display: block;
  block-size: var(--project-height);
  overflow: hidden;
}

/* Zwei bis drei Bilder liegen übereinander. Ohne JavaScript ist nur das
   erste sichtbar; beim Hovern blendet animations.js sie durch. */
.project__frame {
  position: absolute;
  inset-block-start: 0;
  inset-inline: 0;
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
  opacity: 0;
}

.project__frame:first-child {
  opacity: 1;
}

.project__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-xs);
  margin-block-start: var(--space-xs);
  font-size: var(--text-xs);                            /* wie der Text an den Portraits (.team__role) */
}

.project__client {
  color: var(--color-text);
}

.project__name {
  color: var(--color-text-muted);
  text-align: end;
}

.project__client {
  --underline-drop: -0.3em;
}

/* Hover-Linie unter dem Kunden: in Orange und nur 1px — feiner als bei den
   übrigen hereinlaufenden Linien, der Text selbst bleibt dunkel. */
.project__client::after {
  block-size: var(--link-line);
  background-color: var(--color-accent-text);
}

/* Mobil: Rhythmus quer – zwei hoch nebeneinander – quer – …
   Hier zählt die POSITION in der Liste, nicht die Klasse narrow/wide:
   jede 1., 4., 7. … Kachel geht über die volle Breite im Querformat, die
   beiden danach teilen sich eine Zeile im Hochformat. So bleibt der
   Rhythmus bei jeder Anzahl und jeder Reihenfolge der Projekte erhalten
   (Kirby muss nichts wissen). Die Höhe kommt hier aus dem Seitenverhältnis
   statt aus --project-height. */
@media (width < 48em) {
  .project-list {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: var(--space-s);
    row-gap: calc(var(--space-m) + var(--space-xs));    /* Luft zwischen den Kacheln, ~40px */
  }

  /* Kunde und Projektname untereinander, beide links unter dem Bild —
     nebeneinander wurde es in den halbbreiten Kacheln zu eng. */
  .project__meta {
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-2xs);
  }

  .project__name {
    text-align: start;
  }

  .project:nth-child(3n + 1) {
    grid-column: 1 / -1;
  }

  .project__media {
    block-size: auto;
    aspect-ratio: 431 / 533;                            /* hoch, wie im Design */
  }

  .project:nth-child(3n + 1) .project__media {
    aspect-ratio: 776 / 533;                            /* quer, wie im Design */
  }
}

/* 8 Spalten: schmal = 3, breit = 5. Das trifft die Kachelbreiten aus dem
   Design (431 / 776 px bei 1272 px Inhalt) auf rund 2 % genau. */
@media (width >= 48em) {
  .project-list {
    grid-template-columns: repeat(8, minmax(0, 1fr));
  }

  .project--narrow { grid-column: span 3; }
  .project--wide   { grid-column: span 5; }
}


/* =============================================================================
   B6) LEISTUNGEN
   ============================================================================= */

.services {
  padding-block: var(--space-xl);
  overflow: clip;                                       /* schneidet den Überstand des .edge-rule ab */
}

.services__body {
  padding-inline-start: var(--inset);
  display: grid;
  gap: var(--space-l) var(--space-xl);
}

/* Der Text links steht so weit vom Rand wie der Intro-Text ("kurze Wege, …"):
   --inset-narrow statt des vollen --inset. Die Liste rechts bleibt, wo sie
   ist — deshalb wird nur dieser Block per negativem Rand nach links gezogen,
   nicht der Einzug der ganzen Sektion geändert. */
.services__intro {
  margin-inline-start: calc(var(--inset-narrow) - var(--inset));
}

.services__lead {
  font-size: var(--text-l);
  max-inline-size: var(--measure);
}

.services__intro > .link-underline {
  margin-block-start: var(--space-l);
}

.service-list {
  display: grid;
  margin: 0;
  padding: 0;
}

.service {
  margin: 0;
  border-block-start: 1px solid var(--color-border-on-dark);
}

.service:last-child {
  border-block-end: 1px solid var(--color-border-on-dark);
}

.service__link {
  display: block;
  padding-block: var(--space-m);
  padding-inline-start: var(--space-m);   /* Trennlinien laufen im Design weiter nach links als der Text */
  color: var(--color-text-on-dark);
  text-decoration: none;
}

.service__title {
  display: flex;
  align-items: center;
  gap: var(--space-s);
  font-size: var(--h3);
  font-weight: 900;
  transition: color var(--duration-base) var(--ease);
}

.service__arrow {
  flex: 0 0 auto;
  inline-size: clamp(1.5rem, 2.4vw, 2.3125rem);         /* 24 → 37 */
  block-size: auto;
  transition: translate var(--duration-base) var(--ease);
}

.service__link:hover .service__arrow,
.service__link:focus-visible .service__arrow {
  translate: 0.5rem 0;
}

.service__link:hover .service__title,
.service__link:focus-visible .service__title {
  color: var(--color-accent-text);
}

.service__text {
  margin-block-start: var(--space-xs);
  max-inline-size: 32rem;
  font-size: var(--text-l);
}

@media (width >= 62em) {
  .services__body {
    grid-template-columns: minmax(0, 357fr) minmax(0, 612fr);
  }
}


/* =============================================================================
   B7) KONTAKT
   ============================================================================= */

.contact {
  padding-block: var(--space-l) 0;
}

/* Leistungen und Kontakt sind beide dunkel und gehen ineinander über. Zweimal
   der volle Sektionsabstand wirkte dort zu luftig — deshalb oben am Kontakt
   nur der kleinere Abstand, wenn er direkt auf die Leistungen folgt. */
.services + .contact {
  padding-block-start: var(--space-m);
}

.contact__card {
  background-color: var(--color-surface-dark);
  border-radius: var(--radius-l);
  padding: clamp(1.75rem, 6.6vw, 6.25rem) clamp(1.5rem, 7.6vw, 7.1875rem);
  display: grid;
  gap: var(--space-l) var(--space-xl);
}

/* Mobil etwas mehr Luft über „Bereit für dein neues Projekt?" (vorher 28px). */
@media (width < 48em) {
  .contact__card {
    padding-block-start: var(--space-l);
  }
}

.contact__title {
  font-size: var(--h2);
  font-weight: 900;
}

.contact__lead {
  margin-block-start: var(--space-m);
  max-inline-size: 27rem;
  color: var(--bw-100);
}

.contact__details {
  margin-block-start: var(--space-xl);
  display: grid;
  gap: var(--space-m);
}

.contact__detail {
  display: grid;
  gap: var(--space-2xs);
}

.contact__label {
  font-family: var(--font-heading);
  font-size: var(--text-m);
  font-weight: 900;
  color: var(--color-text-on-dark-muted);
}

/* Lange Adressen (z. B. salve@partanumdesign.de) sind EIN Wort. In der
   grossen, sehr breit laufenden Schrift passen sie auf schmalen Schirmen
   nicht in eine Zeile — deshalb dürfen sie dort umbrechen, statt die Karte
   auseinanderzuschieben. min-inline-size: 0 an den Rasterkästen darüber,
   sonst schrumpfen sie nicht unter ihren Inhalt. */
.contact__value {
  margin: 0;
  min-inline-size: 0;
  overflow-wrap: anywhere;
  font-family: var(--font-heading);
  font-size: var(--h4);
  font-weight: 900;
  line-height: var(--lh-heading);
}

.contact__main,
.contact__details,
.contact__detail {
  min-inline-size: 0;
}

/* Auf schmalen Schirmen eine Stufe kleiner, damit die Adresse hinter dem
   Umbruch am @ (siehe <wbr> im Markup) in eine Zeile passt. */
@media (width < 36em) {
  .contact__value {
    font-size: var(--h5);
  }
}

.contact__value a {
  color: var(--color-text-on-dark);
  text-decoration: none;
}

.contact__value a {
  --underline-drop: -0.12em;
}

.contact__value a:hover,
.contact__value a:focus-visible {
  color: var(--color-accent-text);
}

.contact__main > .button {
  margin-block-start: var(--space-m);
}

.contact__image {
  inline-size: min(100%, 14rem);                        /* 224px */
  aspect-ratio: 1;
  object-fit: cover;
  border-radius: var(--radius-l);
}

.contact__address {
  margin-block-start: var(--space-m);
  font-style: normal;
  color: var(--bw-100);
}

.contact__address p + p {
  margin-block-start: var(--space-s);
}

.contact__aside > .link-arrow {
  margin-block-start: var(--space-s);
  color: var(--bw-100);
}

@media (width >= 62em) {
  .contact__card {
    grid-template-columns: minmax(0, 534fr) minmax(0, 427fr);
  }
}


/* =============================================================================
   B8) FUSSBEREICH
   ============================================================================= */

.site-footer {
  padding-block: calc(var(--space-l) + var(--space-s)) var(--space-m);   /* 96 px bei 1512 */
}

/* Reihenfolge im Fuss: Schriftzug, darunter die Links, darunter Copyright. */
.site-footer__top {
  margin-block-start: var(--space-m);
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-s);
}

.inline-list {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0;
  margin: 0;
  padding: 0;
  font-size: var(--text-xs);
}

.inline-list li {
  margin: 0;
}

.inline-list li + li::before {
  content: "|";
  padding-inline: 0.7em;
  color: var(--color-text-on-dark-muted);
}

.inline-list a {
  --underline-drop: -0.3em;

  /* inline-flex + 24px: die Links im Fuss sind eigenständige Ziele und
     brauchen mindestens 24 x 24 px (WCAG 2.5.8). */
  display: inline-flex;
  align-items: center;
  min-block-size: 1.5rem;
  color: var(--color-text-on-dark);
  text-decoration: none;
}

.inline-list a:hover,
.inline-list a:focus-visible {
  color: var(--color-accent-text);
}

.site-footer__wordmark {
  inline-size: 100%;                      /* volle Inhaltsbreite, wie der Rest im .container */
  max-inline-size: none;
  block-size: auto;
  /* Die Datei ist volles Beige; hier nur angedeutet, wie eine Struktur im
     Grund. filter statt opacity, weil die Einblend-Animation (data-anim="fade")
     opacity selbst setzt. Rein dekorativ (alt=""), daher kein Kontrastwert. */
  --wordmark-strength: 4%;
  filter: opacity(var(--wordmark-strength));
}

.site-footer__copyright {
  margin-block-start: var(--space-s);
  font-size: var(--text-xs);
  color: var(--color-text-on-dark-muted);
}


/* =============================================================================
   B9) ANIMATIONEN
   Alles hier greift NUR, wenn <html> die Klasse "anim" trägt. Die setzt das
   kleine Skript im <head> von index.html – und zwar nur, wenn der Nutzer
   keine reduzierte Bewegung eingestellt hat. js/animations.js nimmt die
   Klasse ausserdem wieder weg, falls GSAP nicht geladen werden konnte.
   Ergebnis: ohne JavaScript, ohne GSAP oder mit "Bewegung reduzieren" ist die
   Seite sofort vollständig sichtbar – hier steht nichts, was das verhindert.

   Die zu animierenden Elemente sind im Markup mit data-anim="…" markiert:
     fade      einblenden
     fade-up   einblenden und leicht hochfahren
     reveal    Überschrift fährt hinter einer Maske herein
     words     Wort für Wort aus der Maske hochfahren (nur Hero-Headline)
     line      Strich von rechts nach links aufziehen
     draw      SVG-Pfade nachzeichnen (Wortmarke im Hero)
     image-reveal  Bild wird von unten nach oben aufgedeckt und zoomt dabei
               leicht heraus
     stagger   die direkten Kinder nacheinander einblenden
   ============================================================================= */

.anim [data-anim="fade"],
.anim [data-anim="fade-up"],
.anim [data-anim="reveal"],
.anim [data-anim="words"],
.anim [data-anim="draw"],
.anim [data-anim="stagger"] > * {
  opacity: 0;
}

/* Bilder bleiben sichtbar und werden stattdessen von unten aufgedeckt –
   sonst blitzt beim Start der Maske kurz nichts auf. */
.anim [data-anim="image-reveal"] {
  clip-path: inset(100% 0% 0% 0%);
}

/* Maske für "reveal": animations.js packt den Inhalt in .reveal__inner und
   fährt ihn von unten herein. Das Polster unten lässt Unterlängen heil, die
   negative Aussenkante nimmt ihm den Einfluss auf den Abstand danach. */
.anim [data-anim="reveal"] {
  overflow: hidden;
  padding-block-end: 0.2em;
  margin-block-end: -0.2em;
}

.reveal__inner {
  display: block;
}

/* Der Strich behält seine Deckkraft und wird stattdessen aufgezogen. */
.anim [data-anim="line"] {
  transform: scaleX(0);
  transform-origin: right center;
}

/* Wortweise Maske für die Hero-Überschrift. Die Spans setzt animations.js.
   Das Polster unten lässt Unterlängen (das g in "Webdesign") heil, die
   negative Aussenkante nimmt dem Polster den Einfluss auf die Zeilenhöhe. */
.hero__title .word,
.case-hero__project .word {
  display: inline-block;
  overflow: hidden;
  vertical-align: bottom;
  padding-block-end: 0.16em;
  margin-block-end: -0.16em;
}

.hero__title .word__inner,
.case-hero__project .word__inner {
  display: inline-block;
}

/* --- Kreiskontur um den Mauszeiger (Projektkacheln) ------------------------
   Nur ein Ring; der echte Mauszeiger bleibt sichtbar und sitzt in der Mitte. */
.cursor-badge {
  position: fixed;
  inset-block-start: 0;
  inset-inline-start: 0;
  z-index: 60;
  inline-size: 7.5rem;
  block-size: 7.5rem;
  margin-block-start: -3.75rem;                /* zentriert den Ring auf dem Zeiger */
  margin-inline-start: -3.75rem;
  border: 1.5px solid var(--color-accent);
  border-radius: var(--radius-pill);
  pointer-events: none;
  opacity: 0;
  visibility: hidden;
}



/* =============================================================================
   B10) UNTERSEITEN
   Bausteine, die es nur auf den Leistungsseiten gibt (webdesign.html).
   Header, Projektkacheln, Kontaktkarte und Fussbereich kommen unverändert
   aus B2, B5, B7 und B8 — hier steht nur, was dazukommt.
   ============================================================================= */

/* Mehrere Sektionen hintereinander auf demselben hellen Ton: die Übergänge
   sind dadurch unsichtbar, es wirkt wie eine Fläche. Deshalb trägt jede
   Sektion ihr Innenmass selbst und diese Klasse nur die Farbe. */
.section-light {
  background-color: var(--color-surface);
}

.section-head--single {
  justify-content: flex-start;
}

/* Kleines Label über einer Liste, in Akzentfarbe. */
.eyebrow {
  margin-block-end: var(--space-l);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  line-height: 1.27;
  text-transform: uppercase;
  color: var(--color-accent-text);
}


/* --- Grosses Statement ----------------------------------------------------- */
.statement-section {
  padding-block: var(--space-xl) var(--space-l);
}

.statement {
  margin-block-start: var(--space-l);
  margin-inline-start: auto;                            /* rechtsbündig im Raster */
  max-inline-size: 61.3125rem;                          /* 981px aus dem Frame */
  font-size: var(--text-statement);
  line-height: 1.31;
  text-align: end;
  text-wrap: balance;
}

/* Ohne Label davor (Webdesign) kein zusätzlicher Abstand oben — der
   Sektionsabstand reicht. */
.statement:first-child {
  margin-block-start: 0;
}

/* Rechtsbündiger Fliesstext liest sich auf dem Handy schlecht. */
@media (width < 48em) {
  .statement { text-align: start; }
}


/* --- Haltung + Skills ------------------------------------------------------ */
.approach {
  padding-block: var(--space-l);
}

/* Einzug, Spaltenraster und Spaltenbreiten wie beim Intro der Startseite
   (B4): gleicher Abstand nach links, gleich breite Textspalte. Der Einzug
   hängt am selben Token (--inset-narrow) und geht mit; Raster und die
   90 % sind hier abgeschrieben — wer das Intro ändert, ändert sie mit. */
.approach__inner {
  padding-inline: var(--inset-narrow);
  display: grid;
  gap: var(--space-xl) clamp(1.5rem, 5.82vw, 5.5rem);   /* wie .intro__inner */
}

.approach__copy > p + p {
  margin-block-start: var(--space-s);
}

.approach__text > .link-underline {
  margin-block-start: var(--space-m);
}

.skill-list {
  display: grid;
  margin: 0;
  padding: 0;
}

.skill {
  display: flex;
  align-items: start;                                   /* Haken sitzt auf der ersten Zeile,
                                                           auch wenn der Text umbricht */
  gap: 1.375rem;                                        /* 22px aus dem Frame */
  margin: 0;
  padding-block: var(--space-s);
  border-block-start: 1px solid var(--color-border);
  font-size: var(--text-l);
}

.skill:last-child {
  border-block-end: 1px solid var(--color-border);
}

/* Haken statt Pfeil: ein Pfeil zeigt irgendwohin, hier geht es aber um eine
   Eigenschaft. Bewusst dünn und mit eckigen Enden gezeichnet, damit er zu den
   Haarlinien der Seite passt und nicht wie ein Standard-Icon wirkt.
   Als Maske eingesetzt, damit er die Farbe aus dem CSS nimmt – und als
   data-data:image/svg+xml,<svg%20xmlns='http://www.w3.org/2000/svg'%20width='28'%20height='22'%20viewBox='0%200%2028%2022'%20fill='none'><path%20d='M1%2011.6%20L9.2%2019.8%20L27%202'%20stroke='%23000'%20stroke-width='1.4'%20stroke-linecap='square'%20stroke-linejoin='miter'/></svg>, weil eine externe Maskendatei beim Öffnen über file:// an CORS
   scheitert. Die Form steckt im url(): ein Pfad, ein Strich. */
.skill__icon {
  flex: 0 0 auto;
  margin-block-start: 0.12em;                           /* mittig zur ersten Textzeile */
  inline-size: clamp(1.25rem, 1.85vw, 1.75rem);         /* 20 → 28 */
  block-size: clamp(1rem, 1.45vw, 1.375rem);            /* 16 → 22 */
  background-color: var(--color-accent-text);
  -webkit-mask-image: url("data:image/svg+xml,<svg%20xmlns='http://www.w3.org/2000/svg'%20width='28'%20height='22'%20viewBox='0%200%2028%2022'%20fill='none'><path%20d='M1%2011.6%20L9.2%2019.8%20L27%202'%20stroke='%23000'%20stroke-width='1.4'%20stroke-linecap='square'%20stroke-linejoin='miter'/></svg>");
          mask-image: url("data:image/svg+xml,<svg%20xmlns='http://www.w3.org/2000/svg'%20width='28'%20height='22'%20viewBox='0%200%2028%2022'%20fill='none'><path%20d='M1%2011.6%20L9.2%2019.8%20L27%202'%20stroke='%23000'%20stroke-width='1.4'%20stroke-linecap='square'%20stroke-linejoin='miter'/></svg>");
  -webkit-mask-repeat: no-repeat;
          mask-repeat: no-repeat;
  -webkit-mask-position: center;
          mask-position: center;
  -webkit-mask-size: contain;
          mask-size: contain;
}

@media (width >= 62em) {
  .approach__inner {
    grid-template-columns: minmax(0, 399fr) minmax(0, 518fr);   /* wie .intro__inner */
  }

  .approach__text {
    max-inline-size: 90%;                                /* wie --intro-text-width */
  }

  .approach__skills {
    max-inline-size: 90%;                                /* wie --intro-team-width */
  }
}


/* --- Vier Schritte ---------------------------------------------------------
   Die grosse Ziffer liegt als Wasserzeichen hinter dem Wort "Schritt". */
.steps {
  padding-block: var(--space-l);
}

.step-list {
  display: grid;
  gap: var(--space-l) clamp(1.5rem, 5vw, 4.75rem);      /* Spaltenabstand 24 → 76 */
  margin: 0;
  padding: 0;
  padding-block: var(--space-xl);
  border-block: 1px solid var(--color-border);
  list-style: none;
}

.step {
  margin: 0;
}

.step__marker {
  position: relative;
  display: flex;
  align-items: center;
  min-block-size: 5.125rem;                             /* 82px aus dem Frame */
  margin-block-end: var(--space-m);
}

.step__number {
  position: absolute;
  inset-inline-start: 45%;
  inset-block-start: 50%;
  translate: -50% -50%;
  font-family: var(--font-heading);
  font-weight: 900;
  font-size: clamp(3.5rem, 6vw, 5.625rem);              /* 56 → 90 */
  line-height: var(--lh-heading);
  color: rgb(49 60 68 / 0.07);
  pointer-events: none;
}

.step__label {
  position: relative;
  padding-inline-start: var(--space-m);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  line-height: 1.27;
  text-transform: uppercase;
  color: var(--color-accent-text);
}

.step__text {
  font-size: var(--text-s);
}

/* Unter 992px werden die Spalten breit, 45 % davon rückte die Ziffer weit
   vom Wort „Schritt" weg. Hier steht sie deshalb in festem Abstand zum
   Anfang und überlappt das Wort wie auf dem Desktop. */
@media (width < 62em) {
  .step__number {
    inset-inline-start: 5.5rem;
  }
}

/* Mobil weniger Luft zwischen „Schritt 01" und dem Text darunter. Die Höhe
   bleibt stehen: die Ziffer liegt absolut darin und würde sonst in den Text
   ragen — nur knapp über ihre eigene Zeilenhöhe zurückgenommen. */
@media (width < 48em) {
  .step__marker {
    min-block-size: 4rem;
    margin-block-end: var(--space-xs);
  }
}

@media (width >= 48em) and (width < 62em) {
  .step-list { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (width >= 62em) {
  .step-list { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}


/* --- FAQ -------------------------------------------------------------------
   <details>/<summary> statt eigener Akkordeon-Logik: nativ bedienbar mit
   Tastatur und Screenreader, funktioniert auch ohne JavaScript. */
.faq {
  padding-block: var(--space-xl);
  overflow: clip;                                       /* schneidet den .edge-rule ab */
}

.faq__inner {
  display: grid;
  gap: var(--space-l);
}

.faq__title {
  max-inline-size: 37.5rem;                             /* 600px aus dem Frame */
  font-size: var(--h2);
  font-weight: 900;
  line-height: 1.25;                                    /* etwas luftiger als --lh-heading (1.1) */
}

.faq__title em {
  font-weight: 300;
  font-style: italic;
}

.faq-list {
  display: grid;
}

.faq-item {
  border-block-start: 1px solid var(--color-border-on-dark);
}

.faq-item:last-child {
  border-block-end: 1px solid var(--color-border-on-dark);
}

.faq-item__question {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-s);
  padding-block: var(--space-m);
  font-size: var(--h5);                                 /* 18 → 22, vorher --h4 (20 → 26) */
  line-height: var(--lh-base);
  color: var(--color-text-on-dark);
  list-style: none;                                     /* Standard-Dreieck weg */
  cursor: pointer;
  transition: color var(--duration-base) var(--ease);
}

.faq-item__question::-webkit-details-marker {
  display: none;
}

.faq-item__question:hover {
  color: var(--color-accent-text);
}

/* Plus, das sich beim Öffnen zum Minus dreht. */
.faq-item__icon {
  position: relative;
  flex: 0 0 auto;
  inline-size: 1.6875rem;                               /* 27px aus dem Frame */
  block-size: 1.6875rem;
}

.faq-item__icon::before,
.faq-item__icon::after {
  content: "";
  position: absolute;
  inset-block-start: 50%;
  inset-inline-start: 0;
  inline-size: 100%;
  block-size: 1px;
  background-color: currentColor;
  transition: rotate var(--duration-base) var(--ease);
}

.faq-item__icon::after {
  rotate: 90deg;
}

.faq-item[open] .faq-item__icon::after {
  rotate: 180deg;
}

.faq-item__answer {
  padding-block-end: var(--space-m);
  max-inline-size: var(--measure);
}

/* Link mitten in einer Antwort. Farbe allein genügt nicht, um ihn als Link zu
   erkennen (WCAG 1.4.1) – deshalb eine dauerhafte Linie, die beim Hovern
   dicker wird. Dasselbe Verhalten wie bei .link-underline, nur ohne Pfeil,
   weil der Link hier im Satz steht. */
.faq-item__answer a {
  position: relative;
  color: var(--color-accent-text);
  text-decoration: none;
  transition: color var(--duration-base) var(--ease);
}

.faq-item__answer a:hover::after,
.faq-item__answer a:focus-visible::after {
  scale: 1 2;                                           /* wie .link-underline */
}

.faq-item__answer a::after {
  content: "";
  position: absolute;
  inset-block-end: -0.15em;
  inset-inline: 0;
  block-size: var(--link-line);
  background-color: currentColor;
  transform-origin: bottom center;
  transition: scale var(--duration-base) var(--ease);
}

/* Sanftes Auf- und Zuklappen, wo der Browser es kann. Sonst springt es —
   das ist kein Fehler, nur weniger hübsch. */
@supports (interpolate-size: allow-keywords) and selector(::details-content) {
  :root {
    interpolate-size: allow-keywords;
  }

  .faq-item::details-content {
    block-size: 0;
    overflow: hidden;
    transition: block-size var(--duration-base) var(--ease),
                content-visibility var(--duration-base) allow-discrete;
  }

  .faq-item[open]::details-content {
    block-size: auto;
  }
}

@media (width >= 62em) {
  .faq__inner {
    grid-template-columns: minmax(0, 600fr) minmax(0, 652fr);
    gap: var(--space-s);
  }
}


/* =============================================================================
   B11) PROJEKT-DETAILSEITE
   Bausteine der Projektseite (projekt-01.html). Kontaktkarte
   und Fussbereich kommen unverändert aus B7 und B8.

   Besonderheit: Diese Seite fängt HELL an. Der Kopfbereich bekommt dafür die
   Zusatzklasse .site-header--light — alles andere an ihm bleibt wie in B2.

   .site-header--light und der Titelkopf .case-hero werden auch von
   ueber-uns.html benutzt. Wer hier etwas ändert, ändert es auf beiden Seiten.

   Alle Prozentwerte hier stammen aus dem Figma-Frame (1512 px breit,
   Seitenrand 120 px → 1272 px Inhalt) und sind auf diese 1272 px umgerechnet.
   Dadurch bleibt die Anordnung in jeder Fenstergrösse proportional gleich.
   ============================================================================= */

/* --- Kopfbereich auf hellem Grund ------------------------------------------
   Nur Farben. Die Akzentfarbe wird auf die dunkle Variante zurückgestellt
   (4.75:1 auf --tint), und der Fokusring von Hell auf Dunkel gedreht — auf
   heller Fläche wäre ein helles Ringlein unsichtbar (WCAG 1.4.11).          */
.site-header--light {
  background-color: var(--color-surface);
  color: var(--color-text);
  border-block-end-color: var(--color-border);
  --color-focus: var(--color-primary);
  --color-accent-text: var(--accent-dark);
}

.site-header--light .site-header__rule {
  background-color: var(--color-border);
}

.site-header--light .site-nav__link,
.site-header--light .site-header__toggle {
  color: var(--color-text);
}

/* Hover, Fokus und aktuelle Seite auch im hellen Kopf in Orange (hier das
   dunklere --accent-dark, 4.75:1). Ohne diese Regel gewann die Zeile oben
   und die aktuelle Seite blieb dunkel — mobil, ohne Linie, wäre sie dann
   gar nicht mehr zu erkennen. */
.site-header--light .site-nav__link:hover,
.site-header--light .site-nav__link:focus-visible,
.site-header--light .site-nav__link[aria-current="page"] {
  color: var(--color-accent-text);
}

@media (width < 62em) {
  .site-header--light .site-header__panel {
    background-color: var(--color-surface);
  }

  .site-header--light .site-nav__item + .site-nav__item,
  .site-header--light .site-header__contact {
    border-block-start-color: var(--color-border);
  }

  .site-header--light .site-header__contact-link {
    color: var(--color-text);
  }

  .site-header--light .site-header__contact-address {
    color: var(--color-text-muted);       /* 5.33:1 auf --tint */
  }
}


/* --- Titel ------------------------------------------------------------------
   Signet, kleine Zeile, grosse Überschrift — genau in dieser Reihenfolge
   untereinander. Das Signet steht rechts, aber nicht ganz am Rand.          */
.case-hero {
  padding-block: var(--space-m);
}

.case-hero__signet {
  inline-size: clamp(7rem, 15.3vw, 14.5rem);            /* 112 → 232 */
  block-size: auto;
  margin-inline-start: auto;                            /* nach rechts schieben */
  margin-inline-end: 11.4%;                             /* 145px Einzug im Frame */
  margin-block-end: var(--space-l);
}

.case-hero__title {
  max-inline-size: 65.75rem;                            /* 1052px aus dem Frame */
  margin-inline: auto;
  text-align: center;
}

/* Der Kundenname — klein, in normaler Strichstärke. */
.case-hero__client {
  display: block;                                       /* damit die Animation ihn bewegen kann */
  margin-block-end: var(--space-s);
  font-family: var(--font-heading);
  font-weight: 400;
  font-size: var(--text-xl);
  line-height: var(--lh-base);
}

/* Der Projekttitel — die grösste Schrift der Seite. */
.case-hero__project {
  display: block;
  font-family: var(--font-heading);
  font-weight: 900;
  font-size: var(--h1);
  line-height: var(--lh-heading);
  text-wrap: balance;
}

@media (width < 48em) {
  .case-hero__signet {
    margin-inline-end: 0;
  }
}


/* --- Eckdaten + Aufgabe ------------------------------------------------------
   Drei Spalten: Eckdaten ganz links, in der Mitte bewusst nichts, rechts der
   Text. Die mittlere Spalte IST der Abstand — deshalb steht hier kein gap.  */
.case-facts {
  padding-block: var(--space-xl) var(--space-xl);
}

.case-facts__inner {
  display: grid;
  align-items: start;
  gap: var(--space-l);
}

@media (width >= 62em) {
  .case-facts__inner {
    grid-template-columns: minmax(0, 273fr) minmax(0, 477fr) minmax(0, 513fr);
    gap: 0;
    /* Beide Spalten stehen auf derselben Unterkante: die letzte Zeile der
       Eckdaten (der Vorschau-Link) endet genau dort, wo auch der Text unter
       "Aufgabe & Ziel" endet. Wird der Text länger, rutschen die Eckdaten
       entsprechend mit nach unten. */
    align-items: end;
  }

  .case-facts__aufgabe {
    grid-column: 3;
  }
}

/* Das Label sitzt hier dichter über seinem Text als sonst im Framework. */
.case-facts .eyebrow,
.case-columns .eyebrow {
  margin-block-end: var(--space-m);
}

/* Eckdaten: Begriff fett, Wert darunter, zwischen den Zeilen eine Leerzeile. */
.case-meta {
  display: grid;
  gap: var(--space-s);
  margin: 0;
}

.case-meta__row {
  display: grid;
  gap: var(--space-2xs);
}

.case-meta__label {
  font-family: var(--font-heading);
  font-weight: 900;                                     /* Wide Black, siehe Abschnitt 0 */
  font-size: var(--text-l);
  line-height: var(--lh-base);
}

.case-meta__value {
  margin: 0;
  font-size: var(--text-l);
  line-height: var(--lh-base);
}

/* --- Fliesstext der Projektseite -------------------------------------------- */
.case-prose {
  font-size: var(--text-l);
  line-height: var(--lh-base);
  max-inline-size: var(--measure);
}

.case-prose > p + p {
  margin-block-start: var(--space-s);
}


/* --- Bildstrecke + Zwischentext ---------------------------------------------
   Vier Elemente in einem Raster aus zwei Spalten und zwei Zeilen:

       Spalte 1 (393)        Spalte 2 (879)
     ┌─────────────────┬──────────────────────────────┐
     │  A  (hochkant)  │  B  (quer, eingerückt)       │  Zeile 1
     │                 ├──────────────────────────────┤
     │  Zwischentext   │  C  (gross, ragt nach rechts │  Zeile 2
     │                 │      aus dem Bild heraus)    │
     └─────────────────┴──────────────────────────────┘

   A steht über beide Zeilen, deshalb steht der Text darunter in derselben
   Spalte. Die Prozentwerte an B und C sind ihr Einzug und ihre Breite
   INNERHALB der zweiten Spalte.

   Das Raster gilt in JEDER Fenstergrösse — die Gruppe bricht nicht um, sie
   wird nur kleiner. Auch die senkrechten Abstände sind deshalb in vw
   angegeben: sie schrumpfen im selben Verhältnis mit. Die obere Grenze jeder
   clamp() ist der Wert aus dem Frame, damit die Gruppe auf sehr breiten
   Schirmen nicht weiter auseinanderläuft.

   Einzige Ausnahme ist der Zwischentext: in einer 100px schmalen Spalte wäre
   er nicht mehr lesbar. Unter 992px rutscht er deshalb unter die Bilder und
   nimmt die volle Breite.                                                   */
.case-gallery-section {
  padding-block: var(--space-l) var(--space-xl);
  overflow: clip;                                       /* schneidet Bild C am Fensterrand ab */
}

.case-gallery {
  display: grid;
  grid-template-columns: minmax(0, 393fr) minmax(0, 879fr);
  align-items: start;
  column-gap: 0;
  row-gap: clamp(0rem, 9.92vw, 9.375rem);                /* 150px im Frame */
}

/* Grundform. Die Seitenverhältnisse stammen aus dem Frame — dadurch sitzt das
   Raster auch dann richtig, wenn später Bilder mit anderem Zuschnitt kommen. */
.case-gallery__item {
  margin: 0;
  overflow: hidden;
}

/* Platz im Raster. Ein Bild = eine Zeile hier. */
.case-gallery__item--a {
  grid-column: 1;
  grid-row: 1 / 3;
  aspect-ratio: 393 / 589;
  margin-block-start: clamp(0rem, 4.3vw, 4.0625rem);     /* 65px */
}

.case-gallery__item--b {
  grid-column: 2;
  grid-row: 1;
  aspect-ratio: 544 / 363;
  inline-size: 61.9%;
  margin-inline-start: 25.4%;
}

.case-gallery__item--c {
  grid-column: 2;
  grid-row: 2;
  aspect-ratio: 985 / 657;
  inline-size: 112.1%;                                   /* ragt bewusst über den Rand */
  margin-inline-start: 17.5%;
}

.case-gallery__item img {
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
}

.case-note {
  grid-column: 1;
  grid-row: 2;
  margin-block-start: clamp(0rem, 18.8vw, 17.75rem);    /* 284px – so tief steht er im Frame */
  max-inline-size: 19.375rem;                           /* 310px aus dem Frame */
}

/* Unter 992px wäre die linke Spalte zu schmal für Text. Nur er rückt deshalb
   nach unten und über die volle Breite — die Bilder bleiben, wo sie sind. */
@media (width < 62em) {
  .case-note {
    grid-column: 1 / -1;
    grid-row: 3;
    margin-block-start: var(--space-l);
  }
}

/* --- Gespiegelte Fassung (.case-gallery--mirrored) ---------------------------
   Hochformat + Text rechts, die beiden Querformate links. Kein exakter
   Spiegel: die rechte Spalte beginnt auf derselben Linie wie „Aufgabe & Ziel"
   darüber (Raster aus .case-facts__inner: 273 + 477 | 513), das kleine
   Querformat beginnt bündig am linken Inhaltsrand.
   Alle Bilder behalten ihre absolute Grösse aus der Grundform; die Prozente
   sind nur auf die andere Spaltenbreite umgerechnet:
     A  393/1272 des Inhalts  = 76.1 % der rechten Spalte
     B  61.9 % von 879/1272    = 72 %   der linken Spalte
     C  112.1 % von 879/1272   = 130.5 % der linken Spalte, rechte Kante bei
                                 87.4 % → Rand -43.1 %, ragt links hinaus.   */
.case-gallery--mirrored {
  grid-template-columns: minmax(0, 750fr) minmax(0, 513fr);
}

.case-gallery--mirrored .case-gallery__item--a {
  grid-column: 2;
  inline-size: 76.1%;
}

.case-gallery--mirrored .case-gallery__item--b {
  grid-column: 1;
  inline-size: 72%;
  margin-inline-start: 0;
}

.case-gallery--mirrored .case-gallery__item--c {
  grid-column: 1;
  inline-size: 130.5%;
  margin-inline-start: -43.1%;                          /* ragt bewusst über den linken Rand */
}

.case-gallery--mirrored .case-note {
  grid-column: 2;
}

@media (width < 62em) {
  .case-gallery--mirrored .case-note {
    grid-column: 1 / -1;
  }
}


/* --- Bildband über die volle Fensterbreite -----------------------------------
   Steht bewusst ausserhalb von .container: das Band geht von Rand zu Rand und
   läuft endlos langsam von rechts nach links (animations.js, Abschnitt 1c).

   Wie viele Bilder gleichzeitig zu sehen sind, steuert --strip-visible. Der
   Wert darf krumm sein: 1.25 heisst „ein Bild plus ein Viertel des nächsten",
   damit man auf dem Handy sieht, dass es weitergeht.

   Ohne JavaScript, ohne GSAP oder mit „Bewegung reduzieren" steht das Band
   still — dann ist der Ausschnitt seitlich schiebbar, damit alle Bilder
   erreichbar bleiben.                                                        */
.case-strip-section {
  padding-block: var(--space-l);
}

.case-strip {
  --strip-visible: 3;

  overflow-x: auto;                                     /* ohne Animation: von Hand schiebbar */
  overscroll-behavior-inline: contain;
}

/* Läuft die Animation, übernimmt sie das Schieben – dann fester Ausschnitt.
   Das Band lässt sich zusätzlich mit der Maus greifen und verschieben, der
   Greifhand-Zeiger zeigt das an. touch-action: pan-y hält senkrechtes Wischen
   frei, damit auf dem Handy weiterhin die Seite scrollt.                     */
.anim .case-strip {
  overflow: clip;
  cursor: grab;
  touch-action: pan-y;
  user-select: none;
}

.anim .case-strip.is-dragging {
  cursor: grabbing;
}

/* Sonst zieht der Browser beim Greifen das Bild als Datei aus der Seite. */
.anim .case-strip img {
  -webkit-user-drag: none;
}

.case-strip__track {
  display: flex;
  gap: var(--space-m);
  inline-size: max-content;
}

.case-strip__item {
  flex: 0 0 auto;
  margin: 0;
  overflow: hidden;
  /* Fensterbreite minus die Lücken dazwischen, geteilt durch die Anzahl. */
  inline-size: calc(
    (100vw - (var(--strip-visible) - 1) * var(--space-m)) / var(--strip-visible)
  );
  aspect-ratio: 578 / 794;
}

.case-strip__item img {
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
}

@media (width < 62em) {
  .case-strip { --strip-visible: 2; }
}

@media (width < 48em) {
  .case-strip { --strip-visible: 1.25; }
}


/* --- Zwei Textspalten + Zurück ----------------------------------------------- */
.case-columns {
  padding-block: var(--space-l) var(--space-2xl);
}

.case-columns__inner {
  display: grid;
  gap: var(--space-l);
  max-inline-size: 53.25rem;                            /* 852px aus dem Frame */
  margin-inline: auto;
}

@media (width >= 48em) {
  .case-columns__inner {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 3.875rem;                                      /* 62px aus dem Frame */
  }
}

.case-back {
  display: flex;
  justify-content: center;
  margin-block-start: var(--space-xl);
}

/* Etwas breiter als der Standardbutton, weil mehr Text darin steht. */
.button--wide {
  inline-size: min(100%, 17.6875rem);                   /* 283px aus dem Frame */
}


/* =============================================================================
   B12) ÜBER UNS
   Bausteine, die es nur auf ueber-uns.html gibt. Kopfbereich, Hero, Statement,
   Kontaktkarte und Fussbereich kommen unverändert aus B2, B3, B7, B8 und B10.

   Für diese Seite gibt es kein Figma-Screendesign. Die Masse sind deshalb
   nicht gemessen, sondern aus den Tokens abgeleitet — sie passen zum Rest,
   sind aber ausdrücklich zum Anfassen gedacht.
   ============================================================================= */

/* --- Titelkopf: Typo wie im Hero der Startseite --------------------------------
   Der Baustein ist derselbe wie auf der Projektseite (.case-hero in B11), nur
   die Schrift ist die des Startseiten-Heros: die Überschrift enger gesetzt
   (0.99 statt 1.1), die Zeile darüber klein statt gross.
   Die Farbe kommt von der hellen Fläche — dunkles Blau statt Papierweiss.
   Genutzt auf „Über uns" UND „Webdesign" (Modifier, vorher .about-hero).   */
.case-hero--intro .case-hero__client {
  font-size: var(--text-m);
  font-weight: 400;
  line-height: var(--lh-base);
}

.case-hero--intro .case-hero__project {
  line-height: 0.99;
}


/* --- Intro: Vorteilsliste statt Eckdaten ---------------------------------------
   Der Baustein ist .case-facts aus B11. Dort ist die linke Spalte schmal, weil
   dort nur Stichworte stehen. Hier steht die Vorteilsliste darin und braucht
   mehr Platz — also bekommt sie ihn von der leeren Mittelspalte.            */
@media (width >= 62em) {
  .case-facts--list .case-facts__inner {
    grid-template-columns: minmax(0, 500fr) minmax(0, 250fr) minmax(0, 513fr);
  }
}


/* --- Die zwei Personen --------------------------------------------------------
   Portrait links, Text rechts. Das Verhältnis 4:9 lässt dem Text genug Platz
   für zwei Absätze, ohne dass das Bild zur Briefmarke wird.                   */
.persons {
  padding-block: var(--space-l) var(--space-xl);
}

.person-list {
  display: grid;
  gap: var(--space-xl);
  margin: 0;
  padding: 0;                                           /* der Framework-Default für ul greift sonst durch */
}

.person {
  margin: 0;
}

.person__photo {
  inline-size: min(100%, 20rem);                        /* 320px – bewusst kleiner als die Spalte */
  block-size: auto;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  border-radius: var(--radius-l);                       /* wie die Portraits auf der Startseite */
}

/* Mobil so gross wie die Portraits auf der Startseite (.team__photo): 236px. */
@media (width < 62em) {
  .person__photo {
    inline-size: min(100%, 14.75rem);
  }
}

.person__body {
  margin-block-start: var(--space-m);
}

.person__name {
  margin-block-end: var(--space-s);
  font-size: var(--text-m);                             /* wie .team__name auf der Startseite */
  font-weight: 900;
  line-height: var(--lh-heading);
}

/* Das Label sitzt hier dichter über dem Namen als sonst im Framework. */
.persons .eyebrow {
  margin-block-end: var(--space-xs);
}

.person__copy {
  font-size: var(--text-l);
  line-height: var(--lh-base);
  max-inline-size: var(--measure);
}

.person__copy > p + p {
  margin-block-start: var(--space-s);
}

/* Beide nebeneinander, gleich breit, gleich gross — auf Augenhöhe eben.
   Darunter stapeln sie sich. */
@media (width >= 48em) {
  .person-list {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--space-l) clamp(2rem, 5vw, 4.75rem);
  }
}


/* --- Hier arbeiten wir --------------------------------------------------------
   Spiegelbild zu den Personen: Text links, Bild rechts. Damit bekommt die
   Seite einen Wechsel, statt zweimal dasselbe Raster zu zeigen.              */
.region {
  padding-block: var(--space-l) var(--space-xl);
}

.region__inner {
  display: grid;
  gap: var(--space-m);
  align-items: center;
}

.region__image {
  inline-size: 100%;
  block-size: auto;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  border-radius: var(--radius-l);
}

.region__text > .link-arrow {
  margin-block-start: var(--space-m);
}

@media (width >= 48em) {
  .region__inner {
    grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
    gap: var(--space-l);
  }
}


/* --- In Zahlen ----------------------------------------------------------------
   Baugleich mit den vier Schritten der Webdesign-Seite (.step-list weiter
   oben): grosse Zahl, kleines Label davor, Text darunter, das Ganze zwischen
   zwei durchlaufenden Linien. Wer dort etwas am Raster ändert, sollte es hier
   mitändern — die beiden sollen als Paar lesbar bleiben.

   Ein Unterschied: Bei den Schritten ist die Ziffer reine Deko (7 % Deckkraft),
   die Information steckt im Label. Hier IST die Zahl die Information, deshalb
   ist sie kräftiger gesetzt (3.35:1 statt 1.13:1 — bei dieser Schriftgrösse
   reicht das für WCAG 1.4.3, grosser Text).                                  */
.facts {
  padding-block: var(--space-l);
}

.fact-list {
  display: grid;
  gap: var(--space-l) clamp(1.5rem, 5vw, 4.75rem);      /* wie .step-list */
  margin: 0;
  padding: 0;
  padding-block: var(--space-xl);
  border-block: 1px solid var(--color-border);
  list-style: none;
}

.fact {
  margin: 0;
}

.fact__marker {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;                              /* mittig über dem Text darunter */
  gap: var(--space-2xs);
  min-block-size: 5.125rem;                             /* wie .step__marker */
  margin-block-end: var(--space-m);
}

/* Bei den Schritten liegt die Ziffer als Wasserzeichen HINTER dem Label. Das
   geht dort, weil sie mit 7 % kaum sichtbar ist. Hier muss die Zahl lesbar
   sein — deshalb steht sie neben dem Label statt darunter, sonst überdeckt
   eins das andere. Größe, Farbe und Rhythmus bleiben gleich. */
.fact__number {
  font-family: var(--font-heading);
  font-weight: 900;
  font-size: clamp(2.5rem, 4vw, 3.75rem);               /* 40 → 60 */
  line-height: var(--lh-heading);
  color: rgb(49 60 68 / 0.6);                           /* 3.35:1 — reicht für grossen Text */
  white-space: nowrap;
}

.fact__label {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  line-height: 1.27;
  text-transform: uppercase;
  color: var(--color-accent-text);
}

.fact__text {
  font-size: var(--text-s);
}

/* Mobil (eine Spalte) linksbündig wie der Text darunter — mittig wirkte die
   Zeile dort losgelöst. Ab zwei Spalten bleibt sie mittig.
   Dazu weniger Luft zwischen Zahl/Label und dem Text darunter. */
@media (width < 48em) {
  .fact__marker {
    justify-content: flex-start;
    min-block-size: 0;
    margin-block-end: var(--space-xs);
  }
}

@media (width >= 48em) and (width < 62em) {
  .fact-list { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (width >= 62em) {
  .fact-list { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}




/* =============================================================================
   B13) BRIEFING
   Bausteine, die es nur auf briefing.html gibt. Kopfbereich, Titelkopf und
   Fussbereich kommen unverändert aus B2, B11 und B8.

   Für diese Seite gibt es kein Figma-Screendesign. Die Masse sind aus den
   Tokens abgeleitet — sie passen zum Rest, sind aber zum Anfassen gedacht.
   ============================================================================= */

/* --- Flacher Titelkopf --------------------------------------------------------
   Kleineres Signet und weniger Luft ringsum; die Überschrift ist so gross wie
   auf allen anderen Seiten (--h1). Wer den Kopf wieder gross haben will,
   löscht diese Regeln.                                                      */
.case-hero--compact {
  padding-block: var(--space-s) 0;
}

.case-hero--compact .case-hero__signet {
  inline-size: clamp(5rem, 9vw, 8.5rem);                /* 80 → 136 */
  margin-block-end: var(--space-s);
}


/* --- Fortschritt -------------------------------------------------------------
   Bleibt beim Scrollen oben am Fensterrand stehen. Der Kopfbereich scrollt
   mit (position: relative, B2), deshalb 0 und nicht die Kopfhöhe. Der
   z-index bleibt unter dem des Kopfes (20), damit das mobile Menü darüber
   liegt.                                                                    */
.briefing-progress {
  /* Sitzt unter dem Kopfbereich. Fährt der weg, rutscht sie mit nach oben:
     --header-offset setzt navigation.js auf die Kopfhöhe bzw. auf 0. */
  position: sticky;
  inset-block-start: var(--header-offset, 0px);
  transition: inset-block-start var(--duration-base) var(--ease);
  z-index: 10;
  padding-block: var(--space-s);
  background-color: var(--color-surface);
  border-block-end: 1px solid var(--color-border);
}

.briefing-progress__track {
  block-size: 3px;
  background-color: var(--color-border);
  overflow: hidden;
}

.briefing-progress__fill {
  inline-size: 0;
  block-size: 100%;
  background-color: var(--color-accent);
  transition: inline-size var(--duration-base) var(--ease);
}

.briefing-progress__label {
  display: flex;
  justify-content: space-between;
  gap: var(--space-s);
  margin-block-start: var(--space-2xs);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  text-transform: uppercase;
  color: var(--color-text-muted);
}

/* --- Das Formular ------------------------------------------------------------
   Der ganze Bogen steht als EIN Streifen mittig in der Sektion: Fragen,
   Knöpfe, Meldung und Fusszeile teilen sich dieselbe Breite und dieselbe
   Mitte. --briefing-width ist die eine Stellschraube dafür.                 */
.briefing {
  --briefing-width: 53.75rem;                           /* 860px – Lesebreite für Fragen */

  padding-block: var(--space-xl);
}

.briefing__form,
.briefing-actions,
.briefing-note,
.briefing-foot {
  max-inline-size: var(--briefing-width);
  margin-inline: auto;
}

.briefing__form {
  display: grid;
  gap: var(--space-l);
}

/* Ein Abschnitt. <fieldset> und <legend> statt <div> und <h2>: Screenreader
   lesen die Überschrift dann bei jedem Feld darin mit vor. Der Browser-Rahmen
   ist deshalb hier weg. */
/* min-inline-size: 0 — ein <fieldset> schrumpft sonst nie unter die Breite
   seines Inhalts, und lange Auswahlzeilen schieben die Seite auseinander. */
.briefing-block {
  margin: 0;
  min-inline-size: 0;
  padding: clamp(1.5rem, 3.4vw, 2.5rem);
  border: 0;
  border-radius: var(--radius-l);
  background-color: var(--color-surface-soft);
}

/* float + volle Breite: nur so behandelt der Browser die <legend> wie einen
   normalen Block IM Kasten. Ohne das rendert sie auf der Rahmenlinie, also
   ausserhalb der hellen Fläche. */
.briefing-block__head {
  float: inline-start;
  inline-size: 100%;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-s);
  padding: 0;
  margin-block-end: var(--space-m);
}

.briefing-block__number {
  color: var(--color-accent-text);
}

.briefing-block__title {
  font-family: var(--font-heading);
  font-size: var(--h3);
  font-weight: 900;
  line-height: var(--lh-heading);
}

/* --- Eine Frage --------------------------------------------------------------
   Auch die Fragen mit Auswahl sind <fieldset> mit <legend>; die Regel greift
   deshalb für beides. */
.field {
  margin: 0;
  min-inline-size: 0;                                   /* siehe .briefing-block */
  padding: var(--space-m) 0 0;
  border: 0;
  border-block-start: 1px solid var(--color-border);
}

.field + .field {
  margin-block-start: var(--space-m);
}

.briefing-block > .field:first-of-type {
  padding-block-start: 0;
  border-block-start: 0;
}

/* Was auf eine gefloatete <legend> folgt, muss sie freimachen: Flex- und
   Grid-Kästen weichen einem Float sonst aus und werden 0 breit. */
.briefing-block > .field,
.field > * {
  clear: both;
}

/* Dieselbe Sache für die <legend> der Auswahl-Fragen. */
.field__label {
  float: inline-start;
  inline-size: 100%;
  display: block;
  padding: 0;
  margin-block-end: var(--space-xs);
  font-size: var(--text-l);
  font-weight: 900;
  line-height: var(--lh-base);
  text-wrap: pretty;
}

.field__hint {
  font-weight: 400;
  color: var(--color-text-muted);
}

/* Zwei Spalten ab 768px, darunter untereinander. */
.field__grid {
  display: grid;
  gap: var(--space-xs);
}

@media (width >= 48em) {
  .field__grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

/* --- Eingabefelder ----------------------------------------------------------- */
.input {
  inline-size: 100%;
  min-block-size: var(--tap-target);                    /* WCAG 2.5.8 */
  padding: var(--space-xs) var(--space-s);
  font: inherit;
  font-size: var(--text-l);
  color: var(--color-text);
  background-color: var(--bw-100, #fff);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-s);
}

.input--area {
  min-block-size: 6rem;
  line-height: var(--lh-base);
  resize: vertical;
}

.input::placeholder {
  color: var(--color-text-muted);                       /* 5.33:1 — lesbar, nicht laut */
}

.input:hover {
  border-color: var(--accent-dark);
}

/* --- Auswahl (Haken und Punkte) ----------------------------------------------
   Die ganze Fläche ist klickbar, nicht nur das kleine Kästchen. Gewählt =
   dunkle Fläche mit hellem Text: das erkennt man auch ohne Farbe, und der
   Haken bleibt zusätzlich sichtbar (WCAG 1.4.1).                            */
.choice-list {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs);
}

.choice-list--stacked {
  flex-direction: column;
  align-items: stretch;
}

.choice {
  display: flex;
  max-inline-size: 100%;
  align-items: center;
  gap: var(--space-xs);
  min-block-size: var(--tap-target);
  padding: var(--space-xs) var(--space-s);
  font-size: var(--text-l);
  background-color: var(--bw-100, #fff);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-s);
  cursor: pointer;
  transition: background-color var(--duration-fast) var(--ease),
              border-color var(--duration-fast) var(--ease),
              color var(--duration-fast) var(--ease);
}

.choice:hover {
  border-color: var(--accent-dark);
}

.choice input {
  flex: 0 0 auto;
  margin: 0;
  accent-color: var(--color-primary);
}

.choice:has(input:checked) {
  background-color: var(--color-primary);
  border-color: var(--color-primary);
  color: var(--color-text-on-dark);
}

.choice:has(input:checked) input {
  accent-color: var(--paper);
}

/* Browser ohne :has() zeigen die Wahl nur am Haken — das genügt. */

/* --- Knöpfe ------------------------------------------------------------------
   Der erste Knopf ist der Standard-Button aus B1. Die übrigen sind ruhiger:
   Kontur statt Fläche, damit die Reihe nicht nach vier gleichwertigen
   Aktionen aussieht. Die Kontur hat 4.75:1 (WCAG 1.4.11).                   */
/* Vier gleich breite Knöpfe: ab 768px zwei nebeneinander, darunter
   untereinander. Als Raster statt als Reihe, damit die Breiten nicht an der
   Textlänge hängen und die Gruppe ruhig bleibt. */
.briefing-actions {
  display: grid;
  gap: var(--space-xs);
  margin-block-start: var(--space-l);
}

/* Wie bei der Knopfreihe des Projekt-Schiebers (B14): ohne JavaScript muss
   `hidden` greifen — der Reset liegt in @layer und verliert sonst gegen die
   `display`-Zeile darüber. */
.briefing-actions[hidden] {
  display: none;
}

@media (width >= 48em) {
  .briefing-actions {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

.briefing-actions .button {
  inline-size: 100%;
}

.button--quiet {
  background-color: transparent;
  color: var(--color-text);
  border: 1px solid var(--accent-dark);
}

.button--quiet:hover,
.button--quiet:focus-visible {
  background-color: var(--color-primary);
  color: var(--color-text-on-dark);
  border-color: var(--color-primary);
}

.briefing-note:empty {
  display: none;
}

.briefing-note {
  margin-block-start: var(--space-s);
  max-inline-size: var(--measure);
  font-size: var(--text-l);
  color: var(--color-text-muted);
}

/* --- Fuss des Bogens ----------------------------------------------------------
   Zwei kurze Hinweise nebeneinander, bewusst klein: sie erklären die Knöpfe
   darüber und sollen den Bogen nicht überstimmen. --briefing-foot-size ist
   die Stellschraube; darunter wird es auf dem Handy unleserlich.           */
.briefing-foot {
  --briefing-foot-size: clamp(0.6875rem, 0.655rem + 0.16vw, 0.8125rem);   /* 11 → 13 */

  display: grid;
  gap: var(--space-s) var(--space-l);
  margin-block-start: var(--space-l);
  padding-block-start: var(--space-m);
  border-block-start: 1px solid var(--color-border);
  font-size: var(--briefing-foot-size);
  line-height: var(--lh-base);
  color: var(--color-text-muted);
}

.briefing-foot__text {
  margin: 0;
  max-inline-size: 52ch;
}

.briefing-foot__text strong {
  color: var(--color-text);
}

/* .link-underline bringt eine eigene Schriftgrösse mit (B1) — im Fuss soll
   die Mailadresse so gross sein wie der Satz drumherum. */
.briefing-foot .link-underline {
  font-size: inherit;
  padding-block-end: 0;
}

@media (width >= 48em) {
  .briefing-foot {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

/* --- Druck / PDF --------------------------------------------------------------
   Das Blatt soll so aussehen wie der Bogen, nur ohne Bedienung und ohne
   Flächen, die Toner kosten. Die Antworten in den Feldern druckt der Browser
   mit; leere Felder bleiben als Linie stehen, dann lässt sich der Bogen auch
   mit der Hand ausfüllen.                                                    */
@media print {
  .site-header,
  .site-footer,
  .briefing-progress,
  .briefing-actions,
  .briefing-note,
  .case-hero__signet,
  .noprint {
    display: none !important;
  }

  .briefing,
  .case-hero {
    padding-block: 0;
  }

  .case-hero__title {
    text-align: start;
  }

  .briefing-block {
    padding: 0;
    background: none;
    border-block-start: 1.5pt solid #000;
    border-radius: 0;
    break-inside: auto;
  }

  .briefing-block__head {
    margin-block: 10pt 8pt;
  }

  .field {
    break-inside: avoid;
  }

  .input {
    padding: 0;
    background: none;
    border: 0;
    border-block-end: 0.5pt solid #999;
    border-radius: 0;
    min-block-size: auto;
  }

  .input--area {
    min-block-size: 40pt;
  }

  .choice {
    min-block-size: auto;
    padding: 2pt 6pt;
    background: none;
    border: 0.5pt solid #999;
  }

  .choice:has(input:checked) {
    background: none;
    color: #000;
    border-color: #000;
  }
}


/* =============================================================================
   B14) PROJEKT-SCHIEBER (Startseite)
   =============================================================================

   Der Projekte-Abschnitt der Startseite ist ein Schieber: ein Projekt gross,
   das nächste lugt rechts herein, weiter über zwei runde Knöpfe. Vorbild ist
   der Projekt-Slider auf mindpark.at. Die Kachel im Fokus beginnt auf der
   Inhaltskante, also unter der Überschrift — bündig am Fensterrand lag sie
   nur in Runde 111 und ist in 112 zurückgenommen.

   NUR die Startseite trägt dafür `.projects--slider`. Auf `projekte.html` und
   `webdesign.html` bleibt das Raster aus B5 unverändert — die Kacheln selbst
   sind in beiden Fassungen dieselben (.project, .project__media,
   .project__frame, .project__meta). Dadurch laufen Bildwechsel beim Hovern
   und Zeigerring aus animations.js hier wie dort.

   Technisch ist das kein Karussell-Skript, sondern eine Fläche, die seitlich
   scrollt (overflow-x) mit Einrastpunkten (scroll-snap). Das bringt Wischen,
   Tastaturbedienung und das Verhalten ohne JavaScript gratis mit;
   js/projekt-slider.js bedient nur die beiden Knöpfe und das Ziehen mit der
   Maus.

   **Unter 48em (768px) ist es kein Schieber mehr**: die Kacheln stehen
   untereinander, die Knöpfe sind weg. Siehe ganz unten.

   Stellschrauben stehen alle in .projects--slider ganz oben.
   ========================================================================== */

.projects--slider {
  /* Linker Anschlag: genau die Kante, an der auch der Inhalt im .container
     beginnt — sonst stünde das erste Bild nicht unter der Überschrift.
     (Sektionsbreite minus Inhaltsbreite, halbiert, plus Seitenabstand.) */
  --slider-lead: max(var(--gutter), calc((100% - var(--content-width)) / 2 + var(--gutter)));

  /* Derselbe Wert, nur aus der Fensterbreite statt aus der Sektionsbreite
     gerechnet. Gebraucht wird er für die Kachelbreite: ein Prozentwert würde
     dort gegen die Spur statt gegen die Sektion rechnen und damit gegen einen
     Wert, der selbst von dieser Rechnung abhängt. Der Unterschied zur Zeile
     darüber ist die Breite der Rollbalken-Leiste (rund 15 px) — für die
     Kachelbreite ohne Belang, für den Anschlag oben wäre er sichtbar. */
  --slider-lead-v: max(var(--gutter), calc((100vw - var(--content-width)) / 2 + var(--gutter)));

  /* Wie viel Platz rechts frei bleibt, damit das nächste Projekt hereinlugt.
     Je grösser der Wert, desto kleiner die Kachel. */
  --slider-peek: clamp(4rem, 26vw, 32rem);

  /* Abstand zwischen zwei Projekten. */
  --slider-gap: calc(var(--space-l) + var(--space-s));

  /* Breite einer Kachel: alles ausser Anschlag und Vorschau, höchstens aber
     90 % der Inhaltsbreite der übrigen Sektionen. Sonst würde die Kachel auf
     sehr breiten Schirmen bis an die Inhaltskante laufen. */
  --slide-width: min(
    calc(100vw - var(--slider-lead-v) - var(--slider-peek)),
    calc((var(--content-width) - 2 * var(--gutter)) * 0.9)
  );

  /* Seitenverhältnis der Bilder im Schieber (quer, wie im Design) und die
     Obergrenze, damit ein Bild nie höher wird als das Fenster. Greift die
     Grenze, schneidet object-fit oben und unten etwas weg. */
  --slide-ratio: 776 / 533;
  --slide-max-height: 78svh;
}

/* --- Die schiebbare Fläche -------------------------------------------------
   Steht ausserhalb von .container und reicht deshalb bis zum Fensterrand.
   `overflow: clip` an .projects (B5) schneidet nichts ab, was hier nötig wäre. */
.project-slider {
  overflow-x: auto;
  overscroll-behavior-inline: contain;      /* kein Zurückblättern im Browser */
  scroll-snap-type: x mandatory;
  scroll-padding-inline-start: var(--slider-lead);
  cursor: grab;

  /* Die Rollbalken-Leiste wäre unter den Bildern ein Fremdkörper; bedient
     wird über Knöpfe, Wischen, Ziehen und Tastatur. */
  scrollbar-width: none;
}

.project-slider::-webkit-scrollbar {
  display: none;
}

/* Während des Ziehens darf nichts einrasten, sonst ruckelt der Schieber
   gegen die Maus an — und auch danach nicht, solange er noch zur nächsten
   Kachel gleitet (.is-gliding, von js/projekt-slider.js gesetzt). */
.project-slider.is-dragging,
.project-slider.is-gliding {
  scroll-snap-type: none;
}

.project-slider.is-dragging {
  cursor: grabbing;
  user-select: none;
}

/* Beim Ziehen darf der Klick auf der Kachel nicht als Linkklick ankommen. */
.project-slider.is-dragging a {
  pointer-events: none;
}

/* Bilder und Links lassen sich sonst aus der Seite herausziehen; der Browser
   startet dann sein eigenes Drag and Drop und bricht das Schieben ab. */
.project-slider img,
.project-slider a {
  -webkit-user-drag: none;
}

.project-slider__track {
  display: flex;
  gap: var(--slider-gap);
  margin: 0;
  padding: 0;
  padding-inline: var(--slider-lead);       /* vorne bündig mit der Überschrift */
  list-style: none;
}

.project-slider__track > .project {
  flex: 0 0 var(--slide-width);
  margin: 0;
  scroll-snap-align: start;
}

/* Im Raster gibt --project-height die Höhe vor, hier das Seitenverhältnis:
   die Kachel ist so breit wie der Schieber und wird daraus berechnet. */
.project-slider .project__media {
  block-size: auto;
  aspect-ratio: var(--slide-ratio);
  max-block-size: 78vh;                     /* Rückfall für Browser ohne svh */
  max-block-size: var(--slide-max-height);
}

/* --- „Projekt anzeigen" beim Hovern ----------------------------------------
   Sitzt unten rechts im Bild und blendet beim Hovern (und beim Tabben auf die
   Kachel) ein. Baustein ist der Pfeil-Link `.link-arrow` aus B1, hier als
   <span>: ein zweiter Link in der Kachel wäre weder nötig noch erlaubt, die
   ganze Kachel ist schon einer. `pointer-events: none`, sonst schluckt er den
   Klick — und weil er dadurch selbst nie gehovert wird, hängen Unterstrich
   und Pfeil am Hover der Kachel.

   Papierweiss mit einem weichen Schatten: über einem Foto lässt sich kein
   fester Kontrastwert garantieren, der Schatten hält den Text auch über
   hellen Stellen lesbar. Wer es ganz sicher haben will, nimmt stattdessen
   eine Fläche hinter den Text. */
.project-slider .project__cta {
  position: absolute;
  inset-block-end: var(--space-s);
  inset-inline-end: var(--space-s);
  color: var(--paper);
  text-shadow: 0 1px 6px rgb(35 38 42 / 0.55);
  opacity: 0;
  translate: 0 0.5rem;
  pointer-events: none;
  transition:
    opacity var(--duration-base) var(--ease),
    translate var(--duration-base) var(--ease);
}

.project-slider .project__link:hover .project__cta,
.project-slider .project__link:focus-visible .project__cta {
  opacity: 1;
  translate: 0 0;
}

/* Der Unterstrich des Pfeil-Links kommt mit — so sieht er aus wie jeder
   andere Link der Seite im Hover-Zustand. */
.project-slider .project__link:hover .project__cta .link-arrow__text::after,
.project-slider .project__link:focus-visible .project__cta .link-arrow__text::after {
  scale: 1 1;
}

/* Ohne Maus gibt es kein Hovern — dort steht der Link von Anfang an. */
@media (hover: none) {
  .project-slider .project__cta {
    opacity: 1;
    translate: 0 0;
  }
}


/* --- Die beiden Knöpfe -----------------------------------------------------
   Rechtsbündig unter dem Schieber, wie beim Vorbild. */
.project-slider__nav {
  display: flex;
  justify-content: flex-end;
  gap: var(--space-xs);
  margin-block-start: var(--space-m);
}

/* Ohne JavaScript bleibt `hidden` am Markup stehen. Das `display: none` des
   Resets liegt aber in @layer und verliert deshalb gegen die Zeile darüber —
   die Knöpfe wären sichtbar, ohne etwas zu tun. Diese Regel ist spezifischer
   als beide und schliesst die Lücke. Dasselbe Muster steht in B13 bei den
   Briefing-Knöpfen. */
.project-slider__nav[hidden] {
  display: none;
}

.slider-arrow {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  inline-size: 3.5rem;                      /* 56px, also über --tap-target */
  block-size: 3.5rem;
  padding: 0;
  background-color: transparent;
  color: var(--color-text);
  border: 1px solid var(--color-accent-text);
  border-radius: var(--radius-pill);
  cursor: pointer;
  transition:
    background-color var(--duration-base) var(--ease),
    border-color var(--duration-base) var(--ease),
    color var(--duration-base) var(--ease);
}

/* Der Pfeil steht als SVG direkt im Markup und erbt die Textfarbe
   (fill="currentColor"): so wechselt er beim Hovern die Farbe mit und bleibt
   in jeder Fassung kontrastreich — die Datei im Assets-Ordner ist orange und
   hätte auf Weiss nur 2.44:1. Als Maske eingebunden wäre er beim Betrachten
   über file:// unsichtbar (der Browser verweigert externe Masken). */
.slider-arrow__icon {
  inline-size: 1.375rem;
  block-size: auto;
}

/* Derselbe Pfeil, gespiegelt. scale statt transform, damit sich nichts mit
   GSAP in die Quere kommt. */
.slider-arrow--prev .slider-arrow__icon {
  scale: -1 1;
}

.slider-arrow:hover {
  background-color: var(--color-accent);
  border-color: var(--color-accent);
  color: var(--color-on-accent);
}

/* Am Anfang und am Ende: der Knopf bleibt stehen, wird aber ruhiger. */
.slider-arrow[disabled] {
  border-color: var(--color-border);
  color: var(--color-text-muted);
  cursor: default;
}

.slider-arrow[disabled]:hover {
  background-color: transparent;
  border-color: var(--color-border);
  color: var(--color-text-muted);
}

/* --- Mobil: kein Schieber, sondern eine Liste untereinander ----------------
   Auf dem Handy ist seitliches Schieben für den Hauptinhalt einer Seite der
   falsche Weg — man sieht nur ein Projekt und muss raten, dass es weitergeht.
   Unter 48em wird aus der Spur deshalb eine Spalte: volle Breite, Kachel
   unter Kachel, Knöpfe weg. Der Rahmen (.project-slider) bleibt im Markup
   stehen, verliert hier aber jede Scroll-Eigenschaft. */
@media (width < 48em) {
  .project-slider {
    overflow: visible;
    scroll-snap-type: none;
    cursor: auto;
  }

  .project-slider__track {
    display: grid;                          /* eine Spalte, Kachel unter Kachel */
    gap: calc(var(--space-m) + var(--space-xs));
    padding-inline: var(--gutter);
  }

  .project-slider__track > .project {
    scroll-snap-align: none;
  }

  /* Die Knöpfe hätten hier nichts mehr zu schieben. */
  .project-slider__nav {
    display: none;
  }
}


/* =============================================================================
   C1) PINEGROW BREAKPOINTS
   Pinegrow liest vorhandene Media Queries aus und zeigt sie in der
   Breakpoint-Leiste. Leere Blöcke = Breakpoints stehen zum Klicken bereit.
   Mobile-first, em-basiert (skaliert mit der Browser-Schriftgrösse).
   ============================================================================= */
@media (min-width: 36em)   { /*  576px – Phone quer */ }
@media (min-width: 48em)   { /*  768px – Tablet     */ }
@media (min-width: 62em)   { /*  992px – Desktop S  */ }
@media (min-width: 75em)   { /* 1200px – Desktop M  */ }
@media (min-width: 87.5em) { /* 1400px – Desktop L  */ }

/* =============================================================================
   C2) PRINT
   ============================================================================= */
@media print {
  body { background: #fff; color: #000; font-size: 11pt; }
  a[href^="http"]::after { content: " (" attr(href) ")"; font-size: 9pt; }
}
