/* ==========================================================================
   GRAPE ZOO redesign — isolated stylesheet (task #12)
   Scoped under .gz to avoid touching the legacy frontend styles.
   Mobile-first; desktop rules are sensible defaults pending the desktop Figma.
   Colours are read off the Figma mobile mockups — tweak when the design
   tokens are confirmed.
   ========================================================================== */

/* Elza — already licensed & shipped in the project (public/fonts).
   Only two cuts available: Text Regular + Condensed Bold. If the design uses
   another Elza weight/width, drop its .woff2 in and add a @font-face here. */
@font-face {
  font-family: "Elza Text";
  src: url("/fonts/Elza_Text_Regular.woff") format("woff");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Elza Condensed";
  src: url("/fonts/Elza_Condensed_Bold.woff") format("woff");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

html { overflow-x: hidden; }   /* no horizontal scroll from the swirl side-bleed */

.gz {
  /* Official GRAPE ZOO palette (grape zoo_color chart.pdf) — do not eyeball,
     use these tokens everywhere. */
  --gz-white:   #FFFFFF;
  --gz-black:   #000000;
  --gz-grey:    #A7A9AC;
  --gz-blue:    #7482FF;
  --gz-violet:  #CE72FF;
  --gz-magenta: #FF00B7;
  --gz-pink:    #FAA6FF;   /* header bar, pill buttons, light section bg   */
  --gz-salmon:  #FF9469;
  --gz-orange:  #FF6325;   /* “Kúpiť lístok” CTA                          */
  --gz-yellow:  #F7FF6B;
  --gz-lime:    #D8FF9D;
  --gz-ice:     #DAF2F3;
  --gz-teal:    #56CBCD;
  --gz-green:   #00FF48;

  --gz-ink:     var(--gz-black);
  --gz-paper:   var(--gz-white);

  --gz-header-h: 64px;
  --gz-marquee-h: 58px;      /* real marquee height (padding 4+4 + line-height 50). Feeds the hero
                                offset fallback below; the header partial sets it to 0px when the
                                marquee is empty/hidden so the homepage hero doesn't shift pre-JS. */

  /* Adobe Typekit "elza-condensed" (kit wat5xeg; weights 500/600/700) is the real
     face; local Elza woff is a fallback for dev/offline (Typekit is domain-locked). */
  --gz-font:    "elza-condensed", "Elza Condensed", "Helvetica Neue", Arial, sans-serif;
  --gz-display: "elza-condensed", "Elza Condensed", "Arial Black", sans-serif;

  margin: 0;                 /* kill UA body margin → header edge-to-edge, flush to top */
  font-family: var(--gz-font);
  color: var(--gz-ink);
  background: var(--gz-paper);
  -webkit-font-smoothing: antialiased;
}

.gz *,
.gz *::before,
.gz *::after { box-sizing: border-box; }

.gz img { max-width: 100%; display: block; }

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

/* beat the legacy "p, a, span { font-family: Poppins; font-size: 16px }" so
   .gz text (brand suffix, footer links, …) keeps the inherited Elza font */
.gz p, .gz a, .gz span { font-family: inherit; }

/* --- utilities ----------------------------------------------------------- */
.gz-pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: 60px;              /* per spec */
  font-family: var(--gz-display);   /* Elza Condensed Bold */
  font-weight: 700;
  cursor: pointer;
}

/* Header height (brand line-height + 8px vertical padding) — deterministic, so we
   hardcode it per breakpoint. #k-head reserves it as padding-top and the flyout drops
   from it. Set here so the FIRST paint already matches the pinned header height (no
   layout shift); grape-zoo.js then overrides --gz-header-real-h with the exact measured
   value (identical to these, but self-correcting if the brand size ever changes).
   Keep in sync with .gz-brand line-height (58 = brand lh 50 + 8; 46 for the 900–1000
   laptop band where the brand shrinks to lh 38 — see that media query below). */
:root { --gz-header-real-h: 58px; }

/* ==========================================================================
   HEADER  (brand toggle + hamburger + EN)
   ========================================================================== */
.gz-header {
  position: fixed;           /* pinned (client change): stays visible while the page scrolls.
                                Safe here — no transformed ancestor captures it (body/.superheader/
                                #k-head have no transform/will-change), unlike the CTA deep in #k-body.
                                Its height is reserved as #k-head padding-top (measured, see JS). */
  top: 0;
  left: 0;
  right: 0;
  z-index: 52;               /* above the marquee (50, relative) so the marquee scrolls UNDER it;
                                below the flying animals (60) and mobile menu (100) */
  background: var(--gz-pink);
  display: flex;
  align-items: center;       /* menu items vertically centered */
  gap: 12px;
  padding: 4px 16px;         /* per spec */
}

.gz-brand {
  font-family: var(--gz-display);   /* Elza Condensed Bold */
  font-weight: 700;
  font-size: 42px;
  line-height: 50px;
  letter-spacing: -0.01em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  flex: 1 1 auto;
  min-width: 0;
}
/* only the suffix animates: "Grape" stays static, "Festival" ⇄ "ZOOOOO" */
.gz-brand .gz-brand-swap {
  display: inline-block;
  font-size: inherit;        /* beat legacy p,a,span { font-size:16px } */
  line-height: inherit;
  transition: opacity 240ms ease, transform 240ms ease;
}
.gz-brand .gz-brand-swap.is-swapping {
  opacity: 0;
  transform: translateY(-6px);
}

/* desktop horizontal nav — hidden on mobile (hamburger instead) */
.gz-nav {
  display: none;
  gap: 48px;                 /* per spec */
  align-items: center;
}
.gz-nav a,
.gz-nav__toggle {
  font-family: var(--gz-display);   /* Elza Condensed Bold */
  font-size: 32px;           /* per spec */
  line-height: 38px;
  font-weight: 700;
  letter-spacing: 0.01em;
  text-transform: uppercase;   /* labels come from the CMS in mixed case */
  white-space: nowrap;
}
/* LINE-UP / INFO are <button> toggles — strip the native button chrome so they
   read exactly like the <a> nav items. */
.gz-nav__toggle {
  background: none;
  border: 0;
  margin: 0;
  padding: 0;
  color: inherit;
  cursor: pointer;
}
.gz-nav a:hover,
.gz-nav__toggle:hover,
.gz-menu__nav a:hover { text-decoration: underline; }
/* while its flyout is open the parent stays underlined (per design) */
.gz-nav__toggle.is-open { text-decoration: underline; }
/* no focus box on click; keep a visible ring for keyboard users only (a11y) */
.gz-nav__toggle:focus,
.gz-menu__toggle:focus { outline: none; }
.gz-nav__toggle:focus-visible,
.gz-menu__toggle:focus-visible { outline: 2px solid currentColor; outline-offset: 3px; }

/* header language switch (EN/SK): a .gz-nav child, so it inherits the nav item
   typography (32/38 uppercase), the nav gap (48px) and the hover underline. Per client
   feedback it matches the MENU ITEMS — it briefly used the larger site-title type
   (42/50) but that was reverted, so there is intentionally no size override here.
   Hidden with the nav on mobile; the mobile switch is the untouched .gz-menu__lang. */

.gz-burger {
  width: 49px;
  height: 31px;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  flex: 0 0 auto;
  color: var(--gz-ink);        /* the inline SVG bars use currentColor */
}
.gz-burger svg { display: block; width: 100%; height: 100%; }

/* ==========================================================================
   MARQUEE  (date + location scrolling strip, under the header)
   ========================================================================== */
