/*
Theme Name: EssenzNatur
Theme URI: https://essenznatur.de
Description: B2B theme for EssenzNatur GmbH — CO2 botanical extracts. Child of Hello Elementor. Sections are available as Gutenberg block patterns and as shortcodes for Elementor.
Author: EssenzNatur
Version: 1.2.0
Template: hello-elementor
Text Domain: essenznatur
Requires at least: 6.5
Tested up to: 7.0
License: GPL-2.0-or-later
*/

/* Fonts are self-hosted and enqueued separately from
   assets/fonts/fonts.css — regenerate with: bash assets/fonts/fetch-fonts.sh */

/* ==========================================================================
   Tokens
   ========================================================================== */
:root{
  /* --- Colour ------------------------------------------------------------
     The client's mandated palette (Designer Brief §9 "Color Palette
     (Complete)" and the Quick Reference card). It replaces the sage system
     wholesale: --sage was #516E4F and is now the Brief's primary #2c5f2d,
     --sage-2 was #6B8A67 and is now the Brief's secondary #4a7c4e. The token
     NAMES are kept because ~600 declarations across six sheets reference
     them; renaming them would be churn without meaning.

     Every ratio below is computed, not estimated — see D1.md for the table.

     One rule governs the secondary green: #4a7c4e measures 4.90:1 on white
     but only 4.4960:1 on --band and 4.36:1 on --mist, so it fails AA for
     normal-size copy on two of the four light grounds this site actually
     uses. It is therefore reserved for borders, rules, icon accents, hover
     states and decoration, and never carries small text. Headings — H3
     included — take the primary. */
  --sage:#2c5f2d;          /* Brief: Primary Green   */
  --sage-2:#4a7c4e;        /* Brief: Secondary Green */
  --mist:#e8f5e9;          /* Brief: Light Green — highlight boxes, accents */
  --ink:#333;              /* Brief: Dark Gray — body text */
  --muted:#666;            /* Brief: Medium Gray — secondary text */
  --band:#f5f5f5;          /* Brief: Light Gray — section backgrounds */
  --card:#f9f9f9;          /* Brief §9 component spec: card background */
  --line:#ccc;             /* Brief: form-field border */
  --line-2:#ddd;           /* Brief: card border, hairline rules */
  --paper:#fff; --white:#fff;

  /* Dark grounds. The Brief names no dark ground, but the site has run one
     since round 1 (.sec--dark, footer, CTA band, hero panel) and removing it
     is not a palette decision. --deep is the Brief's own button-hover
     #1e4620, so the dark band is a mandated colour rather than an invented
     one; the tints on it are derived and are declared additions. */
  --deep:#1e4620;          /* Brief §9: button hover, reused as dark ground */
  --deeper:#143017;        /* draft/review bar — one step below --deep      */
  --deep-2:#265829;        /* raised panel on a dark band                   */
  --on-deep:#e8f5e9;       /* 9.56:1 on --deep — primary text on dark       */
  --on-deep-2:#bcd6be;     /* 6.92:1 — lede, footer body, secondary on dark */
  --on-deep-3:#9ab89d;     /* 4.98:1 — labels and eyebrows on dark          */
  --on-primary:#e8f5e9;    /* 6.71:1 on --sage — dim text on the green      */
  --line-on-deep:rgba(232,245,233,.16);   /* decorative rule on dark        */
  --line-on-deep-2:#75997a;               /* 3.38:1 — UI boundary on dark   */

  /* Semantic pair. The Brief mandates #f44336 / #4caf50, and both are
     *fill* colours: #f44336 is 3.68:1 on white (fine as a 2px border,
     under the 4.5:1 floor as text) and #4caf50 is 2.78:1 on white (under
     even the 3:1 graphics floor). The mandated values are kept verbatim for
     borders and marks; the two darkened text variants below are the same
     hues at AA and exist only so an error message can be read. */
  --err:#f44336;           /* Brief: Error Red — borders, marks   */
  --err-text:#c62828;      /* 5.62:1 white / 5.00:1 --mist        */
  --err-bg:#fdecea;
  --ok:#4caf50;            /* Brief: Success Green — marks on dark */
  --ok-text:#2e7d32;       /* 5.13:1 white / 4.56:1 --mist         */

  /* Provisional. A DOCUMENTED ADDITION to the Brief's eight colours, not a
     deviation from them. The Brief's only semantic pair is error/success — a
     binary — and the evidence grammar needs a third, neutral state for a
     claim that is neither confirmed nor wrong. Rendering "pending" in the
     mandated red reads as broken; in --muted grey it disappears into body
     copy.

     The value is #865A20, one step down from the #8F6124 the previous wave
     landed on. #8F6124 clears AA on the four light grounds as a bare colour
     (5.38 / 4.93 / 5.11 / 4.78) but the chip paints its own --amber-bg tint
     underneath itself, and measured on THAT composite it falls to 4.40:1 on
     --band and 4.27:1 on --mist. #865A20 is the same hue and clears 4.5 on
     every ground and every tinted composite, worst case 4.74:1 (--mist,
     tinted). Requires client sign-off as a ninth colour. */
  --amber:#865A20;
  --amber-on-dark:#E0B478; /* 5.62:1 on --deep, 7.49:1 on --deeper */
  --amber-bg:rgba(134,90,32,.09);
  --amber-bd:rgba(134,90,32,.28);
  --amber-bg-dark:rgba(224,180,120,.10);
  --amber-bd-dark:rgba(224,180,120,.30);

  /* Focus ring. The primary green clears the 3:1 graphics floor on all four
     light grounds (7.55 / 6.92 / 7.17 / 6.71) but measures 1.43:1 on --deep,
     so dark grounds keep their own ring at 5.65:1. */
  --focus:var(--sage);
  --focus-on-dark:#a4c4a6;

  /* --- Type ---------------------------------------------------------------
     Brief §9: Inter / Segoe UI throughout. Archivo (display) and IBM Plex
     Mono (data) are retired; --data is kept as an alias rather than deleted
     because ~110 declarations reference it, and the uppercase-tracked label
     it drives is a layout role, not a typeface choice.

     Font stack, and why it is in this order. assets/fonts/fonts.css is NOT
     owned by this task and self-hosts three families: Archivo, IBM Plex Mono
     and — registered under the family name 'Inter Tight' — Inter Tight, which
     is Inter's condensed sibling, not Inter. So the Brief's "Inter" was never
     resolving to a self-hosted file even before this change; it fell through
     to Segoe UI. The stack therefore states the Brief's pair first (Inter,
     then Segoe UI — both of which ship a real 700) and keeps the self-hosted
     'Inter Tight' behind them as a guaranteed fallback for machines that have
     neither. No external request is added, and no new file is fetched:
     Archivo and Plex are simply no longer referenced by anything, so they
     stop downloading.

     Sizes are the Brief's own em values, expressed in rem so they compute to
     exactly 2.5em / 2em / 1.3em / 1em / 0.85em of the 16px root. Nothing
     resolves below 12px on any screen. */
  --display:Inter,'Segoe UI','Inter Tight',system-ui,-apple-system,sans-serif;
  --body:Inter,'Segoe UI','Inter Tight',system-ui,-apple-system,sans-serif;
  --data:Inter,'Segoe UI','Inter Tight',system-ui,-apple-system,sans-serif;

  --fs-display:2.5rem;  /* 40px — Brief H1; the hero shares the H1 size    */
  --fs-h1:2.5rem;       /* 40px — Brief §9 H1                             */
  --fs-h2:2rem;         /* 32px — Brief §9 H2                             */
  --fs-h3:1.3rem;       /* 20.8px — Brief §9 H3                           */
  --fs-lede:1.15rem;    /* 18.4px — not in the Brief; retained intermediate */
  --fs-body:1rem;       /* 16px — Brief §9 body                           */
  --fs-small:.85rem;    /* 13.6px — Brief §9 small text                   */
  --fs-micro:.75rem;    /* 12px — the floor, unchanged                    */

  /* Brief §9: H1/H2 700, H3 600, body 400, CTA 700. --fw-heading is the 700
     the Brief mandates; --fw-sub is the 600 it gives H3 and subheads. */
  --fw-heading:700; --fw-sub:600; --fw-body:400; --fw-micro:500;

  /* Brief §9 line heights: H1 1.3, H2 1.3, H3 1.4, body 1.7, small 1.5.
     §2 says "1.4 for headings" — resolved in favour of §9, see D1.md. */
  --lh-display:1.3; --lh-h:1.3;  --lh-h3:1.4;  --lh-lede:1.5;
  --lh-body:1.7;    --lh-small:1.5; --lh-micro:1.4;

  --ls-micro:.12em; --ls-display:-.02em;
  /* The CTA is 16px uppercase now, not 12px; .12em is too open at that size. */
  --ls-btn:.04em;

  /* --- Spacing ------------------------------------------------------------
     4px base, unchanged. The Brief's own figures (1200 / 40 / 20 / 60 / 30 /
     12 / 10) are all multiples of 4 but not all of them are existing steps,
     so the Brief's numbers are stated literally where they are specified and
     the scale carries everything the Brief does not mention. */
  --s-1:4px;  --s-2:8px;  --s-3:12px; --s-4:16px; --s-5:24px;
  --s-6:32px; --s-7:48px; --s-8:64px; --s-9:96px; --s-10:128px;

  --gap:20px;                 /* Brief §9: grid gap, 20px between items */

  /* Section rhythm. Brief §9 and the Quick Reference say 60px desktop /
     30px mobile; Brief §2 says 40/20. Resolved in favour of 60/30 — see
     D1.md.

     The theme previously ran two rhythms (96px "tight" / 128px standard) and
     the homepage puts .sec--tight on most of its bands, so leaving --tight at
     §2's 40px would have rendered §2's figure on nearly every band while this
     file claimed to have chosen §9's. Picking one means picking one: both
     rhythms resolve to the Brief's single figure, which is also what §9 asks
     for ("Between sections: natural — no extra margin, padding handles it").
     --sec-y-tight is kept as an alias so no template has to change. */
  --sec-y:60px;               /* Brief §9 desktop section padding */
  --sec-y-tight:var(--sec-y);
  --hero-y-top:var(--sec-y);
  --hero-y-bot:var(--sec-y);

  /* --- Form ---------------------------------------------------------------
     Brief §9 component specs: 4px radius on buttons, fields, cards and the
     highlight box. */
  --radius:4px; --radius-full:50%;

  --maxw:1200px;              /* Brief §9: container max-width */
  --rail:40px;                /* Brief §9: container padding, desktop */
}

