/* ==========================================================================
   Fedenko — component layer (FDN-FE-005)

   The approved design bundle (`.design/Fedenko - Standalone.html`) expresses
   every component as React inline styles on CSS custom properties. This file
   is that same system translated once into classes, so the four page tasks
   write markup only — no inline styles, no literal colours.

   RULES FOR THIS FILE
   - Colour, gradient, shadow and motion values come from `tokens.css` only.
     There is no literal hex, rgb() or box-shadow value below. Where the bundle
     used a translucent tint with no token, it is rebuilt with `color-mix()`
     over the *shipped* token, so the D7/D8 contrast corrections carry into the
     tint instead of being bypassed.
   - Geometry the bundle states as bare numbers (control heights 38/46/50/54,
     icon boxes, hairline gaps of 10/14/18px) has no token and is written as a
     literal px with the JSX `file:line` beside it. `tokens.css` has no scale
     step for those values and inventing one is out of scope.
   - LOAD ORDER, and it is not interchangeable:
         1. vendor/bootstrap/css/bootstrap.min.css
         2. assets/css/tokens.css
         3. vendor/aos/aos.css
         4. assets/css/main.css
     Bootstrap must come FIRST. Its Reboot styles `body`, `h1`–`h6` and `a` at
     the same specificity as tokens.css does, so loading Bootstrap second makes
     Reboot win the base elements — measured: `h1` fell back to Bootstrap's
     `system-ui` stack and its fluid `calc(1.375rem + 1.5vw)`, discarding Inter
     and the whole type scale. With this order, tokens.css owns the base
     elements and this file owns the components.
   - Class prefix `fd-` throughout, so nothing collides with Bootstrap's own
     `.btn`, `.card`, `.tag`, `.chip` or `.form-*` namespaces.

   Sections follow the bundle's own file order:
     0 fonts · 1 layout · 2 core · 3 forms · 4 navigation · 5 patterns
     6 shared wrappers · 7 grid ratios · 8 breakpoints · 9 utilities
   ========================================================================== */


/* ==========================================================================
   0. FONTS
   Inter, self-hosted. Only `latin` and `latin-ext` ship — de-CH and en-CH need
   no cyrillic, greek or vietnamese subset (audit finding A4). The bundle's own
   @font-face rules point at bundle UUIDs and would not resolve; these are new.
   `swap` keeps text visible while the file loads.
   ========================================================================== */

@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url("../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: 400 800;
  font-display: swap;
  src: url("../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;
}


/* ==========================================================================
   1. LAYOUT PRIMITIVES
   ========================================================================== */

/* Section wrapper — owns the vertical rhythm and the optional background.
   shared.jsx:52-83 */
.fd-section {
  background: var(--surface-page);
}

.fd-section__inner {
  max-width: var(--container-max);
  margin: 0 auto;
  padding: var(--section-y) var(--gutter);
}

.fd-section--narrow .fd-section__inner {
  max-width: var(--container-narrow);
}

/* Section grammar — the refresh composes page sections from a small set of
   reusable layouts. No page opts in during FDN-FE-010, so these are inert
   until the dedicated content tasks apply the classes. */
.fd-section__card-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr));
  gap: var(--space-4);
  list-style: none;
  margin: 0;
  padding: 0;
}

.fd-section__card-row > * {
  height: 100%;
}

.fd-head--showcase {
  margin-inline: auto;
  max-width: var(--container-narrow);
  text-align: center;
}

.fd-card-skin {
  border: var(--border-w) solid var(--border-cool);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-sm);
}

/* tones — shared.jsx:60-69 */
.fd-section--white { background: var(--surface-page); }
.fd-section--wash { background: var(--grad-wash); }
.fd-section--band { background: var(--grad-band); }
.fd-section--band-strong { background: var(--grad-band-strong); }
.fd-section--cool { background: var(--grad-cool); }
.fd-section--hero { background: var(--grad-deep-soft); }
.fd-section--deep-soft { background: var(--grad-deep-soft); }
.fd-section--navy,
.fd-section--deep { background: var(--grad-deep); }

/* AOS starts reveal elements transparent and non-interactive. Respect reduced
   motion by restoring their usable, visible state even if its observer runs. */
@media (prefers-reduced-motion: reduce) {

  [data-aos] {
    opacity: 1 !important;
    transform: none !important;
    pointer-events: auto !important;
    transition: none !important;
  }
}

/* AOS can otherwise leave an anchor target hidden before its observer catches
   up. Direct section links must always reveal their critical content. */
#process:target [data-aos],
#work:target [data-aos] {
  opacity: 1;
  pointer-events: auto;
  transform: none;
}

/* On dark grounds the section re-colours its own typography, so a page never
   needs an inline `color`. Values are the bundle's own dark-tone choices
   (SectionHead shared.jsx:108-118, CtaBand.jsx:45-52). */
.fd-section--hero,
.fd-section--deep-soft,
.fd-section--navy,
.fd-section--deep {
  color: var(--text-on-dark);
}

.fd-section--hero h1,
.fd-section--hero h2,
.fd-section--hero h3,
.fd-section--deep-soft h1,
.fd-section--deep-soft h2,
.fd-section--deep-soft h3,
.fd-section--navy h1,
.fd-section--navy h2,
.fd-section--navy h3,
.fd-section--deep h1,
.fd-section--deep h2,
.fd-section--deep h3 {
  color: var(--white);
}

.fd-section--hero p,
.fd-section--deep-soft p,
.fd-section--navy p,
.fd-section--deep p {
  color: var(--text-on-dark);
}

/* Hero sections in the bundle set their own tighter padding rather than the
   section rhythm — Home.jsx:18, Cleaning.jsx:221, Renovation.jsx:163.
   FDN-FE-032: every hero owns the full viewport, so its gradient reaches the
   next section without exposing the page background. */