.gz-marquee {
  overflow: hidden;
  display: flex;
  align-items: center;
  background: var(--gz-paper);
  padding: 4px 0 4px 16px;   /* 4px top/bottom + 50px line-height = 58px, matching the header
                                exactly (same 4/4 + lh 50 formula, no border) */
}
.gz-marquee__track {
  display: inline-flex;
  gap: 17px;                 /* per spec */
  white-space: nowrap;
  will-change: transform;
  animation: gz-marquee 60s linear infinite;   /* 20 copies (was 6 @ 18s) → ×20/6 keeps the same px/s */
  animation-play-state: paused;   /* STATIC by default (no motion on first paint) — JS adds
                                     .is-scrolling only when the line overflows the strip. Pausing
                                     (not disabling) keeps the mobile animation-duration override live. */
}
/* Default (static) view — what paints BEFORE the JS runs, so a fitting line never flashes into
   motion: a single copy, left-aligned within the padding, trailing bullet separator dropped. */
.gz-marquee__track > span:not(:first-child) { display: none; }
.gz-marquee__sep { display: none; }
.gz-marquee__track span {
  font-family: var(--gz-display);   /* Elza Condensed Bold */
  font-size: 42px;           /* per spec */
  line-height: 50px;
  font-weight: 700;
}
@keyframes gz-marquee {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}
@media (prefers-reduced-motion: reduce) {
  .gz-marquee__track { animation: none; }
}
/* initMarquee() adds .is-scrolling ONLY when a single line is wider than the strip: the
   animation resumes and every copy + bullet is revealed so the loop is seamless. It flips
   play-state only, so the base + mobile animation-duration (speed) still apply per breakpoint. */
.gz-marquee.is-scrolling .gz-marquee__track { animation-play-state: running; }
.gz-marquee.is-scrolling .gz-marquee__track > span { display: inline; }
.gz-marquee.is-scrolling .gz-marquee__sep { display: inline; }

/* ==========================================================================
   SECTION FLYOUT  (desktop click-to-reveal blue bar, under the header)
   Opened by the LINE-UP / INFO nav toggles; shows that section's children.
   Fixed dropdown that slides down from under the pinned header and overlays the
   content below (so it works at any scroll position). Closes on click-outside,
   ESC, or another toggle. Distinct from the white on-page strip below.
   ========================================================================== */
.gz-flyout {
  max-height: 0;                         /* collapsed; slides open via .is-open */
  overflow: hidden;
  position: fixed;                       /* drops down from under the now-pinned header */
  top: var(--gz-header-real-h);          /* sits right below the fixed header (see :root default + JS) */
  left: 0;
  right: 0;
  z-index: 51;                           /* above the marquee (50), just under the header (52) */
  transition: max-height 220ms ease;     /* short slide-out */
}
.gz-flyout.is-open { max-height: 120px; }   /* > one row of children; caps the slide */
.gz-flyout__panel[hidden] { display: none; }
/* bg lives on the inner row so the collapsed wrapper shows nothing */
.gz-flyout__inner {
  background: #5365FF;                    /* client submenu blue (same as footer bg) */
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;             /* right-aligned default */
  align-items: center;
  gap: 6px 65px;                         /* 65px between items (per spec) */
  padding: 10px 16px;                    /* 10px top/bottom + 38px link line-height = 58px — same
                                            height as the marquee, so the open flyout covers it fully */
  padding-right: var(--gz-flyout-pad-r, 16px);   /* centerPanel() (grape-zoo.js) centres the row under
                                                    its parent toggle when it fits; 16px = flush-right
                                                    default (also the no-JS value) */
}
@media (prefers-reduced-motion: reduce) {
  .gz-flyout { transition: none; }
}
.gz-flyout .gz-flyout__link {            /* same as main nav, just white (0,2,0 beats ".gz a{color:inherit}") */
  font-family: var(--gz-display);
  font-weight: 700;
  font-size: 32px;
  line-height: 38px;
  letter-spacing: 0.01em;
  color: var(--gz-white);
  text-transform: uppercase;             /* data stays mixed-case in the CMS */
  white-space: nowrap;
}
.gz-flyout .gz-flyout__link:hover,
.gz-flyout .gz-flyout__link.is-active { text-decoration: underline; }

/* ==========================================================================
   SECTION SUBMENU  (the white on-page strip — restored from the pre-redesign
   site, git d44a76f). Persists on section pages via $sub_menu. "• TEXT •" pills;
   the active sibling gets an oval outline (per the client design, screenshot 4).
   Desktop-only strip; on mobile the same siblings live in the menu accordion.
   ========================================================================== */
.gz-subnav {
  display: block;                        /* shown on ALL breakpoints (mobile had it in the original design too) */
  background: var(--gz-paper);
}
.gz-subnav__inner {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;               /* centred group per design; wraps on narrow mobile */
  align-items: center;
  gap: 8px 20px;
  padding: 10px 16px;
}
.gz-subnav__link {
  display: inline-flex;
  align-items: center;
  font-family: var(--gz-display);
  font-weight: 700;
  font-size: 22px;
  line-height: 1.1;
  color: var(--gz-ink);
  text-transform: uppercase;
  white-space: nowrap;
  border: 2px solid transparent;         /* reserved so the active pill doesn't shift layout */
  border-radius: 60px;
  padding: 4px 14px;
}
/* "• TEXT •" — bullets flank every item */
.gz-subnav__link::before { content: "•"; margin-right: .5em; }
.gz-subnav__link::after  { content: "•"; margin-left: .5em; }
.gz-subnav__link:hover span { text-decoration: underline; }
.gz-subnav__link.is-active { border-color: var(--gz-ink); }   /* active = oval outline */

/* ==========================================================================
   HERO  (video bg + cycling logo overlay + floating CTAs)
   ========================================================================== */