/* ==========================================================================
   Parent-theme reset — neutralised, not edited.

   hello-elementor/assets/css/reset.css is not a reset. It ships opinionated
   defaults that this theme never asked for, and it is the single root cause
   of three separate defects measured on the live site:

     1. button:hover,button:focus{background-color:#c36} — the burger renders
        #cc3366 on every page below 1025px, and every <button> the theme does
        not explicitly colour flashes hot magenta on hover AND on keyboard
        focus. Confirmed: .burger computed color:rgb(204,51,102).
     2. table td,table th{border:1px solid hsla(0,0%,50%,.502)} plus
        tbody tr:nth-child(odd) zebra. That grey is the entire "spreadsheet"
        impression, and it lands on .dtable and .pdp-table — the theme's own
        signature tables — not merely on unstyled ones.
     3. [type=submit],button{border-radius:3px} — .btn renders 0px as <a> and
        3px as <button>. Same class, two shapes, same page.

   The parent theme is not edited: it is a dependency, and an edit there is
   lost on update. Each block below matches the reset's own specificity so it
   overrides on order alone, which leaves every theme rule — all of which are
   more specific — still winning normally.
   ========================================================================== */

/* 1. Buttons. The reset's chrome goes; the theme's own button rules supply
      background, border and colour themselves, and are more specific. */
button,[type=button],[type=submit],[type=reset]{
  background-color:transparent;border:0;border-radius:0;color:inherit;
  font:inherit;text-align:inherit;padding:0;
  /* The reset also forces white-space:nowrap on every button. That is fine for
     a short CTA and wrong for anything that carries a sentence — it clipped
     three German FAQ questions inside .acc-q at 375px. Buttons wrap by
     default; .btn opts back in below, because a wrapped CTA looks broken. */
  white-space:normal;
}
button:hover,button:focus,
[type=button]:hover,[type=button]:focus,
[type=submit]:hover,[type=submit]:focus,
[type=reset]:hover,[type=reset]:focus{
  background-color:transparent;color:inherit;text-decoration:none;
}

/* 2. Tables. Horizontal rules only — no verticals, no zebra, no hover band.
      Column separation comes from alignment, not from lines. Components that
      want a rule declare their own; this only removes what was inherited. */
table{font-size:inherit;margin-block-end:0}
table td,table th{border:0;padding:var(--s-3) var(--s-4);line-height:var(--lh-small);vertical-align:top}
table tbody>tr:nth-child(odd)>td,table tbody>tr:nth-child(odd)>th,
table tbody tr:hover>td,table tbody tr:hover>th{background-color:transparent}
table caption+thead tr:first-child td,table caption+thead tr:first-child th,
table colgroup+thead tr:first-child td,table colgroup+thead tr:first-child th,
table thead:first-child tr:first-child td,table thead:first-child tr:first-child th{border-block-start:0}
table tbody+tbody{border-block-start:0}
/* A table inside running copy still needs to read as a table. Hairline
   --line under each row, and nothing else. */
.art table td,.art table th,.entry table td,.entry table th{
  border-bottom:1px solid var(--line-2);
}
.art table th,.entry table th{text-align:left;font-weight:var(--fw-heading)}

/* 3. Fields. #666 borders, 3px radii and #000 text were chosen by nobody —
      they are reset defaults reaching every input the theme does not cover. */
input[type=date],input[type=email],input[type=number],input[type=password],
input[type=search],input[type=tel],input[type=text],input[type=time],
input[type=url],select,textarea{
  border:1px solid var(--line);border-radius:var(--radius);color:var(--ink);
  padding:10px 12px;font-size:16px;min-height:44px;
}
input[type=date]:focus,input[type=email]:focus,input[type=number]:focus,
input[type=password]:focus,input[type=search]:focus,input[type=tel]:focus,
input[type=text]:focus,input[type=time]:focus,input[type=url]:focus,
select:focus,textarea:focus{
  border-color:var(--sage);
  /* Brief §9 field spec: "Focus: 2px solid #2c5f2d + light green shadow".
     Drawn as 1px border + 1px ring so the field does not reflow on focus. */
  box-shadow:0 0 0 1px var(--sage),0 0 0 4px rgba(44,95,45,.18);
}

/* 4. Headings and links. The reset sets h1–h6 to weight 500 and a{color:#c36};
      both are overridden below, but stating them here keeps any heading the
      theme does not reach on the type system rather than on the parent's. */
h1,h2,h3,h4,h5,h6{font-weight:var(--fw-heading);margin-block-start:0;margin-block-end:0}
a{color:inherit}
a:active,a:hover{color:inherit}

*{box-sizing:border-box}
html{scroll-behavior:smooth;scrollbar-gutter:stable}
body{margin:0;background:var(--paper);color:var(--ink);font-family:var(--body);
  font-size:var(--fs-body);line-height:var(--lh-body);-webkit-font-smoothing:antialiased}
img{max-width:100%;height:auto;display:block}
a{color:inherit}
button{font:inherit;cursor:pointer}
/* Dark grounds get their own ring: --sage on --deep measures 2.13:1. */
:focus-visible{outline:2px solid var(--focus);outline-offset:3px}
.sec--dark :focus-visible,footer.site :focus-visible,.hero--media :focus-visible,
.proc :focus-visible,.stat :focus-visible,
.sec--cta :focus-visible,.deliver :focus-visible{outline-color:var(--focus-on-dark)}
/* A control that is ITSELF the primary green needs a ring that reads against
   two adjacent colours, not one. The outline sits 3px off the control, so it
   lands on the page ground and clears 6.71–7.55:1 there; but measured against
   the control's own fill it is 1:1, and a keyboard user looking at the button
   sees nothing. The inset white ring supplies that second edge at 7.55:1.
   Ghost buttons are transparent, so they take the outline alone. */
.btn:focus-visible,.skip:focus,.skip:focus-visible,.chip input:focus-visible+span,
.lang a[aria-current="true"]:focus-visible,
.filters a[aria-current="page"]:focus-visible,
.sres-wrap .page-numbers.current:focus-visible,
.ensearch[open]>.ensearch-t:focus-visible,
.seg-card:focus-within .seg-btn{box-shadow:inset 0 0 0 2px var(--white)}
.btn--ghost:focus-visible{box-shadow:none}
/* The footer CTA inverts — white fill on the dark band — so its inner ring
   inverts too: --deep on white is 10.76:1. */
footer.site .footer-cta>.btn:focus-visible{box-shadow:inset 0 0 0 2px var(--deep)}
footer.site .footer-cta>.btn:hover:focus-visible,
footer.site .footer-cta>.btn:focus-visible:active{box-shadow:none}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important;scroll-behavior:auto!important}}

/* Skip link */
.skip{position:absolute;left:-9999px;top:0;z-index:200;background:var(--sage);color:#fff;
  padding:var(--s-3) var(--s-4);font-family:var(--data);font-size:var(--fs-micro);
  letter-spacing:var(--ls-micro);line-height:var(--lh-micro);text-transform:uppercase;
  min-height:44px;display:flex;align-items:center}
.skip:focus{left:var(--s-2);top:var(--s-2)}

.wrap{max-width:var(--maxw);margin:0 auto;padding:0 var(--rail)}
/* The uppercase mono label — one of two tracking devices on the site. */
.eyebrow{font-family:var(--data);font-size:var(--fs-micro);font-weight:var(--fw-micro);
  letter-spacing:var(--ls-micro);line-height:var(--lh-micro);text-transform:uppercase;
  color:var(--sage);margin:0 0 var(--s-3)}
