/* =========================================================
   La Tasi — design tokens
   Edit these to retune the whole site.
   ========================================================= */
:root {
  --color-bg: #FFFFFF;            /* pure white — videos with white backgrounds blend seamlessly */
  --color-text: #161616;
  --color-muted: #9a9a9a;
  --color-accent: #c9b89b;        /* warm sand / clay */
  --color-line: rgba(22, 22, 22, 0.08);

  --glass-bg: rgba(255, 255, 255, 0.55);
  --glass-border: rgba(255, 255, 255, 0.7);
  --glass-blur: 20px;
  --glass-shadow: 0 30px 80px -30px rgba(22, 22, 22, 0.25);

  --font-serif: "Cormorant Garamond", "Playfair Display", Georgia, serif;
  --font-sans: "Montserrat", "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  --font-weight-heading: 600;     /* Cormorant SemiBold for all headings */

  --ease: cubic-bezier(0.4, 0, 0.2, 1);

  /* Master dial for the staged card reveal. Bump for a slower, more cinematic feel. */
  --reveal-base: 90ms;            /* per-step stagger */
  --reveal-duration: 900ms;       /* per-step transition length */
}

* { box-sizing: border-box; }

/* Note: deliberately NOT adding `img { max-width: 100% }` globally —
   that broke the nav logo when its flex parent shrank to 0 px.
   Mobile overflow guards live on individual components instead. */

html, body {
  margin: 0;
  padding: 0;
  background: var(--color-bg);
  color: var(--color-text);
}
/* Horizontal overflow guard — defence in depth.
   • body: overflow-x:hidden + max-width:100% absorbs any stray sub-
     pixel overflow from descendant elements (the original layer).
   • html: overflow-x:clip is added as a second-layer safety net.
     UNLIKE `overflow:hidden`, `clip` does NOT create a scrolling
     container, so `scroll-snap-type: y proximity` on html (below)
     continues to work card-by-card.  Two guards beat one because
     on iOS Safari `body` can occasionally fail to contain rounding
     errors from `100vw` measurements when the safe-area inset is
     non-zero — `clip` on html catches those last-mile leaks. */
html { overflow-x: clip; }
body { overflow-x: hidden; max-width: 100%; }

/* Respect prefers-reduced-motion — Apple HIG / WCAG 2.3.3.  Cards
   and reveal animations stay legible but stop animating for users
   who opted out.  This also kills any residual jitter on motion-
   sensitive devices. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}

/* iOS Safari auto-zooms when the user focuses any input whose font-
   size is below 16 px.  The zoom yanks the modal/form off-screen and
   feels unprofessional.  We pin every input to 16 px on mobile (≤ 900
   px) — large enough to disable auto-zoom, small enough that the
   layout doesn't break.  Desktop keeps the original sizes via the
   :not() media-query inversion at the bottom of each component file. */
@media (max-width: 900px) {
  input:not([type="checkbox"]):not([type="radio"]):not([type="range"]),
  select,
  textarea {
    font-size: 16px !important;
  }
  /* Mobile blur-cap — iOS Safari's compositor pays a heavy per-frame
     cost for blur radii above ~25 px, especially when the blurred
     surface (panel / modal) is repainted during scroll-snap settle.
     Desktop keeps the original 40 px luxury feel; mobile drops to
     24 px which is visually indistinguishable on phone-pixel-density
     screens but ~3× cheaper to rasterise.  Same principle applies to
     glass surfaces inside drawer, modal, story-modal, grid-card-details. */
  .panel,
  .modal__sheet, .modal,
  .drawer,
  .story-modal__sheet,
  .grid-card-details {
    -webkit-backdrop-filter: blur(24px) saturate(160%) !important;
    backdrop-filter: blur(24px) saturate(160%) !important;
  }
}

/* Modal-locked body — when LaTasiModalLock.lock() is active the
   helper sets `data-modal-locked="1"` on <body>.  Belt-and-braces
   safety net: even on the rare browser where `position: fixed; top:
   -Npx` doesn't fully freeze, this CSS rule locks overflow too.  Note
   we deliberately do NOT set `overflow: hidden` here (would un-stick
   the position trick on iOS).  Just `overscroll-behavior: contain`
   to kill rubber-band bleed. */
body[data-modal-locked="1"] {
  overscroll-behavior: contain;
}

html {
  scroll-behavior: smooth;
  /* Proximity (NOT mandatory) snap on every viewport size.
     Mandatory was trapping the user on the last card — after the
     last snap target the browser refused to scroll into the brand-
     essay article below, since "mandatory" insists every scroll
     position must align to a snap point.  With proximity, the
     snap still engages between cards (the premium "click into the
     next frame" feel) but the user can scroll freely off the last
     card into the long-form text + footer at the bottom. */
  scroll-snap-type: y proximity;
  scroll-padding-top: 0;
}
@media (max-width: 900px) {
  html {
    -webkit-overflow-scrolling: touch;
    /* Mobile gets MANDATORY snap so each card is a hard stop. */
    scroll-snap-type: y mandatory;
    /* scroll-padding-top accounts for the fixed pre-launch banner at
       the top of the viewport.  Without this, when a card snaps to
       start, its top edge sits at y=0 — BUT the banner is overlaying
       y=0..banner-h, so the top ~70 px of the card (and its photo)
       are hidden behind the banner.  Worse, the bottom of the card
       (the buy button) gets pushed past 100dvh and out of view.
       With this padding, snap aligns the top of the card with the
       BOTTOM of the banner, so the entire card — title, photo,
       panel chip with buy button — is visible in one screen. */
    scroll-padding-top: var(--prelaunch-banner-h, 70px);
  }
}