.gz-hero {
  position: relative;
  z-index: 3;              /* the swirl can bleed below the hero and paint over the next section */
  background: #111;
}
.gz-hero__media {
  position: absolute;
  inset: 0;
  z-index: 0;
}
.gz-hero__video {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.gz-hero__inner {
  position: relative;
  z-index: 2;
  /* fill the viewport BELOW the header + marquee so the video bottom sits at the
     screen bottom on load. --gz-hero-offset (= header + marquee height) is set by
     initHeroHeight() in grape-zoo.js; the pre-JS fallback is derived from the two
     component vars (header-real-h + marquee-h) so it matches the measured value in
     BOTH states — full when the marquee shows, and header-only when it's hidden
     (the header partial then sets --gz-marquee-h:0), avoiding a first-paint jump.
     vh = fallback for pre-2022 browsers (there vh == the large viewport too, so
     behaviour stays consistent). lvh override = the STATIC large viewport (URL bar
     retracted). We deliberately avoid dvh here: dvh tracks the visible viewport, so
     as the mobile URL bar hides on scroll the hero would continuously resize and
     jump/reflow (reported on iPhone). lvh never changes on scroll → no jump. On
     load with the bar visible the video is a touch taller than the visible area, so
     its bottom sliver sits behind the bar — invisible because the video is
     object-fit:cover, and the CTA is position:fixed so it tracks the visible
     bottom in both states. */
  min-height: calc(100vh - var(--gz-hero-offset, calc(var(--gz-header-real-h) + var(--gz-marquee-h))));
  min-height: calc(100lvh - var(--gz-hero-offset, calc(var(--gz-header-real-h) + var(--gz-marquee-h))));
  display: flex;
  flex-direction: column;
  align-items: flex-start;   /* mobile: logo pinned top-left */
  padding: 16px 16px 28px;   /* mobile: logo 16px from the top & left edge */
}

/* hero logo — the designer's 3 gradient-sticker SVGs; JS picks one at random
   per page load (see initLogoVersion). The 3 variants have differing intrinsic
   widths (355/163/325px), so we FIX the rendered width per breakpoint to keep
   them uniform regardless of which one is drawn: 172px mobile, 354px desktop
   (the latter in the ≥900px block). Pinned top-left by the inner padding +
   align-items. SVG so it scales without quality loss. */
.gz-logo {
  width: 172px;                    /* mobile: fixed design width */
  height: auto;                    /* keep each variant's own aspect ratio */
  max-width: 100%;                 /* never exceed the padded inner box */
  /* NO CSS filter: a drop-shadow here promotes the <img> to a GPU layer that mobile
     browsers (esp. iOS Safari) rasterize below device-pixel-ratio → the SVG looks
     pixelated on mobile (crisp on desktop). Dropping it lets the SVG decode at DPR. */
}

.gz-hero__cta {              /* pinned to the viewport bottom from the start; stays pinned
                                over content as you scroll (no JS slide). Shown site-wide —
                                grape-zoo.js reparents it to a body-level .gz. */
  position: fixed;
  left: 16px;        /* mobile: 16px side gutters (buttons flex-fill to these edges) */
  right: 16px;
  bottom: 8px;       /* 8px above the viewport bottom */
  z-index: 40;       /* above content, below header (50); sits above the swirl */
  display: flex;
  gap: 8px;          /* per spec */
  justify-content: center;
  flex-wrap: nowrap;
}
/* the two buttons split the row (16px gutters, 8px gap). white-space:nowrap stops a button
   wrapping to two lines when flex sizes it a hair under its one-line width; nowrap also makes
   each button's min-content its FULL label, so "Kúpiť lístok" holds its width and "Line-up"
   grows to fill the rest. Reset to content-width on desktop. */
.gz-hero__cta > .gz-pill { flex: 1 1 0; white-space: nowrap; }
/* designer's swirl graphic — fixed size, sits *behind* the floating buttons,
   over the video. Mobile version by default; desktop version + right bleed at
   the breakpoint. Sizes are the Figma asset dimensions. */
.gz-hero__deco {              /* pinned with the CTA (108px lower → bleeds off the
                                 viewport bottom); floats over content, no scroll move */
  position: fixed;
  z-index: 39;                /* just behind the floating buttons */
  bottom: -100px;             /* buttons bottom 8 − 108 (moves down with the buttons) */
  left: 50%;
  transform: translateX(-50%);
  width: 462.4921875px;      /* design @375px → bleeds off both sides */
  height: 232.66px;          /* design swirl aspect 462.49:232.66 (same asset as desktop) */
  background: url("/images/grape-zoo/hero-graphics-d.svg") center/contain no-repeat;
  pointer-events: none;
}
/* body-level host for the reparented floating CTA + swirl (see initFloatingCta
   in grape-zoo.js). It must NOT paint the .gz white background — its children
   are position:fixed so it stays zero-height and out of the way. */
.gz-floating-root { background: none; }

/* NB: selectors are .gz-pill.gz-cta-* (0,2,0) so `color` beats `.gz a { color:
   inherit }` (0,1,1) — otherwise the red buy button's white text falls back to
   the inherited black. Hovers carry the same base specificity + :hover. */
.gz-pill.gz-cta-lineup {
  background: var(--gz-pink);        /* #FAA6FF */
  color: var(--gz-ink);
  font-size: 32px;
  line-height: 38px;
  padding: 16px 24px;
}
.gz-pill.gz-cta-buy {
  background: #FF1F1A;               /* per spec (logo red) */
  color: var(--gz-white);           /* white text on the red button */
  font-size: 32px;
  line-height: 38px;
  padding: 16px 24px;
}
.gz-pill.gz-cta-lineup:hover { background: #E07FE6; }   /* hover per spec */
.gz-pill.gz-cta-buy:hover { background: #DE2521; }

/* ==========================================================================
   LINE-UP  (task #13) — headliner names as coloured CSS "stickers".
   Each name is black Elza Condensed with a 6px coloured outline in the artist's
   own colour (--gz-artist-color, set inline per artist from the admin `color`
   field). The outline is a ring of hard text-shadows rather than
   -webkit-text-stroke so the black fill keeps its FULL weight (stroke eats into
   the letters and closes the counters on a condensed bold face). NOT images.
   Figma: 69/49, 11px gap between names, 6px border. Mobile-first; desktop sizing
   is provisional pending the desktop proportional-scaling decision.
   ========================================================================== */
.gz-lineup {
  background: var(--gz-paper);
  padding: 32px 16px 0;        /* line-up starts 32px below the hero video; bottom gap = CTA padding */
  text-align: center;
  overflow: hidden;            /* the 6px halo can bleed sideways on long names */
}
.gz-lineup__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 11px;                   /* per Figma — gap between artists */
}
/* sub-headliners (Super/Normal) render as a second list 64px below the headliners (Mega).
   The two lists are separate blocks in .gz-lineup, so this margin is the exact group gap. */
.gz-lineup__list--sub { margin-top: 64px; }
.gz-lineup__item { max-width: 100%; }
/* wraps the name → artist detail; block so the click target is exactly the name. color:inherit
   keeps the black sticker fill (beats ".gz a{color:inherit}" is already inherit, but explicit). */
.gz-lineup__link { display: block; color: inherit; }

/* "Special Guest" label above the name (toggled per artist in admin) */
.gz-lineup__tag {
  display: block;
  font-family: var(--gz-display);
  font-weight: 700;
  font-size: 24px;
  line-height: 1;
  color: var(--gz-ink);
  margin-bottom: 6px;
}

.gz-lineup__name {
  display: block;
  font-family: var(--gz-display);      /* Elza Condensed Bold */
  font-weight: 700;
  font-size: 69px;                     /* per Figma */
  line-height: 0.84;                   /* per Figma (84%); 69*0.84 ≈ 58px. The old 49px (71%) was
                                          too tight → 2-line names overlapped. Unitless so the ft
                                          suffix (own line-height) is unaffected. */
  letter-spacing: -0.01em;
  color: var(--gz-ink);                /* black fill, full weight */
  --gz-artist-color: var(--gz-pink);   /* overridden inline per artist */
  /* 6px coloured sticker outline (ring of hard shadows, 36 samples @6px) */
  text-shadow:
    6px 0 .6px var(--gz-artist-color), 5.91px 1.04px .6px var(--gz-artist-color),
    5.64px 2.05px .6px var(--gz-artist-color), 5.2px 3px .6px var(--gz-artist-color),
    4.6px 3.86px .6px var(--gz-artist-color), 3.86px 4.6px .6px var(--gz-artist-color),
    3px 5.2px .6px var(--gz-artist-color), 2.05px 5.64px .6px var(--gz-artist-color),
    1.04px 5.91px .6px var(--gz-artist-color), 0 6px .6px var(--gz-artist-color),
    -1.04px 5.91px .6px var(--gz-artist-color), -2.05px 5.64px .6px var(--gz-artist-color),
    -3px 5.2px .6px var(--gz-artist-color), -3.86px 4.6px .6px var(--gz-artist-color),
    -4.6px 3.86px .6px var(--gz-artist-color), -5.2px 3px .6px var(--gz-artist-color),
    -5.64px 2.05px .6px var(--gz-artist-color), -5.91px 1.04px .6px var(--gz-artist-color),
    -6px 0 .6px var(--gz-artist-color), -5.91px -1.04px .6px var(--gz-artist-color),
    -5.64px -2.05px .6px var(--gz-artist-color), -5.2px -3px .6px var(--gz-artist-color),
    -4.6px -3.86px .6px var(--gz-artist-color), -3.86px -4.6px .6px var(--gz-artist-color),
    -3px -5.2px .6px var(--gz-artist-color), -2.05px -5.64px .6px var(--gz-artist-color),
    -1.04px -5.91px .6px var(--gz-artist-color), 0 -6px .6px var(--gz-artist-color),
    1.04px -5.91px .6px var(--gz-artist-color), 2.05px -5.64px .6px var(--gz-artist-color),
    3px -5.2px .6px var(--gz-artist-color), 3.86px -4.6px .6px var(--gz-artist-color),
    4.6px -3.86px .6px var(--gz-artist-color), 5.2px -3px .6px var(--gz-artist-color),
    5.64px -2.05px .6px var(--gz-artist-color), 5.91px -1.04px .6px var(--gz-artist-color);
}
/* smaller inline suffix, e.g. "ft. PHANTOM" (per-artist, editable in admin as
   description → name_suffix). Inherits --gz-artist-color + the text-shadow ring,
   so it keeps the same coloured 6px outline at a smaller size. Figma: 39/28. */
.gz-lineup__ft {
  font-size: 39px;
  line-height: 28px;
  margin-left: .14em;
}

.gz-lineup__cta { padding: 32px 0; text-align: center; }   /* centred; 32px above/below the button */
.gz-pill.gz-lineup__pill {
  background: var(--gz-pink);        /* #FAA6FF */
  color: var(--gz-ink);
  font-size: 32px;
  line-height: 38px;
  padding: 16px 24px;                /* per Figma */
  margin: 32px 0;                    /* per Figma */
  /* border-radius: 60px inherited from .gz-pill */
}
.gz-pill.gz-lineup__pill:hover { background: #E07FE6; }

/* ==========================================================================
   SECTION SCAFFOLD  (line-up / news / newsletter / footer — next increments)
   ========================================================================== */
.gz-section { padding: 40px 16px; }
.gz-section--pink { background: var(--gz-pink); }
.gz-section--purple { background: var(--gz-magenta); color: var(--gz-white); }  /* newsletter */
.gz-section--blue { background: var(--gz-violet); color: var(--gz-ink); }

/* ===== FOOTER ===== */
.gz-footer {
  background: #5365FF;             /* per spec */
  color: var(--gz-white);
  padding: 32px 16px;             /* 16px side gutter — matches header/marquee/sections (was 10px) */
  font-family: var(--gz-display);
}
.gz-footer a { color: inherit; }

/* big nav — mobile: stacked/centred */
.gz-footer__nav {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  margin-bottom: 42px;             /* mobile: down to the smaller links */
}
.gz-footer__nav a { font-size: 64px; line-height: 77px; font-weight: 700; white-space: nowrap; }
.gz-footer__nav a:hover,
.gz-footer__secondary a:hover { text-decoration: underline; }

/* smaller links + social row — mobile: stacked/centred */
.gz-footer__row {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 32px;                       /* mobile: smaller links → icons */
  margin-bottom: 32px;             /* mobile: icons → logo */
}
.gz-footer__secondary {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
}
.gz-footer__secondary a { font-size: 32px; line-height: 38px; font-weight: 700; }

.gz-footer__social { display: flex; gap: 23px; }
.gz-footer__social img { width: 38px; height: 38px; display: block; }

.gz-footer__logo { display: block; width: 100%; }   /* full width */
.gz-footer__logo img { display: block; width: 100%; height: auto; }

@media (min-width: 900px) {
  .gz-footer__nav {
    flex-direction: row;
    justify-content: space-between;   /* spreads items full-width ≈ 110px gaps at 1440 */
    align-items: baseline;
    flex-wrap: nowrap;
    gap: 24px;                        /* min gap; space-between does the spacing */
    margin-bottom: 24px;
  }
  .gz-footer__nav a { font-size: 74px; line-height: 89px; }
  .gz-footer__row {
    flex-direction: row;
    justify-content: space-between;
    align-items: center;
    gap: 24px;
    margin-bottom: 128px;          /* before logo */
  }
  .gz-footer__secondary { flex-direction: row; gap: 64px; }
}
/* narrower desktops: shrink footer nav so it stays on one row (full spec ≥1440) */
@media (min-width: 900px) and (max-width: 1439px) {
  .gz-footer__nav { gap: 40px; }
  .gz-footer__nav a { font-size: 52px; line-height: 62px; }
}

.gz-placeholder {
  border: 3px dashed currentColor;
  border-radius: 18px;
  padding: 28px;
  text-align: center;
  font-size: 16px;
  opacity: .8;
}

/* image carousel — buy-tickets section (lower on the page, NOT the hero).
   Client spec: section bg #FDE0FF, padding 32px 0, desktop image 934px wide.
   Photos crossfade every 1100ms (matches the brand-toggle rhythm), no controls.
   The desktop (1868×858, wide) and mobile (686×858, portrait) crops have
   different aspect ratios, so BOTH the box ratio and the <picture> source
   switch at the 900px breakpoint (see @media below). */
.gz-carousel-section {
  background: #FDE0FF;
  padding: 32px 16px;            /* 16px side gutters on mobile (matches the news section) */
}
.gz-carousel {
  position: relative;
  width: 100%;
  margin: 0 auto;
  border-radius: 22px;
  overflow: hidden;
}
.gz-carousel::before { content: ""; display: block; padding-top: 125.07%; } /* mobile 686×858, no aspect-ratio dep */
.gz-carousel .gz-slide {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity 300ms ease;   /* snappy enough to read clearly at the 1100ms cadence */
}
.gz-carousel .gz-slide.is-active { opacity: 1; }
.gz-carousel .gz-slide picture { display: block; width: 100%; height: 100%; }
.gz-carousel .gz-slide img { width: 100%; height: 100%; object-fit: cover; }
.gz-carousel__cta {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  white-space: nowrap;   /* keep "Kúpiť lístok" on one line — the 32px pill wraps into a blob on narrow mobile otherwise */
  z-index: 2;
}
@media (min-width: 900px) {
  .gz-carousel { max-width: 934px; }
  .gz-carousel::before { padding-top: 45.93%; } /* desktop 1868×858 shown at 934px */
}

/* ==========================================================================
   NEWS  (task #13) — latest homepage news. Each card is a white rounded box
   (16px radius, per client) whose photo fills the top FLUSH — no white inset around
   the image (per client: "no white border, right = zebra, nothing else") — with the
   designer's "zebra" sticker strip down the photo's RIGHT edge only
   (public/images/grape-zoo/zebra.svg) and a bold headline padded below it inside the
   box. Section bg #FDE0FF continues straight on from the carousel above (same pink,
   no seam) with matching 16px side gutters. Mobile = 1 column; desktop = 4 cards
   across the FULL width (per client — not capped like the carousel). The photo box
   uses a padding-top ratio (no aspect-ratio dependency, matching the carousel).
   Cards align to the top so their heights vary with the headline length. Headlines
   are NFKC-normalized in the blade so the client's fancy-unicode titles render in the
   real Elza Condensed face instead of a serif fallback. The "flying animals" overlay
   is a later step (pending client assets — see docs/grape-zoo-redesign.md).
   ========================================================================== */
.gz-news {
  background: #FDE0FF;              /* same pink as the carousel section — they blend */
  padding: 0 16px 40px;            /* 16px side gutters (mobile); the 32px above the heading comes from the carousel's 32px bottom padding */
}
.gz-news__inner { margin: 0 auto; }

.gz-news__title {
  font-family: var(--gz-display);
  font-weight: 700;
  font-size: 42px;                 /* per client: 42/50 */
  line-height: 50px;
  color: var(--gz-ink);
  margin: 0 0 8px;                 /* 8px above the cards */
}

.gz-news__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: 1fr;      /* mobile: stacked */
  align-items: start;              /* cards size to content (ragged bottoms, per design) */
  gap: 16px;                       /* mobile gap */
}

.gz-news__card {
  background: var(--gz-white);       /* white card (cards are not clickable — no <a> wrapper) */
  border-radius: 16px;               /* per client: card radius 16px */
  overflow: hidden;                  /* clip the photo's top corners to the card radius */
}

/* The block is a ~square (343×343 per design); the photo fills all but the rightmost
   11px and the zebra strip fills that 11px BESIDE it (NOT behind — else the rounded
   corners reveal the photo instead of the page). Visible photo ≈ 332×343 (designer
   asset public/images/grape-zoo/zebra.svg). The FIGURE rounds the whole block
   (border-radius 16 + overflow:hidden); because nothing sits behind the zebra, the
   eaten top-right/bottom-right corners show the pink page, cleanly. Photos are all
   the same (square) height; the cards below vary in height with the headline. */
.gz-news__figure {
  position: relative;
  margin: 0;
  border-radius: 16px;
  overflow: hidden;
}
.gz-news__figure::before { content: ""; display: block; padding-top: 100%; }  /* square block (343×343) */
.gz-news__figure img {
  position: absolute;
  top: 0;
  left: 0;
  /* explicit width: <img> is a REPLACED element, so with width:auto the browser uses the
     image's intrinsic width (clamped by .gz img{max-width:100%}) and IGNORES right:11px —
     the photo then fills the whole figure and sits BEHIND the zebra. Force the box instead. */
  width: calc(100% - 11px);            /* leave the 11px zebra strip on the right */
  height: 100%;
  object-fit: cover;
  display: block;
  background: var(--gz-grey);           /* neutral placeholder before the image loads */
}
.gz-news__figure::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  right: 0;
  width: 11px;
  background: url("/images/grape-zoo/zebra.svg?v=zoo3") center / 100% 100% no-repeat;  /* ?v busts the cached old strip; bump when zebra.svg changes */
  pointer-events: none;
}

.gz-news__headline {
  font-family: var(--gz-display);      /* Elza Condensed Bold */
  font-weight: 700;
  font-size: 26px;                     /* per client: 26/31 */
  line-height: 31px;
  color: var(--gz-ink);
  margin: 0;
  padding: 16px;                       /* headline sits inside the white card, below the photo */
}

/* --- expandable card (homepage + /novinky share this) ----------------------
   Click a card → its body (full article text + date) slides open; multiple can
   be open at once (grape-zoo.js initNewsCards, delegated). The card itself looks
   exactly as before — no chevron/affordance — only a click reveals the body. The
   body uses the grid 0fr→1fr collapse trick so it animates to its natural height.
   The --lightbox variant (two special news items) keeps the old fancybox
   behaviour and is NOT expandable. */
.gz-news__figure { display: block; }   /* the lightbox variant's figure is an <a> */
.gz-news__card.is-expandable { cursor: pointer; }
.gz-news__body {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows .3s ease;
}
.gz-news__card.is-open .gz-news__body { grid-template-rows: 1fr; }
.gz-news__body-inner { min-height: 0; overflow: hidden; }
.gz-news__text {
  padding: 0 16px;
  font-family: var(--gz-font);
  font-size: 16px;
  line-height: 1.5;
  color: var(--gz-ink);
}
.gz-news__text > :first-child { margin-top: 0; }
.gz-news__date {
  display: block;
  padding: 8px 16px 16px;
  font-family: var(--gz-display);
  font-weight: 700;
  font-size: 15px;
  color: var(--gz-ink);
  opacity: .6;
}
@media (prefers-reduced-motion: reduce) {
  .gz-news__body { transition: none; }
}

/* standalone /novinky feed: no carousel above it, so the section needs its own
   top gap under the marquee (on the homepage that gap comes from the carousel) */
.gz-news--feed { padding-top: 32px; }

.gz-news__cta { padding: 32px 0 0; text-align: center; }
.gz-pill.gz-news__pill {
  background: var(--gz-pink);       /* #FAA6FF */
  color: var(--gz-ink);
  font-size: 32px;
  line-height: 38px;
  padding: 16px 24px;
}
.gz-pill.gz-news__pill:hover { background: #E07FE6; }

@media (min-width: 900px) {
  .gz-news { padding: 0 16px 56px; }             /* full-width (per client) — no max-width cap */
  .gz-news__list { grid-template-columns: repeat(4, 1fr); gap: 12px; }   /* desktop gap */
}

/* ==========================================================================
   NEWSLETTER (task #14) — Mailchimp signup, custom-styled. All type is Elza
   Condensed (Typekit "elza-condensed": Bold 700 title, Medium 500 body). MOBILE:
   the violet (#CE72FF) section bleeds full-width between the pink news section above
   and the footer below. DESKTOP: it becomes a rounded (16px) violet box, max-width
   696px, centred on the pink page (#FDE0FF, continuing the news section). Client
   spec: box 696px / padding 24px / radius 16px; title 64/77 mb26; input Condensed
   Medium 24/29, 8px above a 1px full-width rule, mb26; consent Condensed Medium
   24/29, 20×20 checkbox, mb26. The form submits client-side straight to Mailchimp
   (the public site is static HTML on S3, no server endpoint) — see initNewsletter.
   ========================================================================== */
.gz-newsletter { background: var(--gz-violet); }        /* #CE72FF — full-bleed on mobile */
.gz-newsletter__card {
  background: var(--gz-violet);
  padding: 24px;                        /* per spec */
}
.gz-newsletter__title {
  font-family: var(--gz-display);       /* Elza Condensed Bold (700) */
  font-weight: 700;
  font-size: 64px;
  line-height: 77px;
  color: var(--gz-white);
  margin: 0 0 26px;
}

/* e-mail field — Condensed Medium; 8px gap then a 1px full-width rule */
.gz-newsletter__field { margin: 0 0 26px; }
.gz-newsletter__input {
  width: 100%;
  box-sizing: border-box;
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--gz-white);   /* the full-width rule */
  border-radius: 0;                     /* iOS rounds inputs by default */
  padding: 0 0 8px;                     /* 8px between the text and the rule */
  font-family: var(--gz-font);          /* elza-condensed (Typekit) */
  font-weight: 500;                     /* Medium */
  font-size: 24px;
  line-height: 29px;
  color: var(--gz-white);
  -webkit-appearance: none;
  appearance: none;
}
.gz-newsletter__input::placeholder { color: var(--gz-white); opacity: 1; }   /* Firefox dims placeholders */
.gz-newsletter__input:focus { outline: none; }

/* GDPR consent — Condensed Medium 24/29, 20×20 square checkbox, link underlined
   by default and un-underlined on hover (per spec) */
.gz-newsletter__consent {
  display: flex;
  align-items: flex-start;
  gap: 12px;                            /* gap from the checkbox */
  margin: 0 0 26px;
  font-family: var(--gz-font);
  font-weight: 500;                     /* Medium */
  color: var(--gz-white);
  cursor: pointer;
}
/* size must be set on the span + <a> too: legacy style.css `p, a, span { font-size:16px }`
   (element selector) beats the label's inherited 24px, so the text would render at 16px. */
.gz-newsletter__consent,
.gz-newsletter__consent span,
.gz-newsletter__consent a {
  font-size: 24px;
  line-height: 29px;
}
.gz-newsletter__checkbox {
  flex: 0 0 auto;
  box-sizing: border-box;
  width: 20px;
  height: 20px;
  margin: 5px 0 0;                      /* nudge onto the cap-height of the first 29px line */
  -webkit-appearance: none;
  appearance: none;
  background: var(--gz-white);          /* filled white (per client) */
  border: 0;
  border-radius: 0;
  cursor: pointer;
  position: relative;
}
/* checked = the client's black check mark centred on the white square */
.gz-newsletter__checkbox:checked::after {
  content: "";
  position: absolute;
  inset: 0;
  background: url("/images/grape-zoo/checkbox-check.svg") center / contain no-repeat;
}
.gz-newsletter__consent a { color: var(--gz-white); text-decoration: underline; }
.gz-newsletter__consent a:hover { text-decoration: none; }

/* submit — white pill, black text (reuses the .gz-pill base radius/flex). Block-level
   flex so it can be full-width AND centred on mobile; fixed 247px on desktop. */
.gz-pill.gz-newsletter__submit {
  display: flex;
  box-sizing: border-box;               /* so the desktop 247px / mobile 100% is the real width */
  width: 100%;                          /* 100% of the container at the smallest breakpoint */
  margin: 0 auto;                       /* centred on mobile */
  background: var(--gz-white);
  color: var(--gz-ink);
  font-size: 32px;
  line-height: 38px;
  padding: 16px 24px;
}
.gz-pill.gz-newsletter__submit:hover {   /* inverse on hover: black bg, white text */
  background: var(--gz-ink);
  color: var(--gz-white);
}

/* JS status line (validation error / success / "coming soon") */
.gz-newsletter__note {
  margin: 16px 0 0;
  font-family: var(--gz-font);
  font-weight: 500;
  font-size: 18px;
  line-height: 24px;
  color: var(--gz-white);
}

@media (min-width: 900px) {
  .gz-newsletter {
    background: #FDE0FF;                 /* continues the news pink; the box floats on it */
    padding: 0 16px 56px;
  }
  .gz-newsletter__card {
    max-width: 696px;                    /* per spec */
    margin: 0 auto;
    border-radius: 16px;                 /* per spec */
  }
  .gz-pill.gz-newsletter__submit { width: 247px; margin: 0; }   /* fixed 247px, left-aligned on desktop */
}

/* --------------------------------------------------------------------------
   ECOMAIL WIDGET OVERRIDES (task #14)
   The newsletter form is now rendered client-side by Ecomail's widget.js into
   .gz-newsletter. It lands in the LIGHT DOM (no iframe / no shadow root), so we
   CAN restyle it from here. Ecomail ships the form with its own INLINE styles
   (white 770px box, dark-green button, Open Sans), so most rules need
   !important to beat those inline values. Selectors target the generic .ec-v-*
   classes (NOT the per-form #ec_form_… id), so the same rules also style the EN
   widget once it's added. Content fixes belong in the Ecomail editor, not here:
   the leftover "Input title" field label and the duplicate <h2> heading (we keep
   our own .gz-newsletter__title). Those are hidden below only as a safety net. */

/* strip Ecomail's white box + fixed 770px width so the form sits on our card */
.gz-newsletter .ec-v-form-holder {
  background: transparent !important;
  width: 100% !important;
  max-width: 100%;
  padding: 0 !important;
  border-radius: 0 !important;
  overflow: visible !important;
}
.gz-newsletter .ec-v-form-holder form { min-height: 0 !important; }
/* Ecomail locks each step to an inline height:444px — let it size to content so the
   card padding/height reads correctly (no big empty gap inside the violet card) */
.gz-newsletter .ec-v-form-step { height: auto !important; }

/* hide Ecomail's own heading (we render .gz-newsletter__title above) and the
   leftover "Input title" label — prefer removing these in the Ecomail editor */
/* :not(step-send) — hide ONLY the form step's heading; a heading on the success/send
   step must stay visible (Ecomail moves the .ec-v-form-step-visible class onto it after submit) */
.gz-newsletter .ec-v-form-step-visible:not(.ec-v-form-step-send) .ec-v-form-text h2,
.gz-newsletter .ec-v-forms-label { display: none !important; }

/* Ecomail pads every row by 52px horizontally — drop it; our card already pads 24px */
.gz-newsletter .ec-v-form-text,
.gz-newsletter .ec-v-form-input,
.gz-newsletter .ec-v-form-submit { padding-left: 0 !important; padding-right: 0 !important; }
.gz-newsletter .ec-v-form-input { padding-top: 0 !important; padding-bottom: 26px !important; }

/* e-mail field → transparent input with a white underline (matches the design) */
.gz-newsletter input.ec-v-forms-form-control {
  width: 100% !important;
  box-sizing: border-box;
  background: transparent !important;
  border: 0 !important;
  border-bottom: 1px solid var(--gz-white) !important;
  border-radius: 0 !important;
  padding: 0 0 8px !important;
  font-family: var(--gz-font) !important;
  font-weight: 500 !important;                 /* !important — beats Ecomail's later 14px rule */
  font-size: 24px !important;
  line-height: 29px !important;
  box-shadow: none !important;                 /* kill Ecomail's bordered/rounded input box */
  -webkit-appearance: none;
  appearance: none;
  color: var(--gz-white) !important;
}
.gz-newsletter input.ec-v-forms-form-control::placeholder { color: var(--gz-white) !important; opacity: 1; }
.gz-newsletter input.ec-v-forms-form-control:focus { outline: none; }

/* consent text → white, correct typography (readable on the violet card) */
/* size a/span explicitly too — legacy style.css `p, a, span { font-size:16px }` (element
   selector) otherwise shrinks the consent link below the 24px text (same trap as the old form) */
.gz-newsletter .ec-forms-chck-lbl-text,
.gz-newsletter .ec-forms-chck-lbl-text p,
.gz-newsletter .ec-forms-chck-lbl-text a,
.gz-newsletter .ec-forms-chck-lbl-text span {
  color: var(--gz-white) !important;
  font-family: var(--gz-font) !important;
  font-weight: 500 !important;
  font-size: 24px !important;
  line-height: 29px !important;
}
.gz-newsletter .ec-forms-chck-lbl-text a { color: var(--gz-white) !important; text-decoration: underline; }
.gz-newsletter .ec-forms-chck-lbl-text a:hover { text-decoration: none !important; }

/* THANK-YOU / SUCCESS step (Ecomail moves .ec-v-form-step-visible onto .ec-v-form-step-send
   after a successful signup). Per design: Elza Condensed Bold, CENTERED, white, 48/58.
   The * also covers whatever tag Ecomail wraps the message in (h2/p/span) — and beats the
   legacy `p,a,span{font-size:16px}`. NOTE: this state only renders after a real Ecomail
   submit, so it can't be previewed in the local dev env — verify/tune on stage. */
.gz-newsletter .ec-v-form-step-send .ec-v-form-text,
.gz-newsletter .ec-v-form-step-send .ec-v-form-text * {
  color: var(--gz-white) !important;
  font-family: var(--gz-display) !important;   /* Elza Condensed Bold */
  font-weight: 700 !important;
  font-size: 48px !important;
  line-height: 58px !important;
  text-align: left !important;    /* mobile: left-aligned (desktop centers, see media query) */
}
/* Keep the card the same height as the form and position the message per design.
   The .gz-newsletter__title (h2) already has 26px margin-bottom and the card 24px padding,
   so: gap-below-heading = 26 + this margin-top; gap-to-card-bottom = 24 + this padding-bottom.
   Mobile (tuned on stage): 66px below heading (26+40), 93px from the card bottom (24+69).
   The Ecomail success step only renders after a real submit (can't be previewed locally),
   and an "M" badge sits between heading and text. */
.gz-newsletter .ec-v-form-step-send { padding-bottom: 69px !important; }
.gz-newsletter .ec-v-form-step-send .ec-v-form-text { margin-top: 40px !important; }
@media (min-width: 900px) {
  /* Desktop (tuned on stage): 64px below heading (26+38), 124px from the card bottom (24+100). */
  .gz-newsletter .ec-v-form-step-send { padding-bottom: 100px !important; }
  .gz-newsletter .ec-v-form-step-send .ec-v-form-text { margin-top: 38px !important; }
  /* desktop: centered (mobile is left-aligned); override both the block and its children */
  .gz-newsletter .ec-v-form-step-send .ec-v-form-text,
  .gz-newsletter .ec-v-form-step-send .ec-v-form-text * { text-align: center !important; }
}

/* GDPR consent checkbox → our 20×20 white square + black SVG tick (matches the old
   .gz-newsletter__checkbox). Ecomail hides the real <input> and draws the box on the
   empty label's ::before and a CSS tick on ::after; we recolour the box white (it turns
   blue when checked) and swap the tick for checkbox-check.svg. */
.gz-newsletter .ec-v-form-input input[type=checkbox] + label {
  float: left;
  display: block;
  width: 20px;
  height: 20px;
  padding: 0;
  margin: 4px 12px 0 0;                 /* 12px gap to the text; 4px nudges onto the 29px line */
}
.gz-newsletter .ec-v-form-input input[type=checkbox] + label::before,
.gz-newsletter .ec-v-form-input input[type=checkbox]:checked + label::before {
  top: 0; left: 0; width: 20px; height: 20px;
  background: var(--gz-white) !important;
  border: 0 !important;
  border-radius: 0 !important;
}
.gz-newsletter .ec-v-form-input input[type=checkbox]:checked + label::after {
  content: '' !important;
  display: block !important;
  top: 0; left: 0; width: 20px; height: 20px;
  border: 0 !important;
  transform: none !important;
  background: url("/images/grape-zoo/checkbox-check.svg") center / contain no-repeat;
}
/* the consent text is a sibling block — clear Ecomail's 35px indent and let it form a
   clean column next to the floated box */
.gz-newsletter .ec-v-form-input .ec-forms-chck-lbl-text { overflow: hidden; }
.gz-newsletter .ec-v-form-input .ec-forms-chck-lbl-text p { margin-left: 0 !important; }

/* validation errors (e.g. "Neplatný e-mail"): Ecomail draws a beige box and toggles it
   display:none↔block on submit, which grew the violet card (visible jump) and looked
   off-design. Restyle on-brand (transparent, no box, yellow warning text)… */
.gz-newsletter .ec-v-form-error {
  margin: 6px 0 0 !important;
  padding: 0 !important;
  background: transparent !important;
  border: 0 !important;
  border-radius: 0 !important;
  color: var(--gz-yellow) !important;
  font-family: var(--gz-font) !important;
  font-weight: 500 !important;
  font-size: 16px !important;
  line-height: 22px !important;
  text-align: left !important;
}
/* …and RESERVE the e-mail error's line permanently so appearing/clearing it never
   reflows the card (Ecomail sets display:none when valid → force a one-line slot). */
.gz-newsletter .ec-v-form-error-email {
  display: block !important;
  min-height: 22px;
}

/* submit → white pill with ink text (the design's .gz-pill look); hover inverts */
.gz-newsletter .ec-v-form-submit { text-align: left !important; padding-top: 0 !important; padding-bottom: 0 !important; }
.gz-newsletter .ec-v-form-submit button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 100% !important;                      /* !important: Ecomail's JS pins an inline width on submit */
  box-sizing: border-box;
  margin: 0 !important;                        /* kill the button's default top/bottom margin */
  border: 0 !important;
  border-radius: 60px !important;
  background: var(--gz-white) !important;
  color: var(--gz-ink) !important;
  font-family: var(--gz-display) !important;
  font-weight: 700 !important;
  font-size: 24px !important;
  line-height: 34px !important;                /* deterministic text-box height (58 = 34 + 12+12 padding) */
  padding: 12px 24px !important;
  min-height: 58px;                            /* lock height: on submit Ecomail swaps the label for a
                                                  loading spinner (text → smaller SVG) which otherwise
                                                  shrank the button 58→47px. min-height keeps it stable. */
  cursor: pointer;
}
.gz-newsletter .ec-v-form-submit button:hover {
  background: var(--gz-ink) !important;
  color: var(--gz-white) !important;
}
/* kill the focus ring / outline that appears on click (Ecomail/UA button focus style) */
.gz-newsletter .ec-v-form-submit button:focus,
.gz-newsletter .ec-v-form-submit button:focus-visible,
.gz-newsletter .ec-v-form-submit button:active {
  outline: none !important;
  box-shadow: none !important;
}
@media (min-width: 900px) {
  .gz-newsletter .ec-v-form-submit button { width: 247px !important; }
}

