/* ============================================================
   LAYOUT TOGGLE — cinema (default) ⟷ grid (compact gallery)
   ============================================================
   Driven entirely by `body[data-layout="..."]`.  Cinema mode keeps the
   existing immersive scroll-snap experience.  Grid mode shows 6 tiles
   per page (3×2 desktop, 2×N tablet, 1×N phone), with each card's
   info panel expanding INLINE BELOW the row on tap (no modal).
   ============================================================ */

/* --- Toggle icon in nav (always visible regardless of mode) ----- */
.nav__icon--layout {
  position: relative;
}
.layout-icon {
  position: absolute;
  inset: 0;
  margin: auto;
  width: 20px;
  height: 20px;
  transition: opacity 220ms var(--ease), transform 220ms var(--ease);
}
/* In cinema mode, show the GRID icon (the destination).  In grid
   mode, show the CINEMA icon. */
body[data-layout="cinema"] .layout-icon--cinema { opacity: 0; transform: scale(0.7); }
body[data-layout="cinema"] .layout-icon--grid   { opacity: 1; transform: scale(1); }
body[data-layout="grid"]   .layout-icon--cinema { opacity: 1; transform: scale(1); }
body[data-layout="grid"]   .layout-icon--grid   { opacity: 0; transform: scale(0.7); }

/* ============================================================
   GRID MODE
   ============================================================ */
body[data-layout="grid"],
html[data-layout="grid"] {
  /* Disable mandatory scroll-snap globally — grid mode is a normal
     scrollable page.  The attribute is applied to BOTH <html> and
     <body> by layout.js so this works on every browser regardless
     of :has() support. */
  scroll-snap-type: none !important;
}

/* Card container becomes a real CSS Grid.
 *
 * CRITICAL: every width here uses `!important` because the original
 * cinema-mode `.card { width: 100vw }` rules in style.css would
 * otherwise force grid items to be a full viewport wide (the bug
 * users reported as "cards extend past the right edge of the
 * screen, left side empty").  We're not just centering the grid
 * — we're actively neutralising every leftover viewport-width
 * rule that cinema mode applied to the same elements.
 *
 * Width strategy:
 *   `width: calc(100vw - 18px)` — on Windows the vertical scrollbar
 *   takes ~17 px and `100vw` includes it.  Subtracting a fixed
 *   margin guarantees the grid stays strictly INSIDE the visible
 *   viewport, no matter what the user's OS or browser does with
 *   scrollbar gutters.  This is the single most robust way to
 *   prevent the right-edge bleed users have repeatedly reported.
 *   The `min(...)` then caps at 1400 px for ultra-wide monitors. */
body[data-layout="grid"] main#cards {
  display: grid !important;
  grid-template-columns: repeat(3, minmax(0, 1fr)) !important;
  gap: 22px;
  padding: 140px 24px 60px;
  width: min(1400px, calc(100vw - 18px)) !important;
  max-width: min(1400px, calc(100vw - 18px)) !important;
  margin-left: auto !important;
  margin-right: auto !important;
  min-height: auto;
  box-sizing: border-box !important;
  overflow-x: hidden;
  position: relative;
  left: auto !important;
  right: auto !important;
  transform: none !important;
}
/* Belt-and-braces: clip horizontal overflow at the html/body level
   for grid mode and force every direct descendant of main to obey
   its grid track instead of inheriting cinema's `width: 100vw`. */
html[data-layout="grid"],
body[data-layout="grid"] {
  overflow-x: hidden !important;
  max-width: 100vw !important;
  width: 100% !important;
}

/* ============================================================
   SIBLING OVERRIDES — the actual cause of the right-edge bleed
   ============================================================
   `.brand-essay` and `.footer` are SIBLINGS of `main#cards` inside
   `<body>`.  Their cinema-mode CSS sets `.footer { width: 100vw }`
   and `.brand-essay { max-width: min(720px, 100% - 32px) }` — the
   latter is INVALID CSS (calc() missing), so max-width fell back to
   `none` and the long article stretched the body wider than the
   viewport.  Since `main#cards` is centred via `margin: 0 auto`, the
   grid then sat at body-centre (off-screen-right), not viewport-centre.
   Fix: pin these two siblings to viewport width in grid mode. */
body[data-layout="grid"] .brand-essay {
  width: 100% !important;
  max-width: min(720px, calc(100vw - 32px)) !important;
  margin-left: auto !important;
  margin-right: auto !important;
  box-sizing: border-box !important;
  overflow-wrap: anywhere;
}
body[data-layout="grid"] .footer {
  width: 100% !important;
  max-width: 100vw !important;
  margin-left: auto !important;
  margin-right: auto !important;
  box-sizing: border-box !important;
}
/* Other known top-level siblings that the cinema layout sets to
   100vw or scrolls horizontally — clamp them to viewport width too.
   We list these EXPLICITLY rather than using a universal selector,
   so the fixed-position `.brand-tagline` (max-width: 420px) and
   `.nav` (with its own internal constraints) aren't accidentally
   widened by `max-width: 100vw !important`. */