body {
  font-family: var(--font-sans);
  font-size: 15px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

/* Headings: Cormorant Garamond SemiBold across the entire site */
h1, h2, h3, h4, h5, h6 {
  font-family: var(--font-serif);
  font-weight: var(--font-weight-heading);
  letter-spacing: 0.3px;
}

/* Body prose: Cormorant Garamond for actual paragraph text.
   Small UI labels, buttons and form controls remain in the sans (Montserrat). */
p {
  font-family: var(--font-serif);
  font-weight: 400;
  font-size: 16px;
  line-height: 1.55;
}

button {
  font: inherit;
  color: inherit;
  background: none;
  border: none;
  cursor: pointer;
  padding: 0;
}

a { color: inherit; text-decoration: none; }

/* =========================================================
   Top nav
   ========================================================= */
/* The outer .nav is a transparent strip — the three blocks inside
   carry their own glassmorphism. This makes them feel like floating pills
   rather than one continuous bar. */
.nav {
  position: fixed;
  top: 16px;
  left: 16px;
  right: 16px;
  /* height is now auto — the big logo determines the row height,
     and the pills float at the top of that row. */
  z-index: 50;
  pointer-events: none;                 /* let only the blocks be interactive */
  /* Defensive: force-transparent so no inherited browser default or
     UA stylesheet paints a cream-tinted backdrop here.  User reported
     a wide cream "bar" behind the nav that none of my CSS could
     explain — this defends against any UA-level <header> styling
     bleeding through. */
  background: transparent !important;
  -webkit-backdrop-filter: none !important;
  backdrop-filter: none !important;
}
.nav__inner {
  background: transparent !important;
  -webkit-backdrop-filter: none !important;
  backdrop-filter: none !important;
}
.nav__inner {
  max-width: 1600px;
  margin: 0 auto;
  /* Three flex blocks: logo (left) · seasons (centre) · icons (right).
     space-between pushes them to the edges and the centre stays
     mathematically in the middle of the available row.
     min-height keeps the row tall enough for the logo to overflow
     downward like before. */
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 14px;
  min-height: 56px;
  pointer-events: none;
}
.nav__inner > * { pointer-events: auto; }

/* Hamburger button — hidden on desktop, shown on mobile.
   Three thin lines that animate into an X when open. */
.nav__burger {
  display: none;     /* hidden by default — only appears via mobile media query */
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 40px;
  height: 40px;
  padding: 9px;
  background: rgba(255, 255, 255, 0.55);
  -webkit-backdrop-filter: blur(14px) saturate(160%);
  backdrop-filter: blur(14px) saturate(160%);
  border: 1px solid rgba(255, 255, 255, 0.6);
  border-radius: 12px;
  cursor: pointer;
  box-shadow: 0 8px 20px -10px rgba(22, 22, 22, 0.18);
  transition: background 220ms var(--ease);
}
.nav__burger:hover { background: rgba(255, 255, 255, 0.75); }
.nav__burger span {
  display: block;
  width: 100%;
  height: 1.5px;
  background: var(--color-text);
  border-radius: 999px;
  transition: transform 280ms var(--ease), opacity 220ms var(--ease);
  transform-origin: center;
}
.nav__burger[aria-expanded="true"] span:nth-child(1) { transform: translateY(6.5px) rotate(45deg); }
.nav__burger[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.nav__burger[aria-expanded="true"] span:nth-child(3) { transform: translateY(-6.5px) rotate(-45deg); }

/* MOBILE MENU DRAWER — slide-in from the left, full-height, glass.
   Stacks logo + seasons + bespoke + lang in clean vertical list. */
.mobile-menu {
  position: fixed;
  top: 0; left: 0;
  bottom: 0;
  /* Tightened the drawer width so even tiny phones (320 px iPhone SE)
     get enough space on the right for the backdrop tap-area — was
     85 vw which left only 48 px of backdrop. */
  width: min(86vw, 340px);
  background: rgba(248, 242, 234, 0.96);
  -webkit-backdrop-filter: blur(28px) saturate(180%);
  backdrop-filter: blur(28px) saturate(180%);
  border-right: 1px solid rgba(255, 255, 255, 0.6);
  box-shadow: 0 0 50px -10px rgba(22, 22, 22, 0.2);
  /* Padding tuned for mobile:
     - top  60 px so the logo sits below the X close button instead of
       overlapping it (was 56 px and X was clipped behind the logo)
     - sides 22 px so list items have room to breathe but the drawer
       still fits on 320 px screens
     - bottom uses env(safe-area-inset-bottom) so the last item never
       sits behind the iPhone home-bar */
  padding: 60px 22px calc(28px + env(safe-area-inset-bottom));
  z-index: 110;
  display: flex;
  flex-direction: column;
  gap: 20px;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
  transform: translateX(-100%);
  transition: transform 360ms var(--ease);
  visibility: hidden;
}
.mobile-menu[data-open="true"] {
  transform: translateX(0);
  visibility: visible;
}
.mobile-menu__close {
  position: absolute;
  top: 14px;
  right: 14px;
  width: 38px;
  height: 38px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.5);
  border: 1px solid rgba(22, 22, 22, 0.08);
  color: var(--color-text);
  display: grid;
  place-items: center;
  cursor: pointer;
  transition: background 200ms var(--ease);
}
.mobile-menu__close:hover { background: rgba(255, 255, 255, 0.85); }
.mobile-menu__logo {
  /* Smaller logo so the drawer fits more content above the fold —
     was 80 px / 200 px, now scaled down to keep room for the new
     Auktionen section without forcing the user to scroll. */
  height: 60px;
  width: auto;
  max-width: 160px;
  margin-bottom: 4px;
  align-self: flex-start;
}
.mobile-menu__section { display: flex; flex-direction: column; gap: 2px; }
.mobile-menu__eyebrow {
  margin: 0 0 8px;
  font-size: 10px;
  letter-spacing: 3px;
  text-transform: uppercase;
  color: var(--color-muted);
  font-weight: 600;
}
.mobile-menu__item {
  display: block;
  padding: 10px 12px;
  background: transparent;
  border: none;
  text-align: left;
  font-family: var(--font-serif);
  font-size: 17px;
  color: var(--color-text);
  letter-spacing: 0.5px;
  cursor: pointer;
  border-radius: 8px;
  transition: background 180ms var(--ease);
  -webkit-tap-highlight-color: transparent;
}
.mobile-menu__item:hover, .mobile-menu__item:focus-visible {
  background: rgba(22, 22, 22, 0.05);
  outline: none;
}
.mobile-menu__item--gold {
  font-style: italic;
  background: linear-gradient(135deg, #f4e0b3, #d4ab68);
  color: #1c1306;
  margin-top: 4px;
  text-align: center;
  padding: 14px 16px;
  box-shadow: 0 8px 20px -10px rgba(180, 140, 74, 0.4);
}
.mobile-menu__item--gold:hover {
  background: linear-gradient(135deg, #f8e8c4, #d8b574);
}
.mobile-menu__langs {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  /* 4 columns on narrow phones so 12 languages fit in 3 rows instead
     of 4 — the lang grid was previously the tallest section by far,
     pushing everything below it off-screen. */
  grid-template-columns: repeat(4, 1fr);
  gap: 5px;
}
.mobile-menu__langs li button {
  width: 100%;
  padding: 9px 6px;
  background: rgba(255, 255, 255, 0.5);
  border: 1px solid rgba(22, 22, 22, 0.08);
  border-radius: 8px;
  font-size: 10.5px;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: var(--color-text);
  font-weight: 500;
  cursor: pointer;
  transition: all 180ms var(--ease);
  -webkit-tap-highlight-color: transparent;
}
.mobile-menu__langs li button[data-active="true"] {
  background: var(--color-text);
  color: #fff;
  border-color: var(--color-text);
}

/* Backdrop dim behind the drawer */
.mobile-menu-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(22, 22, 22, 0.35);
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
  z-index: 109;
  opacity: 0;
  pointer-events: none;
  transition: opacity 320ms var(--ease);
}
.mobile-menu-backdrop[data-open="true"] {
  opacity: 1;
  pointer-events: auto;
}

/* LEFT: logo — doubled from 90 → 180 px per user request, nudged
   slightly higher (negative top margin) and slightly further left
   (negative left margin overrides the row gap so the logo sits
   tight against the viewport edge inside the nav frame). */
.nav__brand {
  justify-self: start;
  align-self: flex-start;  /* anchor to the TOP of the nav row, not center */
  display: flex;
  align-items: center;
  padding: 0;
  margin-left: -8px;       /* slide left, past the nav frame's inner pad */
  margin-top: -50px;       /* lift well above the pill baseline */
}
.nav__brand__logo {
  display: block;
  height: 180px;            /* 2× the previous 90 px */
  width: auto;
  max-width: 460px;
  object-fit: contain;
  object-position: left center;
  mix-blend-mode: multiply;
}

/* Decorative flowers riding on the seasons pill's border. Each flower is
   absolutely positioned so it doesn't disturb the row layout, and is
   centered on the border line (half inside, half outside) for a "wreath"
   look. Add more by giving the <img> a `nav__flower--{position}` class. */
.nav__flower {
  position: absolute;
  height: 56px;
  width: auto;
  pointer-events: none;
  z-index: 1;
  user-select: none;
}

/* Position presets — each modifier centers the flower on a different
   spot of the pill's border so multiple can coexist without overlap. */
.nav__flower--top-left     { top: -28px; left: 4px; }
.nav__flower--top-center   { top: -28px; left: 50%; transform: translateX(-50%); }
.nav__flower--top-right    { top: -28px; right: 4px; }
.nav__flower--bottom-left  { bottom: -28px; left: 4px; }
.nav__flower--bottom-center{ bottom: -28px; left: 50%; transform: translateX(-50%); }
.nav__flower--bottom-right { bottom: -28px; right: 4px; }
.nav__flower--left         { top: 50%; left: -28px; transform: translateY(-50%); }
.nav__flower--right        { top: 50%; right: -28px; transform: translateY(-50%); }

/* Shared glass-pill styling for the centre + right blocks */
.nav__block {
  height: 56px;
  display: flex;
  align-items: center;
  background: var(--glass-bg);
  -webkit-backdrop-filter: blur(var(--glass-blur));
  backdrop-filter: blur(var(--glass-blur));
  border: 1px solid var(--glass-border);
  border-radius: 999px;                /* fully rounded (pill) */
  box-shadow: var(--glass-shadow);
}

/* Center cluster — wraps the seasons pill + bespoke pill into one block
   so they sit side-by-side with a comfortable gap, instead of being
   pushed to 1/3 + 2/3 by the parent's space-between. */
.nav__center {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: nowrap;
}

/* SUR MESURE button + modal styles removed per user request — the
   feature was deprecated and the markup/JS are gone.  Mobile-media-
   query rules below (around lines 2066, 2388) still reference
   `.nav__bespoke` but those selectors are dead too; we leave them as
   harmless dead CSS to minimise diff and avoid renumbering churn. */

/* MIDDLE: seasons */
.nav__seasons {
  justify-self: center;
  gap: 2px;
  padding: 0 6px;
  position: relative;              /* positioning context for decorative flowers */
  overflow: visible;
}
.nav__season {
  font-family: var(--font-sans);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 2.5px;
  text-transform: uppercase;
  color: var(--color-text);
  opacity: 0.65;
  padding: 9px 18px;
  border-radius: 999px;
  transition: opacity 200ms var(--ease), background 200ms var(--ease), color 200ms var(--ease);
}
.nav__season:hover {
  opacity: 1;
  background: rgba(22, 22, 22, 0.04);
}
.nav__season[data-active="true"] {
  opacity: 1;
  background: var(--color-text);
  color: #fff;
}
/* Above the smallest mobile breakpoint we show the season name and hide
   the icon. The icon stays in the DOM (zero cost) so the small-screen
   media query can simply flip the visibility. */
.nav__season-icon { display: none; }
.nav__season-label { display: inline; }

/* ============================================================
   ANLÄSSE — life-event dropdown inside the seasons pill
   ============================================================
   Lives INSIDE .nav__seasons so the glass pill simply expands to
   host one extra "tab" — same visual home as the 4 seasons, not a
   separate floating control.  The tab is differentiated from the
   seasons by a soft warm gradient hint behind it, so the eye reads
   it as something different worth exploring. */
.nav__divider {
  display: inline-block;
  width: 1px;
  height: 18px;
  align-self: center;
  margin: 0 6px;
  background: linear-gradient(180deg, transparent 0%, rgba(22, 22, 22, 0.18) 50%, transparent 100%);
  flex-shrink: 0;
}
.nav__occasions-toggle {
  /* Light multi-tonal gradient — distinguishes the tab without
     shouting.  Stays in the same brand palette (warm cream → rose). */
  background: linear-gradient(135deg,
    rgba(245, 232, 215, 0.55) 0%,
    rgba(232, 218, 220, 0.55) 50%,
    rgba(218, 212, 224, 0.55) 100%);
  display: inline-flex;
  align-items: center;
  gap: 6px;
  position: relative;
}
.nav__occasions-toggle .nav__season-icon {
  /* Show the star icon ALWAYS for this tab (we don't reuse the
     icon-only collapse behaviour the seasons get on mobile). */
  display: inline-flex;
  align-items: center;
  color: #8a6a2a;
}
.nav__occasions-toggle:hover {
  background: linear-gradient(135deg,
    rgba(245, 232, 215, 0.85) 0%,
    rgba(232, 218, 220, 0.85) 50%,
    rgba(218, 212, 224, 0.85) 100%);
}
.nav__occasions-toggle[aria-expanded="true"] {
  background: linear-gradient(135deg, #f5e8d7 0%, #ead4d6 50%, #dad4e0 100%);
  color: #2a1d09;
  opacity: 1;
}
.nav__occasions-caret {
  transition: transform 220ms var(--ease);
  opacity: 0.7;
  margin-left: 2px;
}
.nav__occasions-toggle[aria-expanded="true"] .nav__occasions-caret {
  transform: rotate(180deg);
}

/* ===== Dropdown panel =====
   Lives at body-level (sibling of <header class="nav">), not inside
   it — see HTML comment.  z-index 120 puts it above the .nav (50),
   the .layout-switch pill (50), and the .brand-tagline (6).  Modals
   at 10000+ still win because we don't want occasions floating over
   a payment form. */
.occasions-menu {
  position: fixed;
  /* Positioned each frame by occasions.js to sit exactly under the
     seasons pill — fixed-position so it works regardless of any
     scroll-snap weirdness or fixed-nav containing block. */
  top: 0;
  left: 0;
  z-index: 120;
  display: grid;
  grid-template-columns: repeat(2, minmax(180px, 1fr));
  gap: 6px;
  padding: 14px;
  width: min(540px, calc(100vw - 32px));
  border-radius: 22px;
  background: rgba(255, 255, 255, 0.92);
  border: 1px solid rgba(22, 22, 22, 0.08);
  box-shadow:
    0 30px 60px -24px rgba(22, 22, 22, 0.32),
    0 0 0 1px rgba(255, 255, 255, 0.6);
  -webkit-backdrop-filter: blur(22px) saturate(150%);
  backdrop-filter: blur(22px) saturate(150%);
  /* Open animation handled by JS toggling [hidden] + CSS keyframe */
  animation: occasionsIn 240ms var(--ease);
  transform-origin: top center;
}
@keyframes occasionsIn {
  from { opacity: 0; transform: translateY(-8px) scale(0.97); }
  to   { opacity: 1; transform: translateY(0)    scale(1); }
}
.occasions-menu[hidden] { display: none; }

.occasions-menu__item {
  appearance: none;
  border: 1px solid transparent;
  background: transparent;
  padding: 12px 14px;
  border-radius: 14px;
  cursor: pointer;
  display: grid;
  grid-template-columns: 36px 1fr;
  grid-template-rows: auto auto;
  align-items: center;
  column-gap: 12px;
  row-gap: 2px;
  text-align: left;
  transition: background 180ms var(--ease), border-color 180ms var(--ease), transform 180ms var(--ease);
}
.occasions-menu__item:hover {
  background: rgba(22, 22, 22, 0.03);
  border-color: rgba(22, 22, 22, 0.06);
  transform: translateX(2px);
}
.occasions-menu__bullet {
  grid-row: 1 / span 2;
  width: 36px;
  height: 36px;
  border-radius: 12px;
  display: inline-block;
  box-shadow:
    inset 0 0 0 1px rgba(255, 255, 255, 0.6),
    0 4px 10px -4px rgba(22, 22, 22, 0.2);
}
/* Per-occasion mood gradients.  Picked to evoke the *feeling* of
   each event without being literal (no white-rose tropes for
   wedding etc.) — soft, modern, museum-quality. */
.occasions-menu__bullet[data-bullet="hochzeit"] {
  background: linear-gradient(135deg, #f8eae3 0%, #e8c8c0 50%, #c7a298 100%);
}
.occasions-menu__bullet[data-bullet="geburt"] {
  background: linear-gradient(135deg, #f4e0e8 0%, #e0e8f0 50%, #c8e0d8 100%);
}
.occasions-menu__bullet[data-bullet="geburtstag"] {
  background: linear-gradient(135deg, #fbe3b8 0%, #f4ad7e 50%, #e07b6b 100%);
}
.occasions-menu__bullet[data-bullet="jubilaeum"] {
  background: linear-gradient(135deg, #f5e4ba 0%, #d4ab68 50%, #a07a3a 100%);
}
.occasions-menu__bullet[data-bullet="trauer"] {
  background: linear-gradient(135deg, #ecece4 0%, #c8d0c4 50%, #98a496 100%);
}
.occasions-menu__bullet[data-bullet="einzug"] {
  background: linear-gradient(135deg, #f4dcc4 0%, #d8a888 50%, #a87858 100%);
}
.occasions-menu__label {
  grid-column: 2;
  font-family: var(--font-serif);
  font-size: 16px;
  font-weight: 500;
  color: var(--color-text);
  line-height: 1.1;
}
.occasions-menu__sub {
  grid-column: 2;
  font-family: var(--font-sans);
  font-size: 10px;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: rgba(74, 57, 32, 0.6);
}

/* Tablet — same dropdown layout, slightly tighter. */
@media (max-width: 900px) {
  .occasions-menu {
    grid-template-columns: 1fr;
    width: min(360px, calc(100vw - 24px));
    padding: 10px;
  }
  .occasions-menu__item { padding: 10px 12px; }
}

/* ===== Mobile-menu occasions section ===== */
.mobile-menu__item--occasion {
  display: flex !important;
  align-items: center;
  gap: 12px;
  text-align: left;
}
.mobile-menu__bullet {
  display: inline-block;
  width: 24px;
  height: 24px;
  border-radius: 8px;
  flex-shrink: 0;
  box-shadow:
    inset 0 0 0 1px rgba(255, 255, 255, 0.55),
    0 2px 6px -2px rgba(22, 22, 22, 0.18);
}
/* Reuse exact same gradients as the desktop dropdown so the visual
   identity of each occasion is consistent between layouts. */
.mobile-menu__bullet[data-bullet="hochzeit"]   { background: linear-gradient(135deg, #f8eae3 0%, #e8c8c0 50%, #c7a298 100%); }
.mobile-menu__bullet[data-bullet="geburt"]     { background: linear-gradient(135deg, #f4e0e8 0%, #e0e8f0 50%, #c8e0d8 100%); }
.mobile-menu__bullet[data-bullet="geburtstag"] { background: linear-gradient(135deg, #fbe3b8 0%, #f4ad7e 50%, #e07b6b 100%); }
.mobile-menu__bullet[data-bullet="jubilaeum"]  { background: linear-gradient(135deg, #f5e4ba 0%, #d4ab68 50%, #a07a3a 100%); }
.mobile-menu__bullet[data-bullet="trauer"]     { background: linear-gradient(135deg, #ecece4 0%, #c8d0c4 50%, #98a496 100%); }
.mobile-menu__bullet[data-bullet="einzug"]     { background: linear-gradient(135deg, #f4dcc4 0%, #d8a888 50%, #a87858 100%); }
/* Phone — full-width sheet anchored near the bottom of the nav. */
@media (max-width: 600px) {
  .occasions-menu {
    width: calc(100vw - 16px);
    border-radius: 18px;
    padding: 8px;
  }
  .occasions-menu__bullet { width: 32px; height: 32px; }
  .occasions-menu__label { font-size: 15px; }
  .nav__divider { height: 14px; margin: 0 4px; }
  .nav__occasions-toggle .nav__season-label { display: none; }
  .nav__occasions-toggle { padding: 6px 10px; gap: 4px; }
}

/* RIGHT: language + cart + account */
.nav__icons {
  justify-self: end;
  gap: 4px;
  padding: 0 6px;
}

/* ---------- Language dropdown ---------- */
.lang { position: relative; margin-right: 4px; }
.lang__toggle {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 36px;
  padding: 0 12px;
  border-radius: 999px;
  font-family: var(--font-sans);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 2.5px;
  text-transform: uppercase;
  background: transparent;               /* lives inside .nav__icons glass pill */
  transition: background 200ms var(--ease);
}
.lang__toggle:hover { background: rgba(22, 22, 22, 0.06); }
.lang__caret {
  transition: transform 200ms var(--ease);
  opacity: 0.6;
}
.lang[data-open="true"] .lang__caret { transform: rotate(180deg); }

.lang__menu {
  position: absolute;
  top: calc(100% + 10px);
  right: 0;
  min-width: 200px;
  max-height: 60vh;
  overflow-y: auto;
  margin: 0;
  padding: 8px;
  list-style: none;
  background: var(--glass-bg);
  -webkit-backdrop-filter: blur(var(--glass-blur));
  backdrop-filter: blur(var(--glass-blur));
  border: 1px solid var(--glass-border);
  border-radius: 16px;
  box-shadow: var(--glass-shadow);
  opacity: 0;
  transform: translateY(-6px);
  transition: opacity 200ms var(--ease), transform 200ms var(--ease);
  pointer-events: none;
  z-index: 60;
}
.lang[data-open="true"] .lang__menu {
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
}
.lang__menu[hidden] { display: none; }
.lang__item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  padding: 10px 14px;
  border-radius: 10px;
  font-size: 13px;
  text-align: left;
  transition: background 150ms var(--ease);
}
.lang__item:hover { background: rgba(22, 22, 22, 0.06); }
.lang__item[data-active="true"] {
  background: rgba(201, 184, 155, 0.25); /* warm sand */
}
.lang__item-code {
  font-size: 10px;
  letter-spacing: 2px;
  color: var(--color-muted);
}
.nav__icon {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px; height: 40px;
  border-radius: 999px;
  transition: background 200ms var(--ease);
}
.nav__icon:hover { background: rgba(22, 22, 22, 0.05); }
.nav__badge {
  position: absolute;
  top: 2px; right: 2px;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  border-radius: 999px;
  background: var(--color-text);
  color: #fff;
  font-size: 10px;
  font-weight: 500;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
/* Browser default `[hidden]` is display:none, but the rule above overrode it.
   Restore so an empty cart shows no black dot. */
.nav__badge[hidden] { display: none !important; }

/* =========================================================
   Product cards — full viewport, scroll-snap
   ========================================================= */
main { display: block; }
/* Reserve a full viewport for the cards container so anything BELOW main
   (brand-essay, footer) stays below the fold during the brief window
   between page-load and first /api/products response.  Without this the
   brand-essay article collapsed up under the navigation on cold reload
   and the user saw the SEO content before the storefront. */
main#cards {
  min-height: 100vh;
  min-height: 100dvh;
}

/* ============================================================
   Server-rendered SEO landing block
   ============================================================
   routes/seo.js injects <article.seo-landing> with H1, intro text,
   and a list of products INTO #cards on first response.  Google +
   AI crawlers read this raw HTML before any JS executes — that's
   the actual ranking signal.
   For human visitors we keep the block off-screen (not display:none,
   which Google might discount).  Screen-reader friendly: positioned
   absolutely off the viewport, full content, full size. */
.seo-landing {
  position: absolute !important;
  left: -10000px;
  top: auto;
  width: 1px;
  height: 1px;
  overflow: hidden;
  /* Once JS replaces #cards' innerHTML with the live grid, this
     element is removed from the DOM entirely — but the original
     server response was already crawled. */
}

/* Each .card-frame is exactly one viewport tall and is a mandatory snap
   target. Animation progress is no longer driven by scroll position — see
   attachWheelLock() in app.js. The page only scrolls when the user has
   finished the current card's animation. */
.card-frame {
  position: relative;
  width: 100%;
  height: 100vh;
  height: 100dvh;
  scroll-snap-align: start;
  /* `scroll-snap-stop: always` makes mandatory snap behave like
     "page-by-page" instead of "skim through".  Without it, a fast
     swipe can carry momentum past one card and snap to the second
     or third in line — exactly the "doesn't stop on each post"
     symptom the user reported. */
  scroll-snap-stop: always;
  /* Note: `will-change: transform` was previously here for compositor
     promotion.  Removed because some iOS/Safari builds combine
     will-change with scroll-snap into a soft-snap (momentum carries
     across snap points).  Without will-change the card sits on the
     main layer and snap engages cleanly. */
}
.card {
  position: relative;
  width: 100%;
  height: 100vh;
  height: 100dvh;
  overflow: hidden;
  background: var(--color-bg);
}

/* Every "page" between the product cards is also a hard snap stop —
   prevents momentum scroll from skipping multiple sections at once,
   so the user's downward swipe travels exactly ONE page per fling. */
.scroll-snap-section {
  scroll-snap-align: start;
  scroll-snap-stop: always;
}

/* =========================================================
   Brand tagline strip — top-right of the storefront
   Italic Cormorant Garamond lines, soft-warm accent, hint at
   the philosophy of the shop. Admin-editable.
   ========================================================= */
.brand-tagline {
  position: fixed;
  top: 96px;                       /* clears the nav pill, breathes more */
  right: 80px;                     /* shifted LEFT — further from the edge */
  z-index: 6;
  pointer-events: none;
  display: flex;
  flex-direction: column;
  gap: 8px;
  text-align: right;
  max-width: 420px;
}
.brand-tagline__line {
  font-family: var(--font-serif);
  font-style: italic;
  font-size: 20px;                 /* up from 15 — more confident, more visible */
  line-height: 1.35;
  letter-spacing: 0.6px;
  color: #5a4422;
  text-shadow: 0 1px 0 rgba(255, 255, 255, 0.55);
  opacity: 0.9;
}
.brand-tagline__line:nth-child(odd) { color: #4a3920; }
.brand-tagline__line:nth-child(2)   { font-size: 26px; }   /* "Home Couture" anchor */
@media (max-width: 900px) {
  /* On mobile the right edge is busy (cart, account icons, social pill) —
     hide the philosophy strip to keep the screen breathable. */
  .brand-tagline { display: none; }
}

/* Background poster image (first frame). Shown INSTANTLY — no fade.
   The canvas paints over it once frames stream in. */
.card__media {
  position: absolute;
  inset: 0;
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  opacity: 1;
}
/* Frame-sequence image (replaces the old <video>). object-fit: contain so
   the full composition is always visible; any letterboxing is white and
   blends seamlessly with the page background. */
.card__frame {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  background: var(--color-bg);
  opacity: 0;
  transition: opacity 1200ms var(--ease);
  user-select: none;
  -webkit-user-drag: none;
}
.card__overlay {
  position: absolute;
  inset: 0;
  background: linear-gradient(
    100deg,
    rgba(255, 255, 255, 0.0) 30%,
    rgba(255, 255, 255, 0.45) 80%
  );
  pointer-events: none;
}

/* =========================================================
   Marquee gallery — one full-viewport section inserted between
   the 2nd and 3rd products. A horizontal track of equal-sized
   16:9 photos floats continuously to the left, looping
   seamlessly thanks to the JS duplicating the items list.
   ========================================================= */
.marquee {
  position: relative;
  width: 100%;
  height: 100vh;
  height: 100dvh;
  scroll-snap-align: start;
  scroll-snap-stop: always;
  background: var(--color-bg);
  display: flex;
  align-items: center;
  overflow: hidden;
  cursor: grab;                 /* hint: this strip is draggable */
  user-select: none;
  -webkit-user-select: none;
  touch-action: pan-y;          /* let page scroll vertically, JS owns horizontal */
}
.marquee--dragging { cursor: grabbing; }
.marquee__item { cursor: pointer; }
.marquee__item:hover { transform: translateY(-2px); transition: transform 200ms var(--ease); }
.marquee__track {
  display: flex;
  gap: 18px;
  width: max-content;
  padding: 0 18px;
  animation: marquee-scroll 60s linear infinite;
  will-change: transform;
}
.marquee__item {
  flex-shrink: 0;
  height: clamp(220px, 38vh, 360px);
  aspect-ratio: 16 / 9;
  border-radius: 16px;
  overflow: hidden;
  background: rgba(0, 0, 0, 0.04);
  box-shadow: 0 14px 36px -14px rgba(0, 0, 0, 0.25);
}
.marquee__item img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  user-select: none;
  -webkit-user-drag: none;
}
/* CSS keyframes kept as a fallback for when JS hasn't yet attached
   the interactive marquee (initial paint). attachMarquee() will override
   `animation: none` once it takes ownership. */
@keyframes marquee-scroll {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(-50%, 0, 0); }
}

/* =========================================================
   Marquee image lightbox — created on demand by JS when the
   user taps a thumbnail. Full-screen modal with the image.
   ========================================================= */
.marquee-lightbox {
  position: fixed;
  inset: 0;
  background: rgba(8, 8, 8, 0.86);
  -webkit-backdrop-filter: blur(20px);
  backdrop-filter: blur(20px);
  z-index: 10000;
  display: none;
  align-items: center;
  justify-content: center;
  padding: 32px;
  opacity: 0;
  transition: opacity 220ms var(--ease);
}
.marquee-lightbox[data-open="true"] {
  display: flex;
  opacity: 1;
}
.marquee-lightbox__img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  border-radius: 14px;
  box-shadow: 0 30px 80px -20px rgba(0, 0, 0, 0.6);
  user-select: none;
  -webkit-user-drag: none;
}
.marquee-lightbox__close {
  position: absolute;
  top: 18px;
  right: 18px;
  width: 44px;
  height: 44px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.16);
  border: 1px solid rgba(255, 255, 255, 0.28);
  color: #fff;
  cursor: pointer;
  display: grid;
  place-items: center;
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  transition: background 180ms var(--ease), transform 180ms var(--ease);
}
.marquee-lightbox__close:hover {
  background: rgba(255, 255, 255, 0.28);
  transform: scale(1.05);
}
@media (max-width: 900px) {
  .marquee-lightbox { padding: 16px; }
  .marquee-lightbox__close { top: 12px; right: 12px; width: 38px; height: 38px; }
}

@media (max-width: 900px) {
  .marquee__track {
    gap: 12px;
    padding: 0 10px;
    animation-duration: 38s;     /* shorter loop on small screens */
  }
  .marquee__item {
    /* Bigger on phones than before — 160 px felt cramped, especially
       in landscape.  240–320 px reads as proper hero photos. */
    height: clamp(220px, 38dvh, 320px);
    border-radius: 14px;
  }
}
@media (prefers-reduced-motion: reduce) {
  .marquee__track { animation: none; }
}

/* =========================================================
   Media slider — animation (slide 0) + gallery photos (slides 1+)
   Single horizontal carousel so users swipe / click ‹ › / dot
   to switch between the scroll-driven animation and the extra
   product photos, all in the same visual area.
   ========================================================= */
.card__media-stack {
  position: absolute;
  inset: 0;
  overflow: hidden;
  /* CRITICAL: must be `pan-x pan-y`, NOT `pan-y`.  Per the touch-action
     spec, the effective value applied to a touch point is the
     INTERSECTION of all ancestor values.  If this stack says `pan-y`,
     then no matter what `.card__slides` below declares, horizontal
     swipes are ignored by the browser — which was the root cause of
     the user-reported "stretching arrows works but finger-swipe doesn't
     change the photo or the dot" bug across many iterations.  By
     allowing BOTH axes here, the slider's own scroll-snap captures
     horizontal swipes, and vertical swipes bubble up to <html> for
     page-level snap. */
  touch-action: pan-x pan-y;
}
/* Native horizontal carousel — replaces the old JS-driven translateX
   approach (which depended on a delicate window-level touchmove
   listener and was the root cause of the reported "swipe doesn't
   change photos" complaint).  Native scroll-snap gives iOS-native
   rubber-band physics, page-by-page snap, and respects user momentum
   — no JS gesture math required.  Each slide is `flex: 0 0 100%` so
   exactly ONE photo fills the viewport at any moment. */
.card__slides {
  display: flex;
  width: 100%;
  height: 100%;
  overflow-x: auto;
  /* overflow-y: visible (NOT hidden) — when an element has y-hidden +
     pan-y, the browser tries to scroll it vertically, fails because
     there's nothing to scroll, and SWALLOWS the touch instead of
     bubbling it up to <html>.  Result: vertical swipes on the gallery
     went nowhere, so the page-level scroll-snap couldn't engage and
     the user saw "auto-scrolling without snapping".  With y-visible
     the browser knows there's no vertical scroll to claim here and
     immediately defers vertical touches up the tree, where the page
     can snap card-by-card.  Horizontal stays clipped because flex
     children with `flex: 0 0 100%` align exactly to the container. */
  overflow-y: visible;
  scroll-snap-type: x mandatory;
  /* Explicit `pan-x pan-y` — `manipulation` is also valid but on some
     older iOS Safari builds it interacted poorly with the ancestor
     chain.  Explicitly enumerating both axes leaves zero room for
     ambiguity: the element receives horizontal AND vertical pan,
     horizontal triggers its own scroll-snap, vertical bubbles up to
     <html>. */
  touch-action: pan-x pan-y;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  scroll-behavior: smooth;
  will-change: scroll-position;
}
.card__slides::-webkit-scrollbar { display: none; }   /* Safari/Chrome */
.card__slide {
  flex: 0 0 100%;
  width: 100%;
  height: 100%;
  position: relative;
  overflow: hidden;
  /* Each slide is its own snap target so swipes land on exactly one
     photo, not somewhere in between. */
  scroll-snap-align: start;
  scroll-snap-stop: always;
}
/* <img> photo slides — native CSS object-fit handles aspect-ratio
   without canvas painting.  `object-fit: contain` shows the full
   composition without cropping; `background: var(--color-bg)` fills
   the letterboxed area so the slide doesn't look "broken" when the
   image is portrait vs landscape. */
.card__slide-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  background: var(--color-bg, #f8f2ea);
  user-select: none;
  -webkit-user-drag: none;
  -webkit-touch-callout: none;
  pointer-events: none;              /* image doesn't intercept swipes */
}
/* Removed: `.card__slide--photo[data-photo-error="1"]` rules.  Since
   v72 the JS-driven canvas painter was replaced with native `<img>`
   tags whose onerror handler swaps the src to /images/placeholders/
   stille.svg directly — the data-photo-error attribute is never set
   any more, so the CSS would never trigger.  Dead code removed. */
.card__slide--photo img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  background: var(--color-bg);
  display: block;
  user-select: none;
  -webkit-user-drag: none;
}
/* Floating prev/next arrows. Always visible on desktop (no hover hide),
   but greyed out at the first/last slide. */
.card__nav {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 48px;
  height: 48px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.7);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  border: 1px solid rgba(255, 255, 255, 0.85);
  color: var(--color-text);
  cursor: pointer;
  display: grid;
  place-items: center;
  z-index: 4;
  opacity: 1;
  box-shadow: 0 8px 24px -10px rgba(22, 22, 22, 0.25);
  transition: opacity 220ms var(--ease), background 200ms var(--ease), transform 200ms var(--ease);
}
.card__nav:hover {
  background: #fff;
  transform: translateY(-50%) scale(1.06);
}
.card__nav--prev { left: 22px; }
.card__nav--next { right: 22px; }
/* JS toggles these data-* attrs to hide the arrow at the first / last slide. */
.card__media-stack[data-at-start="true"] .card__nav--prev { opacity: 0 !important; pointer-events: none; }
.card__media-stack[data-at-end="true"]   .card__nav--next { opacity: 0 !important; pointer-events: none; }

/* =========================================================
   Thumbnail strip — visual preview of each slide. Pinned to
   the BOTTOM-LEFT corner so it doesn't compete with the
   panel on the right (or the bottom-sheet on mobile).
   ========================================================= */
.card__thumbs {
  position: absolute;
  bottom: 22px;
  left: 22px;
  display: flex;
  gap: 8px;
  padding: 8px;
  background: rgba(255, 255, 255, 0.62);
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
  border: 1px solid rgba(255, 255, 255, 0.75);
  border-radius: 14px;
  z-index: 4;
  box-shadow: 0 10px 30px -12px rgba(22, 22, 22, 0.3);
  max-width: calc(100vw - 44px);
  overflow-x: auto;
  scrollbar-width: none;
}
.card__thumbs::-webkit-scrollbar { display: none; }
.card__thumb {
  position: relative;
  flex-shrink: 0;
  width: 64px;
  height: 64px;
  border-radius: 10px;
  overflow: hidden;
  border: 2px solid transparent;
  background: rgba(255, 255, 255, 0.6);
  padding: 0;
  cursor: pointer;
  transition: border-color 200ms var(--ease), transform 200ms var(--ease), box-shadow 200ms var(--ease);
}
.card__thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  pointer-events: none;
}
.card__thumb:hover {
  transform: translateY(-2px);
  border-color: rgba(22, 22, 22, 0.2);
  box-shadow: 0 6px 16px -8px rgba(22, 22, 22, 0.3);
}
.card__thumb[data-active="true"] {
  border-color: var(--la-gold, #b48c4a);
  /* MUCH louder active indicator — previous styling was too subtle on
     small mobile thumbs, users couldn't tell which one was active.
     Now: thick gold border + dark double-ring outside + 1.14 scale +
     gold glow.  Unmissable.  Also bump the z-index so the lifted thumb
     never gets clipped by neighbours during the scale transition. */
  box-shadow:
    0 0 0 3px var(--la-gold, #b48c4a),
    0 0 0 6px rgba(28, 24, 19, .92),
    0 6px 18px -4px rgba(180, 140, 74, .55);
  transform: scale(1.14);
  z-index: 2;
  position: relative;
}
/* Tiny ▶ badge on the animation thumb so user knows it's the moving one */
.card__thumb-badge {
  position: absolute;
  bottom: 4px;
  right: 4px;
  background: rgba(22, 22, 22, 0.85);
  color: #fff;
  font-size: 9px;
  line-height: 1;
  padding: 3px 5px;
  border-radius: 4px;
  pointer-events: none;
}

/* Legacy dots class kept for backwards-compat with any old markup */
.card__dots { display: none; }
.card__dot  { display: none; }

/* Glass info panel floating on the right. On ultra-wide screens
   (>1600 CSS px) the panel pulls inward so it stays in the same visual
   region as the centered 1600px content container — see paintCardCanvas
   in app.js for the matching image-side math. */
.panel {
  position: absolute;
  /* 16:9 landscape pill, BOTTOM-RIGHT next to the floating social column. */
  right: 102px;
  bottom: 16px;
  left: auto;
  top: auto;
  transform: translate(20px, 0);
  width: min(420px, 38vw);
  height: auto;                    /* size to content, badges + buy always fit */
  min-height: 280px;
  max-height: 78vh;
  padding: 4px 18px 18px;
  border-radius: 18px;
  /* === LIGHT GLASSMORPHISM ===
     Lower-alpha gradient + extra blur = airier, lets the photo show
     through more clearly. Specular top edge keeps the surface readable. */
  background:
    linear-gradient(135deg,
      rgba(255, 255, 255, 0.22) 0%,
      rgba(255, 255, 255, 0.10) 100%);
  -webkit-backdrop-filter: blur(40px) saturate(180%) brightness(1.03);
  backdrop-filter: blur(40px) saturate(180%) brightness(1.03);
  border: 1px solid rgba(255, 255, 255, 0.38);
  box-shadow:
    0 22px 56px -20px rgba(0, 0, 0, 0.28),
    inset 0 1px 0 rgba(255, 255, 255, 0.55),
    inset 0 -1px 0 rgba(0, 0, 0, 0.03),
    inset 1px 0 0 rgba(255, 255, 255, 0.28);
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 4px;
  overflow: hidden;
  z-index: 5;
  isolation: isolate;
  opacity: 0;
  transition:
    transform 1100ms var(--ease),
    opacity 900ms var(--ease);
  z-index: 2;
}

/* Heart button — wishlist toggle, top-right of the panel.
   z-index: 7 keeps it ABOVE the close-strip (z-index: 6) so the heart
   stays tappable and visible when the panel is expanded — previously
   the strip was painting over it. */
.panel__wish {
  position: absolute;
  top: 14px;
  right: 14px;
  z-index: 7;
  width: 36px;
  height: 36px;
  border-radius: 999px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: rgba(255, 255, 255, 0.5);
  border: 1px solid rgba(255, 255, 255, 0.7);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  color: var(--color-text);
  cursor: pointer;
  transition: background 200ms var(--ease), color 200ms var(--ease), transform 200ms var(--ease);
}
.panel__wish:hover {
  background: rgba(255, 255, 255, 0.85);
  transform: translateY(-1px);
}
.panel__wish[data-wished="true"] {
  background: #c14a3a;
  border-color: #c14a3a;
  color: #fff;
}
.panel__wish[data-wished="true"] svg path { fill: currentColor; }

/* Small decorative flower in the panel's top-right corner */
.panel__flower {
  position: absolute;
  top: -28px;
  right: -18px;
  height: 72px;
  width: auto;
  pointer-events: none;
  user-select: none;
  opacity: 0;
  transform: rotate(12deg) translateY(8px);
  transition: opacity 1200ms var(--ease) 400ms, transform 1200ms var(--ease) 400ms;
}
.card.is-visible .panel__flower {
  opacity: 1;
  transform: rotate(12deg) translateY(0);
}

.panel__row { display: block; }
.panel__row + .panel__row { margin-top: 6px; }

/* On the 16:9 landscape panel we hide secondary rows so just name, price,
   badges and the buy buttons remain. Stock info, the dividers and the
   separate purpose tag are too much for the compact height. */
.panel .panel__divider { display: none; }
.panel .panel__purpose { display: none; }
.panel .panel__row:has(.panel__stock) { display: none; }

/* Desktop 16:9 panel: COLUMN layout with the same compact tap-chip the
   mobile version uses — minimalist, one place to read the name + price
   and one tap to reveal the story. */
.panel__scroll {
  display: block;
  flex: 1 1 auto;
  min-width: 0;
  min-height: 0;
  overflow: hidden;
}
.panel__actions {
  display: block;
  flex: 0 0 auto;
  width: 100%;
}
.panel__actions-row {
  display: flex;
  gap: 10px;
  align-items: stretch;
}
.panel__cart-icon {
  flex: 0 0 auto;
  width: 44px;
  min-height: 44px;
  border-radius: 999px;
  border: 1px solid rgba(22, 22, 22, 0.1);
  background: rgba(255, 255, 255, 0.28);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.5);
  color: var(--color-text);
  display: grid;
  place-items: center;
  cursor: pointer;
  transition: background 200ms var(--ease), border-color 200ms var(--ease), transform 200ms var(--ease);
  /* Same fast-tap guarantee as the buy button. */
  touch-action: manipulation;
}
.panel__cart-icon:hover {
  background: rgba(255, 255, 255, 0.55);
  border-color: rgba(22, 22, 22, 0.2);
  transform: translateY(-1px);
}
.panel__cart-icon[disabled] { opacity: 0.35; cursor: not-allowed; }
/* The old text "+ in den Warenkorb" link is now redundant on every layout —
   the cart icon button next to "Buy" replaces it. */
.panel__cart-link { display: none !important; }
/* "↑ Geschichte lesen" tab is also retired — the chip's tap reveals story. */
.panel__story-btn { display: none !important; }

/* Chip / tap-strip at the top of the panel (both layouts).
   The chevron is centred at the very TOP edge as a visible expand
   affordance — never overlaps the heart in the top-right. */
.panel__tab {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 18px 16px 8px;        /* extra top room so the chev sits clear */
  background: none;
  border: none;
  cursor: pointer;
  width: 100%;
  text-align: left;
  color: var(--color-text);
  font: inherit;
  position: relative;
  -webkit-tap-highlight-color: transparent;
  flex-shrink: 0;
  /* Kill the 300ms tap-delay + double-tap zoom on iOS so the chip toggles
     instantly. Critical for the bottom-sheet to feel native. */
  touch-action: manipulation;
}
.panel__tab-chev {
  position: absolute;
  top: 4px;
  left: 50%;
  transform: translateX(-50%);
  color: rgba(22, 22, 22, 0.45);
  transition: color 200ms var(--ease), transform 300ms var(--ease);
  pointer-events: none;
}

/* ===== Close-strip — primary close affordance when the panel is open ===== */
/* Sits at the very top of the panel, full-width, clickable. Hidden when
   the panel is collapsed (the .panel__tab does the open job); appears
   when expanded so the user always has a clear way back to the photo. */
.panel__close-strip {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 38px;
  display: none;     /* hidden by default — only shown when expanded */
  align-items: center;
  justify-content: center;
  flex-direction: column;
  gap: 2px;
  /* Background made fully transparent — the previous white gradient +
     backdrop-blur was painting over the "Die Geschichte" heading AND
     the heart button in the top-right corner.  The chevron alone is a
     clear close affordance on its own; we don't need a glass strip
     behind it.  Strip remains clickable across its full width since
     it's still positioned/sized; only the visual layer is gone. */
  background: transparent;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  border: none;
  border-radius: 18px 18px 0 0;
  cursor: pointer;
  z-index: 6;
  padding: 8px 0 4px;
  touch-action: manipulation;
}
/* Handle bar removed in favour of the chevron alone — keeps the top of the
   panel uncluttered. The element is still rendered for legacy JS hooks but
   visually hidden. */
.panel__close-strip-handle {
  display: none;
}
.panel__close-strip-chev {
  color: rgba(22, 22, 22, 0.55);
  transition: color 180ms var(--ease);
}
.panel__close-strip:active .panel__close-strip-handle,
.panel__close-strip:hover .panel__close-strip-handle {
  background: rgba(22, 22, 22, 0.55);
}
.panel__close-strip:active .panel__close-strip-chev,
.panel__close-strip:hover .panel__close-strip-chev {
  color: var(--color-text);
}
/* Show ONLY when panel is expanded / story-open. The pre-existing chevron
   (`.panel__tab-chev`) handles the closed state. */
.panel[data-expanded="true"]   .panel__close-strip,
.panel[data-story-open="true"] .panel__close-strip {
  display: flex;
}
/* When close-strip is shown, hide the redundant tab chevron — they'd
   overlap at the same top-center position. */
.panel[data-expanded="true"]   .panel__tab-chev,
.panel[data-story-open="true"] .panel__tab-chev {
  opacity: 0;
}
/* Push story content below the 38px close-strip so the heading isn't
   tucked under the handle. */
.panel[data-expanded="true"]   .panel__story,
.panel[data-story-open="true"] .panel__story { margin-top: 38px; }
.panel__tab:hover .panel__tab-chev { color: var(--color-text); }
/* When the panel is expanded / story open, rotate the chevron 180° to
   read as "tap to close". Stays visible (not opacity 0) — it's now the
   primary close affordance now that tap-on-image is blocked by the
   covering panel. */
.panel[data-story-open="true"] .panel__tab-chev,
.panel[data-expanded="true"] .panel__tab-chev {
  transform: translateX(-50%) rotate(180deg);
  color: rgba(22, 22, 22, 0.7);
}
.panel__tab-logo {
  flex-shrink: 0;
  height: 22px;
  width: auto;
  max-width: 32px;
  object-fit: contain;
  opacity: 0.9;
}
.panel__tab-text {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 0;
  overflow: hidden;
}
.panel__tab-name {
  font-family: var(--font-serif);
  font-weight: 600;
  font-size: 17px;
  line-height: 1.05;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.panel__tab-meta {
  font-size: 10px;
  letter-spacing: 1.5px;
  color: var(--color-muted);
  text-transform: uppercase;
}
/* The drag-handle bar at the top is fully replaced by the centred chevron
   icon — no need for the redundant decorative dash. Hidden everywhere. */
.panel__tab-handle { display: none !important; }

/* Darken the muted greys inside the panel: against a translucent glass
   background the default #8a8a8a is too pale to read. #555 keeps the
   visual hierarchy (still muted vs the headline) but stays legible. */
.panel .panel__season,
.panel .panel__edition,
.panel .panel__purpose,
.panel .panel__remaining,
.panel .panel__stock,
.panel .panel__badge {
  color: #4f4f4f;
}

.panel__season {
  font-size: 11px;
  letter-spacing: 4px;
  text-transform: uppercase;
}
.panel__name {
  font-family: var(--font-serif);
  font-size: clamp(22px, 2vw, 30px);
  line-height: 1.05;
  font-weight: 600;
  margin: 2px 0 0;
  letter-spacing: 0.5px;
}
.panel__edition {
  font-size: 11px;
  letter-spacing: 2px;
  color: var(--color-muted);
  margin-top: 6px;
  text-transform: uppercase;
}
.panel__desc {
  font-family: var(--font-serif);
  font-size: 19px;
  line-height: 1.45;
  color: #2c2c2c;
  font-style: italic;
  margin: 18px 0 0;
}
.panel__purpose {
  font-size: 10px;
  letter-spacing: 2.5px;
  color: var(--color-muted);
  text-transform: uppercase;
  margin-top: 10px;
}
.panel__divider {
  height: 1px;
  background: var(--color-line);
  margin: 12px 0;
}
.panel__stock {
  display: flex;
  align-items: center;
  gap: 14px;
  font-size: 12px;
  letter-spacing: 1.5px;
  color: #444;
}
.panel__bar {
  flex: 1;
  height: 4px;
  background: rgba(22, 22, 22, 0.08);
  border-radius: 999px;
  overflow: hidden;
}
.panel__bar > i {
  display: block;
  height: 100%;
  background: var(--color-accent);
  width: 0;
  transition: width 1400ms var(--ease) 200ms;
}
.panel__remaining {
  font-size: 11px;
  letter-spacing: 2px;
  text-transform: uppercase;
  color: var(--color-muted);
  margin-top: 8px;
}
/* Red-tinted scarcity callout when remaining ≤ 3. */
.panel__remaining--urgent {
  color: #c14a3a;
  font-weight: 500;
}
.panel__price {
  font-family: var(--font-serif);
  font-size: 22px;
  margin-top: 6px;
}
/* German Preisangabenverordnung — every consumer price must be labelled
   "inkl. MwSt." or equivalent.  Inserted via ::after so we don't need
   to touch every render-template; renders inline next to the price. */
.panel__price::after {
  content: " inkl. MwSt.";
  display: inline-block;
  margin-left: 8px;
  font-family: var(--font-sans);
  font-size: 11px;
  font-style: normal;
  font-weight: 500;
  letter-spacing: 0.5px;
  color: var(--color-muted, #8a8a8a);
  vertical-align: 4px;
}

/* "UNIKAT" row — replaces the old scarcity bar. Communicates that each
   piece is hand-composed and photo is only a reference. Restrained gold
   eyebrow + italic serif explanation. No urgency, no countdown — purely
   a luxury reassurance line. */
.panel__unique {
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid rgba(180, 140, 74, 0.18);
}
.panel__unique-eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 10px;
  letter-spacing: 3.5px;
  text-transform: uppercase;
  font-weight: 700;
  color: #b58e4c;
  margin-bottom: 6px;
}
.panel__unique-eyebrow svg {
  color: #d4ab68;
}
.panel__unique-text {
  margin: 0;
  font-family: var(--font-serif);
  font-style: italic;
  font-size: 13.5px;
  line-height: 1.55;
  color: #3a3a3a;
  letter-spacing: 0.2px;
}

/* Story-section uniqueness disclaimer — italic serif footnote with a
   small gold sparkle in front. Lives at the bottom of the story text,
   above the Lá Tasí signature line. */
.panel__story-disclaimer {
  margin: 14px 0 8px;
  padding: 12px 14px;
  background: rgba(244, 224, 179, 0.18);
  border-left: 2px solid #d4ab68;
  border-radius: 6px;
  font-family: var(--font-serif);
  font-style: italic;
  font-size: 13.5px;
  line-height: 1.55;
  color: #4a3920;
}
.panel__story-disclaimer svg { color: #b58e4c; }

/* "↑ Geschichte lesen" — tab-shape glass pill that HANGS from the very
   top edge of the panel, centred. Square top, rounded bottom — visually
   attached to the panel's top border. Stays visible both states.
   !important on positioning so flex parents can't pull it back into flow. */
.panel__story-btn {
  position: absolute !important;
  top: 0 !important;
  left: 50% !important;
  right: auto !important;
  bottom: auto !important;
  transform: translateX(-50%) !important;
  width: auto !important;
  margin: 0 !important;
  z-index: 4;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 18px 8px;
  border-radius: 0 0 14px 14px;
  background:
    linear-gradient(180deg,
      rgba(255, 255, 255, 0.55) 0%,
      rgba(255, 255, 255, 0.18) 100%);
  -webkit-backdrop-filter: blur(14px) saturate(140%);
  backdrop-filter: blur(14px) saturate(140%);
  border: none !important;
  outline: none;
  box-shadow: none;                              /* no rim, no border */
  font-family: var(--font-serif);
  font-style: italic;
  font-size: 12px;
  letter-spacing: 1px;
  color: var(--color-text);
  cursor: pointer;
  transition: background 200ms var(--ease);
  white-space: nowrap;
  /* Gentle vertical bob to catch attention without being intrusive. */
  animation: story-bob 2.4s ease-in-out infinite;
}
.panel__story-btn:hover {
  background:
    linear-gradient(180deg,
      rgba(255, 255, 255, 0.75) 0%,
      rgba(255, 255, 255, 0.32) 100%);
  animation-play-state: paused;
}
.panel[data-story-open="true"] .panel__story-btn {
  animation: none;                               /* still while open */
}
@keyframes story-bob {
  0%, 100% { transform: translateX(-50%) translateY(0); }
  50%      { transform: translateX(-50%) translateY(4px); }
}
@media (prefers-reduced-motion: reduce) {
  .panel__story-btn { animation: none; }
}
.panel__story-btn svg { opacity: 0.7; transition: opacity 200ms var(--ease), transform 200ms var(--ease); }
.panel__story-btn:hover svg { opacity: 1; }
/* When the story is open, flip the arrow to indicate "tap to close". */
.panel[data-story-open="true"] .panel__story-btn svg { transform: rotate(180deg); }

/* =========================================================
   Story SECTION — lives INSIDE the panel at the top.
   The panel is bottom-anchored on both layouts, so when the
   story is open the panel grows TALLER and its top edge
   moves UPWARD on screen — no separate modal, no separate
   window: the existing panel just unfolds.
   ========================================================= */
/* Closed: completely removed from layout (no width on desktop row
   layout, no height on mobile column). Open: panel switches to
   column direction and story appears at the top with a slide-in. */
.panel__story { display: none; }
.panel[data-story-open="true"] {
  flex-direction: column;          /* desktop was row — story needs full top edge */
  align-items: stretch;
}
.panel[data-story-open="true"] .panel__story {
  display: block;
  position: relative;
  flex-shrink: 0;
  order: -1;
  padding: 22px 22px 18px;
  margin: 0 0 8px;
  max-height: 360px;
  overflow-y: auto;
  border-bottom: 1px solid rgba(22, 22, 22, 0.08);
  animation: panel-story-reveal 480ms cubic-bezier(0.16, 1, 0.3, 1);
}
@keyframes panel-story-reveal {
  from { max-height: 0; opacity: 0; }
  to   { max-height: 360px; opacity: 1; }
}
/* Redundant now that tap-on-image closes the story. Removing it cleans
   up the cluster that was sitting under/behind the wishlist heart. */
.panel__story-close { display: none !important; }
.panel__story-eyebrow {
  font-size: 10px;
  letter-spacing: 4px;
  text-transform: uppercase;
  color: var(--color-accent);
  margin-bottom: 12px;
}
.panel__story-text {
  font-family: var(--font-serif);
  font-style: italic;
  font-size: 16px;
  line-height: 1.55;
  color: #2c2c2c;
  white-space: pre-wrap;
  margin: 0 0 12px;
}
.panel__story-signature {
  font-size: 10px;
  letter-spacing: 4px;
  text-transform: uppercase;
  color: var(--color-muted);
  text-align: right;
}

/* Desktop: 16:9 panel must drop the fixed ratio when story opens —
   otherwise growing height also grows width. Keep width pinned, let
   height drive — panel then visibly expands upward. */
@media (min-width: 901px) {
  .panel[data-story-open="true"] {
    aspect-ratio: auto;
    width: min(520px, 50vw);
    height: auto;
    max-height: 78vh;
  }
}
/* Mobile: panel is already flex column with auto height — the story
   section simply pushes the panel taller and the top edge upward. */
@media (max-width: 900px) {
  .panel[data-story-open="true"] {
    max-height: calc(100dvh - 40px);
  }
  .panel[data-story-open="true"] .panel__story {
    max-height: 50dvh;
    padding: 18px 18px 14px;
  }
  .panel__story-text { font-size: 15px; color: #1c1c1c; }
  /* On the transparent mobile panel the warm-sand "DIE GESCHICHTE" label
     was washing out — use a darker brown so the heading is clearly
     readable through the glass. */
  .panel__story-eyebrow { color: #4a3920; font-weight: 600; }
  .panel__story-signature { color: #6b5430; }
}

/* =========================================================
   Legacy story modal (no longer used, kept for safety).
   ========================================================= */
.story-modal {
  position: fixed;
  inset: 0;
  background: rgba(15, 12, 8, 0.42);
  /* Heavier backdrop blur was perceptibly tanking the first-frame
     opening cost on iOS Safari (≈80–120 ms paint stall).  Drop to a
     light 6 px — still gives the milky-glass effect over the page
     beneath without the GPU hit that caused users to perceive the
     modal as "lagging then jumping open". */
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  z-index: 9000;
  display: flex;
  /* Top-aligned so the sheet visually "opens downward" from the page
     header — per design feedback "плавно раскрываться вниз". */
  align-items: flex-start;
  justify-content: center;
  opacity: 0;
  pointer-events: none;
  /* Shorter fade so the entire open animation finishes in ≤ 260 ms
     instead of the previous ≈ 480 ms — feels snappier without losing
     the smooth reveal. */
  transition: opacity 220ms var(--ease);
}
.story-modal[data-open="true"] {
  opacity: 1;
  pointer-events: auto;
}
.story-modal__sheet {
  position: relative;
  width: min(640px, calc(100% - 24px));
  /* Three-zone layout: sticky header + scrollable body + sticky buy
     button.  flex column drives this; the body grows/shrinks while
     the header and footer keep their natural size and always stay
     visible.  100dvh-aware so iOS URL-bar doesn't push the buy CTA
     past the visible viewport. */
  max-height: calc(100dvh - 80px);
  display: flex;
  flex-direction: column;
  /* Sheet sits near the top of the viewport so it "drops down" from
     above (matches the new align-items: flex-start on the host). */
  margin: 40px 0 40px;
  padding: 0;                          /* zones add their own padding */
  border-radius: 22px;
  background:
    linear-gradient(135deg,
      rgba(255, 255, 255, 0.92) 0%,
      rgba(255, 255, 255, 0.82) 100%);
  /* Sheet blur dropped from 40 px → 14 px.  Combined with the lighter
     glass background (0.92 / 0.82 instead of 0.72 / 0.55) the panel
     still reads as frosted glass but paints in a single frame on iOS,
     instead of the multi-frame stutter that produced the perceived
     lag. */
  -webkit-backdrop-filter: blur(14px) saturate(140%);
  backdrop-filter: blur(14px) saturate(140%);
  box-shadow:
    0 32px 80px -20px rgba(0, 0, 0, 0.4),
    inset 0 1px 0 rgba(255, 255, 255, 0.65);
  /* OPEN DOWNWARD: start above the final position and slide down.
     Previously started at translateY(40px) (slid up), which read as
     "rises from bottom" — opposite of what the user requested. */
  transform: translateY(-32px);
  transition: transform 260ms cubic-bezier(0.16, 1, 0.3, 1);
  overflow: hidden;                    /* clip body scroll to rounded corners */
  /* will-change tells the compositor to put this on its own layer so
     the very first frame already has a paint target, avoiding the
     mid-animation layer-promotion stall. */
  will-change: transform, opacity;
}
.story-modal[data-open="true"] .story-modal__sheet {
  transform: translateY(0);
}

/* ----- Header (title + X close) ----- */
.story-modal__head {
  flex: 0 0 auto;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  padding: 24px 24px 12px;
  border-bottom: 1px solid rgba(22, 22, 22, 0.08);
  background: rgba(255, 255, 255, 0.5);
}
.story-modal__close {
  flex: 0 0 auto;
  width: 44px;                          /* Apple HIG tap target */
  height: 44px;
  border-radius: 999px;
  border: 1px solid rgba(22, 22, 22, 0.08);
  background: rgba(255, 255, 255, 0.85);
  color: var(--color-text);
  cursor: pointer;
  display: grid;
  place-items: center;
  -webkit-tap-highlight-color: transparent;
  transition: background 180ms var(--ease), transform 120ms ease;
}
.story-modal__close:hover { background: #fff; }
.story-modal__close:active { transform: scale(.96); }

.story-modal__title {
  font-family: var(--font-serif);
  font-size: clamp(22px, 3vw, 30px);
  font-weight: 600;
  margin: 0;
  line-height: 1.1;
  flex: 1 1 auto;
  /* Sit visually aligned with the X — slight top padding so the
     baseline matches the close-button centre. */
  padding-top: 4px;
}

/* ----- Body (scrollable story text) ----- */
.story-modal__body {
  flex: 1 1 auto;
  min-height: 0;                        /* required for flex+overflow */
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  padding: 18px 24px 8px;
}
.story-modal__edition {
  font-size: 10px;
  letter-spacing: 3px;
  text-transform: uppercase;
  color: var(--color-muted);
  margin: 0 0 16px;
}
.story-modal__text {
  font-family: var(--font-serif);
  font-style: italic;
  font-size: 17px;
  line-height: 1.6;
  color: #2c2c2c;
  white-space: pre-wrap;
  margin: 0 0 18px;
}
.story-modal__signature {
  font-family: var(--font-serif);
  font-size: 13px;
  letter-spacing: 5px;
  text-transform: uppercase;
  color: var(--color-accent);
  text-align: right;
  border-top: 1px solid rgba(22, 22, 22, 0.1);
  padding-top: 14px;
  margin: 8px 0 0;
}

/* ----- Footer (sticky buy button) ----- */
.story-modal__foot {
  flex: 0 0 auto;
  padding: 14px 18px max(14px, env(safe-area-inset-bottom));
  background: rgba(255, 255, 255, 0.85);
  border-top: 1px solid rgba(22, 22, 22, 0.06);
}
.story-modal__buy {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  min-height: 52px;
  padding: 0 22px;
  border-radius: 12px;
  border: none;
  background: linear-gradient(135deg, #1c1813 0%, #2a2418 100%);
  color: #fff;
  font: 600 14.5px/1 var(--font-sans, Inter, sans-serif);
  letter-spacing: 1.3px;
  text-transform: uppercase;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: transform .12s ease, box-shadow .15s ease;
  box-shadow: 0 8px 20px -10px rgba(0, 0, 0, .35);
}
.story-modal__buy:hover { transform: translateY(-1px); box-shadow: 0 12px 24px -10px rgba(0, 0, 0, .45); }
.story-modal__buy:active { transform: translateY(0); }
.story-modal__buy > span:last-child {
  font-variant-numeric: tabular-nums;
  letter-spacing: .5px;
}

@media (max-width: 600px) {
  /* On mobile the sheet runs nearly edge-to-edge with a small top gap
     so the open-downward drop reveals a strip of the page above it —
     reinforces the "this is opening from above" gesture. */
  .story-modal__sheet {
    width: calc(100% - 12px);
    max-height: calc(100dvh - 80px);
    margin: 20px 0 6px;
    /* Mobile blur cap (matches the global 24px cap on .panel /
       .modal / .drawer) — even 24 px is heavy on mid-range phones, so
       we stay at 12 px specifically here to keep the first paint
       cheap. */
    -webkit-backdrop-filter: blur(12px) saturate(140%);
    backdrop-filter: blur(12px) saturate(140%);
  }
  .story-modal__head { padding: 18px 16px 10px; }
  .story-modal__body { padding: 14px 16px 4px; }
  .story-modal__foot { padding: 12px 14px max(12px, env(safe-area-inset-bottom)); }
  .story-modal__title { font-size: 20px; }
  .story-modal__text { font-size: 15.5px; line-height: 1.55; }
}

/* Trust badges under the price — handmade · worldwide shipping · secure. */
.panel__badges {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 10px;
  /* Visual room before the "Купить" CTA — badges shouldn't crowd the
     primary action. */
  margin-bottom: 14px;
}
.panel__badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px 8px;
  border-radius: 999px;
  background: rgba(22, 22, 22, 0.04);
  color: var(--color-muted);
  font-size: 9.5px;
  letter-spacing: 1px;
  text-transform: uppercase;
}
.panel__badge svg { flex-shrink: 0; opacity: 0.7; }
/* Gift badge — slightly accent-tinted so it stands out as a feature rather
   than a trust signal. Same shape as siblings, gold-warm bg. */
.panel__badge--gift {
  background: rgba(201, 184, 155, 0.22);
  color: #6b5430;
}
.panel__badge--gift svg { opacity: 0.9; }
/* Primary BUY button — LUXE GOLD. Champagne-gold gradient with darker
   inner band fakes a brushed-metal sheen; subtle inner top highlight +
   inner bottom shadow give it weight. Reads as expensive and premium,
   pairs cleanly with the warm-sand brand palette. */
.panel__buy {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  margin-top: 0;
  padding: 12px 18px;
  border-radius: 999px;
  background:
    linear-gradient(135deg,
      #f4e0b3 0%,
      #d4ab68 48%,
      #ecd1a0 100%);             /* lighter champagne — less heavy than before */
  border: none;
  box-shadow:
    0 10px 24px -10px rgba(180, 140, 74, 0.45),
    0 2px 6px -2px rgba(0, 0, 0, 0.15),
    inset 0 1px 0 rgba(255, 255, 255, 0.7),
    inset 0 -1px 0 rgba(120, 90, 38, 0.25);
  color: #2a1d09;
  font-size: 11px;
  letter-spacing: 3px;
  text-transform: uppercase;
  font-weight: 600;
  cursor: pointer;
  transition: transform 220ms var(--ease), box-shadow 220ms var(--ease), background 220ms var(--ease), filter 220ms var(--ease);
  text-shadow: 0 1px 0 rgba(255, 255, 255, 0.25);
  touch-action: manipulation;
}
.panel__buy:hover {
  background:
    linear-gradient(135deg,
      #f8e8c4 0%,
      #d8b574 48%,
      #f0d8a8 100%);
  transform: translateY(-1px);
  box-shadow:
    0 14px 30px -10px rgba(180, 140, 74, 0.5),
    0 3px 8px -2px rgba(0, 0, 0, 0.2),
    inset 0 1px 0 rgba(255, 255, 255, 0.8),
    inset 0 -1px 0 rgba(120, 90, 38, 0.3);
  filter: brightness(1.03);
}
.panel__buy[disabled] {
  background:
    linear-gradient(135deg, rgba(180, 140, 74, 0.35) 0%, rgba(180, 140, 74, 0.5) 100%);
  color: rgba(28, 19, 6, 0.4);
  cursor: not-allowed;
  transform: none;
  filter: saturate(0.5);
}

/* Secondary "+ in den Warenkorb" — AIRY LIGHT GLASS pill. */
.panel__cart-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  margin-top: 8px;
  padding: 9px 16px;
  border-radius: 999px;
  background:
    linear-gradient(135deg,
      rgba(255, 255, 255, 0.32) 0%,
      rgba(255, 255, 255, 0.14) 100%);
  -webkit-backdrop-filter: blur(24px) saturate(170%);
  backdrop-filter: blur(24px) saturate(170%);
  border: none;
  box-shadow:
    0 8px 22px -14px rgba(0, 0, 0, 0.3),
    inset 0 1px 0 rgba(255, 255, 255, 0.55),
    inset 0 -1px 0 rgba(0, 0, 0, 0.03);
  font-size: 10px;
  letter-spacing: 2.5px;
  text-transform: uppercase;
  color: var(--color-text);
  text-align: center;
  cursor: pointer;
  transition: background 220ms var(--ease), transform 220ms var(--ease), box-shadow 220ms var(--ease);
}
.panel__cart-link:hover {
  background:
    linear-gradient(135deg,
      rgba(255, 255, 255, 0.48) 0%,
      rgba(255, 255, 255, 0.24) 100%);
  transform: translateY(-1px);
  box-shadow:
    0 10px 24px -12px rgba(0, 0, 0, 0.28),
    inset 0 1px 0 rgba(255, 255, 255, 0.55),
    inset 0 -1px 0 rgba(0, 0, 0, 0.03);
}
.panel__cart-link[disabled] { opacity: 0.3; cursor: not-allowed; }

/* ---------- Staged reveal ----------
   Each .reveal child sits offset + transparent until .card.is-visible.
   Inline --i (set in JS) controls its position in the stagger.       */
.reveal {
  opacity: 0;
  transform: translateY(14px);
  transition:
    opacity var(--reveal-duration) var(--ease),
    transform var(--reveal-duration) var(--ease);
  transition-delay: calc(var(--i, 0) * var(--reveal-base) + 250ms);
}

.card.is-visible .card__media { opacity: 1; transform: scale(1); }
.card.is-visible .card__frame { opacity: 1; }
.card.is-visible .panel { opacity: 1; transform: translate(0, 0); }
.card.is-visible .reveal { opacity: 1; transform: translateY(0); }

/* Sold-out state */
.card[data-soldout="true"] .panel__buy { pointer-events: none; }
.card[data-soldout="true"] .panel__name::after {
  content: " — Sold Out";
  font-size: 0.5em;
  color: var(--color-muted);
  letter-spacing: 3px;
  text-transform: uppercase;
  display: block;
  margin-top: 6px;
}

/* =========================================================
   Scroll hint (first card only)
   ========================================================= */
.scroll-hint {
  position: fixed;
  left: 50%;
  bottom: 28px;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  font-size: 10px;
  letter-spacing: 4px;
  text-transform: uppercase;
  color: var(--color-text);
  opacity: 0;
  transition: opacity 600ms var(--ease);
  pointer-events: none;
  z-index: 10;
}
.scroll-hint[data-visible="true"] { opacity: 0.6; animation: bob 2.2s ease-in-out infinite; }
@keyframes bob {
  0%, 100% { transform: translate(-50%, 0); }
  50%      { transform: translate(-50%, 6px); }
}

/* =========================================================
   Footer
   ========================================================= */
.footer {
  position: relative;
  width: 100%;
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--color-bg);   /* solid white — seamless with card videos */
  padding: 80px 32px;
}
.footer__glass {
  width: min(1200px, 100%);
  display: grid;
  grid-template-columns: 1.5fr 1fr 1fr 1fr;
  gap: 56px;
  padding: 56px;
  background: var(--glass-bg);
  -webkit-backdrop-filter: blur(var(--glass-blur));
  backdrop-filter: blur(var(--glass-blur));
  border: 1px solid var(--glass-border);
  border-radius: 28px;
  box-shadow: var(--glass-shadow);
  position: relative;
}

/* Decorative flowers placed only in the panel's NATURAL empty space —
   nothing over text. The "Kontakt" column is short (just email + Instagram),
   leaving a tall empty pocket in the bottom-right; that's the main flower.
   Two smaller accents peek from the left & right edges outside the panel. */
.footer__flower {
  position: absolute;
  width: auto;
  pointer-events: none;
  user-select: none;
}

/* MAIN: bottom-right empty zone, beneath the Kontakt column (Instagram link). */
.footer__flower--main {
  bottom: 28px;
  right: 36px;
  height: 150px;
  transform: rotate(-6deg);
  z-index: 2;
}

/* Side accents — peek out from behind the panel along the side edges,
   so they're entirely outside the content columns and can't cover text. */
.footer__flower--edge-left {
  top: 38%;
  left: -44px;
  height: 100px;
  transform: rotate(-28deg);
  z-index: 1;
}
.footer__flower--edge-right {
  top: 18%;
  right: -34px;
  height: 80px;
  transform: rotate(22deg);
  z-index: 1;
  opacity: 0.92;
}
.footer__col h4 {
  font-size: 11px;
  letter-spacing: 3px;
  text-transform: uppercase;
  color: var(--color-muted);
  margin: 0 0 18px;
  font-weight: 500;
}
.footer__brand {
  font-family: var(--font-serif);
  font-size: 30px;
  letter-spacing: 4px;
  text-transform: uppercase;
  margin-bottom: 16px;
}
/* Logo replacement for the old text brand mark in the footer's first column. */
.footer__brand-logo {
  display: block;
  height: 144px;
  width: auto;
  max-width: 320px;
  object-fit: contain;
  margin: -16px 0 22px;
}
@media (max-width: 560px) {
  .footer__brand-logo { height: 96px; max-width: 220px; margin: -8px 0 16px; }
}
.footer__tag {
  font-family: var(--font-serif);
  font-style: italic;
  color: #444;
  margin: 0;
  font-size: 17px;
  line-height: 1.5;
}
.footer__link {
  display: block;
  font-size: 13px;
  margin-bottom: 10px;
  color: var(--color-text);
  opacity: 0.75;
  text-align: left;
  transition: opacity 200ms var(--ease);
}
.footer__link:hover { opacity: 1; }
.footer__link[disabled] { opacity: 0.4; cursor: not-allowed; }

/* Newsletter signup — spans all 4 columns at the bottom of the footer panel */
.footer__newsletter {
  grid-column: 1 / -1;
  margin-top: 18px;
  padding-top: 26px;
  border-top: 1px solid var(--color-line);
  display: grid;
  gap: 14px;
  justify-items: start;
}
.footer__newsletter-title {
  font-family: var(--font-serif);
  font-size: 18px;
  font-style: italic;
  color: var(--color-text);
  margin: 0;
  line-height: 1.4;
  max-width: 540px;
}
.footer__newsletter-form {
  display: flex;
  gap: 8px;
  width: min(420px, 100%);
  /* Critical: allows the flex children to shrink below their
     intrinsic content size on narrow screens.  Without this, the
     long uppercase letter-tracked button label refuses to shrink
     and pushes the form past the viewport edge. */
  max-width: 100%;
  flex-wrap: nowrap;
  box-sizing: border-box;
}
.footer__newsletter-form input {
  flex: 1 1 auto;
  /* Allow the input to shrink down to a sensible minimum instead of
     defaulting to ~200 px and overflowing on a 320 px iPhone SE. */
  min-width: 0;
  height: 44px;
  padding: 0 14px;
  border-radius: 999px;
  border: 1px solid rgba(22, 22, 22, 0.15);
  background: rgba(255, 255, 255, 0.7);
  font: inherit;
  /* iOS Safari auto-zooms <input> fonts below 16 px on focus, which
     visibly pans the page off-screen.  16 px = no zoom. */
  font-size: 16px;
  color: var(--color-text);
  font-family: var(--font-sans);
  -webkit-appearance: none;
  appearance: none;
}
.footer__newsletter-form input:focus {
  outline: none;
  border-color: var(--color-accent);
  background: #fff;
}
.footer__newsletter-form button {
  flex: 0 0 auto;
  height: 44px;
  padding: 0 22px;
  border-radius: 999px;
  background: var(--color-text);
  color: #fff;
  border: none;
  font-size: 11px;
  letter-spacing: 2.5px;
  text-transform: uppercase;
  cursor: pointer;
  transition: background 200ms var(--ease);
  white-space: nowrap;
}
.footer__newsletter-form button:hover { background: #000; }
.footer__newsletter-form button[disabled] { opacity: 0.5; cursor: not-allowed; }
.footer__newsletter-thanks {
  font-family: var(--font-serif);
  font-style: italic;
  color: var(--color-accent);
  margin: 0;
}

/* =========================================================
   Responsive — panel becomes bottom sheet on small screens
   ========================================================= */
@media (max-width: 900px) {
  /* Compact glass nav: hamburger left, logo center, icons right.
     The middle cluster (seasons + bespoke) and lang dropdown are
     hidden — they live in the mobile drawer now. */
  .nav { top: 6px; left: 6px; right: 6px; }
  .nav__inner {
    gap: 6px;
    grid-template-rows: auto;
    align-items: center;
    min-height: 80px;
    /* Critical: every flex child must be allowed to shrink below its
       content size, otherwise long items push the row past the viewport
       and the right cluster falls off-screen on narrow phones. */
    flex-wrap: nowrap;
  }
  .nav__inner > * { min-width: 0; flex-shrink: 1; }
  .nav__brand {
    margin-top: 0;
    align-self: center;
    justify-self: center;
    /* Brand container is allowed to shrink the most — hamburger + icons
       are smaller fixed widths that must always be visible. */
    flex: 0 1 auto;
    min-width: 0;
    overflow: hidden;
  }
  /* Doubled from 72 → 144 px to match the desktop scale-up.  Width clamp
     still respects viewport so on tiny phones the icons cluster never
     gets pushed off-screen — `min(400px, 45vw)` is the cap. */
  .nav__brand__logo {
    height: 144px;
    max-width: min(400px, 45vw);
    width: auto;
  }
  /* Pull the bigger logo significantly higher + left on mobile too.
     align-self: flex-start anchors it to the top of the nav row
     instead of vertically centered with the pills below. */
  .nav__brand {
    align-self: flex-start;
    margin-top: -40px;
    margin-left: -4px;
  }
  /* Show hamburger, hide center cluster + language dropdown */
  .nav__burger { display: flex !important; flex: 0 0 auto; }
  .nav__center { display: none !important; }
  .lang { display: none !important; }
  /* Right cluster — never shrinks below its natural width */
  .nav__icons { flex: 0 0 auto; }
  /* Flowers are too cluttered on a small nav — hide on mobile */
  .nav__flower { display: none; }
  /* Tablet/phone bespoke pill — shrink padding + font, keep visible */
  .nav__bespoke {
    padding: 7px 12px;
    font-size: 11px;
    letter-spacing: 1px;
    gap: 5px;
  }
  .nav__block { height: 42px; }
  .nav__season { padding: 6px 8px; font-size: 9px; letter-spacing: 1.5px; }
  .nav__icon { width: 32px; height: 32px; }
  .lang__toggle { height: 28px; padding: 0 8px; font-size: 9px; }

  /* === MOBILE CARD LAYOUT ===
     Canvas is full-bleed behind everything; panel is a fixed bottom-sheet
     occupying the lower 56% of the viewport. The action bar (buy + cart)
     sits OUTSIDE the scroll area at the panel's bottom, so it's reachable
     no matter what's inside. Uses dynamic viewport height (dvh) so iOS
     Safari's URL bar doesn't push it off-screen. */
  .card-frame {
    /* Card sized to the viewport MINUS the fixed prelaunch banner at
       top.  Earlier it was full 100dvh, so when snap aligned the card
       to the banner's bottom (via scroll-padding-top), the bottom
       ~70 px of the card — where the buy CTA lives — extended below
       the visible viewport.  Subtracting banner height means the
       entire card fits exactly between banner-bottom and viewport-
       bottom, with the chip + buy button always reachable.
       CSS var is published live by prelaunch.js's banner-height
       tracker (settles within one frame of mount). */
    height: calc(100vh - var(--prelaunch-banner-h, 70px));
    height: calc(100dvh - var(--prelaunch-banner-h, 70px));
  }
  .card {
    display: block;
    position: relative;
    height: 100%;       /* match the frame above (already banner-aware) */
    padding: 0;
    overflow: hidden;
  }
  /* Canvas / placeholder fills the WHOLE card behind the panel */
  .card__media, .card__frame {
    position: absolute !important;
    inset: 0;
    width: 100%;
    height: 100%;
    z-index: 1;
  }
  .card__overlay { display: none; }

  /* ===== FLOATING GLASS PANEL ===== */
  /* The media block (canvas / photo) fills the WHOLE viewport. The panel
     floats above it as a translucent glass pill, with 10 px margin on all
     sides — so the user always sees the photograph behind it. Collapsed
     by default, expands on tap. Nothing covers the photo full-bleed. */
  .panel {
    position: absolute;
    left: 6px;
    right: 6px;
    /* Push panel as low as the device allows. `env(safe-area-inset-bottom)`
       respects iOS home-indicator + Android gesture area so nothing is cut.
       On devices without a safe-area, falls back to 2 px. */
    bottom: max(2px, env(safe-area-inset-bottom));
    top: auto;
    width: auto;
    height: auto;
    /* IMPORTANT: explicitly reset the desktop aspect-ratio, min-height + alignment
       properties. Without this the desktop `.panel { min-height: 280px }`
       cascades into mobile and forces the collapsed bottom-sheet to ~half
       the screen tall, making it look like it's stuck mid-page. */
    aspect-ratio: auto;
    min-height: 0;
    align-items: stretch;
    gap: 0;
    max-height: calc(100dvh - 60px);
    transform: none;
    opacity: 1;
    border-radius: 18px;
    padding: 0;
    /* Mobile panel — strong opaque glass so text never fights the photo
       behind it. We keep the SUBTLE glass aesthetic (still some blur +
       inset highlight) but raise the white alpha so even on bright /
       busy backgrounds every label reads cleanly. */
    background:
      linear-gradient(135deg,
        rgba(255, 255, 255, 0.92) 0%,
        rgba(252, 248, 240, 0.88) 100%);
    -webkit-backdrop-filter: blur(28px) saturate(180%);
    backdrop-filter: blur(28px) saturate(180%);
    border: 1px solid rgba(255, 255, 255, 0.7);
    box-shadow:
      0 18px 44px -12px rgba(0, 0, 0, 0.30),
      inset 0 1px 0 rgba(255, 255, 255, 0.9);
    --color-muted: #4a4a4a;       /* still muted but readable on near-opaque glass */
    display: flex;
    flex-direction: column;
    z-index: 3;
    overflow: hidden;
    transition: max-height 360ms cubic-bezier(0.4, 0, 0.2, 1);
  }

  /* Mobile-only tap-strip: name + price + chevron. Tiny drag-handle on top
     hints at expandability. */
  .panel__tab {
    display: flex !important;
    flex-shrink: 0;
    align-items: center;
    gap: 10px;
    padding: 8px 12px 4px;        /* tight vertical padding */
    background: none;
    border: none;
    cursor: pointer;
    width: 100%;
    text-align: left;
    color: var(--color-text);
    font: inherit;
    position: relative;
    -webkit-tap-highlight-color: transparent;
  }
  .panel__tab-handle {
    position: absolute;
    top: 3px; left: 50%;
    transform: translateX(-50%);
    width: 32px;
    height: 3px;
    border-radius: 999px;
    background: rgba(22, 22, 22, 0.2);
  }
  /* Tiny brand mark on the left of the mobile chip. */
  .panel__tab-logo {
    flex-shrink: 0;
    height: 22px;
    width: auto;
    max-width: 36px;
    object-fit: contain;
    opacity: 0.85;
  }
  .panel__tab-text {
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    gap: 1px;
    min-width: 0;
    overflow: hidden;
  }
  .panel__tab-name {
    font-family: var(--font-serif);
    font-weight: 600;
    font-size: 16px;
    line-height: 1.05;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .panel__tab-meta {
    font-size: 9px;
    letter-spacing: 1.2px;
    color: var(--color-muted);
    text-transform: uppercase;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  /* Mobile chevron — visible only while the sheet is collapsed; fades
     away once the description opens (handled by the default rule above)
     so there's no redundant arrow sitting next to the heart. */
  .panel__tab-chev { color: rgba(22, 22, 22, 0.5); }

  /* Scrollable content — completely REMOVED from layout when collapsed,
     so there's no flex-growing empty area. */
  .panel:not([data-expanded="true"]) .panel__scroll { display: none; }
  .panel[data-expanded="true"] .panel__scroll {
    display: block;
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
    padding: 4px 14px 10px;
  }

  /* Cap the expanded panel so it doesn't blanket the entire photo.
     Was: max-height calc(100dvh - 60px) inherited from the base rule
     above (~95% of screen).  Now: 62dvh max — the photo above the
     panel stays visible, and the user can still see WHICH composition
     they're reading about.  Scroll inside the panel handles long copy. */
  .panel[data-expanded="true"] {
    max-height: 62dvh;
  }

  /* Action bar on mobile = single row: big "Купить" + compact cart-icon
     square next to it. The secondary text link is hidden — its job is
     done by the icon button. */
  .panel__actions {
    flex-shrink: 0;
    width: auto;
    padding: 0 10px 10px;
    background: transparent;
    display: block;
  }
  .panel__actions-row {
    display: flex;
    gap: 8px;
    align-items: stretch;
  }
  .panel__buy {
    flex: 1 1 auto;
    margin: 0;
    padding: 11px 14px;
    font-size: 11px;
    letter-spacing: 2.5px;
    border-radius: 12px;
  }
  .panel__cart-icon {
    flex: 0 0 auto;
    width: 44px;
    height: auto;
    min-height: 44px;
    border-radius: 12px;
    border: 1px solid rgba(22, 22, 22, 0.1);
    background: rgba(255, 255, 255, 0.32);
    -webkit-backdrop-filter: blur(14px);
    backdrop-filter: blur(14px);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.5);
    color: var(--color-text);
    display: grid;
    place-items: center;
    cursor: pointer;
    transition: background 200ms var(--ease), border-color 200ms var(--ease), transform 200ms var(--ease);
  }
  .panel__cart-icon:hover {
    background: rgba(255, 255, 255, 0.6);
    border-color: rgba(22, 22, 22, 0.2);
    transform: translateY(-1px);
  }
  .panel__cart-icon[disabled] { opacity: 0.35; cursor: not-allowed; }
  /* The text "+ in den Warenkorb" link is desktop-only — hidden on mobile,
     replaced by the compact icon button above. */
  .panel__actions > .panel__cart-link { display: none; }

  /* The standalone story-tab button is redundant on mobile: tapping the
     panel chip already opens the story along with the panel. Hide it. */
  .panel__story-btn { display: none !important; }

  /* Heart button — top-right of the floating pill (collapsed only). */
  .panel__wish {
    top: 6px; right: 8px; z-index: 4;
    width: 28px; height: 28px;
    background: rgba(255, 255, 255, 0.55);
    border-color: rgba(255, 255, 255, 0.65);
  }
  .panel[data-expanded="true"] .panel__wish {
    top: 10px; right: 10px;
    width: 32px; height: 32px;
  }

  /* Decorative flower hidden on mobile — too busy for compact pill. */
  .panel__flower { display: none; }

  /* Tighter type on mobile so info fits without too much scrolling.
     Colors deliberately near-black (#0e0e0e) so they're unmistakably
     readable on the now near-opaque glass background. */
  .panel__name { font-size: 26px; line-height: 1.15; margin: 2px 0; color: #0e0e0e; }
  .panel__desc { font-size: 14px; line-height: 1.55; color: #2a2a2a; }
  .panel__season { font-size: 10px; letter-spacing: 3px; color: #4a4a4a; font-weight: 600; }
  .panel__price { font-size: 28px; color: #0e0e0e; }
  .panel__purpose { color: #4a4a4a; }
  .panel__unique-text { color: #2a2a2a; }
  .panel__unique-eyebrow { color: #8a6a2a; }            /* deeper gold for contrast */
  .panel__tab-name { color: #0e0e0e; }
  .panel__tab-meta { color: #4a4a4a; }
  .panel__row + .panel__row { margin-top: 10px; }
  .panel__row { gap: 6px; }

  /* Arrows hidden on mobile — swipe + thumbnail tap is the primary nav. */
  .card__nav { display: none; }

  /* Compact glass thumbnail pill in the bottom-LEFT corner, ALWAYS above
     the panel. `--panel-h` is published by attachPanelHeightTracker() in
     app.js and reflects the panel's REAL height (including safe-area
     padding), so the strip never overlaps the buy button regardless of
     device, expanded state, or browser chrome. */
  .card__thumbs {
    bottom: calc(max(2px, env(safe-area-inset-bottom)) + var(--panel-h, 100px) + 60px);
    left: 6px;
    right: auto;
    padding: 4px;
    gap: 4px;
    max-width: calc(100vw - 12px);
    background: rgba(255, 255, 255, 0.55);
    border: 1px solid rgba(255, 255, 255, 0.65);
    transition: opacity 220ms var(--ease), transform 220ms var(--ease), bottom 200ms var(--ease);
  }
  .card__thumb { width: 40px; height: 40px; border-radius: 7px; }
  .card__thumb-badge { font-size: 7px; padding: 1px 3px; bottom: 1px; right: 1px; }
  /* Hide thumbs when the panel is expanded — user is reading details. */
  .card:has(.panel[data-expanded="true"]) .card__thumbs {
    opacity: 0;
    transform: translateY(20px);
    pointer-events: none;
  }

  .footer__glass {
    grid-template-columns: 1fr 1fr;
    gap: 32px;
    padding: 32px;
  }
}

@media (max-width: 560px) {
  .footer__glass {
    grid-template-columns: 1fr;
    /* Tighter padding so the footer doesn't burn 64 px of viewport
       width on chrome alone — was 32 px on each side. */
    padding: 24px 18px;
    gap: 22px;
  }
  /* Newsletter on small screens — stack the title above and let the
     form occupy the full width with input on top, button below.  This
     kills the "Anmelden" button overflowing past the right edge that
     the user reported. */
  .footer__newsletter {
    margin-top: 8px;
    padding-top: 20px;
    gap: 10px;
  }
  .footer__newsletter-title { font-size: 15px; line-height: 1.45; }
  .footer__newsletter-form {
    flex-direction: column;
    width: 100%;
    gap: 10px;
  }
  .footer__newsletter-form input,
  .footer__newsletter-form button {
    width: 100%;
    height: 46px;
  }
  /* Flower images now removed from HTML — no flower-rule needed. */
  .panel__flower { height: 56px; top: -20px; right: -10px; }
  /* Compact season menu — labels collapse to single icons so all four
     pills still fit on a 360 px phone between the logo and the icon
     cluster. aria-label / title on each <button> preserves discoverability
     (long-press shows the German name). */
  .nav__inner { gap: 4px; }
  .nav__seasons {
    gap: 2px;
    padding: 0 4px;
  }
  .nav__season {
    padding: 8px 6px;
    min-width: 30px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }
  .nav__season-icon { display: inline-flex; align-items: center; }
  .nav__season-label { display: none; }
  /* The big-logo column shrinks so the seasons + icons can coexist.
     Doubled from 60 → 120 px on smallest phones, still clamped by 45 vw. */
  .nav__brand__logo { height: 120px; max-width: min(280px, 45vw); }
  /* On the smallest phones the "Sur Mesure" text label is too long.
     Collapse to icon-only — the sparkle alone conveys "special" enough,
     aria-label keeps it discoverable for screen readers. */
  .nav__bespoke {
    padding: 8px;
    min-width: 32px;
    min-height: 32px;
    border-radius: 999px;
  }
  .nav__bespoke-text { display: none; }
  .nav__bespoke-icon { color: #2a1d09; }
  .toast-stack { top: 80px; right: 12px; }
}

/* =========================================================
   Overlays — modal + drawer + cookie banner all share this
   ========================================================= */
.overlay {
  position: fixed;
  inset: 0;
  background: rgba(22, 22, 22, 0.35);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  opacity: 0;
  transition: opacity 280ms var(--ease);
  pointer-events: none;
  z-index: 100;
}
.overlay[data-open="true"] {
  opacity: 1;
  pointer-events: auto;
}

/* Generic glass modal centered on screen */
.modal {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -46%);
  width: min(720px, calc(100vw - 32px));
  max-height: calc(100vh - 64px);
  overflow: auto;
  /* Scrollbar lives INSIDE the rounded frame — thin, soft, with top/bottom
     margin matching the corner radius so the thumb never punches through. */
  scrollbar-width: thin;
  scrollbar-color: rgba(22, 22, 22, 0.28) transparent;
  /* Solid white fallback + glass overlay.  The `background-color` is the
     fallback when the browser doesn't support backdrop-filter (or when
     a parent's stacking context disables it) — without this the user
     sees a near-transparent panel and can't read the form against the
     storefront photos behind.  The linear-gradient still gives the
     subtle top-left lighter / bottom-right darker glass-pane shading. */
  background-color: #ffffff;
  background-image:
    linear-gradient(135deg,
      rgba(255, 255, 255, 0.96) 0%,
      rgba(255, 255, 255, 0.92) 100%);
  -webkit-backdrop-filter: blur(40px) saturate(180%);
  backdrop-filter: blur(40px) saturate(180%);
  border: 1px solid rgba(255, 255, 255, 0.55);
  border-radius: 24px;
  box-shadow:
    0 28px 70px -20px rgba(0, 0, 0, 0.4),
    inset 0 1px 0 rgba(255, 255, 255, 0.7),
    inset 0 -1px 0 rgba(0, 0, 0, 0.04);
  z-index: 200;            /* above mobile-menu (z=110) so opening from drawer always sits on top */
  opacity: 0;
  transition: opacity 320ms var(--ease), transform 320ms var(--ease);
  pointer-events: none;
}
.modal::-webkit-scrollbar { width: 10px; }
.modal::-webkit-scrollbar-track {
  background: transparent;
  margin: 24px 0; /* respect border-radius — scrollbar stops short of corners */
}
.modal::-webkit-scrollbar-thumb {
  background: rgba(22, 22, 22, 0.28);
  border-radius: 999px;
  border: 3px solid transparent;
  background-clip: padding-box;
  min-height: 40px;
}
.modal::-webkit-scrollbar-thumb:hover {
  background: rgba(22, 22, 22, 0.5);
  background-clip: padding-box;
}
.modal[data-open="true"] {
  opacity: 1;
  transform: translate(-50%, -50%);
  pointer-events: auto;
}
/* Override the global muted grey inside modals — the default #8a8a8a
   washes out against the modal's translucent glass background. Form
   labels, totals labels, edition meta, secure-note all read clearly
   on top of the new modal material. */
.modal {
  --color-muted: #4a4a4a;
}
.modal .field input,
.modal .field select,
.modal .field textarea {
  background: rgba(255, 255, 255, 0.7);
  border-color: rgba(22, 22, 22, 0.15);
}
.modal__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 22px 28px 0;
}
.modal__title {
  font-family: var(--font-serif);
  font-size: 28px;
  font-weight: 600;
  letter-spacing: 0.5px;
  margin: 0;
}
/* Logo replaces the text title in the order + success modals — a real
   brand mark instead of plain "La Tasi" wordmark. */
.modal__title-logo {
  height: 38px;
  width: auto;
  max-width: 160px;
  display: block;
  object-fit: contain;
}

/* Accepted-payment-methods badge row, sits right below the "Bezahlen"
   button. Pure visual reassurance — actual method availability is
   driven by Stripe + the dashboard. */
.checkout-methods {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
  justify-content: center;
  margin: 12px 0 4px;
}
.checkout-methods__badge {
  /* These are now real brand SVGs with their own background + colour,
     served as <img>. We only need to constrain size and add a soft
     drop-shadow so the row looks like a unified card lineup. */
  height: 24px;
  width: auto;
  display: inline-block;
  border-radius: 4px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08), 0 0 0 1px rgba(0, 0, 0, 0.04);
  background: transparent;
  vertical-align: middle;
}
@media (max-width: 560px) {
  .checkout-methods { gap: 6px; }
  .checkout-methods__badge { height: 20px; }
}
.modal__close {
  width: 36px; height: 36px;
  border-radius: 999px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: background 200ms var(--ease);
}
.modal__close:hover { background: rgba(22, 22, 22, 0.06); }
.modal__body { padding: 18px 28px 28px; }

/* Cart drawer slides from right */
.drawer {
  position: fixed;
  top: 18px;
  right: 18px;
  bottom: 18px;
  width: min(440px, calc(100vw - 36px));
  border-radius: 22px;
  /* Modern glassmorphism — floating card with margin from edges. */
  background:
    linear-gradient(135deg,
      rgba(255, 255, 255, 0.62) 0%,
      rgba(255, 255, 255, 0.4) 100%);
  -webkit-backdrop-filter: blur(40px) saturate(180%);
  backdrop-filter: blur(40px) saturate(180%);
  border: 1px solid rgba(255, 255, 255, 0.55);
  box-shadow:
    0 24px 60px -16px rgba(0, 0, 0, 0.35),
    inset 0 1px 0 rgba(255, 255, 255, 0.65),
    inset 1px 0 0 rgba(255, 255, 255, 0.4);
  z-index: 110;
  transform: translateX(calc(100% + 32px));
  transition: transform 380ms var(--ease);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
@media (max-width: 560px) {
  .drawer {
    top: 12px;
    right: 12px;
    bottom: 12px;
    width: calc(100vw - 24px);
    border-radius: 18px;
  }
}
.drawer[data-open="true"] { transform: translateX(0); }
.drawer__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 22px 24px;
  border-bottom: 1px solid var(--color-line);
}
.drawer__body { flex: 1; overflow-y: auto; padding: 16px 24px; }
.drawer__footer { padding: 20px 24px; border-top: 1px solid var(--color-line); }

/* Cart item */
.cart-item {
  display: grid;
  grid-template-columns: 64px 1fr auto;
  gap: 14px;
  padding: 12px 0;
  border-bottom: 1px solid var(--color-line);
  align-items: center;
}
.cart-item:last-child { border-bottom: none; }
.cart-item__thumb {
  width: 64px;
  height: 64px;
  border-radius: 10px;
  /* `contain` so the whole composition fits — `cover` was cropping the
     top/bottom of the vase + flowers. Background-color shows around the
     edges as a soft cream mat. */
  background-size: contain;
  background-position: center;
  background-repeat: no-repeat;
  background-color: #fdfaf3;
}
.cart-item__name {
  font-family: var(--font-serif);
  font-size: 18px;
  line-height: 1.1;
}
.cart-item__meta {
  font-size: 11px;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: #4a4a4a;                  /* darker — was #8a8a8a, lost on glass bg */
  margin-top: 4px;
}
.cart-item__qty { display: inline-flex; align-items: center; gap: 8px; margin-top: 6px; }
.cart-item__qty button {
  width: 22px; height: 22px;
  border-radius: 999px;
  background: rgba(22, 22, 22, 0.06);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
}
.cart-item__qty button[disabled] { opacity: 0.3; cursor: not-allowed; }
.cart-item__price { font-family: var(--font-serif); font-size: 17px; }
.cart-item__right {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 8px;
}
/* Trash icon — replaces the old "Entfernen" text link. */
.cart-item__remove {
  width: 30px;
  height: 30px;
  border-radius: 999px;
  border: none;
  background: rgba(22, 22, 22, 0.05);
  color: var(--color-muted);
  cursor: pointer;
  display: grid;
  place-items: center;
  transition: background 200ms var(--ease), color 200ms var(--ease), transform 200ms var(--ease);
}
.cart-item__remove:hover {
  background: rgba(193, 74, 58, 0.12);
  color: #c14a3a;
  transform: translateY(-1px);
}

.cart-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  height: 100%;
  font-family: var(--font-serif);
  font-style: italic;
  color: var(--color-muted);
  font-size: 18px;
}

.cart-total { display: flex; justify-content: space-between; align-items: baseline; }
.cart-total__label { font-size: 11px; letter-spacing: 3px; text-transform: uppercase; color: var(--color-muted); }
.cart-total__value { font-family: var(--font-serif); font-size: 26px; }

/* Cart summary box — subtotal, shipping, grand total stacked, glass card. */
.cart-summary {
  background: rgba(255, 255, 255, 0.35);
  -webkit-backdrop-filter: blur(20px) saturate(160%);
  backdrop-filter: blur(20px) saturate(160%);
  border: 1px solid rgba(255, 255, 255, 0.45);
  border-radius: 14px;
  padding: 14px 16px;
  margin-bottom: 14px;
}
.cart-summary__row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  padding: 4px 0;
  font-size: 13px;
  letter-spacing: 0.5px;
}
.cart-summary__row > :first-child {
  font-size: 11px;
  letter-spacing: 2px;
  text-transform: uppercase;
  color: #4a4a4a;                  /* darker for legibility on glass */
}
.cart-summary__row--total {
  margin-top: 8px;
  padding-top: 10px;
  border-top: 1px solid rgba(22, 22, 22, 0.1);
  position: relative;
}
/* Same MwSt. notice as the checkout total (German PAngV requirement). */
.cart-summary__row--total::after {
  content: "inkl. 19 % MwSt.";
  position: absolute;
  right: 0;
  top: 100%;
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.3px;
  color: var(--color-muted, #8a8a8a);
  margin-top: 4px;
  pointer-events: none;
}
.cart-summary__row--total > :first-child {
  color: var(--color-text);
  font-size: 12px;
}
.cart-summary__row--total > :last-child {
  font-family: var(--font-serif);
  font-size: 24px;
  font-weight: 500;
}

/* =========================================================
   Forms
   ========================================================= */
.form {
  display: grid;
  gap: 12px;
}
.form-row { display: grid; gap: 12px; grid-template-columns: 1fr 2fr; }
.field {
  display: block;
  position: relative;
}
.field > label {
  display: block;
  font-size: 10px;
  letter-spacing: 2px;
  text-transform: uppercase;
  color: var(--color-muted);
  margin-bottom: 4px;
}
.field input, .field select {
  width: 100%;
  height: 44px;
  padding: 0 14px;
  border-radius: 12px;
  border: 1px solid rgba(22, 22, 22, 0.15);
  background: rgba(255, 255, 255, 0.5);
  font: inherit;
  color: var(--color-text);
  transition: border 200ms var(--ease), background 200ms var(--ease);
}
.field input:focus, .field select:focus {
  outline: none;
  border-color: var(--color-accent);
  background: rgba(255, 255, 255, 0.85);
}
.field--error input, .field--error select {
  border-color: #c14a3a;
  background: rgba(193, 74, 58, 0.05);
}
.field__error {
  font-size: 11px;
  color: #c14a3a;
  margin-top: 4px;
  min-height: 14px;
  display: block;
}

/* Buttons (shared) */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  padding: 16px 24px;
  border-radius: 999px;
  font-size: 12px;
  letter-spacing: 3px;
  text-transform: uppercase;
  transition: background 250ms var(--ease), transform 200ms var(--ease), color 200ms var(--ease);
  cursor: pointer;
}
.btn--primary { background: rgba(22, 22, 22, 0.92); color: #fff; }
.btn--primary:hover { background: #000; transform: translateY(-1px); }
.btn--secondary {
  background: rgba(22, 22, 22, 0.06);
  color: var(--color-text);
}
.btn--secondary:hover { background: rgba(22, 22, 22, 0.12); }
/* .btn--ghost previously defined here was DEAD CODE — overridden by the
   account-modal `.btn--ghost` at line ~3079.  Removed during audit. */
.btn[disabled] { opacity: 0.5; cursor: not-allowed; transform: none; }
.btn-row { display: grid; gap: 10px; margin-top: 4px; }

/* =========================================================
   Checkout-modal specifics
   ========================================================= */
.checkout-product {
  display: grid;
  grid-template-columns: 96px 1fr;
  gap: 16px;
  padding: 18px;
  background: rgba(255, 255, 255, 0.5);
  border-radius: 16px;
  margin-bottom: 22px;
}
.checkout-product__thumb {
  width: 96px;
  height: 96px;
  border-radius: 12px;
  background-size: contain;
  background-position: center;
  background-repeat: no-repeat;
  background-color: #fdfaf3;
}
.checkout-product__name {
  font-family: var(--font-serif);
  font-size: 24px;
  line-height: 1.1;
  margin: 0 0 4px;
}
.checkout-product__edition {
  font-size: 10px;
  letter-spacing: 2px;
  text-transform: uppercase;
  color: var(--color-muted);
}
.checkout-product__price {
  font-family: var(--font-serif);
  font-size: 20px;
  margin-top: 8px;
}
.checkout-qty { display: inline-flex; align-items: center; gap: 12px; margin-top: 10px; }
.checkout-qty button {
  width: 28px; height: 28px;
  border-radius: 999px;
  background: rgba(22, 22, 22, 0.06);
}
.checkout-qty button[disabled] { opacity: 0.3; cursor: not-allowed; }

/* ===== BESPOKE / SUR MESURE MODAL =====
   Concierge-style form for one-off personal orders. Larger and more
   spacious than the standard checkout modal; serif type carries
   the "haute couture" weight. Atmospheric: a soft golden glow on the
   right side gives the whole modal a candle-lit feel. */
#bespoke-modal {
  position: relative;
  overflow: hidden;
}
#bespoke-modal::before {
  /* Translucent golden glow in the upper-right corner — purely
     atmospheric, sits behind the content (z-index: 0). */
  content: '';
  position: absolute;
  top: -120px;
  right: -120px;
  width: 460px;
  height: 460px;
  background: radial-gradient(circle,
    rgba(244, 224, 179, 0.55) 0%,
    rgba(212, 171, 104, 0.30) 40%,
    rgba(212, 171, 104, 0) 70%);
  pointer-events: none;
  z-index: 0;
  filter: blur(8px);
}
#bespoke-modal::after {
  /* Secondary, smaller glow on the bottom-left for visual balance */
  content: '';
  position: absolute;
  bottom: -100px;
  left: -100px;
  width: 320px;
  height: 320px;
  background: radial-gradient(circle,
    rgba(244, 224, 179, 0.28) 0%,
    rgba(212, 171, 104, 0) 70%);
  pointer-events: none;
  z-index: 0;
  filter: blur(6px);
}
#bespoke-modal > * { position: relative; z-index: 1; }
.bespoke-body { padding: 18px 36px 36px; }
/* Force every form input/textarea inside the bespoke form to span the
   container — fixes the textarea appearing narrow in the middle of an
   empty space. */
.bespoke-body .field input,
.bespoke-body .field select,
.bespoke-body .field textarea {
  width: 100%;
  display: block;
  box-sizing: border-box;
}
.bespoke-eyebrow {
  margin: 0 0 6px;
  font-size: 11px;
  letter-spacing: 4px;
  text-transform: uppercase;
  color: #b58e4c;
  font-weight: 600;
}
.bespoke-title {
  margin: 0 0 10px;
  font-family: var(--font-serif);
  font-weight: 500;
  font-size: 32px;
  line-height: 1.15;
  color: var(--color-text);
  letter-spacing: 0.5px;
}
.bespoke-intro {
  margin: 0 0 24px;
  font-family: var(--font-serif);
  font-style: italic;
  font-size: 16px;
  line-height: 1.6;
  color: #3a3a3a;
}

/* Self vs Gift — two cards centered, equal width, with a comfortable
   gap. Limited max-width keeps them readable and centered even in a
   wide modal. */
.bespoke-purpose {
  border: none;
  padding: 0;
  margin: 0 auto 22px;
  display: flex;
  gap: 18px;
  justify-content: center;
  flex-wrap: wrap;
}
.bespoke-purpose legend {
  font-size: 11px;
  letter-spacing: 3px;
  text-transform: uppercase;
  color: var(--color-muted);
  margin: 0 0 14px;
  font-weight: 600;
  width: 100%;
  text-align: center;
}
.bespoke-purpose__option {
  flex: 1 1 240px;
  max-width: 280px;
  cursor: pointer;
}
.bespoke-purpose__option { cursor: pointer; }
.bespoke-purpose__option input[type="radio"] {
  position: absolute;
  opacity: 0;
  width: 0; height: 0;
}
.bespoke-purpose__card {
  display: flex;
  flex-direction: column;
  gap: 6px;
  align-items: flex-start;
  padding: 18px 18px 16px;
  background: #fdfaf3;
  border: 1px solid #ece6d6;
  border-radius: 14px;
  color: var(--color-text);
  transition: all 220ms var(--ease);
}
.bespoke-purpose__card svg { color: #b58e4c; margin-bottom: 4px; }
.bespoke-purpose__card strong {
  font-family: var(--font-serif);
  font-size: 17px;
  font-weight: 500;
}
.bespoke-purpose__card span {
  font-size: 11px;
  color: var(--color-muted);
  letter-spacing: 0.4px;
  line-height: 1.5;
}
.bespoke-purpose__option input[type="radio"]:checked + .bespoke-purpose__card {
  background: linear-gradient(135deg, #f4e0b3 0%, #ecd1a0 100%);
  border-color: #d4ab68;
  box-shadow: 0 8px 20px -8px rgba(180, 140, 74, 0.35);
}
.bespoke-purpose__option input[type="radio"]:checked + .bespoke-purpose__card span {
  color: #6b5430;
}

.bespoke-gift-fields {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
  margin: 0 0 14px;
  padding: 14px 14px 6px;
  background: rgba(201, 184, 155, 0.12);
  border-radius: 12px;
  border: 1px dashed rgba(180, 140, 74, 0.3);
}

.bespoke-description label {
  font-family: var(--font-serif);
  font-size: 14px;
  font-weight: 500;
  color: var(--color-text);
  letter-spacing: 0.3px;
}
.bespoke-description textarea {
  font-family: var(--font-serif);
  font-style: italic;
  font-size: 15px;
  line-height: 1.6;
  padding: 16px;
  min-height: 140px;
  background: #fdfaf3;
  border: 1px solid #ece6d6;
  border-radius: 12px;
  resize: vertical;
}
.bespoke-description textarea:focus {
  outline: none;
  border-color: #d4ab68;
  box-shadow: 0 0 0 3px rgba(212, 171, 104, 0.15);
}

.bespoke-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
  margin: 0 0 14px;
}

.bespoke-submit {
  width: 100%;
  margin-top: 8px;
  padding: 16px 28px;
  font-size: 12px;
  letter-spacing: 3px;
}
.bespoke-promise {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  margin: 12px 0 0;
  font-size: 11px;
  color: var(--color-muted);
  letter-spacing: 0.4px;
}

.bespoke-success {
  text-align: center;
  padding: 12px 0;
}
.bespoke-success__seal {
  width: 72px;
  height: 72px;
  border-radius: 50%;
  background: linear-gradient(135deg, #f4e0b3 0%, #d4ab68 100%);
  color: #1c1306;
  display: grid;
  place-items: center;
  margin: 0 auto 22px;
  box-shadow: 0 10px 30px -10px rgba(180, 140, 74, 0.5);
}

@media (max-width: 560px) {
  .bespoke-body { padding: 14px 18px 28px; }
  .bespoke-title { font-size: 26px; }
  .bespoke-purpose { grid-template-columns: 1fr; }
  .bespoke-gift-fields { grid-template-columns: 1fr; }
  .bespoke-row { grid-template-columns: 1fr; }
}

/* "oder" divider between password-login and magic-link login in the
   account modal. Single horizontal rule with the word floating in the
   middle on a small inset background. */
.auth-divider {
  position: relative;
  text-align: center;
  margin: 18px 0 10px;
  color: var(--color-muted);
  font-size: 10px;
  letter-spacing: 3px;
  text-transform: uppercase;
}
.auth-divider::before {
  content: '';
  position: absolute;
  left: 0; right: 0; top: 50%;
  border-top: 1px solid #ece6d6;
}
.auth-divider span {
  position: relative;
  background: #fff;
  padding: 0 12px;
}
.btn--ghost {
  width: 100%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 11px 16px;
  background: #fff;
  border: 1px solid #d6cdb8;
  border-radius: 999px;
  color: var(--color-text);
  font-size: 11px;
  letter-spacing: 2.5px;
  text-transform: uppercase;
  font-weight: 600;
  cursor: pointer;
  transition: background 200ms var(--ease), border-color 200ms var(--ease);
}
.btn--ghost:hover { background: #fdfaf3; border-color: #c9b89b; }
.btn--magic { margin-top: 0; }
.auth-magic-hint {
  margin: 8px 0 0;
  font-size: 10px;
  color: var(--color-muted);
  letter-spacing: 0.3px;
  text-align: center;
  line-height: 1.5;
}

/* "Konto erstellen" + GDPR-marketing-consent stacks above the pay button.
   Both panels are subtle glass cards — same visual weight as the totals
   block so they don't dominate but are clearly distinct from form fields. */
.checkout-account, .checkout-consent {
  margin: 14px 0 0;
  padding: 14px 16px;
  background: rgba(253, 250, 243, 0.7);
  border: 1px solid #ece6d6;
  border-radius: 12px;
}
.checkout-account__row, .checkout-consent__row {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  font-size: 13px;
  line-height: 1.5;
  cursor: pointer;
  padding: 4px 0;
}
.checkout-account__row input[type="checkbox"],
.checkout-consent__row input[type="checkbox"] {
  width: 18px; height: 18px;
  margin: 2px 0 0;
  accent-color: var(--color-text);
  flex-shrink: 0;
}
.checkout-account__row span,
.checkout-consent__row span { flex: 1 1 auto; }
.checkout-account__row strong { display: block; font-weight: 600; color: var(--color-text); }
.checkout-account__hint {
  display: block; font-size: 11px; color: var(--color-muted);
  letter-spacing: 0.3px; margin-top: 1px;
}
.checkout-account__pw { margin-top: 12px; padding-top: 12px; border-top: 1px solid #ece6d6; }
.checkout-account__pw .pw-field { position: relative; }
.checkout-account__pw .pw-field input { padding-right: 38px; }
.checkout-account__pw .pw-toggle {
  position: absolute; right: 6px; top: 50%; transform: translateY(-50%);
  width: 30px; height: 30px; display: grid; place-items: center;
  border: none; background: transparent; cursor: pointer; color: var(--color-muted);
}
.checkout-account__pw .pw-toggle:hover { color: var(--color-text); }
.checkout-consent__title {
  margin: 0 0 4px; font-size: 13px; font-weight: 600; color: var(--color-text);
}
.checkout-consent__sub {
  margin: 0 0 10px; font-size: 11px; color: var(--color-muted); line-height: 1.5;
}
.checkout-consent__legal {
  margin: 8px 0 0; font-size: 10px; color: #b5a78d; line-height: 1.45; letter-spacing: 0.2px;
}

/* ===== PRIVATER KREIS — quiet marketing consent =====
   Replaces the previous gold-banner VIP card which looked too much like
   a coupon advert. New version: small italic-serif headline + one line
   of explanation + a single checkbox on the left. Subtle gold border,
   no gradient fill — reads like a personal request from the atelier. */
.checkout-circle {
  display: flex;
  gap: 14px;
  align-items: flex-start;
  margin: 14px 0;
  padding: 14px 16px;
  background: rgba(253, 250, 243, 0.6);
  border: 1px solid rgba(212, 171, 104, 0.32);
  border-radius: 12px;
  cursor: pointer;
  transition: background 220ms var(--ease), border-color 220ms var(--ease);
}
.checkout-circle:hover {
  background: rgba(253, 250, 243, 0.85);
  border-color: rgba(212, 171, 104, 0.55);
}
.checkout-circle__input { position: absolute; opacity: 0; width: 0; height: 0; }
.checkout-circle__check {
  flex-shrink: 0;
  width: 20px; height: 20px;
  margin-top: 2px;
  border-radius: 5px;
  border: 1.5px solid #b58e4c;
  background: #fff;
  position: relative;
  transition: background 220ms var(--ease);
}
.checkout-circle__check::after {
  content: '';
  position: absolute;
  left: 5px; top: 1px;
  width: 6px; height: 11px;
  border: solid #fff;
  border-width: 0 2px 2px 0;
  transform: rotate(45deg) scale(0);
  transition: transform 220ms var(--ease);
}
.checkout-circle__input:checked ~ .checkout-circle__check {
  background: #b58e4c;
}
.checkout-circle__input:checked ~ .checkout-circle__check::after {
  transform: rotate(45deg) scale(1);
}
.checkout-circle__body {
  flex: 1 1 auto;
}
.checkout-circle__title {
  display: block;
  font-family: var(--font-serif);
  font-style: italic;
  font-size: 16px;
  font-weight: 500;
  color: #1c1306;
  line-height: 1.25;
  margin-bottom: 4px;
  letter-spacing: 0.3px;
}
.checkout-circle__text {
  display: block;
  font-size: 12px;
  line-height: 1.55;
  color: #4a4a4a;
  letter-spacing: 0.1px;
}

/* ===== OLD VIP CARD (kept for legacy) ===== */
.checkout-vip {
  display: block;
  margin: 18px 0 14px;
  padding: 22px 24px 20px;
  border-radius: 16px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  background:
    linear-gradient(135deg, #fff9ec 0%, #fbf2dc 60%, #f4e0b3 100%);
  border: 1.5px solid rgba(212, 171, 104, 0.4);
  box-shadow:
    0 14px 32px -16px rgba(180, 140, 74, 0.4),
    inset 0 1px 0 rgba(255, 255, 255, 0.65);
  transition: all 280ms var(--ease);
}
.checkout-vip:hover {
  transform: translateY(-2px);
  border-color: rgba(212, 171, 104, 0.7);
  box-shadow:
    0 20px 40px -16px rgba(180, 140, 74, 0.55),
    inset 0 1px 0 rgba(255, 255, 255, 0.85);
}
/* Subtle radial shimmer in the corner — small but adds the "specialness" */
.checkout-vip::before {
  content: '';
  position: absolute;
  top: -40px; right: -40px;
  width: 140px; height: 140px;
  background: radial-gradient(circle, rgba(255, 255, 255, 0.6) 0%, transparent 70%);
  pointer-events: none;
}
.checkout-vip__input { position: absolute; opacity: 0; width: 0; height: 0; }
.checkout-vip__sparkle {
  position: absolute;
  top: 18px;
  right: 22px;
  color: #b58e4c;
  opacity: 0.85;
  transition: transform 600ms var(--ease);
}
.checkout-vip:hover .checkout-vip__sparkle { transform: rotate(25deg) scale(1.08); }
.checkout-vip__body {
  position: relative;
  display: block;
}
.checkout-vip__eyebrow {
  display: block;
  font-size: 10px;
  letter-spacing: 4px;
  text-transform: uppercase;
  font-weight: 700;
  color: #7a5c1f;
  margin-bottom: 6px;
}
.checkout-vip__title {
  display: block;
  font-family: var(--font-serif);
  font-style: italic;
  font-size: 22px;
  line-height: 1.2;
  font-weight: 500;
  color: #1c1306;
  margin-bottom: 14px;
  letter-spacing: 0.3px;
  max-width: 80%;     /* leave room for the sparkle */
}
.checkout-vip__perks {
  list-style: none;
  padding: 0;
  margin: 0 0 16px;
  display: grid;
  gap: 7px;
}
.checkout-vip__perks li {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  color: #3a2a0e;
  line-height: 1.5;
}
.checkout-vip__perks svg { color: #b58e4c; flex-shrink: 0; }
.checkout-vip__cta {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 10px 18px;
  border-radius: 999px;
  background: #fff;
  border: 1.5px solid rgba(180, 140, 74, 0.45);
  font-size: 12px;
  letter-spacing: 2.5px;
  text-transform: uppercase;
  font-weight: 600;
  color: #1c1306;
  transition: all 220ms var(--ease);
}
.checkout-vip__check {
  width: 18px; height: 18px;
  border-radius: 6px;
  border: 1.5px solid #b58e4c;
  background: #fff;
  position: relative;
  transition: all 220ms var(--ease);
}
.checkout-vip__check::after {
  content: '';
  position: absolute;
  left: 4px; top: 0px;
  width: 6px; height: 11px;
  border: solid #fff;
  border-width: 0 2px 2px 0;
  transform: rotate(45deg) scale(0);
  transition: transform 220ms var(--ease);
}
.checkout-vip__input:checked ~ .checkout-vip__body .checkout-vip__cta {
  background: linear-gradient(135deg, #f4e0b3, #d4ab68);
  border-color: #b58e4c;
  color: #1c1306;
  box-shadow: 0 6px 16px -6px rgba(180, 140, 74, 0.6);
}
.checkout-vip__input:checked ~ .checkout-vip__body .checkout-vip__check {
  background: #b58e4c;
  border-color: #b58e4c;
}
.checkout-vip__input:checked ~ .checkout-vip__body .checkout-vip__check::after {
  transform: rotate(45deg) scale(1);
}
.checkout-vip__input:focus-visible ~ .checkout-vip__body .checkout-vip__cta {
  outline: 2px solid #d4ab68;
  outline-offset: 3px;
}

/* ===== AGB ACCEPTANCE — required legal check =====
   Minimal styling, clearly distinct from the VIP block. Inline links
   open the legal modal (impressum/datenschutz/agb/widerruf). */
.checkout-agb {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  margin: 4px 0 18px;
  padding: 10px 4px;
  cursor: pointer;
  font-size: 12px;
  color: #4a4a4a;
  line-height: 1.55;
}
.checkout-agb input[type="checkbox"] {
  width: 18px; height: 18px;
  margin: 2px 0 0;
  accent-color: var(--color-text);
  flex-shrink: 0;
  cursor: pointer;
}
.checkout-agb__text { flex: 1 1 auto; }
.checkout-agb__text a {
  color: #6b5430;
  text-decoration: underline;
  text-decoration-color: rgba(180, 140, 74, 0.4);
  text-underline-offset: 2px;
}
.checkout-agb__text a:hover { color: #b58e4c; text-decoration-color: #b58e4c; }
.checkout-agb .field__error {
  display: block;
  margin-top: 4px;
  color: #c14a3a;
  font-size: 11px;
}

@media (max-width: 560px) {
  .checkout-vip { padding: 18px 18px 16px; }
  .checkout-vip__title { font-size: 19px; max-width: 75%; }
  .checkout-vip__perks li { font-size: 12px; }
}

.checkout-divider {
  height: 1px;
  background: var(--color-line);
  margin: 18px 0;
}
.checkout-totals { display: grid; gap: 6px; margin-bottom: 18px; }
.checkout-totals__row { display: flex; justify-content: space-between; font-size: 13px; }
.checkout-totals__row--discount { color: #2f5f37; font-weight: 500; }
.checkout-totals__row--total {
  font-family: var(--font-serif);
  font-size: 22px;
  margin-top: 6px;
  /* Stack the legal MwSt. notice below the total amount.  Cleaner
     than inline because the total row is right-aligned. */
  position: relative;
}
.checkout-totals__row--total::after {
  content: "Alle Preise inkl. 19 % MwSt. zzgl. Versand";
  position: absolute;
  right: 0;
  top: 100%;
  font-family: var(--font-sans);
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.3px;
  color: var(--color-muted, #8a8a8a);
  margin-top: 2px;
  pointer-events: none;
}

/* Gift-wrap section — premium glass card with templates, counter, preview. */
.checkout-gift {
  background:
    linear-gradient(135deg,
      rgba(201, 184, 155, 0.22) 0%,
      rgba(201, 184, 155, 0.10) 100%);
  -webkit-backdrop-filter: blur(20px) saturate(140%);
  backdrop-filter: blur(20px) saturate(140%);
  border: 1px solid rgba(201, 184, 155, 0.45);
  border-radius: 16px;
  padding: 14px 16px;
  margin-bottom: 14px;
  box-shadow:
    0 8px 22px -10px rgba(133, 96, 38, 0.25),
    inset 0 1px 0 rgba(255, 255, 255, 0.6);
}
.checkout-gift__toggle {
  display: flex;
  align-items: center;
  gap: 12px;
  cursor: pointer;
  user-select: none;
}
.checkout-gift__toggle input[type="checkbox"] {
  width: 18px; height: 18px;
  accent-color: #6b5430;
  margin: 0;
  flex-shrink: 0;
  cursor: pointer;
}
.checkout-gift__icon {
  color: #6b5430;
  flex-shrink: 0;
  display: grid;
  place-items: center;
}
.checkout-gift__label {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.checkout-gift__label strong {
  font-size: 13px;
  letter-spacing: 0.5px;
  color: var(--color-text);
}
.checkout-gift__sub {
  font-size: 11px;
  color: var(--color-muted);
  letter-spacing: 0.3px;
}
.checkout-gift__fields {
  display: grid;
  gap: 10px;
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px dashed rgba(201, 184, 155, 0.5);
}
.checkout-gift__fields textarea {
  /* Tall enough that the scrollbar almost never appears, and when it
     does it's styled to blend with the cream paper of the surrounding
     gift card. Resize disabled — fixed look. */
  resize: none;
  min-height: 130px;
  font-family: var(--font-serif);
  font-style: italic;
  font-size: 14.5px;
  line-height: 1.6;
  padding: 14px 16px;
  background: rgba(255, 252, 245, 0.85) !important;
  border: 1px solid rgba(201, 184, 155, 0.4) !important;
  border-radius: 12px !important;
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  color: #2c2c2c;
  /* Subtle scrollbar — Firefox + WebKit syntax. Matches the paper tone
     of the field so it doesn't read as a separate element. */
  scrollbar-width: thin;
  scrollbar-color: rgba(180, 140, 74, 0.4) transparent;
}
.checkout-gift__fields textarea::-webkit-scrollbar { width: 6px; }
.checkout-gift__fields textarea::-webkit-scrollbar-track { background: transparent; }
.checkout-gift__fields textarea::-webkit-scrollbar-thumb {
  background: rgba(180, 140, 74, 0.35);
  border-radius: 999px;
}
.checkout-gift__fields textarea::-webkit-scrollbar-thumb:hover { background: rgba(180, 140, 74, 0.55); }
.checkout-gift__fields textarea:focus {
  border-color: rgba(180, 140, 74, 0.6) !important;
  outline: none;
  box-shadow: 0 0 0 3px rgba(212, 171, 104, 0.12);
}

/* Explanation line above the templates — clarifies the message becomes
   a hand-written card. Sits as a small gold-bordered note. */
.gift-message-explain {
  margin: 4px 0 12px;
  padding: 10px 12px;
  background: rgba(244, 224, 179, 0.18);
  border-left: 2px solid rgba(212, 171, 104, 0.55);
  border-radius: 6px;
  font-family: var(--font-serif);
  font-style: italic;
  font-size: 13px;
  line-height: 1.55;
  color: #4a3920;
}
.gift-message-explain svg { color: #b58e4c; }

/* Quick-pick template chips — line icons in gold, no emoji.
   Refined, gallery-tag look. */
.gift-templates {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 6px;
}
.gift-templates__chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 7px 13px;
  border-radius: 999px;
  border: 1px solid rgba(201, 184, 155, 0.55);
  background: rgba(255, 255, 255, 0.65);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  font-family: var(--font-sans);
  font-size: 11px;
  letter-spacing: 0.5px;
  color: #4a3920;
  cursor: pointer;
  transition: background 200ms var(--ease), transform 200ms var(--ease), border-color 200ms var(--ease), color 200ms var(--ease);
}
.gift-templates__chip svg { color: #b58e4c; flex-shrink: 0; }
.gift-templates__chip:hover {
  background: linear-gradient(135deg, rgba(244, 224, 179, 0.55), rgba(255, 255, 255, 0.85));
  border-color: rgba(180, 140, 74, 0.7);
  color: #1c1306;
  transform: translateY(-1px);
}
.gift-templates__chip:hover svg { color: #8a6a2a; }

/* Live character counter inside the message label */
.gift-message-field label {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
}
.gift-counter {
  font-size: 10px;
  letter-spacing: 1px;
  color: var(--color-muted);
  font-family: var(--font-sans);
  font-style: normal;
}

/* Mini preview of the handwritten gift card */
.gift-card-preview { margin-top: 4px; }
.gift-card-preview__paper {
  background:
    linear-gradient(180deg, #fdfaf3 0%, #f8f2ea 100%);
  border: 1px solid rgba(201, 184, 155, 0.5);
  border-radius: 10px;
  padding: 18px 22px;
  box-shadow:
    0 8px 20px -12px rgba(133, 96, 38, 0.3),
    inset 0 1px 0 rgba(255, 255, 255, 0.8);
  position: relative;
}
.gift-card-preview__paper::before {
  content: "";
  position: absolute;
  top: 8px; left: 8px;
  width: 10px; height: 10px;
  border-top: 1px solid rgba(201, 184, 155, 0.6);
  border-left: 1px solid rgba(201, 184, 155, 0.6);
}
.gift-card-preview__paper::after {
  content: "";
  position: absolute;
  bottom: 8px; right: 8px;
  width: 10px; height: 10px;
  border-bottom: 1px solid rgba(201, 184, 155, 0.6);
  border-right: 1px solid rgba(201, 184, 155, 0.6);
}
.gift-card-preview__text {
  font-family: 'Cormorant Garamond', Georgia, serif;
  font-style: italic;
  font-size: 16px;
  line-height: 1.6;
  color: #2c2418;
  white-space: pre-wrap;
  margin: 0 0 12px;
}
.gift-card-preview__signature {
  font-family: 'Cormorant Garamond', serif;
  font-size: 11px;
  letter-spacing: 4px;
  text-transform: uppercase;
  color: var(--color-accent);
  margin: 0;
  text-align: right;
}

/* Gold price chip next to the gift-wrap toggle label */
.checkout-gift__price {
  display: inline-block;
  margin-left: 6px;
  padding: 2px 8px;
  border-radius: 999px;
  background: linear-gradient(135deg, #e6cf9a 0%, #b58e4c 100%);
  color: #1c1306;
  font-size: 10px;
  letter-spacing: 1px;
  font-weight: 600;
  vertical-align: middle;
}

/* Gift media uploads — thumbnails grid + add button */
.gift-media {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.gift-media__list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(70px, 1fr));
  gap: 8px;
}
.gift-media__list:empty { display: none; }
.gift-media__item {
  position: relative;
  aspect-ratio: 1 / 1;
  border-radius: 10px;
  overflow: hidden;
  border: 1px solid rgba(201, 184, 155, 0.45);
  background: #f8f2ea;
}
.gift-media__item img,
.gift-media__item video {
  width: 100%; height: 100%; object-fit: cover; display: block;
}
.gift-media__remove {
  position: absolute;
  top: 4px; right: 4px;
  width: 22px; height: 22px;
  border-radius: 999px;
  border: none;
  background: rgba(0, 0, 0, 0.65);
  color: #fff;
  font-size: 14px;
  line-height: 1;
  cursor: pointer;
}
.gift-media__remove:hover { background: #c14a3a; }
.gift-media__add {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  align-self: flex-start;
  padding: 8px 14px;
  border-radius: 999px;
  border: 1px dashed rgba(201, 184, 155, 0.6);
  background: rgba(255, 255, 255, 0.5);
  color: #4a3920;
  font-size: 11px;
  letter-spacing: 1px;
  cursor: pointer;
  transition: background 200ms var(--ease), border-color 200ms var(--ease);
}
.gift-media__add:hover {
  background: rgba(255, 255, 255, 0.8);
  border-color: rgba(180, 140, 74, 0.7);
}
.gift-media__status {
  margin: 0;
  font-size: 11px;
  color: var(--color-muted);
  letter-spacing: 0.5px;
}

/* Coupon code input row */
.checkout-coupon {
  display: flex;
  gap: 8px;
  margin-bottom: 6px;
}
.checkout-coupon input {
  flex: 1;
  height: 40px;
  padding: 0 14px;
  border-radius: 10px;
  border: 1px solid rgba(22,22,22,0.15);
  background: rgba(255,255,255,0.5);
  font: inherit;
  font-size: 13px;
  letter-spacing: 1px;
  text-transform: uppercase;
}
.checkout-coupon input:focus {
  outline: none;
  border-color: var(--color-accent);
  background: rgba(255,255,255,0.85);
}
.checkout-coupon input[disabled] {
  background: rgba(82,142,88,0.10);
  border-color: rgba(82,142,88,0.3);
  color: #2f5f37;
  font-weight: 500;
}
.checkout-coupon__btn {
  height: 40px;
  padding: 0 18px;
  border-radius: 999px;
  background: rgba(22,22,22,0.06);
  border: none;
  font-size: 11px;
  letter-spacing: 2px;
  text-transform: uppercase;
  cursor: pointer;
  transition: background 200ms var(--ease);
}
.checkout-coupon__btn:hover { background: rgba(22,22,22,0.12); }
.checkout-coupon__btn--clear { background: rgba(193,74,58,0.1); color: #842a1f; }
.checkout-coupon__btn--clear:hover { background: rgba(193,74,58,0.2); }
.checkout-coupon__feedback {
  font-size: 12px;
  margin: 4px 0 12px;
  letter-spacing: 0.5px;
}
.checkout-secure {
  display: flex;
  align-items: center;
  gap: 8px;
  justify-content: center;
  font-size: 11px;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--color-muted);
  margin-top: 12px;
}

.checkout-success {
  text-align: center;
  padding: 36px 0 12px;
}
.checkout-success__icon {
  width: 56px; height: 56px;
  border-radius: 999px;
  background: var(--color-accent);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  margin-bottom: 16px;
}
.checkout-success__title {
  font-family: var(--font-serif);
  font-size: 28px;
  margin: 0 0 8px;
}
.checkout-success__msg {
  color: #555;
  font-size: 15px;
}

/* =========================================================
   Auth modal — tabs
   ========================================================= */
.tabs { display: flex; gap: 4px; margin-bottom: 18px; }
.tab {
  flex: 1;
  padding: 12px;
  border-radius: 999px;
  font-size: 11px;
  letter-spacing: 2.5px;
  text-transform: uppercase;
  color: var(--color-muted);
  transition: all 250ms var(--ease);
}
.tab[data-active="true"] {
  background: rgba(22, 22, 22, 0.92);
  color: #fff;
}

/* Order card with visual 4-step status tracker */
.order-card {
  padding: 16px 0;
  border-bottom: 1px solid var(--color-line);
}
.order-card:last-child { border-bottom: none; }
/* Hint line under a form input (e.g. password rules) */
.field__hint { font-size: 11px; color: #6a6a6a; margin-top: 6px; letter-spacing: 0.3px; display: block; }

/* Password field with show/hide eye toggle on the right. */
.field__pw { position: relative; }
.field__pw input {
  padding-right: 44px;             /* room for the eye button */
  width: 100%;
}
.field__pw-toggle {
  position: absolute;
  top: 50%;
  right: 6px;
  transform: translateY(-50%);
  width: 32px;
  height: 32px;
  border-radius: 999px;
  background: transparent;
  border: none;
  color: var(--color-muted);
  cursor: pointer;
  display: grid;
  place-items: center;
  transition: background 200ms var(--ease), color 200ms var(--ease);
}
.field__pw-toggle:hover { background: rgba(22, 22, 22, 0.06); color: var(--color-text); }
/* Auth-flow helpers — heading text + back button on the code screen */
.auth-hint {
  font-size: 14px;
  line-height: 1.5;
  color: #2c2c2c;
  margin: 0 0 20px;
  text-align: center;
}
.auth-hint strong { font-family: var(--font-serif); font-style: italic; font-size: 16px; }
.auth-back {
  display: block;
  margin: 14px auto 0;
  background: none;
  border: none;
  color: var(--color-muted);
  font-size: 12px;
  letter-spacing: 1px;
  cursor: pointer;
}
.auth-back:hover { color: var(--color-text); }

/* =========================================================
   Profile editor (account modal → "Profil" tab)
   ========================================================= */
.profile-form { display: flex; flex-direction: column; gap: 18px; }
.profile-form__section {
  background: rgba(255, 255, 255, 0.45);
  border: 1px solid rgba(255, 255, 255, 0.55);
  border-radius: 14px;
  padding: 16px 18px;
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
}
.profile-form__section h4 {
  font-size: 11px;
  letter-spacing: 3px;
  text-transform: uppercase;
  color: var(--color-muted);
  margin: 0 0 12px;
  font-weight: 500;
}
.profile-form__saved {
  font-size: 12px;
  color: #2f5f37;
  font-family: var(--font-serif);
  font-style: italic;
  margin: 4px 0 0;
}
.profile-form__danger {
  border-top: 1px solid rgba(193, 74, 58, 0.15);
  padding-top: 16px;
  margin-top: 6px;
}
.profile-form__danger h4 {
  font-size: 11px;
  letter-spacing: 3px;
  text-transform: uppercase;
  color: #c14a3a;
  margin: 0 0 8px;
}
.btn--danger {
  background: rgba(193, 74, 58, 0.08);
  color: #c14a3a;
  border: 1px solid rgba(193, 74, 58, 0.25);
  padding: 10px 18px;
  border-radius: 999px;
  font-size: 11px;
  letter-spacing: 2px;
  text-transform: uppercase;
  cursor: pointer;
  transition: background 200ms var(--ease);
}
.btn--danger:hover { background: rgba(193, 74, 58, 0.18); }

/* Notification preference rows — checkbox + label + hint */
.pref-row {
  display: flex;
  gap: 12px;
  padding: 10px 0;
  cursor: pointer;
  align-items: flex-start;
}
.pref-row + .pref-row { border-top: 1px solid rgba(22, 22, 22, 0.06); }
.pref-row input[type="checkbox"] {
  margin: 3px 0 0;
  width: 18px; height: 18px;
  accent-color: var(--color-text);
  cursor: pointer;
}
.pref-row__text {
  display: flex;
  flex-direction: column;
  gap: 2px;
  font-size: 13px;
}
.pref-row__text strong { font-weight: 500; }
.pref-row__text span {
  font-size: 11px;
  color: var(--color-muted);
  letter-spacing: 0.2px;
}

/* Saved-cart view in account cabinet */
.profile-cart { display: flex; flex-direction: column; gap: 10px; }
.profile-cart__row {
  display: grid;
  grid-template-columns: 60px 1fr auto;
  gap: 12px;
  align-items: center;
  padding: 10px;
  background: rgba(255, 255, 255, 0.4);
  border-radius: 12px;
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
}
.profile-cart__thumb {
  width: 60px; height: 60px;
  border-radius: 10px;
  background-size: contain;
  background-position: center;
  background-repeat: no-repeat;
  background-color: #fdfaf3;
}
.profile-cart__name { font-family: var(--font-serif); font-size: 15px; }
.profile-cart__meta { font-size: 11px; letter-spacing: 1.5px; text-transform: uppercase; color: var(--color-muted); margin-top: 3px; }
.profile-cart__price { font-family: var(--font-serif); font-size: 15px; }
.profile-cart__total {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  padding: 14px 8px 6px;
  border-top: 1px solid rgba(22, 22, 22, 0.1);
  font-size: 11px;
  letter-spacing: 2px;
  text-transform: uppercase;
  color: var(--color-muted);
}
.profile-cart__total strong {
  font-family: var(--font-serif);
  font-size: 22px;
  color: var(--color-text);
  letter-spacing: 0.5px;
  font-weight: 500;
}

.order-card__head { display: flex; justify-content: space-between; align-items: flex-start; gap: 12px; margin-bottom: 14px; }
.order-card__name { font-family: var(--font-serif); font-size: 16px; }
.order-card__meta { font-size: 11px; color: var(--color-muted); letter-spacing: 1px; margin-top: 3px; }
.order-card__gift {
  font-size: 11px;
  color: #6b5430;
  letter-spacing: 0.5px;
  margin-top: 6px;
  font-style: italic;
}
.order-card__invoice {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  flex-shrink: 0;
  padding: 6px 12px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.4);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  border: 1px solid rgba(22, 22, 22, 0.08);
  font-size: 10px;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--color-text);
  text-decoration: none;
  transition: background 200ms var(--ease), transform 200ms var(--ease);
}
.order-card__invoice:hover {
  background: rgba(255, 255, 255, 0.7);
  transform: translateY(-1px);
}

.order-stepper {
  display: flex;
  align-items: center;
  gap: 6px;
  position: relative;
}
.order-stepper__step {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  flex: 1;
  text-align: center;
}
.order-stepper__dot {
  width: 14px;
  height: 14px;
  border-radius: 999px;
  border: 2px solid rgba(22, 22, 22, 0.18);
  background: rgba(255, 255, 255, 0.6);
  transition: all 250ms var(--ease);
}
.order-stepper__step[data-done="true"] .order-stepper__dot {
  background: var(--color-accent);
  border-color: var(--color-accent);
  box-shadow: 0 0 0 4px rgba(201, 184, 155, 0.25);
}
.order-stepper__label {
  font-size: 9px;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--color-muted);
}
.order-stepper__step[data-done="true"] .order-stepper__label { color: var(--color-text); }
.order-stepper__line {
  flex: 1.2;
  height: 1px;
  background: rgba(22, 22, 22, 0.12);
  margin-top: -14px;
}
.order-stepper--cancelled .order-stepper__dot,
.order-stepper--cancelled .order-stepper__line {
  background: rgba(193, 74, 58, 0.15);
  border-color: rgba(193, 74, 58, 0.4);
  box-shadow: none;
}
.order-stepper__cancel {
  position: absolute;
  inset: 0;
  display: flex; align-items: center; justify-content: center;
  font-family: var(--font-serif);
  font-style: italic;
  color: #c14a3a;
  background: rgba(255, 255, 255, 0.85);
}

/* Wishlist items in account modal */
.wishlist-item {
  display: grid;
  grid-template-columns: 56px 1fr auto;
  gap: 14px;
  align-items: center;
  padding: 12px 0;
  border-bottom: 1px solid var(--color-line);
}
.wishlist-item:last-child { border-bottom: none; }
.wishlist-item__thumb {
  width: 56px; height: 56px;
  border-radius: 10px;
  background-size: contain;
  background-position: center;
  background-repeat: no-repeat;
  background-color: #fdfaf3;
}
.wishlist-item__name { font-family: var(--font-serif); font-size: 17px; }
.wishlist-item__meta {
  font-size: 11px;
  letter-spacing: 1.5px;
  color: var(--color-muted);
  text-transform: uppercase;
  margin-top: 3px;
}
.wishlist-item__remove {
  width: 30px; height: 30px;
  border-radius: 999px;
  background: rgba(22, 22, 22, 0.05);
  border: none;
  color: var(--color-muted);
  font-size: 20px;
  cursor: pointer;
  transition: all 200ms var(--ease);
}
.wishlist-item__remove:hover {
  background: rgba(193, 74, 58, 0.12);
  color: #c14a3a;
}

/* Legacy class still used elsewhere (admin) */
.order-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 14px 0;
  border-bottom: 1px solid var(--color-line);
  font-size: 14px;
}
.order-row__status {
  font-size: 10px;
  letter-spacing: 2px;
  text-transform: uppercase;
  padding: 4px 10px;
  border-radius: 999px;
  background: rgba(22, 22, 22, 0.06);
}
.order-row__status[data-status="paid"] { background: rgba(82, 142, 88, 0.15); color: #2f5f37; }
.order-row__status[data-status="shipped"] { background: rgba(74, 110, 168, 0.15); color: #2c4979; }
.order-row__status[data-status="cancelled"] { background: rgba(193, 74, 58, 0.12); color: #842a1f; }

/* =========================================================
   Toast notifications
   ========================================================= */
.toast-stack {
  position: fixed;
  top: 88px;
  right: 24px;
  z-index: 200;
  display: flex;
  flex-direction: column;
  gap: 10px;
  pointer-events: none;
}
.toast {
  padding: 12px 18px;
  border-radius: 999px;
  background: rgba(22, 22, 22, 0.92);
  color: #fff;
  font-size: 12px;
  letter-spacing: 1.5px;
  box-shadow: var(--glass-shadow);
  pointer-events: auto;
  opacity: 0;
  transform: translateY(-10px);
  transition: opacity 250ms var(--ease), transform 250ms var(--ease);
}
.toast[data-visible="true"] { opacity: 1; transform: translateY(0); }

/* =========================================================
   Recent-sales toast — bottom-LEFT, social proof "X just bought Y"
   ========================================================= */
.recent-toast {
  position: fixed;
  left: 16px;
  bottom: 16px;
  z-index: 70;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 16px 10px 14px;
  border-radius: 999px;
  background: var(--glass-bg);
  -webkit-backdrop-filter: blur(var(--glass-blur));
  backdrop-filter: blur(var(--glass-blur));
  border: 1px solid var(--glass-border);
  box-shadow: var(--glass-shadow);
  font-size: 12px;
  color: var(--color-text);
  max-width: min(380px, calc(100vw - 32px));
  opacity: 0;
  transform: translateY(8px);
  transition: opacity 350ms var(--ease), transform 350ms var(--ease);
  pointer-events: none;
}
.recent-toast[data-visible="true"] { opacity: 1; transform: translateY(0); }
.recent-toast__dot {
  width: 8px;
  height: 8px;
  border-radius: 999px;
  background: #5fa56a;                /* live-pulse green */
  flex-shrink: 0;
  animation: livePulse 1.8s ease-in-out infinite;
}
@keyframes livePulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(95,165,106,0.5); }
  50%      { box-shadow: 0 0 0 6px rgba(95,165,106,0); }
}
.recent-toast__text {
  flex: 1;
  font-family: var(--font-serif);
  font-style: italic;
  line-height: 1.35;
}
.recent-toast__time {
  font-size: 10px;
  letter-spacing: 1.5px;
  color: var(--color-muted);
  text-transform: uppercase;
  flex-shrink: 0;
}
@media (max-width: 560px) {
  .recent-toast { left: 10px; bottom: 170px; font-size: 11px; padding: 8px 12px; }
}

/* =========================================================
   Floating social panel — bottom-right, vertical glass column
   ========================================================= */
.social-panel {
  position: fixed;
  right: 16px;
  bottom: 16px;                  /* match .panel bottom for clean baseline */
  z-index: 80;
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 5px;                  /* narrower without shrinking the icons */
  /* Same glassmorphism recipe as the buy panel so they read as a pair. */
  background:
    linear-gradient(135deg,
      rgba(255, 255, 255, 0.34) 0%,
      rgba(255, 255, 255, 0.18) 100%);
  -webkit-backdrop-filter: blur(36px) saturate(200%) brightness(1.04);
  backdrop-filter: blur(36px) saturate(200%) brightness(1.04);
  border: 1px solid rgba(255, 255, 255, 0.45);
  border-radius: 18px;           /* match .panel border-radius */
  box-shadow:
    0 24px 60px -18px rgba(0, 0, 0, 0.35),
    inset 0 1px 0 rgba(255, 255, 255, 0.7),
    inset 0 -1px 0 rgba(0, 0, 0, 0.04);
}
.social-panel__link {
  width: 40px;
  height: 40px;
  border-radius: 999px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  color: var(--color-text);   /* fallback foreground for TikTok 3rd-layer */
  transition: background 200ms var(--ease), transform 220ms var(--ease);
  /* Button reset — `<button>` placeholder variant needs to look
     identical to the `<a>` variant.  Default browser button has a
     border, system font, and outline on focus; flatten all of them. */
  border: none;
  padding: 0;
  font: inherit;
  cursor: pointer;
}
.social-panel__link:hover { background: rgba(22,22,22,0.05); transform: translateY(-1px); }
.social-panel__link svg {
  width: 22px;
  height: 22px;
  display: block;
  /* CRITICAL on iOS Safari: without this, taps on the SVG glyph
     resolve to <svg>/<path> as the event target — `closest()` still
     works in JS, but the synthetic click that triggers the <button>'s
     default action gets confused.  Result: tapping the WhatsApp icon
     can fire the Telegram button's handler if they're adjacent in DOM
     order.  Forcing all descendants out of the hit-test pipeline
     makes the entire pill a single tap target, identical behaviour
     across iOS/Android/desktop. */
  pointer-events: none;
}
/* Placeholder = no real URL yet, button opens the lead modal.  Tiny
   gold dot in the corner so the admin (and us during QA) can see at a
   glance which icons are still unconfigured. */
.social-panel__link--placeholder {
  position: relative;
}
.social-panel__link--placeholder::after {
  content: '';
  position: absolute;
  top: 5px;
  right: 5px;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: #d4ab68;
  box-shadow: 0 0 0 1.5px #fff, 0 1px 3px rgba(180, 140, 74, 0.5);
}

/* TikTok's third (foreground) glyph uses currentColor — match it to the
   page text so it sits between the cyan + magenta offsets correctly. */
.social-panel__link--tiktok { color: var(--color-text); }

/* On mobile, the social pill lifts ABOVE the purchase panel (mirror image
   of the photo-thumb pill on the left). Uses the global --panel-h var
   published from app.js so it tracks the real panel height. */
@media (max-width: 900px) {
  .social-panel {
    /* Was 6px from the right edge — too close, the glass-pill border
       was getting clipped on devices with rounded screen corners
       (iPhone notch / Android pill cutout).  10px + safe-area gives
       breathing room without losing thumb reach. */
    right: max(10px, env(safe-area-inset-right));
    bottom: calc(max(8px, env(safe-area-inset-bottom)) + var(--panel-h, 100px) + 60px);
    padding: 5px;
    gap: 4px;
    transition: bottom 200ms var(--ease);
    /* Hard guard so the panel never extends past the viewport edge if
       the safe-area calc returns 0 on older devices. */
    max-width: calc(100vw - 20px);
  }
  .social-panel__link { width: 34px; height: 34px; }
  .social-panel__link svg { width: 17px; height: 17px; }
}

/* =========================================================
   Cookie banner — fixed bottom-center, glass, dismissible
   ========================================================= */
.cookie-banner {
  position: fixed;
  left: 16px;
  right: 16px;
  bottom: 16px;
  z-index: 90;
  border-radius: 18px;
  padding: 16px 20px;
  background: rgba(255, 255, 255, 0.85);
  -webkit-backdrop-filter: blur(22px);
  backdrop-filter: blur(22px);
  border: 1px solid var(--glass-border);
  box-shadow: var(--glass-shadow);
  max-width: 760px;
  margin: 0 auto;
  opacity: 0;
  transform: translateY(16px);
  transition: opacity 350ms var(--ease), transform 350ms var(--ease);
}
.cookie-banner[data-visible="true"] { opacity: 1; transform: translateY(0); }
.cookie-banner__inner {
  display: grid;
  gap: 14px;
}
.cookie-banner__top { display: block; }
.cookie-banner__text {
  margin: 0;
  font-size: 13px;
  line-height: 1.5;
  color: var(--color-text);
}
.cookie-banner__more {
  background: none;
  border: none;
  padding: 0 0 0 4px;
  margin: 0;
  font-size: 12px;
  letter-spacing: 1px;
  color: var(--color-text);
  text-decoration: underline;
  cursor: pointer;
}
/* Expandable category panel — hidden until user clicks "Anpassen" */
.cookie-banner__panel {
  display: none;
  flex-direction: column;
  gap: 10px;
  padding: 12px 0;
  border-top: 1px solid rgba(22, 22, 22, 0.08);
}
.cookie-banner__panel[data-expanded="true"] { display: flex; }
.cookie-banner__row {
  display: grid;
  grid-template-columns: 24px 1fr;
  gap: 12px;
  align-items: start;
  font-size: 12px;
  line-height: 1.4;
  cursor: pointer;
}
.cookie-banner__row input[type="checkbox"] {
  width: 18px; height: 18px;
  margin: 2px 0 0;
  accent-color: var(--color-text, #161616);
  cursor: pointer;
}
.cookie-banner__row input[type="checkbox"]:disabled { cursor: not-allowed; opacity: 0.7; }
.cookie-banner__row strong {
  display: block;
  font-size: 13px;
  font-weight: 600;
  margin-bottom: 2px;
}
.cookie-banner__row span {
  display: block;
  color: var(--color-muted, #6b6b6b);
}
.cookie-banner__buttons {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  justify-content: flex-end;
}
/* TTDSG requirement — "Reject" is visually equivalent in size + prominence
   to "Accept all".  No design dark-patterns. */
.cookie-banner__btn {
  padding: 10px 18px;
  border-radius: 999px;
  font-size: 12px;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  font-weight: 600;
  font-family: var(--font-sans, "Inter", system-ui, sans-serif);
  cursor: pointer;
  border: 1px solid rgba(22, 22, 22, 0.18);
  background: transparent;
  color: var(--color-text);
  transition: background 180ms var(--ease), border-color 180ms var(--ease);
}
.cookie-banner__btn--ghost:hover { background: rgba(22, 22, 22, 0.05); }
.cookie-banner__btn--primary {
  background: var(--color-text, #161616);
  color: #fff;
  border-color: var(--color-text, #161616);
}
.cookie-banner__btn--primary:hover { background: #000; }
@media (max-width: 560px) {
  .cookie-banner__buttons { justify-content: stretch; }
  .cookie-banner__buttons .cookie-banner__btn { flex: 1 1 100%; min-width: 0; }
}

/* =========================================================
   Legal modal body — typography for long-form documents
   ========================================================= */
.legal-body { font-size: 14px; line-height: 1.6; color: #2c2c2c; }
.legal-body h2 {
  font-family: var(--font-serif);
  font-size: 28px;
  font-weight: 600;
  margin: 0 0 18px;
}
.legal-body h3 {
  font-family: var(--font-serif);
  font-size: 18px;
  font-weight: 600;
  margin: 22px 0 6px;
}
.legal-body p { margin: 0 0 12px; }
.legal-body ul { padding-left: 22px; margin: 0 0 12px; }
.legal-body li { margin-bottom: 4px; }
.legal-body table { font-size: 13px; }
.legal-body a { color: var(--color-text); text-decoration: underline; }

/* =========================================================
   Mobile tweaks for new components
   ========================================================= */
@media (max-width: 700px) {
  /* ===== FULLSCREEN MODALS ON MOBILE =====
     Centered floating modal looks lost on phone — too much wasted space
     around the edges and the user has to scroll inside a tiny container.
     Take the whole viewport, no margin, no rounded corners. Internal
     content scrolls naturally. */
  .modal {
    top: 0 !important;
    left: 0 !important;
    /* No !important on transform — the slide-up keyframe needs to drive
       transform from 100% to 0%. */
    transform: translateY(0);
    width: 100% !important;
    max-width: 100% !important;
    height: 100vh !important;
    height: 100dvh !important;       /* iOS Safari URL-bar aware */
    max-height: 100dvh !important;
    border-radius: 0 !important;
    box-shadow: none !important;
    display: flex;
    flex-direction: column;
  }
  .modal[data-open="true"] {
    transform: translateY(0);
    /* Slide-up animation feels more native than the desktop fade */
    animation: modalSlideUp 320ms cubic-bezier(0.16, 1, 0.3, 1);
  }
  @keyframes modalSlideUp {
    from { transform: translateY(100%); }
    to   { transform: translateY(0); }
  }
  .modal__header {
    position: sticky;
    top: 0;
    background: rgba(255, 255, 255, 0.96);
    -webkit-backdrop-filter: blur(20px);
    backdrop-filter: blur(20px);
    z-index: 2;
    padding: 16px 20px;
    border-bottom: 1px solid rgba(22, 22, 22, 0.06);
    flex-shrink: 0;
  }
  .modal__title { font-size: 22px; }
  .modal__title-logo { height: 32px; max-width: 130px; }
  .modal__body {
    flex: 1 1 auto;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    padding: 16px 20px 32px;
  }
  .form-row { grid-template-columns: 1fr; }
  .toast-stack { right: 12px; top: 12px; }
  /* Cart drawer: also fullscreen on phone */
  .drawer {
    width: 100% !important;
    height: 100vh !important;
    height: 100dvh !important;
    top: 0 !important;
    right: 0 !important;
    border-radius: 0 !important;
  }
  .checkout-product { grid-template-columns: 72px 1fr; }
  .checkout-product__thumb { width: 72px; height: 72px; }
}

/* =========================================================
   In-panel photo gallery (extra images per product)
   Thumbnails sit below the buy buttons; click opens lightbox.
   ========================================================= */
.panel__gallery-row { margin-top: 6px; }
.panel__gallery {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 72px;
  gap: 10px;
  overflow-x: auto;
  padding: 4px 2px;
  scrollbar-width: thin;
  scroll-snap-type: x proximity;
  -webkit-overflow-scrolling: touch;
}
.panel__gallery::-webkit-scrollbar { height: 6px; }
.panel__gallery::-webkit-scrollbar-thumb { background: rgba(22,22,22,0.18); border-radius: 999px; }
.panel__thumb {
  position: relative;
  width: 72px; height: 72px;
  border-radius: 12px;
  overflow: hidden;
  border: 1px solid rgba(22,22,22,0.12);
  background: rgba(255,255,255,0.6);
  padding: 0;
  cursor: pointer;
  transition: transform 180ms var(--ease), border-color 180ms var(--ease), box-shadow 180ms var(--ease);
  scroll-snap-align: start;
}
.panel__thumb:hover {
  transform: translateY(-2px);
  border-color: var(--color-accent);
  box-shadow: 0 10px 24px -12px rgba(22,22,22,0.35);
}
.panel__thumb img {
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
}


/* Respect users who prefer reduced motion */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; scroll-snap-type: none; }
  .card__media, .card__frame, .panel, .reveal {
    transition: none !important;
    transform: none !important;
    opacity: 1 !important;
  }
  .panel { transform: translateY(-50%) !important; }
}


/* ============================================================
   Brand-essay — luxury editorial spread.
   ============================================================
   This block has TWO jobs that pull in different directions:
     1. Carry the SEO-critical German prose (≈1500 words) that crawlers
        + AI ingest to understand who we are.
     2. Feel like a deliberate magazine spread — not a wall of text.
   The styling below treats it like an editorial print piece: serif
   throughout, gold accents, ornamental dividers between sections,
   generous whitespace, italic eyebrows. No bold underlines on inline
   strongs (they were reading as keyword-stuffing); instead a quiet
   gold tint that respects the typography.
   ============================================================ */
.brand-essay {
  position: relative;
  z-index: 1;
  /* The original `min(720px, 100% - 32px)` was INVALID CSS — `min()`
     can't mix percentages and pixels without an explicit calc().  The
     browser silently dropped the value, max-width fell back to `none`,
     and the long German body copy stretched the article (and body)
     wider than the viewport — which then offset every centered
     sibling to the right.  This was the root cause of the grid-mode
     "cards extend past the right edge, left side empty" bug. */
  max-width: min(720px, calc(100% - 32px));
  margin: 0 auto;
  padding: 120px 28px 64px;
  color: var(--color-text);
  font-family: var(--font-serif, "Cormorant Garamond", Georgia, serif);
  line-height: 1.65;
  font-size: 19px;
  /* German has long compound words (Geschenkverpackung, Hauseinweihung,
     Wohnaccessoires) — let them break inside if they'd overflow a narrow
     phone column rather than push the whole layout wider. */
  overflow-wrap: anywhere;
  word-break: normal;
  /* Anti-FOUC: opacity-only fade-in.  The earlier translateY(8px) move
     was being perceived as the whole page "appearing from below" and
     "the scrollbar jumping down" on reload because the brand-essay
     reflowed while moving — pure opacity is invisible to layout. */
  opacity: 0;
  animation: brand-essay-fadein 280ms ease-out 600ms forwards;
}
@keyframes brand-essay-fadein {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* --- Decorative top ornament — gold seal flourish ---
   Sits above the essay title; visually marks the start of the
   editorial section. Pure decoration, aria-hidden via attribute. */
.brand-essay::before {
  content: "";
  display: block;
  width: 56px;
  height: 1px;
  margin: 0 auto 28px;
  background: linear-gradient(90deg, transparent, var(--gold, #b58e4c) 50%, transparent);
}

/* --- Header --- */
.brand-essay__head {
  text-align: center;
  margin-bottom: 72px;
}
.brand-essay__eyebrow {
  font-family: var(--font-sans, "Inter", system-ui, sans-serif);
  font-size: 10px;
  letter-spacing: 4px;
  text-transform: uppercase;
  color: var(--gold-deep, #8a6a2a);
  margin: 0 0 22px;
  font-weight: 500;
}
.brand-essay__title {
  font-family: var(--font-serif, "Cormorant Garamond", serif);
  font-weight: 400;
  font-size: clamp(36px, 6vw, 60px);
  line-height: 1.1;
  letter-spacing: 0.3px;
  margin: 0 0 28px;
  color: var(--color-text);
}
.brand-essay__lead {
  font-family: var(--font-serif, "Cormorant Garamond", serif);
  font-style: italic;
  font-size: clamp(19px, 2.2vw, 23px);
  line-height: 1.55;
  margin: 0 auto;
  max-width: 580px;
  color: var(--color-text-soft, #4a4a4a);
  font-weight: 400;
}
/* Inline strongs in the lead get a quiet gold tint, no bolding.
   The original underline-style emphasis read as SEO-keyword shouting. */
.brand-essay__lead strong {
  font-weight: 500;
  font-style: normal;
  color: var(--color-text);
}

/* --- Body sections — each becomes its own editorial card --- */
.brand-essay__body { display: grid; gap: 80px; }

/* Ornamental divider BETWEEN sections — small gold dot trio.
   Implemented as a generated marker BEFORE each section (except the
   first) so the rhythm reads as "·  ·  ·" between editorial breaks. */
.brand-essay__section + .brand-essay__section::before {
  content: "·  ·  ·";
  display: block;
  text-align: center;
  letter-spacing: 14px;
  color: var(--gold, #b58e4c);
  font-size: 14px;
  margin: 0 0 64px -14px;
  opacity: 0.55;
}

.brand-essay__section h2 {
  font-family: var(--font-serif, "Cormorant Garamond", serif);
  font-weight: 400;
  font-size: clamp(28px, 3.4vw, 36px);
  line-height: 1.2;
  margin: 0 0 28px;
  letter-spacing: 0.2px;
  text-align: center;
  color: var(--color-text);
}
/* Italic serif sub-heading, no bold sans — matches the magazine vibe. */
.brand-essay__section h3 {
  font-family: var(--font-serif, "Cormorant Garamond", serif);
  font-weight: 400;
  font-size: clamp(20px, 2.4vw, 24px);
  line-height: 1.3;
  margin: 36px 0 12px;
  font-style: italic;
  color: var(--color-text);
}
.brand-essay__section p {
  margin: 0 0 18px;
  font-size: 18px;
  line-height: 1.7;
}
.brand-essay__section p:last-child { margin-bottom: 0; }
/* Quiet emphasis — gold tint, no weight increase, no underline.
   Reads as a refined italic moment in the prose rather than a
   keyword highlight. */
.brand-essay__section strong {
  font-weight: 500;
  color: var(--gold-deep, #8a6a2a);
  font-style: normal;
}
.brand-essay__section em {
  font-style: italic;
  color: var(--color-text);
}

/* --- Lists — bullet replaced with a hairline gold dash --- */
.brand-essay__list {
  list-style: none;
  padding: 0;
  margin: 28px 0;
  display: grid;
  gap: 18px;
}
.brand-essay__list li {
  padding-left: 32px;
  position: relative;
  font-size: 17px;
  line-height: 1.65;
}
.brand-essay__list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 14px;
  width: 18px;
  height: 1px;
  background: var(--gold, #b58e4c);
}
.brand-essay__list--steps { counter-reset: steps; }
.brand-essay__list--steps li {
  counter-increment: steps;
  padding-left: 52px;
  min-height: 38px;
}
.brand-essay__list--steps li::before {
  content: counter(steps, decimal-leading-zero);
  background: none;
  width: auto; height: auto;
  top: -4px; left: 0;
  font-family: var(--font-serif, "Cormorant Garamond", serif);
  font-size: 26px;
  color: var(--gold, #b58e4c);
  font-weight: 400;
  font-style: italic;
}

/* --- FAQ — refined accordion with serif headlines --- */
.brand-essay__faq {
  border-top: 1px solid rgba(181, 142, 76, 0.20);
  padding: 22px 0;
}
.brand-essay__faq:last-of-type {
  border-bottom: 1px solid rgba(181, 142, 76, 0.20);
}
.brand-essay__faq summary {
  cursor: pointer;
  font-family: var(--font-serif, "Cormorant Garamond", serif);
  font-weight: 400;
  font-size: 21px;
  line-height: 1.3;
  list-style: none;
  position: relative;
  padding-right: 40px;
  user-select: none;
  color: var(--color-text);
  transition: color 200ms var(--ease);
}
.brand-essay__faq summary:hover { color: var(--gold-deep, #8a6a2a); }
.brand-essay__faq summary::-webkit-details-marker { display: none; }
.brand-essay__faq summary::after {
  content: "";
  position: absolute;
  right: 4px; top: 50%;
  width: 14px; height: 14px;
  margin-top: -7px;
  border-right: 1px solid var(--gold, #b58e4c);
  border-bottom: 1px solid var(--gold, #b58e4c);
  transform: rotate(45deg);
  transition: transform 250ms var(--ease);
}
.brand-essay__faq[open] summary::after { transform: rotate(-135deg); }
.brand-essay__faq[open] summary { margin-bottom: 14px; }
.brand-essay__faq p {
  margin: 0;
  font-size: 17px;
  line-height: 1.7;
  color: var(--color-text-soft, #4a4a4a);
  font-style: italic;
}

/* --- Links — soft gold underline that grows on hover --- */
.brand-essay a {
  color: var(--gold-deep, #8a6a2a);
  text-decoration: none;
  border-bottom: 1px solid rgba(181, 142, 76, 0.4);
  padding-bottom: 1px;
  transition: border-color 200ms var(--ease), color 200ms var(--ease);
}
.brand-essay a:hover {
  color: var(--color-text);
  border-bottom-color: var(--color-text);
}

/* --- Closing flourish — gold dot mirrors the opening ornament --- */
.brand-essay::after {
  content: "";
  display: block;
  width: 56px;
  height: 1px;
  margin: 64px auto 0;
  background: linear-gradient(90deg, transparent, var(--gold, #b58e4c) 50%, transparent);
}

@media (max-width: 640px) {
  .brand-essay { padding: 80px 22px 48px; font-size: 17px; }
  .brand-essay::before { margin: 0 auto 22px; }
  .brand-essay__head { margin-bottom: 52px; }
  .brand-essay__lead { font-size: 18px; }
  .brand-essay__body { gap: 56px; }
  .brand-essay__section + .brand-essay__section::before { margin-bottom: 44px; }
  .brand-essay__section h2 { font-size: 26px; margin-bottom: 22px; }
  .brand-essay__section h3 { font-size: 19px; }
  .brand-essay__section p { font-size: 17px; }
  .brand-essay__list li { font-size: 16px; }
  .brand-essay__faq summary { font-size: 19px; }
  .brand-essay__faq p { font-size: 16px; }
}

/* =========================================================
   COMING SOON — full-bleed editorial card shown on a season
   landing page (/herbst, /winter, /fruehling) when the API
   returns zero products for that season.  Per-season palette
   is set via the `.coming-soon--<hue>` modifier; the inner
   content is identical across all three.
   ========================================================= */
.coming-soon {
  /* Full-viewport card so the section fills the screen the same
     way a regular product card does — keeps scroll-snap behaviour
     consistent with the rest of the site. */
  position: relative;
  width: 100%;
  height: 100vh;
  height: 100dvh;
  display: grid;
  place-items: center;
  padding: 88px 24px 56px;
  overflow: hidden;
  /* Default palette — overridden per .coming-soon--<hue> below. */
  --cs-bg-start: #f8f2ea;
  --cs-bg-end:   #efe5d4;
  --cs-text:     #1a1a1a;
  --cs-muted:    #6b5a3d;
  --cs-accent:   var(--la-gold, #b48c4a);
  --cs-glyph:    rgba(22, 22, 22, 0.20);
  background:
    radial-gradient(ellipse at 30% 0%, rgba(255, 255, 255, 0.55) 0%, transparent 55%),
    linear-gradient(180deg, var(--cs-bg-start) 0%, var(--cs-bg-end) 100%);
  color: var(--cs-text);
}
/* Per-season palettes — chosen to evoke the mood of each edition
   without veering into kitsch.  All three use a soft, paper-like
   gradient base so the site still reads as the same brand. */
.coming-soon--autumn {
  --cs-bg-start: #f9efde;
  --cs-bg-end:   #ecd3a8;
  --cs-text:     #2a1a08;
  --cs-muted:    #7a4e1f;
  --cs-accent:   #b9742a;
  --cs-glyph:    rgba(120, 68, 16, 0.18);
}
.coming-soon--winter {
  --cs-bg-start: #eef3f6;
  --cs-bg-end:   #c8d3dc;
  --cs-text:     #1f2a33;
  --cs-muted:    #4d6275;
  --cs-accent:   #7693a7;
  --cs-glyph:    rgba(31, 49, 70, 0.16);
}
.coming-soon--spring {
  --cs-bg-start: #fbeef0;
  --cs-bg-end:   #ecd0d8;
  --cs-text:     #3a1f28;
  --cs-muted:    #855566;
  --cs-accent:   #c98a9b;
  --cs-glyph:    rgba(180, 95, 120, 0.20);
}
.coming-soon__inner {
  max-width: 640px;
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 22px;
  /* Subtle fade-in so the page doesn't slam into view. */
  animation: comingSoonIn 720ms cubic-bezier(.16, 1, .3, 1) both;
}
@keyframes comingSoonIn {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: translateY(0); }
}
.coming-soon__glyph {
  /* Decorative seasonal SVG — half-opacity so it reads as an
     ornamental watermark, not a logo.  Color is inherited from the
     inline `style` on the JS render so we don't fight specificity. */
  width: 90px;
  height: 90px;
  opacity: 0.7;
  margin-bottom: 4px;
}
.coming-soon__glyph svg {
  width: 100%;
  height: 100%;
}
.coming-soon__eyebrow {
  margin: 0;
  font-family: var(--font-sans, Inter, sans-serif);
  font-size: 11px;
  letter-spacing: 4px;
  text-transform: uppercase;
  font-weight: 500;
  color: var(--cs-muted);
}
.coming-soon__title {
  margin: 0;
  font-family: var(--font-serif);
  font-weight: 500;
  font-size: clamp(28px, 4.6vw, 46px);
  line-height: 1.18;
  letter-spacing: 0.2px;
  color: var(--cs-text);
}
.coming-soon__body {
  margin: 0;
  font-family: var(--font-serif);
  font-style: italic;
  font-size: clamp(15px, 1.6vw, 18px);
  line-height: 1.55;
  color: var(--cs-text);
  opacity: 0.82;
  max-width: 520px;
}
.coming-soon__cta-row {
  margin-top: 14px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
}
.coming-soon__cta {
  /* Same minimalist language as the grid-detail primary button:
     white fill, hairline outline in the season accent, dark text;
     hover inverts to the accent fill with white text. */
  appearance: none;
  -webkit-appearance: none;
  height: 48px;
  padding: 0 32px;
  border-radius: 999px;
  border: 1.5px solid var(--cs-accent);
  background: #ffffff;
  color: var(--cs-text);
  font-family: var(--font-sans, Inter, sans-serif);
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 2.4px;
  text-transform: uppercase;
  cursor: pointer;
  transition: background 220ms var(--ease),
              color 220ms var(--ease),
              transform 160ms ease;
  -webkit-tap-highlight-color: transparent;
}
.coming-soon__cta:hover {
  background: var(--cs-accent);
  color: #ffffff;
}
.coming-soon__cta:active { transform: translateY(1px); }
.coming-soon__note {
  font-family: var(--font-sans, Inter, sans-serif);
  font-size: 10px;
  letter-spacing: 3px;
  text-transform: uppercase;
  color: var(--cs-muted);
  opacity: 0.8;
}
/* Decorative oversized watermark — same glyph repeated faintly in
   the background corner so the screen doesn't feel empty.  Pure
   decorative, hidden from screen readers via aria-hidden on the JS
   render path.  Driven by the same accent colour so it stays
   per-season correct. */
.coming-soon::before,
.coming-soon::after {
  content: '';
  position: absolute;
  width: 380px;
  height: 380px;
  pointer-events: none;
  opacity: 0.5;
  background-image: radial-gradient(circle at center, var(--cs-glyph) 0%, transparent 60%);
}
.coming-soon::before {
  top: -90px;
  right: -90px;
}
.coming-soon::after {
  bottom: -120px;
  left: -120px;
  opacity: 0.35;
}

/* Mobile fine-tune — tighter padding + smaller glyph, slightly
   shorter line-height so a long title still fits without scroll
   on a 360 px iPhone SE. */
@media (max-width: 600px) {
  .coming-soon {
    /* Subtract the prelaunch banner height (set as --prelaunch-banner-h
       by prelaunch.js) so the inner content actually centres in the
       VISIBLE viewport — without this the glyph hides behind the
       banner on iPhones and the title sits a bit too low. */
    height: calc(100dvh - var(--prelaunch-banner-h, 0px));
    padding: 60px 18px 40px;
  }
  .coming-soon__inner { gap: 16px; }
  .coming-soon__glyph { width: 68px; height: 68px; }
  .coming-soon__title { font-size: clamp(24px, 7vw, 30px); line-height: 1.22; }
  .coming-soon__body  { font-size: 15px; line-height: 1.5; }
  .coming-soon__eyebrow { letter-spacing: 3px; font-size: 10.5px; }
  .coming-soon__cta { height: 46px; padding: 0 24px; font-size: 11px; letter-spacing: 2px; }
  .coming-soon::before { width: 240px; height: 240px; top: -60px; right: -60px; }
  .coming-soon::after  { width: 280px; height: 280px; bottom: -90px; left: -90px; }
}
}