/* ==========================================================================
   FLYING ANIMALS (task #13) — a random animal SVG drifts across the middle of the
   viewport every ~20s (JS: initFlyingAnimals in grape-zoo.js). Fixed, pointer-
   events:none overlay so it never affects layout or clicks; site-wide. NOT inside a
   .gz wrapper (which paints a white bg) — its own class only. z-index sits above page
   content but below the mobile menu (100); animals fly mid-viewport so they don't
   overlap the header/marquee/CTA regardless. Respects prefers-reduced-motion (JS).
   ========================================================================== */
.gz-animals {
  position: fixed;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  z-index: 60;
}
.gz-animal {
  position: absolute;
  left: 0;
  height: auto;              /* width set inline per spawn (120–200px) */
  /* NO will-change: transform — pre-promoting to a GPU layer makes mobile browsers cache
     the SVG as a low-res texture (below DPR) → pixelated in motion. The transform animation
     still composites on its own; the layer is then rasterized at the current (DPR) scale. */
}

/* ==========================================================================
   MOBILE MENU OVERLAY  (built in a later increment; hidden for now)
   ========================================================================== */
.gz-menu {
  position: fixed;
  inset: 0;
  z-index: 100;
  background: var(--gz-pink);
  display: none;
  padding: 8px 16px 32px;
  overflow-y: auto;                     /* tall content (e.g. expanded Info) scrolls INSIDE the menu … */
  -webkit-overflow-scrolling: touch;    /* … with momentum on iOS … */
  overscroll-behavior: contain;         /* … and never chains through to the page underneath */
}
.gz-menu.is-open { display: block; }
/* freeze the page behind the open overlay (the menu itself still scrolls) */
html.gz-menu-open, html.gz-menu-open body { overflow: hidden; }
/* the floating CTA + swirl + flying animals are position:fixed BELOW the menu
   (z 39/40/60 < 100); on iOS Safari they flicker above it during the scroll
   rubber-band. Drop them entirely while the menu is open — it covers the screen
   anyway, so there is nothing to see through. */