body[data-layout="grid"] .scroll-snap-section,
body[data-layout="grid"] .marquee,
body[data-layout="grid"] section.brand-essay,
body[data-layout="grid"] section.footer {
  max-width: 100vw !important;
  box-sizing: border-box !important;
}
/* Catch-all: ANY direct child of main#cards in grid mode is a grid
   item, and grid items must respect their grid track.  This kills
   stray `width: 100vw` from cinema-mode rules on .card-frame,
   .marquee, .scroll-snap-section, etc. */
body[data-layout="grid"] main#cards > * {
  width: 100% !important;
  max-width: 100% !important;
  min-width: 0 !important;
  box-sizing: border-box !important;
  left: auto !important;
  right: auto !important;
  margin-left: 0 !important;
  margin-right: 0 !important;
}
/* ============================================================
   COMING SOON — full-bleed editorial card in grid mode
   ============================================================
   The coming-soon section is a single grid child but needs to span
   the full row AND break out of main#cards's 24-px horizontal
   padding so the gradient + decorative watermarks paint to the
   viewport edges.  Without this override the section would shrink
   into a single grid column and look tiny on desktop. */
body[data-layout="grid"] main#cards > .coming-soon {
  grid-column: 1 / -1;
  width: calc(100% + 48px) !important;
  max-width: calc(100% + 48px) !important;
  margin-left: -24px !important;
  margin-right: -24px !important;
  /* main#cards owns its own top/bottom padding for the float-nav
     clearance — cancel it for this child only so the gradient
     fills the entire viewport without sand-coloured gaps. */
  margin-top: -32px !important;
  margin-bottom: -32px !important;
  border-radius: 0;
}

/* ============================================================
   MARQUEE — grid-mode editorial strip
   ============================================================
   The marquee is the horizontal scrolling band of inspiration
   photos that sits between product rows.  In cinema mode it's a
   full-viewport hero; in grid mode it has to feel like a polished
   editorial banner — generous rounded corners, framed, never
   bleeding past the column track or letting items overflow. */
body[data-layout="grid"] main#cards > .marquee {
  grid-column: 1 / -1;
  height: 260px;
  aspect-ratio: auto;
  position: relative;
  /* Full-bleed width — break out of the parent's 24-px horizontal
     padding so the strip extends a touch beyond the card row.
     Width is compensated via calc() so main#cards's overflow:hidden
     still catches any further bleed at the viewport edge. */
  width: calc(100% + 48px) !important;
  max-width: calc(100% + 48px) !important;
  margin-left: -24px !important;
  margin-right: -24px !important;
  /* NO container styling — no background, no border, no shadow,
     no rounded clipping rect.  The user wants only the images
     themselves visible as floating rounded photos, exactly like
     the Vollbild (cinema) marquee renders them.  overflow:hidden
     still bounds the horizontal scroll-track but it's invisible
     because there's nothing to clip *against*. */
  background: transparent;
  border: none;
  box-shadow: none;
  border-radius: 0;
  overflow: hidden;
  cursor: grab;
  /* Soft mask at left/right edges so images fade in/out rather
     than getting hard-cut by the overflow boundary — gives the
     "floating photos" feel the user described. */
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 32px, #000 calc(100% - 32px), transparent 100%);
  mask-image: linear-gradient(90deg, transparent 0, #000 32px, #000 calc(100% - 32px), transparent 100%);
}
/* Track padding — give the first/last items breathing room at the
   rounded edges instead of brushing the curve. */
body[data-layout="grid"] main#cards > .marquee .marquee__track {
  gap: 14px;
  padding: 0 14px;
  align-items: center;
  height: 100%;
}
/* Items: sized to fit the 260-px container with 20-px vertical
   breathing room.  16:9 aspect-ratio keeps the editorial feel.  No
   clamp() — fixed height matches the container so items never poke
   past the rounded-corner mask. */
body[data-layout="grid"] main#cards > .marquee .marquee__item {
  height: 220px;
  aspect-ratio: 16 / 10;
  border-radius: 18px;
  flex-shrink: 0;
  overflow: hidden;
  background: #ffffff;
  box-shadow: 0 10px 22px -12px rgba(22, 22, 22, 0.25);
}
body[data-layout="grid"] main#cards > .marquee .marquee__item img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* Tablet — substantial photo strip, container grows to host items.
   Parent padding here is 18 px each side, so the negative
   margin matches that to extend the strip to the edges of
   main#cards's content box. */
