/* ==========================================================================
   Fonts — self-hosted.
   Loading these from Google is not an option: the shop's consent manager
   classifies fonts.googleapis.com as a marketing service and blocks the
   stylesheet until consent, so the page would render in a fallback face for
   most visitors. Latin + latin-ext subsets only.
   ========================================================================== */

@font-face {
  font-family: 'Bricolage Grotesque';
  font-style: normal;
  font-weight: 400 700;
  font-stretch: 100%;
  font-display: swap;
  src: url(/wp-content/themes/farmula-redesign-v3/assets/fonts/bricolage-grotesque-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Bricolage Grotesque';
  font-style: normal;
  font-weight: 400 700;
  font-stretch: 100%;
  font-display: swap;
  src: url(/wp-content/themes/farmula-redesign-v3/assets/fonts/bricolage-grotesque-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: 'DM Sans';
  font-style: italic;
  font-weight: 300 400;
  font-display: swap;
  src: url(/wp-content/themes/farmula-redesign-v3/assets/fonts/dm-sans-italic-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'DM Sans';
  font-style: italic;
  font-weight: 300 400;
  font-display: swap;
  src: url(/wp-content/themes/farmula-redesign-v3/assets/fonts/dm-sans-italic-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: 'DM Sans';
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url(/wp-content/themes/farmula-redesign-v3/assets/fonts/dm-sans-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'DM Sans';
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url(/wp-content/themes/farmula-redesign-v3/assets/fonts/dm-sans-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ==========================================================================
   Farmula webshop — design tokens extracted from Figma "Home" (235:15)
   ========================================================================== */

:root {
  /* colors — names follow the Figma color styles */
  --blue: #29265d;          /* headings, dark buttons, footer bg */
  --green: #00a687;         /* CTAs, highlights */
  --dark-grey: #3b3a47;     /* body copy */
  --light-grey: #b8b7cc;    /* category labels, old prices, placeholders */
  --grey: #87869a;          /* search placeholder, tax note */
  --red: #fb1b13;           /* remove-from-cart */
  --light-blue: #efecf9;    /* borders, menu bar, section backgrounds */
  --sea-blue: #373476;      /* footer bottom bar */
  --divider: #e1def3;       /* FAQ separators */
  --tag: #bfd968;           /* NEU tag */
  --tag-text: #222424;

  /* type */
  --font-display: "Bricolage Grotesque", sans-serif;
  --font-body: "DM Sans", sans-serif;

  /* layout */
  --page-width: 1728px;
  --page-margin: 99px;

  /* effects */
  --shadow-card: 0 4px 20px rgba(34, 36, 36, 0.04), 0 2px 2px rgba(34, 36, 36, 0.04);
  --radius-card: 24px;
  --radius-btn: 4px;
}

html, body { margin: 0; padding: 0; }
/* The decorative bleeds (the brochure vector above all) are drawn past the
   canvas's right edge on purpose. Above 1728px they land in the page margin
   and cost nothing, but below it the canvas is zoomed to exactly the viewport
   width, so the bleed sticks out and the whole page gains a horizontal
   scrollbar it has no business having. Clip at the root, which is also what
   the bleed is meant to look like: cut at the edge of the window. `clip`, not
   `hidden` — hidden would make the root a scroll container and take the sticky
   navbar with it. This also covers the 100vw bands above 1729px, which used to
   clip here themselves; the mobile block still repeats it with a `hidden`
   fallback, for the iOS pan-gesture side of the same problem. */
html, body { overflow-x: clip; }
/* the reset is scoped to the design canvas so it cannot reach WordPress chrome
   (admin bar, plugin markup) that lives outside .page. The waitlist popup is
   the design's own markup printed outside .page (the canvas zoom must not
   scale it), so it joins the canvas here and in the typography below. */
.page, .page *, .page *::before, .page *::after,
.stock-popup, .stock-popup *, .stock-popup *::before, .stock-popup *::after,
.cart-drawer, .cart-drawer *, .cart-drawer *::before, .cart-drawer *::after {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

/* .page carries the fixed design canvas, so the same stylesheet works standalone
   and inside a WordPress template that owns <body>. */
/* The canvas scale. The inline script in parts/document-head.php sets the factor
   before the first paint and home.js keeps it in step on resize; until
   2026-09-15 home.js alone set it from the footer, so the page painted at the
   full 1728px and visibly shrank a moment later.

   `body > .page`, not `.page`: WordPress puts a `page` body class on every
   static Page, the front page included, so a bare `.page` matched the body as
   well and the two nested boxes multiplied their zoom. Product pages have no
   such body class, which is why only the Pages came out too small. */
body > .page { zoom: var(--canvas-zoom, 1); }

/* Plugins print their own boxes straight into the body (Complianz' consent
   link, the reCAPTCHA wrapper) and they come out at the design's 1728px, which
   stretched the body past the window and put a horizontal scrollbar under every
   page narrower than the canvas. Capping the body at the window costs the
   canvas nothing: it is already scaled to fit. */
body { max-width: 100%; }

.page {
  width: var(--page-width);
  margin: 0 auto;
  background: #fff;
  font-family: var(--font-body);
  /* Figma pins the optical size to 14 on every text node; letting the browser
     pick it by font-size makes the glyphs narrower and changes every line break. */
  font-optical-sizing: none;
  font-variation-settings: "opsz" 14;
  color: var(--dark-grey);
}
/* WordPress puts `page` on the body of every static page (the front page too), so
   the canvas rule above also narrowed that body to 1728px. With the root clip
   above, everything past it was cut: no bleeds and a banner running off the
   right edge on windows wider than the design. The body stays window-wide. */
body.page { width: auto; margin: 0; }
.stock-popup,
.cart-drawer {
  font-family: var(--font-body);
  font-optical-sizing: none;
  font-variation-settings: "opsz" 14;
  color: var(--dark-grey);
}

h1, h2, h3 {
  font-family: var(--font-display);
  font-weight: 600;
  color: var(--blue);
  font-variation-settings: "opsz" 14, "wdth" 100;
}
a { color: inherit; text-decoration: none; }
ul { list-style: none; }
button { font-family: inherit; cursor: pointer; border: none; background: none; }
input { font-family: inherit; border: none; outline: none; background: transparent; }
img { display: block; }
.accent { color: var(--green); }

/* --- type scale --------------------------------------------------------- */

.hero h1 { font-size: 72px; line-height: normal; letter-spacing: -2.88px; }
.brochure h2, .faq__heading, .services__heading {
  font-size: 60px; line-height: normal; letter-spacing: -2.4px;
}
.service-card h3 { font-size: 40px; line-height: normal; letter-spacing: -1.6px; }

/* --- shared components -------------------------------------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 16px 20px;
  border-radius: var(--radius-btn);
  background: var(--green);
  color: #fff;
  font-size: 18px;
  font-weight: 600;
  line-height: 26px;
  white-space: nowrap;
}
.btn--lg { padding: 20px 32px; }
.btn--sharp { border-radius: 2px; }
.btn--ghost { background: none; border: 1px solid rgba(255, 255, 255, 0.2); }

/* square icon button — nav, cart, carousel arrows, FAQ toggles */
.icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: 50px;
  height: 50px;
  border: 1px solid var(--light-blue);
  border-radius: var(--radius-btn);
  background: #fff;
}
.icon-btn--primary { background: var(--blue); border-color: var(--blue); }
.icon-btn--accent { background: var(--green); border-color: var(--green); }
/* the design has no disabled state, so an inactive arrow keeps its normal look */
.icon-btn.is-disabled { pointer-events: none; }
.icon-btn img { width: 24px; height: 24px; }
.btn img { width: 24px; height: 24px; }

/* slider dots */
.dot {
  width: 16px;
  height: 16px;
  border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, 0.6);
  background: transparent;
  transition: background-color 0.2s ease, border-color 0.2s ease;
}
.dot.is-active { background: #fff; border-color: #fff; }

/* --- interaction states -------------------------------------------------
   The Figma frame is a static mock: it specifies exactly one hover (the cart
   button on the second product card) and no focus or disabled states. These
   keep the page usable by keyboard and give every control feedback, without
   introducing any colour or shape the design does not already use. */

.btn { transition: background-color 0.2s ease, border-color 0.2s ease; }
.btn:hover { background: #00b895; }
.btn--ghost:hover { background: rgba(255, 255, 255, 0.08); border-color: rgba(255, 255, 255, 0.4); }
/* iOS Safari treats quick repeated taps on the same spot as a possible double-tap
   to zoom and holds every click back while it waits for the second tap, so
   stepping a quantity on a phone lagged by a beat per tap (Moritz, 2026-09-04).
   touch-action: manipulation switches the double-tap gesture off on the
   controls, so each tap is a click at once. */
.icon-btn,
.btn,
.qty__value { touch-action: manipulation; }
.icon-btn { transition: background-color 0.2s ease, border-color 0.2s ease; }
.icon-btn:hover { border-color: var(--light-grey); }
.icon-btn--primary:hover { background: #35317a; border-color: #35317a; }
.menu__list a,
.footer__col ul a { transition: color 0.2s ease; }
.menu__list a:hover { color: var(--green); }
.footer__col ul a:hover { color: var(--green); }
.product-card h3 a:hover { color: var(--green); }

:focus-visible {
  outline: 2px solid var(--green);
  outline-offset: 3px;
  border-radius: 2px;
}
.testimonials :focus-visible,
.footer :focus-visible,
.hero :focus-visible { outline-color: #fff; }
/* Text fields count as :focus-visible even on a mouse click, so the keyboard
   ring made every click into a field look like a state of its own. The ring
   stays for buttons and links; a field answers in its border instead — the
   box that has one, since some fields sit borderless inside a bordered form. */
input:focus-visible,
textarea:focus-visible,
select:focus-visible { outline: none; }
.field:focus-within,
.qty__value:focus,
.navbar__search input:focus,
.wissen__search input:focus,
.newsletter__form:focus-within,
.checkout.woocommerce-checkout .checkout-fields > .form-row .input-text:focus,
.checkout.woocommerce-checkout .checkout-fields > .form-row textarea:focus,
.checkout.woocommerce-checkout .checkout-fields > .form-row:focus-within {
  border-color: var(--light-grey);
}

@media (prefers-reduced-motion: reduce) {
  .page *,
  .page *::before,
  .page *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
  }
}

/* ==========================================================================
   Nav bar — 1728 × 104
   ========================================================================== */

/* The frame fixes the nav bar and the menu strip when it scrolls, so both stay
   on screen. Sticky rather than fixed: the 152px they take stay in the flow, so
   every section below keeps the y-coordinate the frame gives it.
   --sticky-top is the WordPress admin bar, measured by script.js — see there
   for why it cannot be a constant. */
.navbar {
  position: sticky;
  top: var(--sticky-top, 0px);
  z-index: 20;
  height: 104px;
  background: #fff;
  border-bottom: 1px solid var(--light-blue);
}

/* Going down the page the header steps out of the way, coming back up it
   returns. It is moved by a transform rather than by giving up its sticky box,
   so the page does not reflow while it scrolls and the two boxes are still
   there to come back to. script.js sets the class. */
.navbar,
.menu { transition: transform 0.3s ease; }
.is-header-hidden .navbar { transform: translateY(-100%); }
/* the strip rests 104px lower, so it travels its own height plus the bar's */
.is-header-hidden .menu { transform: translateY(-152px); }
.navbar__logo { position: absolute; left: 99px; top: 20px; }
.navbar__logo img { width: 203px; height: 64px; }

.navbar__search {
  position: absolute;
  left: 382px;
  top: 28px;
  display: flex;
  align-items: center;
  width: 680px;
  height: 48px;
}
.navbar__search input {
  flex: 1;
  height: 48px;
  padding: 4px 4px 4px 16px;
  border: 1px solid var(--light-blue);
  border-right: none;
  border-radius: 4px 0 0 4px;
  font-size: 16px;
  font-weight: 500;
  color: var(--dark-grey);
}
.navbar__search input::placeholder { color: var(--light-grey); }
.navbar__search-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  border-radius: 0 4px 4px 0;
  background: var(--green);
}

/* The FiboSearch form the navbar renders where the plugin is active — the
   live shop's search-as-you-type. The wrapper takes the field's box, the
   plugin's input takes the design input's clothes, its submit the green
   square; the suggestion panel keeps the plugin's own styling, which is
   what the live shop shows. */
.navbar__search--fibo .dgwt-wcas-search-wrapp,
.dgwt-wcas-om-bar .dgwt-wcas-search-wrapp { flex: 1; width: auto; max-width: none; }
.navbar__search--fibo .dgwt-wcas-search-form,
.dgwt-wcas-om-bar .dgwt-wcas-search-form { margin: 0; padding: 0; }
/* the plugin parks its magnifier inside the field's left; the design's sits
   on the green square the navbar adds beside the form */
.navbar__search--fibo .dgwt-wcas-ico-magnifier,
.dgwt-wcas-om-bar .dgwt-wcas-ico-magnifier { display: none; }
.navbar__search--fibo .dgwt-wcas-sf-wrapp,
.dgwt-wcas-om-bar .dgwt-wcas-sf-wrapp { display: flex; align-items: center; }
/* the plugin's own rule is .dgwt-wcas-sf-wrapp input[type=search]
   .dgwt-wcas-search-input — three classes and an element, 40px tall with
   40px of left padding for the magnifier hidden above. The wrapper class in
   front settles it, as the checkout's field selectors do. */
.navbar__search--fibo .dgwt-wcas-sf-wrapp input[type=search].dgwt-wcas-search-input,
.dgwt-wcas-om-bar .dgwt-wcas-sf-wrapp input[type=search].dgwt-wcas-search-input {
  flex: 1;
  height: 48px;
  margin: 0;
  padding: 4px 4px 4px 16px;
  border: 1px solid var(--light-blue);
  border-right: none;
  border-radius: 4px 0 0 4px;
  background: #fff;
  box-shadow: none;
  font-family: inherit;
  font-size: 16px;
  font-weight: 500;
  color: var(--dark-grey);
}
/* the plugin sets its placeholder italic in grey; the design's is upright */
.navbar__search--fibo .dgwt-wcas-sf-wrapp input[type=search].dgwt-wcas-search-input::placeholder,
.dgwt-wcas-om-bar .dgwt-wcas-sf-wrapp input[type=search].dgwt-wcas-search-input::placeholder {
  color: var(--light-grey);
  font-style: normal;
  font-weight: 500;
}
.navbar__search--fibo .dgwt-wcas-search-submit {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 48px;
  width: 48px;
  height: 48px;
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 0 4px 4px 0;
  background: var(--green);
}
.navbar__search--fibo .dgwt-wcas-search-submit:hover { background: var(--green); }
.navbar__search--fibo .dgwt-wcas-search-submit svg { width: 24px; height: 24px; }
.navbar__search--fibo .dgwt-wcas-search-submit svg path { fill: #fff; }

/* FiboSearch's own mobile overlay, which takes over below the plugin's 992px
   breakpoint: a white sheet over the page whose bar is a grey return block and
   a bare field. The bar carries the design's search box instead (918:4323 for
   the field, 918:4325 for the green square), so the rules above take it along
   and only the bar's own frame is set here. The margins are written out rather
   than taken from --page-margin: that token is 99px until the theme's own
   900px breakpoint, and the overlay is on for another 92px above it.

   The return button is `932:581`: a 48px white square with the light-blue
   border and a light-grey arrow, 16px before the box. Its 48 and that stand
   are what leave the box the 298px the frame draws (250 field + 48 square),
   and the plugin's own arrow is hidden for the asset. The green square is not
   in the plugin's markup at all (dgwt-wcas-no-submit), so home.js clones it in
   from the navbar, as parts/navbar.php puts it beside the form there. The
   stand is the return button's margin, not a gap on the row: the field and the
   green square are one box in the design and have to touch.

   The plugin's own overlay rules are written to beat a theme: two classes and
   the element for the return block, `!important` for the field's 45px and for
   all four sides of the panel. So the selectors here carry the sheet's class
   as well and repeat the !important where the plugin used one. */
.dgwt-wcas-om-bar {
  position: relative;
  display: flex;
  align-items: center;
  height: auto;
  /* the frame sets the row at 40 and the first heading at 112; the 40 above is
     the bar's, the 24 between belongs to the panel (see below) */
  padding: 40px 20px 0;
}
/* the plugin sizes its block at height:100%, which resolved against its own
   45px bar; this one is as tall as its content, so the square is named in full */
.dgwt-wcas-overlay-mobile .dgwt-wcas-om-bar button.dgwt-wcas-om-return {
  flex: 0 0 48px;
  width: 48px;
  height: 48px;
  margin-right: 16px;
  padding: 0;
  border: 1px solid var(--light-blue);
  border-radius: 4px;
  background: #fff url(assets/icon-arrow-left-grey.svg) center / 24px 24px no-repeat;
}
.dgwt-wcas-overlay-mobile .dgwt-wcas-om-bar button.dgwt-wcas-om-return svg { display: none; }
/* the plugin floors the overlay's field at 45px with an !important */
.dgwt-wcas-om-bar .dgwt-wcas-sf-wrapp input[type=search].dgwt-wcas-search-input { height: 48px !important; }

/* The plugin hangs the panel under a 45px bar and stretches it over the whole
   sheet, all with !important. This bar is taller and its height follows the
   frame, so the panel rides on it: the bar is the panel's containing block
   (position: relative above) and 100% is its lower edge. The inline max-height
   the plugin writes stays, that is the cap against the software keyboard and
   what gives the panel its scrollbar.

   The frame stands the rows straight on the white sheet, not on the desktop's
   card, so the panel sheds the frame, the radius and the shadow and runs edge
   to edge; the rows' own 20px inset is what puts them on the page's margins
   (Moritz, 2026-08-27). The panel's 8px above the first row plus the 16 the
   plugin reserves there make the frame's 24 between the box and the first
   heading, which is why the bar carries no bottom padding of its own. */
.dgwt-wcas-overlay-mobile .dgwt-wcas-om-bar .dgwt-wcas-suggestions-wrapp {
  top: 100% !important;
  left: 0 !important;
  right: 0;
  width: auto !important;
  height: auto !important;
  padding: 8px 0 24px;
  border: 0;
  border-radius: 0;
  box-shadow: none;
}

/* The frame's own scale for the rows: 15px section headings over a rule of
   their own, 18px rows, a 40px thumbnail, 8px between rows. The plugin's rules
   for these read ".dgwt-wcas-has-img .dgwt-wcas-suggestion.dgwt-wcas-suggestion-product",
   three classes, and the optimizer's load order relative to the theme varies
   between builds, so every selector here spells out both suggestion classes
   plus the `a`. The sheet's class in front keeps all of it off the desktop
   dropdown, which is a card by design. */
.dgwt-wcas-overlay-mobile a.dgwt-wcas-suggestion.dgwt-wcas-suggestion-headline,
.dgwt-wcas-overlay-mobile a.dgwt-wcas-suggestion.dgwt-wcas-suggestion-headline:not(:first-child) {
  /* the plugin gives the row `width: 100%`, so a horizontal margin is added to
     a box that already fills the panel and the panel scrolls sideways by those
     40px (reported from an iPhone, 2026-08-27). The rows below inset with
     padding and never had it; the heading needs the margin for its rule, so it
     gives up the width instead. */
  width: auto;
  margin: 20px 20px 8px;
  padding: 0 0 8px;
  border-top: 0;
  border-bottom: 1px solid var(--light-blue);
}
.dgwt-wcas-overlay-mobile a.dgwt-wcas-suggestion.dgwt-wcas-suggestion-headline:first-child { margin-top: 0; }
.dgwt-wcas-overlay-mobile a.dgwt-wcas-suggestion.dgwt-wcas-suggestion-headline .dgwt-wcas-st { font-size: 15px; }

.dgwt-wcas-overlay-mobile a.dgwt-wcas-suggestion.dgwt-wcas-suggestion-tax,
.dgwt-wcas-overlay-mobile a.dgwt-wcas-suggestion.dgwt-wcas-suggestion-pt {
  min-height: 0;
  margin: 0 0 8px;
  padding: 0 20px;
}
.dgwt-wcas-overlay-mobile a.dgwt-wcas-suggestion.dgwt-wcas-suggestion-tax strong,
.dgwt-wcas-overlay-mobile a.dgwt-wcas-suggestion.dgwt-wcas-suggestion-pt .dgwt-wcas-st {
  font-size: 18px;
  font-weight: 400;
  line-height: 26px;
}
/* the frame stacks the breadcrumb 4px under the name; the row is one block,
   so the gap is the breadcrumb's own margin */
.dgwt-wcas-overlay-mobile a.dgwt-wcas-suggestion.dgwt-wcas-suggestion-tax .dgwt-wcas-st-breadcrumbs {
  margin-top: 4px;
  line-height: 18px;
}

/* the plugin floors its rows at 52px, which would centre the 40px thumbnail in
   a 60px row and stretch the frame's 56px pitch to 68 */
.dgwt-wcas-overlay-mobile a.dgwt-wcas-suggestion.dgwt-wcas-suggestion-product {
  gap: 8px;
  min-height: 0;
  margin: 0 0 8px;
  padding: 4px 20px;
}
.dgwt-wcas-overlay-mobile a.dgwt-wcas-suggestion.dgwt-wcas-suggestion-product .dgwt-wcas-si {
  flex-basis: 40px;
  width: 40px;
  height: 40px;
  border-radius: 4px;
}
.dgwt-wcas-overlay-mobile a.dgwt-wcas-suggestion.dgwt-wcas-suggestion-product .dgwt-wcas-content-wrapp { gap: 8px; }
/* the frame truncates the long name rather than letting the row grow to two
   lines, which is what keeps the 56px row pitch */
.dgwt-wcas-overlay-mobile a.dgwt-wcas-suggestion.dgwt-wcas-suggestion-product .dgwt-wcas-st-title {
  display: block;
  overflow: hidden;
  font-size: 18px;
  font-weight: 400;
  line-height: 26px;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.dgwt-wcas-overlay-mobile a.dgwt-wcas-suggestion.dgwt-wcas-suggestion-product .dgwt-wcas-sp,
.dgwt-wcas-overlay-mobile a.dgwt-wcas-suggestion.dgwt-wcas-suggestion-product .dgwt-wcas-sp .amount,
.dgwt-wcas-overlay-mobile a.dgwt-wcas-suggestion.dgwt-wcas-suggestion-product .dgwt-wcas-sp .woocommerce-Price-currencySymbol {
  font-size: 18px;
  line-height: 26px;
}

/* no rule above "Alle Produkte ansehen" here — the frame draws one under each
   section heading instead, and only there */
.dgwt-wcas-overlay-mobile a.dgwt-wcas-suggestion.dgwt-wcas-suggestion-more {
  min-height: 0;
  margin: 16px 0 0;
  padding: 0 20px;
  border-top: 0;
}
.dgwt-wcas-overlay-mobile a.dgwt-wcas-suggestion.dgwt-wcas-suggestion-more .dgwt-wcas-st-more,
.dgwt-wcas-overlay-mobile a.dgwt-wcas-suggestion.dgwt-wcas-suggestion-more .dgwt-wcas-st-more-total {
  font-size: 15px;
  line-height: 20px;
}

/* The FiboSearch suggestion panel, dressed as the design's dropdown. The plugin
   appends this wrapper to the end of <body>, not inside .navbar__search--fibo,
   so these rules are unscoped — and the optimizer inlines both stylesheets in
   an order that varies, so anything contested must out-specify the plugin, not
   rely on load order. The details flyout on the right is ON in FiboSearch's
   settings (Figma 652-3761/652-3856) and styled further down; the SKU line
   stays hidden. Settings are flipped with tools/fibosearch-settings.py. */
.dgwt-wcas-suggestions-wrapp {
  padding: 6px 0;
  border: 1px solid var(--light-blue);
  border-radius: 8px;
  box-shadow: 0 12px 32px rgba(41, 38, 93, 0.12);
  background: #fff;
  font-family: var(--font-body);
  color: var(--blue);
}
.dgwt-wcas-suggestions-wrapp a.dgwt-wcas-suggestion,
.dgwt-wcas-suggestions-wrapp a.dgwt-wcas-suggestion:hover {
  border: 0;
  text-decoration: none;
}
/* the plugin underlines the row's inner spans on hover and on the selected
   suggestion (it auto-selects the first to feed the details flyout); the
   design highlights with the lilac wash instead, so no underline anywhere */
.dgwt-wcas-suggestions-wrapp a.dgwt-wcas-suggestion .dgwt-wcas-st,
.dgwt-wcas-suggestions-wrapp a.dgwt-wcas-suggestion .dgwt-wcas-st strong,
.dgwt-wcas-suggestions-wrapp a.dgwt-wcas-suggestion .dgwt-wcas-st-breadcrumbs,
.dgwt-wcas-suggestions-wrapp a.dgwt-wcas-suggestion:hover .dgwt-wcas-st,
.dgwt-wcas-suggestions-wrapp a.dgwt-wcas-suggestion:hover .dgwt-wcas-st strong,
.dgwt-wcas-suggestions-wrapp a.dgwt-wcas-suggestion:hover .dgwt-wcas-st-breadcrumbs {
  text-decoration: none;
}
/* section headings: grey, upper case, spaced */
.dgwt-wcas-suggestions-wrapp .dgwt-wcas-suggestion-headline {
  padding: 14px 20px 4px;
  pointer-events: none;
}
.dgwt-wcas-suggestions-wrapp .dgwt-wcas-suggestion-headline .dgwt-wcas-st {
  color: var(--grey);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
/* a thin rule opens every section but the first, and the "show all" row */
.dgwt-wcas-suggestions-wrapp .dgwt-wcas-suggestion-headline:not(:first-child),
.dgwt-wcas-suggestions-wrapp .dgwt-wcas-suggestion-more {
  border-top: 1px solid var(--divider);
  margin-top: 6px;
}
/* category rows: navy name over its grey breadcrumb */
.dgwt-wcas-suggestions-wrapp .dgwt-wcas-suggestion-tax {
  padding: 8px 20px;
}
.dgwt-wcas-suggestions-wrapp .dgwt-wcas-suggestion-tax .dgwt-wcas-st { display: block; }
.dgwt-wcas-suggestions-wrapp .dgwt-wcas-suggestion-tax strong {
  display: block;
  color: var(--blue);
  font-size: 16px;
  font-weight: 500;
}
.dgwt-wcas-suggestions-wrapp .dgwt-wcas-st-breadcrumbs {
  display: block;
  color: var(--grey);
  font-size: 13px;
  font-weight: 400;
}
/* product rows: thumbnail, navy name, navy bold price pinned right */
.dgwt-wcas-suggestions-wrapp .dgwt-wcas-suggestion-product {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 10px 20px;
}
.dgwt-wcas-suggestions-wrapp .dgwt-wcas-suggestion-product .dgwt-wcas-si {
  flex: 0 0 44px;
  width: 44px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 6px;
  border: 1px solid var(--light-blue);
  background: #fff;
  overflow: hidden;
}
/* The plugin's own stylesheet gives .dgwt-wcas-si img its own border, radius,
   padding and white background. Stacked inside our bordered box that reads as a
   second frame around the image, sometimes with a visible gap. Strip the
   plugin's frame so only our container border shows, per the design. */
.dgwt-wcas-suggestions-wrapp .dgwt-wcas-suggestion-product .dgwt-wcas-si img {
  max-width: 100%;
  max-height: 100%;
  width: auto;
  height: auto;
  border: 0;
  border-radius: 0;
  padding: 3px;
  background: none;
}
.dgwt-wcas-suggestions-wrapp .dgwt-wcas-content-wrapp {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}
.dgwt-wcas-suggestions-wrapp .dgwt-wcas-suggestion-product .dgwt-wcas-st { min-width: 0; }
.dgwt-wcas-suggestions-wrapp .dgwt-wcas-suggestion-product .dgwt-wcas-st-title {
  color: var(--blue);
  font-size: 15px;
  font-weight: 500;
}
.dgwt-wcas-suggestions-wrapp .dgwt-wcas-suggestion-product .dgwt-wcas-sku { display: none; }
.dgwt-wcas-suggestions-wrapp .dgwt-wcas-meta { flex: 0 0 auto; }
.dgwt-wcas-suggestions-wrapp .dgwt-wcas-sp,
.dgwt-wcas-suggestions-wrapp .dgwt-wcas-sp .amount,
.dgwt-wcas-suggestions-wrapp .dgwt-wcas-sp .woocommerce-Price-currencySymbol {
  color: var(--blue);
  font-size: 15px;
  font-weight: 700;
  white-space: nowrap;
}
/* post rows (Beiträge): navy single line, like the category names. The
   <strong> is FiboSearch's query highlight; the design shows no highlight, so
   it inherits the row weight instead of bolding. */
.dgwt-wcas-suggestions-wrapp .dgwt-wcas-suggestion-pt {
  padding: 8px 20px;
}
.dgwt-wcas-suggestions-wrapp .dgwt-wcas-suggestion-pt .dgwt-wcas-st {
  display: block;
  color: var(--blue);
  font-size: 15px;
  font-weight: 500;
}
.dgwt-wcas-suggestions-wrapp .dgwt-wcas-suggestion-pt .dgwt-wcas-st strong {
  font-weight: inherit;
}
/* the resting selection and hover: a faint lilac wash on the pickable rows.
   The plugin's own rule for the tax rows is
   ".dgwt-wcas-has-headings .dgwt-wcas-suggestion.dgwt-wcas-suggestion-tax:hover"
   (four classes, underline, transparent background), so these carry the
   has-headings class on the wrapper to outrank it whatever the inline order. */
.dgwt-wcas-suggestions-wrapp.dgwt-wcas-has-headings .dgwt-wcas-suggestion-tax:hover,
.dgwt-wcas-suggestions-wrapp.dgwt-wcas-has-headings .dgwt-wcas-suggestion-product:hover,
.dgwt-wcas-suggestions-wrapp.dgwt-wcas-has-headings .dgwt-wcas-suggestion-pt:hover,
.dgwt-wcas-suggestions-wrapp.dgwt-wcas-has-headings a.dgwt-wcas-suggestion.dgwt-wcas-suggestion-selected {
  background: rgba(239, 236, 249, 0.55);
  text-decoration: none;
}
.dgwt-wcas-suggestions-wrapp a.dgwt-wcas-suggestion-headline.dgwt-wcas-suggestion-selected,
.dgwt-wcas-suggestions-wrapp a.dgwt-wcas-suggestion-more.dgwt-wcas-suggestion-selected {
  background: none;
}
/* "Alle Produkte ansehen (n)": the design's green, centred and spaced */
.dgwt-wcas-suggestions-wrapp .dgwt-wcas-suggestion-more {
  padding: 14px 20px;
  text-align: center;
}
/* the extra class beats the plugin's own two-class colour rule, whose load
   order relative to the theme differs between the staging and live builds */
.dgwt-wcas-suggestions-wrapp a.dgwt-wcas-suggestion-more .dgwt-wcas-st-more,
.dgwt-wcas-suggestions-wrapp a.dgwt-wcas-suggestion-more .dgwt-wcas-st-more-total {
  color: var(--green);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

/* The details flyout (Figma 652-3761 category hover, 652-3856 product hover):
   FiboSearch renders it as a second body-level wrapper beside the suggestion
   panel, pre-filled with one .dgwt-wcas-details-inner pane per suggestion; the
   plugin toggles -active. The design fuses both into ONE box (652-3856): the
   plugin already places the flyout flush against the dropdown's right edge and
   writes the dropdown's height onto it inline, so the two halves stay equal —
   nothing here may add a margin or override that height. The dropdown's own
   right border is the vertical bar between the halves; home.js re-anchors the
   flyout under the canvas zoom the same way it does the dropdown. */
.dgwt-wcas-details-wrapp {
  border: 1px solid var(--light-blue);
  border-left: 0;
  border-radius: 0 8px 8px 0;
  box-shadow: 0 12px 32px rgba(41, 38, 93, 0.12);
  background: #fff;
  font-family: var(--font-body);
  color: var(--blue);
  box-sizing: border-box;
  /* a pane taller than the plugin-synced height scrolls instead of spilling */
  overflow-y: auto;
}
/* the flyout only exists above the plugin's 992px layout breakpoint; there the
   dropdown gives up its right radius so the pair reads as one rectangle */
@media (min-width: 993px) {
  .dgwt-wcas-suggestions-wrapp { border-radius: 8px 0 0 8px; }
  /* the dropdown's drop shadow would smear across the flyout's seam edge —
     clip it on the right; the flyout's own shadow closes the union's outline */
  .dgwt-wcas-suggestions-wrapp { clip-path: inset(-60px 0 -60px -60px); }
}
.dgwt-wcas-details-wrapp .dgwt-wcas-details-inner { padding: 18px 20px; }
/* category pane: "KATEGORIE: …" heading over that category's products */
.dgwt-wcas-details-wrapp .dgwt-wcas-datails-title {
  display: block;
  padding-bottom: 10px;
  border-bottom: 0; /* the plugin draws its own dotted rule; the rows' divider replaces it */
  color: var(--grey);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.dgwt-wcas-details-wrapp a.dgwt-wcas-tax-product-details {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 10px 0;
  border-top: 1px solid var(--divider);
  text-decoration: none;
}
.dgwt-wcas-details-wrapp .dgwt-wcas-tpd-image {
  flex: 0 0 56px;
  width: 56px;
  height: 56px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--light-blue);
  border-radius: 6px;
  background: #fff;
  overflow: hidden;
}
.dgwt-wcas-details-wrapp .dgwt-wcas-tpd-image img {
  max-width: 100%;
  max-height: 100%;
  width: auto;
  height: auto;
  border: 0;
  border-radius: 0;
  padding: 3px;
  background: none;
}
.dgwt-wcas-details-wrapp .dgwt-wcas-tpd-rest { min-width: 0; }
.dgwt-wcas-details-wrapp .dgwt-wcas-tpd-rest-title {
  display: block;
  color: var(--blue);
  font-size: 15px;
  font-weight: 500;
}
.dgwt-wcas-details-wrapp .dgwt-wcas-tpd-price,
.dgwt-wcas-details-wrapp .dgwt-wcas-tpd-price .amount,
.dgwt-wcas-details-wrapp .dgwt-wcas-tpd-price .woocommerce-Price-currencySymbol {
  color: var(--grey);
  font-size: 14px;
  font-weight: 400;
}
.dgwt-wcas-details-wrapp a.dgwt-wcas-details-more-products {
  display: block;
  padding: 14px 0 2px;
  border-top: 1px solid var(--divider);
  text-align: center;
  text-decoration: none;
  color: var(--green);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
/* product pane: large shot, display-face title, short description, price with
   the cart button beside it. The DOM puts the price above the description, the
   design below it — the column flex reorders, and the add-to-cart form anchors
   into the price row's right edge. */
.dgwt-wcas-details-wrapp .dgwt-wcas-details-main-image {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 200px;
  margin-bottom: 16px;
}
.dgwt-wcas-details-wrapp .dgwt-wcas-details-main-image img {
  max-width: 100%;
  max-height: 100%;
  width: auto;
  height: auto;
  border: 0;
  background: none;
}
.dgwt-wcas-details-wrapp .dgwt-wcas-details-inner-product .dgwt-wcas-details-space {
  display: flex;
  flex-direction: column;
  position: relative;
  padding: 0;
}
.dgwt-wcas-details-wrapp a.dgwt-wcas-details-product-title {
  order: 1;
  color: var(--blue);
  font-family: var(--font-display);
  font-size: 20px;
  font-weight: 600;
  line-height: 1.3;
  text-decoration: none;
}
.dgwt-wcas-details-wrapp a.dgwt-wcas-details-product-title:hover { color: var(--green); }
/* the premium template prints the SKU unconditionally; the design has none */
.dgwt-wcas-details-wrapp .dgwt-wcas-details-product-sku { display: none; }
.dgwt-wcas-details-wrapp .dgwt-wcas-details-hr { display: none; }
.dgwt-wcas-details-wrapp .dgwt-wcas-details-desc {
  order: 2;
  margin-top: 10px;
  color: var(--dark-grey);
  font-size: 14px;
  line-height: 1.5;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.dgwt-wcas-details-wrapp .dgwt-wcas-pd-price {
  order: 3;
  display: flex;
  align-items: center;
  min-height: 50px;
  margin-top: 16px;
  padding-right: 62px;
}
.dgwt-wcas-details-wrapp .dgwt-wcas-pd-price .amount,
.dgwt-wcas-details-wrapp .dgwt-wcas-pd-price .woocommerce-Price-currencySymbol {
  color: var(--blue);
  font-family: var(--font-display);
  font-size: 22px;
  font-weight: 500;
}
.dgwt-wcas-details-wrapp .dgwt-wcas-pd-addtc {
  position: absolute;
  right: 0;
  bottom: 0;
}
.dgwt-wcas-details-wrapp .dgwt-wcas-pd-addtc .quantity { display: none; }
/* the plugin's text link becomes the design's square cart button: the label
   collapses to nothing and the theme's cart glyph paints the face. The
   wrapper <p> carries class "product", which the single-product page styles
   with its lavender ground and 80/99 padding — reset all of that here. */
.dgwt-wcas-details-wrapp .dgwt-wcas-pd-addtc .add_to_cart_inline {
  margin: 0;
  padding: 0;
  background: none;
  width: auto;
}
.dgwt-wcas-details-wrapp .dgwt-wcas-pd-addtc a.add_to_cart_button {
  display: inline-flex;
  width: 50px;
  height: 50px;
  padding: 0;
  border: 1px solid var(--light-blue);
  border-radius: var(--radius-btn);
  background: #fff url(/wp-content/themes/farmula-redesign-v3/assets/icon-cart-nav.svg) center / 24px 24px no-repeat;
  font-size: 0;
  color: transparent;
  transition: border-color 0.2s ease;
}
.dgwt-wcas-details-wrapp .dgwt-wcas-pd-addtc a.add_to_cart_button:hover {
  border-color: var(--light-grey);
}
/* WooCommerce marks the button .loading while the AJAX add runs; the click's
   only other answer is the jump to the cart (home.js), so this dim is the
   feedback in between */
.dgwt-wcas-details-wrapp .dgwt-wcas-pd-addtc a.add_to_cart_button.loading {
  opacity: 0.4;
  pointer-events: none;
}
.dgwt-wcas-details-wrapp .dgwt-wcas-pd-addtc a.added_to_cart { display: none; }

.navbar__info {
  position: absolute;
  right: 298px;
  top: 31px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  font-size: 15px;
  font-weight: 500;
  color: var(--dark-grey);
  white-space: nowrap;
}
/* upper case in the Menu Open panel too, against its Figma frame (1380:2936), on request 2026-09-20 */
.navbar__code { color: var(--light-grey); text-transform: uppercase; }

.navbar__account { position: absolute; left: 1513px; top: 27px; }
.navbar__cart { position: absolute; left: 1579px; top: 27px; }
/* the desktop canvas shows the whole menu, so the hamburger only exists below
   the breakpoint — see the mobile block at the foot of this file */
.navbar__menu-btn { display: none; }
/* the phone's magnifier and the menu's account rows: the desktop bar shows
   the field and the account icon themselves */
.navbar__search-toggle { display: none; }
.menu__account { display: none; }
.navbar__cart-num {
  position: absolute;
  left: 32px;
  top: -8px;
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 26px;
  padding: 2px 8px;
  border-radius: 40px;
  background: var(--green);
  color: #fff;
  font-size: 16px;
  font-weight: 500;
}

/* ==========================================================================
   Menu — 1728 × 48
   ========================================================================== */

.menu {
  position: sticky;
  top: calc(var(--sticky-top, 0px) + 104px);
  z-index: 19;
  height: 48px;
  background: var(--light-blue);
}
.menu__list {
  display: flex;
  align-items: center;
  gap: 32px;
  height: 48px;
  padding-left: var(--page-margin);
}
.menu__list a {
  font-size: 16px;
  font-weight: 600;
  text-transform: uppercase;
  color: var(--blue);
}
.menu__konzept { display: flex; align-items: center; gap: 8px; }
.menu__konzept img { width: 24px; height: 24px; }

/* ==========================================================================
   Hero — 1728 × 600, two slides
   ========================================================================== */

/* touch-action: pan-y lets the browser scroll the page vertically but hands
   horizontal swipes to the slider's JS (script.js onSwipe), so a swipe switches
   the slide instead of dragging the whole page sideways. */
.hero { position: relative; height: 600px; background: #d9d9d9; touch-action: pan-y; }

.hero__slide {
  position: absolute;
  inset: 0;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.4s ease;
}
.hero__slide.is-active { opacity: 1; visibility: visible; }

.hero__media { position: absolute; top: 0; height: 600px; object-fit: cover; }
.hero__media--1 { right: 0; width: 1067px; }
.hero__media--2 { right: 0; width: 1138px; }

.hero__shape { position: absolute; left: 0; top: 0; height: 600px; }
.hero__shape--1 { width: 891px; }
.hero__shape--2 { width: 951px; }

.hero__content {
  position: absolute;
  left: 99px;
  top: 120px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 24px;
  width: 619px;
}
/* Light text on a dark ground blooms in the browser and reads heavier than
   Figma renders it; dropping one weight step matches the design's ink. */
.hero h1 { color: #fff; font-weight: 500; }
.hero__lead { font-size: 22px; line-height: 40px; color: #fff; }
.hero__konzept { display: inline-block; vertical-align: middle; margin-left: 12px; line-height: 0; transition: transform .15s ease; }
.hero__konzept:hover { transform: scale(1.08); }
.hero__konzept img { width: 24px; height: 24px; display: block; }

/* Slide 1 per frame 837:721 (2026-08-21): the angled shape gave way to a
   solid Sea-Blue panel with the 40px bottom-right radius; the panel is the
   content's own box, so its height follows the copy. The ground left of the
   video is the page's dark blue. The frame's 60px H1 stays on the site's
   compacted display scale instead (48px, end-of-file layer). */
.hero__slide--goal { background: var(--blue); }
/* the desktop H1 is the frame's full sentence; the phone shows the short
   variant instead, where the long one broke onto two lines and crowded the
   band (Moritz, 2026-08-21) */
.hero__title-short { display: none; }
.hero__slide--goal .hero__content {
  left: 0;
  top: 107px;
  width: 849px;
  padding: 40px 40px 40px 100px;
  background: var(--sea-blue);
  border-radius: 0 0 40px 0;
}

.hero__bullets { display: flex; flex-direction: column; gap: 16px; }
.hero__bullets li {
  display: flex;
  align-items: center;
  gap: 16px;
  font-size: 20px;
  line-height: 32px;
  color: #fff;
}
.hero__bullets li::before {
  content: "";
  width: 8px;
  height: 8px;
  flex: 0 0 8px;
  background: var(--green);
}

/* slide 2 product shot with the dark fade at its foot */
.hero__product {
  position: absolute;
  left: 621px;
  top: 382px;
  width: 302px;
  height: 231px;
  overflow: hidden;
}
.hero__product img {
  position: absolute;
  left: -14.81%;
  top: -27.04%;
  width: 130.29%;
  height: 152.34%;
  max-width: none;
}
.hero__product::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(to bottom, rgba(41, 38, 93, 0) 49.784%, rgba(41, 38, 93, 0.8) 100%);
}
.hero__off { position: absolute; left: 851px; top: 331px; width: 140px; height: 140px; }

.hero__dots { position: absolute; left: 99px; top: 544px; display: flex; gap: 12px; }

/* Trusted Shops seal — overhangs the hero into the section below, and links to
   the shop's review profile.
   The asset is generated: inc/trustedshops.php refreshes its rating daily, so
   the figures do not freeze at whatever they were the day the design was drawn.
   Its rounded corners live in the file's alpha channel, rebuilt from the Figma
   export, which is why nothing is clipped here. */
.hero__badge {
  position: absolute;
  display: block;
  left: 1595px;
  top: 483px;
  z-index: 2;
}
.hero__badge img { width: 93px; height: 157px; }

/* ==========================================================================
   Product carousel — track starts 96px left of the viewport
   ========================================================================== */

.products { position: relative; height: 698px; margin-top: 80px; }
.products__viewport { width: var(--page-width); height: 608px; overflow: hidden; }
.products__track {
  display: flex;
  gap: 30px;
  /* the first card starts on the page margin so it is never half-cut; the row
     bleeds off the right edge instead, which is where the arrows take over.
     Padding rather than a transform, because the transform is what the script
     animates — this way each canvas states its own resting offset in CSS. */
  padding-left: var(--page-margin);
  transition: transform 0.4s ease;
}

.product-card {
  position: relative;
  flex: 0 0 360px;
  width: 360px;
  height: 608px;
  background: #fff;
  border: 1px solid var(--light-blue);
  border-radius: var(--radius-card) var(--radius-card) var(--radius-card) 0;
  box-shadow: var(--shadow-card);
}
.product-card__img {
  position: absolute;
  left: 20px;
  top: 20px;
  width: 320px;
  height: 320px;
  /* contain, not cover: WooCommerce serves the thumbnail uncropped (the
     shop's cropping is "uncropped" since 2026-09-03), so a tall cartridge or
     a wide hoof block shows whole in the square instead of a centre slice */
  object-fit: contain;
}
.product-card__tag {
  position: absolute;
  left: 20px;
  top: 20px;
  padding: 10px 20px;
  border-radius: 40px;
  background: var(--tag);
  color: var(--tag-text);
  font-size: 14px;
  font-weight: 600;
  text-transform: uppercase;
}
/* Every title in the mock is one line; the real catalogue has plenty that wrap
   to two. The price row is therefore pinned to the foot of the card and the text
   above it clamped, so a long name can never push the price out of the card. */
.product-card__info {
  position: absolute;
  left: 24px;
  right: 24px;
  top: 364px;
  bottom: 86px;
  display: flex;
  flex-direction: column;
  gap: 16px;
  overflow: hidden;
}
/* the category and title keep their full height; the description is the element
   that gives way, so a two-line product name is never cut mid-word */
.product-card__cat,
.product-card h3 { flex: 0 0 auto; }
.product-card h3,
.product-card__desc {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
/* capped at two whole lines so the text never ends on a half-cut line */
.product-card__desc { flex: 0 1 auto; min-height: 0; max-height: 52px; }
/* Frame 638:373 (2026-08-06) rebuilds the shop card as the v2 card, and its
   13px description fits where the old 18px one was sliced mid-line — the
   reason the grid dropped it. The card's own rules live with .shop__grid
   below the grid definition. */
.product-card__cat {
  font-size: 14px;
  font-weight: 600;
  text-transform: uppercase;
  color: var(--light-grey);
  /* the eyebrow always stays on one line: a doubled category like
     "Darmgesundheit · Darmgesundheit" would otherwise wrap to two lines and
     push the title and price down, breaking card alignment in the slider */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.product-card h3 { font-size: 28px; line-height: 40px; }
.product-card__desc { font-size: 18px; line-height: 26px; }
.product-card__row {
  position: absolute;
  left: 24px;
  right: 24px;
  bottom: 36px;
  display: flex;
  align-items: center;
  justify-content: space-between;
}
/* WooCommerce hangs a "Warenkorb anzeigen" link on the button after an AJAX
   add. The card has no room for it — it lands beside the plus and pushes the
   price sideways — and the badge in the header is what says the add worked.
   `.woocommerce a.added_to_cart` is two classes and an element, so this is
   three and an element. */
.page .product-card a.added_to_cart { display: none; }
.product-card__price { display: flex; align-items: center; gap: 7px; width: 184px; }
.product-card__price { flex-wrap: wrap; row-gap: 0; }
.product-card__price .farmula-b2b-label { flex-basis: 100%; line-height: 18px; }
.product-card__vat { flex-basis: 100%; font-size: 14px; line-height: 18px; color: var(--grey); }
.price {
  font-family: var(--font-display);
  font-size: 24px;
  font-weight: 500;
  line-height: 36px;
  color: var(--blue);
}
.price--old { color: var(--light-grey); text-decoration: line-through; }

/* the design shows card 2 with the cart button hovered */
.product-card .icon-btn:hover { background: var(--green); border-color: var(--green); }
.product-card .icon-btn:hover img { filter: brightness(0) invert(1); }

/* WooCommerce flags the button with `loading` while the AJAX add runs.
   Staging answers in ~2s, and a button that shows nothing for two seconds
   reads as dead — so the click is acknowledged at once: the glyph gives way
   to a ring until the shop answers, and the slide-in cart opens. */
.product-card .icon-btn { position: relative; }
.product-card .icon-btn.loading { pointer-events: none; }
.product-card .icon-btn.loading img { opacity: 0; }
.product-card .icon-btn.loading::after {
  content: '';
  position: absolute;
  width: 20px;
  height: 20px;
  border: 2px solid var(--light-blue);
  border-top-color: var(--blue);
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
.products__arrows {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  justify-content: center;
  gap: 20px;
}
.products__prev img { transform: scaleX(-1); }

/* --- v2 carousel (frame 548:203, home only) --------------------------------
   The row is a run of 282px cards that bleeds off both edges of the canvas
   under a white fade, with the arrows floating over the fades. The related
   carousel on the product page and the shop grid keep the previous card —
   their frames have not changed. */

.products--v2 { height: 570px; margin-top: 64px; }
.products--v2 .products__viewport { width: 100%; height: 570px; padding-top: 16px; }
/* no resting padding: script.js centers the row when the padding is 0 */
.products--v2 .products__track { gap: 20px; padding-left: 0; }
/* The home row of 2026-08-31 (837:620: 1080:4684 sale, 837:675 sold out,
   837:686 two-line name) draws a smaller tile: 280 x 476, the shot 200px
   and centred, the name in the 18/26 body bold, a three-line description
   back under it (revision 571:1744 had dropped it). 20 + 200 + 12 + (18 + 12
   + 52 + 12 + 51 + 12 + 17 = 174 at most) + row 50 + 20; the row rests at
   405 like the frame's. The tick rows stay off the desktop card. */
.products--v2 .product-card { flex: 0 0 280px; width: 280px; height: 476px; }
/* Figma aligns the stroke inside the frame, so its 21px inset is our 20px
   padding plus the border */
.products--v2 .product-card__img { left: 40px; top: 20px; width: 200px; height: 200px; }
.products--v2 .product-card__info { left: 20px; right: 20px; top: 232px; bottom: 68px; gap: 12px; }
.products--v2 .product-card h3 { font-size: 24px; line-height: 36px; height: 72px; }
@media (min-width: 901px) {
  .products--v2 .product-card h3 {
    height: auto;
    max-height: 52px;
    font-family: var(--font-body);
    font-size: 18px;
    line-height: 26px;
    font-weight: 700;
  }
}
.products--v2 .product-card__desc {
  display: -webkit-box;
  -webkit-line-clamp: 3;
  font-size: 13px;
  line-height: 17px;
  font-weight: 500;
  max-height: 51px;
}
.products--v2 .product-card__ticks { display: none; }
.products--v2 .product-card__row { left: 20px; right: 20px; bottom: 20px; }

/* The after-add state (green check + "Im Warenkorb" in the price row, frame
   571:1744) is the answer to an add wherever the slide-in cart is not
   installed: prod ran without inc/cart-drawer.php while staging had it, and
   the 2026-09-08 removal of these rules reached prod with the next home.css
   deploy, so cards there acknowledged nothing (Moritz, 2026-09-10). The
   rules below are gated on the drawer's absence; with .cart-drawer in the
   document they are inert and the drawer is the acknowledgement. */
.page a.added_to_cart { display: none; }
/* WooCommerce flags the button with `loading` while the AJAX add runs and
   with `added` once it lands. Staging answers in ~2s, and a button that shows
   nothing for two seconds reads as dead — so the click is acknowledged at
   once: the glyph gives way to a ring until the shop answers. Carousel and
   grid then show the frame's Im-Warenkorb state (further down, with the v2
   card); the article shortcode's card keeps its view-cart link hidden, so
   there the `added` check on the button is the acknowledgement. */
body:not(:has(.cart-drawer)) .wb-products .product-card .icon-btn.added img { display: none; }
body:not(:has(.cart-drawer)) .wb-products .product-card .icon-btn.added::after {
  content: '';
  width: 24px;
  height: 24px;
  background: url(assets/icon-check.svg) no-repeat center / 24px;
}
/* hovered, the button turns green — a green check on it would vanish */
body:not(:has(.cart-drawer)) .wb-products .product-card .icon-btn.added:hover {
  background: #fff;
  border-color: var(--light-blue);
}

/* After an AJAX add the card shows the state frame 571:1744 draws, on the
   carousel and (since 2026-08-06, Moritz) the shop grid alike: the price
   gives way to a green check + "Im Warenkorb" — WooCommerce's own view-cart
   link, renamed in inc/cart-badge.php and unhidden here against the .page
   rule that hides it everywhere else — and the frame's green arrow square
   sits at the row's end. The whole row is that one link into the cart; the
   re-add button steps aside, so the state cannot re-add. */
body:not(:has(.cart-drawer)) .products--v2 .product-card__row:has(.added_to_cart) .product-card__price,
body:not(:has(.cart-drawer)) .shop__grid .product-card__row:has(.added_to_cart) .product-card__price,
body:not(:has(.cart-drawer)) .products--v2 .product-card__row:has(.added_to_cart) .icon-btn,
body:not(:has(.cart-drawer)) .shop__grid .product-card__row:has(.added_to_cart) .icon-btn,
body:not(:has(.cart-drawer)) .product__buy:has(a.added_to_cart) .product__cart { display: none; }
body:not(:has(.cart-drawer)) .page .products--v2 .product-card a.added_to_cart,
body:not(:has(.cart-drawer)) .page .shop__grid .product-card a.added_to_cart,
body:not(:has(.cart-drawer)) .page .product__buy a.added_to_cart {
  display: flex;
  align-items: center;
  flex: 1;
  gap: 8px;
  font-size: 18px;
  font-weight: 600;
  line-height: 26px;
  color: var(--green);
}
body:not(:has(.cart-drawer)) .page .products--v2 .product-card a.added_to_cart::before,
body:not(:has(.cart-drawer)) .page .shop__grid .product-card a.added_to_cart::before,
body:not(:has(.cart-drawer)) .page .product__buy a.added_to_cart::before {
  content: '';
  flex: 0 0 24px;
  height: 24px;
  background: url(assets/icon-check.svg) no-repeat center / 24px;
}
body:not(:has(.cart-drawer)) .page .products--v2 .product-card a.added_to_cart::after,
body:not(:has(.cart-drawer)) .page .shop__grid .product-card a.added_to_cart::after,
body:not(:has(.cart-drawer)) .page .product__buy a.added_to_cart::after {
  content: '';
  flex: 0 0 50px;
  height: 50px;
  margin-left: auto;
  border-radius: var(--radius-btn);
  background: var(--green) url(assets/arrow-carousel.svg) no-repeat center / 24px;
}
/* the card under the frame's cursor annotation carries the deeper shadow */
.products--v2 .product-card:hover { box-shadow: 0 4px 16px rgba(34, 36, 36, 0.08), 0 2px 1px rgba(34, 36, 36, 0.02); }

.product-card__ticks {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin: 0;
  padding: 0;
  list-style: none;
}
.product-card__ticks li {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  line-height: 17px;
  font-weight: 500;
  color: var(--dark-grey);
}
.product-card__ticks img { flex: 0 0 16px; }

.products--v2::before,
.products--v2::after {
  content: '';
  position: absolute;
  top: 0;
  bottom: 0;
  width: 180px;
  z-index: 1;
  pointer-events: none;
}
.products--v2::before { left: 0; background: linear-gradient(to right, #fff, rgba(255, 255, 255, 0)); }
.products--v2::after { right: 0; background: linear-gradient(to left, #fff, rgba(255, 255, 255, 0)); }

.products--v2 .products__arrows { position: static; }
/* on the card's vertical middle: 16px viewport padding + 476 / 2 - 25 */
.products--v2 .products__arrows .icon-btn { position: absolute; top: 229px; z-index: 2; }
/* home.js hides both when the row fits the viewport; .icon-btn's inline-flex
   would otherwise beat the attribute */
.products__arrows .icon-btn[hidden] { display: none; }
.products--v2 .products__prev { left: 20px; }
.products--v2 .products__next { right: 20px; }

/* ==========================================================================
   Testimonials — 1728 × 520, dark band
   ========================================================================== */

.testimonials {
  position: relative;
  height: 520px;
  /* revision 571:1744 pulls the band up to two pixels under the fades */
  margin-top: 2px;
  background: var(--blue);
  /* horizontal swipes drive the slider (script.js), not a sideways page drag */
  touch-action: pan-y;
}

.testimonials__video { position: absolute; left: 99px; top: 80px; width: 490px; height: 360px; }
/* direct child only — the play button nests its own icon in here */
.testimonials__video > img {
  width: 490px;
  height: 360px;
  object-fit: cover;
  border-radius: var(--radius-card) 0 0 0;
}
/* The reel is portrait and the tile is not, so it does not play in the tile:
   the play button opens a lightbox where the video stands near full height.
   The overlay's markup sits outside .page — the canvas zoom above the
   breakpoint must not scale it — and closes on the button, the backdrop and
   Escape, stopping the video as it goes. */
.video-lightbox {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(10, 9, 30, 0.85);
}
.video-lightbox[hidden] { display: none; }
.video-lightbox__player {
  max-height: 90vh;
  max-width: 90vw;
  border-radius: 8px;
  background: #000;
}
.video-lightbox__close {
  position: absolute;
  top: 24px;
  right: 24px;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 50px;
  height: 50px;
  padding: 0;
  border: 1px solid rgba(255, 255, 255, 0.3);
  border-radius: 4px;
  background: none;
}
/* the close glyph is navy; on the dark backdrop it turns white */
.video-lightbox__close img { filter: brightness(0) invert(1); }
.video-lightbox__close:hover { border-color: rgba(255, 255, 255, 0.7); }
.testimonials__play {
  position: absolute;
  left: 205px;
  top: 140px;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 80px;
  height: 80px;
  border-radius: 8px;
  background: var(--green);
  box-shadow: 0 0 40px rgba(0, 0, 0, 0.8);
}
.testimonials__play img { width: 40px; height: 40px; }

.testimonials__body {
  position: absolute;
  left: 619px;
  top: 80px;
  display: flex;
  align-items: flex-start;
  gap: 16px;
  width: 1010px;
}
.testimonials__quote { flex: 0 0 auto; width: 29.44px; height: 19.92px; }
.testimonials__col { display: flex; flex-direction: column; gap: 28px; flex: 1; }

.testimonials blockquote {
  font-size: 48px;
  font-style: italic;
  line-height: normal;
  letter-spacing: -1.92px;
  color: #fff;
  font-weight: 350;
}
.testimonials__meta { display: flex; align-items: center; justify-content: space-between; }
.testimonials__author { display: flex; flex-direction: column; gap: 8px; }
.testimonials__name { font-size: 22px; line-height: 40px; color: #fff; }
.testimonials__place {
  font-size: 14px;
  font-weight: 600;
  text-transform: uppercase;
  color: var(--light-grey);
}
.testimonials__line { border: none; border-top: 1px solid rgba(255, 255, 255, 0.2); }
/* A slide is a wrapper without a box: display: contents leaves the tile and
   the body laid out exactly as before, and hiding the wrapper hides the voice.
   Each slide carries its own copy of the dots, in flow under its own rule —
   a voice without a story button is shorter, and a pinned dots row would hang
   below its rule. script.js keeps the copies in step. */
.testimonials__slide { display: none; }
.testimonials__slide.is-active { display: contents; }
.testimonials__dots { display: flex; gap: 12px; }

/* ==========================================================================
   Services — 1728 × 1016, lilac band with a rounded bottom-right corner
   ========================================================================== */

.services {
  height: 1016px;
  padding-top: 100px;
  background: var(--light-blue);
  border-radius: 0 0 80px 0;
}
.services__heading { text-align: center; }
.services__grid {
  display: grid;
  grid-template-columns: 750px 750px;
  gap: 40px 30px;
  margin: 64px 0 0 var(--page-margin);
}

.service-card {
  position: relative;
  display: flex;
  width: 750px;
  height: 320px;
  background: #fff;
  border: 1px solid var(--light-blue);
  border-radius: var(--radius-card) var(--radius-card) var(--radius-card) 0;
  box-shadow: var(--shadow-card);
  overflow: hidden;
}
.service-card__img {
  position: relative;
  flex: 0 0 320px;
  width: 320px;
  height: 320px;
  border-radius: var(--radius-card) 0 0 0;
  overflow: hidden;
}
.service-card__img > img:first-child {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.service-card__img--mirror > img:first-child { transform: scaleX(-1); }
/* the photo fades into the card instead of ending on a hard edge */
.service-card__img::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(to left, #fff 0%, rgba(255, 255, 255, 0) 50%);
}
.service-card__icon {
  position: absolute;
  right: 20px;
  bottom: 20px;
  z-index: 1;
  width: 64px;
  height: 64px;
}
.service-card__icon--circle {
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--blue);
}
.service-card__icon--circle img { width: 37px; height: 37px; }
.service-card__text {
  display: flex;
  flex-direction: column;
  gap: 16px;
  width: 382px;
  margin: 40px 0 0 24px;
}
.service-card__text p { font-size: 18px; line-height: 26px; }

/* ==========================================================================
   Unser Team (1497:2125) — replaced "Über Farmula" on 2026-10-08
   The home carousel's bleeding row and arrows (.products--v2, home.js) with
   bare 280px portraits instead of the product card (revision of 2026-10-08:
   no card box, no shadow, only the photo's top-left corner rounded).
   ========================================================================== */

.team__heading { margin-top: 48px; }
/* 32 between heading and portraits; nothing casts a shadow, so the viewport
   needs none of the product row's padding. h2 in the selector: the related
   row's `.products__heading + .products--v2` comes later and would win. */
h2.team__heading + .team { height: auto; margin-top: 32px; }
.team .products__viewport { height: auto; padding: 0; }
/* The frame rests the row centred like the product row, which leaves the
   first portrait half under the left fade. Lars leads the team (Moritz,
   2026-10-08), so the row rests on the page margin instead; home.js reads
   the non-zero padding as "not centred" and starts with the back arrow off. */
.team .products__track { gap: 24px; padding-left: var(--page-margin); }
.team-card { flex: 0 0 280px; }
.team-card__img {
  width: 280px;
  height: 400px;
  object-fit: cover;
  border-radius: var(--radius-card) 0 0 0;
}
/* no portrait in the theme: the initials hold the photo's place */
.team-card__img--empty {
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--light-blue);
  color: var(--blue);
  font-family: var(--font-display);
  font-size: 72px;
  font-weight: 600;
  letter-spacing: -2.88px;
}
.team-card__name {
  margin: 12px 0 0;
  font-family: var(--font-body);
  font-size: 18px;
  line-height: 26px;
  font-weight: 700;
  color: var(--blue);
}
.team-card__role { margin: 4px 0 0; font-size: 15px; line-height: 20px; color: var(--dark-grey); }
/* where the frame parks them: 236 below the portraits' top edge */
.team .products__arrows .icon-btn { top: 236px; }

/* ==========================================================================
   Broschüre + Newsletter — 1728 × 816
   ========================================================================== */

.brochure {
  position: relative;
  height: 816px;
  margin-top: 80px;
  background: var(--light-blue);
  border-radius: 80px 0 0 0;
  /* the watermark logo is masked by the band in Figma (571:1857 sits 10px
     above and 65px past its edge); a clip-path instead of overflow:hidden so
     the wide-screen ::before band can still run out to the viewport edges */
  clip-path: inset(0 calc(-1 * var(--bleed, 0px)));
}
.brochure__vector { position: absolute; right: -65px; top: -10px; width: 484px; height: 279px; }

.brochure__intro {
  position: absolute;
  left: 99px;
  top: 80px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 32px;
  width: 880px;
}
.brochure__intro p { font-size: 18px; line-height: 26px; }

.newsletter {
  position: absolute;
  left: 99px;
  top: 392px;
  display: flex;
  flex-direction: column;
  gap: 24px;
  width: 880px;
  height: 344px;
  padding: 40px 56px 40px 47px;
  background: #fff;
  border: 1px solid var(--light-blue);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-card);
}
.newsletter h3 { font-size: 28px; line-height: 40px; }
.newsletter__text { display: flex; flex-direction: column; gap: 16px; }
.newsletter__text p { font-size: 18px; line-height: 26px; }
.newsletter__form {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 4px 4px 4px 24px;
  border: 1px solid var(--light-blue);
  border-radius: var(--radius-btn);
  background: #fff;
}
.newsletter__form input { flex: 1; height: 58px; font-size: 16px; }
.newsletter__form input::placeholder { color: var(--light-grey); }

.brochure__cover { position: absolute; left: 1069px; top: 100px; }
.brochure__book { width: 490px; height: 585px; object-fit: cover; }
.brochure__shadow {
  position: absolute;
  left: 135.73px;
  top: 572.8px;
  width: 217.17px;
  height: 14.93px;
}

/* ==========================================================================
   FAQ — 1728 × 1254
   ========================================================================== */

.faq { position: relative; margin-top: 80px; padding: 0 var(--page-margin); }
.faq__heading { line-height: 72px; }
.faq__list { display: flex; flex-direction: column; gap: 40px; margin-top: 40px; }

/* the separators are drawn as pseudo-elements: in Figma they are zero-height
   strokes, so a real border would push every following section down by 1px */
.faq__item { position: relative; padding-top: 40px; }
.faq__item::before,
.faq__contact::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  width: 1530px;
  border-top: 1px solid var(--divider);
}
/* The row keeps a constant 50px height in both states so that opening an answer
   never shifts the question itself — only the answer below it animates. */
.faq__item summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  min-height: 50px;
  cursor: pointer;
  list-style: none;
}
.faq__item summary::-webkit-details-marker { display: none; }
.faq__item summary h3 { flex: 1; max-width: 1280px; font-size: 28px; line-height: 40px; }

/* Open/closed styling is driven by [open], not by the markup, so every toggle
   animates the same way whichever item the visitor clicks. */
.faq__toggle {
  position: relative;
  transition: background-color 0.3s ease, border-color 0.3s ease;
}
.faq__item[open] .faq__toggle { background: var(--blue); border-color: var(--blue); }
.faq__toggle img {
  position: absolute;
  transition: opacity 0.3s ease, transform 0.3s ease;
}
.faq__toggle-open { opacity: 0; }
.faq__toggle-closed { opacity: 1; transform: scaleY(-1); }
.faq__item[open] .faq__toggle-open { opacity: 1; }
.faq__item[open] .faq__toggle-closed { opacity: 0; transform: none; }

/* padding rather than margin: the height animation has to include the gap */
.faq__answer {
  display: flex;
  flex-direction: column;
  gap: 26px;
  width: 1280px;
  padding-top: 14px;
  overflow: hidden;
}
.faq__answer p { font-size: 18px; line-height: 26px; }

.faq__contact {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 12px;
  width: 750px;
  margin-top: 40px;
  padding: 24px;
  border-radius: 16px;
  background: var(--light-blue);
}
/* the separator sits 40px above the box, not on its edge */
.faq__contact::before { top: -40px; }
.faq__contact h3 { font-size: 28px; line-height: 40px; }
.faq__contact p { font-size: 18px; line-height: 26px; }

/* ==========================================================================
   Footer — 1728 × 768 (648 main + 120 bottom bar)
   ========================================================================== */

.footer { margin-top: 100px; }
.footer__main {
  position: relative;
  height: 648px;
  background: var(--blue);
  color: #fff;
}
.footer__col { position: absolute; top: 100px; }
.footer__col--brand { left: 99px; }
.footer__logo { width: 240px; height: 75px; }
.footer__contact {
  display: flex;
  flex-direction: column;
  gap: 12px;
  width: 261px;
  margin-top: 40px;
  font-size: 16px;
  font-weight: 500;
}
.footer__col--info { left: 489px; }
.footer__col--legal { left: 879px; }
.footer__col--last { left: 1269px; display: flex; flex-direction: column; gap: 40px; }

.footer__col h3 { font-size: 28px; line-height: 40px; color: #fff; font-weight: 500; }
.footer__col ul {
  display: flex;
  flex-direction: column;
  gap: 12px;
  width: 261px;
  margin-top: 24px;
  font-size: 16px;
  font-weight: 500;
}

.footer__block { display: flex; flex-direction: column; gap: 24px; }
.footer__social { display: flex; align-items: center; gap: 20px; }
.footer__tiles { display: flex; flex-wrap: wrap; gap: 20px; width: 360px; }
.footer__tile {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100px;
  height: 44px;
  border-radius: 8px;
  background: #fff;
  overflow: hidden;
}

.footer__bottom {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 120px;
  padding: 0 var(--page-margin);
  background: var(--sea-blue);
  color: #fff;
}
.footer__bottom p { font-size: 14px; font-weight: 500; opacity: 0.5; }
.footer__badges { display: flex; align-items: center; gap: 24px; }
.footer__badges img { width: 50px; height: 50px; }

/* ==========================================================================
   Shop / Products — Figma frame "Products" (377:101), 1728 × 5205
   ========================================================================== */

/* the shop page closes tighter under the last section than the home page does */
.page--shop .footer { margin-top: 80px; }

.breadcrumbs {
  display: flex;
  align-items: center;
  gap: 16px;
  margin: 40px 0 0 var(--page-margin);
  font-size: 16px;
  font-weight: 500;
  color: var(--blue);
}
.breadcrumbs img { width: 16px; height: 16px; }
.breadcrumbs a:hover { color: var(--green); }
/* the page you are already on is greyed out */
.breadcrumbs span { color: var(--light-grey); }

/* The height follows the grid rather than being pinned, because the number of
   products is the shop's to decide — at the design's twelve it comes to the
   frame's 2700px. Only the sidebar is taken out of flow; the main column keeps
   its place in it so it can push the section open. */
/* The sidebar is position:absolute, so it does not stretch .shop. Reserve at
   least the category list's height (48px per row: 36px line + 12px gap, plus a
   24px tail) so a sparse category no longer lets the next section overlap it.
   --shop-cats-count is set on .shop in archive-product.php; without it the
   expression falls back to the original 708px floor. */
.shop { position: relative; margin-top: 80px; min-height: max(708px, calc(var(--shop-cats-count, 0) * 48px + 24px)); }
.shop__side { position: absolute; left: var(--page-margin); top: 0; width: 211px; }
.shop__main { margin-left: 489px; width: 1140px; }

.shop-cats { display: flex; flex-direction: column; gap: 12px; }
.shop-cats a {
  display: flex;
  align-items: center;
  gap: 12px;
  font-family: var(--font-display);
  font-size: 24px;
  font-weight: 500;
  line-height: 36px;
  color: var(--blue);
  white-space: nowrap;
}
.shop-cats__dot { width: 8px; height: 8px; flex: 0 0 8px; background: var(--blue); }
/* the active state colours only its own row: the expanded subcategory list
   nests inside the parent <li>, so a descendant selector would flood it */
.shop-cats a:hover,
.shop-cats li.is-active > a { color: var(--green); }
.shop-cats a:hover .shop-cats__dot,
.shop-cats li.is-active > a .shop-cats__dot { background: var(--green); }
/* subcategories of the active top-level entry, indented under it */
.shop-cats__sub { display: flex; flex-direction: column; gap: 6px; margin: 8px 0 4px 20px; }
.shop-cats__sub a { font-size: 17px; line-height: 26px; gap: 10px; }
.shop-cats__sub .shop-cats__dot { width: 6px; height: 6px; flex: 0 0 6px; }
/* a partner brand's landing page, first in its category's list with the
   brand's logo after the name (1204:3704, inc/brand-pages.php) */
.shop-cats__brand-logo { width: 70px; height: 20px; margin-left: 4px; object-fit: contain; }

.shop__head { display: flex; align-items: center; justify-content: space-between; height: 48px; }
.shop__head h1 { font-size: 40px; line-height: normal; letter-spacing: -1.6px; }
.shop__sort { display: flex; align-items: center; justify-content: flex-end; gap: 12px; }
.shop__sort p { font-size: 18px; font-weight: 600; line-height: 26px; }
/* A real <select>: the frame draws a field with a chevron, and a native control
   keeps the shop sortable by keyboard and without JS. The chevron is the
   background rather than a child, since a select cannot hold one. */
.shop__sort-field {
  appearance: none;
  width: 280px;
  height: 48px;
  padding: 12px 44px 12px 12px;
  border: 1px solid var(--light-blue);
  border-radius: 8px;
  background: #fff url(assets/icon-sort.svg) no-repeat right 12px center;
  background-size: 24px 24px;
  font-family: inherit;
  font-size: 16px;
  font-weight: 500;
  color: var(--dark-grey);
  cursor: pointer;
  transition: border-color 0.2s ease;
}
.shop__sort-field:hover { border-color: var(--light-grey); }

.shop__empty { grid-column: 1 / -1; font-size: 20px; line-height: 32px; }
/* the reset strips colour and underline from every link, so the way back
   to the catalogue needs both put back here */
.shop__empty a { color: var(--green); text-decoration: underline; }
/* the desktop canvas shows the categories as a sidebar, so the control that
   folds them out only exists below the breakpoint */
.shop__filter-btn { display: none; position: relative; }

.shop__grid {
  display: grid;
  grid-template-columns: repeat(3, 364px);
  gap: 24px;
  margin-top: 40px;
}

/* Frame 638:373 (2026-08-06): the shop card is the v2 card at 364 × 505 — the
   240px shot centred, 24/36 name, the 13px description back in two lines or
   up to three tick rows, the price row on the foot. Laid out in flow like the
   cart's cross-sells: position: static switches the base card's offsets off,
   and the info block takes the slack so the row stays put under names of any
   length. .wb-products — an article's [products] shortcode — shares the whole
   variant, so a suggested product looks the same as it does in the shop. */
.shop__grid .product-card,
.wb-products .product-card {
  display: flex;
  flex-direction: column;
  width: auto;
  /* the three-line description needs ~20px more than the frame's two-line 505,
     so a two-line product name and a full description never clip each other.
     A minimum, not a height: a sold-out card carries one more line, and the
     grid stretches its row-mates to match, so rows stay level */
  height: auto;
  min-height: 525px;
  padding: 20px;
}
/* the theme wraps the shot in a link; its line box must not add a descender */
.shop__grid .product-card > a,
.wb-products .product-card > a { display: block; line-height: 0; }
.shop__grid .product-card__img,
.wb-products .product-card__img {
  position: static;
  display: block;
  width: 240px;
  height: 240px;
  margin: 0 auto 12px;
  transform: none;
}
.shop__grid .product-card__info,
.wb-products .product-card__info {
  position: static;
  flex: 1;
  gap: 12px;
  overflow: hidden;
}
.shop__grid .product-card h3,
.wb-products .product-card h3 { font-size: 24px; line-height: 36px; font-weight: 500; }
/* the frame gives the shop card a description preview of up to three lines,
   overriding the base card's two; enough words are passed for it to fill and
   the -webkit-box clamps the rest with an ellipsis */
.shop__grid .product-card__desc,
.wb-products .product-card__desc {
  display: -webkit-box;
  -webkit-line-clamp: 3;
  font-size: 13px;
  line-height: 17px;
  font-weight: 500;
  max-height: 51px;
}
.shop__grid .product-card__row,
.wb-products .product-card__row { position: static; margin-top: 20px; }
/* the empty media box spans the content (638:1758) and keeps its centring */
.shop__grid .product-card__img--empty,
.wb-products .product-card__img--empty { display: flex; width: 100%; }

/* a product with no image still has to fill the media box */
.product-card__img--empty {
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--light-blue);
  border-radius: var(--radius-card) 0 0 0;
}
.product-card__img--empty img { width: 148px; height: 85px; }

.pagination {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 16px;
  margin-top: 40px;
}
.pagination__gap { font-size: 18px; font-weight: 600; line-height: 26px; color: var(--blue); }
.pagination .icon-btn { font-size: 18px; font-weight: 600; line-height: 26px; color: var(--blue); }
.pagination .icon-btn.is-current { color: #fff; }
.pagination__prev img { transform: scaleX(-1); }

/* text beside the USP card; a row rather than two absolute boxes, so the
   section grows with whichever column is taller */
.shop-about {
  display: flex;
  align-items: flex-start;
  gap: 70px;
  margin-top: 80px;
  padding: 0 var(--page-margin);
}
.shop-about__text {
  flex: 0 0 840px;
  display: flex;
  flex-direction: column;
  gap: 32px;
}
.shop-about__text h2 { font-size: 60px; line-height: normal; letter-spacing: -2.4px; }
.shop-about__text p { font-size: 20px; line-height: 32px; }

.usp {
  flex: 0 0 620px;
  display: flex;
  flex-direction: column;
  gap: 24px;
  /* 32 less the 1px border: Figma keeps the stroke inside the frame's padding,
     CSS puts it outside, and the card has to land on the frame's 388px */
  padding: 31px;
  background: #fff;
  border: 1px solid var(--light-blue);
  border-radius: var(--radius-card);
  box-shadow: 0 4px 10px rgba(34, 36, 36, 0.04), 0 2px 1px rgba(34, 36, 36, 0.04);
}
.usp__row { display: flex; align-items: center; gap: 24px; }
/* likewise the separators, which are zero-height strokes in the frame */
.usp__row + .usp__row { border-top: 1px solid var(--divider); padding-top: 23px; }
.usp__text { flex: 1; display: flex; flex-direction: column; gap: 8px; }
.usp__text h3 { font-size: 24px; font-weight: 500; line-height: 36px; }
.usp__text p { font-size: 20px; line-height: 32px; }
.usp img { width: 48px; height: 48px; }

/* Text page (frame 648:2892): breadcrumbs and title, then the page's own
   content beside the highlights card — the same two columns as the product
   page's "Das Tier im Fokus" band. */
.text-page__title {
  margin: 48px 0 0 var(--page-margin);
  font-size: 60px;
  line-height: normal;
  letter-spacing: -2.4px;
}
.text-page {
  display: flex;
  align-items: flex-start;
  gap: 70px;
  margin: 48px 0 80px;
  padding: 0 var(--page-margin);
}
.text-page__content {
  flex: 0 0 840px;
  min-width: 0;
  font-size: 20px;
  line-height: 32px;
  color: var(--dark-grey);
}
.text-page__content > :first-child { margin-top: 0; }
.text-page__content p { margin: 0 0 24px; }
.text-page__content h2,
.text-page__content h3,
.text-page__content h4 {
  font-family: var(--font-display);
  color: var(--blue);
  margin: 40px 0 16px;
}
.text-page__content h2 { font-size: 32px; line-height: normal; letter-spacing: -1px; }
.text-page__content h3 { font-size: 24px; line-height: 36px; }
.text-page__content h4 { font-size: 20px; line-height: 28px; }
.text-page__content a { color: var(--green); }
.text-page__content a:hover { text-decoration: underline; }
/* a .btn in the content (e.g. the 404 page's "back home") keeps its own white
   label — the green content-link colour above would otherwise hide it on the
   button's green ground — and stays a solid button, not an underlined link */
.text-page__content a.btn { color: #fff; }
.text-page__content a.btn:hover { text-decoration: none; }
/* Gutenberg button blocks in the content (e.g. "Jetzt Kontakt aufnehmen" on
   /fuer-haendler/) render as the design's green CTA (Figma 772-2182) instead
   of the editor's default pill */
.text-page__content .wp-block-button__link {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 16px 20px;
  border: none;
  border-radius: var(--radius-btn);
  background: var(--green);
  color: #fff;
  font-family: var(--font-body);
  font-size: 18px;
  font-weight: 600;
  line-height: 26px;
  text-decoration: none;
  white-space: nowrap;
}
.text-page__content .wp-block-button__link:hover {
  background: #00b895;
  text-decoration: none;
}
.text-page__content ul,
.text-page__content ol { margin: 0 0 24px; padding-left: 22px; }
.text-page__content ul { list-style: disc; }
.text-page__content li { margin-bottom: 8px; }
.text-page__content img { max-width: 100%; height: auto; }

/* ==========================================================================
   Wissenbank — Figma frames "Wissenbank" (454:1780) and its 402px mobile
   counterpart (456:48)

   Structurally the shop archive: a category sidebar, a heading, a grid and
   pagination — so it reuses .shop rather than restating that geometry. Only
   the sidebar's width, the grid and the article card are its own.
   ========================================================================== */

/* the brochure sits straight on the footer here, unlike the other pages */
.page--wissen .footer { margin-top: 0; }

.shop--wissen .shop__side { width: 227px; }

/* the article search frame 571:5759 sets beside the heading; the button is
   the nav bar's green one */
.wissen__search { display: flex; align-items: center; width: 400px; height: 48px; }
.wissen__search input {
  flex: 1;
  min-width: 0;
  height: 48px;
  padding: 4px 4px 4px 16px;
  border: 1px solid var(--light-blue);
  border-right: none;
  border-radius: 4px 0 0 4px;
  font-size: 16px;
  font-weight: 500;
  color: var(--dark-grey);
}
.wissen__search input::placeholder { color: var(--light-grey); }
/* the categories are the sidebar on this canvas; the field is the mobile form */
.shop--wissen .shop__sort { display: none; }

.wissen__grid {
  display: grid;
  grid-template-columns: repeat(2, 555px);
  gap: 30px;
  margin-top: 40px;
}

.article-card {
  display: flex;
  flex-direction: column;
  gap: 24px;
  /* 24/24/32 less the 1px border — Figma keeps the stroke inside the frame */
  padding: 23px 23px 31px;
  background: #fff;
  border: 1px solid var(--light-blue);
  border-radius: var(--radius-card) var(--radius-card) var(--radius-card) 0;
  box-shadow: 0 4px 10px rgba(34, 36, 36, 0.04), 0 2px 1px rgba(34, 36, 36, 0.04);
}
.article-card__upper { display: flex; flex-direction: column; gap: 24px; }
.article-card__img { width: 100%; height: 320px; object-fit: cover; border-radius: 8px; }
/* a post with no featured image still has to fill the media box, or the cards
   in a row start at different heights */
.article-card__img--empty {
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--light-blue);
}
.article-card__img--empty img { width: 148px; height: 85px; }
.article-card__text { display: flex; flex-direction: column; gap: 16px; }
.article-card__date {
  font-size: 14px;
  font-weight: 600;
  text-transform: uppercase;
  color: var(--light-grey);
}
.article-card h2 { font-size: 28px; line-height: 40px; }
.article-card h2 a:hover { color: var(--green); }
.article-card__excerpt { font-size: 18px; line-height: 26px; }
/* pinned to the foot so the button lines up across a row of uneven cards */
.article-card .btn { align-self: flex-start; margin-top: auto; }

/* the text sits at the top, the USP card hangs at the bottom of the band */
.shop-about--wissen { min-height: 484px; }
.shop-about--wissen .usp { align-self: flex-end; }
.shop-about__text { gap: 0; }
.shop-about__text h2 { margin-bottom: 32px; }
.shop-about__text ul { font-size: 20px; line-height: 32px; }
/* Category descriptions are free prose (farmula_redesign_term_intro): space the
   paragraphs, give the old subheadings the article's h3 size, and show links as
   links, which the global `a` reset would otherwise leave as body copy. */
.shop-about__text p + p, .shop-about__text p + ul, .shop-about__text ul + p { margin-top: 16px; }
.shop-about__text h3 { margin-top: 32px; font-size: 24px; line-height: 34px; }
.shop-about__text h3 + * { margin-top: 8px; }
.shop-about__text a { color: var(--green); text-decoration: underline; text-underline-offset: 3px; }
.shop-about__text a:hover { color: #00b895; }
.shop-about__links { display: flex; flex-wrap: wrap; gap: 8px 32px; font-weight: 600; }

/* ==========================================================================
   Warenkorb — Figma frames "Warenkorb" (475:309) and its 402px mobile
   counterpart (475:890)
   ========================================================================== */

/* this page carries no broschüre band, so the footer follows the content */
.page--cart .footer { margin-top: 100px; }

/* the back link sits in the title row since frame 571:4414 (2026-08-03) */
.cart__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin: 80px var(--page-margin) 0;
}
.cart__title {
  font-size: 60px;
  line-height: normal;
  letter-spacing: -2.4px;
}

div.cart {
  display: flex;
  align-items: flex-start;
  gap: 80px;
  margin: 40px var(--page-margin) 0;
}
.cart__main { flex: 0 0 960px; }
.cart__side { flex: 0 0 490px; display: flex; flex-direction: column; gap: 24px; }

.cart__items { display: flex; flex-direction: column; gap: 24px; }

/* States the design has no frame for: an empty cart, WooCommerce's own notices
   after a removal, and the no-JS update button. Set in the page's own type so
   they do not arrive in the browser's. */
.cart__empty { font-size: 20px; line-height: 32px; }
.cart__update { margin-top: 24px; }
.woocommerce-message,
.woocommerce-error,
.woocommerce-info {
  margin-bottom: 24px;
  padding: 20px 24px;
  /* woocommerce.css puts its green border-top and an icon-font check into
     ::before on these boxes; both painted over the design's box — the check
     sat on the product's name (Moritz, 2026-08-06) */
  border: 0;
  border-radius: var(--radius-card);
  background: var(--light-blue);
  font-size: 18px;
  line-height: 26px;
  color: var(--blue);
}
.woocommerce-message::before,
.woocommerce-error::before,
.woocommerce-info::before { content: none; }
/* The validation summary: each error on its own breathing row in a red-tinted
   card, so it reads as one coherent summary instead of a wall of underlined
   red lines (Moritz' screenshot, 2026-08-21). Jump-to-field links drop the
   underline — the red row already is the signal — while real page links
   (AGB, Datenschutz, Widerruf) keep theirs. */
.woocommerce-error {
  display: flex;
  flex-direction: column;
  gap: 12px;
  background: #fdeeed;
}
.woocommerce-error li { margin: 0; }
.woocommerce-error a { color: inherit; }
.checkout .woocommerce-error a[href^="#"] { text-decoration: none; }
/* the one action in a notice — the removal's "Rückgängig?", the checkout's
   "Klicke hier, um dich anzumelden." — in the page's green rather than the
   browser's link blue */
.woocommerce-message a,
.woocommerce-info a { color: var(--green); font-weight: 600; }
/* a step deeper than --red: #fb1b13 glares on the tinted card */
.woocommerce-error { color: #c0201a; }

/* The line item is a white card since frame 571:4414; it was a lilac slab.
   Unlike the checkout's boxes this frame keeps its stroke outside the padding
   (the content sits 25px in, 24 padding plus the border), so the padding is
   stated in full. */
.cart-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 24px 32px;
  background: #fff;
  border: 1px solid var(--light-blue);
  border-radius: var(--radius-card);
  box-shadow: 0 4px 10px rgba(34, 36, 36, 0.04), 0 2px 1px rgba(34, 36, 36, 0.04);
}
.cart-item__body { display: flex; align-items: center; gap: 32px; }
/* .page carries the height past `.woocommerce img { height: auto }`: a class
   and an element, which beats a lone class and pins the thumbnail to the square */
.page .cart-item__img {
  flex: 0 0 160px;
  width: 160px;
  height: 160px;
  object-fit: contain;
  border-radius: 8px;
}
.cart-item__text { display: flex; flex-direction: column; gap: 16px; align-items: flex-start; }
.cart-item h2 { font-size: 28px; line-height: 40px; }
.cart-item__qty { display: flex; align-items: center; gap: 16px; }
.cart-item__qty p { font-size: 18px; font-weight: 600; line-height: 26px; color: var(--blue); }
.cart-item__delete {
  display: flex;
  align-items: flex-end;
  gap: 9px;
  padding: 0;
  font-size: 18px;
  font-weight: 600;
  line-height: 26px;
  color: var(--red);
}
.cart-item__delete:hover { text-decoration: underline; }
.cart-item__price {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: flex-end;
  gap: 4px;
}
.cart-item__total {
  font-family: var(--font-display);
  font-size: 40px;
  font-weight: 600;
  line-height: normal;
  letter-spacing: -1.6px;
  color: var(--blue);
}
.cart-item__unit { font-size: 18px; font-weight: 400; line-height: 26px; color: var(--dark-grey); }
.cart-item__unit del { margin-right: 6px; color: var(--light-grey); }

.cart__back {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 18px;
  font-weight: 600;
  line-height: 26px;
  color: var(--green);
}
/* the frame mirrors the right-arrow glyph rather than drawing a left one */
.cart__back img { transform: scaleX(-1); }
.cart__back:hover { text-decoration: underline; }

/* the boxes beside the items: summary, shipping note, payment methods */
.cart-box {
  display: flex;
  flex-direction: column;
  gap: 24px;
  /* 32 less the 1px border — Figma keeps the stroke inside the frame */
  padding: 31px;
  background: #fff;
  border: 1px solid var(--light-blue);
  border-radius: var(--radius-card);
  box-shadow: 0 4px 10px rgba(34, 36, 36, 0.04), 0 2px 1px rgba(34, 36, 36, 0.04);
}
.cart-box__head { display: flex; align-items: center; gap: 24px; }
.cart-box__head h2 { flex: 1; font-size: 24px; font-weight: 500; line-height: 36px; }
.cart-box__head img { flex: 0 0 48px; width: 48px; height: 48px; }
/* zero-height stroke in the frame */
.cart-box__rule { border: none; border-top: 1px solid var(--divider); margin-bottom: -1px; }

.cart-box__total { display: flex; flex-direction: column; gap: 4px; }
.cart-box__line { display: flex; align-items: center; justify-content: space-between; }
.cart-box__line p { font-size: 16px; font-weight: 500; color: var(--grey); }
.cart-box__line .cart-box__line-value {
  font-family: var(--font-display);
  font-size: 24px;
  font-weight: 500;
  line-height: 36px;
  color: var(--blue);
}
.cart-box__total-row { display: flex; justify-content: space-between; margin-top: 8px; }
.cart-box__total-row p {
  font-family: var(--font-display);
  font-size: 40px;
  font-weight: 600;
  line-height: normal;
  letter-spacing: -1.6px;
  color: var(--blue);
}
.cart-box__note { font-size: 15px; font-weight: 400; color: var(--grey); }
.cart-box__cta { justify-content: center; }

.cart-box__pay { display: flex; flex-wrap: wrap; gap: 20px; }
.cart-box__tile {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 128px;
  height: 56px;
  border: 1px solid var(--light-blue);
  border-radius: 8px;
  background: #fff;
  overflow: hidden;
}

/* the shipping note is one row, so it carries no rule and no gap of its own */
.cart-box--shipping { gap: 0; }
.cart-box--shipping .cart-box__head h2 { line-height: 36px; }

/* the not-yet-qualified variant (frame 668:568): label and its bar stack in the
   head's left slot, the delivery icon keeps the 48px column. 18px semibold navy
   over an 8px fully-rounded track that fills green toward the free-shipping
   threshold; the 24px head gap matches the frame's 354px-to-icon offset. */
.cart-box--progress .cart-box__head { align-items: center; }
.cart-box__ship { flex: 1; display: flex; flex-direction: column; gap: 8px; }
.cart-box__ship-label {
  font-size: 18px;
  font-weight: 600;
  line-height: 26px;
  color: var(--blue);
}
.cart-box__ship-bar {
  height: 8px;
  border-radius: 4px;
  background: var(--light-blue);
  overflow: hidden;
}
.cart-box__ship-fill {
  display: block;
  height: 100%;
  border-radius: 4px;
  background: var(--green);
}

.suggest { margin-top: 80px; }
.suggest__heading {
  margin-bottom: 40px;
  font-size: 40px;
  line-height: normal;
  letter-spacing: -1.6px;
}
/* Frame 571:4414 fills the column with three of the v2 carousel cards at 300px.
   The base card positions its content absolutely against a fixed height; on
   mobile these cards follow their content instead, so this variant lays the
   card out in flow — position: static switches the base offsets off. */
.suggest__grid { display: grid; grid-template-columns: repeat(3, 300px); gap: 30px; }
.suggest__grid .product-card {
  display: flex;
  flex-direction: column;
  width: 300px;
  height: auto;
  min-height: 522px; /* see .shop__grid: a sold-out card is one line taller */
  padding: 20px;
}
.suggest__grid .product-card__img {
  position: static;
  width: 240px;
  height: 240px;
  margin-bottom: 12px;
}
.suggest__grid .product-card__info {
  position: static;
  flex: 1;
  gap: 12px;
  overflow: hidden;
}
.suggest__grid .product-card__row { position: static; margin-top: 16px; display: flex; }
.suggest__grid .product-card h3 { font-size: 24px; line-height: 36px; }
.suggest__grid .product-card__desc {
  display: -webkit-box;
  font-size: 13px;
  line-height: 17px;
  font-weight: 500;
  max-height: 34px;
}

/* ==========================================================================
   Bestellung — Figma frames "Bestellung" (482:1553) and its 402px mobile
   counterpart (487:430), 1728 × 2461
   ========================================================================== */

/* The checkout strips the chrome down to a logo and the legal links: nothing on
   the page leads anywhere but forward or back to the cart. */
.navbar--slim { height: 104px; background: var(--blue); border-bottom: none; }
.navbar--slim .navbar__logo { left: var(--page-margin); top: 20px; }

.page--checkout .footer { margin-top: 100px; }
.footer--slim .footer__main {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 24px;
  height: 200px;
  padding: 40px var(--page-margin);
}
.footer__legal { display: flex; gap: 40px; font-size: 16px; font-weight: 500; }
.footer__legal a { transition: color 0.2s ease; }
.footer__legal a:hover { color: var(--green); }
/* the copyright keeps the 40px it has on every page; the badges stay centred */
.footer--slim .footer__bottom-text {
  display: flex;
  flex-direction: column;
  gap: 8px;
  align-self: flex-start;
  margin-top: 40px;
}
.footer--slim .footer__note { font-size: 13px; }

.checkout__back {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 40px var(--page-margin) 0;
  width: fit-content;
  font-size: 18px;
  font-weight: 600;
  line-height: 26px;
  color: var(--green);
}
.checkout__back:hover { text-decoration: underline; }

.checkout__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  /* bottom gap so the login/added-to-cart notice below does not sit flush
     against "Ihre Bestellung" */
  margin: 40px var(--page-margin) 32px;
}
/* 40px since frames 599:6712/599:7090 — the checkout family left the 60 behind */
.checkout__head h1 { font-size: 40px; line-height: normal; letter-spacing: -1.6px; }
.checkout__secure {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 18px;
  font-weight: 600;
  line-height: 26px;
  color: var(--sea-blue);
}

.checkout {
  display: flex;
  /* wrap, because checkout.js prepends its error list straight into this
     row: as a third flex item it was squeezed into a 169px strip beside the
     columns. Wrapped, the list takes the whole first line and the two
     columns sit below unchanged — column-gap rather than gap, so the new
     row costs no 80px of air; the notice's own margin is the spacing. */
  flex-wrap: wrap;
  align-items: flex-start;
  column-gap: 80px;
  margin: 40px var(--page-margin) 0;
}
/* The two columns are the shortcode's .woocommerce box, not the form:
   WooCommerce prints the login bar and the login form it reveals before
   form.checkout, so with the columns inside the form the summary started
   under them, 90px down for every guest and 460 more with the login open,
   while 599:6712 has it level with the form. So the box is a grid, everything
   it holds takes the left column, form.checkout dissolves into it (display:
   contents; its margins go with it) and the summary spans the right column
   from the first row. "span 40" rather than "/ -1": with no explicit rows,
   -1 is line 2. The mobile block puts the form back together.
   Since the steps (1097:5488) the card is two cells of this grid: the login
   column .checkout-gate, which has to stay outside form.checkout because it
   holds a form of its own, and .checkout__form beside it. 480 + 480 is the
   card's 960, and with no gap between the tracks the two lilac cells read as
   one slab; the summary's 80px of air is its own margin. Wherever there is no
   login column (step 2, a shop without the login reminder) the form takes
   both tracks. */
.page--checkout .checkout-wrap > .woocommerce {
  display: grid;
  grid-template-columns: 480px 480px 570px;
  align-items: start;
  margin: 0 var(--page-margin);
}
.page--checkout .checkout-wrap > .woocommerce > *,
.page--checkout .checkout__form,
.checkout .woocommerce-NoticeGroup { grid-column: 1 / span 2; }
/* checkout.js prepends its error list into the form, behind the login column
   in source order: left there, auto-placement would push the form a row
   below the column it belongs beside */
.checkout .woocommerce-NoticeGroup { order: -1; }
.page--checkout .checkout-wrap > .woocommerce > form.checkout { display: contents; }
.page--checkout .checkout-wrap > .woocommerce > .checkout-gate { grid-column: 1; align-self: stretch; }
.page--checkout .checkout-gate ~ form.checkout .checkout__form { grid-column: 2; align-self: stretch; padding-left: 16px; }
.page--checkout .checkout__side { grid-column: 3; grid-row: 1 / span 40; margin-left: 80px; }
.checkout .woocommerce-NoticeGroup { flex: 0 0 100%; }
.checkout ul.woocommerce-error,
.checkout ul.woocommerce-message,
.checkout ul.woocommerce-info { list-style: none; }
/* inside an error the links keep the error's red, not the page's green */
.woocommerce-error a { color: inherit; }
/* the "… wurde dem Warenkorb hinzugefügt" message prints before the form and
   takes the left column like everything else in the box */
.checkout-wrap .woocommerce-notices-wrapper { margin: 0; }
/* the form is one lilac slab with a single rounded corner, like the cart's
   line items — not the white card the summary beside it sits in */
.checkout__form {
  flex: 0 0 960px;
  display: flex;
  flex-direction: column;
  gap: 40px;
  padding: 32px;
  background: var(--light-blue);
  border-radius: 0 40px 0 0;
}
.checkout__side { flex: 0 0 490px; display: flex; flex-direction: column; gap: 24px; }

.checkout-block { display: flex; flex-direction: column; gap: 24px; }
.checkout-block h2 { font-size: 28px; line-height: 40px; }
.checkout-block__head { display: flex; align-items: flex-start; justify-content: space-between; }
.checkout-block__title { display: flex; flex-direction: column; gap: 8px; }
.checkout-block__title p { font-size: 18px; line-height: 26px; color: var(--grey); }
.checkout-fields { display: flex; flex-direction: column; gap: 20px; }
.checkout-fields__row { display: flex; gap: 24px; }
.checkout-fields__row .field { flex: 1; }
/* the fields frame 599:6712 sets at half width, alone on their row */
.field--half { width: 436px; }
.checkout .field-group { width: 436px; }
.checkout-fields__rule { border: none; border-top: 1px solid var(--divider); margin-bottom: -1px; }

/* one field: a white box the input sits inside, so the select can carry its
   label in the same frame the text inputs fill edge to edge */
.field-group { display: flex; flex-direction: column; gap: 8px; }
.field {
  display: flex;
  align-items: center;
  height: 64px;
  /* 24/16 less the 1px border — Figma keeps the stroke inside the frame */
  padding: 0 15px 0 23px;
  background: #fff;
  border: 1px solid var(--light-blue);
  border-radius: 4px;
}
/* 18px, not the frame's 16: the labels, the country select and every line of
   copy beside these fields are 18px, and the typed address read smaller than
   all of it. Moritz's call, 2026-07-31. */
.field input {
  width: 100%;
  font-size: 18px;
  font-weight: 500;
  line-height: normal;
  color: var(--dark-grey);
}
.field input::placeholder { color: var(--light-grey); }
/* the browser's autofill highlight paints only the input, which sits inset in
   the white .field box, so the pale blue came out as a partial patch. The
   background is browser-internal and ignores `background`; the inset shadow
   covers it, so autofilled fields look like every other filled field. */
input:-webkit-autofill,
input:-webkit-autofill:hover,
input:-webkit-autofill:focus {
  -webkit-box-shadow: 0 0 0 1000px #fff inset;
  -webkit-text-fill-color: var(--dark-grey);
}
.field__hint { font-size: 13px; font-weight: 500; color: var(--grey); }

.field--select {
  position: relative;
  flex-direction: column;
  align-items: stretch;
  /* from the top like the floated labels beside it: label at 10, value under */
  justify-content: flex-start;
  gap: 4px;
  padding-top: 10px;
  /* the 55px band under the chevron belongs to the select, not the box: a
     click only opens the picker when it lands on the select itself — on the
     label it merely focuses. So the box keeps no right padding and the select
     spans the full width, carrying the 55px as its own. */
  padding-right: 0;
}
.field__label { font-size: 13px; font-weight: 500; color: var(--light-grey); }

/* Every field floats its label the way the design draws Land/Region: as long
   as the field is empty the placeholder is the label, and the moment it has
   content the name appears small in the field's upper corner with the value
   dropping under it. Pure CSS — :placeholder-shown knows whether there is
   content, :has() lifts that to the box. */
.field { position: relative; }
.field:not(.field--select) .field__label {
  display: none;
  position: absolute;
  left: 24px;
  top: 10px;
  line-height: normal;
}
.field:has(input:not(:placeholder-shown)) .field__label { display: block; }
.field:has(input:not(:placeholder-shown)) {
  align-items: flex-end;
  padding-bottom: 11px;
}
.field--select select {
  appearance: none;
  /* the whole box is the hit area: a select only opens for a click that lands
     on the control itself, and the chevron is centred on the 64px row — the
     26px line box the flow gave the select left the arrow's upper half over
     bare label. Parked absolute over the field instead, the value pinned by
     padding to the flow's own position (measured: 31px under the padding
     edge, 31 + 26 + 5 = the 62px padding box). The label shows through the
     transparent control. */
  position: absolute;
  inset: 0;
  padding: 31px 55px 5px 23px;
  font-family: inherit;
  font-size: 18px;
  line-height: 26px;
  color: var(--dark-grey);
  background: none;
  border: none;
  outline: none;
  cursor: pointer;
}
/* the chevron is the nav's, turned over — the design uses the same glyph */
.field--select::after {
  content: "";
  position: absolute;
  right: 15px;
  top: 50%;
  width: 24px;
  height: 24px;
  transform: translateY(-50%) scaleY(-1);
  background: url(assets/icon-chevron-up.svg) center / 24px 24px no-repeat;
  pointer-events: none;
}

/* Checkboxes and radios are drawn rather than imported: both are a 22px box
   inside a 24px slot, and a real input keeps the label clickable. */
.check {
  display: flex;
  align-items: center;
  gap: 8px;
  /* the label is a block in a flex column and would stretch across the card,
     making the whole empty row toggle the box (Moritz, checkout 2026-09-10) */
  width: fit-content;
  max-width: 100%;
  font-size: 13px;
  font-weight: 500;
  line-height: normal;
  color: var(--dark-grey);
  cursor: pointer;
}
.check--top { align-items: flex-start; }
.check a { text-decoration: underline; }
.check input {
  flex: 0 0 22px;
  width: 22px;
  height: 22px;
  margin: 1px;
  appearance: none;
  background: #fff;
  border: 1px solid var(--light-grey);
  border-radius: 4px;
  cursor: pointer;
}
.check input:checked {
  background: var(--green) url(assets/check-white.svg) center / 13.5px 9.81px no-repeat;
}

.choices { display: flex; flex-direction: column; gap: 8px; }
.choice {
  display: flex;
  align-items: center;
  gap: 8px;
  height: 64px;
  padding: 0 15px 0 23px;
  background: #fff;
  border: 1px solid var(--light-blue);
  border-radius: 4px;
  cursor: pointer;
}
.choice:has(input:checked) { border-color: var(--green); }
.choice input {
  flex: 0 0 22px;
  width: 22px;
  height: 22px;
  margin: 1px;
  appearance: none;
  background: #fff;
  border: 1px solid var(--light-grey);
  border-radius: 50%;
  cursor: pointer;
}
/* filled green with a light-blue pip, not a green pip on white */
.choice input:checked { background: var(--green); }
.choice input:checked::after {
  content: "";
  display: block;
  width: 6px;
  height: 6px;
  margin: 7px;   /* centred in the 20px box the 1px border leaves */
  border-radius: 50%;
  background: var(--light-blue);
}
.choice__label { flex: 1; font-size: 18px; line-height: 26px; color: var(--dark-grey); }
.choice__logo { width: 32px; height: 24px; object-fit: contain; }
.choice__logo--wide { width: 113px; height: 16px; }

.checkout__submit { max-width: 400px; justify-content: center; }

/* the summary reuses the cart's white box; only its contents are new */
.summary { display: flex; flex-direction: column; gap: 16px; }
.summary__row { display: flex; align-items: center; gap: 16px; }
.summary__img { flex: 0 0 100px; width: 100px; height: 100px; object-fit: contain; }
.summary__text { flex: 1; display: flex; flex-direction: column; gap: 4px; }
.summary__name { font-size: 18px; font-weight: 600; line-height: 26px; color: var(--blue); }
.summary__qty { font-size: 16px; font-weight: 500; color: var(--grey); }
.summary__line { display: flex; align-items: center; justify-content: space-between; }
.summary__line p { font-size: 16px; font-weight: 500; color: var(--grey); }
.summary__price,
.summary__line .summary__value {
  font-family: var(--font-display);
  font-size: 24px;
  font-weight: 500;
  line-height: 36px;
  color: var(--blue);
}

.cart-box--sum { gap: 4px; }
.checkout-total { display: flex; flex-direction: column; gap: 4px; }
.checkout-total__row { display: flex; align-items: flex-start; justify-content: space-between; }
.checkout-total__row p {
  font-family: var(--font-display);
  font-size: 28px;
  font-weight: 600;
  line-height: 40px;
  color: var(--blue);
}
.checkout-total__row .checkout-total__value {
  font-size: 40px;
  line-height: normal;
  letter-spacing: -1.6px;
}
.checkout-total__note { font-size: 16px; font-weight: 500; color: var(--grey); }

/* --- the same page, rendered by WooCommerce ------------------------------

   Everything below only ever matches inside the WordPress theme: the static
   checkout.html above carries the design's own classes, while WooCommerce emits
   its own markup that has to be mapped onto them. Kept together here so the two
   never drift: a change to the design's checkout has to be answered in this
   block, and the block says which WooCommerce class it is answering. */

/* WooCommerce nests the fields two wrappers deep; the design has one column, so
   the wrappers step out of the way and their children lay themselves out. */
.checkout .col2-set,
.checkout .col-1,
.checkout .col-2,
.checkout .woocommerce-account-fields,
.checkout__side .woocommerce-checkout-review-order { display: contents; }
/* not `contents` for the review itself: checkout.js blocks it while the totals
   recalculate (blockUI, a white overlay positioned absolute over the element),
   and a box-less element hands that overlay to the viewport, so the whole page
   went white on every address change (Moritz, 2026-09-22). A column with the
   side's 24px keeps the overlay on the two summary boxes. */
.checkout-review { position: relative; display: flex; flex-direction: column; gap: 24px; }

/* .checkout__form is a flex column with gap:40, so every zero-height wrapper
   WooCommerce flattens into it (clearfix divs, the hidden order-attribution
   inputs) still reserves a 40px slot — that is the empty space above
   Kontaktinformationen. Take them out of the flow. */
.checkout__form wc-order-attribution-inputs,
.checkout__form > .clear,
.checkout .woocommerce-account-fields > .clear { display: none; }
/* .col2-set carries WooCommerce's clearfix, and the pseudo-elements of a
   display:contents box are flex items of the card like its children: one gap
   slot above the first block and one under the last. Until the steps a -40px
   margin on the first block hid the upper one and the lower one read as card
   padding; with a pane that holds a heading and a button it was half the
   card. */
.checkout .col2-set::before,
.checkout .col2-set::after { display: none; }

/* the returning-customer login form, the left column's content once
   "Anmelden" is pressed (1311:3412) — the account Anmelden form without the
   card, which the column already is. `form` in the selector: WooCommerce's
   own `.woocommerce form.login` (border, 20px padding, 2em 0 margin, 5px
   corners) outranks a class-only rule (Moritz, 2026-09-17). */
.page--checkout .woocommerce form.woocommerce-form-login {
  display: flex;
  flex-direction: column;
  gap: 40px;
  margin: 0;
  padding: 0;
  border: none;
  border-radius: 0;
}
/* the two fields share a row on the account page; the column stacks them at
   the form's 20px pitch, and the tick follows at 24 rather than the 40 the
   button and the link keep */
.page--checkout .checkout-gate .field-row { flex-direction: column; gap: 20px; }
/* flex: 1 would take the 64px height for a basis of 0 in a column */
.page--checkout .checkout-gate .field-row .field { flex: none; }
.page--checkout .checkout-gate .woocommerce-form-login__submit { justify-content: center; width: 100%; max-width: none; }
.page--checkout .checkout-gate label.woocommerce-form-login__rememberme { margin-top: -16px; }
.page--checkout .woocommerce-form-login .field input.input-text {
  width: 100%;
  height: 100%;
  padding: 0;
  border: none;
  background: none;
  box-shadow: none;
  font-family: inherit;
  font-size: 18px;
  font-weight: 500;
  line-height: normal;
  color: var(--dark-grey);
}
.page--checkout .woocommerce-form-login .field input.input-text:focus { outline: none; }
.page--checkout .woocommerce-form-login .field input.input-text::placeholder { color: var(--light-grey); }
.page--checkout .woocommerce-form-login .field .field__label { display: none; }
.page--checkout .woocommerce-form-login .field,
.page--checkout .woocommerce-form-login .field:has(input.input-text:not(:placeholder-shown)) {
  align-items: stretch;
  padding: 0 15px 0 23px;
}
.page--checkout .woocommerce-form-login .password-input {
  display: block;
  flex: 1 1 auto;
  min-width: 0;
  width: 100%;
  height: 100%;
}
.page--checkout .woocommerce-form-login .show-password-input { display: none; }
.page--checkout .woocommerce-form-login label.woocommerce-form-login__rememberme {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0;
}
.page--checkout .woocommerce-form-login .woocommerce-form-login__submit { margin: 0; }
.page--checkout .woocommerce-form-login .account-forgot { margin: 0; }

/* the Lieferadresse block hangs a full form-gap below the Konto checkbox; the
   design (599-6762) closes about half of it */
.checkout section.checkout-block.woocommerce-billing-fields { margin-top: -20px; }

/* the checkbox stack (599-6777): "Auch als Rechnungsadresse nutzen" out of
   form-shipping.php, then Mailchimp's newsletter row (hooked to
   woocommerce_before_order_notes, a plugin setting) and the order note, all in
   two flex columns at the same 20px pitch. Both are items of the card's
   40px column of their own, so that gap is cancelled: the billing section's
   trailing gap slot leaves the 24px to the phone field, and the second column
   keeps the 20px pitch. WooCommerce's clearfix pseudo-elements would each
   take a gap slot of their own in these columns, so they go. */
.checkout .woocommerce-shipping-fields,
.checkout .woocommerce-additional-fields {
  display: flex;
  flex-direction: column;
  gap: 20px;
}
.checkout .woocommerce-shipping-fields { margin-top: -40px; }
.checkout .woocommerce-additional-fields { margin-top: -20px; }
.checkout .woocommerce-shipping-fields::before,
.checkout .woocommerce-shipping-fields::after,
.checkout .woocommerce-additional-fields::before,
.checkout .woocommerce-additional-fields::after,
.checkout .woocommerce-additional-fields > .clear { display: none; }
/* Mailchimp's GDPR wrapper stays in the markup while the newsletter is
   unchecked and would hold a gap slot as an empty flex item */
form.checkout:has(#mailchimp_woocommerce_newsletter:not(:checked)) .woocommerce-additional-fields > div:has(> #mailchimp-gdpr-fields) {
  display: none !important; /* the plugin writes display:block inline */
}
/* the shipping block follows the order-note checkbox at the same distance the
   Lieferadresse heading keeps from the Konto checkbox (44px) */
.checkout section.checkout-block.checkout__shipping { margin-top: -36px; }
/* WooCommerce's own "ship to a different address?" is the posted one; the
   design's inverted twin above it is the one that is seen */
.checkout__ship-different { display: none; }


/* one field per row, except the pairs the design puts side by side.
   Scoped by :has(> .form-row) so it only touches the fields WooCommerce emits —
   the static page's own .checkout-fields stays the plain column it is. */
.checkout-fields:has(> .form-row) { flex-flow: row wrap; gap: 20px 24px; }
/* `.woocommerce form .form-row` gives every row 3px of padding and 6px of margin
   and outweighs a two-class selector, so the form's own two classes are both
   named here. The gap above is the design's spacing; the rest is WooCommerce
   pushing rows apart on top of it. */
.checkout.woocommerce-checkout .checkout-fields > .form-row { flex: 0 0 100%; margin: 0; padding: 0; }
/* the same weight as the flex: 0 0 100% above, or that rule wins and every
   half quietly renders full width — which it did until 2026-08-03 */
.checkout.woocommerce-checkout .checkout-fields > .form-row.farmula-half {
  flex: 0 0 calc(50% - 12px);
}
/* the placeholder is the label, so the label itself is only for screen readers */
.farmula-hide-label > label,
.screen-reader-text {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
}
.checkout abbr.required { border: none; text-decoration: none; }

/* Both of the form's classes again, and for the same reason as the rows above:
   `.woocommerce form .form-row .input-text` sets the height, the padding, the
   weight and the border of every field here, and one class more is what settles
   it. Without this the fields render 41px tall with 9px of padding, weight 400
   and WooCommerce's near-black border — which is what they did until 2026-07-31,
   while checkout.html measured a perfect 64px, because on the static page there
   is no woocommerce.css to lose to. */
/* WooCommerce wraps every control in an inline span, whose line box put 6px
   around each field — the rows stood at 70 beside the country's 64 */
.checkout .form-row .woocommerce-input-wrapper { display: block; }
.checkout.woocommerce-checkout .form-row input.input-text,
.checkout.woocommerce-checkout .form-row textarea.input-text {
  display: flex;
  width: 100%;
  height: 64px;
  padding: 0 15px 0 23px;
  background: #fff;
  border: 1px solid var(--light-blue);
  border-radius: 4px;
  /* the same 18px .field input carries — see there */
  font-size: 18px;
  font-weight: 500;
  color: var(--dark-grey);
}
/* The note gets WooCommerce's `input-text` class as well, and the rule above
   would otherwise hold it at a single field's height: a class beats an element,
   so `.input-text` there outranks a bare `textarea` here however late it comes.
   Both selectors carry the class for that reason. */
.checkout.woocommerce-checkout .form-row textarea.input-text {
  height: 128px;
  padding: 19px 15px 19px 23px;
  resize: vertical;
}
.checkout .form-row .input-text::placeholder,
.checkout .form-row textarea::placeholder { color: var(--light-grey); }

/* The floating label, WooCommerce edition: the label WooCommerce renders is
   parked off screen while the placeholder does its job, and comes back small
   into the field's upper corner as soon as the field has content — the same
   state the design draws for Land/Region. The un-hiding must outweigh the
   .farmula-hide-label clip rule, which the :has() chain does.
   Focus counts as content (2026-09-10): Safari on iOS blanks the placeholder
   the moment a field is tapped, which left an empty box with the star still
   in it. So a focused field floats its label and drops placeholder and star,
   whichever browser. */
.checkout .checkout-fields > .form-row,
.checkout .field-group > .form-row { position: relative; }
.checkout .form-row.farmula-hide-label input.input-text:focus::placeholder { color: transparent; }
.checkout .form-row.farmula-hide-label:has(input.input-text:not(:placeholder-shown)) > label,
.checkout .form-row.farmula-hide-label:has(input.input-text:focus) > label {
  width: auto;
  height: auto;
  overflow: visible;
  clip: auto;
  clip-path: none;
  left: 24px;
  top: 10px;
  z-index: 1;
  font-size: 13px;
  font-weight: 500;
  line-height: normal;
  color: var(--light-grey);
  pointer-events: none;
}
/* scoped to the placeholder-labelled rows: a field without a placeholder — the
   coupon, say — always counts as "not showing" one and must not shift */
.checkout.woocommerce-checkout .form-row.farmula-hide-label:has(input.input-text:not(:placeholder-shown)) input.input-text,
.checkout.woocommerce-checkout .form-row.farmula-hide-label:has(input.input-text:focus) input.input-text {
  padding-top: 22px;
}
.checkout.woocommerce-checkout .form-row.woocommerce-invalid .input-text { border-color: var(--red); }

/* a field with a select carries its label above the value, the way the design
   draws Land/Region — so the box is the row itself, not the control */
/* The form's two classes carry the padding past our own
   .checkout.woocommerce-checkout … .form-row { padding: 0 } — which had been
   zeroing this row's 23px since the wiring, parking the label a pixel off the
   border. Invisible until the floated labels stood beside it. */
.checkout .form-row:has(select),
.checkout.woocommerce-checkout .checkout-fields > .form-row:has(select) {
  position: relative;
  display: flex;
  flex-direction: column;
  /* from the top like the floated labels beside it, not centred: the label at
     10, the value under it at the same height as a filled field's */
  justify-content: flex-start;
  gap: 4px;
  height: 64px;
  /* no right padding: the 55px band under the chevron is the select's own —
     a click there must land on the select to open the picker, a click on the
     row only focuses it */
  padding: 10px 0 0 23px;
  background: #fff;
  border: 1px solid var(--light-blue);
  border-radius: 4px;
}
.checkout .form-row:has(select) > label {
  font-size: 13px;
  font-weight: 500;
  line-height: normal;
  color: var(--light-grey);
}
.checkout .form-row:has(select) select {
  appearance: none;
  /* the whole box is the hit area, as in the static edition above — absolute
     over the row, out of WooCommerce's inline wrapper span. The value sits
     33px under the padding edge here, not the static 31: the plugin CSS gives
     the label two more pixels of line. 33 + 26 + 3 = the 62px padding box.
     The 23px left is the design's, replacing WooCommerce's own .5em; the 55px
     right keeps the value clear of the chevron. */
  position: absolute;
  inset: 0;
  padding: 33px 55px 3px 23px;
  font-family: inherit;
  font-size: 18px;
  line-height: 26px;
  color: var(--dark-grey);
  background: none;
  border: none;
  outline: none;
  cursor: pointer;
}
.checkout .form-row:has(select)::after {
  content: "";
  position: absolute;
  right: 15px;
  top: 50%;
  width: 24px;
  height: 24px;
  transform: translateY(-50%) scaleY(-1);
  background: url(assets/icon-chevron-up.svg) center / 24px 24px no-repeat;
  pointer-events: none;
}

/* WooCommerce's own checkbox rows, and the legal ones Germanized adds before
   the order button.
   The form's second class is repeated in the selector on purpose. Something in
   the plugin CSS keeps these labels inline at the same weight as a three-class
   selector and, loading later, wins the tie — and an inline label makes its
   checkbox an inline box that ignores width, which is how the AGB box collapsed
   to two pixels. Both classes are really on the form; naming both is what
   settles it. */
.checkout.woocommerce-checkout .form-row .checkbox,
.checkout.woocommerce-checkout .wc-gzd-checkbox-placeholder label,
.checkout .form-row .checkbox,
.checkout .wc-gzd-checkbox-placeholder label {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  font-size: 13px;
  font-weight: 500;
  line-height: normal;
  color: var(--dark-grey);
  cursor: pointer;
}
.checkout.woocommerce-checkout .form-row .checkbox input[type="checkbox"],
.checkout.woocommerce-checkout .wc-gzd-checkbox-placeholder input[type="checkbox"],
.checkout .form-row .checkbox input[type="checkbox"],
.checkout .wc-gzd-checkbox-placeholder input[type="checkbox"] {
  display: block;
  flex: 0 0 22px;
  width: 22px;
  height: 22px;
  margin: 1px;
  appearance: none;
  background: #fff;
  border: 1px solid var(--light-grey);
  border-radius: 4px;
  cursor: pointer;
}
.checkout.woocommerce-checkout .form-row .checkbox input[type="checkbox"]:checked,
.checkout.woocommerce-checkout .wc-gzd-checkbox-placeholder input[type="checkbox"]:checked,
.checkout .form-row .checkbox input[type="checkbox"]:checked,
.checkout .wc-gzd-checkbox-placeholder input[type="checkbox"]:checked {
  background: var(--green) url(assets/check-white.svg) center / 13.5px 9.81px no-repeat;
}
.checkout a { text-decoration: underline; }
.checkout h2 a,
.checkout .checkout__back { text-decoration: none; }

/* the payment methods and the order button, which core puts in one wrapper */
.checkout #payment { display: flex; flex-direction: column; gap: 40px; }
.checkout .wc_payment_methods { padding: 0; }
.checkout .payment_box {
  margin-top: 8px;
  padding: 20px 24px;
  background: #fff;
  border: 1px solid var(--light-blue);
  border-radius: 4px;
  font-size: 16px;
  line-height: 26px;
}
.checkout .payment_box p:last-child { margin-bottom: 0; }
.checkout .place-order { display: flex; flex-direction: column; gap: 20px; margin: 0; }

/* Germanized renders the order button itself; form-checkout.php lifts its block
   out of the order review and prints it at the foot of the card instead */
.checkout .wc-gzd-order-submit { display: flex; flex-direction: column; gap: 20px; }
.checkout .wc-gzd-order-submit .place-order { gap: 20px; }
.checkout .wc-gzd-checkbox-placeholder:empty { display: none; }

/* The promo-code fold (frame 621:379), in the Bestellübersicht between the
   items and the totals. Folded it is one grey line with a chevron; open it is
   the field — floating its label like every other — with the navy Anwenden
   beside it. It replaced WooCommerce's coupon banner over the form. */
.coupon-fold { display: flex; flex-direction: column; gap: 12px; }
.coupon-fold__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  padding: 0;
  font-size: 15px;
  line-height: normal;
  color: var(--grey);
}
/* the chevron points down while folded, up while open */
.coupon-fold__head img { transform: scaleY(-1); }
.coupon-fold.is-open .coupon-fold__head img { transform: none; }
.coupon-fold__body { display: flex; gap: 16px; }
.coupon-fold__body[hidden] { display: none; }
.coupon-fold__field { flex: 1; }
.coupon-fold__apply {
  flex: 0 0 160px;
  height: 64px;
  border-radius: 4px;
  background: var(--sea-blue);
  color: #fff;
  font-size: 18px;
  font-weight: 600;
  line-height: 26px;
}
.coupon-fold__apply:hover { background: var(--blue); }
/* the apply answer arrives in WooCommerce's notice box; the fold is its box */
.coupon-fold__note:empty { display: none; }
.coupon-fold__note .woocommerce-error,
.coupon-fold__note .woocommerce-message,
.coupon-fold__note .woocommerce-info {
  margin: 0;
  padding: 0;
  background: none;
  border: none;
  font-size: 15px;
  line-height: 20px;
  color: var(--dark-grey);
}
.coupon-fold__note ul { margin: 0; padding: 0; list-style: none; }
.coupon-fold__note .woocommerce-error { color: var(--red); }

/* real product names are longer than the frame's samples: the name wraps, the
   price does not */
.summary__price { white-space: nowrap; }
.summary__price del { display: block; font-size: 16px; line-height: 20px; color: var(--light-grey); }
.summary__name { overflow-wrap: break-word; }

/* ==========================================================================
   Bestellbestätigung — Figma frames "Order Confirmation" (599:7090) and its
   402px counterpart (599:7548), 1728 × 1752. The full nav bar without the menu
   strip, three lilac cards on the left, the two address cards on the right.
   ========================================================================== */

/* the frame mirrors the right-arrow glyph rather than drawing a left one */
.page--confirm .checkout__back img { transform: scaleX(-1); }
/* the checkout underlines its links; nothing in these cards is a text link */
.confirm a { text-decoration: none; }

.confirm__main {
  flex: 0 0 960px;
  display: flex;
  flex-direction: column;
  gap: 24px;
}

/* a lilac slab with the one rounded corner, like the checkout's form card */
.confirm-card {
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding: 32px;
  background: var(--light-blue);
  border-radius: 0 24px 0 0;
}
.confirm-card__lead { font-size: 18px; font-weight: 600; line-height: 26px; color: var(--blue); }
.confirm-card__copy { font-size: 15px; line-height: 20px; color: var(--dark-grey); }

.confirm-facts { display: flex; flex-wrap: wrap; gap: 32px; margin: 0; }
.confirm-facts div { display: flex; flex-direction: column; gap: 4px; }
.confirm-facts dt {
  font-size: 14px;
  font-weight: 600;
  text-transform: uppercase;
  color: var(--grey);
}
.confirm-facts dd { margin: 0; font-size: 15px; color: var(--dark-grey); }

.confirm-order { gap: 40px; }
.confirm-order__table { display: flex; flex-direction: column; gap: 16px; }
.confirm-order__row {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  font-size: 18px;
  font-weight: 600;
  line-height: 26px;
  color: var(--blue);
}
.confirm-order__row p { margin: 0; }
.confirm-order__row--item {
  font-size: 15px;
  font-weight: 400;
  line-height: 20px;
  color: var(--dark-grey);
}
/* the head and the item rows share four columns: the product takes the room,
   Stückpreis, Menge and Gesamtpreis sit at fixed widths so the rows line up
   (each row is its own grid). The totals below stay two-ended flex rows. */
.confirm-order__row--head,
.confirm-order__row--item {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 112px 64px 112px;
  column-gap: 16px;
  align-items: start;
}
.confirm-order__row--head p + p,
.confirm-order__row--item p + p { text-align: right; white-space: nowrap; }
.confirm-order__rule { width: 100%; border: none; border-top: 1px solid var(--light-grey); margin-bottom: -1px; }
.confirm-order__actions { display: flex; gap: 20px; }
.confirm-order__actions .btn { flex: 1; justify-content: center; }

.confirm-address {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin: 0;
  padding: 0;
  list-style: none;
  font-size: 18px;
  line-height: 26px;
  color: var(--blue);
}
.confirm-address p { margin: 0; }

/* Whatever the gateway still needs — bank details for a transfer, a code. It
   writes its own headings and lists into the card, and hands its text over
   inside WooCommerce's own notice box — a grey fill, a coloured top rule and
   an icon before the first line. The design's card is already around it, so
   the inner box is flattened and its type set to the card's. */
.confirm-card--instructions h2,
.confirm-card--instructions h3 {
  font-size: 18px;
  font-weight: 600;
  line-height: 26px;
  color: var(--blue);
}
.confirm-card--instructions p,
.confirm-card--instructions li {
  font-size: 15px;
  line-height: 20px;
  color: var(--dark-grey);
}
.confirm-card--instructions p { margin: 0; }
/* Mollie's bank-transfer text is three paragraphs (the ask, the account
   lines, the deadline); with every margin flattened above they ran together
   into one block. The values are bold (see farmula_redesign_mollie_instructions)
   and take the card's blue so the IBAN and reference stand out from labels. */
.confirm-card--instructions .mollie-instructions p + p { margin-top: 12px; }
.confirm-card--instructions .mollie-instructions strong { font-weight: 600; color: var(--blue); }
.confirm-card--instructions ul {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin: 0;
  padding: 0;
  list-style: none;
}
.confirm-card--instructions .woocommerce-info,
.confirm-card--instructions .woocommerce-message,
.confirm-card--instructions .woocommerce-notice {
  margin: 0;
  padding: 0;
  background: none;
  border: none;
  border-radius: 0;
  color: inherit;
  font-size: inherit;
  line-height: inherit;
}
.confirm-card--instructions .woocommerce-info::before,
.confirm-card--instructions .woocommerce-message::before,
.confirm-card--instructions .woocommerce-notice::before { content: none; }

/* The review stays a table so a plugin's <tr> still has one to sit in, but
   without WooCommerce's shop_table class: only the tag was needed, and the class
   brings a grey fill, a border, row rules and cell padding with it. */
.checkout-review__table { width: 100%; border: none; border-collapse: collapse; }
.checkout-review__table,
.checkout-review__table tbody,
.checkout-review__table tr { display: block; }
.checkout-review__table tr,
.checkout-review__table td,
.checkout-review__table th {
  padding: 0;
  border: none;
  background: none;
  text-align: left;
  font-size: inherit;
}
.checkout-review__table tr + tr { margin-top: 16px; }
.checkout-review__table td.summary__row { display: flex; }
.checkout-review__table .summary__img {
  width: 100px;
  height: 100px;
  max-width: none;
  object-fit: contain;
}

/* ==========================================================================
   Blog Article — Figma frames "Blog Article" (459:555) and its 402px mobile
   counterpart (461:1611)
   ========================================================================== */

/* the brochure sits straight on the footer here too */
.page--article .footer { margin-top: 0; }

.article__title {
  margin: 80px var(--page-margin) 0;
  font-size: 60px;
  line-height: normal;
  letter-spacing: -2.4px;
}

/* the piece on the left, who wrote it and where to share it on the right */
.article {
  display: flex;
  align-items: flex-start;
  gap: 80px;
  margin: 64px var(--page-margin) 0;
}
.article__body { flex: 0 0 960px; display: flex; flex-direction: column; gap: 40px; }
/* height:auto matters — the width/height attributes are presentational hints,
   and an explicit height beats aspect-ratio. Without it the hero keeps its
   637px on every width, which happens to be right at 960 and nowhere else. */
.article__hero {
  width: 100%;
  height: auto;
  aspect-ratio: 960 / 637;
  object-fit: cover;
  border-radius: 8px;
}

.article__text {
  display: flex;
  flex-direction: column;
  gap: 24px;
  /* the literature lists at the foot of a piece carry bare URLs and long
     runs of non-breaking spaces, which are one unbreakable word to the
     line breaker; without this they push the column past the viewport on
     a phone instead of wrapping */
  min-width: 0;
  overflow-wrap: break-word;
}
/* a legacy post whose whole body sits in one bare <div> (pasted from the old
   editor) would otherwise lose the paragraph spacing: the gap only reaches
   the flex container's direct children */
.article__text > div:not([class]) { display: flex; flex-direction: column; gap: 24px; }
.article__text p { font-size: 18px; line-height: 26px; }
.article__text h2 { font-size: 28px; line-height: 40px; }
.article__text ul { list-style: disc; padding-left: 20px; font-size: 18px; line-height: 26px; }
/* The block editor's "Textfarbe" wraps text in <mark class="has-inline-color">.
   WordPress ships no style for it, so the browser default (yellow background)
   showed through since the redesign. Keep the inline colour, drop the marker. */
.article__text mark.has-inline-color,
.text-page__content mark.has-inline-color { background: transparent; }
/* Same reasoning as .product__desc: the global `a { color: inherit;
   text-decoration: none }` reset leaves prose links looking like body copy, and
   editors had started underlining them by hand in the editor to compensate.
   :not(.wb-products *) keeps the [products] cards out, which render as <li>
   wrapped in an <a>; the image rule below uses the same exclusion. */
.article__text p a:not(.wb-products *),
.article__text li a:not(.wb-products *),
.article__text td a:not(.wb-products *) {
  color: var(--green);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.article__text p a:not(.wb-products *):hover,
.article__text li a:not(.wb-products *):hover,
.article__text td a:not(.wb-products *):hover { color: #00b895; }
/* images inside the running text are wider than they are tall, unlike the hero */
/* :not(.wb-products *): the [products] cards carry their own image sizes,
   and the 24px cart glyph cropped to 960:532 was a basket without wheels
   (Moritz, 2026-08-25) */
/* An inline image keeps its own shape and the width its author gave it,
   capped at the column. The 960/532 crop (object-fit: cover) that stood here
   until 2026-09-09 cut the footnote off every table and the right edge off
   every chart in the knowledge base, and width: 100% blew a 300px thumbnail
   up to column width. */
.article__text img:not(.wb-products *) {
  max-width: 100%;
  height: auto;
  border-radius: 8px;
}
.article__text img.aligncenter { display: block; margin-left: auto; margin-right: auto; }

.article__meta { flex: 0 0 489px; display: flex; flex-direction: column; gap: 32px; }
.article__meta-block { display: flex; flex-direction: column; gap: 12px; }
.article__meta-label {
  font-size: 14px;
  font-weight: 600;
  text-transform: uppercase;
  color: var(--grey);
}
.article__meta-value { font-size: 18px; font-weight: 600; line-height: 26px; color: var(--blue); }
.article__meta-value a:hover { color: var(--green); }

.article__author { display: flex; flex-direction: column; gap: 16px; }
.article__author-row { display: flex; align-items: center; gap: 16px; }
.article__avatar { width: 64px; height: 64px; border-radius: 50%; object-fit: cover; }
.article__author-name { display: flex; flex-direction: column; gap: 4px; }
.article__author-title { font-size: 18px; font-weight: 600; line-height: 26px; color: var(--blue); }
.article__author-role { font-size: 16px; font-weight: 500; color: var(--grey); }
.article__author-bio { font-size: 16px; font-weight: 500; }

.article__share { display: flex; align-items: center; gap: 20px; }
.article__share img { width: 32px; height: 32px; }
.article__share a,
.article__copy { display: block; transition: opacity 0.2s ease; }
.article__share a:hover,
.article__copy:hover { opacity: 0.7; }
/* the copy button is the only control here with no destination, so it says so */
.article__copy { position: relative; }
.article__copy.is-copied::after {
  content: "Link kopiert";
  position: absolute;
  left: 50%;
  bottom: calc(100% + 8px);
  transform: translateX(-50%);
  padding: 4px 10px;
  border-radius: var(--radius-btn);
  background: var(--blue);
  color: #fff;
  font-size: 14px;
  font-weight: 600;
  line-height: 20px;
  white-space: nowrap;
}

/* WordPress wraps content images in a figure; the design has neither caption
   frame nor margin around them */
.article__text figure { margin: 0; }
/* the classic editor writes the caption's pixel width as an inline style on
   the wrapper, which is wider than the column on a phone */
.article__text .wp-caption { max-width: 100%; }
.article__text figure img { margin: 0; }

/* further reading: the Wissenbank card in a three-column row */
.more { margin: 80px var(--page-margin) 0; }
.more__heading {
  margin-bottom: 40px;
  font-size: 40px;
  line-height: normal;
  letter-spacing: -1.6px;
}
.more__grid { display: grid; grid-template-columns: repeat(3, 490px); gap: 30px; }
.more__grid .article-card__img { height: 278px; }

/* ==========================================================================
   Product Details — Figma frame "Product Details" (401:393), 1728 × 5184
   ========================================================================== */

.page--product .footer { margin-top: 80px; }

.product__name {
  margin: 80px 0 0 var(--page-margin);
  font-size: 60px;
  line-height: normal;
  letter-spacing: -2.4px;
}

/* two columns on a lilac band: the gallery card, and everything you read */
.product {
  display: flex;
  align-items: flex-start;
  gap: 80px;
  margin-top: 64px;
  padding: 80px var(--page-margin);
  background: var(--light-blue);
}

.product__card {
  /* the anchor for the zoom lens script.js lays over the shot on hover */
  position: relative;
  flex: 0 0 750px;
  padding: 32px;
  background: #fff;
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-card);
}
.product__zoom {
  position: absolute;
  z-index: 1;
  background-repeat: no-repeat;
}
/* the parent theme's `.woocommerce img { height: auto }` (a class and an
   element) outranks a lone class, and a tall shot (Mischspitzen 365x908) then
   ran the full column height; the doubled selector pins the square */
.woocommerce img.product__photo,
.product__photo {
  width: 560px;
  height: 560px;
  margin: 0 auto;
  /* contain, not cover: a product shot cropped to a square loses its lid */
  object-fit: contain;
}

/* the swipeable strip is a mobile-only affordance; the desktop keeps the single
   zoomable shot and swaps it from the thumbnails */
.product__slides { display: none; }

.product__thumbs { display: flex; justify-content: center; gap: 20px; margin-top: 16px; }
.product__thumb {
  width: 100px;
  height: 100px;
  padding: 0;
  border: 1px solid var(--light-grey);
  transition: opacity 0.2s ease;
}
.product__thumb img { width: 100%; height: 100%; object-fit: contain; }
/* the frame dims every shot but the one on show */
.product__thumb:not(.is-active) { opacity: 0.4; }
.product__thumb:hover { opacity: 1; }

/* frame 1123:2506: the technical pictograms sit centred under the thumbnail
   strip, six to a row at the 60px horizont exports them in, wrapping to a
   second row past six */
.product__icons {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 4px;
  max-width: 380px;
  margin: 40px auto 0;
  padding: 0;
  list-style: none;
}
.product__icons li { flex: 0 0 auto; line-height: 0; }
/* the square pictograms are 60px; the wide Leitfähigkeit label keeps its
   ratio at the same height */
.product__icons img { width: auto; height: 60px; }

.product__usps { display: flex; flex-direction: column; gap: 24px; margin-top: 40px; }
.product__checks { display: flex; gap: 40px; }
.product__checks ul { flex: 1; display: flex; flex-direction: column; gap: 16px; }
.product__checks li {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 18px;
  line-height: 26px;
}
.product__checks img { flex: 0 0 24px; }

/* Frames 571:2716/571:3050: the green toggle under a folded description.
   script.js reveals the button and adds the class, so without JS everything
   simply stays open. It used to be mobile-only, which left the long
   manufacturer descriptions running unbroken down the desktop page. */
.product__more:not([hidden]) { display: flex; }
.product__more {
  display: none;
  align-items: center;
  gap: 8px;
  padding: 0;
  font-size: 18px;
  font-weight: 600;
  line-height: 26px;
  color: var(--green);
}
.product__more img { transform: scaleY(-1); }
.product__more.is-open img { transform: none; }
/* zero-height stroke in the frame, so it must not add a row of its own */
.product__rule { border: none; border-top: 1px solid var(--divider); margin-bottom: -1px; }

.product__ask,
.product__download {
  display: flex;
  align-items: center;
  align-self: flex-start;
  gap: 8px;
  font-size: 18px;
  font-weight: 600;
  line-height: 26px;
  color: var(--green);
}
.product__ask:hover,
.product__download:hover { text-decoration: underline; }

.product__info { flex: 0 0 700px; display: flex; flex-direction: column; gap: 24px; }

/* The WordPress template wraps this row in the add-to-cart form, the static
   page does not, so both carry the layout. */
/* the frame stacks the price, the tax note and then the action row (frame
   647:2731): quantity stepper and the cart button share one line under them */
.product__buy,
.product__buy-form { display: flex; flex-direction: column; align-items: flex-start; gap: 16px; }
.product__buy-form { width: 100%; }
.product__buy-price { display: flex; flex-direction: column; gap: 8px; }
.product__buy-actions { display: flex; align-items: center; gap: 16px; }
.product__price-row { display: flex; align-items: center; gap: 16px; }
/* sold out / backorder: the line under the price, and the "tell me" form */
.product__stock { font-size: 15px; line-height: 22px; color: var(--red, #fb1b13); }
.notify { display: flex; flex-direction: column; gap: 8px; width: 100%; max-width: 520px; }
.notify__lead { font-size: 16px; font-weight: 600; color: var(--blue); }
.notify__row {
  display: flex;
  align-items: center;
  padding: 4px 4px 4px 20px;
  border: 1px solid var(--light-blue);
  border-radius: var(--radius-btn);
  background: #fff;
}
.notify__row:focus-within { border-color: var(--light-grey); }
.notify__input { flex: 1; min-width: 0; height: 50px; border: 0; background: transparent; font-size: 16px; font-family: inherit; color: var(--dark-grey); }
.notify__input:focus { outline: none; }
.notify__input::placeholder { color: var(--light-grey); }
.notify__btn { padding: 12px 18px; white-space: nowrap; }
.notify__hp { position: absolute; left: -9999px; width: 1px; height: 1px; opacity: 0; }
.notify__msg { font-size: 15px; line-height: 22px; color: var(--green); }
.notify__msg.is-error { color: var(--red, #fb1b13); }
.notify__note { font-size: 13px; line-height: 18px; color: var(--light-grey); }
.notify.is-done .notify__row, .notify.is-done .notify__lead { display: none; }

/* --- ausverkauft auf der karte + warteliste-popup ----------------------------
   Cards 837:675 / 1062:4598: "Aktuell ausverkauft" is the last line of the
   text block, right under the description, and a bordered Benachrichtigen
   button stands where the cart glyph was. The button opens the popup
   (997:2217 desktop, 997:3066 mobile), which flips to 997:2710 once the
   address is stored. The popup's form is the product page's .notify form, so
   the rules above and the submit handler in home.js serve both. */
.product-card__stock { flex: 0 0 auto; font-size: 13px; line-height: 17px; font-weight: 500; color: var(--light-grey); }
/* the price column gives up its fixed 184px, so the button fits beside it */
.product-card__price--out { flex: 1 1 auto; width: auto; min-width: 0; margin-right: 8px; }
.product-card__notify {
  width: auto;
  height: 48px;
  gap: 8px;
  padding: 12px;
  font-size: 13px;
  line-height: 17px;
  font-weight: 500;
  color: var(--dark-grey);
  white-space: nowrap;
}
/* the card's hover turns the glyph white; the label follows */
.product-card .product-card__notify:hover { color: #fff; }
/* Signed up (1058:3290): a green tick and "Benachrichtigung"; hovered
   (837:7710): red, a white cross, and the click takes the address off the
   list again. home.js sets is-subscribed from what the browser remembers. */
.product-card__notify-ico--check,
.product-card__notify-ico--close,
.product-card__notify-label--on { display: none; }
.product-card__notify.is-subscribed .product-card__notify-ico--notify,
.product-card__notify.is-subscribed .product-card__notify-label--off { display: none; }
.product-card__notify.is-subscribed .product-card__notify-ico--check,
.product-card__notify.is-subscribed .product-card__notify-label--on { display: block; }
.product-card .product-card__notify.is-subscribed:hover { background: var(--red); border-color: var(--red); }
.product-card .product-card__notify.is-subscribed:hover .product-card__notify-ico--check { display: none; }
.product-card .product-card__notify.is-subscribed:hover .product-card__notify-ico--close { display: block; }
/* the tick stays green on its white ground; the hover inversion is for the cross only */
.product-card .product-card__notify .product-card__notify-ico--check { filter: none; }
.product-card__notify.is-busy { pointer-events: none; opacity: 0.6; }
/* Slider (home, Verwandte Produkte), sold out (837:675): the desktop card's
   info block already reserves the stock line (see the v2 carousel above).
   Its row is 238px against 83px of price plus the frame's 151px button, which
   our wider face renders at 160px, so the button runs 6px side padding (146px)
   and the price column keeps 6px to it: 83 + 6 + 146 = 235. */
.products--v2 .product-card__price--out .price { white-space: nowrap; }
@media (min-width: 901px) {
  .products--v2 .product-card__price--out { margin-right: 6px; }
  .products--v2 .product-card__price--out ~ .product-card__notify { padding: 12px 6px; gap: 6px; }
}

/* The overlay scrolls when the box does not fit, and the box centres itself
   with auto margins rather than align-items: a centred flex item that
   overflows loses its top edge, auto margins collapse to zero instead. On the
   phone the soft keyboard halves the visible height, and Safari shifts the
   layout viewport out from under a fixed element; home.js therefore sizes
   the overlay to the visual viewport while the dialog is open. */
/* --- the slide-in cart (1100:9508, mobile 1230:4661) --------------------
   Printed by inc/cart-drawer.php outside .page, like the waitlist popup;
   home.js opens it on every AJAX add. The panel takes the canvas zoom itself,
   otherwise it stays at design size next to a page scaled down to the window
   and reads a third too big on a 1280px screen. A 540px (design) panel on the
   right edge, full height: the title bar and the totals
   with the buttons stay, the lines scroll between them. The backdrop dims
   the page like the overlay in 1100:9899 (Dark Grey at 80%) and catches the
   click that closes the panel. */
.cart-drawer { position: fixed; inset: 0; z-index: 100000; }
.cart-drawer[hidden] { display: none; }
.cart-drawer__backdrop {
  position: absolute;
  inset: 0;
  background: var(--dark-grey);
  opacity: 0;
  transition: opacity 0.3s ease;
}
.cart-drawer.is-open .cart-drawer__backdrop { opacity: 0.8; }
.cart-drawer__panel {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  display: flex;
  flex-direction: column;
  width: 540px;
  max-width: 100%;
  padding-bottom: 40px;
  overflow: hidden;
  border-radius: 24px 0 0 24px;
  /* blue under the title bar's rounded corner: a white background there
     shows through the anti-aliased edge as a pale rim around the curve */
  background: linear-gradient(var(--blue) 40px, #fff 40px);
  zoom: var(--canvas-zoom, 1);
  box-shadow: 0 4px 10px rgba(34, 36, 36, 0.04), 0 2px 1px rgba(34, 36, 36, 0.04);
  transform: translateX(100%);
  transition: transform 0.3s ease;
}
.cart-drawer.is-open .cart-drawer__panel { transform: none; }
@media (prefers-reduced-motion: reduce) { .cart-drawer__panel, .cart-drawer__backdrop { transition: none; } }
.cart-drawer__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex: 0 0 auto;
  padding: 20px 24px;
  background: var(--blue);
}
.cart-drawer__title {
  font-family: var(--font-display);
  font-size: 36px;
  font-weight: 600;
  line-height: normal;
  letter-spacing: -1.44px;
  color: #fff;
  font-variation-settings: "opsz" 14, "wdth" 100;
}
.cart-drawer__close { display: flex; padding: 0; }
.cart-drawer__added {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  flex: 0 0 auto;
  margin: 24px 24px 0;
  padding: 10px;
  border-radius: 8px;
  background: rgba(0, 166, 135, 0.1);
  font-size: 18px;
  line-height: 26px;
  color: var(--green);
}
.cart-drawer__added[hidden] { display: none; }
.cart-drawer__content { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; }
.cart-drawer__items {
  display: flex;
  flex-direction: column;
  gap: 16px;
  flex: 1 1 auto;
  min-height: 0;
  padding: 24px 24px;
  overflow-y: auto;
  scrollbar-width: thin;
  scrollbar-color: var(--light-grey) transparent;
}
.cart-drawer__added:not([hidden]) + .cart-drawer__content .cart-drawer__items { padding-top: 16px; }
.cart-drawer__items::-webkit-scrollbar { width: 8px; }
.cart-drawer__items::-webkit-scrollbar-thumb { border-radius: 8px; background: var(--light-grey); }
/* A quantity on its way to the shop: the line fades under a ring, the totals
   fade with it (home.js sets is-updating on the first click, is-busy while
   the request runs). The children fade and not the card, so the ring keeps
   its full colour. */
.cart-drawer.is-busy .cart-drawer__content { pointer-events: none; }
.cart-drawer__lines, .cart-drawer__total { transition: opacity 0.15s ease; }
.cart-drawer.is-updating .cart-drawer__lines,
.cart-drawer.is-updating .cart-drawer__total { opacity: 0.4; }
.cart-drawer__item.is-updating { position: relative; }
.cart-drawer__item.is-updating > * { opacity: 0.4; transition: opacity 0.15s ease; }
.cart-drawer__item.is-updating::after {
  content: '';
  position: absolute;
  top: calc(50% - 16px);
  left: calc(50% - 16px);
  width: 32px;
  height: 32px;
  border: 3px solid var(--light-blue);
  border-top-color: var(--blue);
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
}
.cart-drawer__empty { font-size: 18px; line-height: 26px; }
.cart-drawer__item {
  display: flex;
  flex-direction: column;
  gap: 16px;
  flex: 0 0 auto;
  padding: 24px;
  border: 1px solid var(--light-blue);
  border-radius: var(--radius-card);
  background: #fff;
  box-shadow: 0 4px 10px rgba(34, 36, 36, 0.04), 0 2px 1px rgba(34, 36, 36, 0.04);
}
.cart-drawer__item-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; }
.cart-drawer__item-link { display: flex; align-items: center; gap: 16px; min-width: 0; }
.cart-drawer__item-link:hover .cart-drawer__item-name { color: var(--green); }
.cart-drawer .cart-drawer__img { flex: 0 0 80px; width: 80px; height: 80px; object-fit: contain; border-radius: 8px; }
.cart-drawer__img--empty { display: flex; align-items: center; justify-content: center; background: var(--light-blue); }
.cart-drawer__img--empty img { width: 74px; height: 42px; }
.cart-drawer__item-text { display: flex; flex-direction: column; gap: 4px; min-width: 0; font-size: 18px; line-height: 26px; }
.cart-drawer__item-name { font-weight: 700; color: var(--blue); transition: color 0.2s ease; }
.cart-drawer__item-unit { color: var(--dark-grey); }
.cart-drawer__item-unit del { margin-right: 6px; color: var(--light-grey); }
.cart-drawer__remove { display: flex; flex: 0 0 24px; }
.cart-drawer__item-row { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 16px; }
.cart-drawer__qty { display: flex; align-items: center; gap: 16px; }
.cart-drawer__qty p { font-size: 18px; line-height: 26px; color: var(--dark-grey); }
.cart-drawer__item-total {
  font-family: var(--font-display);
  font-size: 28px;
  font-weight: 600;
  line-height: 40px;
  color: var(--blue);
  font-variation-settings: "opsz" 14, "wdth" 100;
}
.cart-drawer__foot {
  display: flex;
  flex-direction: column;
  gap: 16px;
  flex: 0 0 auto;
  padding: 24px 24px 0;
  border-top: 1px solid var(--light-blue);
}
.cart-drawer__lines { display: flex; flex-direction: column; gap: 8px; font-size: 18px; line-height: 26px; }
.cart-drawer__line { display: flex; align-items: center; justify-content: space-between; }
.cart-drawer__line p { color: var(--grey); }
.cart-drawer__line .cart-drawer__line-value { font-weight: 700; color: var(--blue); }
/* frames 1100:9508 / 1230:4661: free shipping in green, and under the shipping
   line the bar that fills towards it, with what is still missing in tiny text */
.cart-drawer__line .cart-drawer__line-value--free { color: var(--green); }
.cart-drawer__freebar { display: flex; flex-direction: column; align-items: flex-end; gap: 4px; }
.cart-drawer__freebar-track { width: 100%; height: 8px; border-radius: 2px; background: var(--light-blue); overflow: hidden; }
.cart-drawer__freebar-track span { display: block; height: 100%; border-radius: 2px; background: var(--green); }
.cart-drawer__freebar-note { font-size: 13px; line-height: normal; font-weight: 500; color: var(--grey); }
.cart-drawer__total { display: flex; flex-direction: column; gap: 4px; }
.cart-drawer__total-row {
  display: flex;
  justify-content: space-between;
  font-family: var(--font-display);
  font-size: 36px;
  font-weight: 600;
  line-height: normal;
  letter-spacing: -1.44px;
  color: var(--blue);
  font-variation-settings: "opsz" 14, "wdth" 100;
}
.cart-drawer__note { font-size: 15px; color: var(--grey); }
.cart-drawer .btn { justify-content: center; width: 100%; font-weight: 700; }
.cart-drawer__view { background: #fff; border: 1px solid var(--blue); color: var(--sea-blue); }
.cart-drawer__view:hover { background: var(--light-blue); }
/* PayPal's SDK draws the yellow button itself (gold, rect, "checkout"
   label: "Direkt zu PayPal" with the mark in German). Height and corners come
   from farmula_redesign_paypal_mini_cart_style() in inc/cart-drawer.php; the
   box only holds its place. */
.cart-drawer__paypal { width: 100%; }
.cart-drawer__paypal:empty { display: none; }
@media (max-width: 900px) {
  /* 1230:4661: the panel is the whole screen, the title one step smaller */
  .cart-drawer__panel { width: 100%; padding-bottom: 24px; border-radius: 0; }
  .cart-drawer__title { font-size: 28px; line-height: 40px; letter-spacing: 0; }
  /* the three buttons at the PayPal button's 40px, as agrar-fachversand.com
     does it on the phone (Moritz, 2026-09-17); the outlined one counts its
     1px border into the 40 */
  .cart-drawer .btn { height: 40px; padding-top: 0; padding-bottom: 0; font-size: 16px; line-height: 24px; }
  .cart-drawer .btn img { width: 20px; height: 20px; }
  /* the totals above them at body size, like the phone cart on
     agrar-fachversand.com: lines 16px, the total a heading step, not the
     36px display size */
  .cart-drawer__foot { gap: 12px; padding-top: 16px; }
  .cart-drawer__lines { gap: 4px; font-size: 16px; line-height: 24px; }
  .cart-drawer__total { gap: 0; }
  .cart-drawer__total-row { font-size: 22px; line-height: 30px; letter-spacing: -0.44px; }
  .cart-drawer__note { font-size: 13px; line-height: 18px; }
  /* the page behind a full-screen panel must not scroll under the finger */
  html.cart-drawer-open { overflow: hidden; }
}

.stock-popup {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: 20px;
  overflow-y: auto;
  background: rgba(59, 58, 71, 0.8);
}
.stock-popup[hidden] { display: none; }
.stock-popup__box {
  position: relative;
  margin: auto;
  display: flex;
  flex-direction: column;
  gap: 24px;
  width: 640px;
  max-width: 100%;
  padding: 40px;
  border: 1px solid var(--light-blue);
  border-radius: var(--radius-card);
  background: #fff;
  box-shadow: var(--shadow-card);
}
.stock-popup__close { position: absolute; top: 15px; right: 15px; display: flex; padding: 0; }
.stock-popup__product { display: flex; align-items: center; gap: 16px; }
.stock-popup__img { flex: 0 0 100px; width: 100px; height: 100px; object-fit: contain; }
.stock-popup__meta { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.stock-popup__name { font-size: 18px; line-height: 26px; font-weight: 700; color: var(--blue); }
.stock-popup__state { font-size: 15px; line-height: 20px; color: var(--grey); }
.stock-popup__title { font-family: var(--font-display); font-size: 24px; line-height: 32px; font-weight: 500; color: var(--blue); }
.stock-popup__title span { color: var(--green); }
.stock-popup__title--done { display: none; }
.stock-popup .notify { max-width: none; }
.stock-popup .notify__row { padding-left: 24px; }
.stock-popup .notify__btn { padding: 16px 20px; font-weight: 700; }
.stock-popup .notify__btn img { display: none; }
.stock-popup .notify__note { text-align: center; }
/* done (997:2710): the title says thanks, the address stays in the field and
   the button becomes a tick; the row therefore stays, unlike on the product page */
.stock-popup.is-done .stock-popup__title { display: none; }
.stock-popup.is-done .stock-popup__title--done { display: block; }
.stock-popup .notify.is-done .notify__row { display: flex; }
.stock-popup .notify.is-done .notify__msg,
.stock-popup .notify.is-done .notify__note,
.stock-popup .notify.is-done .notify__btn span { display: none; }
.stock-popup .notify.is-done .notify__btn img { display: block; }
/* the AGB popup on the checkout (inc/checkout.php): the same dialog, wider,
   the page's text scrolling inside it */
.terms-popup__box { width: 880px; max-height: calc(100vh - 40px); gap: 16px; }
.terms-popup__title { padding-right: 40px; font-family: var(--font-display); font-size: 24px; line-height: 32px; font-weight: 500; color: var(--blue); }
.terms-popup__content { flex: 0 1 auto; min-height: 0; overflow-y: auto; padding-right: 8px; font-size: 16px; line-height: 26px; }
.terms-popup__content h2 { font-size: 22px; line-height: 30px; letter-spacing: 0; }
.terms-popup__content h3 { font-size: 18px; line-height: 26px; }
.terms-popup__content p { margin-bottom: 16px; }
.terms-popup__company { margin-bottom: 32px; color: var(--dark-grey); }
.terms-popup__company p { margin-bottom: 12px; }
.terms-popup__company p:first-child { font-weight: 600; color: var(--blue); }
@media (max-width: 900px) {
  /* 997:3066: 362px box, the field and the button stacked at full width */
  .stock-popup__box { width: 362px; padding: 40px 32px; }
  .terms-popup__box { width: 100%; padding: 32px 20px; }
  .stock-popup__img { flex-basis: 64px; width: 64px; height: 64px; }
  .stock-popup .notify__row { flex-direction: column; align-items: stretch; gap: 8px; padding: 0; border: 0; }
  /* the product page's flex: 1 1 0% would collapse the field to its text
     height in a column; here it is a fixed 58px row (997:3176) */
  .stock-popup .notify__input {
    flex: 0 0 58px;
    height: 58px;
    padding: 4px 4px 4px 16px;
    border: 1px solid var(--light-blue);
    border-radius: var(--radius-btn);
  }
  .stock-popup .notify__input:focus { border-color: var(--light-grey); }
  .stock-popup .notify__btn { justify-content: center; border-radius: var(--radius-btn); }
}
.product__price {
  font-family: var(--font-display);
  font-size: 40px;
  font-weight: 600;
  line-height: normal;
  letter-spacing: -1.6px;
  color: var(--blue);
}
/* On sale WooCommerce prints <del> regular </del> <ins> sale </ins>. The frame
   (647:2732) sets the struck regular price the same 40px as the sale price, in
   grey, 8px before it; the sale price keeps the navy and drops the underline
   <ins> carries by default. */
.product__price del {
  margin-right: 8px;
  color: var(--light-grey);
}
.product__price ins { text-decoration: none; }
.product__tax { font-size: 16px; font-weight: 500; color: var(--grey); }

/* the click's acknowledgement while WooCommerce's loading class is on the
   button — the card's ring, in white on the green ground */
/* the frame's buy button is 50px tall to line up with the quantity stepper's
   boxes, where the theme's default button is 58 */
.product__cart { position: relative; padding-top: 12px; padding-bottom: 12px; }
.product__cart.loading { pointer-events: none; color: transparent; }
.product__cart.loading img { opacity: 0; }
.product__cart.loading::after {
  content: '';
  position: absolute;
  left: 50%;
  top: 50%;
  width: 20px;
  height: 20px;
  margin: -10px 0 0 -10px;
  border: 2px solid rgba(255, 255, 255, 0.35);
  border-top-color: #fff;
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
}

.qty { display: flex; gap: 8px; }
.qty__value {
  width: 50px;
  height: 50px;
  text-align: center;
  font-size: 18px;
  font-weight: 600;
  line-height: 26px;
  color: var(--blue);
}
.qty__down img { transform: scaleY(-1); }
/* the design's field is a plain box; the stepper beside it does the stepping */
.qty__value { appearance: textfield; -moz-appearance: textfield; }
.qty__value::-webkit-outer-spin-button,
.qty__value::-webkit-inner-spin-button { appearance: none; margin: 0; }

.product__desc { display: flex; flex-direction: column; gap: 24px; }

/* Two foldable groups on the product page, the description and the Merkmale
   table, each behind its own toggle: both collapse to the height script.js
   measures against. The gradient names the section background in full instead
   of fading to `transparent`, which interpolates through grey in some engines.
   Over the spec rows it dims the stripes, which is the point: it says the table
   carries on. */
.product__fold.is-collapsed { position: relative; max-height: 470px; overflow: hidden; }
.product__fold.is-collapsed::after {
  content: "";
  position: absolute;
  inset: auto 0 0 0;
  height: 96px;
  background: linear-gradient(to bottom, rgba(239, 236, 249, 0), var(--light-blue));
  pointer-events: none;
}
/* The frame opens the description with one big heading and sets the rest a step
   down. Real descriptions from the shop use <h2> throughout, so the size comes
   from the position rather than the level. */
.product__desc h2,
.product__desc h3 { font-size: 28px; line-height: 40px; letter-spacing: 0; }
.product__desc h2:first-of-type {
  font-size: 40px;
  line-height: normal;
  letter-spacing: -1.6px;
}
.product__desc p { font-size: 18px; line-height: 26px; }
/* Prose lists keep their bullets. Figma stores them as one text node with line
   breaks, which reads in the metadata as though there were none — the rendered
   frame shows the discs, so check the render, not the node. */
.product__desc ul,
.shop-about__text ul { list-style: disc; padding-left: 20px; }
.product__desc ul { font-size: 18px; line-height: 26px; }

/* Manufacturer descriptions carry the occasional link, currently the horizont
   product videos. The global `a { color: inherit; text-decoration: none }` reset
   swallows them into the surrounding copy, so prose links get the green the text
   pages already use, plus a permanent underline: at 18px inside a dense block the
   colour alone still reads as body text. Scoped to the prose elements so that
   .product__download, a styled icon link, keeps its own look. */
.product__desc p a,
.product__desc li a,
.product__desc td a {
  color: var(--green);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.product__desc p a:hover,
.product__desc li a:hover,
.product__desc td a:hover { color: #00b895; }

/* the spec rows alternate white and half-white, which reads as a stripe over
   the lilac band without needing a second colour */
.product__spec {
  display: flex;
  gap: 40px;
  padding: 8px 16px;
  background: #fff;
  font-size: 18px;
  line-height: 26px;
}
.product__spec:nth-child(even) { background: rgba(255, 255, 255, 0.5); }
.product__spec dt { flex: 0 0 200px; font-weight: 600; }
.product__spec dd { flex: 1; }

/* related products: the home carousel with a heading above it */
/* the related row is the v2 carousel since frame 571:2249; the heading stands
   above the section, which follows 48 under it instead of its usual 64 */
.products__heading {
  margin: 80px 0 0 var(--page-margin);
  font-size: 60px;
  line-height: normal;
  letter-spacing: -2.4px;
}
.products__heading + .products--v2 { margin-top: 48px; }

/* ==========================================================================
   Form pages — the lilac card shared by Kontaktformular (772:2060) and Mein
   Konto (810:3255 Anmelden, 810:3923 Registrieren). Full nav bar and menu
   strip, breadcrumbs and title, then a card at the page margin, only as wide
   as the fields need, with the one rounded corner like the checkout's form
   card. The fields reuse .field/.field--half; the button reuses the green .btn.
   Contact- and account-specific rows layer on the shared .form-* base.

   The two-up wrapper is .field-row, NOT .form-row: WooCommerce owns .form-row
   on the live checkout, and this stylesheet ships there too.
   ========================================================================== */

.form-page { margin: 48px 0 80px; padding: 0 var(--page-margin); }

/* the lilac slab with the one rounded corner, like the checkout's form card */
.form-card {
  display: flex;
  flex-direction: column;
  gap: 40px;
  max-width: 1010px;
  padding: 32px;
  background: var(--light-blue);
  border-radius: 0 40px 0 0;
}

/* two fields to a row on the wide canvas, 24px between them (frame 772:2127) */
.field-row { display: flex; gap: 24px; }
.field-row .field { flex: 1; min-width: 0; }

/* the green CTA, full width up to 400 and centred, 700 as the frames draw it
   rather than the .btn default 600 */
.form-submit { width: 100%; max-width: 400px; justify-content: center; font-weight: 700; }

/* the required marker keeps the green the design gives it once the label floats */
.field__label .req { color: var(--green); }

/* front-end validation (Figma 837:6167, wired in home.js): the box goes red
   and the 13px note hangs under it. Inside the fixed-height .field boxes and
   the checkout's positioned rows the note sits absolute below the box; in the
   block-label forms (edit-address) it simply flows after the input. */
.field-error {
  margin: 4px 0 0;
  font-size: 13px;
  font-weight: 500;
  line-height: normal;
  color: var(--red);
}
label.field .field-error,
.checkout .form-row .field-error {
  position: absolute;
  left: 0;
  top: 100%;
  margin: 2px 0 0;
  white-space: nowrap;
}
.form-row.field--error { position: relative; }
/* the absolute note eats ~18px of the container's 20px row gap, which left the
   red line touching the next box (mobile checkout, 25.08.). An errored row
   reserves the note's height, so the error keeps the normal 20px of air to the
   field below it. Written out with the container chain because the margin: 0
   reset above carries four classes and would win otherwise. */
.checkout .form-row.field--error,
.checkout.woocommerce-checkout .checkout-fields > .form-row.field--error,
.checkout.woocommerce-checkout .field-group > .form-row.field--error {
  margin-bottom: 20px;
}
/* the placeholder's required star (home.js sets and places it): the theme's
   own font, small and raised beside the placeholder text; gone as soon as the
   field has content, exactly like the placeholder itself */
.ph-star {
  position: absolute;
  transform: translateY(-70%);
  font-size: 13px;
  font-weight: 600;
  line-height: 1;
  color: var(--light-grey);
  pointer-events: none;
}
input:not(:placeholder-shown) + .ph-star,
input:focus + .ph-star { display: none; }
/* password inputs end up wrapped in WooCommerce's show-password span, which
   breaks the sibling selector above — hide via the wrapper instead */
.password-input:has(input:not(:placeholder-shown)) + .ph-star,
.password-input:has(input:focus) + .ph-star { display: none; }
.checkout .form-row { position: relative; }
/* the guest hint follows the e-mail box directly; the errored row's reserved
   margin clears the absolute note, this tops the hint up to the same ~21px of
   air the fields below an error get (measured live, 25.08.) */
.checkout .form-row.field--error + .field__hint { margin-top: 12px; }
.field.field--error { border-color: var(--red); }
.form-row.field--error .input-text,
.form-row.field--error select,
.form-row.field--error input[type="checkbox"] { border-color: var(--red); }
/* under a checkbox row (the AGB box) the note flows after the label and wraps:
   the sentence is long, and the row has no fixed height for an absolute note
   to hang from. Indented past the 22px box, its 1px margin on both sides and
   the 8px gap, so it starts under the label's text. */
.checkout .form-row .checkbox ~ .field-error {
  position: static;
  white-space: normal;
  margin: 6px 0 0 32px;
}

/* --- Kontaktformular (772:2060) --------------------------------------- */

.contact__intro { display: flex; flex-direction: column; gap: 24px; }
.contact__intro h2 { font-size: 28px; line-height: 40px; color: var(--blue); }
.contact__address {
  display: flex;
  flex-direction: column;
  gap: 8px;
  font-size: 18px;
  line-height: 26px;
  color: var(--dark-grey);
}
.contact__address p { margin: 0; }
.contact__address .accent { color: var(--green); }

.contact__fields { display: flex; flex-direction: column; gap: 20px; }

/* the theme's own contact form (parts/contact-form.php, topro.nl): the page's
   text above it keeps the text-page type, but not its 840px flex basis, which
   in the card's column would become a height */
.form-card .text-page__content { flex: none; display: block; }
.contact__form { display: flex; flex-direction: column; gap: 20px; }
.contact__status { margin: 0; padding: 16px 20px; font-size: 18px; line-height: 26px; border-radius: 4px; background: #fff; }
.contact__status--ok { color: var(--green); border: 1px solid var(--green); }
.contact__status--error { color: var(--red); border: 1px solid var(--red); }

/* the message box: a tall field with the label pinned top-left, so the textarea
   fills the box below it rather than centring like the one-line fields */
.contact__message {
  height: 128px;
  align-items: stretch;
  /* 24/16/4 less the 1px border the field keeps inside the frame */
  padding: 23px 15px 3px 23px;
}
.contact__message textarea {
  width: 100%;
  height: 100%;
  resize: none;
  font-family: inherit;
  font-size: 18px;
  font-weight: 500;
  line-height: 26px;
  color: var(--dark-grey);
  background: none;
  border: none;
  outline: none;
}
.contact__message textarea::placeholder { color: var(--light-grey); }

/* --- Mein Konto — Anmelden / Registrieren (810:3255 / 810:3923) -------- */

/* the tab row: the current view a blue heading, the other a grey underlined
   link, both in the display face (frame 810:3697) */
.account-tabs {
  display: flex;
  gap: 24px;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 28px;
  line-height: 40px;
}
.account-tabs a { color: var(--light-grey); text-decoration: underline; }
.account-tabs a:hover { color: var(--green); }
.account-tabs .is-active { color: var(--blue); text-decoration: none; }

/* a field group: the inputs, the note and the checkboxes 24 apart (810:3662) */
.account-group { display: flex; flex-direction: column; gap: 24px; }
/* the register email sits at 560, not filling the row (frame 810:4022) */
.account-email { max-width: 560px; }
.account-note { font-size: 18px; line-height: 26px; color: var(--dark-grey); }
.account-note--bold { font-weight: 700; color: var(--blue); }
.account-forgot { font-size: 18px; font-weight: 700; line-height: 26px; color: var(--green); }
.account-forgot:hover { text-decoration: underline; }

/* the checkbox labels here are body text, not the checkout's 13px */
.check--lg { font-size: 18px; font-weight: 400; line-height: 26px; }


/* --- Kontaktformular: the live Gravity Form (id 1) inside the card ------ */

/* The form is the shop's own Gravity Form. home.js copies each field's label
   into its input as the placeholder and marks the wrapper ready, so the card
   shows the design's placeholder-labels instead of GF's labels above. */
.page--contact .gform_wrapper { margin: 0; }
.page--contact .gform_wrapper.gravity-theme .gform_fields {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: 20px 24px;
}
.page--contact .gform_wrapper.gravity-theme .gfield--width-half { grid-column: span 6; }
.page--contact .gform_wrapper.gravity-theme .gfield--width-full { grid-column: span 12; }
.page--contact .gform_wrapper .gfield { margin: 0; }
/* GF's own base CSS hides these; belt-and-braces so a spacer never shows */
.page--contact .gform_wrapper .gfield_visibility_hidden,
.page--contact .gform_wrapper .gfield--type-hidden,
.page--contact .gform_wrapper .gform_validation_container { display: none; }
/* once JS has moved the labels into placeholders, take the labels out of view */
.page--contact .gf-placeholders-ready .gfield_label {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}
/* the field box, like .field */
.page--contact .gform_wrapper .gfield input[type="text"],
.page--contact .gform_wrapper .gfield input[type="email"],
.page--contact .gform_wrapper .gfield input[type="tel"],
.page--contact .gform_wrapper .gfield textarea {
  width: 100%;
  height: 64px;
  padding: 0 15px 0 23px;
  background: #fff;
  border: 1px solid var(--light-blue);
  border-radius: 4px;
  font-family: inherit;
  font-size: 18px;
  font-weight: 500;
  line-height: normal;
  color: var(--dark-grey);
  box-shadow: none;
}
.page--contact .gform_wrapper .gfield textarea {
  height: 128px;
  padding: 23px 15px 3px 23px;
  line-height: 26px;
  resize: none;
}
.page--contact .gform_wrapper .gfield input::placeholder,
.page--contact .gform_wrapper .gfield textarea::placeholder { color: var(--light-grey); }
.page--contact .gform_wrapper .gfield input:focus,
.page--contact .gform_wrapper .gfield textarea:focus { outline: none; border-color: var(--green); }
.page--contact .gform_wrapper .gfield_required { color: var(--green); }
.page--contact .gform_wrapper .gfield_description.validation_message,
.page--contact .gform_wrapper .validation_message {
  color: var(--red);
  font-size: 13px;
  font-weight: 500;
  margin-top: 4px;
}
/* the submit: the green CTA, 40 under the fields as the frame draws it */
.page--contact .gform_wrapper .gform_footer { margin: 40px 0 0; padding: 0; }
.page--contact .gform_wrapper .gform_button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  max-width: 400px;
  padding: 16px 20px;
  background: var(--green);
  border: none;
  border-radius: var(--radius-btn);
  color: #fff;
  font-family: inherit;
  font-size: 18px;
  font-weight: 700;
  line-height: 26px;
  cursor: pointer;
}
.page--contact .gform_wrapper .gform_button:hover { background: #00b895; }

/* --- Mein Konto: WooCommerce's login/register forms in the card -------- */

/* the tabs are buttons in the theme (the toggle is client-side); the .is-active
   heading and the underlined links come from the shared .account-tabs rules */
.account-tab { font: inherit; background: none; border: none; padding: 0; cursor: pointer; color: var(--light-grey); text-decoration: underline; }
.account-tab:hover { color: var(--green); }
.account-tab.is-active { color: var(--blue); text-decoration: none; cursor: default; }

.page--account .woocommerce-notices-wrapper:empty { display: none; }
.page--account .woocommerce-notices-wrapper { margin: 0 0 24px; }

/* each form is a card-level column: the field cluster (an .account-group) 24
   apart, then 40 to the button */
.page--account .woocommerce-form-login,
.page--account .woocommerce-form-register {
  display: flex;
  flex-direction: column;
  gap: 40px;
  margin: 0;
}
/* the input sits bare inside our .field box: strip WooCommerce's own chrome */
/* Password managers (1Password) anchor their menu to the input's box. The
   .field floating-label otherwise shrinks the input to a thin line and shifts
   it when filled, so the 1Password menu landed in the wrong place. On the
   account fields the input fills the field's full height and the label stays a
   plain placeholder, so the input's box matches the field the user sees and the
   menu anchors right under it. */
.page--account .field input.input-text {
  width: 100%;
  height: 100%;
  padding: 0;
  border: none;
  background: none;
  box-shadow: none;
  font-family: inherit;
  font-size: 18px;
  font-weight: 500;
  line-height: normal;
  color: var(--dark-grey);
}
.page--account .field input.input-text:focus { outline: none; }
.page--account .field input.input-text::placeholder { color: var(--light-grey); }
/* The label floats here like everywhere else (Figma 837:5711): the base rule
   under .field__label hides it while the placeholder carries the name and pops
   it into the upper corner once the field has text. What the account page must
   NOT inherit is the base pattern's shrink-to-flex-end input, because the
   full-height input box is what anchors the 1Password menu (see above). So the
   input keeps height:100% in both states and the filled state instead drops
   the centred value below the label with top padding, which border-box absorbs
   without changing the box. */
.page--account .field:has(input.input-text:not(:placeholder-shown)) input.input-text {
  padding-top: 15px;
}
/* stretch the input to the field's full height in both states (base .field
   centres it, and shifts it to flex-end when filled), so height:100% fills */
.page--account .field,
.page--account .field:has(input.input-text:not(:placeholder-shown)) {
  align-items: stretch;
  padding: 0 15px 0 23px;
}
/* WooCommerce wraps the password input in <span class="password-input"> for its
   show-password button; that span shrinks to the input's default width, which
   left the input — and 1Password's inline icon — anchored mid-field. Make the
   wrapper fill the field so the input reaches its right edge. */
.page--account .field .password-input {
  display: block;
  flex: 1 1 auto;
  min-width: 0;
  width: 100%;
  height: 100%;
}

/* the register checkboxes (Mailchimp newsletter + GDPR): the drawn box at 18px.
   The remember-me box is a .check in the markup, so the shared .check rules
   style it; these cover WooCommerce/Mailchimp's own checkbox rows. */
.page--account .woocommerce-form-register .form-row { margin: 0; }
.page--account .woocommerce-form__label-for-checkbox {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  font-size: 18px;
  font-weight: 400;
  line-height: 26px;
  color: var(--dark-grey);
  cursor: pointer;
}
.page--account .woocommerce-form-register input.input-checkbox,
.page--account .woocommerce-form-register .woocommerce-form__input-checkbox {
  flex: 0 0 22px;
  width: 22px;
  height: 22px;
  margin: 1px;
  appearance: none;
  -webkit-appearance: none;
  background: #fff;
  border: 1px solid var(--light-grey);
  border-radius: 4px;
  cursor: pointer;
}
.page--account .woocommerce-form-register input.input-checkbox:checked,
.page--account .woocommerce-form-register .woocommerce-form__input-checkbox:checked {
  background: var(--green) url(assets/check-white.svg) center / 13.5px 9.81px no-repeat;
  border-color: var(--green);
}
/* the Mailchimp GDPR block: its intro is the design's bold prompt */
.page--account #mailchimp-gdpr-fields { display: flex; flex-direction: column; gap: 24px; margin: 0; }
/* The register group is a flex column with gap:24, so every zero-height wrapper
   WooCommerce/Mailchimp inject (clearfix divs, the hidden order-attribution
   inputs) still adds a 24px gap around itself. Take them out of the flow. */
.page--account .woocommerce-form-register .clear,
.page--account .woocommerce-form-register wc-order-attribution-inputs {
  display: none;
}
/* When the newsletter opt-in is unchecked, Mailchimp empties the GDPR options
   but leaves their wrapper reserving a flex slot, floating the Registrieren
   button far below the checkbox. Collapse the wrapper (its inline display:block
   needs !important) so the button follows the box. */
.page--account .woocommerce-form-register:has(#mailchimp_woocommerce_newsletter:not(:checked)) div:has(> #mailchimp-gdpr-fields) {
  display: none !important;
}
.page--account #mailchimp-gdpr-fields > p:first-child {
  margin: 0;
  font-size: 18px;
  font-weight: 700;
  line-height: 26px;
  color: var(--blue);
}
.page--account #mailchimp-gdpr-fields .clear { display: none; }
.page--account .mailchimp-newsletter { margin: 0; }
.page--account .woocommerce-form__label-for-checkbox span { display: inline; }

/* the submit + forgot carry .form-submit / .account-forgot from the markup */
.page--account .woocommerce-form-register__submit,
.page--account .woocommerce-form-login__submit { margin: 0; }

/* --- Mein Konto, logged in (837:2513 Dashboard, 848:11728 Adresse,
   848:11214 Kontodetails; mobile 837:8438 / 848:11985 / 848:11467) ---------
   WooCommerce emits .woocommerce-MyAccount-navigation and -content as
   siblings; the design draws the navigation as a white card of divider rows
   with a light outline icon on the right, and the endpoint content beside it.
   The frame's grid is 620px card + 70px + 840px content inside the 1530px
   between the page margins. */
.account-page .woocommerce {
  display: flex;
  align-items: flex-start;
  gap: 70px;
}
/* WooCommerce's clearfix (.woocommerce::before / ::after, content " ",
   display table) turns into two empty flex items here, and each one costs a
   70px gap: the card sat 70px in from the margin and the content column ran
   140px short of the frame's 840 (seen on prod 2026-09-04). */
.account-page .woocommerce::before,
.account-page .woocommerce::after { display: none; }
.account-page .woocommerce-MyAccount-navigation {
  flex: 0 0 620px;
  padding: 32px;
  background: #fff;
  border: 1px solid var(--light-blue);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-card);
  box-sizing: border-box;
}
.account-page .woocommerce-MyAccount-navigation ul { margin: 0; padding: 0; list-style: none; }
.account-page .woocommerce-MyAccount-navigation li { padding: 24px 0; }
.account-page .woocommerce-MyAccount-navigation li + li { border-top: 1px solid var(--divider); }
.account-page .woocommerce-MyAccount-navigation li:first-child { padding-top: 0; }
.account-page .woocommerce-MyAccount-navigation li:last-child { padding-bottom: 0; }
.account-page .woocommerce-MyAccount-navigation a {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  height: 48px;
  color: var(--blue);
  font-family: var(--font-display);
  font-size: 24px;
  font-weight: 500;
  line-height: 32px;
  text-decoration: none;
}
.account-page .woocommerce-MyAccount-navigation a:hover,
.account-page .woocommerce-MyAccount-navigation .is-active a { color: var(--green); }
/* the icons are masks over a plain color, so the active page's icon goes
   green with its row while the exported SVGs keep a single baked-in color */
.account-page .woocommerce-MyAccount-navigation a::after {
  content: '';
  flex: 0 0 48px;
  width: 48px;
  height: 48px;
  background: var(--light-grey);
  -webkit-mask: center / contain no-repeat;
  mask: center / contain no-repeat;
}
.account-page .woocommerce-MyAccount-navigation a:hover::after,
.account-page .woocommerce-MyAccount-navigation .is-active a::after { background: var(--green); }
.account-page .woocommerce-MyAccount-navigation-link--dashboard a::after { -webkit-mask-image: url(assets/icon-acct-home.svg); mask-image: url(assets/icon-acct-home.svg); }
/* the orders glyph is drawn 42x40 inside its 48px box, not full-bleed */
.account-page .woocommerce-MyAccount-navigation-link--orders a::after { -webkit-mask-image: url(assets/icon-acct-orders.svg); mask-image: url(assets/icon-acct-orders.svg); -webkit-mask-size: 42px 40px; mask-size: 42px 40px; }
.account-page .woocommerce-MyAccount-navigation-link--edit-address a::after { -webkit-mask-image: url(assets/icon-acct-address.svg); mask-image: url(assets/icon-acct-address.svg); }
.account-page .woocommerce-MyAccount-navigation-link--edit-account a::after { -webkit-mask-image: url(assets/icon-acct-user.svg); mask-image: url(assets/icon-acct-user.svg); }
.account-page .woocommerce-MyAccount-navigation-link--customer-logout a::after { -webkit-mask-image: url(assets/icon-acct-exit.svg); mask-image: url(assets/icon-acct-exit.svg); }

/* the content column: the design's type on whatever the endpoint renders */
.account-page .woocommerce-MyAccount-content {
  flex: 1;
  min-width: 0;
  font-size: 18px;
  line-height: 26px;
  color: var(--dark-grey);
}
.account-page .woocommerce-MyAccount-content > :first-child { margin-top: 0; }
.account-page .woocommerce-MyAccount-content h2 {
  margin: 0 0 32px;
  font-size: 36px;
  line-height: normal;
  letter-spacing: -1.44px;
  color: var(--blue);
}
.account-page .woocommerce-MyAccount-content h3 {
  margin: 0 0 24px;
  font-size: 28px;
  line-height: 40px;
  color: var(--blue);
}
.account-page .woocommerce-MyAccount-content p { margin: 0 0 32px; }
.account-page .woocommerce-MyAccount-content a { color: var(--green); }
.account-page .woocommerce-MyAccount-content a:hover { text-decoration: underline; }
/* notices become the design's lavender card (827:366's info panel) */
.account-page .woocommerce-MyAccount-content .woocommerce-message,
.account-page .woocommerce-MyAccount-content .woocommerce-info {
  margin: 0 0 24px;
  padding: 20px 24px;
  background: var(--light-blue);
  border: 0;
  border-radius: 0 12px 0 0;
  color: var(--dark-grey);
}
.account-page .woocommerce-MyAccount-content .woocommerce-message::before,
.account-page .woocommerce-MyAccount-content .woocommerce-info::before { display: none; }
/* A notice with a button: woocommerce.css floats the button right, and on a
   phone the text wrapped around it ("Bestät|ige"). Core puts the button first
   (e-mail confirmation) or last ("Keine Bestellung"), so the notice becomes a
   column and order moves the button under the text in both (2026-09-28).
   :has keeps notices with plain inline links in normal text flow. */
.account-page .woocommerce-MyAccount-content .woocommerce-info:has(> .button),
.account-page .woocommerce-MyAccount-content .woocommerce-message:has(> .button) {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 16px;
}
.account-page .woocommerce-MyAccount-content .woocommerce-info > .button,
.account-page .woocommerce-MyAccount-content .woocommerce-message > .button { float: none; order: 1; margin: 0; }
/* buttons anywhere in the content: the design's green CTA */
.account-page .woocommerce-MyAccount-content .button:not(.btn),
.account-page .woocommerce-MyAccount-content button[type='submit']:not(.btn) {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 14px 20px;
  border: none;
  border-radius: var(--radius-btn);
  background: var(--green);
  color: #fff;
  font-family: var(--font-body);
  font-size: 16px;
  font-weight: 600;
  line-height: 24px;
  text-decoration: none;
  cursor: pointer;
}
.account-page .woocommerce-MyAccount-content .button:not(.btn):hover,
.account-page .woocommerce-MyAccount-content button[type='submit']:not(.btn):hover {
  background: #00b895;
  text-decoration: none;
  color: #fff;
}
/* --- Bestellungen + Bestellung (1062:3353 / 3689 / 3927 / 4212) ----------
   Both tables in the frames' language: an 18/26 header row in bold dark
   grey, rows on 1px dividers with 8px above and below, 40px between the
   columns, nothing else. The orders list is core's myaccount/orders.php as
   it is; the order view is our view-order.php over core's markup. */
.account-page .woocommerce-MyAccount-content table {
  width: 100%;
  margin: 0 0 24px;
  border-collapse: collapse;
  border: 0;
  table-layout: fixed;
}
/* .shop_table in the selector: WooCommerce's `.woocommerce table.shop_table td`
   (two classes, two elements) otherwise keeps its 9px 12px padding and
   1px border-top over these two-class rules */
.account-page .woocommerce-MyAccount-content .shop_table th,
.account-page .woocommerce-MyAccount-content .shop_table td {
  padding: 8px 40px 8px 0;
  border: 0;
  border-bottom: 1px solid var(--divider);
  background: none;
  font-size: 18px;
  line-height: 26px;
  font-weight: 400;
  color: var(--dark-grey);
  text-align: left;
  vertical-align: middle;
}
.account-page .woocommerce-MyAccount-content .shop_table th:last-child,
.account-page .woocommerce-MyAccount-content .shop_table td:last-child { padding-right: 0; }
.account-page .woocommerce-MyAccount-content .shop_table thead th,
.account-page .woocommerce-MyAccount-content .shop_table tfoot th { font-weight: 700; }
/* WooCommerce's stylesheet bolds tfoot cells (two classes, three elements)
   and stripes rows */
.account-page .woocommerce-MyAccount-content .order_details tfoot td { font-weight: 400; }
.account-page .woocommerce-MyAccount-content tbody tr:nth-child(2n) td,
.account-page .woocommerce-MyAccount-content tbody tr:nth-child(2n) th { background: none; }
/* only the date stays on one line: status ("Bezahlung ausstehend") and total
   (a refund shows old and new amount) can be wider than their fixed column
   and spilled into the next cell while nowrap (2026-09-28) */
.account-page .woocommerce-MyAccount-content .account-orders-table .woocommerce-orders-table__cell-order-date { white-space: nowrap; }
/* Bestellungen: 100 / 128 / 140 / 220 (the cells' 40px right padding is
   the gap), the button fills what is left: 132px on the 840px column */
.account-page .account-orders-table .woocommerce-orders-table__header-order-number { width: 100px; }
.account-page .account-orders-table .woocommerce-orders-table__header-order-date { width: 128px; }
.account-page .account-orders-table .woocommerce-orders-table__header-order-status { width: 140px; }
.account-page .account-orders-table .woocommerce-orders-table__header-order-total { width: 220px; }
.account-page .account-orders-table tbody th a { font-weight: 700; color: var(--green); }
.account-page .account-orders-table tbody th a:hover { text-decoration: none; }
/* the green 40px button, in the list and under the order view alike */
.account-page .woocommerce-MyAccount-content .woocommerce-orders-table__cell-order-actions .button:not(.btn),
.account-page .woocommerce-MyAccount-content .order_details .order-actions-button:not(.btn) {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  max-width: 400px;
  height: 40px;
  margin: 0 0 8px;
  padding: 0 20px;
  border: 0;
  border-radius: var(--radius-btn);
  background: var(--green);
  font-size: 18px;
  line-height: 26px;
  font-weight: 700;
  color: #fff;
  text-decoration: none;
  white-space: nowrap;
}
.account-page .woocommerce-MyAccount-content .woocommerce-orders-table__cell-order-actions .button:not(.btn):last-child,
.account-page .woocommerce-MyAccount-content .order_details .order-actions-button:not(.btn):last-child { margin-bottom: 0; }
.account-page .woocommerce-MyAccount-content .woocommerce-orders-table__cell-order-actions .button:not(.btn):hover,
.account-page .woocommerce-MyAccount-content .order_details .order-actions-button:not(.btn):hover { background: #00b895; text-decoration: none; }
.account-page .woocommerce-MyAccount-content .order_details .order-actions td { text-align: right; }
.account-page .woocommerce-MyAccount-content .order_details .order-actions-button:not(.btn) { display: inline-flex; width: auto; }

/* Bestellung: the updates block over the details */
.account-page .order-view__back {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 32px;
  font-weight: 700;
}
.account-page .order-view__back img { width: 24px; height: 24px; transform: scaleX(-1); }
.account-page .order-view__updates { display: flex; flex-direction: column; gap: 16px; margin: 0 0 32px; }
.account-page .order-view__updates p { margin: 0; }
/* the frame sets the whole status sentence in regular weight */
.account-page .order-view__updates mark { background: none; color: inherit; font-weight: 400; }
.account-page .order-view__note-date { font-weight: 700; }
/* Bestelldetails, Rechnungsadresse, Lieferadresse are the frame's 28/40 */
.account-page .woocommerce-MyAccount-content h2.woocommerce-order-details__title,
.account-page .woocommerce-MyAccount-content h2.woocommerce-column__title {
  margin: 0 0 24px;
  font-size: 28px;
  line-height: 40px;
  letter-spacing: 0;
}
.account-page .woocommerce-order-details { margin: 0 0 32px; }
/* the item table: Produkt 160 / Stückpreis 128 / Menge 140, Gesamtpreis
   takes the rest and sits right; the totals' labels bold, values right */
.account-page .order_details .product-name { width: 160px; }
.account-page .order_details .product-unit-price { width: 128px; }
.account-page .order_details .product-quantity-cell { width: 140px; }
.account-page .woocommerce-MyAccount-content .order_details .product-total,
.account-page .woocommerce-MyAccount-content .order_details tfoot td { text-align: right; }
.account-page .order_details .product-unit-price,
.account-page .order_details .product-quantity-cell,
.account-page .order_details .product-total { white-space: nowrap; }
.account-page .order_details tbody td a { color: var(--dark-grey); }
.account-page .woocommerce-MyAccount-content .order_details tfoot th { font-weight: 700; }
/* the addresses stack, in running type; core's <address> would be italic */
.account-page .woocommerce-customer-details .woocommerce-columns--addresses::before,
.account-page .woocommerce-customer-details .woocommerce-columns--addresses::after { display: none; }
.account-page .woocommerce-customer-details .woocommerce-column { float: none; width: 100%; margin: 0 0 32px; }
.account-page .woocommerce-customer-details .woocommerce-column:last-child { margin-bottom: 0; }
.account-page .woocommerce-customer-details address {
  padding: 0;
  border: 0;
  border-radius: 0;
  font-style: normal;
  font-size: 18px;
  line-height: 26px;
  color: var(--dark-grey);
}
.account-page .woocommerce-customer-details address p { margin: 0; }
/* WooCommerce hangs icon-font glyphs before the phone and mail lines and
   indents the lines for them */
.account-page .woocommerce-customer-details address .woocommerce-customer-details--phone,
.account-page .woocommerce-customer-details address .woocommerce-customer-details--email { padding-left: 0; }
.account-page .woocommerce-customer-details--phone::before,
.account-page .woocommerce-customer-details--email::before { display: none; }
@media (max-width: 900px) {
  /* Bestellungen (1062:3689): every order a block of label / value lines
     with the button across, blocks on dividers. WooCommerce's own responsive
     table rules (shop_table_responsive, two classes and three elements)
     float the label and force the value right with !important; three
     classes here outrank them. */
  .account-page .woocommerce-MyAccount-content .account-orders-table,
  .account-page .woocommerce-MyAccount-content .account-orders-table tbody,
  .account-page .woocommerce-MyAccount-content .account-orders-table tr,
  .account-page .woocommerce-MyAccount-content .account-orders-table th,
  .account-page .woocommerce-MyAccount-content .account-orders-table td { display: block; width: auto; }
  .account-page .woocommerce-MyAccount-content .account-orders-table thead { display: none; }
  .account-page .woocommerce-MyAccount-content .account-orders-table { border-top: 1px solid var(--divider); }
  .account-page .woocommerce-MyAccount-content .account-orders-table tbody tr {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 8px 0;
    border-bottom: 1px solid var(--divider);
  }
  .account-page .woocommerce-MyAccount-content .account-orders-table tbody th,
  .account-page .woocommerce-MyAccount-content .account-orders-table tbody td {
    display: flex;
    justify-content: flex-start;
    padding: 0;
    border: 0;
    background: none !important;
    text-align: right !important;
  }
  /* the label takes the left, everything after it (core wraps the amount in
     a span beside plain text) packs to the right as one run */
  .account-page .woocommerce-MyAccount-content .account-orders-table tbody th::before,
  .account-page .woocommerce-MyAccount-content .account-orders-table tbody td::before {
    content: attr(data-title);
    float: none;
    flex: 0 0 auto;
    margin-right: auto;
    padding-right: 8px;
    font-weight: 700;
    text-align: left;
  }
  /* The total is amount + bare text ("für 1 Artikel"), for a refund a <del> and
     an <ins> before it. As flex items the spaces between them vanished
     ("9,40 €0,00 €") and the text wrapped as its own narrow box, so this
     cell flows as plain inline text with the label floated left (2026-09-28). */
  .account-page .woocommerce-MyAccount-content .account-orders-table tbody td.woocommerce-orders-table__cell-order-total { display: block; }
  .account-page .woocommerce-MyAccount-content .account-orders-table tbody td.woocommerce-orders-table__cell-order-total::before { float: left; }
  .account-page .woocommerce-MyAccount-content .orders__title,
  .account-page .woocommerce-MyAccount-content .order-view__title { font-size: 36px; letter-spacing: -1.44px; }
  .account-page .woocommerce-MyAccount-content .account-orders-table .woocommerce-orders-table__cell-order-actions::before { display: none; }
  .account-page .woocommerce-MyAccount-content .account-orders-table .woocommerce-orders-table__cell-order-actions { display: block; }
  .account-page .woocommerce-MyAccount-content .woocommerce-orders-table__cell-order-actions .button:not(.btn) { max-width: none; }

  /* Bestellung (1062:4212): an item is "Produkt" over its name, then the
     three amounts with their headings above them; the totals stay label
     left, value right; the Anmerkung stacks. */
  .account-page .woocommerce-MyAccount-content .order_details,
  .account-page .woocommerce-MyAccount-content .order_details tbody,
  .account-page .woocommerce-MyAccount-content .order_details tfoot,
  .account-page .woocommerce-MyAccount-content .order_details tr,
  .account-page .woocommerce-MyAccount-content .order_details th,
  .account-page .woocommerce-MyAccount-content .order_details td { display: block; width: auto; }
  .account-page .woocommerce-MyAccount-content .order_details thead { display: none; }
  .account-page .woocommerce-MyAccount-content .order_details th,
  .account-page .woocommerce-MyAccount-content .order_details td { padding: 0; border: 0; background: none !important; }
  .account-page .woocommerce-MyAccount-content .order_details tbody tr {
    display: grid;
    grid-template-columns: 100px 100px minmax(0, 1fr);
    column-gap: 20px;
    row-gap: 8px;
    padding: 8px 0;
    border-bottom: 1px solid var(--divider);
  }
  .account-page .woocommerce-MyAccount-content .order_details tbody td::before {
    content: attr(data-title);
    display: block;
    margin-bottom: 8px;
    font-weight: 700;
  }
  .account-page .woocommerce-MyAccount-content .order_details tbody .product-name { grid-column: 1 / -1; }
  .account-page .woocommerce-MyAccount-content .order_details tbody .product-unit-price,
  .account-page .woocommerce-MyAccount-content .order_details tbody .product-quantity-cell { text-align: left; }
  .account-page .woocommerce-MyAccount-content .order_details tbody .product-total { text-align: right; }
  .account-page .woocommerce-MyAccount-content .order_details tbody .product-purchase-note td { grid-column: 1 / -1; }
  .account-page .woocommerce-MyAccount-content .order_details tbody .product-purchase-note td::before { display: none; }
  .account-page .woocommerce-MyAccount-content .order_details tfoot tr {
    display: flex;
    justify-content: space-between;
    gap: 8px;
    padding: 8px 0;
    border-bottom: 1px solid var(--divider);
  }
  .account-page .woocommerce-MyAccount-content .order_details tfoot th { flex: 0 0 auto; }
  .account-page .woocommerce-MyAccount-content .order_details tfoot .order-note,
  .account-page .woocommerce-MyAccount-content .order_details tfoot .order-actions { flex-direction: column; }
  .account-page .woocommerce-MyAccount-content .order_details tfoot .order-note td,
  .account-page .woocommerce-MyAccount-content .order_details tfoot .order-actions td { text-align: left; }
  .account-page .woocommerce-MyAccount-content .order_details .order-actions-button:not(.btn) { display: flex; width: 100%; max-width: none; }
}
/* address / account-details forms: the design's white field boxes */
.account-page .woocommerce-MyAccount-content .form-row { margin: 0 0 16px; padding: 0; }
.account-page .woocommerce-MyAccount-content .form-row label { display: block; margin: 0 0 6px; font-size: 14px; font-weight: 500; color: var(--blue); }
.account-page .woocommerce-MyAccount-content .form-row .input-text,
.account-page .woocommerce-MyAccount-content .form-row select {
  width: 100%;
  height: 56px;
  padding: 0 20px;
  border: 1px solid var(--light-blue);
  border-radius: 4px;
  background: #fff;
  box-sizing: border-box;
  font-family: inherit;
  font-size: 17px;
  color: var(--dark-grey);
}
.account-page .woocommerce-MyAccount-content .form-row .input-text:focus,
.account-page .woocommerce-MyAccount-content .form-row select:focus { outline: 2px solid var(--green); outline-offset: 0; }
.account-page .woocommerce-MyAccount-content fieldset { margin: 24px 0; padding: 0; border: 0; }
.account-page .woocommerce-MyAccount-content legend { margin: 0 0 12px; font-weight: 600; color: var(--blue); }

/* the dashboard welcome (837:2646): the greeting in the design's Big Text.
   The temporary-password notice is WooCommerce's own (resend button, rate
   limit); it lands in the notices wrapper above the content column, dressed
   as the design's lavender one-round-corner card with the button under the
   text — the markup puts the resend link first, column-reverse turns it. */
.account-page .account-hello { font-size: 22px; line-height: 40px; }
.page--account .woocommerce-notices-wrapper .woocommerce-info,
.page--account .woocommerce-notices-wrapper .woocommerce-message {
  display: flex;
  flex-direction: column-reverse;
  align-items: flex-start;
  gap: 24px;
  margin: 0 0 32px;
  padding: 32px;
  background: var(--light-blue);
  border: 0;
  border-radius: 0 40px 0 0;
  font-size: 18px;
  line-height: 26px;
  color: var(--dark-grey);
}
.page--account .woocommerce-notices-wrapper .woocommerce-info::before,
.page--account .woocommerce-notices-wrapper .woocommerce-message::before { display: none; }
.page--account .woocommerce-notices-wrapper .woocommerce-info a.button,
.page--account .woocommerce-notices-wrapper .woocommerce-message a.button {
  display: flex;
  justify-content: center;
  width: 100%;
  max-width: 400px;
  padding: 16px 20px;
  border-radius: var(--radius-btn);
  background: var(--green);
  color: #fff;
  font-size: 18px;
  font-weight: 700;
  line-height: 26px;
  text-decoration: none;
}
.page--account .woocommerce-notices-wrapper .woocommerce-info a.button:hover,
.page--account .woocommerce-notices-wrapper .woocommerce-message a.button:hover { background: #00b895; }
.account-page .account-contact { margin: 0; padding: 0 0 0 27px; list-style: disc; }

/* Adresse (848:12364): the two address types stacked, each heading + green
   edit link + the saved address or the empty-state line */
.account-page .account-addresses { display: flex; flex-direction: column; gap: 32px; }
.account-page .account-address h3 { margin: 0 0 24px; }
.account-page .account-address__edit { display: inline-block; margin: 0 0 24px; }
.account-page .account-address address { font-style: normal; }
.account-page .account-address .account-address__none { margin: 0; }

/* Kontodetails (848:11347): the column's 32px rhythm on the form, the field
   groups 20px apart inside it. The single-field rows hold the design's half
   width (408 of 840). */
.account-page form.account-details {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 32px;
}
.account-page form.account-details h2,
.account-page form.account-details h3 { margin: 0; }
.account-page .account-fields { display: flex; flex-direction: column; gap: 20px; width: 100%; }
.account-page .account-fields .field-row { width: 100%; }
.account-page .field-row--single .field { flex: 0 0 calc(50% - 12px); }
.account-page form.account-details .form-submit { margin: 0; }

/* the newsletter block: inside the .account-mc wrapper the plugin renders the
   design's single "Bestell-Aktualisierungen" checkbox (swapped in through its
   mailchimp_woocommerce_my_account_field filter, see functions.php) and the
   marketing permissions under #mailchimp-gdpr-fields. There checkbox and
   label are SIBLINGS, so the block is a wrapping flex row: each line holds
   box + label vertically centred, and the plugin's .clear divs are the line
   breaks (full-basis items) rather than floats. */
.check--body { font-size: 18px; font-weight: 400; line-height: 26px; }
.account-page .account-mc { display: flex; flex-direction: column; gap: 16px; }
.page--account .account-mc #mailchimp-gdpr-fields {
  display: flex;
  /* row + zero row-gap stated outright: the register card's own
     #mailchimp-gdpr-fields rule says column with gap 24, and any property
     this rule stays silent on falls back to that one */
  flex-direction: row;
  flex-wrap: wrap;
  align-items: center;
  gap: 0 8px;
  margin: 16px 0 0;
}
.page--account .account-mc #mailchimp-gdpr-fields > p:first-child {
  flex: 0 0 100%;
  margin: 0 0 8px;
  font-size: 18px;
  font-weight: 700;
  line-height: 26px;
  color: var(--blue);
}
.page--account .account-mc #mailchimp-gdpr-fields .clear { display: block; flex: 0 0 100%; height: 16px; }
.page--account .account-mc #mailchimp-gdpr-fields input[type='checkbox'] {
  flex: 0 0 22px;
  width: 22px;
  height: 22px;
  margin: 1px;
  padding: 0;
  appearance: none;
  -webkit-appearance: none;
  background: #fff;
  border: 1px solid var(--light-grey);
  border-radius: 4px;
  cursor: pointer;
}
.page--account .account-mc #mailchimp-gdpr-fields input[type='checkbox']:checked {
  background: var(--green) url(assets/check-white.svg) center / 13.5px 9.81px no-repeat;
  border-color: var(--green);
}
.page--account .account-mc #mailchimp-gdpr-fields label {
  flex: 0 1 auto;
  margin: 0;
  font-size: 18px;
  font-weight: 400;
  line-height: 26px;
  color: var(--dark-grey);
  cursor: pointer;
}

@media (max-width: 900px) {
  /* the mobile frame keeps 20px page margins for the logged-in area; only the
     logged-out login card runs edge to edge (the .form-page padding: 0 below) */
  .form-page.account-page { padding: 0 20px; }
  .account-page .woocommerce { flex-direction: column; gap: 32px; }
  .account-page .woocommerce-MyAccount-navigation { flex: none; width: 100%; padding: 24px 20px; }
  .account-page .woocommerce-MyAccount-navigation li { padding: 16px 0; }
  /* the mobile frame drops the dashboard's welcome line and goes straight to
     the greeting (837:8438) */
  .account-page .account-welcome { display: none; }
  .account-page .woocommerce-MyAccount-content h2 { font-size: 28px; letter-spacing: -1.12px; }
  .account-page .woocommerce-MyAccount-content h3 { font-size: 24px; line-height: 32px; }
  .account-page .field-row--single .field { flex: 1 1 auto; }
}
.page--account .woocommerce-form-login .account-forgot { margin: 0; }

/* --- out-specify WooCommerce's own woocommerce.css (still enqueued here) --- */

/* WC gives form.login/.register a bordered, padded box (`.woocommerce form.login`,
   0,2,1). The card is the frame, so strip it — with a higher-specificity match. */
.page--account .account-card form.woocommerce-form-login,
.page--account .account-card form.woocommerce-form-register {
  border: none;
  padding: 0;
  margin: 0;
  border-radius: 0;
}

/* remember-me: WC's own rememberme label styling can override .check's flex row,
   which drops the box out of vertical-centre. Force it. */
.page--account .woocommerce-form-login label.woocommerce-form-login__rememberme {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0;
}

/* register checkboxes: `.woocommerce form .form-row input.input-checkbox` (0,3,2)
   sets display:inline + negative margins, which collapses our sized box — the
   pre-checked newsletter one vanished entirely. Beat it (0,4,2) and give the box
   an explicit inline-block size so width/height apply. */
.page--account .woocommerce-form-register label.woocommerce-form__label-for-checkbox {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  font-size: 18px;
  font-weight: 400;
  line-height: 26px;
  color: var(--dark-grey);
  cursor: pointer;
}
.page--account .woocommerce-form-register label.woocommerce-form__label-for-checkbox input.input-checkbox {
  flex: 0 0 22px;
  display: inline-block;
  width: 22px;
  height: 22px;
  margin: 0;
  padding: 0;
  appearance: none;
  -webkit-appearance: none;
  background: #fff;
  border: 1px solid var(--light-grey);
  border-radius: 4px;
  cursor: pointer;
  vertical-align: middle;
}
.page--account .woocommerce-form-register label.woocommerce-form__label-for-checkbox input.input-checkbox:checked {
  background: var(--green) url(assets/check-white.svg) center / 13.5px 9.81px no-repeat;
  border-color: var(--green);
}
.page--account .woocommerce-form-register label.woocommerce-form__label-for-checkbox span {
  display: inline;
  margin: 0;
}

/* WooCommerce's JS inserts a password show/hide eye (span.show-password-input);
   it free-floats over our .field box, so drop it. */
.page--account .show-password-input { display: none; }

/* --- Checkout: the same Mailchimp newsletter/GDPR checkboxes appear on the
   checkout, where WooCommerce's woocommerce.css leaves them as tiny native
   boxes. Style them like the checkout's other checkboxes (this mirrors the
   account rules above, scoped to the checkout at 13px). Beats woocommerce.css's
   `.woocommerce form .form-row input.input-checkbox` (0,3,2) at (0,4,2). --- */
.page--checkout .checkout label.woocommerce-form__label-for-checkbox {
  display: flex;
  align-items: center;
  gap: 8px;
  width: fit-content;
  max-width: 100%;
  margin: 0;
  font-size: 13px;
  font-weight: 500;
  line-height: normal;
  color: var(--dark-grey);
  cursor: pointer;
}
/* the newsletter row's label also carries WooCommerce's "inline" class, and
   `.woocommerce form .form-row label.inline { display: inline }` (0,3,2)
   beats the rule above (0,3,1): the box and the text then sit on a text
   line, 3px closer than the flex rows around it (Moritz' phone screenshot,
   2026-09-10) */
.page--checkout .checkout label.woocommerce-form__label-for-checkbox.inline { display: flex; }
.page--checkout .checkout label.woocommerce-form__label-for-checkbox input.input-checkbox {
  flex: 0 0 22px;
  display: inline-block;
  width: 22px;
  height: 22px;
  /* 1px like .check input, so every checkbox column starts on the same x */
  margin: 1px;
  padding: 0;
  appearance: none;
  -webkit-appearance: none;
  background: #fff;
  border: 1px solid var(--light-grey);
  border-radius: 4px;
  cursor: pointer;
  vertical-align: middle;
}
.page--checkout .checkout label.woocommerce-form__label-for-checkbox input.input-checkbox:checked {
  background: var(--green) url(assets/check-white.svg) center / 13.5px 9.81px no-repeat;
  border-color: var(--green);
}
.page--checkout .checkout label.woocommerce-form__label-for-checkbox span { display: inline; margin: 0; }
/* the Mailchimp GDPR block on checkout: intro prompt + the two options, spaced */
.page--checkout .checkout #mailchimp-gdpr-fields { display: flex; flex-direction: column; gap: 8px; margin: -8px 0 0; }
.page--checkout .checkout #mailchimp-gdpr-fields > p:first-child { margin: 0; font-size: 13px; font-weight: 600; color: var(--blue); }
.page--checkout .checkout #mailchimp-gdpr-fields .clear { display: none; }
/* padding 0: WooCommerce's .form-row padding pushed this row 3px right of
   every other checkbox */
.page--checkout .checkout .mailchimp-newsletter { margin: 0; padding: 0; }
/* Germanized's required checkboxes (AGB/Datenschutz/Widerruf) print the star
   as its own span after the text span. The label is a flex row, so the star
   became a separate flex item and sat at the far right of the whole text
   block instead of after "akzeptieren." (Moritz, 2026-09-16). Hide that span
   and append the star to the text itself; the screen-reader "Erforderlich"
   span stays. */
.page--checkout .checkout label.woocommerce-form__label-for-checkbox .woocommerce-gzd-legal-checkbox-text ~ .required { display: none; }
.page--checkout .checkout label.woocommerce-form__label-for-checkbox .woocommerce-gzd-legal-checkbox-text:has(~ .required)::after {
  content: "\00a0*";
  color: #a00;
  font-weight: 700;
}


/* ==========================================================================
   Mobile — Figma frames "Home Mobile" (346:123) and "Menu Open" (376:91)

   The design ships two canvases and nothing between them: 1728px and 402px.
   Above the breakpoint script.js scales the 1728px canvas to the viewport, so
   the fixed-pixel desktop layout holds its proportions down to roughly 900px.
   At 900px it hands over to this block, which drops the absolute positioning
   for normal flow and a 20px page margin, and stays fluid from there down —
   402px is the design width, not a minimum, and phones narrower than that are
   common.

   Only the geometry changes. The type scale, colours, radii and shadows are
   the same tokens as the desktop canvas, except where Figma states otherwise:
   the hero H1 (72 -> 44px), the testimonial quote (48 -> 28px), the section
   headings (60 -> 40px) and the FAQ questions (28 -> 24px).
   ========================================================================== */

@media (max-width: 900px) {

  :root { --page-margin: 20px; }

  /* decorative bleeds (brochure vector et al.) reach past the right edge;
     unclipped they widen the layout viewport (435px on the 2026-08-21
     screenshot) and the whole page pans sideways into white space. Clip at
     the root — the bleed look is exactly a clip at the viewport edge. iOS
     then also stops treating taps as potential pan gestures. */
  html, body { overflow-x: hidden; overflow-x: clip; }
  /* a horizontally pannable page made Safari hold taps back for the
     double-tap-zoom decision — the menu button felt dead. Opting the
     controls out of double-tap zoom removes that delay for good. */
  a, button { touch-action: manipulation; }

  .page {
    width: 100%;
    position: relative;
  }

  /* --- nav bar: one 68px row (canvas "A: kompakter Kopf", 2026-09-22) ---- */

  /* The frame (346:124) stacked the logo row and the search field into 170px.
     Since 2026-09-22 the bar is one row: menu button left, the logo centred
     at 118px, the magnifier and the cart right. The field waits behind the
     magnifier (home.js focuses it, FiboSearch opens its overlay) and the
     account icon moved into the menu. That gives the product page about
     100px of its first screen back: 94 % of the paid clicks land there on a
     phone, and the price and the button have to be on screen before the
     first scroll. */
  .navbar { height: 68px; }
  .navbar__logo {
    left: 50%;
    top: 15px;
    transform: translateX(-50%);
    transition: transform .12s ease, opacity .12s ease;
  }
  .navbar__logo img { width: 118px; height: 37px; }
  /* a tap on the logo navigates with no visible response otherwise — press
     feedback so the touch registers before the next page arrives */
  .navbar__logo:active { transform: translateX(-50%) scale(.94); opacity: .6; }

  /* the controls are bare 44px glyphs in this row, hung off the two edges so
     they stay put on any width */
  .navbar__cart,
  .navbar__menu-btn,
  .navbar__search-toggle {
    left: auto;
    top: 12px;
    width: 44px;
    height: 44px;
  }
  .navbar__account { display: none; }
  .navbar__cart { right: 16px; }
  .navbar__search-toggle { right: 60px; }
  .navbar__menu-btn { left: 12px; right: auto; }
  .navbar__cart .icon-btn,
  .navbar__menu-btn,
  .navbar__search-toggle {
    width: 44px;
    height: 44px;
    border-color: transparent;
    background: transparent;
  }
  .navbar__cart-num { left: 24px; top: -4px; }

  .navbar__menu-btn,
  .navbar__search-toggle { display: inline-flex; position: absolute; }
  /* stacked so the button keeps one box while the glyphs cross-fade */
  .navbar__menu-btn img { position: absolute; transition: opacity 0.2s ease; }
  .navbar__menu-close { opacity: 0; }
  .is-menu-open .navbar__menu-btn { background: var(--blue); border-color: var(--blue); }
  .is-menu-open .navbar__menu-open { opacity: 0; }
  .is-menu-open .navbar__menu-close { opacity: 1; }

  /* closed, the field is clipped to a pixel under the bar: still in the
     document and focusable, so the magnifier can hand it the focus that
     opens the plugin's overlay. display: none would take the focus with it. */
  .navbar__search {
    left: var(--page-margin);
    right: var(--page-margin);
    top: 60px;
    width: auto;
    height: 1px;
    opacity: 0;
    clip-path: inset(50%);
    pointer-events: none;
  }
  .navbar__info { display: none; }

  /* --- menu open (376:91) — the nav bar grows around the list ----------- */

  /* Open, the bar reads top to bottom: hotline block at 84, rule at 148, the
     menu list at 172, in two columns, filled column-first (the first half of
     the rows left, the rest right), and the search under the list (Moritz,
     2026-09-21: whoever opens the menu came for the categories, and few
     visitors search, about 2 % of mobile sessions). Every offset is the
     frame's less the 22px the bar lost on 2026-09-22. The rows come from the
     shop's menu, which grows when categories are added, so home.js counts
     them into --menu-rows and measures the open list into --menu-list-h
     (184px is the frame's five-row column, kept as fallback); the search and
     the bar's lower edge ride on it: list, 24px, the 48px field, 24px. */
  .is-menu-open .navbar { height: calc(var(--menu-list-h, 184px) + 268px); }
  .is-menu-open .navbar__search {
    top: calc(var(--menu-list-h, 184px) + 196px);
    height: 48px;
    opacity: 1;
    clip-path: none;
    pointer-events: auto;
  }
  .is-menu-open .navbar__info {
    display: flex;
    left: var(--page-margin);
    right: auto;
    top: 84px;
    gap: 8px;
    font-size: 13px;
    font-weight: 500;
    line-height: 18px;
  }
  /* the rule between the hotline block and the list (848:11191) */
  .is-menu-open .navbar::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    top: 148px;
    border-top: 1px solid var(--light-blue);
  }
  /* the desktop menu strip becomes the vertical list inside that panel */
  .menu { display: none; }
  /* the panel travels with the nav bar, which is pinned to the top of the
     viewport — hence fixed rather than absolute against the page, which would
     leave the links behind at the document's top once the page is scrolled.
     There is no zoom below the breakpoint, so fixed lands on real pixels. */
  .is-menu-open .menu {
    display: block;
    position: fixed;
    z-index: 21;
    left: var(--page-margin);
    right: var(--page-margin);
    top: calc(var(--sticky-top, 0px) + 172px);
    height: auto;
    background: none;
  }
  /* two equal columns filled top to bottom, as the frame reads: a grid
     rather than CSS columns, because column boxes truncate margins at the
     break unevenly, while row-gap keeps the measured list height exact */
  .is-menu-open .menu__list {
    display: grid;
    grid-auto-flow: column;
    grid-template-rows: repeat(var(--menu-rows, 5), auto);
    grid-auto-columns: 1fr;
    gap: 20px 64px;
    height: auto;
    padding-left: 0;
  }
  /* the row is as tall as its label; without this the list item's own
     strut makes every row taller and the panel outgrows the frame */
  .is-menu-open .menu__list li { line-height: 20px; }
  .is-menu-open .menu__list a { font-size: 15px; }
  /* the account rows close the list, with the glyph the bar used to carry */
  .is-menu-open .menu__account { display: block; }
  .is-menu-open .menu__account a { display: flex; align-items: center; gap: 8px; }

  /* --- hero (348:345) — 402 x 627 --------------------------------------- */

  .hero { height: 627px; background: #fff; }
  /* the media sits above the copy instead of beside it, and the dark ground
     is a band rather than the angled shape the desktop canvas uses */
  .hero__slide::before {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    /* one pixel under the media's 226px edge: on fractional device-pixel
       ratios the two edges round apart and a white hairline of page ground
       shows between video and band (Moritz' phone, 2026-08-06). The band
       slides behind the opaque media instead; same bottom edge. */
    top: 225px;
    height: 364px;
    background: var(--blue);
  }
  .hero__media {
    left: 0;
    right: 0;
    width: 100%;
    height: 226px;
  }
  .hero__shape,
  .hero__product,
  .hero__off { display: none; }

  .hero__content {
    left: var(--page-margin);
    right: var(--page-margin);
    top: 266px;
    width: auto;
  }
  /* the goal slide's desktop panel dissolves into the band layout here — the
     position must be restated too, since the panel rule's two classes outrank
     this block's plain .hero__content */
  .hero__slide--goal { background: none; }
  .hero__slide--goal .hero__content {
    left: var(--page-margin);
    right: var(--page-margin);
    top: 250px;
    width: auto;
    padding: 0;
    background: none;
    border-radius: 0;
  }
  /* the goal copy is three sentences, not slide 2's three short bullets: at
     the band's 18px it runs under the dots and the Trusted-Shops seal, so it
     steps down to the small-text size and starts a touch higher */
  .hero__slide--goal .hero__lead { font-size: 15px; line-height: 22px; }
  /* the short H1 variant — the long one breaks onto two lines here */
  .hero__title-long { display: none; }
  .hero__title-short { display: inline; }
  .hero h1 { font-size: 44px; letter-spacing: -1.76px; }
  .hero__lead { font-size: 18px; line-height: 26px; }
  /* the 24px icon sets the button's row height in the frame, not the label */
  .hero .btn--lg { line-height: 24px; }
  .hero__bullets li { font-size: 18px; line-height: 26px; }
  .hero__dots { left: var(--page-margin); top: 533px; }
  .hero__badge { left: auto; right: var(--page-margin); top: 470px; }

  /* --- product carousel (348:331) — one card per view ------------------- */

  .products { height: 610px; margin-top: 20px; }
  /* the viewport is a native scroller here: a swipe is the gesture a touch
     user reaches for, snap keeps a card per view, and the arrows drive
     scrollLeft (script.js). scroll-behavior stays in CSS so a programmatic
     scroll glides — and the tests can turn it off without touching the code */
  .products__viewport {
    width: 100%;
    height: 528px;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scroll-padding-left: var(--page-margin);
    scroll-behavior: smooth;
    scrollbar-width: none;
  }
  .products__viewport::-webkit-scrollbar { display: none; }
  .products__track { gap: 20px; }
  /* one card, with the page margin left and right of it: the track's padding
     is already outside this percentage, so only one margin is subtracted */
  .product-card {
    flex-basis: calc(100% - var(--page-margin));
    width: auto;
    height: 528px;
    scroll-snap-align: start;
  }
  /* the shot is centred at 240px rather than filling the card's full width */
  .product-card__img {
    left: 50%;
    transform: translateX(-50%);
    top: 24px;
    width: 240px;
    height: 240px;
  }
  .product-card__info { top: 284px; }

  /* The mobile tile of 2026-08-31 (837:1480): 362 wide at content height,
     the 200px shot centred, the name in the 18/26 body bold, a two-line 15px
     description, the price row 20px under the text (434 with a one-line
     name). Every card keeps its own content height: one card fills the view
     here, so a sold-out tile's extra line is never seen next to a shorter
     one, while a row pinned to a stretched foot would leave a hole under the
     text of every card that has no extra line. The arrows float at the
     viewport's edges under short white fades. */
  .products--v2 { height: auto; margin-top: 2px; }
  /* the shadow reaches 24px below the card; the scroller would clip it */
  .products--v2 .products__viewport { height: auto; padding-top: 0; padding-bottom: 24px; }
  .products--v2 .products__track { padding-left: var(--page-margin); align-items: flex-start; }
  .products--v2 .product-card {
    flex-basis: calc(100% - var(--page-margin));
    display: flex;
    flex-direction: column;
    width: auto;
    height: auto;
    padding: 20px;
  }
  /* the theme wraps the shot in a link; its line box must not add a descender */
  .products--v2 .product-card > a { display: block; line-height: 0; }
  .products--v2 .product-card__img {
    position: static;
    display: block;
    left: auto;
    top: auto;
    width: 200px;
    height: 200px;
    margin: 0 auto 12px;
    transform: none;
  }
  .products--v2 .product-card__info { position: static; flex: 0 0 auto; gap: 12px; margin-bottom: 20px; overflow: visible; }
  .products--v2 .product-card h3 {
    height: auto;
    max-height: 52px;
    font-family: var(--font-body);
    font-size: 18px;
    line-height: 26px;
    font-weight: 700;
  }
  .products--v2 .product-card__desc {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    font-size: 15px;
    line-height: 20px;
    font-weight: 400;
    max-height: 40px;
  }
  .products--v2 .product-card__ticks { display: flex; }
  .products--v2 .product-card__row { position: static; margin-top: 0; }
  /* The fades shrink to short tails behind the arrows. The frame parks both
     over the shot (116px); Moritz wants them on the card's vertical middle
     (2026-08-06) — a documented deviation. */
  .products--v2::before,
  .products--v2::after { top: calc(50% - 25px); bottom: auto; height: 50px; width: 90px; }
  .products--v2 .products__arrows .icon-btn { top: 50%; transform: translateY(-50%); }
  .products--v2 .products__prev { left: 0; }
  .products--v2 .products__next { right: 0; }

  /* --- testimonials (346:202) ------------------------------------------- */

  .testimonials {
    height: auto;
    margin-top: 40px;
    padding: 40px var(--page-margin);
  }
  .testimonials__video {
    position: relative;
    left: auto;
    top: auto;
    width: 100%;
    height: 266px;
  }
  .testimonials__video > img { width: 100%; height: 266px; }
  .testimonials__play {
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
  }
  .testimonials__body {
    position: relative;
    left: auto;
    top: auto;
    flex-direction: column;
    width: auto;
    margin-top: 32px;
  }
  /* At 28px the light-on-dark bloom that the desktop quote corrects for is
     negligible, and the lighter weight costs a line break: weight 350 fits the
     quote into four lines where the frame sets five. */
  .testimonials blockquote {
    font-size: 28px;
    line-height: 36px;
    letter-spacing: -1.12px;
    font-weight: 400;
  }
  /* author over button rather than side by side */
  .testimonials__meta { flex-direction: column; align-items: stretch; gap: 28px; }

  /* every button that spans the column centres its label and steps down a
     size; only the hero keeps the desktop 18px/600 (btn--lg) */
  .brochure__intro .btn,
  .newsletter__form .btn,
  .testimonials__meta .btn {
    justify-content: center;
    font-size: 16px;
    font-weight: 500;
    /* the icon, not the label, sets the row height in the frame */
    line-height: 24px;
  }
  /* Figma aligns strokes to the inside of a frame, so the padding it states
     already contains the 1px stroke. CSS puts the border outside the padding
     box, so every bordered box here takes the border back out of its padding —
     otherwise each one is 2px taller than the frame and the error accumulates
     down the page. */
  .testimonials__meta .btn--ghost { padding: 15px 19px; }

  /* same reason: the frame's separator is a zero-height stroke */
  .testimonials__line { margin-bottom: -1px; }

  /* --- services (348:394) ----------------------------------------------- */

  .services { height: auto; padding: 40px 0; }
  .services__heading { font-size: 40px; letter-spacing: -1.6px; }
  .services__grid {
    grid-template-columns: 1fr;
    gap: 20px;
    margin: 32px var(--page-margin) 0;
  }
  /* photo on top, copy underneath */
  .service-card {
    flex-direction: column;
    width: auto;
    height: auto;
    padding-bottom: 40px;
  }
  .service-card__img {
    flex: 0 0 auto;
    width: 100%;
    height: auto;
    aspect-ratio: 1;
    border-radius: var(--radius-card) var(--radius-card) 0 0;
  }
  /* the photo now fades downwards into the copy instead of sideways */
  .service-card__img::after {
    background: linear-gradient(to top, #fff 0%, rgba(255, 255, 255, 0) 50%);
  }
  .service-card h3 { font-size: 28px; line-height: 40px; letter-spacing: 0; }
  .service-card__text { width: auto; margin: 24px 24px 0; }

  /* --- unser team: no mobile frame; the portrait keeps its size, snaps - */

  .team__heading { margin-top: 40px; }
  h2.team__heading + .team { margin-top: 24px; }
  .team-card { scroll-snap-align: start; }
  /* on the photo's middle, not the column's: the names hang below it */
  .team .products__arrows .icon-btn { top: 175px; transform: none; }
  .team::before,
  .team::after { top: 175px; }

  /* --- broschüre + newsletter (450:481) --------------------------------- */

  /* source order is intro, newsletter, cover; the mobile frame leads with the
     book, so the three blocks are reordered rather than moved in the markup */
  .brochure {
    height: auto;
    margin-top: 40px;
    padding: 40px var(--page-margin);
    display: flex;
    flex-direction: column;
  }
  /* the vector bleeds off the right edge behind the book */
  .brochure__vector { right: -42px; top: -10px; width: 297px; height: 171px; }
  .brochure__cover {
    order: 1;
    position: relative;
    left: auto;
    top: auto;
    width: 240px;
    height: 288px;
    margin: 0 auto;
  }
  .brochure__book { width: 240px; height: 287px; }
  .brochure__shadow { left: 66px; top: 281px; width: 106px; height: 7px; }
  .brochure__intro {
    order: 2;
    position: relative;
    left: auto;
    top: auto;
    width: auto;
    align-items: stretch;
    margin-top: 24px;
  }
  .brochure h2 { font-size: 40px; letter-spacing: -1.6px; }
  /* Every mobile frame draws this paragraph 8 lines tall (256px); the
     browser's DM Sans wraps the same copy into 7, which left every mobile
     page 32px short through the band. The drawn height is reserved instead
     of chasing Figma's line breaks, which no font metric guarantees. */
  .brochure__intro p { font-size: 20px; line-height: 32px; min-height: 256px; }

  .newsletter {
    order: 3;
    position: relative;
    left: auto;
    top: auto;
    width: auto;
    height: auto;
    margin-top: 40px;
    padding: 31px 23px;  /* 32/24 less the 1px border — see above */
  }
  .newsletter__text p { font-size: 20px; line-height: 32px; }
  .newsletter__form { padding: 3px 3px 3px 15px; }
  .newsletter__form input { height: 53px; }
  /* no icon in this one, so the label alone sets the height */
  .newsletter__form .btn { line-height: normal; }

  /* --- FAQ (348:543) ---------------------------------------------------- */

  .faq { margin-top: 40px; }
  .faq__heading { font-size: 40px; line-height: normal; letter-spacing: -1.6px; }
  .faq__list { gap: 32px; margin-top: 64px; }
  .faq__item { padding-top: 32px; }
  .faq__item::before,
  .faq__contact::before { width: 100%; }
  .faq__item summary { align-items: flex-start; gap: 16px; }
  .faq__item summary h3 {
    max-width: none;
    font-size: 24px;
    line-height: 28px;
  }
  /* the answer keeps to the question's column rather than running under the
     toggle: 50px button plus the 16px gap beside it */
  .faq__answer { width: calc(100% - 66px); gap: 32px; padding-top: 24px; }
  .faq__answer p { font-size: 20px; line-height: 32px; }
  .faq__contact { width: auto; margin-top: 32px; }
  .faq__contact::before { top: -32px; }
  .faq__contact p { font-size: 20px; line-height: 32px; }

  /* --- footer (348:612) — one column ------------------------------------ */

  .footer { margin-top: 40px; }
  .footer__main {
    height: auto;
    display: flex;
    flex-direction: column;
    gap: 32px;
    padding: 40px var(--page-margin);
  }
  .footer__col {
    position: static;
    left: auto;
    top: auto;
  }
  .footer__col--brand { display: flex; flex-direction: column; }
  .footer__contact { width: auto; }
  .footer__col ul { width: auto; }
  /* the three blocks of the last column become columns of their own */
  .footer__col--last { display: contents; }

  .footer__bottom { height: 98px; }

  /* --- shop (444:248) and its filter panel (444:1543) ------------------- */

  .page--shop .footer { margin-top: 40px; }

  .breadcrumbs { gap: 8px; margin-top: 24px; }

  /* one column: the head, the category list, the grid and the paging all
     become rows of the same stack, which is what lets the list fold out
     between the sort row and the products */
  .shop {
    height: auto;
    min-height: 0; /* sidebar is in flow here, so no reserved height is needed */
    margin-top: 40px;
    padding: 0 var(--page-margin);
    display: flex;
    flex-direction: column;
    gap: 24px;
  }
  .shop__main { display: contents; }
  .shop__head {
    order: 1;
    flex-direction: column;
    align-items: stretch;
    gap: 24px;
    height: auto;
  }
  .shop__head h1 { letter-spacing: -1.6px; }
  .shop__sort { justify-content: flex-start; gap: 16px; }
  .shop__sort p { display: none; }
  .shop__sort-field { width: auto; flex: 1; }

  .shop__filter-btn { display: inline-flex; width: 48px; height: 48px; }
  .shop__filter-btn img { position: absolute; transition: opacity 0.2s ease; }
  /* the open state has no white chevron asset of its own — it is the sort
     field's chevron inverted and turned to point back up */
  .shop__filter-close { opacity: 0; filter: brightness(0) invert(1); transform: scaleY(-1); }
  .is-filter-open .shop__filter-btn { background: var(--green); border-color: var(--green); }
  .is-filter-open .shop__filter-open { opacity: 0; }
  .is-filter-open .shop__filter-close { opacity: 1; }

  .shop__side {
    order: 2;
    position: static;
    width: auto;
    display: none;
  }
  .is-filter-open .shop__side { display: block; }

  .shop__grid { order: 3; grid-template-columns: 1fr; gap: 20px; margin-top: 0; }
  /* frame 638:887 stacks the cards at their content's height, like the cart's
     cross-sells — the 505px box is the desktop grid's */
  .shop__grid .product-card { height: auto; }
  .pagination { order: 4; margin-top: 0; }
  .pagination__extra { display: none; }

  /* --- das tier im fokus (450:436) -------------------------------------- */

  .shop-about {
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    margin-top: 40px;
    padding: 0 var(--page-margin);
  }
  .shop-about__text {
    flex: 0 0 auto;
    width: auto;
  }
  .shop-about__text h2 { font-size: 40px; letter-spacing: -1.6px; }

  .usp {
    flex: 0 0 auto;
    width: auto;
    margin-top: 32px;
    padding: 23px 19px;  /* 24/20 less the 1px border */
  }

  /* text page: one column, the card under the content (the .usp margin above
     provides the gap) */
  .text-page__title { margin-top: 24px; font-size: 40px; letter-spacing: -1.6px; }
  .text-page {
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    margin: 24px 0 40px;
  }
  .text-page__content { flex: 0 0 auto; width: auto; font-size: 18px; line-height: 28px; }
  .text-page__content h2 { font-size: 28px; }

  /* --- wissenbank (456:48) ---------------------------------------------- */

  /* the sidebar has no room, so the categories become the field in the head;
     there is no fold-out list here, so no filter button either */
  .shop--wissen .shop__side,
  .shop--wissen .shop__filter-btn { display: none; }
  .shop--wissen .shop__sort { display: flex; }
  /* stacked over the category field, 16 to it against the head's 24 */
  .wissen__search { width: auto; margin-bottom: -8px; }

  .wissen__grid { order: 3; grid-template-columns: 1fr; gap: 20px; margin-top: 0; }
  .article-card__img { height: 200px; }
  .article-card .btn { align-self: stretch; justify-content: center; }

  .shop-about--wissen { min-height: 0; }
  .shop-about--wissen .usp { align-self: auto; }

  /* --- warenkorb (475:890) ---------------------------------------------- */

  .page--cart .footer { margin-top: 40px; }

  /* the title row stacks: title, then the back link, then the items */
  .cart__head {
    flex-direction: column;
    align-items: flex-start;
    gap: 24px;
    margin: 40px var(--page-margin) 0;
  }
  .cart__title { font-size: 40px; letter-spacing: -1.6px; }

  /* One column, and the suggestions move behind the summary boxes — which they
     cannot do from inside the left column, so it steps out of the way and the
     four blocks are ordered directly. */
  div.cart {
    flex-direction: column;
    align-items: stretch;
    gap: 24px;
    margin: 24px var(--page-margin) 0;
  }
  /* The form only exists in the WordPress template, where it wraps the items so
     a quantity change can post itself. It must not become a stacking step
     between .cart and .cart__items, or the ordering below has nothing to sort. */
  .cart__main,
  .cart__form { display: contents; }
  .cart__side { flex: 0 0 auto; width: auto; order: 3; }
  .cart__items { order: 1; }

  /* The mobile item card (571:3895) puts the photo and the price side by side
     and the name, the stepper and the delete link below, which the desktop
     nesting cannot do — so the wrappers step out of the way and the children
     wrap into rows themselves. 20/32 padding less the border. */
  .cart-item { flex-wrap: wrap; align-items: center; padding: 32px 20px; }
  .cart-item__body,
  .cart-item__text { display: contents; }
  .page .cart-item__img { order: 1; flex: 0 0 128px; width: 128px; height: 128px; margin-bottom: 24px; }
  .cart-item__price { order: 2; margin-bottom: 24px; }
  .cart-item h2 { order: 3; flex: 1 0 100%; margin-bottom: 16px; }
  .cart-item__qty { order: 4; flex: 1 0 100%; margin-bottom: 16px; }
  .cart-item__delete { order: 5; }

  .cart-box { padding: 31px 19px; }
  .cart-box__head img { flex: 0 0 40px; width: 40px; height: 40px; }
  .cart-box__pay { gap: 16px; }
  .cart-box__tile { width: 96px; height: 42px; }

  /* the column's own 24px gap supplies the rest of the frame's 40 */
  .suggest { order: 4; margin-top: 16px; }
  .suggest__heading { font-size: 40px; letter-spacing: -1.6px; }
  .suggest__grid { grid-template-columns: 1fr; gap: 20px; }
  /* full width, following its content — the frame's stacked cards each take
     their own height — with the shot centred. The shot sits inside the card's
     link, not directly in the flex column, so it centres via auto margins; the
     carousel's translateX(-50%) (which pairs with left: 50% there) must not
     leak in — on this static image it would shove the shot half out of the
     card to the left. */
  .suggest__grid .product-card { width: auto; height: auto; }
  .suggest__grid .product-card__img {
    align-self: center;
    display: block;
    margin-inline: auto;
    transform: none;
  }
  .suggest__grid .product-card__info { flex: 0 0 auto; }
  .suggest__grid .product-card__row { margin-top: 20px; }

  /* --- bestellbestätigung (599:7548) ------------------------------------- */

  /* the columns stack; the back link stays, 32 under the slim bar */
  .confirm { flex-direction: column; align-items: stretch; gap: 24px; margin-top: 24px; }
  .confirm__main { flex: 0 0 auto; }
  .confirm .checkout__side { flex: 0 0 auto; width: auto; }
  .confirm-card { padding: 24px 20px; }
  /* the lead keeps 20px to what follows; everything else stays at the 16 */
  .confirm-card__lead { margin-bottom: 4px; }
  .confirm-order { gap: 20px; }
  /* the address boxes breathe a little wider here than the checkout's do */
  .page--confirm .checkout__side .cart-box { gap: 24px; }
  /* the fact columns stack, one under the other */
  .confirm-facts { flex-direction: column; gap: 16px; }
  /* a total wraps onto two lines, label over value; the head and item rows
     stay side by side, an item's name being the part that wraps */
  .confirm-order__row--total { flex-direction: column; gap: 4px; }
  /* an item folds to two lines: the name over "Stückpreis × Menge", the
     Gesamtpreis at the right of both; the head keeps Produkt and Gesamtpreis */
  .confirm-order__row--head { grid-template-columns: minmax(0, 1fr) auto; }
  .confirm-order__row--head p:nth-child(2),
  .confirm-order__row--head p:nth-child(3) { display: none; }
  /* the name spans the flexible track, so it wraps instead of widening the
     two content-sized tracks the Stückpreis and Menge sit in */
  .confirm-order__row--item {
    grid-template-columns: max-content max-content minmax(0, 1fr) auto;
    grid-template-areas: "name name name total" "unit qty . total";
    column-gap: 6px;
    row-gap: 4px;
  }
  .confirm-order__row--item .confirm-order__name { grid-area: name; }
  .confirm-order__row--item .confirm-order__unit { grid-area: unit; text-align: left; }
  .confirm-order__row--item .confirm-order__qty { grid-area: qty; text-align: left; }
  .confirm-order__row--item .confirm-order__total { grid-area: total; }
  .confirm-order__actions { flex-direction: column; gap: 16px; }

  /* --- bestellung (487:430) --------------------------------------------- */

  /* the slim bar keeps its full-size logo: there is no search or cart beside
     it competing for the row, so it does not have to shrink the way the
     ordinary nav bar does */
  .navbar--slim { height: 104px; }
  .navbar--slim .navbar__logo { top: 20px; }
  .navbar--slim .navbar__logo img { width: 203px; height: 64px; }

  .page--checkout .footer { margin-top: 40px; }
  .footer--slim .footer__main { height: auto; gap: 32px; }
  .footer__legal { flex-direction: column; gap: 24px; }
  .footer--slim .footer__bottom {
    height: auto;
    flex-direction: column;
    align-items: flex-start;
    gap: 16px;
    padding: 40px var(--page-margin);
  }
  .footer--slim .footer__bottom-text { gap: 16px; margin-top: 0; }

  .checkout__back { margin-top: 32px; }

  .checkout__head {
    flex-direction: column;
    align-items: flex-start;
    gap: 4px;
    margin-top: 40px;
  }
  .checkout__head h1 { font-size: 32px; letter-spacing: -1.28px; }

  /* the card first, the summary under it (1097:5237); until the steps the
     summary led, which put a whole box between the heading and the first
     button */
  /* the desktop grid on the .woocommerce box is undone here: the box is a
     block again and carries the gutter, the form is the flex column */
  .page--checkout .checkout-wrap > .woocommerce { display: block; }
  .page--checkout .checkout-wrap > .woocommerce > form.checkout { display: flex; }
  .checkout {
    flex-direction: column;
    align-items: stretch;
    gap: 24px;
    margin: 24px 0 0;
  }
  .checkout__form,
  .checkout__side { flex: 0 0 auto; width: auto; }
  .checkout__side { order: 2; }
  .page--checkout .checkout__side { margin-left: 0; }
  .checkout__form { order: 1; gap: 24px; padding: 24px 20px; }

  .checkout__side .cart-box { padding: 23px 19px; gap: 20px; }
  /* the ordinary mobile summary box drops its icon to 40px; this one keeps 48 */
  .checkout__side .cart-box__head img { flex: 0 0 48px; width: 48px; height: 48px; }
  .cart-box--sum { gap: 4px; }

  /* the coupon row per the mobile frame (837:10380/81): the field's text at
     the frame's 15px "Small Text", and the Anwenden button sized by its
     content (20px sides) instead of the desktop's fixed 160px — at 393px
     that fixed width squeezed the field to ~97px and the 18px placeholder
     truncated to "Code einge" */
  .coupon-fold__field input { font-size: 15px; }
  .coupon-fold__apply { flex: 0 0 auto; padding: 0 20px; }

  /* the price moves above the name instead of sitting off to the right, so the
     row becomes a grid with the photo spanning both of its rows */
  .summary__row {
    display: grid;
    grid-template-columns: 100px 1fr;
    align-items: center;
    column-gap: 16px;
    row-gap: 4px;
  }
  /* the review's row is a <td>, which the desktop rule above sets to flex */
  .checkout-review__table td.summary__row { display: grid; }
  .summary__img { grid-area: 1 / 1 / 3 / 2; }
  .summary__price { grid-area: 1 / 2 / 2 / 3; }
  .summary__text { grid-area: 2 / 2 / 3 / 3; }
  .summary__price {
    font-family: var(--font-body);
    font-size: 18px;
    font-weight: 600;
    line-height: 26px;
  }

  .checkout-total__row .checkout-total__value { font-size: 28px; line-height: 40px; letter-spacing: 0; }

  /* "Anmelden" has no room beside the heading here */
  .checkout-block__head { flex-direction: column; align-items: flex-start; gap: 8px; }

  /* the pairs stack, so the halves go back to their own height instead of
     splitting the row between them */
  .checkout-fields__row { flex-direction: column; gap: 20px; }
  .checkout-fields__row .field { flex: 0 0 64px; }

  .choice__label { font-size: 16px; line-height: normal; }
  .choice__logo--wide { width: 48px; height: 7px; }

  .checkout__submit { max-width: none; }

  /* WooCommerce's fields: the pairs stack here too */
  .checkout.woocommerce-checkout .checkout-fields > .form-row.farmula-half { flex: 0 0 100%; }
  .field--half { width: 100%; }
  .checkout .field-group { width: auto; }
  /* the card's section gap is 24px here, so that is what gets cancelled */
  .checkout .woocommerce-shipping-fields { margin-top: -24px; }
  .checkout .woocommerce-additional-fields { margin-top: -4px; }

  /* --- Form pages: Kontaktformular + Mein Konto (810:2696 / 810:3055) ---- */

  /* the card runs edge to edge with 20px of its own, keeping the one rounded
     corner; the field pairs stack, except Wohnort/Telefonnummer which the
     frame keeps two-up (810:3002) */
  .form-page { padding: 0; }
  .form-card { max-width: none; padding: 20px; }
  .field-row { flex-direction: column; gap: 20px; }
  /* stacked, the desktop's flex:1 (basis 0) would run along the new main axis
     and squash the 64px field height — let the boxes keep their own size */
  .field-row:not(.field-row--pair) .field { flex: none; }
  .field-row--pair { flex-direction: row; gap: 24px; }
  .form-submit { max-width: none; }


  /* GF stacks its half fields on the narrow canvas */
  .page--contact .gform_wrapper.gravity-theme .gfield--width-half { grid-column: span 12; }
  .page--contact .gform_wrapper .gform_button { max-width: none; }

  /* --- blog article (461:1611) ------------------------------------------ */

  .page--article .footer { margin-top: 0; }

  .article__title {
    margin: 40px var(--page-margin) 0;
    font-size: 40px;
    letter-spacing: -1.6px;
  }

  /* who wrote it moves above the piece, with a rule between the two */
  .article {
    flex-direction: column;
    /* the row layout starts the two columns at the same top edge; once
       they stack, flex-start would instead size each one to its own
       content and let a wide child overflow the page */
    align-items: stretch;
    gap: 24px;
    margin: 40px var(--page-margin) 0;
  }
  .article__meta { order: -1; flex: 0 0 auto; gap: 24px; }
  /* the column's own gap already spaces this off the last block, so it adds
     none of its own; the negative margin keeps it a zero-height stroke */
  .article__meta::after {
    content: "";
    display: block;
    margin-bottom: -1px;
    border-top: 1px solid var(--divider);
  }
  .article__body { flex: 0 0 auto; min-width: 0; gap: 24px; }
  /* a comparison table has a min-content width of its own that no amount of
     wrapping gets under 390px, so it scrolls sideways in its own box
     instead of pushing the piece off the page; display:block is what puts
     the overflow on the table element rather than on its wrapper box */
  .article__text table { display: block; max-width: 100%; overflow-x: auto; }

  .more { margin: 40px var(--page-margin) 0; }
  .more__heading { margin-bottom: 24px; font-size: 40px; letter-spacing: -1.6px; }
  .more__grid { grid-template-columns: 1fr; gap: 20px; }
  .more__grid .article-card__img { height: 200px; }

  /* --- product details (444:1895) --------------------------------------- */

  .page--product .footer { margin-top: 40px; }

  /* The product page's first screen follows the canvas "A: kompakter Kopf"
     (2026-09-22) rather than frame 444:1895; its rules sit in the block at
     the foot of this file. What stays here is the gallery's mechanics. */

  /* with more than one shot the single photo gives way to the swipe strip: a
     native horizontal scroller with one shot per view, snapped, the same
     gesture the related-products carousel uses. :has keeps the single-image
     case showing the plain photo. */
  .product__card:has(.product__slides) > .product__photo { display: none; }
  .product__slides {
    display: flex;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scroll-behavior: smooth;
    scrollbar-width: none;
  }
  .product__slides::-webkit-scrollbar { display: none; }
  /* every slide shares one frame. A flex row is only ever as tall as its
     tallest child, so letting each shot set its own height makes everything
     below hop as you swipe between a square and a landscape shot; a fixed
     height keeps the frame still and contains each shot in it. */
  .product__slide {
    flex: 0 0 100%;
    width: 100%;
    object-fit: contain;
    scroll-snap-align: start;
  }

  .product__icons { max-width: 316px; }
  .product__icons img { height: 48px; }
  .product__usps { gap: 16px; }

  /* the variable/grouped fallback keeps its own stacked price row */
  .product__buy { display: block; }
  .product__price-row { justify-content: space-between; gap: 16px; }

  .product__desc h2:first-of-type { font-size: 40px; }

  /* the label sits above its value instead of beside it: a 200px label column
     would leave barely a third of the line for the value */
  .product__spec { flex-direction: column; gap: 8px; }
  .product__spec dt { flex: 0 0 auto; }

  /* related products: the v2 mobile carousel, plus the heading the desktop
     frame gives it — see the README for why it is kept here. */
  .products__heading {
    margin: 40px 0 0 var(--page-margin);
    font-size: 40px;
    letter-spacing: -1.6px;
  }
  .products__heading + .products--v2 { margin-top: 24px; }

  /* the compact tick list of frame 571:3050: one column, 16px checks */
  .product__checks { flex-direction: column; gap: 8px; }
  .product__checks ul { gap: 8px; }
  .product__checks li { font-size: 15px; line-height: 20px; }
  .product__checks img { flex: 0 0 16px; width: 16px; height: 16px; }

}

/* ==========================================================================
   The checkout's steps — Figma frames 1097:5488 (the two columns), 1100:7659
   (step 1, the address) and 1100:8105 (step 2, shipping and payment); at 402px
   1097:5237, 1311:3412 (the login unfolded), 1311:3680 and 1100:8911.

   All of it is one WooCommerce form. home.js sets .js-steps and data-step on
   .checkout-wrap (gate, login, address, payment) and every rule that hides
   something hangs off those two, so without the script the page is the one
   long form it was.
   ========================================================================== */

.btn--blue { background: var(--blue); }
.btn--blue:hover { background: #35317a; }

.checkout__title { display: flex; align-items: center; gap: 12px; }
.checkout__step {
  padding: 8px 12px;
  border-radius: 40px;
  background: var(--sea-blue);
  font-size: 15px;
  line-height: 20px;
  color: #fff;
  white-space: nowrap;
}
/* an empty cart renders no form, and then there are no steps to count */
.page--checkout:not(:has(form.checkout)) .checkout__step { display: none; }

/* the left column, "Ich bin bereits Kunde": the card's left half, so its
   padding is the card's 32 on three sides and half the 32px column gap on the
   fourth; .checkout__form carries the other half */
.checkout-gate {
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding: 32px 16px 32px 32px;
  background: var(--light-blue);
}
.checkout-gate h2 { font-size: 28px; line-height: 40px; }
.checkout-gate__btn { justify-content: center; width: 100%; }
/* the phone's wording of the two buttons, see the 900px block */
.checkout-gate__label--phone { display: none; }
.checkout-gate__who { font-size: 18px; line-height: 26px; color: var(--dark-grey); }
.checkout-gate__logout {
  width: fit-content;
  font-size: 18px;
  font-weight: 600;
  line-height: 26px;
  color: var(--green);
}
.checkout-gate__logout:hover { text-decoration: underline; }
/* the login form's first field sits 16px under the heading like the button
   did; its own blocks keep their 40 */
.checkout-gate form.woocommerce-form-login { margin-top: 0; }

/* the guest's column: heading, "Weiter", then what it unfolds */
.checkout-contact .checkout-block__title { flex: 1; gap: 16px; }
.checkout-contact .checkout-block__title p { color: var(--dark-grey); }
.checkout .checkout-contact .field-group { width: 100%; }

/* the AGB row, the rule and the button continue the 20px pitch of the
   checkbox stack; all three are items of the card's 40px column */
.checkout__legal { display: flex; flex-direction: column; gap: 20px; margin-top: -20px; }
.checkout__legal > :empty { display: none; }
.checkout__form .checkout-fields__rule { width: 100%; margin-top: -20px; }
.checkout__next { justify-content: center; width: 100%; max-width: 400px; margin-top: -20px; }
/* without the order note the wrapper under the rule holds a checkbox only
   where Mailchimp prints its newsletter row. Where it holds none (hidden order
   attribution inputs, which post from a display: none box too), wrapper and
   rule would each keep a gap slot over "Nächste". */
.checkout__form .woocommerce-additional-fields:not(:has(input[type="checkbox"])),
.checkout__legal + .checkout-fields__rule:not(:has(+ .woocommerce-additional-fields input[type="checkbox"])) { display: none; }

.checkout-step { display: contents; }
/* buttons that only switch panes have nothing to do without the script */
.checkout-wrap:not(.js-steps) .checkout-gate__btn,
.checkout-wrap:not(.js-steps) .checkout__next { display: none; }

/* gate and login: two headings, two buttons, nothing else of the form */
.checkout-wrap.js-steps:is([data-step="gate"], [data-step="login"]) .checkout-step--payment,
.checkout-wrap.js-steps:is([data-step="gate"], [data-step="login"]) .checkout-step--address > :not(#customer_details),
.checkout-wrap.js-steps:is([data-step="gate"], [data-step="login"]) #customer_details .col-2,
.checkout-wrap.js-steps:is([data-step="gate"], [data-step="login"]) #customer_details .col-1 > :not(.checkout-contact),
.checkout-wrap.js-steps:is([data-step="gate"], [data-step="login"]) .checkout-contact > :not(.checkout-block__head),
.checkout-wrap.js-steps:is([data-step="gate"], [data-step="login"]) .checkout-contact .checkout-block__title p { display: none; }
.checkout-wrap.js-steps[data-step="login"] .checkout-gate > .checkout-gate__btn,
.checkout-wrap.js-steps:not([data-step="login"]) .checkout-gate form.woocommerce-form-login { display: none; }

/* step 1 */
.checkout-wrap.js-steps[data-step="address"] .checkout-contact .checkout-gate__btn,
.checkout-wrap.js-steps[data-step="address"] .checkout-step--payment { display: none; }

/* step 2: the card is the form alone, at the full 960 */
.checkout-wrap.js-steps[data-step="payment"] .checkout-gate,
.checkout-wrap.js-steps[data-step="payment"] .checkout-step--address { display: none; }
.page--checkout .checkout-wrap.js-steps[data-step="payment"] .checkout__form { grid-column: 1 / span 2; padding-left: 32px; }
/* the snippet's own copy of the § 7 UWG notice; the one that counts stands
   under the AGB box on step 1 (form-shipping.php) */
.checkout-step--payment .farmula-objection-notice { display: none; }
/* 1100:8105 draws the methods straight on the card. woocommerce.css boxes
   them (tinted #payment, 1em of padding and a rule under the list, 1em around
   the button row) with an id in every selector, so the answers carry it too.
   Germanized's "Zahlungsart auswählen" repeats the "Bezahlarten" above it. */
.woocommerce-checkout .checkout #payment { background: none; border-radius: 0; }
.woocommerce-checkout .checkout #payment ul.payment_methods { padding: 0; border-bottom: none; }
.woocommerce-checkout .checkout #payment div.form-row { padding: 0; }
/* !important: Germanized's script shows and hides the heading with the
   gateways and writes display:block inline */
.checkout #order_payment_heading { display: none !important; }
/* `.woocommerce form .form-row` pads every row by 3px; the e-mail row, the AGB
   box and the order button stood that far right of everything else in the
   column (the AGB box beside "Auch als Rechnungsadresse nutzen": Moritz,
   2026-09-21) */
.checkout.woocommerce-checkout .field-group > .form-row,
.checkout.woocommerce-checkout .checkout__legal .form-row,
.checkout.woocommerce-checkout .wc-gzd-order-submit .form-row { margin: 0; padding: 0; }
/* The terms row is a sentence without a box (Germanized "hide_input",
   2026-09-22): Germanized prints the label without the checkbox class, so it
   takes the checkbox rows' type here; the AGB link is underlined like the
   links in a .check. The § 7 UWG notice under it starts on the same x. The
   snippet's inline 35px indent and -20px margin are from the boxed days,
   hence !important: 8px of the 20px gap stay. */
.checkout__legal .legal label.woocommerce-form__label {
  display: block;
  margin: 0;
  font-size: 13px;
  font-weight: 500;
  line-height: normal;
  color: var(--dark-grey);
}
.checkout__legal .legal a { text-decoration: underline; }
.checkout__legal .farmula-objection-notice { margin-top: -12px !important; padding-left: 0 !important; }
/* both steps end on a button with the arrow (1100:7659, 1100:8105); the order
   button's markup is Germanized's, so its arrow is drawn here */
.checkout__submit::after {
  content: "";
  flex: 0 0 24px;
  height: 24px;
  background: url(assets/arrow-narrow-right-white.svg) center / 24px 24px no-repeat;
}
/* under the order button: the order note, then the promo code, both open and
   as wide as the choice rows above (Moritz, 2026-09-21; no frame). One item of
   the card's 40px column, 20px between its two boxes. */
/* "right under the button": the button's row is a 20px flex column whose
   unseen items (nonce, gateway containers) leave one gap slot under the
   button, and the card adds its 40. 24px remain. */
.checkout__after-submit { display: flex; flex-direction: column; gap: 20px; width: 100%; margin-top: -36px; }
.checkout__after-submit .form-row { margin: 0; padding: 0; }

/* the shipping block's pull-up answered the order note that stood above it
   until the steps; that pane is the other one now */
.checkout-wrap.js-steps[data-step="payment"] .checkout section.checkout-block.checkout__shipping { margin-top: 0; }

@media (max-width: 900px) {
  /* 1097:5237: title and pill at the two ends of the row, the lock line under it */
  .checkout__title { width: 100%; justify-content: space-between; }

  /* one column: the login half on top of the form half, still one slab, so
     the rounded corner is the upper one's and the seam has no gap */
  .checkout-gate { padding: 24px 20px 8px; border-radius: 0 40px 0 0; }
  /* the head is a column with flex-start here, which shrank "Weiter" to its text */
  .checkout-contact .checkout-block__title { align-self: stretch; }
  /* The choice is two slim buttons that say what the headings said, "Ich bin
     bereits Kunde" and "Neukunde/Gast" (Moritz, 2026-09-21, after
     agrar-fachversand; frame 1097:5237 draws heading + 58px button twice). A
     heading comes back with what its button unfolds: the login form, the
     address. */
  .checkout-gate__label { display: none; }
  .checkout-gate__label--phone { display: inline; }
  /* 12px between the two while nothing is unfolded: the gate's 8 of bottom
     padding plus 4 here instead of the form's 24 */
  .page--checkout .checkout-wrap.js-steps[data-step="gate"] .checkout-gate ~ form.checkout .checkout__form { padding-top: 4px; }
  .checkout-wrap.js-steps:not([data-step="login"]) .checkout-gate:not(.checkout-gate--known) h2,
  .checkout-wrap.js-steps:is([data-step="gate"], [data-step="login"]) .checkout-contact h2 { display: none; }
  .page--checkout .checkout-gate ~ form.checkout { margin-top: 0; }
  .page--checkout .checkout-gate ~ form.checkout .checkout__form { padding-left: 20px; border-radius: 0; }
  .page--checkout .checkout-wrap.js-steps[data-step="payment"] .checkout__form { padding-left: 20px; border-radius: 0 40px 0 0; }
  .checkout-wrap.js-steps[data-step="payment"] .checkout-gate ~ form.checkout { margin-top: 24px; }
  /* the card's gap is 24 here, so 4 is what the 20px pitch takes back */
  .checkout__legal,
  .checkout__form .checkout-fields__rule,
  .checkout__next { margin-top: -4px; }
  .checkout__next { max-width: none; }
  /* the card's gap is 24 here: 20 + 24 - 20 leaves the same 24 */
  .checkout__after-submit { margin-top: -20px; }

  /* Phone sizes for every control of the checkout (Moritz, 2026-09-21: the
     frames' 64px fields and 58px buttons read oversized on a phone): fields
     and choice rows 48px, buttons 44px, 16px type, which is also the size
     below which iOS zooms into a focused field. The floated label shrinks to
     11px at 5px from the top, the value drops under it. The star beside the
     placeholder is placed from the input's own metrics (home.js) and follows.
     Hung on [data-step], which checkout.php prints. */
  .page--checkout .checkout-wrap[data-step] .btn { height: 44px; padding-block: 0; font-size: 16px; }
  .page--checkout .checkout-wrap[data-step] .field,
  .page--checkout .checkout-wrap[data-step] .choice,
  .page--checkout .checkout-wrap[data-step] .coupon-fold__apply { height: 48px; }
  .page--checkout .checkout-wrap[data-step] .coupon-fold__apply { font-size: 16px; }
  .page--checkout .checkout-wrap[data-step] .field input,
  .page--checkout .checkout-wrap[data-step] .woocommerce-form-login .field input.input-text { font-size: 16px; }
  .page--checkout .checkout-wrap[data-step] .field:not(.field--select) .field__label { top: 5px; font-size: 11px; }
  .page--checkout .checkout-wrap[data-step] .field:has(input:not(:placeholder-shown)) { padding-bottom: 5px; }

  .checkout-wrap[data-step] .checkout.woocommerce-checkout .form-row input.input-text,
  .checkout-wrap[data-step] .checkout.woocommerce-checkout .form-row textarea.input-text { height: 48px; font-size: 16px; }
  .checkout-wrap[data-step] .checkout.woocommerce-checkout .form-row textarea.input-text { height: 96px; padding-block: 13px; }
  .checkout-wrap[data-step] .checkout .form-row.farmula-hide-label:has(input.input-text:not(:placeholder-shown)) > label,
  .checkout-wrap[data-step] .checkout .form-row.farmula-hide-label:has(input.input-text:focus) > label { top: 5px; font-size: 11px; }
  .checkout-wrap[data-step] .checkout.woocommerce-checkout .form-row.farmula-hide-label:has(input.input-text:not(:placeholder-shown)) input.input-text,
  .checkout-wrap[data-step] .checkout.woocommerce-checkout .form-row.farmula-hide-label:has(input.input-text:focus) input.input-text { padding-top: 16px; }

  /* the login form follows: its tick and its link at the 13px of every other
     checkbox row in the card (they stood at 18), its blocks at the 20px pitch
     of the address instead of the frame's 40 */
  .page--checkout .checkout-wrap[data-step] form.woocommerce-form-login { gap: 20px; }
  .page--checkout .checkout-wrap[data-step] .checkout-gate label.woocommerce-form-login__rememberme,
  .page--checkout .checkout-wrap[data-step] .checkout-gate label.woocommerce-form-login__rememberme span,
  .page--checkout .checkout-wrap[data-step] .checkout-gate .account-forgot { font-size: 13px; line-height: normal; }
  .page--checkout .checkout-wrap[data-step] .checkout-gate label.woocommerce-form-login__rememberme { margin-top: 0; font-weight: 500; }

  /* the line under "Ich habe kein Konto" explains the field below it: 14px,
     between the 22px heading and the 16px of the field (it stood at 18) */
  .page--checkout .checkout-wrap[data-step] .checkout-contact .checkout-block__title p { font-size: 14px; line-height: 20px; }

  /* Land/Region: label at 5, the value's 22px line ends 2px over the border:
     22 + 22 + 2 = the 46px padding box */
  .checkout-wrap[data-step] .checkout .form-row:has(select),
  .checkout-wrap[data-step] .checkout.woocommerce-checkout .checkout-fields > .form-row:has(select) { height: 48px; padding-top: 5px; }
  .checkout-wrap[data-step] .checkout .form-row:has(select) > label { font-size: 11px; }
  .checkout-wrap[data-step] .checkout .form-row:has(select) select { padding: 22px 55px 2px 23px; font-size: 16px; line-height: 22px; }
}

/* ============================================================================
   COMPACTION LAYER — 2026-08-11
   Trial reduction of the type scale, spacing and radii across the redesign, to
   test a tighter density (measured against agrar-fachversand). Reversible: this
   whole block is additive and overrides only. Delete from here to end-of-file
   to restore the original sizes. Tracking follows -4% of the new size; heading
   line-heights tighten toward ~1.2.
   ========================================================================== */
:root { --radius-card: 16px; }

/* display headings, desktop */
.hero h1 { font-size: 48px; letter-spacing: -1.92px; }
.brochure h2, .faq__heading, .services__heading,
.shop-about__text h2, .text-page__title, .cart__title,
.article__title, .product__name, .products__heading { font-size: 40px; letter-spacing: -1.6px; }
.testimonials blockquote { font-size: 34px; }
.service-card h3, .shop__head h1, .cart-item__total, .cart-box__total-row p,
.suggest__heading, .checkout__head h1, .checkout-total__row .checkout-total__value,
.more__heading, .product__price, .product__desc h2:first-of-type { font-size: 28px; letter-spacing: -1.12px; }
.text-page__content h2 { font-size: 26px; letter-spacing: -1.04px; }
.product-card h3, .newsletter h3, .faq__item summary h3, .faq__contact h3,
.footer__col h3, .article-card h2, .cart-item h2, .checkout-block h2, .checkout-gate h2,
.checkout-total__row p, .article__text h2, .product__desc h3 { font-size: 22px; line-height: 30px; }

/* box headings */
.cart-box__head h2 { font-size: 20px; line-height: 28px; }

/* spacing + radius */
.products, .faq, .shop, .suggest, .page--shop .footer { margin-top: 48px; }
div.cart { gap: 48px; }
.cart__head { margin-top: 48px; }
.cart__side { gap: 16px; }
.cart-box { padding: 23px; }

@media (max-width: 900px) {
  .hero h1 { font-size: 32px; letter-spacing: -1.28px; }
  .services__heading, .brochure h2, .faq__heading, .shop-about__text h2,
  .text-page__title, .cart__title, .suggest__heading, .article__title, .more__heading,
  .product__name, .product__desc h2:first-of-type, .products__heading { font-size: 30px; letter-spacing: -1.2px; }
  .checkout__head h1 { font-size: 26px; letter-spacing: -1.04px; }
  .service-card h3, .text-page__content h2, .checkout-total__row .checkout-total__value { font-size: 22px; }
  div.cart { gap: 32px; }
  .cart-box { padding: 23px 19px; }
}
/* ===================== end COMPACTION LAYER ===================== */

/* ==========================================================================
   Wide screens — viewports beyond the 1728px canvas

   Confirmed with the designer 2026-08-25: the 1728px Figma frame is the
   artboard, not a page box. Content sits in the 1530px column; every
   coloured band (and the hero media) is meant to reach the viewport edges.
   Below 1729px nothing changes: script.js scales the canvas to the viewport,
   so these rules can never fire there.

   Technique: each band paints a 100vw layer through a ::before that sits
   between the band's own background and its content (isolation keeps the
   negative z-index inside the band). The canvas geometry is untouched.
   ========================================================================== */

@media (min-width: 1729px) {

  :root { --bleed: calc((100vw - var(--page-width)) / 2); }

  .navbar,
  .menu,
  .hero,
  .hero__slide,
  .testimonials,
  .services,
  .brochure,
  .footer__main,
  .footer__bottom {
    isolation: isolate;
  }
  .services,
  .footer__bottom { position: relative; }

  .navbar::before,
  .menu::before,
  .hero::before,
  .hero__slide::before,
  .testimonials::before,
  .services::before,
  .brochure::before,
  .footer__main::before,
  .footer__bottom::before {
    content: "";
    position: absolute;
    top: 0;
    bottom: 0;
    left: 50%;
    width: 100vw;
    transform: translateX(-50%);
    z-index: -1;
  }

  .navbar::before { background: #fff; border-bottom: 1px solid var(--light-blue); }
  .navbar { border-bottom: none; }
  .navbar--slim::before { background: var(--blue); border-bottom: none; }
  .navbar--slim { background: transparent; }

  .menu::before { background: var(--light-blue); }

  /* base grey while a slide fades in; both slides ground on the dark blue,
     the hero media covers the right half out to the viewport edge */
  .hero::before { background: #d9d9d9; }
  .hero__slide::before { background: var(--blue); }
  .hero__media { right: calc(-1 * var(--bleed)); }
  .hero__media--1 { width: calc(1067px + var(--bleed)); }
  .hero__media--2 { width: calc(1138px + var(--bleed)); }

  .testimonials::before { background: var(--blue); }

  /* the rounded corner moves out to the viewport edge with the band */
  .services { background: transparent; border-radius: 0; }
  .services::before { background: var(--light-blue); border-radius: 0 0 80px 0; }

  /* like .services, mirrored: the top-left radius rides the viewport edge */
  .brochure { background: transparent; border-radius: 0; }
  .brochure::before { background: var(--light-blue); border-radius: 80px 0 0 0; }
  /* the watermark keeps the artboard's crop: 65px past the viewport edge */
  .brochure__vector { right: calc(-65px - var(--bleed)); }

  .footer__main::before { background: var(--blue); }
  .footer__bottom::before { background: var(--sea-blue); }
}

/* --- site notice strip (parts/notice.php) --------------------------------
   Sits in the flow right under the sticky header, so the first thing on
   screen after the newsletter redirect says what happened. */
.sitenotice { background: var(--green); color: #fff; }
.sitenotice--error { background: var(--red); }
.sitenotice__inner {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 16px var(--page-margin);
}
.sitenotice__icon { flex: 0 0 auto; color: rgba(255, 255, 255, 0.22); }
.sitenotice p { margin: 0; font-size: 17px; line-height: 24px; font-weight: 500; }

@media (max-width: 900px) {
  .sitenotice__inner { align-items: flex-start; padding: 14px var(--page-margin); }
  .sitenotice p { font-size: 15px; line-height: 22px; }
}

/* --- consent banner stands above the search overlay ----------------------
   Complianz runs with the soft cookie wall on, so while the banner waits
   for an answer it puts `pointer-events: none` on every element outside
   itself. Its container is `position: fixed; z-index: 9999` and opens a
   stacking context, so that 9999 is the number the rest of the page is
   measured against. FiboSearch asks for z-index 99999999999 on its mobile
   overlay, which every browser clamps to 2147483647, the top of the range.
   A banner that arrives while the overlay is open therefore lands behind
   the white sheet: the shopper sees his search results, taps one, and
   nothing happens, with nothing on screen to say why (reported from an
   Android phone, 2026-09-11: "Boli" typed, product tapped, page dead).
   Which of the two wins was down to DOM order, since both sat at the cap.

   The banner cannot be raised past the cap, so the overlay comes down
   instead, and the banner and its dark wall take the two layers above it.
   A tap on "Akzeptieren" then frees the page with the suggestions still
   standing. The overlay keeps a number far above everything the theme
   itself stacks, so nothing else changes order. */
.dgwt-wcas-overlay-mobile,
.js-dgwt-wcas-overlay-mobile { z-index: 2147482000 !important; }
.cmplz-soft-cookiewall { z-index: 2147482500 !important; }
#cmplz-cookiebanner-container { z-index: 2147483000 !important; }

/* The banner is docked at bottom: 0 and its "Akzeptieren" row ended 12px above
   the screen's edge. On an iPhone that strip lies under Safari's collapsed
   toolbar: the first tap there brings the toolbar back and never reaches the
   button, the second one does (Moritz, 2026-09-23, "oft zweimal"). "Ablehnen"
   sits a row higher and answered at once. 48px more padding lifts both rows
   out of the strip; when the toolbar is out, the band is plain banner. */
@media (max-width: 900px) {
  #cmplz-cookiebanner-container .cmplz-cookiebanner.cmplz-bottom { padding-bottom: 60px; }
}

/* --- product page: the compact first screen (2026-09-22) -------------------
   Paid visitors land on a product page on a phone (94 % mobile in the Weidezaun
   campaign) and the price, the shipping note and the button all sat below the
   gallery, about one and a half screens down. A price under the title (21.09.)
   and a fixed buy bar (21./22.09.) were both tried and taken out again on
   2026-09-22; instead the phone's first screen is the canvas "A: kompakter
   Kopf" (claude.ai/artifact/RVT3oabJWSghR1P3iiwkJ9): a 68px bar, a small
   crumb and title, a 240px photo with dots, the delivery line, the price and
   the button, all inside Safari's 664px first screen. Desktop keeps the two
   columns and only gains the Trusted Shops line under the button; the dots,
   the delivery line and the PayPal box are the phone's. */
.product__dots,
.product__delivery { display: none; }
/* "Direkt zu PayPal" under the cart button on both canvases (Moritz,
   2026-09-23): on the desktop as wide as the stepper-and-button row above it.
   The box shows only with the plugin's button in it. The plugin prints its
   Pay Later message on the same hook and shows it with an inline display, so
   that rule has to outrank it; the message was never on this page (the hook
   the plugin renders on by default does not fire in this template). */
.product__paypal { width: 407px; }
.product__paypal:not(:has(.ppc-button-wrapper)) { display: none; }
.product__paypal .ppcp-messages { display: none !important; }
/* The SDK stacks its button layers at z-index 100 and 300, above the sticky
   .navbar (20): scrolling back up, the header slid in under the button
   (30.09.2026). Isolating the box keeps those numbers inside it. */
.product__paypal,
.ppc-button-wrapper { isolation: isolate; }

/* the shipping wording that does not apply to the current quantity */
.product__shipping .is-off { display: none; }

.ts-line { display: flex; align-items: center; gap: 12px; color: var(--blue); text-decoration: none; }
/* the round seal, cut out of the hero badge bitmap: 186px wide, the seal is the
   106px circle at 40/19, shown at 42px */
.ts-line__seal {
  flex: 0 0 42px;
  width: 42px;
  height: 42px;
  border-radius: 50%;
  background: url(assets/badge-trustedshops.png) -16px -7.5px / 74px auto no-repeat;
}
.ts-line__text strong { font-size: 15px; line-height: 20px; font-weight: 600; }
.ts-line:hover strong { color: var(--green); }

@media (max-width: 900px) {
  /* The canvas from the top, in px: bar 68, crumb at 76 (20 high), title at
     108 (26), photo at 146 (240), dots at 394 (6), delivery line at 410 (40),
     price at 460 (38), the stepper row at 510 (50, ends 560), PayPal at 568
     (48, ends 616), the seal line at 626. Safari's first screen on an iPhone
     is 664px, so the cart button and the PayPal button both make it. */

  /* one small grey line, the category chain only: "Home" and the product's
     own name go, the chevrons shrink with the text */
  .page--product .breadcrumbs {
    flex-wrap: nowrap;
    gap: 6px;
    margin: 8px var(--page-margin) 0;
    height: 20px;
    overflow: hidden;
    font-size: 12px;
    line-height: 20px;
    white-space: nowrap;
    color: var(--grey);
  }
  .page--product .breadcrumbs > a:first-child,
  .page--product .breadcrumbs > a:first-child + img,
  .page--product .breadcrumbs span,
  .page--product .breadcrumbs img:last-of-type { display: none; }
  .page--product .breadcrumbs a { color: inherit; }
  .page--product .breadcrumbs img { width: 12px; height: 12px; }

  .product__name {
    margin: 12px var(--page-margin) 0;
    font-size: 22px;
    line-height: 26px;
    letter-spacing: -0.88px;
  }

  /* One column in the canvas' order. The desktop's two column wrappers are
     dissolved (display: contents), so the photo, the dots, the buy box, the
     highlights and the text are all rows of the section and take the order
     the canvas gives them; the gap is per row. Every row spans the column:
     .product aligns its columns to flex-start, which would shrink a row to
     its content, and min-width lets a pasted table wrap instead of widening
     the screen (see the table rules below). */
  .product {
    flex-direction: column;
    gap: 0;
    margin-top: 0;
    padding: 0 var(--page-margin) 32px;
    /* the canvas is white throughout; on the desktop's lilac band the light
       blue rules, the stepper's border and the dots would all vanish */
    background: #fff;
  }
  /* ...so the fade over a collapsed block ends in that white, not in the
     desktop's lilac (it painted a lilac slab over the last lines, 2026-09-28) */
  .product__fold.is-collapsed::after { background: linear-gradient(to bottom, rgba(255, 255, 255, 0), #fff); }
  .product__card,
  .product__info { display: contents; }
  .product__card > *,
  .product__info > * { align-self: stretch; min-width: 0; }
  .product__card > * + *,
  .product__info > * + * { margin-top: 24px; }

  /* the shots fill the screen's width on white, the way the Amazon app shows
     a packshot (Moritz, 2026-08-14), 240px tall. WooCommerce's own
     `.woocommerce img { height: auto; max-width: 100% }` outranks a bare
     class, hence the long forms. */
  .woocommerce img.product__photo,
  .product__photo,
  .product__slides {
    order: 0;
    width: calc(100% + 2 * var(--page-margin));
    max-width: none;
    margin: 12px calc(-1 * var(--page-margin)) 0;
  }
  .woocommerce img.product__photo,
  .product__photo,
  .woocommerce img.product__slide,
  .product__slide { height: 240px; aspect-ratio: auto; padding: 0; }
  .product__thumbs { display: none; }
  .product__dots { order: 0; display: flex; justify-content: center; gap: 6px; margin-top: 8px; }
  .product__dot {
    box-sizing: content-box;
    width: 6px;
    height: 6px;
    padding: 5px 0;
    border: 0;
    border-radius: 3px;
    background: var(--light-grey) content-box;
    transition: width 0.2s ease;
  }
  .product__dot.is-active { width: 16px; background-color: var(--green); }

  .product__buy { order: 1; margin-top: 10px; }
  /* the Staffelpreise from the volume pricing plugin follow the buy box */
  .farmula-volume,
  .farmula-volume-pack { order: 1; }
  .product__icons,
  .product__usps,
  .product__desc,
  .product__more,
  .product__specs { order: 2; }
  .product__icons { margin-top: 16px; }
  .product__usps { margin-top: 16px; }

  /* the buy box from the top: the delivery line, the price beside its note,
     the stepper beside the button, PayPal, the seal. The price is the unit
     price at one and the line total above it (the volume pricing script
     writes it); the note turns to "versandkostenfrei" with the quantity. */
  .product__buy-form {
    display: grid;
    grid-template-columns: 1fr;
    grid-template-areas:
      "delivery"
      "price"
      "actions"
      "paypal"
      "seal";
    row-gap: 0;
  }
  /* after moto-renzo.biz: a truck, "Lieferzeit:" in bold, a green dot, the
     days, between two thin rules */
  .product__delivery {
    grid-area: delivery;
    display: flex;
    align-items: center;
    gap: 12px;
    height: 40px;
    border-top: 1px solid var(--light-blue);
    border-bottom: 1px solid var(--light-blue);
    font-size: 14px;
    line-height: 20px;
    color: var(--blue);
  }
  .product__delivery img { flex: 0 0 26px; }
  .product__delivery strong { font-weight: 700; }
  .product__delivery-dot {
    width: 8px;
    height: 8px;
    margin-left: -4px;
    border-radius: 50%;
    background: var(--green);
  }
  .product__buy-price {
    grid-area: price;
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    justify-content: space-between;
    align-items: baseline;
    gap: 0 16px;
    margin-top: 10px;
  }
  .product__price { font-size: 32px; line-height: 38px; letter-spacing: -1.28px; }
  /* the note stands right of the price on three lines, VAT, shipping cost,
     then "ab 75 € versandkostenfrei" (two lines once the line ships free);
     the delivery time is the truck line's */
  .product__tax { font-size: 13px; line-height: 18px; font-weight: 400; text-align: right; }
  .product__tax .product__vat,
  .product__tax .product__shipping-from { display: block; }
  .product__tax .product__sep,
  .product__tax .product__delivery-note { display: none; }
  .product__stock { flex-basis: 100%; }
  .product__buy-actions { grid-area: actions; display: flex; gap: 12px; margin-top: 12px; }
  /* one bordered 130px box: minus, the number, plus */
  .qty {
    flex: 0 0 130px;
    gap: 0;
    height: 50px;
    border: 1px solid var(--light-blue);
    border-radius: 8px;
  }
  .qty .icon-btn { width: 42px; height: 48px; border: 0; background: none; }
  .qty__value { flex: 1; width: auto; height: 48px; font-size: 16px; }
  .product__cart { flex: 1; height: 50px; justify-content: center; margin: 0; padding-inline: 12px; }
  .product__paypal { grid-area: paypal; width: auto; margin-top: 8px; }
  /* the seal line in one row: the small seal, then the sentence */
  .ts-line { grid-area: seal; gap: 8px; margin-top: 10px; }
  .ts-line__seal { flex-basis: 24px; width: 24px; height: 24px; background-size: 42px auto; background-position: -9px -4px; }
  .ts-line__text strong { font-size: 13px; line-height: 18px; }

  /* the description's headings step down from the 22px title (Moritz,
     2026-09-23: at 30-32px the shop's opening heading, often an <h1> pasted
     into the text, dwarfed the product's name) */
  .product__desc h1,
  .product__desc h2:first-of-type { font-size: 22px; line-height: 28px; letter-spacing: -0.88px; }
  .product__desc h2,
  .product__desc h1 ~ h2:first-of-type { font-size: 20px; line-height: 28px; letter-spacing: -0.4px; }
  .product__desc h3 { font-size: 18px; line-height: 26px; }

  /* A table pasted from Word carries its desktop width as attributes
     (<table width="727">, <td width="340">). Its min-content then widened the
     whole info column past the screen, and the button, the text and, once it
     was right-aligned, the price ran off the right edge (Lämmermilch,
     2026-09-21; live on prod too, where the left-aligned price hid it). The
     column is pinned to the screen, and a table gives up its fixed widths and
     wraps its cells instead. */
  .product__info { align-self: stretch; min-width: 0; }
  .product__desc { overflow-wrap: break-word; }
  .product__desc table { width: 100%; max-width: 100%; height: auto !important; }
  .product__desc td,
  .product__desc th { width: auto; padding-right: 12px; vertical-align: top; }
}

/* WooCommerce's checkout.js adds its own inline error under a field
   (.checkout-inline-error-message); home.js writes .field-error for the same
   fault, so the message showed twice (topro.nl staging, 2026-09-29). Where the
   theme has spoken, WooCommerce's copy steps back. */
.form-row:has(.field-error) .checkout-inline-error-message { display: none; }

/* --- hero slide 2: the Q4 2026 promotion (front-page.php) ------------------
   Carmen's banner carries its copy in the picture. On the desktop canvas it
   covers the whole 1728 x 600 slide (a 1200 x 447 file, so cover crops about
   20px top and bottom, well clear of the text); the ground behind it is the
   banner's own navy, so the band past the canvas on wide screens matches. On
   a phone the text would be unreadably small: the picture is cropped to its
   right half (the blanket, the cows, the boxes) in the media slot, and the
   offer is set as text in the band below. */
.hero__slide--q4 { background: #061465; }
.hero__q4-link { position: absolute; inset: 0; display: block; }
.hero__media--q4 { left: 0; right: 0; width: 100%; }
.hero__content--q4 { display: none; }

@media (max-width: 900px) {
  /* the navy ground belongs to the banner; below the media the band is the
     same dark blue as slide 1, and white under it */
  .hero__slide--q4 { background: none; }
  .hero__media--q4 { object-position: right center; }
  .hero__q4-link { bottom: auto; height: 226px; }
  .hero__content--q4 { display: flex; top: 250px; }
  .hero__content--q4 h1 { font-size: 36px; letter-spacing: -1.44px; }
  .hero__content--q4 .hero__lead { font-size: 16px; line-height: 24px; }
}

@media (min-width: 1729px) {
  .hero__slide--q4::before { background: #061465; }
  .hero__media--q4 { left: auto; width: calc(var(--page-width) + var(--bleed)); }
}

/* Both shops since 02.10.2026 (Figma "Hero 2", 168:510): the copy is live text
   on the banner's navy. That is farmula's --blue, but topro.nl redefines
   --blue, so the picture's own colour is spelled out here. */
.hero__slide--q4-text { background: #29265d; }
.hero__slide--q4-text .hero__content--q4 { display: flex; z-index: 1; width: 540px; }
.hero__slide--q4-text .hero__content--q4 .hero__lead {
  font-family: var(--font-display, "Bricolage Grotesque", sans-serif);
  font-size: 28px; line-height: normal; font-weight: 500; letter-spacing: -0.56px;
}
.hero__lead-mark { color: #bfd968; }

@media (max-width: 900px) {
  .hero__slide--q4-text { background: none; }
  .hero__slide--q4-text .hero__content--q4 { width: auto; }
  .hero__slide--q4-text .hero__content--q4 .hero__lead { font-family: inherit; font-size: 16px; line-height: 24px; letter-spacing: 0; }
}

@media (min-width: 1729px) {
  .hero__slide--q4-text::before { background: #29265d; }
  /* the copy sits at the page margin, so the picture starts at the page's
     left edge (not the window's) and runs out to the right like the video */
  .hero__slide--q4-text .hero__media--q4 { left: 0; right: auto; object-position: left center; }
}