.fd-section--hero .fd-section__inner {
  padding: 72px var(--gutter) var(--space-9);
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

/* FDN-FE-018: short sections that would otherwise leave a white strip below
   their content. Vertically centred so the gap reads as deliberate space. */
.fd-section--full .fd-section__inner {
  min-height: var(--section-min);
  display: flex;
  flex-direction: column;
  justify-content: center;
}

/* A plain content container, for markup that is not a full Section. */
.fd-container {
  max-width: var(--container-max);
  margin: 0 auto;
  padding-inline: var(--gutter);
}

.fd-container--narrow {
  max-width: var(--container-narrow);
}

/* Vertical stack — replaces the bundle's `display:flex; flexDirection:column`
   with an explicit gap. Used by nearly every component's text block. */
.fd-stack {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.fd-stack--tight { gap: var(--space-2); }
.fd-stack--loose { gap: var(--space-5); }

/* Horizontal group that wraps — button rows, chip rows, tag rows. */
.fd-cluster {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
}


/* ==========================================================================
   2. CORE COMPONENTS
   ========================================================================== */

html,
body {
  overflow-x: hidden;
}

/* --- Icon — Icon.jsx --------------------------------------------------------
   Icon.jsx:22 fetched each SVG from unpkg.com at runtime (audit A2). Here the
   icons come from the self-hosted sprite at `assets/img/icons/sprite.svg`;
   `stroke-width` 1.75 and `currentColor` (Icon.jsx:11, :39) are inherited
   from this referencing element, because an external sprite root cannot pass
   presentation attributes into a <use> shadow tree. Markup:
     <svg class="fd-icon" aria-hidden="true" focusable="false">
       <use href="assets/img/icons/sprite.svg#i-check"></use>
     </svg> */
.fd-icon-sprite { display: none; }

.fd-icon {
  display: inline-flex;
  flex: 0 0 auto;
  width: 20px;                        /* Icon.jsx:9 default size */
  height: 20px;
  color: var(--accent-icon);          /* Icon.jsx:39 default */
  fill: none;
  stroke: currentColor;
  stroke-width: 1.75;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* sizes the bundle actually asks for */
.fd-icon--xs { width: 15px; height: 15px; }   /* Checkbox.jsx:49 */
.fd-icon--sm { width: 16px; height: 16px; }   /* Button sm, ServiceCard arrow */
.fd-icon--md { width: 18px; height: 18px; }   /* Button md/lg, Select chevron */
.fd-icon--lg { width: 22px; height: 22px; }   /* RadioCards.jsx:53, burger */
.fd-icon--xl { width: 24px; height: 24px; }   /* FactStat.jsx:23, ServiceCard */

/* colour roles — never a literal, always a token */
.fd-icon--current { color: currentColor; }
.fd-icon--solid { fill: currentColor; stroke: none; }
.fd-icon--blue { color: var(--blue-500); }
.fd-icon--on-dark { color: var(--white); }

/* --- Logo — Logo.jsx --------------------------------------------------------
   NOTE (audit A1): the bundle's own logo file is generated mockup output. The
   image this class points at is a page-task decision; the class only sizes it. */
.fd-logo {
  display: block;
  width: auto;
  height: 38px;                       /* SiteHeader.jsx:50 desktop */
  border-radius: var(--radius-badge);
  padding: 2px;
}

.fd-logo--sm { height: 30px; }        /* SiteHeader.jsx:50 mobile */
.fd-logo--footer { height: 34px; }    /* SiteFooter.jsx:41 */

/* --- Button — Button.jsx --------------------------------------------------- */
.fd-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;                          /* Button.jsx:86 — no space token at 10 */
  height: 46px;                       /* Button.jsx:12 size md */
  padding: 0 22px;                    /* Button.jsx:11 */
  font-family: inherit;
  font-size: var(--fs-body);
  font-weight: var(--fw-semibold);
  letter-spacing: -0.005em;           /* Button.jsx:91 */
  line-height: 1;
  white-space: nowrap;
  text-decoration: none;
  border-radius: var(--radius-pill);
  border: var(--border-w) solid transparent;
  cursor: pointer;
  transition:
    background var(--dur-base) var(--ease-standard),
    border-color var(--dur-base) var(--ease-standard),
    transform var(--dur-fast) var(--ease-standard);
}

.fd-btn:hover {
  text-decoration: none;
  transform: translateY(-1px);        /* Button.jsx:97 */
}

.fd-btn:disabled,
.fd-btn.is-disabled {
  opacity: 0.45;                      /* Button.jsx:94 */
  cursor: not-allowed;
  transform: none;
}

/* sizes — Button.jsx:4-20 */
.fd-btn--sm {
  height: 38px;
  padding: 0 var(--space-4);
  font-size: var(--fs-small);
}

.fd-btn--lg {
  height: 54px;
  padding: 0 28px;
  font-size: var(--fs-lead);
}

.fd-btn--full {
  width: 100%;
  min-width: 100%;
}

/* variants — Button.jsx:21-44, hover states Button.jsx:45-61 */
.fd-btn--primary {
  background: var(--grad-red);
  color: var(--text-on-red);
  border-color: var(--red-700);
  box-shadow: var(--shadow-sm);
}

.fd-btn--primary:hover:not(:disabled):not(.is-disabled) {
  background: var(--grad-red-hover);
  border-color: var(--red-700);
  color: var(--text-on-red);
}

.fd-btn--secondary {
  background: var(--grad-blue);
  color: var(--text-on-blue);
  border-color: var(--blue-600);
  box-shadow: var(--shadow-xs);
}

.fd-btn--secondary:hover:not(:disabled):not(.is-disabled) {
  background: var(--grad-blue-hover);
  border-color: var(--blue-700);
  color: var(--text-on-blue);
}

.fd-btn--ghost {
  background: var(--white);
  color: var(--action-ghost-text);
  border-color: var(--action-ghost-border);
}

.fd-btn--ghost:hover:not(:disabled):not(.is-disabled) {
  background: var(--grad-wash);
  border-color: var(--border-strong);
  color: var(--action-ghost-text);    /* D11 — must stay --blue-600 on this fill */
}

.fd-btn--quiet {
  background: transparent;
  color: var(--action-ghost-text);
  border-color: transparent;
}

.fd-btn--quiet:hover:not(:disabled):not(.is-disabled) {
  background: var(--surface-wash);
  color: var(--action-ghost-text);
}

/* --- Card — Card.jsx -------------------------------------------------------- */
.fd-card {
  border-radius: var(--radius-card);
  padding: 28px;                      /* Card.jsx:31 default */
  background: var(--white);
  border: var(--border-w) solid var(--border-cool);
  box-shadow: var(--shadow-card);
  transition:
    transform var(--dur-base) var(--ease-standard),
    box-shadow var(--dur-base) var(--ease-standard);
}

/* tones — Card.jsx:4-27 */
.fd-card--white {
  background: var(--white);
  border-color: var(--border-cool);
}

.fd-card--wash {
  background: var(--grad-wash);
  border-color: var(--sky-300);
}

.fd-card--band {
  background: var(--grad-band);
  border-color: var(--sky-300);
}

/* `navy` and `deep` are the same declaration in the bundle (Card.jsx:17-26);
   both aliases are kept so page markup can use either name. */
.fd-card--navy,
.fd-card--deep {
  background: var(--grad-deep);
  border-color: var(--blue-700);
  color: var(--text-on-dark);
}

.fd-card--navy h2,
.fd-card--navy h3,
.fd-card--deep h2,
.fd-card--deep h3 {
  color: var(--white);
}

/* radius / padding variants the pages ask for */
.fd-card--shell { border-radius: var(--radius-shell); }   /* shared.jsx:152 */
.fd-card--pad-sm { padding: var(--space-5); }             /* shared.jsx:153 */
.fd-card--pad-lg { padding: var(--space-6); }             /* Cleaning.jsx:63 */

/* Card.jsx:44-45 — lift only when the card opts in */
.fd-card--lift:hover {
  box-shadow: var(--shadow-lift);
  transform: translateY(-3px);
}

/* --- Chip — Chip.jsx -------------------------------------------------------- */
.fd-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  height: 36px;                       /* Chip.jsx:23 */
  padding: 0 var(--space-4);
  font-family: inherit;
  font-size: var(--fs-small);
  font-weight: var(--fw-medium);
  border-radius: var(--radius-pill);
  background: var(--sky-100);
  color: var(--blue-700);
  border: var(--border-w) solid var(--sky-300);
  cursor: default;
  transition: var(--transition-ui);
}

/* Chip.jsx:31 — only the button form is interactive */
button.fd-chip,
.fd-chip--action {
  cursor: pointer;
}

button.fd-chip:hover,
.fd-chip--action:hover {
  background: var(--sky-200);
}

/* Chip.jsx:28-30 — `aria-pressed` is the state carrier, so style from it and
   the two can never disagree. `.is-active` is the non-button fallback. */
button.fd-chip[aria-pressed="true"],
.fd-chip.is-active {
  background: var(--white);
  color: var(--blue-700);
  border-color: var(--white);
}

/* --- Tag — Tag.jsx ---------------------------------------------------------- */
.fd-tag {
  display: inline-flex;
  align-items: center;
  height: 26px;                       /* Tag.jsx:51 */
  padding: 0 10px;                    /* Tag.jsx:52 — no space token at 10 */
  border-radius: var(--radius-badge);
  font-size: var(--fs-label);
  font-weight: var(--fw-semibold);
  letter-spacing: 0.01em;             /* Tag.jsx:56 */
  background: var(--accent-chip-bg);
  color: var(--accent-chip-text);
  border: var(--border-w) solid var(--sky-300);
}

.fd-tag--sky {
  background: var(--sky-200);
  color: var(--blue-700);
  border-color: var(--sky-300);
}

.fd-tag--navy {
  background: var(--navy-900);
  color: var(--white);
  border-color: var(--navy-900);
}

/* Tag.jsx:15-19 used rgba(255,255,255,.14 / .30). No token exists for those
   tints, so they are rebuilt from --white with color-mix rather than typed as
   a literal rgb(). */
.fd-tag--on-dark {
  background: color-mix(in srgb, var(--white) 14%, transparent);
  color: var(--white);
  border-color: color-mix(in srgb, var(--white) 30%, transparent);
}

/* Tag.jsx:20-34 mixed each status tint from the BUNDLE's hue, i.e. the
   pre-correction #1F9D57 / #C9821A. Mixing from the shipped token instead
   carries D7 and D8 into the tint, exactly as DESIGN_AUDIT.md requires. */
.fd-tag--ok {
  background: color-mix(in srgb, var(--status-ok) 10%, var(--white));
  color: var(--status-ok);
  border-color: color-mix(in srgb, var(--status-ok) 28%, var(--white));
}

.fd-tag--warn {
  background: color-mix(in srgb, var(--status-warn) 10%, var(--white));
  color: var(--status-warn);
  border-color: color-mix(in srgb, var(--status-warn) 28%, var(--white));
}

.fd-tag--danger {
  background: color-mix(in srgb, var(--status-danger) 9%, var(--white));
  color: var(--status-danger);
  border-color: color-mix(in srgb, var(--status-danger) 26%, var(--white));
}

.fd-tag--outline {
  background: var(--white);
  color: var(--blue-500);
  border-color: var(--border-cool);
}

/* --- SectionLabel — SectionLabel.jsx ---------------------------------------- */
.fd-eyebrow {
  font-size: var(--fs-label);
  line-height: var(--lh-label);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  font-weight: var(--fw-semibold);
  color: var(--blue-500);
}

.fd-eyebrow--on-dark {
  color: var(--text-on-dark);              /* SectionLabel.jsx:17 */
}

.fd-text--on-dark {
  color: var(--white);
}

/* CtaBand.jsx:41 uses --sky-300 for its dark eyebrow instead. */
.fd-eyebrow--on-deep {
  color: var(--sky-300);
}


/* ==========================================================================
   3. FORM COMPONENTS
   ========================================================================== */

/* --- FormField — FormField.jsx ---------------------------------------------- */
.fd-field {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.fd-field__label {
  font-size: var(--fs-small);
  font-weight: var(--fw-semibold);
  color: var(--text-primary);
}

/* FormField.jsx:28-32 — the required marker */
.fd-field__required {
  color: var(--action-primary);
  margin-left: var(--space-1);
}

.fd-field__hint {
  font-size: var(--fs-small);
  color: var(--text-muted);
}

.fd-field__error {
  font-size: var(--fs-small);
  color: var(--status-danger);
}

/* --- Input / Select / Textarea — Input.jsx, Select.jsx, Textarea.jsx --------
   One shared control skin; the three differ only in padding and height. */
.fd-input,
.fd-select,
.fd-textarea {
  width: 100%;
  font-family: inherit;
  font-size: var(--fs-body);
  color: var(--text-primary);
  background: var(--white);
  border: var(--border-w) solid var(--border-cool);
  border-radius: var(--radius-card);
  outline: none;
  transition: var(--transition-ui);
}

.fd-input,
.fd-select {
  height: 50px;                       /* Input.jsx:29, Select.jsx:31 */
  padding: 0 var(--space-4);
}

.fd-textarea {
  padding: 14px var(--space-4);       /* Textarea.jsx:24 */
  line-height: var(--lh-body);
  resize: vertical;
}

.fd-select {
  appearance: none;
  padding-right: 44px;                /* Select.jsx:29 — room for the chevron */
}

/* Input.jsx:26-31 focus state. The global :focus-visible ring in tokens.css
   (D9) still applies; this adds the bundle's own border + glow. */
.fd-input:focus,
.fd-select:focus,
.fd-textarea:focus {
  border-color: var(--border-focus);
  box-shadow: var(--focus-ring);
}

/* invalid — Input.jsx:26. Styled from `aria-invalid` so the visual state and
   the state a screen reader announces can never drift apart. */
.fd-input[aria-invalid="true"],
.fd-select[aria-invalid="true"],
.fd-textarea[aria-invalid="true"],
.fd-input.is-invalid,
.fd-select.is-invalid,
.fd-textarea.is-invalid {
  border-color: var(--status-danger);
}

/* Wrapper that positions the select chevron and the input prefix. */
.fd-control {
  position: relative;
  display: flex;
  align-items: center;
}

.fd-control__chevron {
  position: absolute;
  right: var(--space-4);              /* Select.jsx:48 */
  color: var(--blue-500);
  pointer-events: none;
}

.fd-control__prefix {
  position: absolute;
  left: var(--space-4);               /* Input.jsx:37 */
  color: var(--text-muted);
  font-size: var(--fs-body);
  pointer-events: none;
}

.fd-control--prefixed .fd-input {
  padding-left: 44px;                 /* Input.jsx:28 */
}

/* --- Checkbox — Checkbox.jsx ------------------------------------------------ */
.fd-check {
  display: flex;
  gap: var(--space-3);
  align-items: flex-start;
  cursor: pointer;
  min-height: var(--touch-min);
  padding: 6px 0;                     /* Checkbox.jsx:19 */
}

/* Checkbox.jsx:26-31 — the real input stays in the accessibility tree and
   keeps keyboard operation; only its paint is replaced. */
.fd-check__input {
  position: absolute;
  opacity: 0;
  width: 1px;
  height: 1px;
}

.fd-check__box {
  flex: 0 0 auto;
  width: 22px;                        /* Checkbox.jsx:36 */
  height: 22px;
  margin-top: 2px;
  border-radius: var(--radius-control);
  background: var(--white);
  border: var(--border-w) solid var(--border-strong);
  display: grid;
  place-items: center;
  transition: var(--transition-ui);
}

/* the tick is always in the DOM and revealed on check, so no JS is needed */
.fd-check__box .fd-icon-sprite { display: none; }

.fd-check__box .fd-icon {
  color: var(--white);
  opacity: 0;
  transition: opacity var(--dur-fast) var(--ease-standard);
}

.fd-check__input:checked + .fd-check__box {
  background: var(--surface-blue);
  border-color: var(--blue-500);
}

.fd-check__input:checked + .fd-check__box .fd-icon-sprite { display: none; }

.fd-check__input:checked + .fd-check__box .fd-icon {
  opacity: 1;
}

/* the hidden input cannot show a ring itself — forward it to the painted box */
.fd-check__input:focus-visible + .fd-check__box {
  outline: 2px solid var(--border-focus);
  outline-offset: 2px;
}

.fd-check__text {
  min-width: 0;
  flex: 1;
}

.fd-check__label {
  font-size: var(--fs-body);
  color: var(--text-primary);
}

.fd-check__hint {
  display: block;
  font-size: var(--fs-small);
  color: var(--text-muted);
}

/* --- RadioCards — RadioCards.jsx -------------------------------------------- */
/* RadioCards.jsx:15 — auto-fit, so long German labels collapse the column
   before they clip the text. Kept verbatim rather than swapped for a Bootstrap
   row, because the Bootstrap split cannot express "wrap on content width". */
.fd-radiocards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 190px), 1fr));
  gap: var(--space-3);
}

.fd-radiocards--1col {
  grid-template-columns: 1fr;
}

.fd-radiocard {
  display: flex;
  gap: var(--space-3);
  align-items: flex-start;
  cursor: pointer;
  padding: 14px var(--space-4);       /* RadioCards.jsx:32 */
  min-height: var(--touch-min);
  border-radius: var(--radius-card);
  background: var(--white);
  border: var(--border-w) solid var(--border-cool);
  transition: var(--transition-ui);
}

.fd-radiocard__input {
  position: absolute;
  opacity: 0;
  width: 1px;
  height: 1px;
}

.fd-radiocard__input:checked ~ .fd-radiocard__body {
  color: inherit;
}

/* :has() lets the label carry the checked skin without a JS class toggle.
   RadioCards.jsx:36-37 */
.fd-radiocard:has(.fd-radiocard__input:checked) {
  background: var(--surface-wash);
  border-color: var(--blue-500);
}

.fd-radiocard:has(.fd-radiocard__input:checked) .fd-icon-sprite { display: none; }

.fd-radiocard .fd-icon {
  color: var(--blue-500);             /* RadioCards.jsx:54 */
}

.fd-radiocard:has(.fd-radiocard__input:focus-visible) {
  outline: 2px solid var(--border-focus);
  outline-offset: 2px;
}

.fd-radiocard__body {
  min-width: 0;
  flex: 1;
}

.fd-radiocard__label {
  display: block;
  font-size: var(--fs-body);
  font-weight: var(--fw-semibold);
  color: var(--text-primary);
  overflow-wrap: anywhere;            /* RadioCards.jsx:69 */
}

.fd-radiocard__hint {
  display: block;
  font-size: var(--fs-small);
  color: var(--text-muted);
}


/* ==========================================================================
   4. NAVIGATION
   ========================================================================== */

/* --- SiteHeader — SiteHeader.jsx -------------------------------------------- */
.fd-glass {
  background: var(--glass-bg);
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(130%);
  backdrop-filter: blur(var(--glass-blur)) saturate(130%);
  border: var(--border-w) solid var(--glass-line);
  box-shadow: var(--shadow-card);
}

@supports not (backdrop-filter: blur(1px)) {
  .fd-glass {
    background: var(--surface-wash);
  }
}

.fd-header {
  position: sticky;
  top: 0;
  z-index: 20;                        /* SiteHeader.jsx:22 */
  background: var(--glass-bg);
  border-bottom: var(--border-w) solid var(--border-cool);
  -webkit-backdrop-filter: blur(var(--glass-blur-sm)) saturate(130%);
  backdrop-filter: blur(var(--glass-blur-sm)) saturate(130%);
  transition: background var(--dur-base) var(--ease-standard), box-shadow var(--dur-base) var(--ease-standard);
}

.fd-header.is-scrolled {
  background: var(--glass-bg-strong);
  box-shadow: var(--shadow-sm);
}

@supports not (backdrop-filter: blur(1px)) {
  .fd-header,
  .fd-header.is-scrolled {
    background: var(--surface-wash);
  }
}

.fd-header__bar {
  max-width: var(--container-max);
  margin: 0 auto;
  padding: 0 var(--gutter);
  height: var(--header-h);
  display: flex;
  align-items: center;
  gap: var(--space-5);
}

.fd-header__brand {
  display: flex;
  flex: 0 0 auto;
}

.fd-header__nav {
  display: flex;
  gap: var(--space-1);
  margin-left: var(--space-3);
  flex: 1;
}

/* nav pill — SiteHeader.jsx:69-78 */
.fd-header__link {
  display: inline-flex;
  align-items: center;
  padding: var(--space-2) 14px;
  border-radius: var(--radius-pill);
  font-size: var(--fs-small);
  font-weight: var(--fw-semibold);
  color: var(--text-body);
  background: transparent;
  text-decoration: none;
  transition: var(--transition-ui);
}

.fd-header__link:hover {
  background: var(--surface-wash);
  color: var(--text-link-hover);
  text-decoration: none;
}

/* `aria-current="page"` is the state carrier; `.is-active` is the fallback. */
.fd-header__link[aria-current="page"],
.fd-header__link.is-active {
  color: var(--blue-700);
  background: var(--surface-band);
}