@media (max-width: 1000px) {
  body[data-layout="grid"] main#cards > .marquee {
    height: 280px;        /* up from 220 — items now feel like hero photos */
    border-radius: 0;     /* container stays invisible — items keep their rounding */
    width: calc(100% + 36px) !important;
    max-width: calc(100% + 36px) !important;
    margin-left: -18px !important;
    margin-right: -18px !important;
  }
  body[data-layout="grid"] main#cards > .marquee .marquee__item {
    height: 240px;        /* up from 180 */
    aspect-ratio: 4 / 3;
    border-radius: 16px;
  }
  body[data-layout="grid"] main#cards > .marquee .marquee__track {
    gap: 14px; padding: 0 14px;
  }
}
/* Phone — generous photo strip.  130-px items felt cramped per user
   feedback; bumped up so each photo reads as a proper inspiration tile.
   Parent padding is 12 px each side. */
@media (max-width: 600px) {
  body[data-layout="grid"] main#cards > .marquee {
    height: 260px;        /* up from 160 — about 60 % taller */
    border-radius: 0;     /* container invisible — items keep their rounding */
    width: calc(100% + 24px) !important;
    max-width: calc(100% + 24px) !important;
    margin-left: -12px !important;
    margin-right: -12px !important;
    /* Tighter fade mask on phone since edges are closer together. */
    -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 18px, #000 calc(100% - 18px), transparent 100%);
    mask-image: linear-gradient(90deg, transparent 0, #000 18px, #000 calc(100% - 18px), transparent 100%);
  }
  body[data-layout="grid"] main#cards > .marquee .marquee__item {
    height: 220px;        /* up from 130 — visible without zooming */
    aspect-ratio: 4 / 3;
    border-radius: 14px;
  }
  body[data-layout="grid"] main#cards > .marquee .marquee__track {
    gap: 12px; padding: 0 12px;
  }
}

/* Each card-frame is no longer a viewport — it's just a grid cell.
   !important because cinema-mode `.card-frame { width: 100vw }` has
   the same specificity-after-tiebreak as ours, and we MUST win. */
body[data-layout="grid"] .card-frame {
  width: 100% !important;
  height: auto !important;
  min-width: 0 !important;
  max-width: 100% !important;
  scroll-snap-align: none;
  scroll-snap-stop: normal;
  position: relative !important;
  left: auto !important;
  right: auto !important;
  transform: none !important;
  box-sizing: border-box !important;
  /* Allow both axes — `pan-x pan-y` lets the swipe handler in
     grid-gallery.js flip slides AND lets the page scroll vertically
     when the user starts a vertical gesture on the photo.  The JS
     axis-locks after ~8 px so neither direction gets stolen. */
  touch-action: pan-x pan-y;
  -webkit-user-select: none;
  user-select: none;
}
body[data-layout="grid"] .card {
  width: 100% !important;
  height: auto !important;
  min-width: 0 !important;
  max-width: 100% !important;
  display: block;
  position: relative !important;
  left: auto !important;
  right: auto !important;
  transform: none !important;
  aspect-ratio: 4 / 5;        /* tall tile, like a magazine card */
  overflow: hidden;
  border-radius: 18px;
  background: #ffffff;
  border: 1px solid rgba(22, 22, 22, 0.08);
  box-shadow: 0 14px 36px -18px rgba(22, 22, 22, 0.18);
  transition: transform 240ms var(--ease), box-shadow 240ms var(--ease), border-color 240ms var(--ease);
  cursor: pointer;
  box-sizing: border-box !important;
}
body[data-layout="grid"] .card:hover {
  transform: translateY(-3px) !important;     /* beat the `transform: none !important` reset above */
  box-shadow: 0 22px 54px -18px rgba(22, 22, 22, 0.28);
}
/* Active card — clear "you tapped me, look below" cue.
   Per user feedback the previous gold ring was "лишняя" / too loud;
   we now use a soft neutral lift + a more present shadow so the
   relationship to the detail-row stays clear without the brand
   colour shouting on every tap.  Border stays the regular sand-grey
   inherited from the unselected state. */
body[data-layout="grid"] .card-frame[data-grid-expanded] .card {
  border-color: rgba(22, 22, 22, 0.12);
  box-shadow: 0 22px 50px -18px rgba(22, 22, 22, 0.32);
  transform: translateY(-2px) !important;
}
body[data-layout="grid"] .card-frame[data-grid-expanded]::before {
  /* Quiet neutral connector — same purpose (visually link the
     tile to its detail-row below) but no longer painted in the
     brand gold so the open state reads as muted rather than loud. */
  content: '';
  position: absolute;
  bottom: -14px;
  left: 50%;
  transform: translateX(-50%);
  width: 0;
  height: 0;
  border-left: 12px solid transparent;
  border-right: 12px solid transparent;
  border-top: 12px solid rgba(22, 22, 22, 0.45);
  z-index: 4;
  filter: drop-shadow(0 3px 5px rgba(22, 22, 22, 0.18));
  animation: gridConnectorIn 280ms var(--ease);
}
@keyframes gridConnectorIn {
  from { opacity: 0; transform: translate(-50%, -6px); }
  to   { opacity: 1; transform: translate(-50%, 0); }
}