/* Brief §9 typography table. Headings carry the primary green; body copy
   carries --ink. H3's mandated colour is the secondary green, which measures
   4.4960:1 on --band and 4.36:1 on --mist — below AA for 20.8px/600 text,
   which is not "large scale" under WCAG (that needs 24px, or 18.66px at 700).
   H3 therefore takes the primary green too. Documented in D1.md. */
/* overflow-wrap:break-word, not anywhere: it breaks a word only when that word
   cannot fit on a line by itself, so every heading that already fits is laid
   out identically. German compounds need it — "Vertriebspartnerschaften" in the
   /distributor/ H1 pushed the document to scrollWidth 345 against clientWidth
   320 with no element box exceeding the viewport, because the overflow was a
   text run inside a correctly-sized box. */
h1,h2,h3,h4{font-family:var(--display);font-weight:var(--fw-heading);
  letter-spacing:var(--ls-display);line-height:var(--lh-h);margin:0;color:var(--sage);
  overflow-wrap:break-word}
h1{font-size:var(--fs-h1);line-height:var(--lh-display)}
h2{font-size:var(--fs-h2)}
h3{font-size:var(--fs-h3);line-height:var(--lh-h3);font-weight:var(--fw-sub)}
h4{font-size:var(--fs-lede);line-height:var(--lh-h3);font-weight:var(--fw-sub)}
/* Headings inside a dark band, on the green itself, or inside running copy
   set on a card do not take the green: it is unreadable on --deep (1.43:1)
   and on --sage (1.00:1). */
.sec--dark h1,.sec--dark h2,.sec--dark h3,.sec--dark h4,
footer.site h1,footer.site h2,footer.site h3,footer.site h4,
.hero-panel h1,.hero-panel h2,.hero-panel h3{color:var(--on-deep)}
/* Display is a role, not a heading level: the hero H1 wears it, section H1s
   do not. It is the only size above --fs-h1. */
.t-display,.hero h1,.hero-panel h1{font-size:var(--fs-display);line-height:var(--lh-display)}
/* These two are the interior-page title and section heading. They existed
   because h1/h2 were sized for the homepage hero; now that Display is its own
   role, "small h1" is simply H1 and "small h2" is simply H2. Kept as aliases
   rather than deleted, because they are on ~20 templates and templates are
   not in this wave's scope. */
.h1-sm{font-size:var(--fs-h1);line-height:var(--lh-display)}
.h2-sm{font-size:var(--fs-h2);line-height:var(--lh-h)}
p{margin:0 0 var(--s-3)}   /* Brief §9: paragraph spacing 12px bottom */
/* Brief §9: list item spacing 10px. Scoped to running copy — a nav or a
   footer column is a list too, and 10px between its items is not the same
   instruction. */
.art li,.entry li{margin-bottom:10px}
.lede{font-size:var(--fs-lede);line-height:var(--lh-lede);color:var(--muted);max-width:62ch}
.dim{color:var(--muted)}
/* Three section rhythms, not six. Every value is on the 4px scale, so nothing
   renders fractional between breakpoints the way clamp() did (51.2 / 76.8 /
   81.92px at 1024), and mobile finally differs from tablet. */
.sec{padding:var(--sec-y) 0}
.sec--tight{padding:var(--sec-y-tight) 0}
.sec--dark{background:var(--deep);color:var(--on-deep)}
.sec--dark .lede,.sec--dark .dim{color:var(--on-deep-2)}
.sec--dark .eyebrow{color:var(--on-deep-3)}
/* Brief §9 uses #f5f5f5 for section backgrounds and reserves #e8f5e9 for
   cards, highlight boxes and accents. The alternating band therefore takes
   --band; the class name is left alone because templates are not in scope. */
.sec--mist{background:var(--band)}
.sec--center{max-width:760px;text-align:center;margin:0 auto}
.hd{display:flex;justify-content:space-between;align-items:flex-end;gap:var(--s-6);flex-wrap:wrap;margin-bottom:var(--s-7)}
.hd p{margin:var(--s-3) 0 0}

/* ==========================================================================
   Buttons
   ========================================================================== */
/* border-radius is declared explicitly. Without it .btn rendered 0px as <a>
   and 3px as <button>, because the parent reset radiused one tag and not the
   other. One declaration fixes every .btn call site without touching any. */
/* Brief §9 CTA row and the Quick Reference button block: Inter 16px / 700,
   white on #2c5f2d, 12px vertical and 20px horizontal padding, 44px minimum
   height, 4px radius, #1e4620 on hover. White on the primary green measures
   7.55:1; white on the hover green 10.76:1. */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:var(--s-2);
  border:1px solid var(--sage);border-radius:var(--radius);background:var(--sage);color:#fff;
  padding:12px 20px;min-height:44px;font-family:var(--body);
  font-size:var(--fs-body);font-weight:var(--fw-heading);letter-spacing:var(--ls-btn);
  line-height:1;text-transform:uppercase;white-space:nowrap;
  text-decoration:none;transition:background .18s,color .18s,border-color .18s}