.fd-header__actions {
  display: flex;
  align-items: center;
  gap: 14px;                          /* SiteHeader.jsx:88 */
  margin-left: auto;
}

/* burger — SiteHeader.jsx:106-118. Hidden above the nav breakpoint (§8). */
.fd-header__burger {
  display: none;
  width: var(--touch-min);            /* 44px — SiteHeader.jsx:110 */
  height: var(--touch-min);
  place-items: center;
  background: var(--surface-wash);
  border: var(--border-w) solid var(--border-cool);
  border-radius: var(--radius-control);
  cursor: pointer;
  color: var(--blue-500);             /* SiteHeader.jsx:122 */
}

/* the burger swaps its glyph from `aria-expanded`, so the two cannot drift */
.fd-header__burger .fd-header__burger-close { display: none; }
.fd-header__burger[aria-expanded="true"] .fd-header__burger-open { display: none; }
.fd-header__burger[aria-expanded="true"] .fd-header__burger-close { display: inline-flex; }

/* mobile drawer — SiteHeader.jsx:123-153 */
.fd-header__drawer {
  display: none;
  border-top: var(--border-w) solid var(--border-cool);
  padding: var(--space-3) var(--gutter-mobile) var(--space-5);
  flex-direction: column;
  gap: var(--space-1);
  background: var(--white);
}

.fd-header__drawer.is-open {
  display: flex;
}

.fd-header__drawer-link {
  min-height: var(--touch-min);
  display: flex;
  align-items: center;
  padding: 0 var(--space-3);
  border-radius: var(--radius-control);
  font-weight: var(--fw-semibold);
  font-size: var(--fs-body);
  color: var(--text-primary);
  background: transparent;
  text-decoration: none;
}

.fd-header__drawer-link[aria-current="page"],
.fd-header__drawer-link.is-active {
  color: var(--blue-700);
  background: var(--surface-band);
}

.fd-header__drawer .fd-btn {
  margin-top: var(--space-2);         /* SiteHeader.jsx:159 */
}

.fd-header__drawer .fd-lang {
  display: none;
  align-self: flex-start;
  margin-top: var(--space-2);
}

/* --- LangSwitch — LangSwitch.jsx -------------------------------------------- */
.fd-lang {
  display: inline-flex;
  padding: 3px;                       /* LangSwitch.jsx:16 */
  gap: 2px;
  background: var(--surface-wash);
  border: var(--border-w) solid var(--border-cool);
  border-radius: var(--radius-pill);
}

.fd-lang__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 40px;                    /* LangSwitch.jsx:30 */
  height: 30px;
  padding: 0 10px;
  border-radius: var(--radius-pill);
  border: none;
  cursor: pointer;
  font-family: inherit;
  font-size: var(--fs-label);
  font-weight: var(--fw-semibold);
  letter-spacing: 0.03em;             /* LangSwitch.jsx:38 */
  background: transparent;
  color: var(--text-muted);
  line-height: 1;
  text-decoration: none;
  transition: var(--transition-ui);
}

.fd-lang__btn:hover {
  color: var(--text-link-hover);
  text-decoration: none;
}

/* Buttons use `aria-pressed`; page links expose their current language with
   `aria-current`. Keep both forms visually equivalent during the migration. */
.fd-lang__btn[aria-pressed="true"],
.fd-lang__btn[aria-current="true"],
.fd-lang__btn[aria-current="page"] {
  background: var(--surface-blue);
  color: var(--text-on-blue);
}

/* --- SiteFooter — SiteFooter.jsx -------------------------------------------- */
.fd-footer {
  background: var(--grad-deep);       /* D1 — top stop capped for --text-on-dark */
  color: var(--text-on-dark);
}

.fd-footer__inner {
  max-width: var(--container-max);
  margin: 0 auto;
  padding: 56px var(--gutter) var(--space-6);   /* SiteFooter.jsx:21 */
  display: grid;
  /* SiteFooter.jsx:23 — brand column plus one column per link group. Kept as
     Grid rather than a Bootstrap row: the column count is data-driven. */
  grid-template-columns: minmax(220px, 1fr) repeat(3, minmax(0, 1fr));
  gap: 40px;
}

.fd-footer__brand {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

/* SiteFooter.jsx:33-38 — the logo sits on a white plate so a dark mark stays
   legible on the deep gradient. */
.fd-footer__plate {
  background: var(--white);
  border-radius: var(--radius-badge);
  padding: 10px 14px;
  align-self: flex-start;
}

.fd-footer__tagline {
  font-size: var(--fs-small);
  color: var(--sky-300);
  max-width: 260px;                   /* SiteFooter.jsx:46 */
}

.fd-footer__col {
  display: flex;
  flex-direction: column;
  /* No gap between the links: each one carries a 44px hit area of its own
     (see .fd-footer__link), so a list gap on top of that would push the
     column far past the bundle's rhythm. The title keeps its own spacing. */
  gap: 0;
}

.fd-footer__col-title {
  margin-bottom: var(--space-2);
  font-size: var(--fs-label);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  font-weight: var(--fw-semibold);
  color: var(--white);
}

.fd-footer__link {
  font-size: var(--fs-small);
  color: var(--text-on-dark);
  text-decoration: none;
  /* The bundle renders these as bare inline links, 24px tall on a 32px list
     gap — 36px of vertical rhythm. That clears WCAG 2.5.8 AA but not this
     project's own 44px touch-target rule (CLAUDE.md), so the hit area is
     grown without moving the text. */
  display: inline-flex;
  align-items: center;
  min-height: var(--touch-min);
}

.fd-footer__link:hover {
  color: var(--white);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.fd-footer__legal {
  border-top: var(--border-w) solid var(--navy-700);
}

.fd-footer__legal-inner {
  max-width: var(--container-max);
  margin: 0 auto;
  padding: 18px var(--gutter);        /* SiteFooter.jsx:79 */
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  justify-content: space-between;
  font-size: var(--fs-label);
  color: var(--sky-300);
}


/* ==========================================================================
   5. PATTERNS
   ========================================================================== */

/* --- CtaBand — CtaBand.jsx --------------------------------------------------- */
.fd-cta {
  border-radius: var(--radius-shell);
  padding: var(--space-7);            /* CtaBand.jsx:18 — 48px */
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-6);
  align-items: center;
  justify-content: space-between;
  background: var(--grad-band);
  border: var(--border-w) solid var(--sky-300);
}

.fd-cta--dark {
  background: var(--grad-deep);
  border-color: var(--blue-700);
}

.fd-cta__body {
  max-width: 620px;                   /* CtaBand.jsx:30 */
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.fd-cta__title {
  color: var(--text-primary);
}

.fd-cta--dark .fd-cta__title {
  color: var(--white);
}

.fd-cta__text {
  font-size: var(--fs-lead);
  line-height: var(--lh-lead);
  color: var(--text-body);
}

.fd-cta--dark .fd-cta__text {
  color: var(--text-on-dark);
}

.fd-cta__actions {
  display: flex;
  gap: var(--space-3);
  flex-wrap: wrap;
}

/* --- FactStat — FactStat.jsx -------------------------------------------------- */
.fd-fact {
  display: flex;
  gap: 14px;                          /* FactStat.jsx:17 */
  align-items: flex-start;
}

.fd-fact .fd-icon-sprite { display: none; }

.fd-fact .fd-icon {
  margin-top: var(--space-1);
  color: var(--blue-500);
}

.fd-fact__value {
  font-size: var(--fs-h3);
  line-height: 1.2;                   /* FactStat.jsx:31 */
  font-weight: var(--fw-bold);
  letter-spacing: var(--ls-h3);
  font-variant-numeric: tabular-nums;
  color: var(--text-primary);
}

.fd-fact__label {
  font-size: var(--fs-small);
  color: var(--text-body);
}

.fd-fact__note {
  font-size: var(--fs-label);
  color: var(--text-muted);
  margin-top: var(--space-1);
}

/* dark tone — FactStat.jsx:24, :33, :39, :44 */
.fd-fact--on-dark .fd-icon-sprite { display: none; }

.fd-fact--on-dark .fd-icon { color: var(--white); }
.fd-fact--on-dark .fd-fact__value { color: var(--white); }
.fd-fact--on-dark .fd-fact__label { color: var(--text-on-dark); }

/* FactStat.jsx:44 used rgba(255,255,255,.72); no token, so mixed from --white. */
.fd-fact--on-dark .fd-fact__note {
  color: color-mix(in srgb, var(--white) 72%, transparent);
}

/* --- FaqAccordion — FaqAccordion.jsx ------------------------------------------ */
.fd-faq {
  border-top: var(--border-w) solid var(--border-cool);
}

.fd-faq__item {
  border-bottom: var(--border-w) solid var(--border-cool);
}

.fd-faq__trigger {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  min-height: 64px;                   /* FaqAccordion.jsx:34 — ≥ --touch-min */
  padding: var(--space-4) 0;
  background: none;
  border: none;
  cursor: pointer;
  text-align: left;
  font-family: inherit;
  font-size: var(--fs-lead);
  font-weight: var(--fw-semibold);
  letter-spacing: -0.01em;            /* FaqAccordion.jsx:47 */
  color: var(--text-primary);
}

.fd-faq__trigger .fd-icon-sprite { display: none; }

.fd-faq .fd-icon {
  color: var(--blue-500);
}

/* FaqAccordion.jsx:50 — plus / minus swap driven by aria-expanded */
.fd-faq__icon-minus { display: none; }
.fd-faq__trigger[aria-expanded="true"] .fd-faq__icon-plus { display: none; }
.fd-faq__trigger[aria-expanded="true"] .fd-faq__icon-minus { display: inline-flex; }

/* The bundle unmounted the answer; here it is hidden with `hidden`, which
   keeps it out of the accessibility tree just the same and needs no JS to
   rebuild the DOM. */
.fd-faq__panel[hidden] {
  display: none;
}

.fd-faq__panel {
  padding-bottom: 22px;               /* FaqAccordion.jsx:55 */
  max-width: 720px;
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  color: var(--text-body);
}

/* dark tone — FaqAccordion.jsx:12, :46, :52, :59. The hairline was
   rgba(255,255,255,.30); no token, so mixed from --white. */
.fd-faq--on-dark,
.fd-faq--on-dark .fd-faq__item {
  border-color: color-mix(in srgb, var(--white) 30%, transparent);
}

.fd-faq--on-dark .fd-faq__trigger { color: var(--white); }
.fd-faq--on-dark .fd-faq__trigger .fd-icon-sprite { display: none; }

.fd-faq--on-dark .fd-icon { color: var(--white); }
.fd-faq--on-dark .fd-faq__panel { color: var(--text-on-dark); }

/* Gradient-backed FAQ sections retain the dark-tone accordion treatment. */
.fd-section--deep-soft .fd-faq,
.fd-section--deep-soft .fd-faq__item {
  border-color: color-mix(in srgb, var(--white) 30%, transparent);
}

.fd-section--deep-soft .fd-faq__trigger,
.fd-section--deep-soft .fd-faq .fd-icon {
  color: var(--white);
}

.fd-section--deep-soft .fd-faq__panel {
  padding: var(--space-4);
  margin-bottom: var(--space-3);
  color: var(--text-on-dark);
  background: rgba(16, 35, 58, .2);
  border-radius: var(--radius-card);
}

/* --- Testimonials — FDN-FE-023 --------------------------------------------- */
.fd-testimonials {
  max-width: 820px;
  margin-inline: auto;
  outline: none;
}

.fd-testimonials:focus {
  border-radius: var(--radius-shell);
  box-shadow: var(--focus-ring);
}

.fd-testimonials .swiper-wrapper {
  height: auto;
  padding: var(--space-2) var(--space-1);
}

.fd-testimonial {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-4);
  width: 100%;
  padding: var(--space-6);
  border-radius: var(--radius-card);
  background: var(--surface-raised);
  border: none;
  text-align: center;
}

.fd-testimonial:focus {
  box-shadow: var(--focus-ring), var(--shadow-card);
}

.fd-testimonial__identity {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-3);
  text-align: center;
}

.fd-testimonial__service-icon {
  display: grid;
  place-items: center;
  width: 100px;
  height: 100px;
  border-radius: 50%;
  border: 3px solid var(--sky-300);
  color: var(--blue-700);
}

.fd-testimonial__author {
  font-size: var(--fs-body);
  font-weight: var(--fw-semibold);
  color: var(--text-primary);
}

.fd-testimonial__service-icon .fd-icon {
  width: 48px;
  height: 48px;
}

.fd-testimonial__quote {
  margin: 0;
  font-size: var(--fs-lead);
  line-height: var(--lh-lead);
  color: var(--text-primary);
  font-style: italic;
  text-align: center;
}

.fd-testimonial__quote::before,
.fd-testimonial__quote::after {
  color: var(--amber-600);
  font-size: var(--fs-h2);
  font-weight: var(--fw-bold);
  line-height: 0;
}

.fd-testimonial__quote::before { content: "“"; margin-right: var(--space-1); }
.fd-testimonial__quote::after { content: "”"; margin-left: var(--space-1); }

.fd-testimonials .swiper-pagination {
  margin-top: var(--space-5);
  position: relative;
}

.fd-testimonials .swiper-pagination-bullet {
  width: 12px;
  height: 12px;
  background: var(--navy-700);
  opacity: 0.5;
}