/* Media area fills the whole tile (the panel is moved below in grid mode). */
body[data-layout="grid"] .card__media-stack,
body[data-layout="grid"] .card__media,
body[data-layout="grid"] .card__frame {
  position: absolute !important;
  inset: 0;
  width: 100% !important;
  height: 100% !important;
  z-index: 1;
  border-radius: inherit;
}
/* IMAGE FIT — `contain` (not `cover`) so the WHOLE composition is
   visible inside every tile.  Cinema mode crops the landscape
   render to cover the portrait card, which the user reported as
   "the picture goes beyond the window".  Contain centres the image
   and leaves a clean white letterbox — same white the studio photos
   were shot on, so the tile reads as one continuous canvas (no
   visible "frame" between letterbox and composition). */
body[data-layout="grid"] .card__media {
  background-size: contain !important;
  background-position: center !important;
  background-repeat: no-repeat !important;
  background-color: #ffffff;     /* matches studio photo bg — invisible seam */
}
/* The canvas overlay (cinema's scrub painter target) must be fully
   transparent in grid mode so the static poster underneath shows
   through.  Painter is bailed in app.js too, but belt-and-braces. */
body[data-layout="grid"] .card__frame {
  background: transparent !important;
  opacity: 0 !important;
  pointer-events: none;
}

/* Hide the per-slide nav arrows + dots in grid (cleaner look — user
   can tap the tile to open the full detail panel below). */
body[data-layout="grid"] .card__nav,
body[data-layout="grid"] .card__thumbs,
body[data-layout="grid"] .card__overlay {
  display: none !important;
}

/* Hide the BIG floating side panel — replaced by inline expandable
   strip at the bottom of each tile. */
body[data-layout="grid"] .panel {
  display: none !important;
}

/* ----- Compact info strip overlay on each tile ----- */
/* Title + price always visible, anchored to the bottom of the tile.
   The full description / "Bezahlen" / "Add to cart" actions are in a
   COLLAPSED expandable panel below the tile. */
body[data-layout="grid"] .card::after {
  /* Subtle dark scrim under the title for readability over photos. */
  content: '';
  position: absolute;
  inset: auto 0 0 0;
  height: 45%;
  background: linear-gradient(180deg, transparent 0%, rgba(22, 22, 22, 0.55) 100%);
  pointer-events: none;
  z-index: 2;
  border-radius: 0 0 18px 18px;
}

/* ----- Inline title overlay ----- */
body[data-layout="grid"] .card-frame::after {
  /* JS will populate this via the data-* attributes set on .card-frame.
     We render it as a CSS pseudo-element with attr() so we don't have
     to mutate the card markup in JS — the title + price come from the
     `data-name` and `data-price` attributes the renderer sets. */
  content: attr(data-name) ' · ' attr(data-price);
  position: absolute;
  left: 16px;
  right: 16px;
  bottom: 18px;
  color: #ffffff;
  font-family: var(--font-serif);
  font-size: 18px;
  letter-spacing: 0.3px;
  line-height: 1.3;
  z-index: 3;
  text-shadow: 0 2px 8px rgba(0, 0, 0, 0.5);
  pointer-events: none;
}

/* ============================================================
   IN-CARD GALLERY (grid-gallery.js)
   ============================================================
   Each tile with > 1 image gets a row of dots at the bottom and
   subtle ‹ › arrows on the sides (visible on hover, on phone
   they're always visible since there's no hover). */
.grid-gallery__dots {
  position: absolute;
  /* Sit above the title-overlay (which ends at bottom: 18 + line height) */
  bottom: 56px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  gap: 6px;
  z-index: 4;
  pointer-events: auto;
}
.grid-gallery__dot {
  width: 7px;
  height: 7px;
  padding: 0;
  border: none;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.55);
  cursor: pointer;
  transition: background 180ms var(--ease), width 220ms var(--ease);
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
}
.grid-gallery__dot[data-active="true"] {
  background: #ffffff;
  width: 22px;
  border-radius: 4px;
}
.grid-gallery__dot:hover { background: rgba(255, 255, 255, 0.85); }

.grid-gallery__arrow {
  position: absolute;
  top: 42%;
  width: 34px;
  height: 34px;
  padding: 0;
  border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, 0.5);
  background: rgba(20, 20, 20, 0.45);
  color: #ffffff;
  cursor: pointer;
  display: grid;
  place-items: center;
  z-index: 4;
  opacity: 0;                     /* hidden until card-hover or touch */
  transform: translateY(-50%);
  transition: opacity 180ms var(--ease), background 160ms var(--ease);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
}
.grid-gallery__arrow--prev { left: 8px; }
.grid-gallery__arrow--next { right: 8px; }
body[data-layout="grid"] .card-frame:hover .grid-gallery__arrow {
  opacity: 1;
}
.grid-gallery__arrow:hover {
  background: rgba(0, 0, 0, 0.65);
}
/* On touch devices (no hover), keep them faintly visible so users
   discover the gallery exists without needing a hover hint. */