.btn:hover,.btn:focus,.btn:active{background:var(--deep);border-color:var(--deep);color:#fff}
.btn--ghost{background:transparent;color:var(--sage);border-color:var(--sage-2)}
.btn--ghost:hover,.btn--ghost:focus,.btn--ghost:active{color:var(--deep);border-color:var(--sage);background:transparent}
/* A ghost button is identified by its border, so on a dark band that border
   has to clear the 3:1 non-text floor: --line-on-deep-2 is 3.38:1 on --deep. */
.sec--dark .btn--ghost{color:var(--on-deep);border-color:var(--line-on-deep-2)}
.sec--dark .btn--ghost:hover{border-color:var(--on-deep-3);color:#fff}
.btn--sm{padding:var(--s-2) var(--s-4);min-height:44px}

/* ==========================================================================
   Header
   ========================================================================== */
header.site{position:sticky;top:0;z-index:60;background:var(--paper);border-bottom:1px solid var(--line)}
.admin-bar header.site{top:32px}
@media(max-width:782px){.admin-bar header.site{top:46px}}
.en-site-header .nav{display:flex;align-items:center;gap:var(--s-5);min-height:var(--s-8);position:relative;max-width:calc(var(--maxw) + var(--s-9))}
.brand{display:flex;align-items:center;gap:var(--s-3);text-decoration:none;flex:0 0 auto}
/* Scoped to #primary-menu, not ".nav ul". The language switcher is also a
   <ul> inside .nav, so the broad selector was styling it as a nav menu — and
   the mobile rule below was hiding it outright on every screen under 1000px. */
#primary-menu{display:flex;gap:0;list-style:none;margin:0;padding:0}
#primary-menu a{font-size:var(--fs-small);line-height:var(--lh-small);text-decoration:none;
  padding:var(--s-2) var(--s-1);color:var(--muted);white-space:nowrap;border-bottom:2px solid transparent;display:flex;align-items:center;min-height:44px}
#primary-menu a:hover{color:var(--ink)}
#primary-menu a.on,#primary-menu li.current-menu-item>a,#primary-menu li.current-menu-ancestor>a{color:var(--ink);border-bottom-color:var(--sage);font-weight:var(--fw-micro)}
.primary-navigation{display:flex;align-items:center;justify-content:center;min-width:0;flex:1 1 auto}
.nav-panel-actions{display:none}
.navtools{display:flex;align-items:center;gap:var(--s-3);flex:0 0 auto}

/* --------------------------------------------------------------------------
   Desktop header row — the German fit

   The row is brand + .primary-navigation + .navtools in one flex line, and in
   German it did not fit at any desktop width. Measured, DE, gap from the last
   menu item's right edge to .navtools:

     1281px: -12   1360px: -5   1440px: -5   1920px: -5

   English cleared by +14 to +16 at the same widths, which is why the overlap
   read as an English-only non-problem. The symmetry matters too: because
   .primary-navigation centres the menu, an over-wide menu spills equally at
   both ends, so "Kontakt" sat under the search disclosure and "Startseite" sat
   under the wordmark by the same amount.

   Note that .primary-navigation's own scrollWidth is 0 over its clientWidth
   throughout — #primary-menu absorbs the overflow inside itself rather than
   pushing its container — so a container scroll-width check reports a clean
   row here. The gap between the two boxes is the measurement that sees it.

   The arithmetic at 1281, the binding width, where the row is viewport-bound
   rather than --maxw-bound: 1281 - 80 rail = 1201 of track, against brand 187 +
   menu 735 + tools 304 + two 24px gaps = 1274. 73px short.

   Four small takes rather than one large one, none of which changes what the
   row contains:

     nav gap    24 -> 16   x2   = 16px
     tools gap  12 ->  8   x3   = 12px
     brand gap  12 ->  8   x1   =  4px
     item pad    4 ->  3   x16  = 32px   (8 items, both sides)
     item type 13.6 -> 13       = ~24px

   13px is stated literally, as .f input's 16px is: it is between --fs-small
   (13.6) and --fs-micro (12) and is not a scale step, it is the width this row
   has. It stays comfortably above the 12px floor, and #666 on white measures
   5.74:1 at that size, so the AA margin is unchanged.

   The 40px rail is deliberately left alone: taking it to 32 would have bought
   another 16px, but it is the same rail every .wrap below the header uses, and
   the wordmark would no longer line up with the page content under it.

   After, gap from the last item to .navtools, both languages:

     DE  1281: +13   1360: +19   1440: +19   1920: +19
     EN  1281: +33   1360: +40   1440: +40   1920: +40

   Below 1281 the burger is active and none of this applies.
   -------------------------------------------------------------------------- */
@media(min-width:1281px){
  .en-site-header .nav{gap:var(--s-4)}
  .navtools{gap:var(--s-2)}
  /* .en-site-header .brand, not .brand: zip/05-brand.css sets .brand--mark
     {gap:var(--s-3)} at the same specificity and loads after this sheet, so a
     bare .brand here loses the cascade by order and silently gives back 4px. */
  .en-site-header .brand{gap:var(--s-2)}
  /* One owner for the space between items.
     ---------------------------------------
     Spacing used to come from two places at once: 2px of column-gap plus 3px of
     padding on each side of every link. A plain pair therefore sat 8px apart —
     but a parent item ends in the dropdown caret, and the caret carried its own
     8px of right padding on top of the gap, so the space after "Produkte" or
     "Unternehmen" measured 13px against 8px everywhere else. Uneven by roughly
     half again, and only on the items the eye already treats as different.

     The gap is now stated once, on the list, and the links contribute nothing
     to it. 70-nav.css takes the caret's trailing padding to zero for the same
     reason, so a parent item's box ends at the caret exactly as a plain item's
     ends at its last letter, and every gap in the row is the same 8px.

     Width, at the 1281px binding case this block exists for: the old model
     spent 48px of link padding + 14px of gap + 9px for each parent item; the
     new one spends 56px of gap + 2px per parent. On the German menu that is
     roughly 20px returned to the row, so the measured clearance to .navtools
     documented above widens rather than narrows.

     The gap itself is set in two steps below, because the row has two widths
     and only one of them is tight. */
  #primary-menu a{font-size:13px;padding-left:0;padding-right:0}

  /* Step one: the hand-off width.
     -----------------------------
     8px was uniform but cramped — adjacent labels read as one run of text
     rather than as separate destinations. How much more the row can afford is
     bounded by French, which carries eight items against German and English's
     seven and the longest CTA of the three ("Demander un échantillon"), so it
     is the language measured here.

     .primary-navigation centres the menu, so slack is symmetric and the figure
     below is the clearance at each end — to .navtools on one side, to the
     wordmark on the other. Measured, FR, at the 1201px track a 1281px viewport
     provides:

       gap  8px: +36.3    16px:  +8.3
       gap 12px: +22.3    20px:  -5.7   (overlaps)

     16px leaves the last item 8px from the search control, which is closer to
     the tools than the items are to each other — the row would read as one
     undifferentiated strip again at the other end. 12px is the widest step
     that keeps the menu clearly separated from both neighbours. */
  #primary-menu{column-gap:var(--s-3)}
}

/* Step two: the full-width row.
   -----------------------------
   .nav is capped at --maxw + --s-9 = 1296px, so the track stops growing once
   the viewport passes 1376px and every wider screen is the same layout. That
   width is not tight, and holding it to the hand-off's 12px spends none of it.

   Measured, FR, at the full 1296px track:

     gap 20px: +41.8    24px: +27.8    28px: +13.8

   24px is --s-5, a real step on the scale rather than a fitted number, and it
   still leaves the row more clearance at each end than the 22.3px the 1281px
   case runs at. 28px would take the clearance below the gap itself, which is
   the same failure as 16px above, just at the other size. */
@media(min-width:1376px){
  #primary-menu{column-gap:var(--s-5)}
}
.lang{display:flex;border:1px solid var(--line);font-family:var(--data);
  font-size:var(--fs-micro);font-weight:var(--fw-micro);letter-spacing:var(--ls-micro);
  list-style:none;margin:0;padding:0}
.lang li{display:flex}
.lang a{padding:var(--s-2) var(--s-3);color:var(--muted);text-decoration:none;display:block}
.lang a:hover{color:var(--ink)}
.lang a[aria-current="true"]{background:var(--sage);color:#fff}
.header-search-desktop .ensearch-t-label{border:0;clip-path:inset(50%);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}
.header-search-desktop .ensearch-t{padding:var(--s-2);gap:0;min-width:44px;justify-content:center}
.nav-cta{white-space:nowrap;padding:var(--s-2) var(--s-4);font-family:var(--body);font-size:var(--fs-small);font-weight:var(--fw-heading);letter-spacing:0;text-transform:none}
/* The reset painted this #cc3366 at rest and filled it magenta on hover and
   on keyboard focus. Colour is now stated rather than inherited. */
.burger{display:none;border:1px solid var(--line);background:transparent;color:var(--ink);
  padding:0;font-size:var(--fs-small);min-width:44px;min-height:44px;border-radius:var(--radius)}
.burger:hover,.burger:focus{background:transparent;color:var(--sage);border-color:var(--sage)}
.burger-lines{display:grid;gap:var(--s-1);width:16px}
.burger-lines span{display:block;width:16px;height:1px;background:currentColor}


/* ==========================================================================
   Hero
   ========================================================================== */
/* The hero keeps its own rhythm, per the direction — but on the scale, so it
   stops rendering fractional between breakpoints. */
.hero{padding:var(--hero-y-top) 0 var(--hero-y-bot)}
.hero-grid{display:grid;grid-template-columns:1.02fr .98fr;gap:var(--s-7);align-items:start}
.hero h1{margin-bottom:var(--s-5)}
.hero h1 em{font-style:normal;color:var(--sage)}
.acts{display:flex;gap:var(--s-3);flex-wrap:wrap;margin-top:var(--s-5);align-items:center}
.trust{display:flex;flex-wrap:wrap;gap:var(--s-2) var(--s-5);margin-top:var(--s-6);padding-top:var(--s-5);border-top:1px solid var(--line);
  font-family:var(--data);font-size:var(--fs-micro);font-weight:var(--fw-micro);
  letter-spacing:var(--ls-micro);line-height:var(--lh-micro);text-transform:uppercase;color:var(--muted);list-style:none;padding-left:0}
.trust li{display:flex;align-items:center;gap:var(--s-2)}
.trust li::before{content:"";width:5px;height:5px;background:var(--sage-2);border-radius:var(--radius-full);flex:0 0 auto}

/* --- Full-bleed media hero (C1) -------------------------------------------
   The section reserves its own height, so the image or video arriving later
   cannot shift anything below it. The copy sits on a near-opaque panel:
   HERO-01 has specular highlights reaching pure white spread across the whole
   frame, so a translucent scrim cannot guarantee legibility anywhere. */
.hero--media{position:relative;padding:0;display:flex;align-items:flex-end;
  min-height:600px;background:var(--deep);overflow:hidden;isolation:isolate}  /* Brief §9: hero 600px desktop */
.hero-media{position:absolute;inset:0;z-index:0}
.hero-picture{position:absolute;inset:0;display:block}
.hero-img,.hero-vid{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block}
.hero-vid{z-index:1}
/* Tonal unity only — legibility is the panel's job, not this layer's. */
.hero-scrim{position:absolute;inset:0;z-index:2;
  background:linear-gradient(100deg,rgba(20,48,23,.72) 0%,rgba(20,48,23,.46) 46%,rgba(20,48,23,.20) 100%)}
.hero--media>.wrap{position:relative;z-index:3;width:100%;
  padding-top:var(--hero-y-top);padding-bottom:var(--hero-y-bot)}
/* Wide enough that "Botanische Extrakte," holds its own line at 60px — the
   existing headline was written to break after the comma, and a narrower
   panel broke it mid-phrase. The lede keeps its own measure inside. */
.hero-panel{position:relative;background:rgba(18,42,20,.95);border:1px solid rgba(154,184,157,.22);
  padding:var(--s-6);max-width:46rem;color:var(--on-deep)}
.hero-panel[hidden]{display:none}
/* Small text control, bottom right of the panel (client request, Sept 2026). */
.hero-panel-close{display:block;width:fit-content;min-height:24px;margin:var(--s-4) 0 calc(-1 * var(--s-3)) auto;padding:var(--s-1) 0;border:0;background:none;color:var(--on-deep-3);font-family:var(--data);font-size:var(--fs-micro);letter-spacing:.04em;line-height:1.4;text-decoration:underline;text-decoration-color:rgba(188,214,190,.45);text-underline-offset:3px;cursor:pointer}
.hero-panel-close:hover,.hero-panel-close:focus-visible{color:#fff;text-decoration-color:currentColor}
.hero-panel-restore{display:inline-flex;align-items:center;gap:var(--s-2);min-height:44px;padding:var(--s-3) var(--s-4);border:1px solid rgba(188,214,190,.5);background:rgba(18,42,20,.92);color:var(--on-deep);font-family:var(--data);font-size:var(--fs-micro);font-weight:var(--fw-micro);letter-spacing:var(--ls-micro);text-transform:uppercase;cursor:pointer}
.hero-panel-restore[hidden]{display:none}
.hero-panel-restore:hover,.hero-panel-restore:focus-visible{border-color:var(--focus-on-dark);background:var(--deep);color:#fff}
.hero-panel-restore .en-icon{width:16px;height:16px}
.hero-panel .eyebrow{color:var(--on-deep-3)}
.hero-panel h1{margin-bottom:var(--s-4);color:#fff}
.hero-panel h1 em{font-style:normal;color:var(--focus-on-dark)}
.hero-panel .lede{color:var(--on-deep-2);margin-bottom:0;max-width:48ch}
.hero-panel .trust{border-top-color:rgba(154,184,157,.26);color:var(--on-deep-2)}
.hero-panel .trust li::before{background:var(--on-deep-3)}
.hero-more{font-family:var(--data);font-size:var(--fs-micro);font-weight:var(--fw-micro);
  letter-spacing:var(--ls-micro);line-height:var(--lh-micro);text-transform:uppercase;
  color:var(--on-deep-2);text-decoration:none;border-bottom:1px solid rgba(188,214,190,.4);padding-bottom:2px}
.hero-more:hover,.hero-more:focus{color:#fff;border-bottom-color:#fff}
@media (prefers-reduced-motion:reduce){.hero-vid{display:none}}

/* --- Application tiles (C7) -----------------------------------------------
   Name, one line, one image, one link. Nothing else by design. */
.tile{display:flex;flex-direction:column;text-decoration:none;color:inherit;background:var(--paper);
  transition:background .18s ease}
.sec--mist .tile{background:var(--mist)}
.tile:hover,.tile:focus-within{background:var(--white)}
.tile-body{padding:var(--s-5);flex:1;display:flex;flex-direction:column}
.tile-body h3{margin:0 0 var(--s-2)}
.tile-body p{font-size:var(--fs-small);line-height:var(--lh-small);color:var(--muted);margin:0 0 var(--s-4)}
.tile .more{margin-top:auto;align-self:flex-start}
.tile:hover .more,.tile:focus-within .more{border-bottom-color:var(--sage)}

/* --- Decorative Europe outline (P5) ---------------------------------------
   Background layer only. Sits under content at low contrast; if it ever
   competes with text, the map loses. */
.has-eumap{position:relative;isolation:isolate;overflow:hidden}
.has-eumap>.wrap{position:relative;z-index:1}
.eumap{position:absolute;top:50%;right:-6%;transform:translateY(-50%);z-index:0;
  width:min(58%,680px);pointer-events:none;opacity:.26}
.eumap svg{width:100%;height:auto;display:block}
/* Measured, not eyeballed. Because the content column is wider than the page
   gutters, form labels do sit over the outline, so the only honest question is
   how much contrast that costs. At these values the worst overlapping text
   measures 5.26:1 against 5.54:1 on bare background — a 5% reduction, still
   clear of the 4.5:1 AA floor. Earlier, heavier values cost 7.4%. */
.eumap-land path{fill:var(--sage);fill-opacity:.05;stroke:var(--sage);stroke-opacity:.11;stroke-width:1.1}
.eumap-grid path{stroke:var(--sage);stroke-opacity:.07;stroke-width:.8}

/* ==========================================================================
   Technical data sheet — signature component
   ========================================================================== */
.tds{background:var(--white);border:1px solid var(--line);box-shadow:0 1px 0 var(--line-2),0 22px 44px -34px rgba(20,48,23,.42)}
.tds-top{display:flex;justify-content:space-between;align-items:center;gap:var(--s-3);padding:var(--s-3) var(--s-4);background:var(--deep);color:var(--on-deep)}
.tds-top .t{font-family:var(--data);font-size:var(--fs-micro);font-weight:var(--fw-micro);
  letter-spacing:var(--ls-micro);line-height:var(--lh-micro);text-transform:uppercase}
.tds-top .r{font-family:var(--data);font-size:var(--fs-micro);line-height:var(--lh-micro);color:var(--on-deep-3)}
.tds-tabs{display:flex;border-bottom:1px solid var(--line)}
.tds-tabs button{flex:1;border:0;border-radius:0;background:transparent;padding:var(--s-3) var(--s-1);
  font-family:var(--data);font-size:var(--fs-micro);font-weight:var(--fw-micro);
  letter-spacing:var(--ls-micro);line-height:var(--lh-micro);text-transform:uppercase;color:var(--muted);border-bottom:2px solid transparent}
.tds-tabs button[aria-selected="true"]{color:var(--ink);border-bottom-color:var(--sage);background:var(--card)}
.tds-body{padding:var(--s-5) var(--s-4) var(--s-4)}
.tds-name{font-family:var(--display);font-size:var(--fs-h3);font-weight:var(--fw-heading);letter-spacing:var(--ls-display);line-height:var(--lh-h3)}
.tds-bot{font-family:var(--data);font-size:var(--fs-micro);line-height:var(--lh-micro);color:var(--sage);margin-top:var(--s-1)}
.tds-rows{margin:var(--s-4) 0 0;border-top:1px solid var(--line-2)}
.tds-row{display:grid;grid-template-columns:122px 1fr;gap:var(--s-3);padding:var(--s-2) 0;border-bottom:1px solid var(--line-2);align-items:baseline}
.tds-row dt{font-family:var(--data);font-size:var(--fs-micro);font-weight:var(--fw-micro);
  letter-spacing:var(--ls-micro);line-height:var(--lh-micro);text-transform:uppercase;color:var(--muted)}
.tds-row dd{margin:0;font-size:var(--fs-small);line-height:var(--lh-small)}
.tds-row dd b{font-family:var(--data);font-weight:var(--fw-micro);font-size:var(--fs-small)}
.docs{display:flex;flex-wrap:wrap;gap:var(--s-1);margin-top:var(--s-3);list-style:none;padding:0}
.doc{font-family:var(--data);font-size:var(--fs-micro);font-weight:var(--fw-micro);
  letter-spacing:var(--ls-micro);line-height:var(--lh-micro);text-transform:uppercase;
  border:1px solid var(--line);border-radius:var(--radius);
  padding:var(--s-1) var(--s-2);color:var(--muted);background:var(--card);display:inline-block}
/* "Document available" is a confirmed state, not a pending one. It wore the
   pending amber, which made the same colour mean two opposite things in one
   component. Confirmed is --sage everywhere on the site. */
.doc.on{border-color:var(--sage);color:var(--sage)}
.tds-foot{display:flex;gap:var(--s-2);padding:var(--s-3) var(--s-4);border-top:1px solid var(--line);background:var(--card);flex-wrap:wrap}
.flag{margin-top:var(--s-3);font-size:var(--fs-small);color:var(--amber);display:flex;gap:var(--s-2);line-height:var(--lh-small)}
.flag::before{content:"\00a7";font-family:var(--data);flex:0 0 auto;font-weight:var(--fw-micro)}

/* ==========================================================================
   Grids & cards
   ========================================================================== */
.g3{display:grid;grid-template-columns:repeat(3,1fr);gap:1px;background:var(--line)}
.g2{display:grid;grid-template-columns:repeat(2,1fr);gap:1px;background:var(--line)}
/* One card padding. Was 29/25 here, 26/25/29 on tiles and image cards, 24 on
   .qbox — five card surfaces, five paddings, none responsive. */
.g3>*,.g2>*{background:var(--paper);padding:var(--s-5)}
.sec--mist .g3>*,.sec--mist .g2>*{background:var(--mist)}
.card-n{font-family:var(--data);font-size:var(--fs-micro);font-weight:var(--fw-micro);
  line-height:var(--lh-micro);color:var(--sage);letter-spacing:var(--ls-micro);text-transform:uppercase}
.card h3{margin:var(--s-3) 0 var(--s-2)}
.card p{font-size:var(--fs-small);line-height:var(--lh-small);color:var(--muted);margin-bottom:var(--s-3)}
.card ul{margin:0 0 var(--s-4);padding:0;list-style:none;font-size:var(--fs-small);line-height:var(--lh-small);color:var(--muted)}
.card ul li{padding:var(--s-1) 0;border-top:1px solid var(--line-2);display:flex;justify-content:space-between;gap:var(--s-3)}
.card ul li span{font-family:var(--data);font-size:var(--fs-micro);line-height:var(--lh-micro);color:var(--sage);text-align:right;flex:0 0 auto}
.card a.more,.more{font-family:var(--data);font-size:var(--fs-micro);font-weight:var(--fw-micro);
  letter-spacing:var(--ls-micro);line-height:var(--lh-micro);text-transform:uppercase;color:var(--sage);text-decoration:none;border-bottom:1px solid var(--line)}
.card a.more:hover,.more:hover{border-bottom-color:var(--sage)}
/* A plain card sits inside a grid cell that already carries the padding,
   so its body adds none. This has to come first: an image card zeroes the
   cell padding so the photo can bleed, and its body supplies its own. */
.card .card-body{padding:0}
.card--img{padding:0!important;display:flex;flex-direction:column}
.card--img .card-body{padding:var(--s-5);flex:1;display:flex;flex-direction:column}
.card--img .more{margin-top:auto;align-self:flex-start}
.split{display:grid;grid-template-columns:1fr 1fr;gap:var(--s-7);align-items:center}
.band{padding:0 0 var(--s-6)}

/* Process */
.proc{display:grid;grid-template-columns:repeat(5,1fr);gap:1px;background:var(--line-on-deep);margin-top:var(--s-1);list-style:none;padding:0}
.proc>li{background:var(--deep);padding:var(--s-5)}
.proc .n{font-family:var(--data);font-size:var(--fs-h2);font-weight:var(--fw-body);color:var(--focus-on-dark);line-height:1;letter-spacing:var(--ls-display)}
.proc h3{font-size:var(--fs-h3);margin:var(--s-3) 0 var(--s-2);color:#fff}
.proc p{font-size:var(--fs-small);color:var(--on-deep-2);margin:0;line-height:var(--lh-small)}

/* ==========================================================================
   Product list
   ========================================================================== */
.filters{display:flex;gap:var(--s-2);flex-wrap:wrap;margin-bottom:var(--s-5)}
.filters a{border:1px solid var(--line);border-radius:var(--radius);background:transparent;padding:var(--s-2) var(--s-3);font-family:var(--data);
  font-size:var(--fs-micro);font-weight:var(--fw-micro);letter-spacing:var(--ls-micro);line-height:var(--lh-micro);
  text-transform:uppercase;color:var(--muted);text-decoration:none;display:inline-block}
.filters a[aria-current="page"]{background:var(--deep);border-color:var(--deep);color:#fff}
.plist{border-top:1px solid var(--line)}
.prow{display:grid;grid-template-columns:1.3fr 1.5fr .8fr auto;gap:var(--s-4);align-items:center;padding:var(--s-4) var(--s-1);
  border-bottom:1px solid var(--line);width:100%;background:transparent;text-align:left;text-decoration:none;color:inherit}
.prow:hover{background:var(--card)}
.prow .nm{font-family:var(--display);font-weight:var(--fw-heading);font-size:var(--fs-lede);letter-spacing:var(--ls-display);display:block}
.prow .bt{font-family:var(--data);font-size:var(--fs-micro);line-height:var(--lh-micro);color:var(--sage);display:block;margin-top:var(--s-1)}
.prow .mk{font-size:var(--fs-small);line-height:var(--lh-small);color:var(--muted)}
.prow .cat{font-family:var(--data);font-size:var(--fs-micro);font-weight:var(--fw-micro);letter-spacing:var(--ls-micro);line-height:var(--lh-micro);text-transform:uppercase;color:var(--muted)}
.prow .go{font-family:var(--data);font-size:var(--fs-micro);font-weight:var(--fw-micro);letter-spacing:var(--ls-micro);line-height:var(--lh-micro);text-transform:uppercase;color:var(--sage);white-space:nowrap}
.back{font-family:var(--data);font-size:var(--fs-micro);font-weight:var(--fw-micro);letter-spacing:var(--ls-micro);line-height:var(--lh-micro);text-transform:uppercase;color:var(--sage);text-decoration:none}
.back:hover{color:var(--deep)}
.plink{text-decoration:none;border-bottom:1px solid transparent}
.plink:hover{border-bottom-color:var(--sage);color:var(--ink)}

/* ==========================================================================
   Quality boxes / test scope
   ========================================================================== */
.qgrid{display:grid;grid-template-columns:repeat(2,1fr);gap:var(--gap)}
.qbox{border:1px solid var(--line);background:var(--white);padding:var(--s-5)}
.qbox h3{margin-bottom:var(--s-2)}
.qbox p{font-size:var(--fs-small);line-height:var(--lh-small);color:var(--muted);margin-bottom:0}
.status{display:inline-flex;align-items:center;gap:var(--s-2);font-family:var(--data);
  font-size:var(--fs-micro);font-weight:var(--fw-micro);letter-spacing:var(--ls-micro);line-height:var(--lh-micro);
  text-transform:uppercase;padding:var(--s-1) var(--s-2);border:1px solid var(--line);border-radius:var(--radius);color:var(--muted);margin-bottom:var(--s-3)}
.status::before{content:"";width:5px;height:5px;border-radius:var(--radius-full);background:var(--amber);flex:0 0 auto}
.testlist{list-style:none;margin:0;padding:0}
.testlist li{display:grid;grid-template-columns:1fr auto;gap:var(--s-4);padding:var(--s-2) 0;border-bottom:1px solid var(--line-2);font-size:var(--fs-small);line-height:var(--lh-small)}
.testlist li span{font-family:var(--data);font-size:var(--fs-micro);line-height:var(--lh-micro);color:var(--muted);text-align:right}

/* ==========================================================================
   Documentation matrix — real table
   ========================================================================== */
.dtable-wrap{border-top:1px solid var(--line);overflow-x:auto}
.dtable{width:100%;border-collapse:collapse;min-width:620px}
/* Horizontal rules only. The vertical hairlines and the zebra were the parent
   reset's, not ours, and they are neutralised at the head of this file — this
   rule supplies the one rule per row that replaces them. Row height is a single
   value across every table on the site. */
.dtable th,.dtable td{padding:var(--s-3) var(--s-3);border-bottom:1px solid var(--line-2);text-align:center;vertical-align:middle}
.dtable thead th{padding:var(--s-2) var(--s-3);border-bottom:1px solid var(--line);
  font-family:var(--data);font-size:var(--fs-micro);font-weight:var(--fw-micro);
  letter-spacing:var(--ls-micro);line-height:var(--lh-micro);text-transform:uppercase;color:var(--muted)}
.dtable th[scope="row"],.dtable thead th:first-child{text-align:left;min-width:210px}
.dtable tbody tr:hover{background:var(--card)}
.dt-n{font-family:var(--display);font-weight:var(--fw-heading);font-size:var(--fs-body);letter-spacing:var(--ls-display);text-decoration:none;color:inherit;display:block}
.dt-n:hover{color:var(--sage)}
.dt-n i{display:block;font-family:var(--data);font-size:var(--fs-micro);line-height:var(--lh-micro);color:var(--sage);font-style:normal;margin-top:var(--s-1);font-weight:var(--fw-body)}
/* Fix: the prototype rendered the negative state at 1.3:1 contrast. */
.dt-y{color:var(--sage);font-size:var(--fs-small)}
.dt-n-mark{color:var(--muted);font-size:var(--fs-small)}

/* ==========================================================================
   Accordion
   ========================================================================== */
.acc{border-top:1px solid var(--line)}
.acc-i{border-bottom:1px solid var(--line)}
.acc-q{width:100%;display:flex;justify-content:space-between;align-items:flex-start;gap:var(--s-5);
  background:transparent;border:0;border-radius:0;padding:var(--s-4) 0;text-align:left;font-family:var(--display);
  font-weight:var(--fw-heading);font-size:var(--fs-lede);letter-spacing:var(--ls-display);line-height:var(--lh-h3);color:var(--ink)}
.acc-q:hover{color:var(--sage)}
.acc-icon{color:var(--sage);flex:0 0 auto;transition:transform var(--dur) var(--ease)}
.acc-q[aria-expanded="true"] .acc-icon{transform:rotate(45deg)}
.acc-a{display:none;padding:0 var(--s-7) var(--s-4) 0}
.acc-a.on{display:block}
.acc-a p{margin:0;font-size:var(--fs-small);line-height:var(--lh-small);color:var(--muted);max-width:72ch}

/* ==========================================================================
   Forms
   ========================================================================== */
.formwrap{display:grid;grid-template-columns:1fr 330px;gap:var(--s-7);align-items:start}
/* No aside: the contact page carries its own contact-facts band, so the form
   takes the full measure rather than leaving a 330px column standing empty. */
.formwrap--solo{grid-template-columns:minmax(0,720px)}
.fset{border:0;padding:0;margin:0 0 var(--s-5)}
.fset legend{font-family:var(--data);font-size:var(--fs-micro);font-weight:var(--fw-micro);
  letter-spacing:var(--ls-micro);line-height:var(--lh-micro);text-transform:uppercase;color:var(--sage);padding:0;margin-bottom:var(--s-3)}
.frow{display:grid;grid-template-columns:1fr 1fr;gap:var(--s-3)}
.f{margin-bottom:var(--s-3)}
.f label{display:block;font-size:var(--fs-small);line-height:var(--lh-small);color:var(--muted);margin-bottom:var(--s-1)}
/* The required marker is not a pending state. It wore the pending amber, which
   is the third of the three meanings that colour was carrying. */
.f label .req{color:var(--ink)}
/* Brief §9 / Quick Reference field spec: 1px #ccc, 10px 12px padding, 44px
   height, 16px font (which is also what stops iOS zooming the page on
   focus), 4px radius, 2px #2c5f2d focus with a light-green shadow, 2px
   #f44336 in error. 16px is stated literally rather than as --fs-body so the
   no-zoom guarantee survives any future change to the body scale. */
.f input,.f select,.f textarea{width:100%;border:1px solid var(--line);background:var(--white);
  padding:10px 12px;font-family:var(--body);font-size:16px;color:var(--ink);
  border-radius:var(--radius);min-height:44px}
.f textarea{min-height:100px;resize:vertical;padding-top:10px}
.f input:focus,.f select:focus,.f textarea:focus{border-color:var(--sage);outline:none;
  box-shadow:0 0 0 1px var(--sage),0 0 0 4px rgba(44,95,45,.18)}
/* The mandated #f44336 is 3.68:1 on white — a legal 2px border, but not a
   legal message. The message takes the AA variant of the same hue. */
.f .err{font-size:var(--fs-small);line-height:var(--lh-small);color:var(--err-text);margin:var(--s-1) 0 0}
.f input[aria-invalid="true"],.f select[aria-invalid="true"],.f textarea[aria-invalid="true"]{
  border-color:var(--err);box-shadow:0 0 0 1px var(--err)}
.f .warn{font-size:var(--fs-small);line-height:var(--lh-small);color:var(--amber);margin:var(--s-1) 0 0}
.chips{display:flex;flex-wrap:wrap;gap:var(--s-2)}
.chip{position:relative;display:inline-block}
.chip input{position:absolute;opacity:0;width:0;height:0}
.chip span{display:inline-block;border:1px solid var(--line);border-radius:var(--radius);background:var(--white);
  padding:var(--s-2) var(--s-3);font-size:var(--fs-small);line-height:var(--lh-small);transition:.14s}
.chip input:checked+span{border-color:var(--sage);background:var(--sage);color:#fff}
.chip input:focus-visible+span{outline:2px solid var(--focus);outline-offset:2px}
.consent{display:flex;gap:var(--s-2);align-items:flex-start;font-size:var(--fs-small);color:var(--muted);margin-bottom:var(--s-3);line-height:var(--lh-small)}
.consent input{margin-top:var(--s-1);flex:0 0 auto;accent-color:var(--sage);width:auto}
.hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}
/* Brief §9 card spec: #f9f9f9 on #ddd, 15–20px padding, 4px radius. */
.aside{background:var(--card);border:1px solid var(--line-2);border-radius:var(--radius);padding:var(--gap)}
.aside h3{font-size:var(--fs-lede);margin-bottom:var(--s-3)}
.steps{list-style:none;margin:0 0 var(--s-5);padding:0;counter-reset:s}
.steps li{counter-increment:s;display:grid;grid-template-columns:var(--s-5) 1fr;gap:var(--s-3);padding:var(--s-3) 0;border-top:1px solid var(--line-2);font-size:var(--fs-small);line-height:var(--lh-small);color:var(--muted)}
.steps li::before{content:counter(s,decimal-leading-zero);font-family:var(--data);font-size:var(--fs-micro);color:var(--sage);padding-top:var(--s-1)}
.steps li b{color:var(--ink);font-weight:var(--fw-heading);display:block;font-size:var(--fs-small)}
/* The error callout borrows the highlight-box geometry (5px left rule, 20px
   padding, 4px radius) with the error hue in place of the green. */
.notice{border:1px solid var(--err);border-left:5px solid var(--err);background:var(--err-bg);
  border-radius:var(--radius);padding:var(--gap);margin-bottom:var(--s-5);
  font-size:var(--fs-small);line-height:var(--lh-small);color:var(--err-text)}
.notice ul{margin:var(--s-2) 0 0;padding-left:var(--s-4)}
/* Brief §9 highlight box: #e8f5e9 ground, 5px left border in the primary
   green, 20px padding, 4px radius. */
.done{border-left:5px solid var(--sage);background:var(--mist);border-radius:var(--radius);padding:var(--gap)}
.done .tick{width:36px;height:36px;border-radius:var(--radius-full);background:var(--sage);color:#fff;display:grid;place-items:center;font-size:var(--fs-lede);margin-bottom:var(--s-4)}
.done code{font-family:var(--data);font-size:var(--fs-small);background:var(--white);
  border:1px solid var(--line-2);border-radius:var(--radius);padding:var(--s-1) var(--s-2)}

/* ==========================================================================
   Person
   ========================================================================== */
.person{display:grid;grid-template-columns:78px 1fr;gap:var(--gap);align-items:center;
  border:1px solid var(--line-2);border-radius:var(--radius);background:var(--card);padding:var(--gap)}
.person .av{width:78px;height:78px;background:var(--mist);border:1px solid var(--line);display:grid;place-items:center;
  overflow:hidden;padding:0}
.person .nm{font-family:var(--display);font-weight:var(--fw-heading);font-size:var(--fs-lede)}
.person .ro{font-family:var(--data);font-size:var(--fs-micro);font-weight:var(--fw-micro);
  letter-spacing:var(--ls-micro);line-height:var(--lh-micro);text-transform:uppercase;color:var(--sage);margin:var(--s-1) 0 var(--s-2)}
.person a{font-size:var(--fs-small);line-height:var(--lh-small);text-decoration:none;color:var(--ink);border-bottom:1px solid var(--line);display:inline-block;margin-right:var(--s-3)}
.person a:hover{border-bottom-color:var(--sage)}

/* ==========================================================================
   Article
   ========================================================================== */
.art h2{font-size:var(--fs-h2);margin:var(--s-6) 0 var(--s-3)}
.art-sec{border-top:1px solid var(--line-2);padding-top:var(--s-1)}
.art-ph{border:1px dashed var(--line);background:var(--card);padding:var(--s-4);font-size:var(--fs-small);line-height:var(--lh-small);color:var(--muted);
  display:flex;gap:var(--s-3);align-items:baseline}
.art-ph span{font-family:var(--data);font-size:var(--fs-micro);line-height:var(--lh-micro);color:var(--sage);flex:0 0 auto}

/* ==========================================================================
   Image placeholders — each carries its own shot brief
   ========================================================================== */
.ph{margin:0;position:relative;aspect-ratio:var(--r,16/10);display:grid;place-items:center;overflow:hidden;
  border:1px dashed var(--sage-2);background-color:var(--mist);
  background-image:repeating-linear-gradient(45deg,rgba(44,95,45,.055) 0 12px,transparent 12px 24px)}
.ph img{width:100%;height:100%;object-fit:cover}
.ph-in{text-align:center;padding:var(--s-4);max-width:92%}
.ph-id{font-family:var(--data);font-size:var(--fs-micro);font-weight:var(--fw-micro);
  letter-spacing:var(--ls-micro);line-height:var(--lh-micro);color:var(--sage);border:1px solid var(--sage-2);border-radius:var(--radius);
  padding:var(--s-1) var(--s-2);display:inline-block;margin-bottom:var(--s-2);background:rgba(255,255,255,.72)}
.ph-t{display:block;font-size:var(--fs-small);color:var(--deep);line-height:var(--lh-small);margin-bottom:var(--s-1);font-weight:var(--fw-micro)}
.ph-s{display:block;font-family:var(--data);font-size:var(--fs-micro);line-height:var(--lh-micro);color:var(--muted);letter-spacing:var(--ls-micro)}
.ph--dark{border-color:var(--line-on-deep);background-color:var(--deep-2);
  background-image:repeating-linear-gradient(45deg,rgba(255,255,255,.045) 0 12px,transparent 12px 24px);margin-bottom:var(--s-1)}
.ph--dark .ph-id{color:var(--on-deep-3);border-color:var(--line-on-deep);background:rgba(0,0,0,.2)}
.ph--dark .ph-t{color:var(--on-deep)}
.ph--dark .ph-s{color:var(--on-deep-3)}
.ph--card{border-left:0;border-right:0;border-top:0}
/* Real photograph in the slot: no dashed placeholder outline, no pattern. */
.ph--filled{border:0;background-image:none;background-color:var(--mist)}

/* Empty slot as a visitor sees it. The dashed outline and the hatching are
   placeholder affordances that say "something is missing here" — true, but it
   is not the visitor's problem. A quiet tinted block holds the same aspect
   ratio, so the page does not reflow when the photograph arrives. */
.ph--empty{border:0;background-image:none;background-color:var(--mist)}
.ph--sq{width:100%;height:100%;border:0;aspect-ratio:1/1}

/* ==========================================================================
   Footer
   ========================================================================== */
footer.site{background:var(--deep);color:var(--on-deep-2);padding:var(--s-7) 0 var(--s-5);font-size:var(--fs-small);line-height:var(--lh-small)}
footer.site h2{font-family:var(--data);font-size:var(--fs-micro);font-weight:var(--fw-micro);
  letter-spacing:var(--ls-micro);text-transform:uppercase;color:var(--on-deep-3);margin-bottom:var(--s-3);line-height:var(--lh-micro)}
.fgrid{display:grid;grid-template-columns:1.35fr 1fr 1fr 1.15fr;gap:var(--s-6)}
footer.site ul{list-style:none;margin:0;padding:0}
footer.site li{padding:var(--s-1) 0}
footer.site a{text-decoration:none;color:var(--on-deep-2)}
footer.site a:hover{color:#fff}
.fbot{margin-top:var(--s-7);padding-top:var(--s-5);border-top:1px solid var(--line-on-deep);display:flex;justify-content:space-between;
  gap:var(--s-4);flex-wrap:wrap;font-family:var(--data);font-size:var(--fs-micro);line-height:var(--lh-micro);letter-spacing:var(--ls-micro);color:var(--on-deep-3)}
.fbot nav{display:flex;gap:var(--s-4);flex-wrap:wrap}
/* The legal bar is the last set of links on every page and the only ones the
   theme left at their line-box height: measured 71x17, 81x17 and 27x17 at 375,
   against a 44px target. The footer's own column links already resolve to
   335x44, the language switch to 44x44 and the burger to 44x44, so this bar was
   the single exception, on all 40 routes in both languages.

   min-height/min-width on the box rather than padding: padding would need a
   negative margin to keep the row's left edge flush with the copyright line
   above, and that margin would overlap adjacent hit areas — the row's 16px gap
   is the only thing keeping the three targets separable. Only "AGB" is narrower
   than 44px, so centring is the only text that moves at all. */
@media (max-width:1024px){
  .fbot nav a{display:inline-flex;align-items:center;justify-content:center;min-height:44px;min-width:44px}
}

/* ==========================================================================
   Cookie notice
   ========================================================================== */
.cookie{position:fixed;left:var(--rail);right:var(--rail);bottom:var(--s-4);z-index:80;background:var(--white);
  border:1px solid var(--line);box-shadow:0 20px 44px -28px rgba(20,48,23,.5);padding:var(--s-4) var(--s-5);
  display:flex;gap:var(--s-4);align-items:center;flex-wrap:wrap;max-width:740px;margin:0 auto;font-size:var(--fs-small);line-height:var(--lh-small)}
.cookie[hidden]{display:none}
.cookie p{margin:0;flex:1 1 300px;color:var(--muted)}
.cookie .acts{display:flex;gap:var(--s-2);margin:0}

/* ==========================================================================
   Responsive
   ========================================================================== */

/* --- Mobile type and rhythm ------------------------------------------------
   The whole type system responds by redefining eight tokens once, at the one
   boundary the brief specifies. Nothing else in the codebase restates a size
   per breakpoint, which is what let 63 sizes accumulate in the first place.

   Note what is NOT here: --fs-body, --fs-small and --fs-micro do not change.
   Body copy is 16px on both, small is 14 on both, and the label floor is 12px
   on every screen — that floor is the point, and a mobile-only exception
   would put it straight back where it was. */
@media (max-width:767px){
  :root{
    /* Brief §9 mobile column: H1 1.8em, H2 1.5em, H3 1.2em. Body, small and
       micro are deliberately absent — the Brief keeps body at 1em on mobile
       to stop iOS zooming, small stays 0.85em, and 12px is the floor. */
    --fs-display:1.8rem; --fs-h1:1.8rem; --fs-h2:1.5rem; --fs-h3:1.2rem;
    --fs-lede:1.05rem;
    /* Brief §9 / Quick Reference: 30px mobile section padding, one figure. */
    --sec-y:30px;
  }
}

@media(max-width:1000px){
  .split,.hero-grid,.formwrap{grid-template-columns:1fr}
  .proc{grid-template-columns:repeat(2,1fr)}
  .fgrid{grid-template-columns:1fr 1fr}
}

/* --- Header fit ------------------------------------------------------------
   The header overflowed its own container from 1001px up: the desktop menu was
   switched on at 1001px but the row does not fit there, so the language
   switcher — the primary control on a bilingual site — was pushed off-screen
   across a band of common laptop widths.

   The switch now happens at the width where the row actually fits. Measured,
   not guessed: brand 208 + menu 739 + tools 187 + two gaps needs 1169px of
   track, against the 1132px that --maxw 1180 minus the rail actually provides.
   So the menu also gives back 8px of padding per item (7 items, 56px), which
   brings it to 1113 and leaves 19px of slack at the widest.

   The binding case is German — "Qualität & Rückverfolgbarkeit" alone is 203px,
   and the English twin is narrower — so this is measured against DE.

   The layout breakpoints above stay at 1000: they are about content columns,
   not about this row. */
@media(max-width:1280px){
  .en-site-header .primary-navigation{display:none;position:absolute;left:50%;top:100%;width:100vw;max-height:calc(100dvh - var(--s-8));overflow-y:auto;overscroll-behavior:contain;transform:translateX(-50%);background:var(--paper);border-bottom:1px solid var(--line);padding:var(--s-3) max(var(--rail),calc((100vw - var(--maxw))/2 + var(--rail))) var(--s-5);z-index:70}
  .en-site-header .primary-navigation.open{display:block}
  .admin-bar .en-site-header .primary-navigation{max-height:calc(100dvh - var(--s-8) - 32px)}
  #primary-menu{display:none}
  .primary-navigation.open #primary-menu{display:flex;flex-direction:column;gap:0;margin:0}
  .primary-navigation.open #primary-menu>li>a{padding:var(--s-3) 0;font-size:var(--fs-body);border-bottom:1px solid var(--line-2);min-height:44px;white-space:normal;overflow-wrap:anywhere}
  .primary-navigation.open #primary-menu>li.current-menu-item>a,.primary-navigation.open #primary-menu>li.current-menu-ancestor>a{border-bottom-color:var(--sage);color:var(--ink);font-weight:var(--fw-micro)}
  .nav-panel-actions{display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:end;gap:var(--s-4);padding-top:var(--s-5)}
  .nav-panel-search .ensearch-f label{margin-bottom:var(--s-2)}
  .nav-panel-search .ensearch-f .btn{background:transparent;color:var(--sage);border-color:var(--sage)}
  .nav-panel-search .ensearch-f .btn:hover{background:var(--sage);color:#fff}
  .nav-panel-cta{white-space:nowrap}
  .nav-cta{display:none}
  .burger{display:flex;align-items:center;justify-content:center}
  .navtools{margin-left:auto}
  body.nav-open{overflow:hidden}
}
@media(max-width:782px){
  .admin-bar .en-site-header .primary-navigation{max-height:calc(100dvh - var(--s-8) - 46px)}
}

/* Below the burger threshold the row is brand + search + language + burger,
   and at 375 that came to 398px inside a 327px track — so the burger's right
   edge sat at 402px on a 375px screen and the menu could not be opened at all
   on a phone. That predates this wave; raising the label floor to 12px and the
   burger to 44px widened it further, so it is closed here rather than left.

   Two changes: the row tightens to the next step down on every gap, and the
   brand is finally allowed to yield. It was flex:0 0 auto, which is what let
   it push the controls off the edge instead of giving up its own slack. */
@media(max-width:1280px){
  .nav{gap:var(--s-3)}
  .navtools{gap:var(--s-2)}
  .brand{flex:0 0 auto;min-width:0;gap:var(--s-2)}
  .lang a{padding:var(--s-2)}
}
@media(max-width:520px){
  .nav-panel-actions{grid-template-columns:1fr}
  .nav-panel-cta{justify-content:center}
}
@media(max-width:350px){
  /* Search remains available inside the opened menu; removing the duplicate
     toolbar trigger keeps the complete logo and language switch on one row. */
  .header-search-desktop{display:none}
}
@media(max-width:767px){
  :root{--rail:20px}   /* Brief §9: container padding 20px on mobile */
  /* The CTA is 16px/700 uppercase now (Brief §9), which is roughly 40% wider
     than the 12px label it replaced. German labels overrun a 375px column at
     that size, so below the mobile boundary a button is allowed to wrap
     rather than push the page sideways. */
  .btn{white-space:normal;text-align:center}
}
@media(max-width:1000px){
  /* The map is sized against the text column; below this width there is no
     column to sit beside, so it drops behind the content and fades further. */
  .eumap{width:min(86%,560px);right:-14%;opacity:.26}
}
@media(max-width:720px){
  .g3,.g2,.qgrid{grid-template-columns:1fr}
  .hero--media{min-height:500px}   /* Brief §9: hero 500px mobile */
  .hero-panel{max-width:none;padding:var(--gap)}
  /* At this width the panel spans the column, so the scrim carries less of the
     tonal work and the image is darkened evenly instead of directionally. */
  .hero-scrim{background:linear-gradient(180deg,rgba(20,48,23,.42) 0%,rgba(20,48,23,.66) 100%)}
  .eumap{width:130%;right:-30%;opacity:.20}
  .proc,.frow{grid-template-columns:1fr}
  .prow{grid-template-columns:1fr;gap:var(--s-1);padding:var(--s-4) var(--s-1)}
  .prow .go{display:none}
  .fgrid{grid-template-columns:1fr}
  .tds-row{grid-template-columns:100px 1fr;gap:var(--s-2)}
  .person{grid-template-columns:1fr}
  .person .av{width:100%;height:auto;aspect-ratio:1/1}
}