.fd-testimonials .swiper-pagination-bullet-active {
  background: var(--blue-600);
  opacity: 1;
}

@media (min-width: 992px) {
  .fd-testimonial__quote {
    max-width: 80%;
  }
}

@media (max-width: 768px) {
  .fd-testimonial__quote { font-size: var(--fs-body); }
}

/* --- PhotoFrame — PhotoFrame.jsx ---------------------------------------------- */
.fd-photo {
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;                          /* PhotoFrame.jsx:20 */
}

.fd-photo__frame {
  position: relative;
  aspect-ratio: 4 / 3;                /* PhotoFrame.jsx:7 default */
  border-radius: var(--radius-card);
  overflow: hidden;
  background: var(--surface-band);
  border: var(--border-w) solid var(--sky-300);
}

.fd-photo--shell .fd-photo__frame { border-radius: var(--radius-shell); }
.fd-photo--square .fd-photo__frame { aspect-ratio: 1 / 1; }
.fd-photo--wide .fd-photo__frame { aspect-ratio: 16 / 9; }
.fd-photo--portrait .fd-photo__frame { aspect-ratio: 3 / 4; }

.fd-photo__img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* PhotoFrame.jsx:41-52 — the "Bild folgt" state when no photo is approved yet */
.fd-photo__placeholder {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  color: var(--blue-500);
  font-size: var(--fs-small);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
}

.fd-photo__caption {
  margin-top: var(--space-2);
  font-size: var(--fs-small);
  line-height: var(--lh-small);
  color: var(--text-muted);           /* D3 — the corrected muted grey */
}

.fd-photo--on-dark .fd-photo__caption {
  color: var(--text-on-dark);
}

/* --- ProcessSteps — ProcessSteps.jsx ------------------------------------------- */
.fd-steps {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--space-5);
  list-style: none;
  margin: 0;
  padding: 0;
}

.fd-steps__item {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  min-width: 0;
  padding: var(--space-5);
  background: var(--surface-raised);
  border: var(--border-w) solid var(--border-cool);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-sm);
}

.fd-steps__number {
  color: var(--text-muted);
  font-size: 2.75rem;
  font-variant-numeric: tabular-nums;
  line-height: 1;
  font-weight: var(--fw-bold);
}

.fd-steps__title {
  font-size: var(--fs-lead);
  font-weight: var(--fw-semibold);
  letter-spacing: -0.01em;
  color: var(--text-primary);
}

.fd-steps__text {
  font-size: var(--fs-small);
  line-height: var(--lh-small);
  color: var(--text-body);
}

.fd-steps__icon {
  margin: 0;
  color: var(--accent-icon);
}

/* dark tone — ProcessSteps.jsx:28, :37-38, :46, :53 */
.fd-steps--on-dark .fd-steps__item { border-top-color: var(--navy-700); }
.fd-steps--on-dark .fd-steps__number { color: var(--sky-300); }
.fd-steps--on-dark .fd-steps__title { color: var(--white); }
.fd-steps--on-dark .fd-steps__text { color: var(--text-on-dark); }

/* --- fd-step-card — FDN-FE-019 ------------------------------------------- */
.fd-step-card {
  display: grid;
  grid-template-areas:
    "number icon"
    "title title"
    "text text";
  grid-template-columns: minmax(0, 1fr) auto;
  column-gap: var(--space-3);
  row-gap: var(--space-3);
  align-items: start;
  padding: var(--space-6);
  background: var(--surface-raised);
  border: var(--border-w) solid var(--border-cool);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-card);
  transition: var(--transition-ui);
  list-style: none;
}

.fd-step-card .fd-icon-badge {
  grid-area: icon;
  justify-self: end;
  align-self: center;
}

.fd-step-card .fd-steps__number {
  grid-area: number;
  align-self: center;
}

.fd-step-card .fd-steps__title {
  grid-area: title;
}

.fd-step-card .fd-steps__text {
  grid-area: text;
}

/* On blue / dark ground, apply fd-glass instead of the white card */
.fd-step-card.fd-glass {
  background: var(--glass-bg);
  border-color: var(--glass-line);
}

.fd-step-card.fd-glass .fd-steps__title { color: var(--white); }
.fd-step-card.fd-glass .fd-steps__text { color: var(--text-on-dark); }
.fd-step-card.fd-glass .fd-steps__number { color: var(--sky-300); }

.fd-section--deep-soft .fd-step-card.fd-glass .fd-steps__title { color: var(--text-primary); }
.fd-section--deep-soft .fd-step-card.fd-glass .fd-steps__text  { color: var(--text-body); }
.fd-section--deep-soft .fd-step-card.fd-glass .fd-steps__number { color: var(--navy-700); }

.fd-step-card:hover,
.fd-step-card:focus-within {
  border-color: var(--action-primary);
  transform: translateY(-2px);
  box-shadow: var(--shadow-lift);
}

/* --- fd-icon-badge — reusable coloured icon square (FDN-FE-019) ---------- */
.fd-icon-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  border-radius: var(--radius-badge);
  flex-shrink: 0;
}

.fd-icon-badge .fd-icon {
  color: var(--white);
  width: 24px;
  height: 24px;
}

.fd-icon-badge--blue   { background: var(--blue-500); }
.fd-icon-badge--green  { background: var(--status-ok); }
.fd-icon-badge--purple { background: var(--purple-500); }
.fd-icon-badge--coral  { background: var(--action-primary); }

/* --- fd-benefits — FDN-FE-027 -------------------------------------------- */
.fd-benefits {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--space-5);
}

.fd-benefit {
  display: grid;
  align-content: start;
  gap: var(--space-3);
  min-width: 0;
  padding: var(--space-6);
  background: var(--surface-raised);
  border: var(--border-w) solid var(--border-cool);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-card);
}

.fd-benefit__title {
  margin: 0;
  color: var(--text-primary);
  font-size: var(--fs-lead);
  font-weight: var(--fw-semibold);
  line-height: var(--lh-lead);
}

.fd-benefit__text {
  margin: 0;
  color: var(--text-body);
  font-size: var(--fs-small);
  line-height: var(--lh-small);
}

/* FDN-FE-085 — card copy follows the home-process reading direction: the
   visual marker sits to the right while the heading and supporting copy keep
   their natural left-aligned flow. A float lets longer copy use the space below
   the badge on both narrow and wide cards. */
.fd-benefit {
  display: flow-root;
}

.fd-benefit > .fd-icon-badge {
  float: right;
  margin: 0 0 var(--space-2) var(--space-3);
}

/* Scope cards must remain opaque and readable on the blue gradient. */
.fd-section--deep-soft .fd-benefit {
  background: var(--white);
  color: var(--text-primary);
}

.fd-section--deep-soft .fd-benefit__title { color: var(--text-primary); }
.fd-section--deep-soft .fd-benefit__text { color: var(--text-body); }

@media (min-width: 992px) {
  .fd-benefits--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

@media (max-width: 991.98px) {
  .fd-benefits { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .fd-benefits > .fd-benefit:last-child:nth-child(odd) { grid-column: 1 / -1; }
}

@media (max-width: 575.98px) {
  .fd-benefits { grid-template-columns: 1fr; }
  .fd-benefits > .fd-benefit:last-child:nth-child(odd) { grid-column: auto; }
}

/* --- ServiceCard — ServiceCard.jsx --------------------------------------------- */
.fd-service {
  display: flex;
  flex-direction: column;
  gap: 14px;                          /* ServiceCard.jsx:22 */
  padding: 28px;
  text-decoration: none;
  border-radius: var(--radius-card);
  background: var(--white);
  border: var(--border-w) solid var(--border-cool);
  box-shadow: var(--shadow-card);
  transition:
    transform var(--dur-base) var(--ease-standard),
    box-shadow var(--dur-base) var(--ease-standard),
    border-color var(--dur-base) var(--ease-standard);
}

.fd-service--wash {
  background: var(--surface-wash);
  border-color: var(--sky-300);
}

.fd-service:hover,
.fd-service:focus-visible {
  text-decoration: none;
  border-color: var(--border-strong);
  box-shadow: var(--shadow-lift);
  transform: translateY(-3px);
}

.fd-service__badge {
  width: 48px;                        /* ServiceCard.jsx:35 */
  height: 48px;
  border-radius: var(--radius-badge);
  background: var(--sky-200);
  display: grid;
  place-items: center;
}

.fd-service__badge .fd-icon-sprite { display: none; }

.fd-service__badge .fd-icon {
  color: var(--blue-500);
}

.fd-service__title {
  font-size: var(--fs-h3);
  line-height: var(--lh-h3);
  letter-spacing: var(--ls-h3);
  font-weight: var(--fw-semibold);
  color: var(--text-primary);
}

.fd-service__text {
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  color: var(--text-body);
  flex: 1;
}

.fd-service__scope {
  display: grid;
  gap: var(--space-1);
  margin: 0;
  padding: 0;
  list-style: none;
  color: var(--text-body);
  font-size: var(--fs-small);
  line-height: var(--lh-small);
}

.fd-service__scope li {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: var(--space-2);
}

.fd-service__scope li::before {
  content: "•";
  color: var(--text-link);
}

/* FDN-FE-092: the repair card is the only one carrying a full scope list, so
   in the three-column grid it stood alone on its own row at 808px against its
   siblings' 257px. It spans the row instead, and the list runs in columns so
   the card keeps the height of a normal band. */
.fd-service--repair {
  grid-column: 1 / -1;
}

.fd-service--repair .fd-service__scope {
  display: block;
  columns: 3;
  column-gap: var(--space-6);
}

.fd-service--repair .fd-service__scope li {
  margin-bottom: var(--space-1);
  break-inside: avoid;
}

.fd-service__guarantee {
  margin-top: var(--space-2);
  font-size: var(--fs-small);
  line-height: var(--lh-small);
  font-weight: var(--fw-semibold);
  color: var(--text-primary);
}

@media (max-width: 900px) {
  .fd-service--repair .fd-service__scope { columns: 2; }
}

@media (max-width: 600px) {
  .fd-service--repair .fd-service__scope { columns: 1; }
}

/* ServiceCard.jsx:68 painted this label --blue-500. On the card's own white or
   wash ground that is D4 territory, so the link role token is used instead. */
.fd-service__action {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--fs-small);
  font-weight: var(--fw-semibold);
  color: var(--text-link);
}

.fd-service__action .fd-icon-sprite { display: none; }

.fd-service__action .fd-icon {
  color: currentColor;
  transition: transform var(--dur-base) var(--ease-standard);
}

.fd-service:not(.fd-service--photo) {
  display: flow-root;
}

.fd-service:not(.fd-service--photo) .fd-service__badge {
  float: right;
  margin: 0 0 var(--space-2) var(--space-3);
}

.fd-service:not(.fd-service--photo) .fd-service__title,
.fd-service:not(.fd-service--photo) .fd-service__text {
  display: block;
}

.fd-service:hover .fd-service__action .fd-icon-sprite { display: none; }

.fd-service:hover .fd-service__action .fd-icon {
  transform: translateX(3px);         /* ServiceCard.jsx:75 */
}


/* ==========================================================================
   6. SHARED WRAPPERS — shared.jsx
   ========================================================================== */

/* --- SectionHead — shared.jsx:86-119 ------------------------------------------ */
.fd-head {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  max-width: 720px;                   /* shared.jsx:93 default */
  margin-bottom: 40px;
}

.fd-head--center {
  text-align: center;
  margin-inline: auto;
}

.fd-head--wide { max-width: none; }

/* Buttons that close a section, below a card grid or a copy block. This is NOT
   .fd-hero__actions: that one sits 4px under a hero lead paragraph on purpose,
   and reusing it after a card grid glues the buttons to the cards. */
.fd-section__actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-3);
  margin-top: 64px;
}

.fd-head__lead {
  font-size: var(--fs-lead);
  line-height: var(--lh-lead);
  color: var(--text-body);
}

.fd-section--hero .fd-head__lead,
.fd-section--deep-soft .fd-head__lead,
.fd-section--navy .fd-head__lead,
.fd-section--deep .fd-head__lead {
  color: var(--text-on-dark);
}

/* --- Disclaimer — shared.jsx:122-142 -------------------------------------------
   Carries the "unverbindlich" wording, the legally load-bearing line on every
   enquiry page — hence D3's correction of --text-muted. */
.fd-disclaimer {
  display: flex;
  gap: var(--space-2);
  align-items: flex-start;
  font-size: var(--fs-small);
  color: var(--text-muted);
}

.fd-disclaimer .fd-icon-sprite { display: none; }

.fd-disclaimer .fd-icon {
  margin-top: 2px;
  flex: 0 0 auto;
}

/* --- WhatsAppPreview — shared.jsx:145-198 -------------------------------------
   Read-only preview of the message a journey would prepare. It never sends
   anything and never carries a real number: the recipient is out of scope
   until the client approves it. */
.fd-wa {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.fd-wa__head {
  display: flex;
  align-items: center;
  gap: 10px;
}

.fd-wa__head .fd-icon-sprite { display: none; }

.fd-wa__head .fd-icon {
  color: var(--blue-500);
}

.fd-wa__title {
  font-size: var(--fs-small);
  font-weight: var(--fw-semibold);
  color: var(--text-primary);
}

.fd-wa__body {
  background: var(--white);
  border: var(--border-w) solid var(--border-cool);
  border-radius: var(--radius-card);
  padding: 18px;                      /* shared.jsx:180 */
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.fd-wa__line {
  font-size: var(--fs-small);
  line-height: 1.6;                   /* shared.jsx:189 */
  color: var(--text-body);
  font-weight: var(--fw-regular);
}

.fd-wa__line:first-child {
  color: var(--text-primary);
  font-weight: var(--fw-semibold);
}

/* --- pricing tables — FDN-FE-060 ----------------------------------------- */
.fd-pricing-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-5);
}