@media (hover: none) {
  .grid-gallery__arrow { opacity: 0.7; }
}

/* ============================================================
   LAYOUT TOGGLE — light glassmorphism, right-side under tagline
   ============================================================
   The user's request:
     - Right side, under the "Keine Schnittblumen" philosophy lines
     - Light, modern glass effect (no opaque white pill)
     - No solid black active state — use a subtle gold/cream tint
       that fits the luxury brand palette instead.
   The tagline (`.brand-tagline`) sits fixed at top: 96px right: 80px
   with up to ~4 lines of 20-26 px serif italic, so we anchor the
   switch around top: 260 px — leaves a generous gap, never overlaps. */
/* Single-button compact pill — shows the OPPOSITE mode (the action,
   not the state).  Sits right under the "Keine Schnittblumen" tagline
   on desktop, same right alignment.  Hidden on mobile because the
   hamburger menu already exposes the toggle.

   Visual: refined warm-white glass pill with a thin gold ring,
   gentle drop shadow and a soft gold glow on hover.  Aligns with the
   brand-tagline typography family. */
.layout-switch {
  position: fixed;
  /* Sits BELOW the 4-line brand-tagline (Unikat / Home Couture / ...
     / Keine Schnittblumen).  Tagline top = 96 px, height ≈ 130 px →
     bottom ≈ 226 px.  We anchor the switch a touch lower so the line
     "Keine Schnittblumen" and the pill never share a row. */
  top: 252px;
  right: 80px;
  z-index: 50;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 10px 18px;
  cursor: pointer;
  appearance: none;
  border: 1px solid rgba(180, 140, 74, 0.32);
  border-radius: 999px;
  background: linear-gradient(180deg,
    rgba(255, 252, 245, 0.92) 0%,
    rgba(248, 240, 224, 0.88) 100%);
  font-family: var(--font-sans, Inter, sans-serif);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 2.4px;
  text-transform: uppercase;
  color: var(--gold-deep, #8a6a2a);
  -webkit-backdrop-filter: blur(18px) saturate(140%);
  backdrop-filter: blur(18px) saturate(140%);
  box-shadow:
    0 14px 32px -14px rgba(180, 140, 74, 0.32),
    0 2px 6px -2px rgba(22, 22, 22, 0.10),
    inset 0 1px 0 rgba(255, 255, 255, 0.85);
  transition: transform 200ms var(--ease), box-shadow 220ms var(--ease),
              background 220ms var(--ease), color 220ms var(--ease);
}
.layout-switch:hover {
  transform: translateY(-1px);
  background: linear-gradient(180deg,
    rgba(244, 224, 180, 0.94) 0%,
    rgba(228, 196, 138, 0.92) 100%);
  color: #2a1d09;
  box-shadow:
    0 18px 36px -14px rgba(180, 140, 74, 0.55),
    inset 0 1px 0 rgba(255, 255, 255, 0.95);
}
.layout-switch:active { transform: translateY(0); }

.layout-switch__option {
  display: none;
  align-items: center;
  gap: 8px;
}
/* Show ONLY the option that matches the OPPOSITE mode — body's
   [data-when-layout] convention is "show this when body.layout === X". */
body[data-layout="cinema"] .layout-switch__option[data-when-layout="cinema"] { display: inline-flex; }
body[data-layout="grid"]   .layout-switch__option[data-when-layout="grid"]   { display: inline-flex; }

.layout-switch__option svg {
  display: block;
  stroke: currentColor;
  opacity: 0.88;
}

/* Tablet (max 900) — tagline is hidden by style.css, so we float
   the pill in the upper-right corner instead.  Same visual identity
   as desktop but compact + sized for thumb tap. */
@media (max-width: 900px) {
  .layout-switch {
    top: 86px;          /* clears the nav (top: 16px + ~50px tall) */
    right: 16px;
    padding: 9px 14px;
    font-size: 10px;
    letter-spacing: 1.8px;
    gap: 6px;
  }
  .layout-switch__option svg { width: 12px; height: 12px; }
}
/* Phone (max 600) — even more compact, sits just under the nav. */
@media (max-width: 600px) {
  .layout-switch {
    top: 78px;
    right: 12px;
    padding: 8px 12px;
    font-size: 9px;
    letter-spacing: 1.5px;
  }
  .layout-switch__option svg { width: 11px; height: 11px; }
}

/* Hide the small icon-only toggle in the nav cluster — the new
   pill above is the user-facing control.  Keep the icon hidden but
   still in the DOM so any old click handlers / accessibility tools
   referring to #layout-toggle don't break. */
.nav__icon--layout {
  display: none !important;
}

/* ============================================================
   LAYOUT_LOCK 2026-05-30 — site is locked to grid (Galerie) mode.
   ============================================================
   Per user request the cinema (Vollbild) mode is no longer offered
   as a user choice.  All three toggle surfaces are hidden:
     • #layout-switch       — the central pill above the cards
     • #layout-toggle       — the nav-icon (already hidden above)
     • #mobile-layout-toggle — the entry inside the hamburger drawer
   Code for both modes is retained for possible future re-enabling
   (see LAYOUT_LOCK flag in /js/layout.js).  To revive the toggle,
   set LAYOUT_LOCK = false there AND delete this block. */
#layout-switch,
.layout-switch,
#mobile-layout-toggle {
  display: none !important;
}
/* The "Ansicht" section heading inside the mobile-menu becomes empty
   once the toggle is hidden — hide the section too so we don't ship
   an orphan "Ansicht" label with nothing under it. */