html.gz-menu-open .gz-floating-root,
html.gz-menu-open .gz-animals { display: none; }
.gz-menu__top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: 44px;
}
.gz-menu__lang {
  font-family: var(--gz-display);
  font-weight: 700;
  font-size: 42px;         /* site-title typography (matches .gz-brand, like the desktop EN switch) */
  line-height: 50px;
  letter-spacing: -0.01em;
}
.gz-menu__close {
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  color: var(--gz-ink);
  width: 39px;             /* X: 39×42 (design asset hamburger-close.svg) */
  height: 42px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.gz-menu__close svg { display: block; }
.gz-menu__nav {
  margin-top: 50px;        /* items start 50px below the EN/X row */
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
}
.gz-menu__nav a {
  font-family: var(--gz-display);
  font-weight: 700;
  font-size: 64px;
  line-height: 77px;
  text-transform: uppercase;   /* labels come from the CMS in mixed case */
}
/* mobile accordion: LINE-UP / INFO expand their children inline */
.gz-menu__group {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;                              /* submenu starts 10px below the parent (per spec) */
}
.gz-menu__toggle {
  background: none;
  border: 0;
  margin: 0;
  padding: 0;
  color: inherit;
  cursor: pointer;
  font-family: var(--gz-display);
  font-weight: 700;
  font-size: 64px;
  line-height: 77px;
  text-transform: uppercase;   /* labels come from the CMS in mixed case */
}
.gz-menu__toggle[aria-expanded="true"] { text-decoration: underline; }   /* expanded parent underlined (per design) */
.gz-menu__children {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 11px;                              /* between submenu items (per spec) */
}
.gz-menu__children[hidden] { display: none; }
.gz-menu__children a {                    /* condensed bold 32/38 (per spec); after .gz-menu__nav a → wins on equal specificity */
  font-size: 32px;
  line-height: 38px;
  text-transform: uppercase;
}
.gz-menu__children a:hover { text-decoration: underline; }
.gz-menu__social {
  margin-top: 136px;       /* 136px below the menu items */
  display: flex;
  justify-content: center;
  gap: 23px;
}
.gz-menu__social a { display: inline-flex; }
.gz-menu__social img {
  width: 38px;
  height: 38px;
  display: block;
}

/* ==========================================================================
   DESKTOP  (provisional — refine once the desktop Figma is available)
   ========================================================================== */
@media (min-width: 900px) {
  .gz { --gz-header-h: 84px; }
  .gz-brand { flex: 0 0 auto; }
  .gz-nav { display: flex; flex: 1 1 auto; justify-content: flex-end; }
  .gz-burger { display: none; }
  .gz-menu { display: none !important; }  /* mobile overlay never on desktop */
  .gz-hero__inner { align-items: flex-start; padding: 24px 24px 28px; }  /* logo top-left 24px; min-height (vh/lvh − offset) inherited from the base rule */
  .gz-logo { width: 354px; }  /* desktop: uniform width across variants (mobile pins it to 172px) */
  /* client change: buttons 16px from the right, 8px from the bottom (same as mobile);
     graphic bottom stays 108px below the buttons (8 − 108 = −100 → bleeds off the bottom) */
  .gz-hero__cta { right: 16px; left: auto; transform: none; bottom: 8px; margin: 0; }
  .gz-hero__cta > .gz-pill { flex: 0 0 auto; }   /* content-width, right-aligned pair (not full-width like mobile) */
  .gz-hero__deco {
    width: 462.49px;            /* desktop asset (Figma) */
    height: 232.66px;
    left: auto;
    right: -15.49px;           /* bleeds 15.49px past the frame's right edge */
    bottom: -100px;
    transform: none;
    background-image: url("/images/grape-zoo/hero-graphics-d.svg");
  }
  .gz-marquee__track { animation-duration: 100s; }   /* 20 copies (was 6 @ 30s) → ×20/6 keeps the same px/s */
}

/* Narrow desktop widths overflow with the real display font (Elza Condensed) — and the
   brand's animated suffix swaps to the WIDER "ZOOOO", so the threshold is 1000px, not the
   ~950 the fallback font suggests. Below it, shrink the whole header uniformly; at ≥1001 it
   stays at full design size. Must scale brand, plain nav links AND the submenu toggles
   (.gz-nav__toggle = LINE-UP / INFO) together — otherwise the toggles stay 32px while the
   links drop to 22px and the items look mismatched. The language switch (.gz-lang) is a
   plain .gz-nav <a>, so it follows the links. Full spec (brand 42/50, nav 32/38, gap 48) at ≥1001. */
@media (min-width: 900px) and (max-width: 1000px) {
  .gz-brand { font-size: 32px; line-height: 38px; }
  .gz-nav { gap: 22px; }
  .gz-nav a,
  .gz-nav__toggle { font-size: 22px; line-height: 26px; }   /* links + toggles + .gz-lang all equal */
  :root { --gz-header-real-h: 46px; }   /* brand shrinks to lh 38 → header 38 + 8 = 46 (keep in sync) */
}

/* ==========================================================================
   LEGACY LAYOUT OVERRIDES
   Integrate the new in-flow header/footer into the old fixed-header layout
   (layouts/frontend.blade.php). Loaded after style.css so these win.
   ========================================================================== */
.superheader,
.superheader.with-submenu,
.superheader.without-submenu { height: auto !important; }        /* was fixed 61/118px; !important beats
                                                                    per-page legacy rules like
                                                                    ".smart-page-information .superheader.with-submenu{height:72px}"
                                                                    (style.css) that otherwise clip #k-head → content overlaps */
#k-head { position: static; background: none; z-index: auto;     /* new header is out of flow (fixed) … */
          padding-top: var(--gz-header-real-h); }                /* … so reserve its height (see :root default +
                                                                    JS) — marquee sits right below the pinned
                                                                    header. Keeps #k-head height = header + marquee,
                                                                    so --gz-hero-offset is unchanged and the
                                                                    homepage hero still fits. */