.fd-pricing-card {
  padding: var(--space-6);
  background: var(--surface-raised);
  border: var(--border-w) solid var(--border-cool);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-card);
}

.fd-pricing-card--wide { max-width: var(--container-narrow); margin-inline: auto; }

.fd-pricing-table {
  width: 100%;
  margin-top: var(--space-4);
  border-collapse: collapse;
}

.fd-pricing-table th,
.fd-pricing-table td {
  padding: var(--space-3) 0;
  border-bottom: var(--border-w) solid var(--border-cool);
  font-size: var(--fs-small);
  line-height: var(--lh-small);
}

.fd-pricing-table tr:last-child th,
.fd-pricing-table tr:last-child td { border-bottom: 0; }

.fd-pricing-table th {
  padding-right: var(--space-3);
  color: var(--text-primary);
  font-weight: var(--fw-medium);
  text-align: left;
}

.fd-pricing-table td {
  color: var(--text-primary);
  font-weight: var(--fw-bold);
  text-align: right;
  white-space: nowrap;
}

.fd-pricing-note {
  max-width: var(--container-narrow);
  margin: var(--space-5) auto 0;
  color: var(--text-body);
  font-size: var(--fs-small);
  text-align: center;
}

@media (max-width: 991px) {
  .fd-pricing-grid { grid-template-columns: 1fr; }
}

/* On narrow viewports the label + non-wrapping price exceed the card's content
   width, so the table's min-content width pushes the card past the viewport and
   the page scrolls sideways. Stack the two cells instead of shrinking them. */
@media (max-width: 575px) {
  .fd-pricing-table,
  .fd-pricing-table tbody,
  .fd-pricing-table tr,
  .fd-pricing-table th,
  .fd-pricing-table td { display: block; width: auto; }

  .fd-pricing-table tr {
    padding: var(--space-3) 0;
    border-bottom: var(--border-w) solid var(--border-cool);
  }

  .fd-pricing-table tr:last-child { border-bottom: 0; }

  .fd-pricing-table th,
  .fd-pricing-table td {
    padding: 0;
    border-bottom: 0;
    overflow-wrap: break-word;
  }

  .fd-pricing-table td {
    margin-top: var(--space-1);
    text-align: left;
    white-space: normal;
  }
}

.fd-pricing-card h3 {
  margin: 0;
  font-size: var(--fs-body);
  font-weight: var(--fw-bold);
  color: var(--text-primary);
}


/* ==========================================================================
   7. GRID RATIOS
   The bundle sets `gridTemplateColumns` inline. Pages use Bootstrap's
   `.row` / `.col-lg-*` instead; where the bundle's ratio is uneven the nearest
   Bootstrap split is used and the deviation is recorded here.

     bundle ratio        %          Bootstrap split   deviation
     1fr 1fr             50 / 50    col-lg-6 + 6      none
     1.05fr 0.95fr       52.5/47.5  col-lg-6 + 6      -2.5 pt on the lead column
     1.1fr 0.9fr         55 / 45    col-lg-7 + 5      +3.3 pt on the lead column
     1.15fr 0.85fr       57.5/42.5  col-lg-7 + 5      +0.8 pt on the lead column
     0.9fr 1.1fr         45 / 55    col-lg-5 + 7      -3.3 pt on the lead column
     0.85fr 1.15fr       42.5/57.5  col-lg-5 + 7      -0.8 pt on the lead column
     repeat(3, 1fr)      thirds     col-lg-4 ×3       none
     repeat(4, 1fr)      quarters   col-lg-3 ×4       none

   Evidence: Home.jsx:23, :82, :102, :216, :244, :315, :341;
             Cleaning.jsx:57, :95, :223, :276, :315, :328, :365;
             Renovation.jsx:20, :59, :165, :218, :278, :340.

   Bootstrap's default gutter is 1.5rem = 24px, which already equals
   --gutter / --space-5, so the bundle's `gap: 24` needs no override. The
   larger `gap: 56` / `gap: 48` pairs get the two helpers below.
   ========================================================================== */

.fd-row-gap-lg {
  --bs-gutter-x: var(--space-7);      /* 48px — Cleaning.jsx:224 */
  --bs-gutter-y: var(--space-7);
}

.fd-row-gap-xl {
  /* Home.jsx:24 asks for a 56px column gap. A Bootstrap row pulls itself out
     by half its gutter on each side, and the only padding available to absorb
     that pull is --gutter (24px). 56 would need 28, so the row hung 4px past
     the viewport on both edges — measured at 791px CSS width. The vertical
     gap keeps the bundle's 56; the horizontal one is capped at 48 (= 2 ×
     --gutter), which is the widest gap the container can hold. Deviation from
     the bundle: 8px of column gap, only on rows using this helper. */
  --bs-gutter-x: var(--space-7);      /* 48px, capped — see above */
  --bs-gutter-y: 56px;                /* Home.jsx:24 */
}

/* Gallery grid — the filterable grid is CSS Grid + vanilla JS, never Isotope. */
.fd-gallery {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  grid-auto-rows: 1fr;
  gap: var(--space-5);
  margin-inline: auto;
}

.fd-gallery__item {
  position: relative;
  display: flex;
  min-width: 0;
  margin: 0;
  overflow: hidden;
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-sm);
}

.fd-gallery__item .fd-photo__frame {
  flex: 1;
  aspect-ratio: 4 / 3;
}

.fd-gallery__item .fd-photo__caption {
  position: absolute;
  bottom: var(--space-3);
  left: var(--space-3);
  max-width: calc(100% - var(--space-6));
  margin: 0;
  padding: var(--space-2) var(--space-3);
  background: var(--glass-bg-strong);
  border: var(--border-w) solid var(--glass-line);
  -webkit-backdrop-filter: blur(var(--glass-blur-sm)) saturate(130%);
  backdrop-filter: blur(var(--glass-blur-sm)) saturate(130%);
  border-radius: var(--radius-badge);
  color: var(--text-primary);
}

@supports not (backdrop-filter: blur(1px)) {
  .fd-gallery__item .fd-photo__caption {
    background: var(--surface-band);
  }
}

.fd-gallery__item[hidden] {
  display: none;
}

.fd-gallery__filters {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-start;
  gap: var(--space-2);
  margin-bottom: var(--space-5);
}


/* ==========================================================================
   8. BREAKPOINTS
   Each `mobile ? A : B` in the JSX becomes a real media query.

      991.98px  header nav → burger        (see the note below)
      991.98px  two-column → single, gallery 3-up → 2-up
      820px     h1/h2 → mobile sizes       (in tokens.css; the bundle's own step)
      767.98px  section padding, gutters and hero padding → mobile values

   HEADER BREAKPOINT — the `900px` step carried over from the previous bundle
   is DROPPED. Two reasons, one structural and one measured.

   Structural: `SiteHeader.jsx:51` and `:80` branch on a single `mobile`
   boolean. There is a desktop row and a mobile row and nothing in between, so
   there is no third arrangement for a 900px step to switch into.

   Measured: at 1440px, with the five German nav labels, the DE/EN switch and
   the CTA, the desktop bar needs **909px** minimum (brand 52 + gap 24 +
   margin 12 + nav 467 + gap 24 + actions 283 + padding 48). That is the width
   at which the row would begin to crowd — close to the old 900px figure, so
   the previous audit was not wrong about the number. It is simply unreachable
   now: the nav became a burger at 1199.98px, well above 909px, so between
   900px and 1199px no desktop nav was rendered at all. The responsive switch
   now follows the 991.98px content breakpoint, preserving the full nav and
   conversion CTA at ordinary laptop widths including 1053px.
   ========================================================================== */

@media (max-width: 991.98px) {
  /* SiteHeader.jsx:51 / :80 — desktop nav out, burger in */
  .fd-header__nav {
    display: none;
  }

  .fd-header__burger {
    display: grid;
  }

  .fd-header__actions .fd-lang {
    display: none;
  }

  .fd-header__actions .fd-header__phone-link {
    display: inline-flex;
    gap: var(--space-2);
    padding: 0 var(--space-3);
    min-height: var(--touch-min);
    height: var(--touch-min);
  }

  .fd-header__phone-full {
    display: inline;
  }

  .fd-header__drawer .fd-lang {
    display: inline-flex;
  }

}

@media (max-width: 991.98px) {
  .fd-gallery {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .fd-steps {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .fd-footer__inner {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--space-6);
  }

  /* CtaBand.jsx:22 — the actions drop under the copy rather than sit beside it */
  .fd-cta {
    padding: var(--space-6);
  }

  .fd-cta__body {
    max-width: none;
  }
}

@media (max-width: 767.98px) {
  /* shared.jsx:80 — mobile section rhythm and gutter */
  .fd-section__inner {
    padding: var(--section-y-mobile) var(--gutter-mobile);
  }

  .fd-section--hero .fd-section__inner {
    padding: var(--space-4) var(--gutter-mobile);
    min-height: calc(100svh - var(--header-h-mobile));
  }

  /* FDN-FE-018: on mobile all min-height collapses; content dictates height */
  .fd-section--full .fd-section__inner {
    min-height: auto;
  }

  .fd-container {
    padding-inline: var(--gutter-mobile);
  }

  /* SiteHeader.jsx:32-33 */
  .fd-header__bar {
    padding: 0 var(--gutter-mobile);
    height: var(--header-h-mobile);
    gap: var(--space-3);
  }

  .fd-logo {
    height: 30px;                     /* SiteHeader.jsx:50 mobile */
  }

  .fd-header__actions {
    gap: 10px;                        /* SiteHeader.jsx:101 */
  }

  /* shared.jsx:102 */
  .fd-head {
    margin-bottom: 28px;
  }

  .fd-gallery {
    display: flex;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    gap: var(--space-4);
    -webkit-overflow-scrolling: touch;
    padding-bottom: var(--space-3);
  }

  .fd-gallery__item {
    flex: 0 0 85%;
    scroll-snap-align: start;
  }

  .fd-steps {
    grid-template-columns: 1fr;
  }

  .fd-footer__inner {
    grid-template-columns: 1fr;
    padding: var(--space-7) var(--gutter-mobile) var(--space-5);
  }

  .fd-footer__tagline {
    max-width: none;
  }

  .fd-cta {
    padding: var(--space-5);
  }

  .fd-cta__actions {
    width: 100%;
  }

  .fd-cta__actions .fd-btn {
    flex: 1 1 100%;
    min-width: 0;
    white-space: normal;
  }

  /* Cleaning.jsx:63 / Renovation.jsx:26 — cards tighten on mobile */
  .fd-card--pad-lg {
    padding: 22px;
  }

  /* A Bootstrap `.row` pulls itself out by half a gutter on each side. With
     --bs-gutter-x at 48px that is -24px against a 20px mobile gutter, which
     measured as 4px of horizontal page overflow at 375px. Collapsing the
     helpers to the standard gutter fixes it and matches the bundle's own
     mobile gaps (Home.jsx:24 → 32, Cleaning.jsx:224 → 28). */
  .fd-row-gap-lg {
    --bs-gutter-x: var(--space-5);
    --bs-gutter-y: 28px;
  }

  .fd-row-gap-xl {
    --bs-gutter-x: var(--space-5);
    --bs-gutter-y: var(--space-6);
  }

  /* Every interactive target must clear 44px at 375px. The bundle sizes these
     four for a mouse (Button sm 38, Chip 36, LangSwitch 30, the logo link at
     its image height); on touch they grow. Nothing else about them changes. */
  .fd-btn--sm,
  .fd-lang__btn {
    height: var(--touch-min);
  }

  .fd-lang__btn {
    min-width: var(--touch-min);
    padding: 0 8px;
  }

  .fd-chip {
    min-height: var(--touch-min);
  }

  .fd-header__brand {
    min-height: var(--touch-min);
    align-items: center;
  }
}


/* ==========================================================================
   9. UTILITIES
   ========================================================================== */

/* Screen-reader-only text that still reaches the accessibility tree. */
.fd-sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* Skip link — hidden until focused, then pinned to the top-left. */
.fd-skip-link {
  position: absolute;
  left: var(--space-4);
  top: calc(var(--space-4) * -6);
  z-index: 100;
  padding: var(--space-3) var(--space-4);
  background: var(--white);
  color: var(--text-link);
  border: var(--border-w) solid var(--border-focus);
  border-radius: var(--radius-control);
  font-weight: var(--fw-semibold);
  transition: top var(--dur-fast) var(--ease-standard);
}

.fd-skip-link:focus {
  top: var(--space-4);
}

/* `scroll-margin-top` keeps a hash target clear of the sticky header. */
[id] {
  scroll-margin-top: calc(var(--header-h) + var(--space-4));
}

/* Smooth scrolling is opt-in via JS (main.js), which checks
   `prefers-reduced-motion` itself, so no CSS `scroll-behavior` is set here. */

/* Locks background scroll while the mobile drawer is open. */
.fd-scroll-locked {
  overflow: hidden;
}

/* The lift/translate effects above are motion. tokens.css collapses every
   duration to 1ms under `prefers-reduced-motion: reduce`, which neutralises the
   transitions; the transforms themselves are suppressed here. */
@media (prefers-reduced-motion: reduce) {
  .fd-btn:hover,
  .fd-card--lift:hover,
  .fd-service:hover {
    transform: none;
  }

  .fd-service:hover .fd-service__action .fd-icon-sprite { display: none; }

  .fd-service:hover .fd-service__action .fd-icon {
    transform: none;
  }

  .fd-section--hero .fd-hero__copy { transition: none; }
}


/* ==========================================================================
   10. HOME-PAGE COMPONENTS — ADDED BY FDN-FE-001

   !! THESE CLASSES BELONG TO FDN-FE-005 !!
   They were missing from the shared layer when index.html was built, and a
   page task may not use inline styles or literal colours. Every declaration
   below is transcribed from `.design/extracted/src/ui_kits__website__Home.jsx`
   with the line beside it, and uses tokens only. Fold this block into the
   sections above when FDN-FE-005 is next revised.

   The one component here that has no counterpart in §5 is PathCard
   (Home.jsx:118-185) — the two equal entry cards under the hero.
   ========================================================================== */

/* The home hero closes with a hairline instead of running into the next
   section — Home.jsx:13. */
.fd-section--edge {
  border-bottom: var(--border-w) solid var(--blue-600);
}

/* --- hero layout — Home.jsx:20-99 ------------------------------------------- */
.fd-hero__copy {
  display: flex;
  flex-direction: column;
  gap: 20px;                          /* Home.jsx:31 — no space token at 20 */
}

.fd-hero__lead {
  margin-inline-start: calc(var(--space-4) - var(--border-w));
  font-size: var(--fs-lead);
  line-height: var(--lh-lead);
  max-width: 520px;                   /* Home.jsx:44 */
}

.fd-hero__actions {
  display: flex;
  flex-wrap: wrap;                    /* two --lg buttons no longer fit col-lg-7 */
  gap: var(--space-3);                /* Home.jsx:50 */
  margin-top: var(--space-1);         /* Home.jsx:51 */
}


.fd-hero__photos {
  display: grid;
  grid-template-columns: 1fr 1fr;     /* Home.jsx:82 — stays 2-up on mobile */
  gap: var(--space-4);                /* Home.jsx:83 */
  align-items: start;
}

/* Home.jsx:90-91 — the first photo drops by 28px so the pair reads as a stagger
   rather than a block. Removed once the hero stacks. */
.fd-photo--offset {
  margin-top: 28px;
}

/* PhotoFrame ratio the shared layer does not carry yet — Home.jsx:208 */
.fd-photo--ultrawide .fd-photo__frame {
  aspect-ratio: 21 / 9;
}

/* --- PathCard — Home.jsx:118-185 -------------------------------------------- */
.fd-paths {
  display: grid;
  grid-template-columns: 1fr 1fr;     /* Home.jsx:102 */
  gap: var(--space-4);                /* Home.jsx:103 */
  margin-top: 44px;                   /* Home.jsx:104 — no space token at 44 */
}

.fd-path {
  display: flex;
  gap: 18px;                          /* Home.jsx:132 — no space token at 18 */
  align-items: flex-start;
  padding: 26px;                      /* Home.jsx:129 */
  text-decoration: none;
}

.fd-path:hover {
  text-decoration: none;
}

.fd-path__badge {
  flex: 0 0 auto;
  width: 52px;                        /* Home.jsx:139-140 */
  height: 52px;
  border-radius: var(--radius-badge);
  border: var(--border-w) solid var(--sky-300);
  display: grid;
  place-items: center;
}

/* Home.jsx:143 — the wash card lifts its badge to white, the white card drops
   it onto the band, so the icon never sits on its own ground. */
.fd-path--cleaning .fd-path__badge { background: var(--white); }
.fd-path--renovation .fd-path__badge { background: var(--surface-band); }
.fd-path--renovation .fd-path__badge .fd-icon { color: var(--blue-700); }

.fd-path__body {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);                /* Home.jsx:156 */
}

