/* ============================================================
   FONT — ospitati qui, non su Google

   Due ragioni, nell'ordine. La prima è legale: un font caricato da
   fonts.gstatic.com manda l'IP di ogni visitatore negli Stati
   Uniti, e in Germania su questo si perdono cause. La seconda è di
   velocità: due connessioni a domini terzi in meno prima che il
   testo si possa disegnare, e la cache è la nostra — dal 2020 i
   browser la partizionano per sito, quindi la "cache condivisa di
   Google Fonts" non esiste più.

   Sono file VARIABILI: uno solo copre tutti i pesi dell'intervallo
   invece di un file per peso. Rethink Sans va da 400 a 800, Inter
   da 100 a 900.

   Divisi per unicode-range come li serve Google: il browser scarica
   latin-ext solo se in pagina compare un carattere che lo richiede.
   Per il tedesco basta latin — 106 kB invece di 253.

   Licenze SIL OFL in assets/fonts/, da distribuire coi font.
   ============================================================ */
@font-face{
  font-family:'Rethink Sans';
  font-style:normal;
  font-weight:400 800;
  font-display:swap;
  src:url('../assets/fonts/rethink-sans-latin.woff2') format('woff2');
  unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face{
  font-family:'Rethink Sans';
  font-style:normal;
  font-weight:400 800;
  font-display:swap;
  src:url('../assets/fonts/rethink-sans-latin-ext.woff2') format('woff2');
  unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face{
  font-family:'Inter';
  font-style:normal;
  font-weight:100 900;
  font-display:swap;
  src:url('../assets/fonts/inter-latin.woff2') format('woff2');
  unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face{
  font-family:'Inter';
  font-style:normal;
  font-weight:100 900;
  font-display:swap;
  src:url('../assets/fonts/inter-latin-ext.woff2') format('woff2');
  unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* ---- font di ripiego con metriche allineate ----
   Non scaricano niente: prendono Arial già installato e ne
   correggono ascendente e discendente perché l'altezza di riga
   coincida con quella del font vero, così nell'istante prima che
   arrivi il woff2 il layout non scatta.
   Base Arial e non system-ui, che è un font diverso su ogni
   piattaforma: un solo set di correzioni non varrebbe per tutte. */
@font-face{
  font-family:'Rethink Sans Fallback';
  src:local('Arial');
  ascent-override:99%;
  descent-override:31%;
  line-gap-override:0%;
}
@font-face{
  font-family:'Inter Fallback';
  src:local('Arial');
  ascent-override:97%;
  descent-override:24%;
  line-gap-override:0%;
}

/* ============================================================
   NEW MONDAY — main.css
   Condiviso da ogni pagina: reset, token, typography, layout
   globale, header (menu desktop + mobile), footer, animazioni.

   TOKEN — origine e regola dei clamp
   ---------------------------------------------------------
   Tutti i valori sono letti dai mode del file Figma
   "Website 2026 — New Style" (691Xmz61IOB6lzDwxhrpQV) via MCP:
     Desktop → valore massimo, raggiunto a 1920px
     Laptop  → valore minimo,  raggiunto a 1280px
     Mobile  → valore minimo,  raggiunto a  500px

   Dove Mobile == Laptop (tutta la scala spacing, i radius,
   header-item-h e quasi tutti i font-size) basta UN clamp:
   interpola fra 1280 e 1920 e sotto i 1280 resta fisso.

   Dove Mobile != Laptop servono DUE clamp separati: il primo
   interpola 500→1280, il secondo (in @media min-width:1280px)
   interpola 1280→1920. Riguarda solo: headings-xl (44/84/128),
   button-lg (14/16/24) e il margine di pagina (32/54/110).

   Formula del clamp 1280→1920:
     clamp(min, calc((max-min)/6.4 * 1vw + (3*min - 2*max) * 1px), max)
   ============================================================ */

:root{
  /* ---- colori — collection Figma "Foundamental - Color".
         I nomi seguono 1:1 le variabili Figma:
           Base/black · Base/white
           Primary/primary, primary-NN  → --color-primary(-NN)
           Neutral/gray-NN              → --color-gray-NN
         Nella scala Figma "primary 100" È Primary/primary e
         "neutral 100" È Base/black: non esistono come token
         separati e qui non vengono duplicati. ---- */
  --color-black:#111111;   /* Base/black */
  --color-white:#ffffff;   /* Base/white */

  --color-primary-10:  #e6f9fa;
  --color-primary-15:  #d0f6f7;
  --color-primary-20:  #88e1e3;
  --color-primary-30:  #2bd6d9;
  --color-primary-40:  #00c7ca;
  --color-primary:     #009193;   /* primary 100 */
  --color-primary-200: #005f61;
  --color-primary-300: #004142;

  --color-gray-10: #f8fafc;
  --color-gray-15: #f0f3f5;
  --color-gray-20: #c9ced1;
  --color-gray-40: #969ea3;
  --color-gray-60: #67737a;
  --color-gray-80: #414b52;
  --color-gray-90: #1f2529;

  /* Extra/academy — viola della UX Growth Academy */
  --color-academy: #7f5fd7;

  /* Primary/error — campi e messaggi d'errore delle form */
  --color-error: #d92644;

  /* ---- famiglie — Figma font/family ---- */
  /* la coda non è "sans-serif" generico: sono i font di sistema che
     esistono davvero su macOS, Windows e Android, così nell'istante
     prima che arrivi il woff2 il testo non cade su Times. */
  --font-base:'Rethink Sans', 'Rethink Sans Fallback', system-ui, -apple-system, 'Segoe UI', Roboto, Arial, sans-serif;   /* font/family/font-base */
  --font-sans:'Inter', 'Inter Fallback', system-ui, -apple-system, 'Segoe UI', Roboto, Arial, sans-serif;          /* font/family/font-sans */

  /* ---- easing ---- */
  --ease-out:   cubic-bezier(.16,1,.3,1);
  --ease-inout: cubic-bezier(.65,0,.35,1);

  /* ---- spacing — Figma spacing/spacing-XX
         Laptop e Mobile coincidono su tutta la scala → un clamp. ---- */
  /* Tre punti, non due: valore Mobile fino a 375, Laptop a 1280,
     Desktop a 1920. La seconda rampa sta nel @media in fondo.
     Letti dalle variabili nei nodi 2253:7732 / 7733 / 7747,
     non dalla tavola disegnata 76:849, che è disallineata. */
  --space-4:    clamp(3px, calc(0.1105vw + 2.5856px), 4px);
  --space-8:    6px;
  --space-12:   clamp(8px, calc(0.1105vw + 7.5856px), 9px);
  --space-16:   clamp(10px, calc(0.2210vw + 9.1713px), 12px);
  --space-20:   clamp(12px, calc(0.2210vw + 11.1713px), 14px);
  --space-24:   clamp(14px, calc(0.2210vw + 13.1713px), 16px);
  --space-32:   22px;
  --space-48:   clamp(24px, calc(0.8840vw + 20.6851px), 32px);
  --space-64:   clamp(30px, calc(1.3260vw + 25.0276px), 42px);
  --space-80:   clamp(48px, calc(0.6630vw + 45.5138px), 54px);
  --space-128:  clamp(64px, calc(2.2099vw + 55.7127px), 84px);
  --space-240:  clamp(120px, calc(4.4199vw + 103.4254px), 160px);
  --space-320:  clamp(180px, calc(6.6298vw + 155.1381px), 240px);

  /* margine di pagina: Mobile 24 != Laptop 54 (spacing-80) !=
     Desktop 110 → due clamp, vedi @media sotto. La rampa sale da
     24 (fino a 500px di viewport) a 54 a 1280. */
  --space-page-margin: clamp(24px, calc(3.8462vw + 4.7692px), 54px);

  /* ---- radius — derivati dalla stessa scala spacing ----
     Come nel Figma (Primitive → radius/*): ogni radius-N è un alias
     di spacing-N, con gli stessi valori nei tre mode. */
  --radius-4:   var(--space-4);
  --radius-8:   var(--space-8);
  --radius-12:  var(--space-12);
  --radius-16:  var(--space-16);
  --radius-20:  var(--space-20);
  --radius-24:  var(--space-24);
  --radius-32:  var(--space-32);
  --radius-48:  var(--space-48);
  --radius-64:  var(--space-64);
  --radius-80:  var(--space-80);
  --radius-128: var(--space-128);
  --radius-240: var(--space-240);
  --radius-320: var(--space-320);
  --radius-pill: 100vh;  /* pillola: basta un raggio ≥ metà altezza, il browser lo riduce fino a far combaciare gli angoli */

  /* ---- ombre — Figma effect style Shadow/* ---- */
  --shadow-banner: 0 8px 32px rgb(0 0 0 / .12);    /* Shadow/Banner: banner cookie */
  --shadow-dialog: 0 16px 48px rgb(0 0 0 / .16);   /* Shadow/Dialog: preferenze cookie, finestre di conferma */

  /* ---- MENU MOBILE — misure proprie ----
     Il menu non segue più la scala del design system: dal frame
     Figma 2241:4740 ha valori suoi, in px, che non cambiano con
     la larghezza della finestra. Ogni variabile porta il nome del
     suo ruolo, non del gradino di scala da cui veniva. */
  --menu-bar-pad:          24px;  /* barra: dai bordi e dal fondo */
  --menu-pill-pad:         22px;
  /* stesso colore, due opacità: la dissolvenza interpola solo l'alfa.
     Lo stato a riposo NON usa color-mix, che mescolando con
     "transparent" azzera anche i canali e restituisce nero a 0%:
     serve la sintassi relativa, che tiene il colore e cambia solo
     l'alfa. Se un browser non la conosce la dichiarazione cade e
     lo sfondo torna al valore iniziale, anch'esso invisibile. */
  --menu-pill-bg:          color-mix(in srgb, var(--color-gray-20) 50%, transparent);
  --menu-pill-bg-off:      rgb(from var(--color-gray-20) r g b / 0);
  --menu-toggle-pad:       16px;
  --menu-font-toggle:      16px;
  /* altezza della barra: non è un valore a sé, è quello che risulta
     dal toggle. Serve dichiarata perché il tetto di apertura la
     sottrae all'altezza dello schermo. */
  --menu-bar-h:            calc(var(--menu-toggle-pad) * 2 + var(--menu-font-toggle) * 1.5);

  --menu-panel-pad-bottom: 12px;
  --menu-dropdown-pad:     16px;
  --menu-dropdown-radius:  32px;
  --menu-border:            2px;
  --menu-gap:              16px;  /* fra i blocchi dentro al pannello */
  --menu-account-gap:       8px;  /* dashboard: sotto "Signed in as" */

  --menu-list-pad-top:     10px;
  --menu-group-gap:        24px;  /* pannello Leistungen: voci → pulsante */
  --menu-group-head-gap:    8px;
  --menu-group-head-pad:   14px;
  --menu-group-back-gap:    8px;  /* sotto il tasto indietro (sticky alto 60 = 52 + 8) */
  --menu-item-pad-y:        4px;
  --menu-item-pad-x:       12px;
  --menu-item-radius:      16px;
  --menu-font-item:        24px;
  --menu-item-bg-tap:      var(--color-gray-15);
  --menu-arrow:            20px;
  --menu-back-pad:         16px;
  --menu-sep-inset:        12px;

  --menu-contact-gap:       6px;
  --menu-dm-pad-y:         12px;
  --menu-dm-pad-x:         14px;
  --menu-dm-radius:        16px;
  --menu-dm-icon:          22px;
  --menu-dm-gap:           12px;
  --menu-font-dm:          12px;

  /* ---- font-size — Figma font/size ---- */
  --font-size-headings-jumbo: clamp(54px, calc(6.6667vw + 20.6667px), 106px);
  /* headings-xl: Mobile 44 != Laptop 84 → due clamp */
  --font-size-headings-xl:    clamp(44px, calc(5.1282vw + 18.359px), 84px);
  --font-size-headings-lg:    clamp(40px, calc(3.0769vw + 24.6154px), 64px);
  --font-size-headings-md:    clamp(36px, calc(2.3077vw + 24.4615px), 54px);
  --font-size-headings-sm:    clamp(30px, calc(1.5385vw + 22.3077px), 42px);
  --font-size-headings-xs:    clamp(24px, calc(1.0256vw + 18.8718px), 32px);
  --font-size-headings-xxs:   clamp(16px, calc(1.0256vw + 10.8718px), 24px);

  --font-size-paragraph-xl:   clamp(34px, calc(0.5128vw + 31.4359px), 38px);
  --font-size-paragraph-lg:   clamp(24px, calc(1.0256vw + 18.8718px), 32px);
  --font-size-paragraph-md:   clamp(16px, calc(1.0256vw + 10.8718px), 24px);
  --font-size-paragraph-sm:   clamp(14px, calc(0.2564vw + 12.7179px), 16px);
  --font-size-paragraph-xs:   clamp(12px, calc(0.625vw + 4.0px), 16px);
  --font-size-review-quote:   clamp(16px, calc(1.0256vw + 10.8718px), 24px);
  --font-size-special-note:   clamp(10px, calc(0.2564vw + 8.7179px), 12px);   /* font/size/special/note: 10 Mobile · 12 Laptop */

  /* button-lg: Mobile 14 != Laptop 16 → due clamp */
  --font-size-button-lg:      clamp(16px, 1.25vw, 24px);
  --font-size-button-sm:      clamp(12px, calc(0.625vw + 4.0px), 16px);

  /* ---- size — Figma component/* e larghezza di pagina ---- */
  --size-header-item: clamp(34px, calc(2.8125vw - 2px), 52px);
  /* casella del consenso privacy: in mobile pareggia l'altezza di
     riga del testo accanto (paragraph-xs 12 x 1.5 = 18), che la
     scala spacing non dava — spacing-24 lì vale 14. */
  --size-consent-box: clamp(18px, calc(0.9375vw + 6px), 24px);
  /* il segno di spunta dentro alla casella: due terzi del suo lato
     in tutti e due i mode (12 su 18, 16 su 24), quindi stessa
     rampa. Anche qui spacing-16 non andava: in mobile vale 10. */
  --size-consent-check: clamp(12px, calc(0.625vw + 4px), 16px);
  /* bordo della casella: 1,5 in mobile, 2 in desktop (Figma
     2249:7701 e 2017:5452). Va applicato con box-shadow:inset e
     non con border, perché Chrome tronca border-width all'intero
     e 1.5px diventerebbe 1px. */
  --size-consent-border: clamp(1.5px, calc(0.078125vw + 0.5px), 2px);
  --size-page-max: 1920px;

  /* Colonne della griglia di pagina come misure, per i blocchi che
     NON stanno in un .page-grid ma devono essere larghi N colonne:
     un titolo, un paragrafo, un contenitore più stretto della
     pagina. Dentro a un .page-grid si usa --grid-col, non queste.

     Il 100% NON si calcola qui: una variabile non registrata viene
     copiata come testo nell'elemento che la usa, e lì il 100% è la
     larghezza del suo contenitore. Quindi danno il numero giusto
     solo se il contenitore è largo quanto la griglia — come quello
     di una section, che ha già il margine di pagina come padding.
     Non registrarle con @property: non serve, e due delle scelte
     che @property chiede le rompono. Con syntax:'<length>' il 100%
     non è accettato e la variabile vale 0; con inherits:false vive
     solo in :root e agli elementi arriva 0. (Misurato: 1128px non
     registrata, 0px in quei due casi.)

     Una colonna è quello che resta togliendo i gutter, diviso il
     numero di colonne; N colonne sono N di quelle più gli N-1 gutter
     in mezzo. min() tiene N entro le colonne che la griglia ha:
     sotto i 1024 è una sola, e ogni --size-col-* diventa il 100%. */
  --grid-columns: 12;
  --grid-gutter:  var(--space-16);
  --grid-column:  calc((100% - var(--grid-gutter) * (var(--grid-columns) - 1)) / var(--grid-columns));
  --size-col-1:  calc(var(--grid-column) * min(1, var(--grid-columns)) + var(--grid-gutter) * (min(1, var(--grid-columns)) - 1));
  --size-col-2:  calc(var(--grid-column) * min(2, var(--grid-columns)) + var(--grid-gutter) * (min(2, var(--grid-columns)) - 1));
  --size-col-3:  calc(var(--grid-column) * min(3, var(--grid-columns)) + var(--grid-gutter) * (min(3, var(--grid-columns)) - 1));
  --size-col-4:  calc(var(--grid-column) * min(4, var(--grid-columns)) + var(--grid-gutter) * (min(4, var(--grid-columns)) - 1));
  --size-col-5:  calc(var(--grid-column) * min(5, var(--grid-columns)) + var(--grid-gutter) * (min(5, var(--grid-columns)) - 1));
  --size-col-6:  calc(var(--grid-column) * min(6, var(--grid-columns)) + var(--grid-gutter) * (min(6, var(--grid-columns)) - 1));
  --size-col-7:  calc(var(--grid-column) * min(7, var(--grid-columns)) + var(--grid-gutter) * (min(7, var(--grid-columns)) - 1));
  --size-col-8:  calc(var(--grid-column) * min(8, var(--grid-columns)) + var(--grid-gutter) * (min(8, var(--grid-columns)) - 1));
  --size-col-9:  calc(var(--grid-column) * min(9, var(--grid-columns)) + var(--grid-gutter) * (min(9, var(--grid-columns)) - 1));
  --size-col-10: calc(var(--grid-column) * min(10, var(--grid-columns)) + var(--grid-gutter) * (min(10, var(--grid-columns)) - 1));
  --size-col-11: calc(var(--grid-column) * min(11, var(--grid-columns)) + var(--grid-gutter) * (min(11, var(--grid-columns)) - 1));
  --size-col-12: calc(var(--grid-column) * min(12, var(--grid-columns)) + var(--grid-gutter) * (min(12, var(--grid-columns)) - 1));
}
@media (max-width: 1023px){
  :root{ --grid-columns: 1; }
}

/* Fascia Laptop→Desktop: solo i token in cui Mobile e Laptop
   divergono cambiano formula qui; tutti gli altri hanno già il
   clamp corretto perché il loro minimo È il valore Laptop. */
@media (min-width: 1280px){
  :root{
    --space-4:    4px;
    --space-8:    clamp(6px, calc(0.3125vw + 2.0000px), 8px);
    --space-12:   clamp(9px, calc(0.4688vw + 3.0000px), 12px);
    --space-16:   clamp(12px, calc(0.6250vw + 4.0000px), 16px);
    --space-20:   clamp(14px, calc(0.9375vw + 2.0000px), 20px);
    --space-24:   clamp(16px, calc(1.2500vw + 0.0000px), 24px);
    --space-32:   clamp(22px, calc(1.5625vw + 2.0000px), 32px);
    --space-48:   clamp(32px, calc(2.5000vw + 0.0000px), 48px);
    --space-64:   clamp(42px, calc(3.4375vw - 2.0000px), 64px);
    --space-80:   clamp(54px, calc(4.0625vw + 2.0000px), 80px);
    --space-128:  clamp(84px, calc(6.8750vw - 4.0000px), 128px);
    --space-240:  clamp(160px, calc(12.5000vw + 0.0000px), 240px);
    --space-320:  clamp(240px, calc(12.5000vw + 80.0000px), 320px);

    --space-page-margin:     clamp(54px, calc(8.75vw - 58px),  110px);
    --font-size-headings-jumbo: clamp(106px, calc(8.4375vw - 2.0px), 160px);
    --font-size-headings-xl:    clamp(84px, calc(6.875vw - 4.0px), 128px);
    --font-size-headings-lg:    clamp(64px, 5.0vw, 96px);
    --font-size-headings-md:    clamp(54px, calc(4.0625vw + 2.0px), 80px);
    --font-size-headings-sm:    clamp(42px, calc(3.4375vw - 2.0px), 64px);
    --font-size-headings-xs:    clamp(32px, 2.5vw, 48px);
    --font-size-headings-xxs:   clamp(24px, 1.875vw, 36px);
    --font-size-paragraph-xl:   clamp(38px, calc(2.8125vw + 2.0px), 56px);
    --font-size-paragraph-lg:   clamp(32px, 2.5vw, 48px);
    --font-size-paragraph-md:   clamp(24px, calc(1.25vw + 8.0px), 32px);
    --font-size-paragraph-sm:   clamp(16px, 1.25vw, 24px);
    --font-size-review-quote:   clamp(24px, calc(2.5vw - 8.0px), 40px);
    --font-size-special-note:   clamp(12px, calc(0.3125vw + 8.0px), 14px);     /* 12 Laptop · 14 Desktop */
  }
}

/* ============================================================
   RESET
   ============================================================ */
*{ box-sizing:border-box; margin:0; padding:0; }
html{ scroll-behavior:smooth; }

/* Ancore (#kontakt, #anfrage…): da 1024 in su il menu sta in alto e
   fisso, quindi la pagina si ferma sotto di lui più un respiro di
   space-32. Altezza del menu = margine sopra (space-32) + elemento
   (size-header-item) + padding del logo sopra e sotto (space-16).
   Sotto i 1024 la barra è in fondo e non copre niente. */
@media (min-width: 1024px){
  html{
    scroll-padding-top:calc(var(--space-32) * 2 + var(--size-header-item) + var(--space-16) * 2);
  }
}

body{
  font-family:var(--font-sans);
  color:var(--color-black);
  background:var(--color-white);
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
}

/* le immagini non si trascinano fuori dalla pagina: qui Chrome e
   Safari, Firefox non legge la proprietà e lo ferma main.js
   (dragstart). Clic destro e "Salva immagine" restano. */
img{ display:block; max-width:100%; -webkit-user-drag:none; }

::selection{ background:var(--color-primary-40); color:var(--color-black); }
/* serve perché dichiariamo display su parecchi custom element: una
   regola d'autore batte sempre quella dello user-agent, quindi senza
   questa l'attributo hidden non nasconderebbe più niente */
[hidden]{ display:none !important; }
a{ color:inherit; text-decoration:none; }
button{ font:inherit; color:inherit; background:none; border:none; cursor:pointer; }
ul{ list-style:none; }
p{ margin:0; }

@media (prefers-reduced-motion: reduce){
  *, *::before, *::after{
    animation-duration:0.001ms !important;
    animation-iteration-count:1 !important;
    transition-duration:0.001ms !important;
    scroll-behavior:auto !important;
  }
}

:focus-visible{
  outline:2px solid var(--color-primary);
  outline-offset:3px;
  border-radius:4px;
}

/* ---- container: 1700 di contenuto a 1920; oltre i 1920 resta
   boxed e il margine laterale assorbe lo spazio in più ---- */
.container{
  width:100%;
  max-width:var(--size-page-max);
  margin-inline:auto;
  padding-inline:var(--space-page-margin);
}

/* ============================================================
   GRIGLIA DI PAGINA — 12 colonne, come la griglia del Figma

   Il sito è disegnato a 1920 su 12 colonne con grondaia 16 e
   margine 110. Un blocco progettato su 10 colonne deve restare su
   10 colonne a QUALUNQUE larghezza, non essere largo 1414px: quel
   numero è lo span letto a 1920 e congelato, e scendendo verso il
   laptop smette di limitare e il blocco si allarga fino a 12.

   Si usa come le righe di Bootstrap. Il contenitore prende la
   classe, i figli occupano tutta la riga di default, e chi deve
   stare su meno colonne lo dichiara con --grid-col, nel foglio
   della pagina:

       <section class="faq page-grid">
       .faq-list{ --grid-col: 2 / span 10; }

   Solo column-gap, mai gap: la distanza VERTICALE fra i figli resta
   una decisione della section (row-gap), e un gap intero la
   sovrascriverebbe con la grondaia.

   --grid-col non si eredita (@property): senza, uno span dichiarato
   su un figlio passerebbe ai nipoti, e dentro a una griglia annidata
   li sposterebbe.

   Numero di colonne e gutter li danno --grid-columns e --grid-gutter
   in :root, gli stessi delle --size-col-*: così griglia e misure non
   possono andare fuori passo.

   Sotto i 1024 la pagina è impilata: --grid-columns vale 1, e ogni
   figlio occupa la colonna tutta. Gli span vengono ignorati lì, non
   tradotti — un "2 / span 10" dentro a una griglia da una colonna
   creerebbe dieci colonne implicite.
   ============================================================ */
@property --grid-col{ syntax:'*'; inherits:false; }
.page-grid{
  display:grid;
  grid-template-columns:repeat(var(--grid-columns), minmax(0, 1fr));
  column-gap:var(--grid-gutter);
}
.page-grid > *{ grid-column:var(--grid-col, 1 / -1); }
@media (max-width: 1023px){
  .page-grid > *{ grid-column:1 / -1; }
}

/* ============================================================
   SERVICE-BLOCK — titolo, testo e immagine di un servizio su fondo
   nero (Figma Leistungen 2065:4014). Lo usano home e /leistungen/,
   con gli stessi file in assets/images/services/: le regole stanno
   qui una volta sola.

   Il blocco porta da sé il limite di pagina e il margine, così la
   section che lo contiene può andare a tutta larghezza col suo
   sfondo nero, come .pillars e il footer.

   Testo sulle colonne 1-5 e immagine sulle 9-12 della griglia di
   pagina. L'immagine tiene il rapporto del file, 556×330, a ogni
   larghezza: prima la larghezza era ferma a 556px e l'altezza
   scendeva in vw, e object-fit:cover tagliava fino a 110px su 330.
   align-self:start perché lo stretch della griglia la allungherebbe
   all'altezza del testo accanto e l'aspect-ratio non varrebbe più.
   Il testo invece si stira: space-between tiene il pulsante al
   fondo, cioè allineato al bordo inferiore dell'immagine.
   Angoli vivi e nessun bordo, come nel frame Leistungen.
   ============================================================ */
service-block{
  width:100%;
  max-width:var(--size-page-max);
  margin-inline:auto;
  padding-inline:var(--space-page-margin);
  box-sizing:border-box;
  display:flex;
  flex-direction:column;
  gap:var(--space-48);
}
.service-block-title{ color:var(--color-white); }
.service-block-row{ row-gap:var(--space-32); }
.service-block-copy{
  --grid-col: 1 / span 5;
  display:flex;
  flex-direction:column;
  align-items:flex-start;
  justify-content:space-between;
  gap:var(--space-48);
  padding-block:var(--space-16);
}
.service-block-copy p{
  width:100%;
  font-family:var(--font-sans);
  font-size:var(--font-size-paragraph-sm);
  line-height:1.5;
  color:var(--color-white);
}
.service-block-copy p + p{ margin-top:var(--space-8); }
.service-block-media{
  --grid-col: 9 / span 4;
  align-self:start;
  aspect-ratio:556 / 330;
  overflow:hidden;
  background:var(--color-gray-15);
}
.service-block-media img{ width:100%; height:100%; object-fit:cover; }
@media (max-width: 1023px){
  .service-block-copy{ gap:32px; }
}

/* ============================================================
   SERVICE CARD — elenco servizi su fondo nero, senza immagine
   (Figma 3393:32133): home, /leistungen/ e /experten/.
   Tutta la scheda è il link, la freccia è solo un segno. All'hover
   (e al focus da tastiera) cambiano fondo e bordi: gray-90 dentro,
   primary-40 sul contorno e sul cerchio della freccia.
   Il contorno è un'ombra inset come negli altri componenti: lo
   stroke Figma sta dentro alla scheda. Nella transition ci sono
   anche opacity e transform: altrimenti questa regola, più
   specifica, cancellerebbe quella dello scroll-reveal.
   L'immagine resta nell'HTML, nascosta (hidden), se dovesse tornare.
   ============================================================ */
.service-cards{
  width:100%;
  max-width:var(--size-page-max);
  margin-inline:auto;
  padding-inline:var(--space-page-margin);
  box-sizing:border-box;
  display:flex;
  flex-direction:column;
  gap:var(--space-48);
}
.service-card{
  display:flex;
  align-items:flex-start;
  gap:var(--space-12);
  padding:var(--space-48);
  border-radius:var(--radius-24);
  box-shadow:inset 0 0 0 2px var(--color-gray-60);
  color:var(--color-white);
  transition:background-color .3s var(--ease-out), box-shadow .3s var(--ease-out),
             opacity .8s var(--ease-out), transform .8s var(--ease-out);
}
/* il testo sta su 8 colonne: 1128 a 1920, minimo il valore a 1280 */
.service-card-copy{
  display:flex;
  flex-direction:column;
  gap:var(--space-48);
  flex:0 1 clamp(752px, 58.75vw, 1128px);
  min-width:0;
}
.service-card-title{ color:var(--color-white); }
.service-card-text{ color:var(--color-white); }
.service-card-arrow{ margin-left:auto; }
.service-card:hover,
.service-card:focus-visible{
  background:var(--color-gray-90);
  box-shadow:inset 0 0 0 2px var(--color-primary-40);
}
.service-card:hover .service-card-arrow,
.service-card:focus-visible .service-card-arrow{ box-shadow:inset 0 0 0 2px var(--color-primary-40); }
@media (max-width: 1023px){
  .service-card{ flex-direction:column; gap:32px; padding:24px; }
  .service-card-copy{ flex-basis:auto; gap:24px; }
  .service-card-arrow{ margin-left:0; }
}

/* ============================================================
   SCROLL-REVEAL — la regola base sta in :where() così ha
   specificità 0: qualunque componente con una transition propria
   (hover di stat-card, case-row…) vince senza dover ricorrere
   all'ordine nel file. Serve soprattutto ora che i wrapper sono
   custom element: un selettore di tipo (0,0,1) perderebbe contro
   .reveal (0,1,0) e l'hover tornerebbe "a scatto".
   ============================================================ */
:where(.reveal){
  opacity:0;
  transform:translateY(28px);
  transition:opacity .8s var(--ease-out), transform .8s var(--ease-out);
  transition-delay:var(--reveal-delay, 0ms);
}
.reveal.is-visible{
  opacity:1;
  transform:translateY(0);
}

/* ============================================================
   TIPOGRAFIA — una classe per ogni text style di Figma,
   indipendente dal tag HTML: il tag definisce la semantica
   (h1, h2, h3…), la classe definisce l'aspetto.

   overflow-wrap:anywhere — le parole composte tedesche (es.
   "Bildschirmschoner") spezzano invece di sfondare il container;
   "anywhere" (non "break-word") riduce anche la larghezza
   min-content, così i flex item si restringono e non generano
   overflow orizzontale su mobile.
   ============================================================ */
.heading-jumbo{ font-family:var(--font-base); font-weight:600; font-size:var(--font-size-headings-jumbo); line-height:1.04; letter-spacing:-0.01em; overflow-wrap:anywhere; }
.heading-xl{  font-family:var(--font-base); font-weight:600; font-size:var(--font-size-headings-xl);  line-height:1.04; letter-spacing:-0.01em; overflow-wrap:anywhere; }
/* Headings/XL-CAP: stesso stile di XL, tutto maiuscolo. In Figma è
   uno stile a sé, non una variante applicata a mano. */
.heading-xl-cap{ font-family:var(--font-base); font-weight:600; font-size:var(--font-size-headings-xl); line-height:1.04; letter-spacing:-0.01em; text-transform:uppercase; overflow-wrap:anywhere; }
.heading-lg{  font-family:var(--font-base); font-weight:600; font-size:var(--font-size-headings-lg);  line-height:1.12; letter-spacing:-0.01em; overflow-wrap:anywhere; }
.heading-md{  font-family:var(--font-base); font-weight:600; font-size:var(--font-size-headings-md);  line-height:1.12; letter-spacing:-0.01em; overflow-wrap:anywhere; }
.heading-sm{  font-family:var(--font-base); font-weight:600; font-size:var(--font-size-headings-sm);  line-height:1.2;  letter-spacing:-0.01em; overflow-wrap:anywhere; }
.heading-xs{  font-family:var(--font-base); font-weight:600; font-size:var(--font-size-headings-xs);  line-height:1.2;  letter-spacing:-0.01em; overflow-wrap:anywhere; }
.heading-xxs{ font-family:var(--font-base); font-weight:600; font-size:var(--font-size-headings-xxs); line-height:1.3;  letter-spacing:-0.01em; overflow-wrap:anywhere; }

.paragraph-xl{ font-family:var(--font-base); font-weight:400; font-size:var(--font-size-paragraph-xl); line-height:1.3; letter-spacing:-0.01em; }
.paragraph-lg{ font-family:var(--font-base); font-weight:400; font-size:var(--font-size-paragraph-lg); line-height:1.3; letter-spacing:-0.01em; }
.paragraph-md{ font-family:var(--font-base); font-weight:400; font-size:var(--font-size-paragraph-md); line-height:1.4; letter-spacing:-0.01em; }
.paragraph-sm{ font-family:var(--font-sans); font-weight:400; font-size:var(--font-size-paragraph-sm); line-height:1.5; }
.paragraph-xs{ font-family:var(--font-sans); font-weight:400; font-size:var(--font-size-paragraph-xs); line-height:1.5; }

.review-quote{ font-family:var(--font-base); font-weight:400; font-size:var(--font-size-review-quote); line-height:1.2; letter-spacing:-0.01em; }
.ui-menu{   font-family:var(--font-base); font-weight:400; font-size:var(--font-size-paragraph-sm); line-height:1.5; }
.ui-button{ font-family:var(--font-base); font-weight:600; font-size:var(--font-size-button-lg); line-height:1; text-transform:uppercase; }

/* eyebrow NON è uno stile di testo a sé: in Figma è Paragraph/SM
   colorato in gray-40. Quindi ripete Paragraph/SM per intero —
   line-height compresa — e aggiunge solo il colore. */
.eyebrow{
  font-family:var(--font-sans);
  font-weight:400;
  font-size:var(--font-size-paragraph-sm);
  line-height:1.5;
  color:var(--color-gray-40);
}

/* ============================================================
   ICONE MONOCROMATICHE
   ------------------------------------------------------------
   Regola: il file SVG porta SOLO la forma, mai il colore. Dentro
   al file i path hanno fill="currentColor"; il colore lo decide
   il CSS. Così di ogni icona esiste UN file solo, e per cambiare
   colore si tocca una variabile, non la geometria dell'SVG.

   Il codice SVG sta DENTRO l'HTML, non in un <img>: un SVG
   caricato come immagine è un documento a sé e non eredita il
   color della pagina, quindi lì currentColor resterebbe nero.

   Ogni forma è dichiarata UNA volta in <svg class="svg-sprite">
   in cima al body, come <symbol id="icon-nome">. Nei punti d'uso
   si richiama con <use>: l'id resta unico (ripeterlo su ogni
   istanza sarebbe HTML non valido) e la geometria non si duplica.

     <svg class="icon icon--stars trust-card-stars"
          role="img" aria-label="4,9 von 5 Sternen">
       <use href="#icon-stars"></use>
     </svg>
     .trust-card-stars{ width:…; color:var(--color-primary-30); }

   role + aria-label sono obbligatori: sostituiscono l'alt.

   Le icone NON monocromatiche (loghi clienti, badge, premi,
   Google, Trustpilot) restano <img>: i loro colori sono del
   brand, non nostri token.
   ============================================================ */

/* contenitore dei <symbol>: fuori dal flusso e a dimensione zero.
   Non si usa display:none — in alcuni browser azzera anche i
   riferimenti <use>. */
.svg-sprite{
  position:absolute;
  width:0;
  height:0;
  overflow:hidden;
}

/* display:block toglie lo spazio del baseline che un <svg> inline si
   porta dietro (è un elemento inline come <img>).
   Qui NON si dichiara fill/stroke: ogni <symbol> porta già il proprio
   fill="currentColor" oppure stroke="currentColor". Ripeterlo nel CSS
   sarebbe una seconda fonte di verità per la stessa cosa. Al CSS
   resta solo il colore, tramite la classe di contesto. */
.icon{
  display:block;
  flex-shrink:0;
}
/* aspect-ratio esplicito: basta dichiarare la larghezza e
   l'altezza segue, senza dipendere dal viewBox del symbol */
.icon--stars{       aspect-ratio:156 / 24; }
.icon--arrow-right{ aspect-ratio:1; }
.icon--arrow-down{  aspect-ratio:1; }
.icon--arrow-back{  aspect-ratio:14.1249 / 14; }
.icon--asterisk{    aspect-ratio:1; }
.icon--whatsapp,
.icon--phone,
.icon--mail,
.icon--calendar,
.icon--check{       aspect-ratio:1; }
.icon--check-lg{    aspect-ratio:1; }
/* logo: una sola forma per il pittogramma, richiamata dall'header
   (verde) e dal footer (bianco). Il colore lo mette la classe di
   contesto, non il file — vedi .logo-symbol e .footer-logo. */
.icon--logo-symbol{ aspect-ratio:75.0002 / 30; }
.icon--logo-text{   aspect-ratio:209.019 / 22.4966; }

/* ---- icona +/- dell'accordion (Figma "accordion", 35:1441) ----
   Una sola forma: la stanghetta, ripetuta due volte nello stesso
   <svg> — una orizzontale fissa e una ruotata a 90°. Chiuso è un
   +, aperto la seconda ruota e diventa un -: una rotazione
   animata, non una dissolvenza fra due icone.

   Qui il codice SVG è inline e non passa dallo sprite: la barra
   da animare dev'essere un nodo vero, e i path dentro a un <use>
   finiscono in uno shadow tree che il CSS non può selezionare.

   Colore: gray-40 da chiuso, primary da aperto (come in Figma).
   Sta qui e non nel CSS di pagina così le FAQ restano identiche
   su tutte le pagine. */
.accordion-icon{
  flex-shrink:0;
  width:clamp(32px, 2.5vw, 48px);
  aspect-ratio:1;
  color:var(--color-gray-40);
  transition:color .3s var(--ease-out);
}
/* transform-box:view-box → il centro di rotazione è il centro del
   viewBox, non l'origine 0,0 del sistema SVG */
.accordion-bar-v{
  transform-box:view-box;
  transform-origin:center;
  transform:rotate(90deg);
  transition:transform .4s var(--ease-out);
}
accordion-item.is-open .accordion-icon{ color:var(--color-primary); }
accordion-item.is-open .accordion-bar-v{ transform:rotate(180deg); }

/* ============================================================
   BUTTONS — ogni variante segue esattamente il suo componente
   Figma (dimensioni, gap, presenza/assenza della freccia).
   ============================================================ */

/* button-primary: bg nero, SENZA freccia (hero "Erstgespräch",
   clients "Kontakt aufnehmen") */
.btn-primary{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  gap:var(--space-16);
  background:var(--color-black);
  color:var(--color-white);
  padding:var(--space-24) var(--space-48);
  border-radius:var(--radius-pill);
  transition: background .5s var(--ease-out), background-color .3s var(--ease-out), transform .3s var(--ease-out);
}
.btn-primary:hover{ background:var(--color-primary); }
.btn-primary .btn-label{
  display:flex; align-items:center; justify-content:center;
  height:var(--space-32);
  font-family:var(--font-base); font-weight:600;
  font-size:var(--font-size-button-lg); line-height:1; text-transform:uppercase;
}
.btn-primary .btn-arrow{ width:var(--space-32); height:var(--space-32); }

/* button-secondary: bordo nero, CON freccia (hero "Projekte ansehen")

   BORDI DEI COMPONENTI — perché box-shadow e non border
   ------------------------------------------------------------
   In Figma lo stroke di questi componenti è allineato all'INTERNO:
   la misura del frame comprende già il bordo. button-secondary è
   373×80 = padding 24+24 più la label alta 32, il bordo NON si
   somma. Con `border` i 2px per lato diventerebbero 4px in più su
   entrambi gli assi e ogni bottone risulterebbe 84 invece di 80.
   `box-shadow: inset` disegna la stessa riga senza entrare nel box.
   Vale per tutti i componenti con stroke di questo file. */
.btn-secondary{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  gap:var(--space-16);
  background:transparent;
  color:var(--color-black);
  box-shadow:inset 0 0 0 2px var(--color-black);
  padding:var(--space-24) var(--space-48);
  border-radius:var(--radius-pill);
  transition:box-shadow .3s var(--ease-out);
}
.btn-secondary:hover{ box-shadow:inset 0 0 0 2px var(--color-primary); }
.btn-secondary .btn-label{
  display:flex; align-items:center; height:var(--space-32);
  font-family:var(--font-base); font-weight:600;
  font-size:var(--font-size-button-lg); line-height:1; text-transform:uppercase;
}
.btn-secondary .btn-arrow{ width:var(--space-32); height:var(--space-32); }

/* button-primary-dark: bg BIANCO, testo nero, CON freccia */
.btn-primary-dark{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  gap:var(--space-16);
  background:var(--color-white);
  color:var(--color-black);
  padding:var(--space-24) var(--space-48);
  border-radius:var(--radius-pill);
  transition:background-color .3s var(--ease-out);
}
.btn-primary-dark:hover{ background:var(--color-primary-40); }
.btn-primary-dark .btn-label{
  display:flex; align-items:center; height:var(--space-32);
  font-family:var(--font-base); font-weight:600;
  font-size:var(--font-size-button-lg); line-height:1; text-transform:uppercase;
}
.btn-primary-dark .btn-arrow{ width:var(--space-32); height:var(--space-32); }

/* button-secondary-dark: bordo gray-20, testo BIANCO, CON freccia
   (blocchi servizio della pagina Leistungen) */
.btn-secondary-dark{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  gap:var(--space-16);
  background:transparent;
  color:var(--color-white);
  box-shadow:inset 0 0 0 2px var(--color-gray-20);
  padding:var(--space-24) var(--space-48);
  border-radius:var(--radius-pill);
  transition:box-shadow .3s var(--ease-out);
}
.btn-secondary-dark:hover{ box-shadow:inset 0 0 0 2px var(--color-primary-40); }
.btn-secondary-dark .btn-label{
  display:flex; align-items:center; height:var(--space-32);
  font-family:var(--font-base); font-weight:600;
  font-size:var(--font-size-button-lg); line-height:1; text-transform:uppercase;
}
.btn-secondary-dark .btn-arrow{ width:var(--space-32); height:var(--space-32); }

/* button-icon-primary: cerchio nero pieno con freccia (hero Leistungen) */
.btn-icon-primary{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  background:var(--color-black);
  color:var(--color-white);
  padding:var(--space-24);
  border-radius:var(--radius-pill);
  flex-shrink:0;
  transition:background-color .3s var(--ease-out);
}
.btn-icon-primary:hover{ background:var(--color-primary); }
.btn-icon-primary .icon{ width:var(--space-32); height:var(--space-32); }

/* button-icon-primary-dark (Figma 3186:11635): cerchio gray-15 per
   sopra le immagini e i video scuri, hover primary-40. Oggi i
   comandi del reel in home. */
.btn-icon-primary-dark{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  background:var(--color-gray-15);
  color:var(--color-black);
  padding:var(--space-24);
  border-radius:var(--radius-pill);
  flex-shrink:0;
  transition:background-color .3s var(--ease-out);
}
/* solo dove esiste davvero il passaggio del mouse: sui touch il :hover
   resta attaccato dopo il tocco e il pulsante rimaneva verde */
@media (hover: hover){
  .btn-icon-primary-dark:hover{ background:var(--color-primary-40); }
}
/* sul touch il verde dura solo mentre si preme, come le voci del
   menu mobile */
.btn-icon-primary-dark:active{ background:var(--color-primary-40); }
.btn-icon-primary-dark .icon{ width:var(--space-32); height:var(--space-32); }

/* filter-primary: pillola dei filtri per settore (pagina Projekte).
   Default grigio pieno, hover bianco con bordo gray-20, selezionato
   bianco con bordo primary. */
.filter-primary{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  gap:var(--space-12);
  background:var(--color-gray-15);
  box-shadow:inset 0 0 0 2px var(--color-gray-15);
  padding:var(--space-16) var(--space-32);
  border-radius:var(--radius-pill);
  transition:background-color .25s var(--ease-out), box-shadow .25s var(--ease-out);
}
.filter-primary .btn-label{
  display:flex; align-items:center; height:var(--space-20);
  font-family:var(--font-base); font-weight:600;
  font-size:var(--font-size-button-sm); line-height:1;
  text-transform:uppercase; color:var(--color-black);
}
.filter-primary:hover{
  background:var(--color-white);
  box-shadow:inset 0 0 0 2px var(--color-gray-20);
}
.filter-primary.is-active{
  background:var(--color-white);
  box-shadow:inset 0 0 0 2px var(--color-primary);
}

/* button-icon secondary (grande, PortfolioItem) */
.btn-icon-secondary{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  box-shadow:inset 0 0 0 2px var(--color-black);
  padding:var(--space-24);
  border-radius:var(--radius-pill);
  flex-shrink:0;
  transition:box-shadow .3s var(--ease-out);
}
.btn-icon-secondary:hover{ box-shadow:inset 0 0 0 2px var(--color-primary); }
.btn-icon-secondary .icon{ width:var(--space-32); height:var(--space-32); }

/* button-icon secondary-dark (per sfondi scuri) */
.btn-icon-secondary-dark{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  box-shadow:inset 0 0 0 2px var(--color-gray-20);
  padding:var(--space-24);
  border-radius:var(--radius-pill);
  flex-shrink:0;
  transition:box-shadow .3s var(--ease-out);
}
.btn-icon-secondary-dark:hover{ box-shadow:inset 0 0 0 2px var(--color-primary-40); }
.btn-icon-secondary-dark .icon{ width:var(--space-32); height:var(--space-32); }
.btn-icon-secondary-dark.is-reversed{ transform:rotate(180deg); }

/* button-icon-secondary-s (piccolo, righe CaseDownload): appare in
   hover. Nel componente il bordo è primary in ENTRAMBE le varianti —
   fra default e hover cambia solo l'opacità, non il colore. */
.btn-icon-secondary-s{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  box-shadow:inset 0 0 0 1.6px var(--color-primary);
  padding:var(--space-16);
  border-radius:var(--radius-pill);
  opacity:0;
  transition:opacity .3s var(--ease-out);
}
.btn-icon-secondary-s .icon{ width:var(--space-20); height:var(--space-20); }

/* button-primary-s: variante compatta, header e footer
   (px-32 py-16 gap-12, label h-20, testo button-sm) */
.btn-primary--s{
  padding:var(--space-16) var(--space-32);
  gap:var(--space-12);
}
.btn-primary--s .btn-label{
  height:var(--space-20);
  font-size:var(--font-size-button-sm);
}
.btn-primary--s .btn-arrow{
  width:var(--space-20);
  height:var(--space-20);
}

/* button-secondary-s: gemella bordata di button-primary-s, stesse
   misure (Figma 215:2662, 216×52). La usa /cookie-admin/. */
.btn-secondary--s{
  padding:var(--space-16) var(--space-32);
  gap:var(--space-12);
}
.btn-secondary--s .btn-label{
  height:var(--space-20);
  font-size:var(--font-size-button-sm);
}
.btn-secondary--s .btn-arrow{
  width:var(--space-20);
  height:var(--space-20);
}
/* lo stroke della variante s nel Figma è 1.6, non 2 */
.btn-secondary--s{ box-shadow:inset 0 0 0 1.6px var(--color-black); }
.btn-secondary--s:hover{ box-shadow:inset 0 0 0 1.6px var(--color-primary); }

/* button-primary-dark, variante compatta "s" (footer "Kontakt") */
.btn-primary-dark--s{ padding:var(--space-16) var(--space-32); gap:var(--space-12); }
.btn-primary-dark--s .btn-label{ height:var(--space-20); font-size:var(--font-size-button-sm); }
.btn-primary-dark--s .btn-arrow{ width:var(--space-20); height:var(--space-20); }

/* filter-secondary (Figma 2001:4076): pillola su fondo chiaro, usata
   come tag selezionabile nelle form. Default bianco su bianco, hover
   bordo gray-40, selezionato bordo primary.
   Il bordo è box-shadow e non border perché in Figma lo stroke è
   allineato all'INTERNO: la pillola misura 52 di altezza bordo
   compreso, non 56 (vedi nota sui bordi in .btn-secondary). */
.filter-secondary{
  position:relative;
  display:inline-flex;
  align-items:center;
  justify-content:center;
  gap:var(--space-12);
  background:var(--color-white);
  box-shadow:inset 0 0 0 2px var(--color-white);
  padding:var(--space-16) var(--space-32);
  border-radius:var(--radius-pill);
  cursor:pointer;
  transition:box-shadow .25s var(--ease-out);
}
.filter-secondary .btn-label{
  display:flex; align-items:center; height:var(--space-20);
  font-family:var(--font-base); font-weight:600;
  font-size:var(--font-size-button-sm); line-height:1;
  text-transform:uppercase; color:var(--color-black);
}
.filter-secondary:hover{ box-shadow:inset 0 0 0 2px var(--color-gray-40); }
.filter-secondary:has(.filter-input:checked){ box-shadow:inset 0 0 0 2px var(--color-primary); }
.filter-secondary:has(.filter-input:focus-visible){
  outline:2px solid var(--color-primary);
  outline-offset:3px;
}

/* ============================================================
   FORM — primitive condivise da tutte le pagine.
   Qui stanno solo i mattoni (campo, etichetta, input, consenso):
   griglia, larghezze e spaziature della singola form restano nel
   CSS della pagina, perché cambiano da un layout all'altro.
   ============================================================ */
form-field{
  display:flex;
  flex-direction:column;
  gap:var(--space-8);
}
/* due colonne, il campo lungo le occupa entrambe. Il numero di
   colonne è lo stesso in tutti i frame; a cambiare da una pagina
   all'altra è solo quali campi vanno a piena larghezza. */
.form-grid{
  display:grid;
  grid-template-columns:repeat(2, minmax(0, 1fr));
  gap:var(--space-32) var(--space-16);
  width:100%;
}
.form-field--full{ grid-column:1 / -1; }
.form-label{
  font-family:var(--font-sans);
  font-size:var(--font-size-paragraph-sm);
  line-height:1.5;
  color:var(--color-black);
}
.form-label--light{ color:var(--color-white); }

/* Il bordo è un box-shadow inset e non un border per due motivi:
   in focus passa da 1 a 2px senza che il campo cresca facendo
   saltare la riga, e lo stroke resta interno al box, quindi il
   campo misura 68 esatti come nel frame Figma.
   border:0 è obbligatorio: il reset azzera solo margin e padding,
   e senza input e textarea si riprendono il bordo "2px inset"
   dello user-agent. */
.form-input{
  width:100%;
  font-family:var(--font-sans);
  font-size:var(--font-size-paragraph-sm);
  line-height:1.5;
  color:var(--color-black);
  background:var(--color-white);
  border:0;
  box-shadow:inset 0 0 0 1px var(--color-gray-20);
  border-radius:var(--radius-8);
  padding:var(--space-16) var(--space-24);
  transition:box-shadow .25s var(--ease-out);
}
.form-input::placeholder{ color:var(--color-gray-40); }
/* focus nero come nel Figma (form-field, stato focus) */
.form-input:focus{ outline:none; box-shadow:inset 0 0 0 2px var(--color-black); }
/* La textarea si adatta a quello che ci si scrive: parte da tre
   righe, cresce fino a sei, e da lì in poi scorre dentro.
   Dove field-sizing non c'è (Firefox) resta ferma a tre righe e
   scorre già dalla quarta.

   lh è l'altezza di riga CALCOLATA dell'elemento, quindi "3lh" sono
   tre righe vere a qualunque viewport, senza numeri da ricalcolare a
   mano quando cambia il corpo del testo.

   box-sizing:content-box è l'UNICA deroga al border-box globale, e
   sta qui perché è ciò che rende min/max-height leggibili: misurano
   le sole righe, senza doverci sommare il padding con un calc.
   Si porta dietro width:auto, obbligatorio: con content-box un
   width:100% varrebbe "100% PIÙ il padding" e la textarea uscirebbe
   dalla colonna di 36px, con tanto di scroll orizzontale in mobile.
   La larghezza la dà comunque il contenitore, che è un flex in
   colonna e quindi la stira.
   La deroga si ferma qui: .form-input tiene border-box e width:100%,
   perché lì la larghezza dev'essere una proprietà del campo e non
   una conseguenza di come è fatto il wrapper.

   Lo scorrimento oltre il massimo non serve dichiararlo: overflow-y
   di una textarea è già auto.

   resize:none e non "vertical": il default dei browser è BOTH, e
   togliendo la riga si otterrebbe il trascinamento anche in
   orizzontale, che sfonda la colonna della form. Il ridimensionamento
   a mano non serve più, visto che l'altezza la fa il contenuto. */
.form-textarea{
  field-sizing:content;
  box-sizing:content-box;
  width:auto;
  min-height:3lh;
  max-height:6lh;
  resize:none;
}

/* ---- consenso privacy (Figma "checkbox", 2017:5451) ----
   Il quadratino nativo è nascosto e ridisegnato: acceso diventa
   nero pieno con la spunta bianca, non primary. */
.form-consent{
  position:relative;
  display:flex;
  gap:var(--space-16);
  cursor:pointer;
}
.form-consent-input{
  position:absolute;
  width:1px; height:1px;
  opacity:0;
  margin:0;
  pointer-events:none;
}
.form-consent-box{
  display:flex;
  align-items:center;
  justify-content:center;
  width:var(--size-consent-box);
  height:var(--size-consent-box);
  box-shadow:inset 0 0 0 var(--size-consent-border) var(--color-gray-60);
  border-radius:var(--radius-8);
  flex-shrink:0;
  color:var(--color-gray-60);
  transition:background-color .2s var(--ease-out), box-shadow .2s var(--ease-out), color .2s var(--ease-out);
}
.form-consent-check{
  width:var(--size-consent-check);
  opacity:0;
  transition:opacity .2s var(--ease-out);
}
.form-consent:has(.form-consent-input:checked) .form-consent-box{
  background:var(--color-black);
  box-shadow:inset 0 0 0 var(--size-consent-border) var(--color-black);
  color:var(--color-white);
}
.form-consent:has(.form-consent-input:checked) .form-consent-check{ opacity:1; }
.form-consent:has(.form-consent-input:focus-visible) .form-consent-box{
  outline:2px solid var(--color-primary);
  outline-offset:3px;
}
.form-consent-text{
  font-family:var(--font-sans);
  font-size:var(--font-size-paragraph-xs);
  line-height:1.5;
  color:var(--color-gray-80);
}
.form-consent-text a{
  text-decoration:underline;
  transition:color .25s var(--ease-out);
}
.form-consent-text a:hover{ color:var(--color-primary); }

/* Su fondo nero (Figma checkbox-dark, newsletter): testo gray-15,
   casella gray-40; spuntata bianca con la spunta nera; in errore
   bianca col bordo rosso. */
.form-consent--dark .form-consent-text{ color:var(--color-gray-15); }
.form-consent--dark .form-consent-box{ box-shadow:inset 0 0 0 var(--size-consent-border) var(--color-gray-40); }
.form-consent--dark:has(.form-consent-input:checked) .form-consent-box{
  background:var(--color-white);
  box-shadow:inset 0 0 0 var(--size-consent-border) var(--color-white);
  color:var(--color-black);
}
.form-consent--dark:has(.form-consent-input[aria-invalid="true"]) .form-consent-box{
  background:var(--color-white);
  box-shadow:inset 0 0 0 var(--size-consent-border) var(--color-error);
}

/* due caselle una sotto l'altra (Neuigkeiten + Datenschutz), accanto
   al pulsante come prima stava la casella sola */
.form-consents{ display:flex; flex-direction:column; gap:var(--space-16); }

/* ---- stati della form (Figma form-field, checkbox, button-primary) ----
   Errore: bordo 2px Primary/error e messaggio Paragraph/XS sotto.
   Disattivato (durante l'invio): fondo gray-15, bordo gray-20, testo
   gray-40; il pulsante diventa gray-40. Gli errori li scrive main.js,
   che li collega al campo con aria-describedby. */
.form-input[aria-invalid="true"],
.form-input[aria-invalid="true"]:focus{ box-shadow:inset 0 0 0 2px var(--color-error); }
.form-input:disabled{
  background:var(--color-gray-15);
  box-shadow:inset 0 0 0 1px var(--color-gray-20);
  color:var(--color-gray-40);
}
.form-error{
  display:block;
  font-family:var(--font-sans);
  font-size:var(--font-size-paragraph-xs);
  line-height:1.5;
  color:var(--color-error);
}
.form-consent:has(.form-consent-input[aria-invalid="true"]) .form-consent-box{
  box-shadow:inset 0 0 0 var(--size-consent-border) var(--color-error);
}
.btn-primary:disabled,
.btn-primary:disabled:hover{ background:var(--color-gray-40); cursor:default; }
.filter-input:disabled + .btn-label{ opacity:.5; }

/* ---- messaggio dopo l'invio (Figma form-message) ----
   Copre lo spazio della form, che resta al suo posto invisibile:
   la pagina non salta. Testo Headings/XXS, alternativa Paragraph/SM. */
form.is-done{ position:relative; }
form.is-done > :not(.form-message){ visibility:hidden; }
.form-message{
  position:absolute;
  inset:0;
  display:flex;
  flex-direction:column;
  align-items:center;
  justify-content:center;
  gap:var(--space-48);
  padding-inline:var(--space-80);
  text-align:center;
  outline:none;
}
.form-message[hidden]{ display:none; }
.form-message-text{ max-width:682px; }
.form-message-alt{ display:flex; flex-direction:column; align-items:center; gap:var(--space-24); }
@media (max-width: 767px){
  .form-message{ padding-inline:0; }
}

/* ---- form su fondo nero (Figma form-field-dark, newsletter) ----
   Campo bianco come l'altro; cambia il focus, primary-40 invece del
   nero che sul fondo nero sparirebbe. Messaggio finale in bianco. */
.form--dark .form-input:focus{ box-shadow:inset 0 0 0 2px var(--color-primary-40); }
.form--dark .form-input[aria-invalid="true"],
.form--dark .form-input[aria-invalid="true"]:focus{ box-shadow:inset 0 0 0 2px var(--color-error); }
.form--dark .form-message{ color:var(--color-white); }
.btn-primary-dark:disabled,
.btn-primary-dark:disabled:hover{ background:var(--color-gray-40); cursor:default; }

/* l'input resta nel DOM e nel tab order (serve per tastiera e per
   l'invio della form): è solo invisibile e senza ingombro */
.filter-input{
  position:absolute;
  width:1px; height:1px;
  opacity:0;
  margin:0;
  pointer-events:none;
}

/* ============================================================
   CAROSELLO — scorrimento orizzontale con aggancio.

   Scorrimento e aggancio li fa il CSS; il JS (main.js) sposta solo
   scrollLeft per le frecce e l'avanzamento automatico, e clona le
   prime card per il giro infinito.

   Marcatura attesa:
     <card-scroller class="carousel">
       <div class="carousel-track"> …card… </div>
     </card-scroller>
     <div class="carousel-nav" hidden> …due bottoni… </div>

   Le misure delle card restano al CSS di pagina: qui c'è solo la
   meccanica dello scorrimento, che è identica ovunque.
   ============================================================ */
.carousel{
  width:100%;
  overflow-x:auto;
  scrollbar-width:none;
  -webkit-overflow-scrolling:touch;
  scroll-snap-type:x mandatory;
  /* le card si agganciano al margine di pagina, non al bordo dello
     schermo: lo dice scroll-padding, il padding del track serve solo
     a distanziare visivamente la prima e l'ultima */
  scroll-padding-inline-start:var(--space-page-margin);
}
.carousel::-webkit-scrollbar{ display:none; }
.carousel-track{
  display:flex;
  align-items:stretch;
  gap:var(--space-16);
  width:max-content;
  padding-inline:var(--space-page-margin);
}
.carousel-track > *{ scroll-snap-align:start; }

/* fila delle frecce, in basso a destra */
.carousel-nav{
  display:flex;
  justify-content:flex-end;
  gap:var(--space-20);
  padding-inline:clamp(93.333px, 7.292vw, 140px);
}

/* ============================================================
   STICKY HEADER — su desktop resta in alto; allo scroll il pill si
   restringe in larghezza (l'interpolazione è in main.js, qui ci
   sono solo gli stati di partenza e di arrivo). Sfondo e blur non
   fanno parte dell'animazione: sono sempre attivi.
   ============================================================ */
.site-header{
  position:fixed;
  top:0; left:0; right:0;
  z-index:1000;
}

menu-sticky{
  display:flex;
  justify-content:center;
  width:100%;
  max-width:var(--size-page-max);
  margin-inline:auto;
  padding:var(--space-32) calc( var(--space-page-margin) - var(--space-32) ) 0;
}

/* Il pill NON ha padding verticale: lo spacing-16 sopra e sotto è
   spostato dentro ai figli (logo, voci di menu, CTA). Così il box
   di ogni .nav-item arriva fino al bordo del pill e nav-dropdown,
   ancorato a top:100%, gli resta adiacente: scendendo dalla voce
   verso il submenu il puntatore non attraversa mai un'area fuori
   hover, quindi il menu non lampeggia. */
.nav-pill{
  display:flex;
  align-items:center;
  justify-content:space-between;
  width:100%;
  gap:0;
  /* espanso in cima alla pagina il pill è invisibile ma dello stesso
     colore: allo scroll cambia solo l'opacità, in dissolvenza.
     Su mobile lo sfondo vale sempre, vedi il media query in fondo. */
  background:var(--menu-pill-bg-off);
  transition:background-color .3s var(--ease-out);
  backdrop-filter:blur(16px);
  -webkit-backdrop-filter:blur(16px);
  border-radius:var(--radius-pill);
  padding-block:0;
  padding-inline:var(--space-32);
}
.site-header.is-scrolled .nav-pill{
  background:var(--menu-pill-bg);
  width:fit-content;
  gap:var(--space-64);
}

.logo{ display:flex; align-items:center; flex-shrink:0; padding-block:var(--space-16); }

/* Logo in cima alla pagina. Serve solo dove la barra sta in fondo:
   sopra i 1024 il logo è già nell'header. Riusa .logo-symbol e
   .logo-text dell'header, che portano misure e ritaglio. */
.page-logo{ display:none; }

.logo-symbol{
  position:relative;
  width:clamp(50px, 3.906vw, 75px);
  height:var(--size-header-item);
  overflow:hidden;
  flex-shrink:0;
  color:var(--color-primary);
}
.logo-symbol svg{
  position:absolute;
  top:50%; left:0;
  transform:translateY(-50%);
  width:clamp(50px, 3.906vw, 75px);
  height:clamp(20px, 1.5625vw, 30px);
}

.logo-text{
  position:relative;
  width:clamp(149px, 11.667vw, 224px);
  height:var(--size-header-item);
  overflow:hidden;
  flex-shrink:0;
  color:var(--color-black);
}
.site-header.is-scrolled .logo-text{ width:0; }
.logo-text svg{
  position:absolute;
  left:clamp(10px, 0.78vw, 15px);
  top:50%;
  transform:translateY(-50%);
  width:clamp(139.4px, 10.886vw, 209.02px);
  height:clamp(15px, 1.1717vw, 22.5px);
}

/* stretch e non center: la CTA è di un paio di px più alta delle
   voci, e con il centering le voci resterebbero staccate dal bordo
   del pill — cioè nav-dropdown partirebbe da dentro il pill. Con
   lo stretch il box della voce coincide sempre con l'altezza del
   pill, a qualunque viewport. */
.nav-list{
  display:flex;
  align-items:stretch;
  align-self:stretch;
  gap:var(--space-32);
  flex-shrink:0;
}

/* menu-item: l'altezza del testo (= header-item-h) nasce da
   line-height 1.5 + 2 × spacing-8 sul link, come in Figma; lo
   spacing-16 che prima stava sul pill è qui, così il box della
   voce tocca il bordo del pill ed è contiguo a nav-dropdown. */
.nav-item{
  position:relative;
  display:flex;
  align-items:center;
  padding-block:var(--space-16);
}

.nav-link{
  display:flex;
  align-items:center;
  justify-content:center;
  padding-block:var(--space-8);
  font-family:var(--font-base);
  font-weight:400;
  font-size:var(--font-size-paragraph-sm);
  line-height:1.5;
  color:var(--color-black);
  white-space:nowrap;
  transition:color .3s var(--ease-out);
}
/* Verde sulla voce della sezione in cui ci si trova, non solo sulla
   pagina esatta: "Leistungen" è verde sia su /leistungen/ sia su
   /leistungen/crm-systeme/. A distinguere i due casi è l'aria —
   aria-current="page" la pagina, "true" la sezione — mentre il
   colore è lo stesso, perché per chi guarda il senso è quello. */
.nav-link.is-current{ color:var(--color-primary); }
/* La voce della pagina in cui si è non è un link: è uno <span>, così
   non ha href e il cursore resta la freccia. Il selettore sull'aria
   copre anche il caso di un <button> come trigger, che dal reset si
   porterebbe dietro la manina.
   Attenzione: vale solo per aria-current="page". Sulla SEZIONE
   ("Leistungen" stando su crm-systeme) il link deve restare tale,
   perché porta a una pagina diversa da quella in cui si è. */
.nav-link[aria-current="page"],
.mobile-list-item[aria-current="page"],
.submenu-item[aria-current="page"]{ cursor:default; }
/* :not(.is-current) perché hover e is-current hanno la stessa
   specificità: senza, passando il mouse sulla voce della sezione in
   cui si è già, il verde tornava grigio. E il grigio dell'hover vuol
   dire "ci puoi andare", che lì non ha senso. */
.nav-link:not(.is-current):hover{ color:var(--color-gray-80); }

/* la CTA ha già il suo padding (è il pill nero visibile): qui serve
   solo lo stacco dal bordo, quindi margin e non padding */
.nav-pill > .btn-primary{ margin-block:var(--space-16); }

/* ---- SUBMENU DESKTOP (Figma 369:4725) ----
   Il wrapper nav-dropdown è il "ponte" di hover: parte da top:100%
   di .nav-item — che grazie al suo padding-block arriva al bordo
   del pill — e in Figma il frame drop-down ha padding-top =
   spacing-8, ed è proprio quel padding a coprire gli 8px fra il
   pill e il pannello. Se fosse un margin, il puntatore uscirebbe
   dall'area hover attraversando il vuoto e il submenu si
   chiuderebbe: qui invece l'area resta continua da .nav-item fino
   a dropdown-menu.
   PROVA IN CORSO — centraggio orizzontale sulla voce.
   left:50% porta il bordo sinistro del pannello a metà della voce,
   translateX(-50%) lo tira indietro di metà della propria
   larghezza: il centro cade sul centro, qualunque sia la larghezza.

   Per tornare indietro basta rimettere queste due righe al posto
   di left/transform qui sotto:
       left:calc( -1 * (var(--space-16) + var(--space-24) + 1px) );
   Allineava il TESTO del submenu a quello della voce, sottraendo il
   padding del pannello più quello della voce (+1 di bordo) — in
   Figma left -40 a 1920. Sono due criteri diversi: o la scatola è
   centrata sulla voce, o il testo è incolonnato col testo. */
nav-dropdown{
  display:block;
  position:absolute;
  top:100%;
  left:50%;
  transform:translateX(-50%);
  padding-top:var(--space-8);
  z-index:10;
  opacity:0;
  visibility:hidden;
  transition:opacity .3s var(--ease-out), visibility .3s;
}
.nav-item--dropdown:hover nav-dropdown,
.nav-item--dropdown:focus-within nav-dropdown{
  opacity:1;
  visibility:visible;
}

dropdown-menu{
  display:flex;
  flex-direction:column;
  background:var(--color-white);
  border:1px solid var(--color-gray-20);
  border-radius:var(--radius-32);
  padding:var(--space-16);
}

.submenu-item{
  padding:var(--space-8) var(--space-24);
  border-radius:var(--radius-24);
  font-family:var(--font-base);
  font-weight:400;
  font-size:var(--font-size-paragraph-sm);
  line-height:1.5;
  color:var(--color-gray-60);
  white-space:nowrap;
  transition:color .25s var(--ease-out), background-color .25s var(--ease-out);
}
.submenu-item:not(.is-current):hover{
  background:var(--color-gray-15);
  color:var(--color-black);
}
/* La voce corrente tiene il pill dell'hover ma scrive in verde: è
   lo stesso segnale che prende la voce di primo livello, così da
   qualunque punto del menu si capisce dove si è. */
.submenu-item.is-current{
  background:var(--color-gray-15);
  color:var(--color-primary);
}

/* ---- MEGA MENU Leistungen (Figma 3353:10176) ----
   Tre colonne — Modelle, Expert:innen, Leistungen — larghe quanto
   la pagina, non quanto la voce. Si apre come gli altri sottomenu,
   su :hover e :focus-within della voce (regola qui sopra): la voce
   è un <button> senza azione, come "Über uns".
   Il pannello NON può ancorarsi a menu-sticky: il backdrop-filter
   fa del pill il contenitore di ogni discendente assoluto, e il pill
   allo scroll si restringe. Però resta sempre centrato nella pagina,
   quindi left:50% sul pill è il centro della pagina; la larghezza la
   dà menu-sticky come container. 100cqw è il suo box di CONTENUTO,
   che sta già dentro al padding (margine di pagina − spacing-32):
   per arrivare al margine di pagina si tolgono i due spacing-32. La voce rinuncia al proprio contesto (static) per
   passare il riferimento al pill.
   Le colonne sono col-3 · col-6 · col-3 della griglia di pagina, con
   i due divisori da 1px e 6px di gap ai lati di ciascuno: è la
   somma del frame Figma (1700 a 1920, con 4px di avanzo centrati). */
menu-sticky{ container-type:inline-size; }
.nav-item--mega{ position:static; }
.nav-item--mega nav-dropdown{
  width:calc(100cqw - 2 * var(--space-32));
}
mega-menu{
  display:grid;
  grid-template-columns:var(--size-col-3) 1px var(--size-col-6) 1px var(--size-col-3);
  justify-content:center;
  column-gap:6px;
  padding-block:var(--space-48);
  background:var(--color-white);
  border:1px solid var(--color-gray-20);
  border-radius:var(--radius-32);
}
.mega-divider{ background:var(--menu-pill-bg); }
.mega-col{
  display:flex;
  flex-direction:column;
  gap:var(--space-32);
  min-width:0;
  padding-inline:var(--space-24);
}
.mega-col-top{
  display:flex;
  flex-direction:column;
  gap:var(--space-24);
  flex:1 1 auto;
}
.mega-col-head{
  display:flex;
  flex-direction:column;
  gap:var(--space-8);
  padding-inline:var(--space-24);
  color:var(--color-black);
}
.mega-links{ display:flex; gap:var(--space-16); }
.mega-list{ display:flex; flex-direction:column; flex:1 1 0; min-width:0; }
.mega-list > li{ display:flex; }   /* la voce abbraccia il testo, senza la riga di base sotto */
.mega-col-cta{ padding-inline:var(--space-24); }
.mega-col-cta .btn-label{ white-space:nowrap; }   /* come nel Figma: il testo non va a capo */
/* sotto i 1280 la prima colonna è più stretta del pulsante (a 1024
   uscirebbe di 30px sul divisorio): lì il testo va su due righe */
@media (max-width: 1279px){ .mega-col-cta .btn-label{ white-space:normal; } }

/* ---- VELO sotto ai menu aperti ----
   Nero al 50% con lo stesso blur del pill, su tutta la finestra:
   sotto al mega menu Leistungen (desktop) e sotto a tutto il menu
   mobile aperto. È un ::before dell'header: z-index:-1 lo mette
   dentro al suo contesto, quindi sopra alla pagina ma sotto a barra
   e pannelli. pointer-events:none: non cambia niente nei clic, il
   menu si chiude come prima (uscita del puntatore, tocco fuori). */
.site-header::before{
  content:"";
  position:fixed;
  inset:0;
  z-index:-1;
  background:color-mix(in srgb, var(--color-black) 50%, transparent);
  backdrop-filter:blur(16px);
  -webkit-backdrop-filter:blur(16px);
  opacity:0;
  visibility:hidden;
  pointer-events:none;
  transition:opacity .3s var(--ease-out), visibility .3s;
}
@media (min-width: 1024px){
  .site-header:has(.nav-item--mega:hover)::before,
  .site-header:has(.nav-item--mega:focus-within)::before{ opacity:1; visibility:visible; }
}
.site-header.is-menu-open::before{ opacity:1; visibility:visible; }
/* col velo il logo diventa bianco, simbolo e scritta: il nero
   della scritta sul velo scuro non si leggerebbe */
.logo-symbol,
.logo-text{ transition:color .3s var(--ease-out); }
@media (min-width: 1024px){
  .site-header:has(.nav-item--mega:hover) :is(.logo-symbol, .logo-text),
  .site-header:has(.nav-item--mega:focus-within) :is(.logo-symbol, .logo-text){ color:var(--color-white); }
}
.site-header.is-menu-open :is(.logo-symbol, .logo-text){ color:var(--color-white); }

/* ---- custom element: display esplicito, altrimenti sono inline.
   card-scroller è usato due volte (testimonial e kompetenzen): il
   tag porta il display, le due classi solo le differenze. ---- */
card-scroller,
marquee-band,
video-embed,
accordion-item,
logo-frame{ display:block; }

/* questi due vengono usati solo dal menu mobile, ma il display va
   dichiarato anche fuori dalla media query: senza, restano inline
   nel resto del sito e in ogni pagina che li riusi */
menu-panel,
contact-row{ display:flex; }

/* il toggle "Menu" e il pannello mobile non esistono da 1024 in su */
.nav-menu-toggle,
menu-mobile{ display:none; }

/* ============================================================
   MENU MOBILE (Figma 374:3176 "menu-mobile-anim")
   ------------------------------------------------------------
   Sotto i 1024px l'header si ancora in BASSO: la barra resta
   fissa sul bordo inferiore e il pannello cresce sopra di essa.

   1. apertura e chiusura: una dissolvenza, senza movimento (la
      salita da dietro la barra è stata tolta il 2026-11-03).
   2. drill-down (open → Leistungen / Über uns): scorrimento
      ORIZZONTALE. In Figma lo slot del primo livello si sposta a
      left -265 (fuori a sinistra) e quello del sottomenu arriva
      da left +285 (fuori a destra). Solo il pannello attivo è in
      flusso (position:relative), gli altri sono assoluti: così
      l'altezza del contenitore segue sempre il pannello visibile,
      esattamente come le varianti del componente.
   ============================================================ */
@media (max-width: 1023px){
  /* Il .container porta un padding-inline pari al margine di pagina,
     ma quasi sempre sta dentro a una sezione che lo ha già: il
     margine si sommava e il testo restava 262px invece di 326.
     Su mobile ogni pixel conta, quindi qui non lo aggiunge. */
  .container{ padding-inline:0; }

  .carousel-nav{ padding-inline:var(--space-page-margin); }
  .site-header{
    top:auto;
    bottom:0;
  }
  menu-sticky{
    flex-direction:column;
    align-items:stretch;
    /* misura propria del menu, non più il margine di pagina */
    padding:0 var(--menu-bar-pad) var(--menu-bar-pad);
  }

  /* nel pill mobile restano logo e toggle: le voci in linea e la
     CTA "Kontakt" vivono dentro il pannello */
  .nav-list,
  .nav-pill > .btn-primary{ display:none; }

  /* sfondo e blur arrivano già dalla regola base */
  .nav-pill{
    padding:0 var(--menu-pill-pad);
    /* qui la barra non si espande mai: lo sfondo vale sempre */
    background:var(--menu-pill-bg);
  }
  /* niente restringimento allo scroll: la barra è già compatta */
  .site-header.is-scrolled .nav-pill{
    width:100%;
    gap:0;
  }
  /* nella barra mobile resta il solo simbolo, come in Figma
     (logo-text a larghezza 0). Qui l'altezza della barra la dà il
     toggle: il padding-block che su desktop porta il logo a filo
     del pill va tolto, altrimenti alza la barra. */
  .logo{ padding-block:0; }
  .logo-text{ width:0; }

  .nav-menu-toggle{
    display:flex;
    align-items:center;
    padding:var(--menu-toggle-pad);
    font-family:var(--font-base);
    font-weight:400;
    font-size:var(--menu-font-toggle);
    line-height:1.5;
    color:var(--color-black);
  }

  /* --- pannello --- */
  menu-mobile{
    display:block;
    /* nessun padding laterale: la dropdown è larga quanto la barra,
       e lo stacco dai bordi lo dà già menu-sticky */
    padding-inline:0;
    padding-bottom:var(--menu-panel-pad-bottom);
  }

  /* Apertura e chiusura in dissolvenza, senza movimento. L'altezza
     segue il pannello attivo (l'unico in flusso), con un tetto: lo
     schermo meno la barra e i suoi margini. */
  .mobile-menu-clip{
    overflow:hidden;
    display:flex;
    flex-direction:column;
    min-height:0;
    max-height:calc(100dvh - var(--menu-bar-h) - var(--menu-bar-pad) * 2 - var(--menu-panel-pad-bottom));
    opacity:0;
    visibility:hidden;
    transition:opacity .3s var(--ease-out), visibility .3s;
  }
  .site-header.is-menu-open .mobile-menu-clip{
    opacity:1;
    visibility:visible;
  }

  dropdown-menu{
    position:relative;
    display:flex;
    flex-direction:column;
    background:var(--color-white);
    /* lo stroke Figma non occupa spazio (295 = 327 - 16 - 16):
       inset invece di border, così il contenuto resta 295.
       Il border:1px della regola base — quella del sottomenu
       desktop — va azzerato, altrimenti si somma. */
    border:0;
    box-shadow:inset 0 0 0 var(--menu-border) var(--color-gray-20);
    border-radius:var(--menu-dropdown-radius);
    padding:var(--menu-dropdown-pad);
    overflow:hidden;
  }

  menu-panel{
    position:absolute;
    inset-block-start:0;
    inset-inline-start:0;
    width:100%;
    display:flex;
    flex-direction:column;
    gap:var(--menu-gap);
    transform:translateX(100%);
    opacity:0;
    visibility:hidden;
    transition:transform .4s var(--ease-out), opacity .3s var(--ease-out), visibility .4s;
  }
  menu-panel.is-active{
    position:relative;
    transform:translateX(0);
    opacity:1;
    visibility:visible;
  }
  /* il primo livello esce a sinistra mentre il sottomenu entra */
  menu-panel.is-behind{ transform:translateX(-100%); }

  .mobile-back{
    display:flex;
    align-items:center;
    justify-content:center;
    align-self:flex-start;
    padding:var(--menu-back-pad);
    border-radius:var(--radius-pill);
  }
  .mobile-back .icon{
    width:var(--menu-arrow);
    height:var(--menu-arrow);
    transform:rotate(180deg);   /* arrow-right ruotata, come in Figma */
  }

  /* la lista non ha spaziature proprie: le porta la singola voce */
  .mobile-list{
    display:flex;
    flex-direction:column;
  }
  /* lo stacco in alto ce l'ha solo il primo livello: nei sottomenu
     la distanza dal bordo la fa già il tasto indietro. Nei pannelli
     Leistungen e Über uns le liste sono due, e applicandolo a tutte
     il pannello cresceva di 10px per lista. */
  menu-panel[data-panel="root"] .mobile-list{
    padding-top:var(--menu-list-pad-top);
  }
  /* menu-item-mobile (Figma 381:3296). Il padding orizzontale sta
     QUI e non sulla lista: così lo sfondo dello stato premuto
     copre anche i fianchi della voce, non solo sopra e sotto. */
  .mobile-list-item{
    display:flex;
    align-items:center;
    width:100%;
    justify-content:space-between;
    gap:var(--menu-item-pad-x);
    padding:var(--menu-item-pad-y) var(--menu-item-pad-x);
    border-radius:var(--menu-item-radius);
    font-family:var(--font-base);
    font-weight:600;
    font-size:var(--menu-font-item);
    line-height:1.5;
    color:var(--color-black);
    text-align:left;
  }
  /* in Figma la variante si chiama "hover", ma qui il menu esiste
     solo su touch: lo stato è quello premuto, non il passaggio
     del mouse. */
  .mobile-list-item:active{ background:var(--menu-item-bg-tap); }
  .mobile-list-item.is-current{ color:var(--color-primary); }

  /* freccia delle voci che aprono un sottomenu */
  .mobile-list-arrow{
    width:var(--menu-arrow);
    flex-shrink:0;
  }

  .mobile-separator{
    height:2px;
    margin-inline:var(--menu-sep-inset);
    background:var(--color-gray-20);
    border:0;
  }

  /* --- pannello Leistungen (Figma 2236:9337) ---
     Tre gruppi — Modelle, Expert:innen, Leistungen — più lunghi
     dello schermo: il tasto indietro resta fermo in alto e sotto
     scorre il resto. Il pannello è a tutto schermo: l'altezza è
     quella del tetto del menu aperto (schermo meno barra, margini
     e scatola) meno il tasto indietro e il suo stacco. */
  menu-panel[data-panel="leistungen"]{ gap:var(--menu-group-back-gap); }
  .mobile-scroll{
    display:flex;
    flex-direction:column;
    gap:var(--menu-gap);
    height:calc(
      100dvh - var(--menu-bar-h) - var(--menu-bar-pad) * 2 - var(--menu-panel-pad-bottom)
      - var(--menu-dropdown-pad) * 2
      - (var(--menu-back-pad) * 2 + var(--menu-arrow)) - var(--menu-group-back-gap)
    );
    overflow-x:hidden;
    overflow-y:auto;
    overscroll-behavior:contain;
  }
  /* in un flex ad altezza fissa i figli si stringerebbero invece di
     scorrere: i separatori da 2px sparivano */
  .mobile-scroll > *{ flex-shrink:0; }
  /* barra di scorrimento da 2px, come nel Figma (nero al 6% la
     guida, al 20% il cursore) */
  .mobile-scroll::-webkit-scrollbar{ width:6px; }
  .mobile-scroll::-webkit-scrollbar-track{ border-right:4px solid transparent; background:rgb(17 17 17 / .06) content-box; }
  .mobile-scroll::-webkit-scrollbar-thumb{ border-right:4px solid transparent; background:rgb(17 17 17 / .2) content-box; }
  @supports not selector(::-webkit-scrollbar){
    .mobile-scroll{ scrollbar-width:thin; scrollbar-color:rgb(17 17 17 / .2) rgb(17 17 17 / .06); }
  }
  .mobile-group{
    display:flex;
    flex-direction:column;
    gap:var(--menu-group-gap);
    padding-bottom:var(--menu-gap);
  }
  .mobile-group-top{
    display:flex;
    flex-direction:column;
    gap:var(--menu-gap);
  }
  .mobile-group-head{
    display:flex;
    flex-direction:column;
    gap:var(--menu-group-head-gap);
    padding-inline:var(--menu-group-head-pad);
    color:var(--color-black);
  }
  .mobile-group-cta{ padding-inline:var(--menu-item-pad-x); }

  /* riga di contatto diretto: Whatsapp · Telefon · E-Mail */
  contact-row{
    display:flex;
    align-items:center;
    gap:var(--menu-contact-gap);
    width:100%;
  }
  .mobile-contact-item{
    flex:1 1 0;
    min-width:0;
    display:flex;
    flex-direction:column;
    align-items:center;
    justify-content:center;
    gap:var(--menu-dm-gap);
    padding:var(--menu-dm-pad-y) var(--menu-dm-pad-x);
    border-radius:var(--menu-dm-radius);
    background:var(--color-gray-15);
  }
  /* il fondo della tile è già gray-15: da premuta si scurisce di
     poco tirando verso gray-20 (prima erano due grigi distinti
     della vecchia scala, ora collassati in un unico token).
     Stato di tap, non hover: il menu esiste solo su touch. */
  .mobile-contact-item:active{ background:color-mix(in srgb, var(--color-gray-20) 15%, var(--color-gray-15)); }
  .mobile-contact-item .icon{ width:var(--menu-dm-icon); height:var(--menu-dm-icon); }
  .mobile-contact-item span{
    font-family:var(--font-sans);
    font-size:var(--menu-font-dm);
    line-height:1.5;
    color:var(--color-black);
  }

  /* --- logo in cima alla pagina (Figma 374:3787) ---
     24px dal bordo e dall'alto, poi 30px fino al primo contenuto:
     nel frame il titolo attacca a 88px, cioè 24 + 34 di logo + 30. */
  .page-logo{
    display:flex;
    align-items:center;
    width:max-content;
    margin-block-start:var(--space-page-margin);
    margin-inline-start:var(--space-page-margin);
  }
  /* nell'header il testo del logo è nascosto, qui no */
  .page-logo .logo-text{ width:clamp(149px, 11.667vw, 224px); }

  /* con il menu aperto la pagina dietro non scrolla */
  body.has-menu-open{ overflow:hidden; }
}

/* ============================================================
   SCHERMO BASSO (telefono coricato) — sotto i 540px di altezza
   il menu intero (490px) non ci sta. Spariscono i contatti e le
   voci scendono a 16px. Il pannello Leistungen resta comunque
   più alto dello schermo: lì il tetto di apertura lo ferma al
   bordo e lo si scorre.
   La soglia è sull'ALTEZZA, non su orientation:landscape, che
   prenderebbe anche i portatili.
   ============================================================ */
@media (max-width: 1023px) and (max-height: 540px){
  :root{ --menu-font-item:16px; }
  contact-row{ display:none; }
  /* min-height:0 toglie il vincolo di min-content sul flex item:
     senza, non si accorcerebbe e non scorrerebbe */
  dropdown-menu{
    min-height:0;
    overflow-x:hidden;
    overflow-y:auto;
  }
}

/* ============================================================
   FOOTER — sticky. Il main ha z-index e sfondo propri e scorre
   SOPRA il footer (position:fixed dietro). Il margin-bottom del
   main — pari all'altezza del footer, impostato via JS — libera
   in fondo lo spazio che rivela il footer mentre si scrolla.
   ============================================================ */
main{
  position:relative;
  z-index:1;
  background:var(--color-white);
}
.site-footer{
  position:fixed;
  left:0; right:0; bottom:0;
  z-index:-1;
  background:var(--color-black);
  color:var(--color-white);
}
/* ---- velo del footer
   Mentre il footer si scopre resta sotto a un velo nero che si
   dirada: appena spunta è pieno, a footer scoperto è a zero. A
   guidarlo è lo scorrimento e non un timer — è una scroll-driven
   animation, quindi gira sul compositore e non costa JS.

   Il timeline è quello della PAGINA, non del footer: il footer è
   position:fixed, non scorre, e una view() su di lui non avanzerebbe
   mai di un millimetro. La finestra utile sono gli ultimi --footer-h
   pixel di scorrimento, che è esattamente quanto dura il reveal;
   quella misura la scrive il JS, che il footer lo misura già per il
   margin-bottom del main.

   @supports perché dove le scroll-driven animation non ci sono il
   velo semplicemente non esiste e il footer si comporta come prima.
   Sotto i 1024 e sulla 404 il footer è nel flusso: lì il velo è
   spento (vedi più avanti). */
@supports (animation-timeline: scroll()) {
  .site-footer::after{
    content:"";
    position:absolute;
    inset:0;
    background:var(--color-black);
    pointer-events:none;
    opacity:1;
    animation:footer-scrim-fade linear both;
    animation-timeline:scroll(root block);
    animation-range:calc(100% - var(--footer-h, 0px)) 100%;
  }
  /* Il velo resta pieno per il primo 30% della finestra e si dirada
     nel restante 70%: così la striscia che spunta per prima — le
     righe in fondo al footer — esce ancora nera, e il diradarsi
     comincia quando c'è già qualcosa da scoprire.
     La soglia è stata 10% e poi 50%: a 10 il nero se ne andava
     troppo presto, a 50 il velo restava pieno per metà corsa e poi
     spariva di colpo. */
  @keyframes footer-scrim-fade{
    0%, 30%{ opacity:1 }
    100%   { opacity:0 }
  }
}
.footer-inner{
  width:100%;
  max-width:var(--size-page-max);
  margin-inline:auto;
  padding:var(--space-128) var(--space-page-margin) var(--space-80);
  display:flex;
  flex-direction:column;
  gap:var(--space-128);
}
/* Il footer sta sulla griglia di pagina: dodici colonne, grondaia
   var(--space-16). Il marchio ne occupa 3, le tre liste 2 ciascuna
   in fondo, e le 3 colonne vuote in mezzo sono la distanza fra i due
   blocchi — non un gap.

   Era un flex con justify-content:space-between e un max-width per
   blocco, e il difetto era strutturale: a 1920 i due blocchi
   toccavano subito il loro tetto (405 e 842) e da lì non scendevano
   più, quindi restringendo la finestra si mangiava solo il vuoto
   centrale — da 453px a 57px fra 1920 e 1440 — mentre le liste
   restavano larghe uguali. Si avvicinavano invece di stringersi.
   Con le colonne la larghezza di ogni blocco è una frazione della
   pagina, quindi scalano tutti insieme. */
.footer-top{
  display:grid;
  grid-template-columns:repeat(12, minmax(0, 1fr));
  gap:var(--space-16);
}
.footer-brand{
  grid-column:1 / span 3;
  display:flex;
  flex-direction:column;
  align-items:flex-start;
  gap:var(--space-24);
}
.footer-logo{ display:block; color:var(--color-white); }
.footer-logo .icon{ height:clamp(21.333px,2.083vw,32px); width:auto; }
.footer-brand-text{
  font-family:var(--font-base);
  font-weight:600;
  font-size:var(--font-size-paragraph-sm);
  line-height:1.2;
  color:var(--color-gray-40);
}
/* le ultime sei colonne, divise in tre parti uguali: ogni lista ne
   occupa due, e con la stessa grondaia le divisioni cadono esatte
   sulle linee della griglia di pagina (una lista = 270px a 1920) */
.footer-cols{
  grid-column:7 / span 6;
  display:grid;
  grid-template-columns:repeat(3, minmax(0, 1fr));
  gap:var(--space-16);
}
.footer-col{ display:flex; flex-direction:column; gap:var(--space-24); }
.footer-col-title{
  font-family:var(--font-base);
  font-weight:600;
  font-size:var(--font-size-paragraph-sm);
  line-height:1.1;
  color:var(--color-white);
}
.footer-links{ display:flex; flex-direction:column; gap:var(--space-16); }
.footer-links a{
  font-family:var(--font-base);
  font-weight:400;
  font-size:var(--font-size-paragraph-sm);
  line-height:1.2;
  color:var(--color-gray-20);
  transition:color .25s var(--ease-out);
}
.footer-links a:hover{ color:var(--color-white); }
/* Stessa griglia della riga sopra, così le due righe si allineano
   sulle stesse linee: il copyright parte dove parte il marchio, e i
   link legali stanno nelle ultime due colonne, cioè esattamente
   sotto la lista "Social".
   Il copyright aveva width:270px — che sono due colonne A 1920 e
   basta: a 1440 due colonne sono 207 e lui restava 270. Adesso è
   uno span e segue. */
.footer-bottom{
  border-top:1px solid var(--color-gray-80);
  padding-top:var(--space-24);
  display:grid;
  grid-template-columns:repeat(12, minmax(0, 1fr));
  gap:var(--space-16);
  align-items:end;
}
/* display:contents scioglie il wrapper: copyright e indirizzi
   diventano celle della griglia invece di stare in una scatola
   sola, e possono prendersi le loro colonne. */
.footer-legal-left{ display:contents; }
.footer-copyright{
  font-family:var(--font-sans);
  font-size:var(--font-size-paragraph-xs);
  line-height:1.5;
  color:var(--color-gray-40);
  grid-column:1 / span 2;
}
/* indirizzo, e-mail e telefono sono link: stesso trattamento di
   AGB/Datenschutz/Impressum, che stanno sulla stessa riga */
/* testo che esiste solo per i lettori di schermo: non si vede, ma
   non è display:none, altrimenti non verrebbe letto. */
.visually-hidden{
  position:absolute;
  width:1px; height:1px;
  padding:0; margin:-1px;
  overflow:hidden;
  clip-path:inset(50%);
  white-space:nowrap;
  border:0;
}

/* <address> arriva in corsivo dal browser: qui è testo normale */
/* tre colonne e non due: la riga dell'indirizzo è il link più il
   pulsante che copia, e a 1280 in giù i due insieme riempiono già
   tutta la larghezza disponibile */
.footer-contact{ grid-column:3 / span 3; display:flex; flex-direction:column; font-style:normal; }
/* Il link resta un link — tocco sul numero chiama, sull'indirizzo
   apre le mappe — e accanto c'è un pulsante che copia. Due bersagli
   distinti per due azioni distinte (Figma 2298:7350). */
.footer-contact-row{ display:flex; align-items:center; gap:var(--space-12); }
.footer-copy{
  display:flex;
  align-items:center;
  justify-content:center;
  padding-inline:10px;
  border-radius:var(--radius-pill);
  background:var(--color-gray-40);
  color:var(--color-black);
  font-family:var(--font-sans);
  font-size:12px;
  line-height:1.5;
  white-space:nowrap;
  cursor:pointer;
  /* invisibile ma presente nel flusso: comparendo non sposta nulla */
  opacity:0;
  transition:opacity .25s var(--ease-out);
}
/* .is-copied lo mette il JS per il tempo della conferma: senza,
   togliendo il mouse subito dopo il clic il pulsante spariva mentre
   dentro diceva "Kopiert", e chi ha copiato non vedeva mai la
   conferma. La visibilità segue la stessa regola dell'etichetta —
   dura il suo tempo e non la interrompe nessun evento del mouse. */
.footer-contact-row:hover .footer-copy,
.footer-copy:focus-visible,
.footer-copy.is-copied{ opacity:1; }
.footer-contact a{
  font-family:var(--font-sans);
  font-size:var(--font-size-paragraph-xs);
  line-height:1.5;
  color:var(--color-gray-40);
  transition:color .25s var(--ease-out);
}
/* Il bersaglio dell'hover è la RIGA, non il link: il pulsante
   compare già così (vedi sopra), e se il link tornasse grigio
   passandoci sopra sembrerebbero due cose scollegate invece di una
   riga sola. Il :has() fa lo stesso da tastiera, quando il fuoco è
   sul pulsante. */
.footer-contact-row:hover a,
.footer-contact-row:has(:focus-visible) a,
.footer-contact-row:has(.is-copied) a{ color:var(--color-white); }
.footer-legal-right{ grid-column:11 / -1; display:flex; gap:var(--space-24); align-items:center; justify-content:flex-end; }
.footer-legal-right a{
  font-family:var(--font-sans);
  font-size:var(--font-size-paragraph-xs);
  line-height:1.5;
  color:var(--color-gray-40);
  transition:color .25s var(--ease-out);
}
.footer-legal-right a:hover{ color:var(--color-white); }

@media (max-width: 1023px){
  /* impilato: una colonna sola, e i due blocchi la occupano tutta */
  .footer-top{ grid-template-columns:1fr; gap:48px; }
  .footer-brand{ grid-column:1 / -1; }
  .footer-cols{ grid-column:1 / -1; grid-template-columns:1fr 1fr; gap:48px 24px; }
  .footer-col{ align-content:start; }
  /* impilato: una colonna sola. Il wrapper torna a essere una
     scatola vera — con display:contents i suoi figli resterebbero
     celle della griglia e si porterebbero dietro gli span, che qui
     creerebbero dieci colonne implicite. */
  .footer-bottom{ grid-template-columns:1fr; align-items:start; gap:24px; }
  .footer-legal-left{ display:flex; gap:var(--space-32); flex-wrap:wrap; }
  .footer-legal-right{ grid-column:auto; justify-content:flex-start; }
  /* indirizzo, e-mail e telefono su mobile si toccano col dito: le
     righe vanno distanziate, altrimenti a 24px di line-height i
     bersagli sono attaccati e si sbaglia link. */
  .footer-contact{ gap:16px; }
  .footer-contact a{ padding-block:4px; }
  /* senza hover il pulsante sarebbe irraggiungibile: sempre visibile */
  .footer-copy{ opacity:1; }

  /* su mobile il footer supera l'altezza del viewport: la tecnica
     "fixed reveal" non riesce a mostrarlo tutto → footer nel flusso
     normale e nessun margin-bottom sul main (gestito anche via JS).
     Il padding-bottom lascia spazio alla barra ancorata in basso. */
  main{ margin-bottom:0 !important; }
  .site-footer{ position:static; }
  /* footer nel flusso: non si scopre, quindi niente da diradare */
  .site-footer::after{ display:none; }
  .footer-inner{ padding-bottom:calc( var(--space-128) + var(--size-header-item) ); }
}


/* ============================================================
   FORM DI CONTATTO — condivisa
   Stessa sezione su kontakt e sulle cinque pagine servizio: le
   regole stanno qui e non nel foglio di una pagina, altrimenti
   servirebbe una copia per ciascuna.
   La .form-section della home è un'altra cosa e ha le sue regole
   in home.css, che essendo caricato dopo vincono su queste.
   Circoscritte a .form-inner, che solo questa form ha: la home usa
   gli stessi nomi di classe (.contact-form, .form-grid, .form-footer)
   per una form diversa, e senza il vincolo queste regole finirebbero
   anche là. La .form-textarea fa eccezione ed è volutamente globale:
   l'altezza si comporta allo stesso modo in tutte le form del sito.
   ============================================================ */
/* stesso schema di .pillars: la fascia grigia arriva ai bordi,
   il contenuto resta dentro ai 1920 */
.form-section:has(.form-inner){
  background:var(--color-gray-15);
  padding-block:var(--space-240);
}
.form-inner{
  width:100%;
  max-width:var(--size-page-max);
  margin-inline:auto;
  padding-inline:var(--space-page-margin);
  box-sizing:border-box;
  display:flex;
  align-items:flex-start;
  justify-content:center;
  gap:var(--space-80);
}
.form-inner .form-aside{
  flex:1 1 0;
  min-width:0;
  display:flex;
  flex-direction:column;
  gap:var(--space-80);
}
.form-inner .form-aside-copy{
  display:flex;
  flex-direction:column;
  gap:var(--space-24);
}
.form-inner .form-schedule{
  display:flex;
  flex-direction:column;
  align-items:flex-start;
  gap:var(--space-24);
}

/* button-scheduler-primary: pillola primary-30 con avatar, nome,
   ruolo e icona calendario (Figma 2001:4709). Stroke interno come
   in filter-secondary: la pillola resta alta 112, non 116. */
.btn-scheduler{
  display:inline-flex;
  align-items:center;
  gap:var(--space-24);
  padding:var(--space-24) var(--space-48) var(--space-24) var(--space-24);
  background:var(--color-primary-30);
  box-shadow:inset 0 0 0 2px var(--color-primary-30);
  border-radius:var(--radius-pill);
  color:var(--color-black);
  transition:background-color .3s var(--ease-out);
}
/* In hover la pillola si svuota (Figma 2001:4711). Il filo primary-30
   è dichiarato una volta sola nella regola di base e vale in entrambi
   gli stati: qui cambia SOLO il fondo, da primary-30 a bianco. Il
   testo resta nero. */
.btn-scheduler:hover{ background:var(--color-white); }
.btn-scheduler-avatar{
  width:clamp(42.667px, 3.333vw, 64px);
  height:clamp(42.667px, 3.333vw, 64px);
  border-radius:var(--radius-pill);
  flex-shrink:0;
  object-fit:cover;
}
.btn-scheduler-label{
  display:flex;
  flex-direction:column;
  justify-content:center;
  gap:var(--space-4);
  white-space:nowrap;
}
.btn-scheduler-name{
  font-family:var(--font-base);
  font-weight:600;
  font-size:var(--font-size-button-lg);
  line-height:1;
  text-transform:uppercase;
}
.btn-scheduler-role{
  font-family:var(--font-sans);
  font-size:var(--font-size-paragraph-xs);
  line-height:1.5;
}
.form-inner .btn-scheduler-icon{ width:var(--space-32); flex-shrink:0; }

.form-inner .contact-form{
  width:clamp(560.667px, 43.802vw, 841px);
  flex-shrink:0;
  display:flex;
  flex-direction:column;
  gap:var(--space-48);
}

/* ---- gruppi di tag: "How can we help you?" è multi-scelta
   (checkbox), "Project budget" è a scelta unica (radio). In
   entrambi i casi l'input nativo è nascosto e resta la sola
   pillola: lo stato selezionato lo legge :has(), niente JS.

   Il gruppo è un div con role="group" + aria-labelledby e non un
   fieldset/legend: il legend non è un flex item, quindi il gap di
   16 fra titolo e riga non verrebbe applicato. ---- */
.form-inner .form-tags{
  display:flex;
  flex-direction:column;
  gap:var(--space-16);
}
.form-inner .form-tags-title{ color:var(--color-black); }
.form-inner .form-tags-row{
  display:flex;
  flex-wrap:wrap;
  gap:var(--space-16);
}



/* ---- consenso privacy + invio ---- */
.form-inner .form-footer{
  display:flex;
  flex-direction:column;
  align-items:flex-start;
  gap:var(--space-32);
}

/* la fascia mobile della form deve stare DOPO le regole base,
   altrimenti perde il confronto a parità di specificità */
@media (max-width: 1023px){
  .form-section:has(.form-inner){ padding-block:120px; }
  .form-inner{ flex-direction:column; gap:64px; }
  .form-inner .form-aside{ flex:0 0 auto; width:100%; gap:48px; }
  .form-inner .contact-form{ width:100%; flex-shrink:1; }
  .form-inner .form-grid{ grid-template-columns:1fr; }
  .form-inner .form-field{ grid-column:1 / -1; }
  .form-inner .form-footer .btn-primary{ justify-content:center; width:100%; }
}

/* ============================================================
   BREAKPOINT TABLET/MOBILE
   ============================================================ */


/* ============================================================
   BERATUNG — immagine e testo affiancati, condivisa
   Stessa sezione su /leistungen/ e su /kontakt/ (Figma 2298:7866).
   Nessun'altra pagina usa questi nomi, quindi non serve
   circoscriverla come la form.
   ============================================================ */
/* ============================================================
   UX-BERATUNG — immagine a sinistra, contenuto a destra
   (Figma 368:3639). I flex-basis riproducono il rapporto
   842 : 794 del frame.
   ============================================================ */
.beratung{
  width:100%;
  max-width:var(--size-page-max);
  margin-inline:auto;
  padding:var(--space-240) var(--space-page-margin) 0;
  box-sizing:border-box;
  display:flex;
  align-items:stretch;
  gap:var(--space-64);
}
.beratung-media{
  flex:0 1 842px;
  height:clamp(377.333px, 29.4792vw, 566px);
  border-radius:var(--radius-24);
  overflow:hidden;
  background:var(--color-gray-15);
}
.beratung-media img{ width:100%; height:100%; object-fit:cover; }
.beratung-content{
  flex:0 1 794px;
  display:flex;
  flex-direction:column;
  /* flex-start: senza, il bottone si stira per tutta la colonna
     invece di restare largo quanto il suo contenuto */
  align-items:flex-start;
  justify-content:space-between;
  gap:var(--space-64);
}
.beratung-copy{
  display:flex;
  flex-direction:column;
  gap:var(--space-24);
}
.beratung-text{
  font-family:var(--font-sans);
  font-size:var(--font-size-paragraph-sm);
  line-height:1.5;
}

/* ============================================================
   CASE STUDIES — testata centrata + due portfolio-item
   (Figma 368:3476). portfolio-item è il componente della home.
   ============================================================ */

@media (max-width: 1023px){
  .beratung{ flex-direction:column; padding-top:120px; }
  .beratung-media{ flex:0 0 auto; height:auto; aspect-ratio:4/3; }
  .beratung-content{ flex:0 0 auto; gap:32px; }
  .beratung-content .btn-primary{ justify-content:center; }
}


/* ============================================================
   WERTE — sezione scura, griglia di valori. Condivisa.
   Su /agentur/ e su /karriere/ (Figma 334:3807).

   Le righe non hanno altezza fissa: in CSS Grid gli item di una
   stessa riga si estendono all'altezza della riga, quindi i
   border-bottom restano allineati anche quando i testi hanno
   lunghezze diverse.
   ============================================================ */
.werte{
  background:var(--color-black);
  color:var(--color-white);
  padding:var(--space-240) 0;
  display:flex;
  flex-direction:column;
  align-items:center;
  gap:var(--space-128);
}
.werte-head{
  width:min(1414px, calc(100% - 2 * var(--space-page-margin)));
  display:flex;
  flex-direction:column;
  gap:var(--space-24);
  text-align:center;
}
.werte-heading{ color:var(--color-white); }

.werte-grid{
  width:min(1700px, calc(100% - 2 * var(--space-page-margin)));
  display:grid;
  grid-template-columns:repeat(3, minmax(0, 1fr));
  gap:var(--space-64) var(--space-48);
}
value-block{
  display:flex;
  flex-direction:column;
  gap:var(--space-48);
  padding-bottom:var(--space-48);
  /* in Figma questo bordo è Primary/primary-30 (#2bd6d9): ora che il
     token esiste si usa quello, non più l'approssimazione al -40. */
  border-bottom:2px solid var(--color-primary-30);
}
.value-title{ color:var(--color-white); }
.value-text{
  font-family:var(--font-sans);
  font-size:var(--font-size-paragraph-sm);
  line-height:1.5;
  color:var(--color-gray-40);
}

/* ============================================================
   LOGO CAROUSEL — identico al blocco "clients" della home
   (ticker verticale sincronizzato). Figma 334:3799.
   ============================================================ */

@media (max-width: 1023px){
  .werte-grid{ grid-template-columns:1fr; gap:48px; }
}


/* ============================================================
   CTA BANNER — la scheda scura di chiusura pagina. Condivisa.
   Su /projekte/, sulle case study e su /karriere/. Era duplicata
   in projekte.css e case-study.css: qui ce n'è una copia sola.
   Il view-transition-name resta in projekte.css, perché serve
   solo alla transizione verso la case study.
   ============================================================ */

.cta-banner{
  width:100%;
  max-width:var(--size-page-max);
  margin-inline:auto;
  padding:var(--space-240) var(--space-page-margin);
  box-sizing:border-box;
}
cta-card{
  display:flex;
  flex-direction:column;
  align-items:center;
  justify-content:center;
  gap:var(--space-64);
  min-height:clamp(356.667px, 27.8646vw, 535px);
  padding:var(--space-80) var(--space-48);
  background:var(--color-black);
  color:var(--color-white);
  border-radius:var(--radius-24);
  overflow:hidden;
  text-align:center;
}
.cta-copy{
  display:flex;
  flex-direction:column;
  align-items:center;
  gap:var(--space-24);
}
.cta-text{
  font-family:var(--font-base);
  font-weight:400;
  font-size:var(--font-size-paragraph-md);
  line-height:1.4;
  letter-spacing:-0.01em;
}

/* variante V3 (Figma 3360:10378, 3221:9695): la scheda abbraccia il
   contenuto invece dell'altezza minima, 1700×498 a 1920, e il testo
   va a capo a col-8 (1128). Pagine servizio, ruoli e Karriere. */
.cta-banner--hug cta-card{ min-height:0; }
.cta-banner--hug .cta-text{ max-width:var(--size-col-8); }

/* ============================================================
   BREAKPOINT TABLET/MOBILE
   ============================================================ */

@media (max-width: 1023px){
  .cta-banner{ padding-block:120px; }
  cta-card{ min-height:0; padding:48px 24px; gap:40px; }
  cta-card .btn-primary-dark{ justify-content:center; }
  .cta-banner{ padding-block:80px 120px; }
}

/* ============================================================
   CONTRASTO ELEVATO (forced-colors: Windows e altri)
   In questa modalità il browser toglie le ombre, e qui molte linee
   sono box-shadow:inset (lo stroke "interno" del Figma, che non
   occupa spazio). Senza questo blocco pulsanti bordati, campi,
   caselle e card perdono il contorno. Le si ridisegna con un outline
   interno: zero spazio come l'ombra, ma il browser lo tiene e lo
   colora con i colori di sistema. Per chi non usa la modalità non
   cambia niente. Si prova con Chrome DevTools → Rendering →
   "Emulate CSS media feature forced-colors".
   ============================================================ */
@media (forced-colors: active){
  /* bordo del reel in home (home.css, box-shadow sull'::after) */
  .hero-reel::after{ outline:1px solid CanvasText; outline-offset:-1px; }
  /* anche i pulsanti pieni: in questa modalità perdono il fondo */
  .btn-primary, .btn-primary-dark, .btn-icon-primary, .btn-icon-primary-s,
  .btn-secondary, .btn-secondary-dark,
  .btn-icon-secondary, .btn-icon-secondary-dark, .btn-icon-secondary-s,
  .btn-scheduler, .filter-primary, .filter-secondary{
    outline:2px solid ButtonText;
    outline-offset:-2px;
  }
  .form-input, .form-consent-box, dropdown-menu,
  .trust-card, .testimonial-card, .direkt-card, .mitgeben-card,
  result-card, result-card-logo, .service-card{
    outline:2px solid CanvasText;
    outline-offset:-2px;
  }
  /* il tag scelto si riconosceva solo dal colore del bordo */
  .filter-primary:has(.filter-input:checked),
  .filter-secondary:has(.filter-input:checked){ outline:4px solid Highlight; outline-offset:-4px; }
  /* il focus dei campi era un'ombra: qui torna un contorno di sistema */
  .form-input:focus,
  .form-consent:has(.form-consent-input:focus-visible) .form-consent-box{ outline:3px solid Highlight; outline-offset:-3px; }
  .form-input[aria-invalid="true"]{ outline-style:dashed; }
}