#k-subhead { display: none; }                                    /* nav moved into the new header */
#k-body { margin-top: 0 !important; margin-bottom: 0; }          /* drop legacy fixed-header offsets; !important beats
                                                                    per-page rules like ".smart-page-history #k-body{margin-top:300px}"
                                                                    (style.css, mobile) that the header no longer needs (it's in flow) */
#k-footer { margin-bottom: 0; }
/* legacy style.css `#k-footer a { color:#000; text-decoration:none }` (ID selector, 1,0,1)
   beats the redesign footer rules on the integrated site → links render black with no hover
   underline. Restore the inherited colour (white, from .gz-footer) and the hover underline. */
#k-footer a { color: inherit; }
#k-footer .gz-footer__nav a:hover,
#k-footer .gz-footer__secondary a:hover { text-decoration: underline; }
/* legacy pages (shop, …) tuck content up under the OLD fixed header via negative
   margins — e.g. `.video-container { margin-top: -81px }` — which now slides the
   black block up over the in-flow marquee and hides it. Reset the pull-up, and
   keep the marquee above page content so nothing can cover it. */
.video-container { margin-top: 0; }
.gz-marquee { position: relative; z-index: 50; }
/* homepage is full-bleed (hero video) → drop the legacy 40px body side padding */
.smart-page-homepage #k-body { padding: 0; }

/* footer text must stay white — beat legacy "#k-footer a" (specificity 1,0,1) */
#k-footer .gz-footer,
#k-footer .gz-footer a { color: #fff; }

/* /shop: kill the legacy full-screen vertical-centering. script.js (initialised for the
   old full-bleed video hero) inline-sets .shop{height:…} and .shop .row{margin-top:…}
   to centre the icon row in a viewport-tall black box, and legacy CSS gives
   .video-container min-height:750px + padding-top:100px. With no hero video here that
   just leaves huge empty gaps above/below the icons. !important beats the JS inline
   styles (they carry no !important) and re-wins after its resize handler. */
.smart-page-shop_page .shop { height: auto !important; }
.smart-page-shop_page .shop .row { margin-top: 0 !important; }
.smart-page-shop_page .video-container { min-height: 0; padding: 48px 0; margin-bottom: 0; }
/* …and because the page is now short, pin the footer to the bottom (sticky footer) so
   the black body background can't show as a strip below it on tall viewports. Flex the
   body column and let the footer absorb the free space above it. Fixed overlays (header,
   flying animals, floating CTA) are out of flow → unaffected. On tall content the free
   space is zero, so the footer just flows normally. */
.smart-page-shop_page { display: flex; flex-direction: column; min-height: 100vh; }
.smart-page-shop_page #k-footer { margin-top: auto; }