.fd-path__title {
  font-size: var(--fs-h3);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--ls-h3);
  color: var(--text-primary);
}

.fd-path__text {
  font-size: var(--fs-small);
  line-height: var(--lh-small);
  color: var(--text-body);
}

/* Home.jsx:178 painted this label --blue-500. On the card's wash ground that is
   D4, so the link role token is used — the same correction ServiceCard got. */
.fd-path__action {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--fs-small);
  font-weight: var(--fw-semibold);
  color: var(--text-link);
}

/* Path cards use the same icon-right, text-wraps pattern as the other cards. */
.fd-path {
  display: flow-root;
}

.fd-path__badge {
  float: right;
  width: 48px;
  height: 48px;
  margin: 0 0 var(--space-2) var(--space-3);
}

.fd-path__body {
  display: block;
}

.fd-path__title,
.fd-path__text {
  display: block;
}

/* --- section grids the bundle states inline --------------------------------- */
.fd-facts {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-6);
}

/* Facts are evidence slots: one prominent value, then its context. */
#facts .fd-fact,
.fd-about-facts .fd-fact {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-6);
  border-radius: var(--radius-card);
}

#facts .fd-fact .fd-icon-badge,
.fd-about-facts .fd-fact .fd-icon-badge {
  order: -1;
}

#facts .fd-fact .fd-icon-badge .fd-icon,
.fd-about-facts .fd-fact .fd-icon-badge .fd-icon {
  margin-top: 0;
}

#facts .fd-fact__value,
.fd-about-facts .fd-fact__value {
  font-size: var(--fs-h1);
  line-height: var(--lh-h1);
  font-weight: var(--fw-extrabold);
  letter-spacing: var(--ls-h1);
}

#facts .fd-fact__label,
.fd-about-facts .fd-fact__label {
  font-size: var(--fs-small);
  font-weight: var(--fw-semibold);
  line-height: var(--lh-small);
}

#facts .fd-fact__note,
.fd-about-facts .fd-fact__note {
  color: var(--text-on-dark);
  margin-top: 0;
}

@supports not (backdrop-filter: blur(1px)) {
  #facts .fd-fact.fd-glass,
  .fd-about-facts .fd-fact.fd-glass {
    background: var(--surface-navy);
  }
}

.fd-services {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));   /* Home.jsx:216 */
  gap: 20px;                          /* Home.jsx:217 — no space token at 20 */
}

.fd-services--home {
  width: min(100%, calc(var(--container-max) * 3 / 4));
  gap: 100px;
  margin-inline: auto;
}

/* A chip row that is not a gallery filter — Home.jsx:350-360, Home.jsx:302-307 */
.fd-chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin: 0;
  padding: 0;
  list-style: none;
}

/* FDN-FE-103 — the local-area photo follows the full chip column on desktop,
   preventing an empty deep-soft block beside the municipality list. */
@media (min-width: 992px) {
  #area .fd-photo,
  #area .fd-photo__frame {
    height: 100%;
  }

  #area .fd-photo__frame {
    aspect-ratio: auto;
  }
}

@media (max-width: 991.98px) {
  .fd-paths,
  .fd-services {
    grid-template-columns: 1fr;
  }

  .fd-facts {
    grid-template-columns: 1fr;
  }

  /* the hero has stacked, so the stagger has nothing left to stagger against */
  .fd-photo--offset {
    margin-top: 0;
  }
}

@media (max-width: 767.98px) {
  /* FDN-FE-083: keep the full message and actions in the first viewport.
     Hero media begins after the blue copy field rather than competing with it. */
  /* FDN-FE-123: while the cookie banner covers the lower half of the first
     screen, the hero copy rides up by the exact distance main.js measures and
     glides back to centre when the banner closes. */
  .fd-section--hero .fd-hero__copy {
    transform: translateY(calc(-1 * var(--fd-hero-lift, 0px)));
    transition: transform 280ms ease;
  }

  .fd-hero__copy {
    align-items: center;
    gap: var(--space-3);
    text-align: center;
  }

  .fd-section--hero h1 {
    font-size: calc(var(--fs-h1-mobile) - var(--space-2));
  }

  .fd-hero__lead {
    margin-inline: auto;
    font-size: var(--fs-small);
    max-width: 34ch;
  }

  .fd-hero__actions {
    width: 100%;
    margin-top: 0;
    gap: var(--space-2);
  }

  .fd-hero__actions .fd-btn--lg {
    height: var(--space-7);
    font-size: var(--fs-body);
  }

  /* No photography in any hero on mobile — the copy and the CTA own the first
     screen. Hiding the figure alone would leave its empty grid column behind and
     the row gutter would still print a strip, so the whole column goes. Columns
     that hold facts or contact details (kontakt, ueber-uns) carry no .fd-photo
     and are deliberately untouched. */
  #hero .col-lg-5:has(.fd-photo),
  #hero .col-lg-6:has(.fd-hero__photos) {
    display: none;
  }

  .fd-hero__photos {
    display: none;
  }

  /* Home.jsx:49 / :57 — the hero buttons stack and go full width */
  .fd-hero__actions,
  .fd-section__actions {
    flex-direction: column;
  }

  .fd-hero__actions .fd-btn,
  .fd-section__actions .fd-btn {
    width: 100%;
  }

  .fd-section__actions {
    margin-top: 40px;
  }

  .fd-facts {
    gap: var(--space-5);
  }

  #facts .fd-fact__value,
  .fd-about-facts .fd-fact__value {
    font-size: var(--fs-h1-mobile);
  }

  .fd-paths {
    margin-top: 28px;                 /* Home.jsx:104 mobile */
  }
}


/* ==========================================================================
   11. CLEANING-PAGE COMPONENTS — ADDED BY FDN-FE-002

   !! THESE CLASSES BELONG TO FDN-FE-005 !!
   They were missing from the shared layer when cleaning.html was built, and a
   page task may not use inline styles or literal colours. Every declaration
   below is transcribed from `.design/extracted/src/ui_kits__website__Cleaning.jsx`
   with the line beside it, and uses tokens only. Fold this block into the
   sections above when FDN-FE-005 is next revised.

   NOTHING here belongs to the cancelled price calculator: the estimate card,
   the CHF total and the hours line (Cleaning.jsx:157-199) have no styles,
   because they have no markup.
   ========================================================================== */

/* PhotoFrame ratio the shared layer does not carry yet — Cleaning.jsx:370, :374 */
.fd-photo--3x2 .fd-photo__frame {
  aspect-ratio: 3 / 2;
}

/* Cleaning.jsx:276 — the service grid runs three up here, not two as on home */
.fd-services--3 {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

/* --- scope cards — FDN-FE-036 --------------------------------------------- */
/* Four scope cards in a three-column grid left the last one alone beside two
   empty columns — the large void the client reported next to the small-repairs
   section. A fixed count cannot serve both pages: renovation has four cards,
   reinigung five. `auto-fit` collapses the empty tracks so each page gets one
   even row, and the narrower breakpoints further down still take over. */
.fd-scope-cards {
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
}

.fd-scope-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-5);
}

.fd-scope-card {
  background: var(--glass-bg);
  border-radius: var(--radius-card);
  padding: var(--space-5);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.fd-scope-card__head {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}

/* The card is a light glass pane whatever the section behind it, so its text
   is always dark. Scoped to the component rather than to the section, but it
   has to be scoped to *something*: a bare `.fd-scope-card__title` (0,1,0)
   loses to `.fd-section--deep-soft h3` (0,1,1) and the title renders white on
   a light pane at a ratio of 1.7. Measured in a browser, not assumed —
   audit check 12 only runs with `--browser`, which is how this shipped twice. */
.fd-scope-card .fd-scope-card__title {
  font-size: var(--fs-lead);
  font-weight: 600;
  line-height: var(--lh-lead);
  color: var(--text-primary);
  margin: 0;
}

.fd-scope-card__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.fd-scope-card .fd-scope-card__list li {
  position: relative;
  padding-left: var(--space-4);
  font-size: var(--fs-small);
  line-height: var(--lh-body);
  color: var(--text-primary);
}

.fd-scope-card__list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.45em;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--blue-500);
}

.fd-steps--compact {
  grid-template-columns: 1fr;
  gap: var(--space-3);
}