.mobile-menu__section:has(#mobile-layout-toggle) {
  display: none !important;
}

/* "MwSt." note positioned a row below price (still pseudo-element). */
body[data-layout="grid"] .card-frame::before {
  content: 'inkl. MwSt.';
  position: absolute;
  left: 16px;
  bottom: 4px;
  color: rgba(255, 255, 255, 0.8);
  font-family: var(--font-sans);
  font-size: 10px;
  letter-spacing: 0.5px;
  z-index: 3;
  text-shadow: 0 1px 4px rgba(0, 0, 0, 0.4);
  pointer-events: none;
}

/* ============================================================
   GRID — expandable detail strip (full-row width, slides down)
   ============================================================ */
/* The detail container is generated by app.js per row.  When a card
   is in "expanded" state we attach data-grid-expanded="true" to its
   .card-frame, which surfaces the matching `.grid-detail` row below
   that grid line. */
.grid-detail {
  display: none;
  grid-column: 1 / -1;
  background: #fff;
  /* Replaced solid border with inset box-shadow so the gold edge
     doesn't inflate the element's border-box and overflow the grid
     track (was a 4-px right-side bleed on tight viewports). */
  border-radius: 18px;
  box-shadow:
    inset 0 0 0 2px var(--gold, #b58e4c),
    0 24px 60px -18px rgba(181, 142, 76, 0.35),
    0 0 0 1px rgba(181, 142, 76, 0.12);
  overflow: hidden;
  position: relative;
  /* Layout-safety: ALWAYS stay within the parent grid track no
     matter what.  Without these, a long German product name or a
     wide image could push the right edge past the viewport. */
  box-sizing: border-box;
  width: 100%;
  max-width: 100%;
  min-width: 0;
}
body[data-layout="grid"] .grid-detail[data-open="true"] {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 0;
  animation: gridDetailIn 320ms var(--ease);
}
@keyframes gridDetailIn {
  from { opacity: 0; transform: translateY(-12px); max-height: 0; }
  to   { opacity: 1; transform: translateY(0);    max-height: 1200px; }
}
/* Wrapper holds the photo + gallery controls (arrows + dots).
   The wrapper carries the aspect-ratio so the grid track gets a
   predictable size; the inner .grid-detail__media absolutely fills
   the wrapper so the background-image scales naturally. */
.grid-detail__media-wrap {
  position: relative;
  background: #ffffff;
  aspect-ratio: 1 / 1;
  min-width: 0;
  width: 100%;
  max-width: 100%;
  box-sizing: border-box;
  overflow: hidden;
  /* Allow both axes so finger-swipe can flip slides AND the user can
     still scroll the page vertically by starting on this photo.  The
     JS in grid-detail.js axis-locks on the first ~8 px of movement
     so the wrong axis never gets stolen. */
  touch-action: pan-x pan-y;
  -webkit-user-select: none;
  user-select: none;
}
.grid-detail__media {
  /* `contain` — show the WHOLE bouquet image, never cropped.  Photos
     were getting clipped on the sides with `cover`; user explicitly
     asked for non-cropped images here.  White background matches the
     studio shot so any letterboxing reads as a single canvas. */
  position: absolute;
  inset: 0;
  background-color: #ffffff;
  background-size: contain;
  background-position: center;
  background-repeat: no-repeat;
  transition: background-image 220ms var(--ease);
}

/* ===== Gallery controls inside the detail row ===== */
.grid-detail__arrow {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 42px;
  height: 42px;
  padding: 0;
  border-radius: 50%;
  border: 1px solid rgba(22, 22, 22, 0.10);
  background: rgba(255, 255, 255, 0.85);
  color: var(--color-text, #1a1a1a);
  cursor: pointer;
  display: grid;
  place-items: center;
  z-index: 4;
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  box-shadow: 0 6px 18px -10px rgba(22, 22, 22, 0.25);
  transition: background 180ms var(--ease), transform 200ms var(--ease);
}
.grid-detail__arrow:hover {
  background: rgba(255, 255, 255, 1);
  transform: translateY(-50%) scale(1.06);
}
.grid-detail__arrow--prev { left: 14px; }
.grid-detail__arrow--next { right: 14px; }
.grid-detail__arrow svg { display: block; }

.grid-detail__dots {
  position: absolute;
  bottom: 16px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  gap: 7px;
  z-index: 4;
  padding: 6px 10px;
  background: rgba(255, 255, 255, 0.6);
  border-radius: 999px;
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  box-shadow: 0 4px 14px -8px rgba(22, 22, 22, 0.2);
}
.grid-detail__dot {
  width: 8px;
  height: 8px;
  padding: 0;
  border: none;
  border-radius: 50%;
  background: rgba(22, 22, 22, 0.22);
  cursor: pointer;
  transition: background 180ms var(--ease), width 220ms var(--ease);
}
.grid-detail__dot[data-active="true"] {
  background: var(--gold-deep, #8a6a2a);
  width: 22px;
  border-radius: 5px;
}
.grid-detail__dot:hover { background: rgba(22, 22, 22, 0.4); }
.grid-detail__body {
  padding: 32px 36px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 14px;
  min-width: 0;
  max-width: 100%;
  box-sizing: border-box;
  /* Long German compound words (e.g. "Persönliche Anfertigung") would
     otherwise push the column wider than its grid track. */
  overflow-wrap: break-word;
  word-wrap: break-word;
}
.grid-detail__eyebrow {
  font-size: 10px;
  letter-spacing: 3px;
  text-transform: uppercase;
  color: var(--gold-deep, #8a6a2a);
  font-weight: 600;
  margin: 0;
}
.grid-detail__title {
  font-family: var(--font-serif);
  font-size: clamp(22px, 2.4vw, 32px);
  font-weight: 500;
  margin: 0;
  line-height: 1.15;
  overflow-wrap: break-word;
  word-wrap: break-word;
  hyphens: auto;
  max-width: 100%;
}
.grid-detail__price {
  font-family: var(--font-serif);
  font-size: clamp(18px, 1.8vw, 24px);
  margin: 0;
  overflow-wrap: break-word;
}
.grid-detail__price small {
  font-family: var(--font-sans);
  font-size: 10px;
  color: var(--color-muted, #8a8a8a);
  margin-left: 8px;
  letter-spacing: 0.5px;
  vertical-align: 4px;
}
.grid-detail__story {
  font-size: 15px;
  line-height: 1.6;
  color: var(--color-text-soft, #4a4a4a);
  margin: 0;
  overflow-wrap: break-word;
  word-wrap: break-word;
  max-width: 100%;
}
.grid-detail__cta {
  display: flex;
  flex-wrap: wrap;        /* lets buttons stack on narrow widths instead of overflowing */
  gap: 10px;
  margin-top: 10px;
  max-width: 100%;
}
/* PRIMARY CTA — "Vorab sichern" / "Buy".
   Per user feedback: stripped back to the most minimalist statement
   we can give it — white fill, gold hairline outline, jet-black text.
   No tonal fills, no warm sepia, no soft shadows.  The brand-gold
   outline is the only decorative element, just enough to register
   as the primary action without shouting. */
.grid-detail__cta button {
  flex: 1 1 140px;        /* min basis so buttons can wrap rather than overflow */
  min-width: 0;
  max-width: 100%;
  height: 46px;
  padding: 0 18px;
  border-radius: 999px;
  border: 1.5px solid var(--la-gold, #b48c4a);
  background: #ffffff;
  color: #161616;
  font-family: var(--font-sans, Inter, sans-serif);
  font-size: 11px;
  letter-spacing: 2.2px;
  text-transform: uppercase;
  font-weight: 600;
  cursor: pointer;
  transition: background 220ms var(--ease), color 220ms var(--ease),
              border-color 220ms var(--ease), transform 160ms ease;
  box-sizing: border-box;
  white-space: normal;
  -webkit-tap-highlight-color: transparent;
}
.grid-detail__cta button:hover {
  /* On hover the white fill inverts to gold — the only "movement"
     the button makes.  Keeps the minimalist outline language. */
  background: var(--la-gold, #b48c4a);
  border-color: var(--la-gold, #b48c4a);
  color: #ffffff;
}
.grid-detail__cta button:active {
  transform: translateY(1px);
}

/* SECONDARY CTA — "Bei Eröffnung benachrichtigen" / "Add to cart".
   Quiet companion to the primary: same shape, same minimalist
   language, but with a thin sand-grey outline so it visually
   recedes next to the gold-outlined primary.  Both share the same
   white-fill / dark-text base — they read as a matched pair. */
.grid-detail__cta button.btn--ghost {
  background: #ffffff;
  border: 1px solid rgba(22, 22, 22, 0.22);
  color: #161616;
}
.grid-detail__cta button.btn--ghost:hover {
  /* Subtle warm tint on hover, no fill swap — keeps the hierarchy
     where gold-on-hover is reserved for the primary action. */
  background: #f8f2ea;
  border-color: rgba(22, 22, 22, 0.45);
  color: #161616;
}
.grid-detail__close {
  position: absolute;
  top: 12px; right: 12px;
  width: 32px; height: 32px;
  border-radius: 50%;
  border: 1px solid rgba(22, 22, 22, 0.10);
  background: #fff;
  cursor: pointer;
  display: grid; place-items: center;
  z-index: 4;
  transition: background 160ms var(--ease);
}
.grid-detail__close:hover { background: rgba(22, 22, 22, 0.05); }

/* Tablet — 2 columns */
@media (max-width: 1000px) {
  body[data-layout="grid"] main#cards {
    grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
    padding: 130px 18px 50px;
    gap: 16px;
    /* Slightly smaller scrollbar reservation on tablets that
       still use overlay scrollbars. */
    width: min(1100px, calc(100vw - 14px)) !important;
    max-width: min(1100px, calc(100vw - 14px)) !important;
  }
  /* Detail row stays 2-col side-by-side on tablet — image left, body
     right.  Single-column would waste a lot of vertical scroll. */
  body[data-layout="grid"] .grid-detail[data-open="true"] {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
  }
  .grid-detail__media-wrap { aspect-ratio: 4 / 5; }
  .grid-detail__body { padding: 24px 26px; gap: 12px; }
  .grid-detail__title { font-size: clamp(20px, 3.2vw, 26px); }
}

/* Phone — 1 column, compact stacked detail.  Image is a short banner
   (3:2 landscape) so it doesn't dominate the screen and the body
   content sits visible without scrolling. */
@media (max-width: 600px) {
  body[data-layout="grid"] main#cards {
    grid-template-columns: minmax(0, 1fr) !important;
    /* Tighter horizontal padding on phones — every pixel counts on a
       375-px viewport.  12 px each side leaves the full content area
       for the card without ever brushing the right edge.
       Mobile browsers usually use overlay scrollbars, so we don't
       subtract the gutter — just stay strictly within 100vw. */
    width: 100vw !important;
    max-width: 100vw !important;
    padding: 120px 12px 40px;
    gap: 14px;
  }
  body[data-layout="grid"] .card {
    aspect-ratio: 4 / 5;
  }
  body[data-layout="grid"] .card-frame::after {
    font-size: 16px;
    left: 14px;
    right: 14px;
  }
  body[data-layout="grid"] .card-frame::before {
    left: 14px;
  }
  body[data-layout="grid"] .grid-detail[data-open="true"] {
    grid-template-columns: minmax(0, 1fr);       /* stack vertically on phone */
  }
  .grid-detail__media-wrap { aspect-ratio: 3 / 2; }
  /* Smaller arrows + dots on phone — give thumb room without
     covering too much of the actual photo. */
  .grid-detail__arrow { width: 36px; height: 36px; }
  .grid-detail__arrow--prev { left: 8px; }
  .grid-detail__arrow--next { right: 8px; }
  .grid-detail__dots { bottom: 10px; padding: 5px 8px; }
  .grid-detail__dot { width: 7px; height: 7px; }
  .grid-detail__dot[data-active="true"] { width: 18px; }
  .grid-detail__body {
    padding: 18px 18px 22px;
    gap: 10px;
  }
  .grid-detail__title { font-size: 22px; line-height: 1.2; }
  .grid-detail__price { font-size: 19px; }
  .grid-detail__story { font-size: 14px; }
  .grid-detail__close { top: 8px; right: 8px; }
  .grid-detail__cta { flex-direction: column; gap: 8px; margin-top: 12px; }
  .grid-detail__cta button {
    flex: 1 1 auto;
    width: 100%;
    height: 46px;
    font-size: 12px;
    letter-spacing: 1.8px;       /* a bit tighter so longer labels fit */
  }
  /* Mobile connector arrow — slightly smaller. */
  body[data-layout="grid"] .card-frame[data-grid-expanded]::before {
    border-left-width: 10px;
    border-right-width: 10px;
    border-top-width: 10px;
    bottom: -10px;
  }
}

/* Extra-small phones (≤380 px, e.g. iPhone SE) — squeeze further. */
@media (max-width: 380px) {
  body[data-layout="grid"] main#cards {
    padding: 116px 10px 32px;
    gap: 12px;
  }
  .grid-detail__body { padding: 16px 14px 20px; }
  .grid-detail__title { font-size: 20px; }
  .grid-detail__price { font-size: 18px; }
  .grid-detail__cta button { letter-spacing: 1.4px; font-size: 11px; }
}

/* ============================================================
   Hide the brand-essay + footer's snap-section behavior in grid mode
   (they're now just normal blocks at the bottom of a scrolling page).
   ============================================================ */
body[data-layout="grid"] .scroll-snap-section,
body[data-layout="grid"] .brand-essay,
body[data-layout="grid"] .footer {
  scroll-snap-align: none;
}