@media (min-width: 768px) {
  .fd-steps--compact {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

.fd-scope__note {
  margin-top: var(--space-5);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  color: var(--text-on-dark);
}

#umfang.fd-section--deep-soft .fd-scope__note {
  color: var(--text-on-dark);
}

/* --- enquiry form — the layout Cleaning.jsx:54-149 used for the calculator --- */
.fd-form {
  display: flex;
  flex-direction: column;
  gap: 22px;                          /* Cleaning.jsx:66 — no space token at 22 */
}

/* A fieldset is the correct grouping element for a question-led step, but its
   UA border, padding and legend placement have to be reset first. */
.fd-form__step {
  display: flex;
  flex-direction: column;
  gap: 18px;                          /* Cleaning.jsx:96 */
  margin: 0;
  padding: 0;
  border: 0;
  min-width: 0;                       /* fieldsets ignore flex/grid shrink otherwise */
}

.fd-form__legend {
  float: none;                        /* legends are not flex items in every UA */
  width: 100%;
  padding: 0;
  margin: 0;
  font-size: var(--fs-h3);
  line-height: var(--lh-h3);
  letter-spacing: var(--ls-h3);
  font-weight: var(--fw-semibold);
  color: var(--text-primary);
}

.fd-form__grid {
  display: grid;
  grid-template-columns: 1fr 1fr;     /* Cleaning.jsx:95 */
  gap: 18px;                          /* Cleaning.jsx:96 */
}

/* Cleaning.jsx:134 — checkbox rows stack tight; each row already carries its
   own 44px minimum from .fd-check. */
.fd-checks {
  display: grid;
  gap: 2px;
}

.fd-form__actions {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

/* FDN-FE-025 — one centred enquiry column keeps the form and its prepared
   WhatsApp message together without the empty second column. */
.fd-enquiry {
  max-width: var(--container-narrow);
  margin-inline: auto;
}

.fd-wa-disclosure {
  border: var(--border-w) solid var(--border-cool);
  border-radius: var(--radius-card);
}

.fd-wa-disclosure__toggle {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-height: var(--touch-min);
  padding: var(--space-2) var(--space-3);
  color: var(--text-primary);
  cursor: pointer;
  font-size: var(--fs-small);
  font-weight: var(--fw-semibold);
}

.fd-wa-disclosure__toggle:focus-visible {
  border-radius: var(--radius-card);
  box-shadow: var(--focus-ring);
  outline: none;
}

.fd-wa-disclosure__toggle::marker {
  color: var(--blue-500);
}

.fd-wa-disclosure .fd-wa {
  margin: 0 var(--space-3) var(--space-3);
}

.fd-form__status[hidden] {
  display: none;
}

/* Cleaning.jsx:152-155 — the summary column follows the form down the page. */
.fd-aside {
  position: sticky;
  top: 96px;
}

@media (max-width: 991.98px) {
  .fd-services--3 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .fd-scope-cards { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .fd-scope-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .fd-scope-grid--3 > .fd-scope-card:last-child:nth-child(odd) { grid-column: 1 / -1; }

  /* Cleaning.jsx:154 — `position: mobile ? "static" : "sticky"` */
  .fd-aside {
    position: static;
    top: auto;
  }
}

@media (max-width: 767.98px) {
  .fd-services--3 {
    grid-template-columns: 1fr;
  }

  .fd-form__grid {
    grid-template-columns: 1fr;       /* Cleaning.jsx:95 mobile */
  }

  /* FDN-FE-084 — compact home-service stack while retaining full photo frames. */
  .fd-services--home {
    gap: var(--space-5);
  }

  .fd-services--home .fd-service--photo .fd-service__image {
    width: calc(100% - var(--space-6));
    margin-inline: auto;
    object-fit: contain;
  }

  .fd-services--home .fd-service__plate {
    padding-block: var(--space-3);
  }
}

@media (max-width: 575px) {
  .fd-scope-cards { grid-template-columns: 1fr; }
  .fd-scope-grid { grid-template-columns: 1fr; }
}

/* FDN-FE-008 — Home service visuals replace the generic ultra-wide image. */
.fd-service--photo {
  position: relative;
  display: block;
  min-height: var(--touch-min);
  padding: 0;
  overflow: hidden;
  color: var(--white);
  border: var(--border-w) solid var(--border-cool);
  border-radius: var(--radius-card);
  background: var(--navy-900);
  box-shadow: none;
}

.fd-service--photo:hover,
.fd-service--photo:focus-visible {
  transform: none;
  border-color: var(--border-focus);
  box-shadow: var(--shadow-lift);
}

.fd-services--home .fd-service__image {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 5 / 5;
  object-fit: cover;
}

.fd-service__plate {
  display: grid;
  gap: var(--space-2);
  padding: var(--space-4);
}

.fd-service__plate.fd-glass {
  position: relative;
  isolation: isolate;
  background: color-mix(in srgb, var(--sky-200) 48%, transparent);
}

.fd-service__plate.fd-glass::before {
  position: absolute;
  z-index: 0;
  inset: 0;
  pointer-events: none;
  content: "";
  opacity: .58;
  background: var(--grad-deep-soft);
}

.fd-service__plate.fd-glass > * {
  position: relative;
  z-index: 1;
}

.fd-service--photo .fd-service__title { color: var(--sky-100); }
.fd-service--photo .fd-service__details { display: grid; gap: var(--space-2); }
.fd-service--photo .fd-service__text,
.fd-service--photo .fd-service__disclaimer { color: var(--sky-200); }
.fd-service--photo .fd-service__action { color: var(--white); }
.fd-service--photo .fd-service__disclaimer { font-size: var(--fs-small); line-height: var(--lh-small); }

@supports not (backdrop-filter: blur(1px)) {
  .fd-service__plate.fd-glass { background: var(--grad-deep-soft); }

  .fd-service__plate.fd-glass::before { display: none; }
}

@media (hover: hover) and (pointer: fine) {
  .fd-service--photo .fd-service__plate { position: absolute; right: 0; bottom: 0; left: 0; }
  .fd-service--photo .fd-service__details { display: none; }
  .fd-service--photo:hover .fd-service__details,
  .fd-service--photo:focus-within .fd-service__details { display: grid; }
  .fd-service--photo:hover .fd-service__title,
  .fd-service--photo:focus-within .fd-service__title { font-size: var(--fs-h2); }
}

.fd-cta__paths {
  flex: 1 1 100%;
}

.fd-cta__paths .fd-paths {
  margin-top: 0;
}

/* FDN-FE-004 — Contact page: composed from the settled card and field system. */
.fd-contact-facts { display: grid; gap: var(--space-3); padding: var(--space-6); color: var(--white); border: var(--border-w) solid var(--sky-300); border-radius: var(--radius-shell); background: rgba(16, 35, 58, .14); }
.fd-contact-fact { display: flex; align-items: center; gap: var(--space-3); min-height: var(--touch-min); }
.fd-contact-fact .fd-icon { color: var(--white); }
.fd-contact-fact a { color: var(--white); }
.fd-contact-fact a:hover { color: var(--white); text-decoration: underline; text-underline-offset: 3px; }
.fd-contact-channels { display: grid; gap: var(--space-2); margin-top: var(--space-5); }
.fd-contact-channel { display: inline-flex; align-items: center; gap: var(--space-3); min-height: var(--touch-min); color: var(--white); font-weight: var(--fw-semibold); text-decoration: none; }
.fd-contact-channel { padding: 0 var(--space-3); border: var(--border-w) solid var(--sky-300); border-radius: var(--radius-control); background: rgba(16, 35, 58, .35); }
.fd-contact-channel:hover { color: var(--white); text-decoration: underline; text-underline-offset: 3px; }
.fd-footer__contact-link { gap: var(--space-3); color: var(--text-on-dark); font-weight: var(--fw-semibold); }
.fd-footer__contact-link:hover { color: var(--white); }
.fd-contact-map { margin-top: var(--space-5); border-radius: var(--radius-card); overflow: hidden; }
.fd-contact-map__iframe { display: block; width: 100%; height: 400px; border: 0; border-radius: var(--radius-card); }
.fd-contact-form { display: flex; flex-direction: column; gap: var(--space-5); }
@media (max-width: 767.98px) { .fd-contact-facts { padding: var(--space-5); } .fd-contact-map__iframe { height: 280px; } }

/* FDN-FE-039 — About page: compact, evenly spaced fact badges. */
.fd-about-facts {
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-3);
}

.fd-about-facts .fd-fact {
  gap: var(--space-2);
  padding: var(--space-3);
  text-align: left;
}

.fd-about-facts .fd-icon-badge {
  width: 48px;
  height: 48px;
}

.fd-about-facts .fd-icon-badge .fd-icon {
  width: 24px;
  height: 24px;
}

.fd-about-facts .fd-fact__value {
  font-size: var(--fs-h3);
  line-height: var(--lh-h3);
  letter-spacing: var(--ls-h3);
}

.fd-about-facts .fd-fact__label {
  font-size: var(--fs-label);
  line-height: var(--lh-label);
}

.fd-about-facts .fd-fact__note {
  display: none;
}

.fd-about-services { margin-top: var(--space-6); }
.fd-about-story-row { align-items: stretch; }
.fd-about-story__content, .fd-about-story__photo { height: 100%; }
.fd-about-story__content { display: flex; flex-direction: column; justify-content: space-between; gap: var(--space-6); }
.fd-about-story__detail { margin-top: var(--space-4); }
.fd-about-story__photo .fd-photo__frame { height: 100%; aspect-ratio: auto; }
@media (max-width: 991.98px) { .fd-about-story__photo .fd-photo__frame { min-height: 280px; } }
@media (max-width: 767.98px) {
  .fd-about-facts { gap: var(--space-2); }
  .fd-about-facts .fd-fact { padding: var(--space-2); }
  .fd-about-facts .fd-fact__value { font-size: var(--fs-small); }
  .fd-about-facts .fd-fact__label { font-size: var(--fs-label); }
}

/* FDN-FE-029 — Footer service-area line. ------------------------------------ */
.fd-footer__service-area {
  font-size: var(--fs-label);
  color: var(--sky-300);
  margin-top: var(--space-2);
}

/* FDN-FE-056 — Not found page. -------------------------------------------- */
.fd-not-found {
  align-items: center;
  background: var(--grad-wash);
  display: flex;
  min-height: calc(100vh - var(--header-h));
  padding: var(--section-y) var(--gutter);
  text-align: center;
}

.fd-not-found__inner { margin: 0 auto; max-width: var(--container-narrow); }
.fd-not-found__code { color: var(--blue-600); font-size: var(--fs-label); font-weight: var(--fw-bold); letter-spacing: var(--ls-label); margin-bottom: var(--space-3); }
.fd-not-found__title { margin-bottom: var(--space-4); }
.fd-not-found__copy { margin: 0 auto var(--space-6); max-width: 38rem; }
.fd-not-found__actions { display: flex; flex-wrap: wrap; gap: var(--space-3); justify-content: center; }

/* FDN-FE-057 — legal pages. */
.fd-legal { max-width: var(--container-narrow); }
.fd-legal h1 { margin-bottom: var(--space-6); }
.fd-legal section { margin-top: var(--space-6); }
.fd-legal h2 { margin-bottom: var(--space-3); }
.fd-legal p { max-width: 72ch; }
.fd-legal__lead { font-size: var(--fs-body); line-height: var(--lh-body); }
.fd-footer__legal-links { display: flex; flex-wrap: wrap; gap: var(--space-3); }
.fd-footer__legal-links a { color: var(--text-on-dark); min-height: var(--touch-min); display: inline-flex; align-items: center; }
.fd-footer__legal-links a:hover { color: var(--white); }
.fd-footer__legal-links a:focus-visible { border-radius: var(--radius-control); box-shadow: var(--focus-ring); outline: none; }

/* FDN-SEO-009 — Ratgeber / Guides ---------------------------------------- */
.fd-guide { max-width: 46rem; margin: 0 auto; padding: var(--section-y) var(--gutter); }
.fd-guide__breadcrumb { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-bottom: var(--space-5); font-size: var(--fs-small); }
.fd-guide__breadcrumb a { color: var(--blue-700); }
.fd-guide__lead { font-size: var(--fs-lead); line-height: var(--lh-lead); }
.fd-guide h1 { margin-bottom: var(--space-5); }
.fd-guide h2 { margin-top: var(--space-8); margin-bottom: var(--space-3); font-size: var(--fs-h3); }
.fd-guide p, .fd-guide li { line-height: var(--lh-body); }
.fd-guide ul { padding-left: var(--space-5); }
.fd-guide__cta { margin-top: var(--space-8); padding: var(--space-5); border-radius: var(--radius-card); background: var(--surface-band); }
.fd-guide-index { max-width: var(--container-max); margin: 0 auto; padding: var(--section-y) var(--gutter); }
.fd-guide-index__grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-4); margin-top: var(--space-6); }
.fd-guide-index__card { display: grid; gap: var(--space-3); padding: var(--space-5); border: var(--border-w) solid var(--border-cool); border-radius: var(--radius-card); background: var(--surface-raised); }
.fd-guide-index__card a { color: var(--blue-700); font-weight: var(--fw-semibold); }
/* Card headings follow the site-wide card convention (--fs-h3), like
   .fd-service__title and .fd-path__title. Left bare, an <h2> renders at 34px
   inside a ~373px column and wraps to five lines. */
.fd-guide-index__card h2 { font-size: var(--fs-h3); line-height: var(--lh-h3); letter-spacing: var(--ls-h3); font-weight: var(--fw-semibold); color: var(--text-primary); margin: 0; }
.fd-guide-index__lead { font-size: var(--fs-lead); line-height: var(--lh-lead); color: var(--text-muted); }
@media (max-width: 767.98px) { .fd-guide { padding: var(--section-y-mobile) var(--gutter-mobile); } .fd-guide-index { padding: var(--section-y-mobile) var(--gutter-mobile); } .fd-guide-index__grid { grid-template-columns: 1fr; } .fd-guide-index__card h2 { font-size: var(--fs-h3); } }

@media (max-width: 820px) {
  .fd-not-found { min-height: calc(100vh - var(--header-h-mobile)); padding: var(--section-y-mobile) var(--gutter-mobile); }
  .fd-not-found__actions { display: grid; }
  .fd-footer__legal-inner { gap: var(--space-3); }
}

/* FDN-FE-058 — Cookie consent bottom sheet. */
.fd-consent[hidden] { display: none; }
.fd-consent { bottom: 0; left: 0; padding: var(--space-4); position: fixed; right: 0; z-index: 1100; }
body.fd-consent-open { padding-bottom: calc(var(--section-y) + var(--space-10)); }
.fd-consent__panel { background: var(--surface-raised); border: var(--border-w) solid var(--border-sky); border-radius: var(--radius-shell); box-shadow: var(--shadow-lift); display: grid; gap: var(--space-3); margin: 0 auto; max-width: var(--container-max); padding: var(--space-4); }
.fd-consent__content { display: grid; gap: var(--space-2); }
.fd-consent__title { font-size: var(--fs-h3); }
.fd-consent__intro { max-width: 72ch; }
.fd-consent__utility { align-items: center; display: flex; flex-wrap: wrap; gap: var(--space-3); }
.fd-consent__details summary { align-items: center; color: var(--blue-700); cursor: pointer; display: inline-flex; font-weight: var(--fw-semibold); min-height: var(--touch-min); }
.fd-consent__details summary:focus-visible { border-radius: var(--radius-control); box-shadow: var(--focus-ring); outline: none; }
.fd-consent__categories { display: grid; gap: var(--space-3); margin: 0; }
.fd-consent__details[open] .fd-consent__categories { margin-top: var(--space-3); }
.fd-consent__categories div { background: var(--surface-band); border-radius: var(--radius-control); padding: var(--space-3); }
.fd-consent__categories dt { color: var(--text-primary); font-weight: var(--fw-semibold); }
.fd-consent__categories dd { margin: var(--space-1) 0 0; }
.fd-consent__links { display: flex; flex-wrap: wrap; gap: var(--space-3); }
.fd-consent__privacy { align-items: center; display: inline-flex; font-weight: var(--fw-semibold); min-height: var(--touch-min); }
.fd-consent__actions { display: grid; gap: var(--space-3); grid-template-columns: repeat(2, minmax(0, 1fr)); }
.fd-consent__action { justify-content: center; min-height: var(--touch-min); }

.fd-whatsapp-float {
  align-items: center;
  background: var(--grad-red);
  border: 0;
  border-radius: 50%;
  bottom: var(--space-4);
  box-shadow: var(--shadow-lift);
  color: var(--text-on-red);
  display: inline-flex;
  height: var(--touch-min);
  justify-content: center;
  position: fixed;
  right: var(--space-4);
  width: var(--touch-min);
  z-index: 1090;
}

.fd-whatsapp-float:hover {
  background: var(--grad-red-hover);
  color: var(--text-on-red);
  transform: translateY(-1px);
}

.fd-whatsapp-float:focus-visible {
  box-shadow: var(--focus-ring), var(--shadow-lift);
  outline: none;
}

body.fd-consent-open .fd-whatsapp-float {
  display: none;
}

.fd-footer__cookie-settings { background: none; border: 0; color: var(--text-on-dark); cursor: pointer; font-size: inherit; min-height: var(--touch-min); padding: 0; text-align: left; }
.fd-footer__cookie-settings:hover { color: var(--white); text-decoration: underline; text-underline-offset: 3px; }
.fd-footer__cookie-settings:focus-visible { border-radius: var(--radius-control); box-shadow: var(--focus-ring); outline: none; }
@media (max-width: 820px) {
  .fd-consent { padding: var(--space-1); }
  body.fd-consent-open { padding-bottom: calc(var(--section-y-mobile) + var(--space-10)); }
  .fd-consent__panel { gap: 0; padding: var(--space-1); }
  .fd-consent__content { gap: var(--space-1); }
  .fd-consent__title { font-size: var(--fs-body); }
  .fd-consent__intro { line-height: var(--lh-label); }
  .fd-consent__utility { gap: var(--space-1); }
  .fd-consent__categories { gap: var(--space-2); }
  .fd-consent__actions { gap: var(--space-1); }
}


/* FDN-FE-086 — card accents stay structurally present, so the red hover
   stripe never changes a card's dimensions. The token palette has no
   --red-500; --red-600 is the approved Swiss-red accent. */
.fd-card,
.fd-radiocard,
.fd-pricing-card,
.fd-benefit,
.fd-service:not(.fd-service--photo),
.fd-path,
#facts .fd-fact,
.fd-about-facts .fd-fact,
.fd-step-card {
  border-left: 4px solid transparent;
  transition: border-color 0.2s, box-shadow 0.2s, transform var(--dur-base) var(--ease-standard);
}

.fd-card:hover,
.fd-card:focus-within,
.fd-radiocard:hover,
.fd-radiocard:has(.fd-radiocard__input:focus-visible),
.fd-pricing-card:hover,
.fd-benefit:hover,
.fd-benefit:focus-within,
.fd-service:not(.fd-service--photo):hover,
.fd-service:not(.fd-service--photo):focus-visible,
.fd-path:hover,
.fd-path:focus-visible,
#facts .fd-fact:hover,
#facts .fd-fact:focus-within,
.fd-about-facts .fd-fact:hover,
.fd-about-facts .fd-fact:focus-within,
.fd-step-card:hover,
.fd-step-card:focus-within {
  border-left-color: var(--red-600);
  box-shadow: var(--shadow-lift);
}

/* Every affected icon starts on a pale blue ground and fills red with a white
   glyph when its parent card is active. */
.fd-card .fd-icon-badge,
.fd-benefit .fd-icon-badge,
.fd-step-card .fd-icon-badge,
.fd-service:not(.fd-service--photo) .fd-service__badge,
.fd-path .fd-path__badge {
  background: var(--sky-100);
  color: var(--blue-600);
  transition: background-color 0.2s, color 0.2s;
}

.fd-card .fd-icon-badge .fd-icon,
.fd-benefit .fd-icon-badge .fd-icon,
.fd-step-card .fd-icon-badge .fd-icon,
.fd-service:not(.fd-service--photo) .fd-service__badge .fd-icon,
.fd-path .fd-path__badge .fd-icon {
  color: currentColor;
  transition: color 0.2s;
}

.fd-card:hover .fd-icon-badge,
.fd-card:focus-within .fd-icon-badge,
.fd-benefit:hover .fd-icon-badge,
.fd-benefit:focus-within .fd-icon-badge,
.fd-step-card:hover .fd-icon-badge,
.fd-step-card:focus-within .fd-icon-badge,
.fd-service:not(.fd-service--photo):hover .fd-service__badge,
.fd-service:not(.fd-service--photo):focus-visible .fd-service__badge,
.fd-path:hover .fd-path__badge,
.fd-path:focus-visible .fd-path__badge {
  background: var(--red-600);
  color: var(--white);
}

/* --- FDN-FE-096: light surfaces inside dark sections ---------------------- */
/* The dark-section rules above (`.fd-section--deep p`, `… h3`, and siblings)
   are DESCENDANT selectors, so they also repaint text that sits inside a white
   card nested in that section. Nothing reset it, so any light surface dropped
   into a dark section rendered near-invisible text on its own background.

   FDN-FE-093 shipped exactly that: the Umzugspaket cards on index.html and
   reinigung.html sit in `.fd-section--deep-soft`, and their titles rendered
   white-on-white at a contrast ratio of 1.0. The enquiry form's hints did the
   same at 1.09 inside `.fd-card--white`.

   Every light surface therefore restores its own typography. `:is()` takes the
   highest specificity among its arguments, so these land at (0,3,0) and beat
   the (0,1,1) section rules without `!important`. */
   `.fd-glass` is excluded throughout: a glass card is translucent, so it is not
   a light surface — it already carries its own tone rules for both grounds. */
:is(.fd-section--hero, .fd-section--deep-soft, .fd-section--navy, .fd-section--deep)
:is(.fd-card--white, .fd-service:not(.fd-service--photo), .fd-benefit,
    .fd-pricing-card, .fd-step-card, .fd-radiocard):not(.fd-glass) {
  color: var(--text-body);
}

:is(.fd-section--hero, .fd-section--deep-soft, .fd-section--navy, .fd-section--deep)
:is(.fd-card--white, .fd-service:not(.fd-service--photo), .fd-benefit,
    .fd-pricing-card, .fd-step-card, .fd-radiocard):not(.fd-glass)
:is(h1, h2, h3, h4, .fd-service__title, .fd-benefit__title, .fd-card__title) {
  color: var(--text-primary);
}

:is(.fd-section--hero, .fd-section--deep-soft, .fd-section--navy, .fd-section--deep)
:is(.fd-card--white, .fd-service:not(.fd-service--photo), .fd-benefit,
    .fd-pricing-card, .fd-step-card, .fd-radiocard):not(.fd-glass)
:is(p, li, span, label, .fd-service__text, .fd-benefit__text) {
  color: var(--text-body);
}

:is(.fd-section--hero, .fd-section--deep-soft, .fd-section--navy, .fd-section--deep)
:is(.fd-card--white, .fd-service:not(.fd-service--photo), .fd-benefit,
    .fd-pricing-card, .fd-step-card, .fd-radiocard):not(.fd-glass)
:is(.fd-field__hint, .fd-form__note, small) {
  color: var(--text-muted);
}

/* Glass over the deep-soft ramp: the card is 62% opaque, so at the ramp's dark
   end the effective ground is rgb(163,195,223) and `--text-body` lands at 3.98
   — under AA. `--navy-700` clears it on the whole ramp. */
.fd-section--deep-soft .fd-step-card.fd-glass .fd-steps__text {
  color: var(--navy-700);
}

/* Button labels take the button's own colour, never the surrounding card's
   body tone — without this the reset above greyed out the label on the red
   CTA inside a white card (contrast 1.59). */
:is(.fd-section--hero, .fd-section--deep-soft, .fd-section--navy, .fd-section--deep)
:is(.fd-card--white, .fd-service:not(.fd-service--photo), .fd-benefit,
    .fd-pricing-card, .fd-step-card, .fd-radiocard):not(.fd-glass)
.fd-btn * {
  color: inherit;
}

/* The scope note sits at roughly 69% along the `--grad-deep-soft` ramp, where
   the ground is #4E99D3. White reaches only 3.08 there and `--text-link` 3.52,
   so the link takes the navy tone (5.15) and carries an underline for the
   affordance the colour no longer signals. */
.fd-scope__note a {
  color: var(--text-primary);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.fd-scope__note a:hover,
.fd-scope__note a:focus-visible {
  color: var(--navy-700);
}

/* `--sky-300` on the navy footer and on deep eyebrows measures 3.82. `--sky-200`
   clears AA at 5.39 and stays quieter than white, which is what these
   secondary lines are for. */
.fd-footer__tagline,
.fd-footer__service-area,
.fd-eyebrow--on-deep {
  color: var(--sky-200);
}

/* `--glass-bg` is `--sky-100` at 62% — a LIGHT pane. Over a dark section it
   lifts the ground to roughly rgb(162,196,225), where white text measures 1.83
   and `--text-on-dark` 1.69. Glass on a dark ground therefore carries dark
   typography, which is the resolution `.fd-section--deep-soft
   .fd-step-card.fd-glass` already arrived at; this generalises it so the facts
   band stops being the exception. */
:is(.fd-section--hero, .fd-section--deep-soft, .fd-section--navy, .fd-section--deep)
.fd-glass {
  color: var(--text-body);
}

:is(.fd-section--hero, .fd-section--deep-soft, .fd-section--navy, .fd-section--deep)
.fd-glass
:is(h1, h2, h3, h4, .fd-fact__value, .fd-steps__title, .fd-service__title) {
  color: var(--text-primary);
}

:is(.fd-section--hero, .fd-section--deep-soft, .fd-section--navy, .fd-section--deep)
.fd-glass
:is(p, span, li, .fd-fact__label, .fd-steps__text, .fd-service__text) {
  color: var(--text-body);
}

:is(.fd-section--hero, .fd-section--deep-soft, .fd-section--navy, .fd-section--deep)
.fd-glass
:is(.fd-fact__note, .fd-field__hint, small) {
  color: var(--text-muted);
}

/* The facts band is glass over `--deep`, so its own on-dark rules (white value,
   `--text-on-dark` label, white-at-72% note) all land on a pale ground and
   measure 1.7–1.8. Spelled out explicitly rather than left to the generic
   glass reset, because `--text-muted` is still too light on this pane. */
.fd-section--deep .fd-fact.fd-glass .fd-fact__value,
.fd-section--navy .fd-fact.fd-glass .fd-fact__value {
  color: var(--text-primary);
}

.fd-section--deep .fd-fact.fd-glass .fd-fact__label,
.fd-section--navy .fd-fact.fd-glass .fd-fact__label {
  color: var(--text-primary);
}

.fd-section--deep .fd-fact.fd-glass .fd-fact__note,
.fd-section--navy .fd-fact.fd-glass .fd-fact__note {
  color: var(--text-body);
}

/* `#facts .fd-fact__note` carries ID specificity, so the glass reset above
   never reached it — the note stayed at white-72% on a pale pane (1.67). */
#facts .fd-fact.fd-glass .fd-fact__note,
.fd-about-facts .fd-fact.fd-glass .fd-fact__note {
  color: var(--text-body);
}

#facts .fd-fact.fd-glass .fd-fact__label,
.fd-about-facts .fd-fact.fd-glass .fd-fact__label {
  color: var(--text-primary);
}

/* The legal strip sat at `--sky-300` on the navy footer (2.92). */
.fd-footer__legal-inner {
  color: var(--sky-200);
}

/* Card titles wrap around the floated icon badge (FDN-FE-085), which in a
   four-column card left a one-word last line — "Schriftlich / festgelegter /
   Umfang". Balancing evens the line lengths and usually saves a line. */
.fd-benefit__title,
.fd-service__title,
.fd-steps__title,
.fd-path__title,
.fd-card__title {
  text-wrap: balance;
}
