/* =============================================================================
   landing.css — SCR-001 Splash + SCR-002 Invalid Link
   Distilled from docs/mockups/mcd_fifa_scratchwin_mod002-003_hifi_mockups.html
   Mobile-first; no external fonts (system stack) to stay under 200KB initial.
   ============================================================================= */

/* Speedee — McDonald's brand typeface (proprietary, licensed).
   Self-hosted WOFF2 at /assets/fonts/speedee/. Sora / Manrope (Google
   Fonts, loaded by each template) stay in the fallback chain in case
   the WOFF2 fails to load. font-display: swap avoids invisible text
   while the licensed font is downloading. */
@font-face {
    font-family: 'Speedee';
    src: url('/assets/fonts/speedee/Speedee-Light.woff2') format('woff2');
    font-weight: 300;
    font-style: normal;
    font-display: swap;
}
@font-face {
    font-family: 'Speedee';
    src: url('/assets/fonts/speedee/Speedee-LightItalic.woff2') format('woff2');
    font-weight: 300;
    font-style: italic;
    font-display: swap;
}
@font-face {
    font-family: 'Speedee';
    src: url('/assets/fonts/speedee/Speedee-Regular.woff2') format('woff2');
    font-weight: 400;
    font-style: normal;
    font-display: swap;
}
@font-face {
    font-family: 'Speedee';
    src: url('/assets/fonts/speedee/Speedee-Italic.woff2') format('woff2');
    font-weight: 400;
    font-style: italic;
    font-display: swap;
}
@font-face {
    font-family: 'Speedee';
    src: url('/assets/fonts/speedee/Speedee-Bold.woff2') format('woff2');
    font-weight: 700;
    font-style: normal;
    font-display: swap;
}
@font-face {
    font-family: 'Speedee';
    src: url('/assets/fonts/speedee/Speedee-BoldItalic.woff2') format('woff2');
    font-weight: 700;
    font-style: italic;
    font-display: swap;
}
/* Speedee Condensed is not part of the licensed pack we have; references
   to `'Speedee Condensed'` in the font stacks gracefully fall through to
   Sora (similar geometric humanist sans) until the condensed family is
   licensed. Declarations intentionally omitted to avoid 404s. */

:root {
    /* Force light rendering even when the OS/browser prefers dark — this
       campaign UI is light-only. The `only` keyword also opts the page out of
       the browser's auto/forced dark mode (e.g. Chrome Auto Dark Theme). */
    color-scheme: only light;

    /* McDonald's brand palette — per docs/Brand guideline/McD brand colour.jpg
       Core: Gold #FFBC0D, Red #DB0007. Functional: Black #000000,
       Charcoal #2D2D2D, Light Gray #F7F7F7, Kraft #B69A81. */
    --mcd-red:         #DB0007;
    --mcd-red-dark:    #A50005;
    --mcd-red-soft:    #FCE6E6;
    --mcd-yellow:      #FFBC0D;
    --mcd-yellow-soft: #FFE599;
    --mcd-yellow-tint: #FFF6D6;
    --mcd-cream:       #FFFBF0;
    --mcd-white:       #FFFFFF;
    --mcd-black:       #000000;
    --mcd-charcoal:    #2D2D2D;
    --mcd-grey:        #8E8B85;
    --mcd-grey-light:  #E8E5DE;
    --mcd-grey-bg:     #F7F7F7;
    --mcd-kraft:       #B69A81;
    /* McDonald's European Green — PMS 350 C / RGB 38.79.54 / HEX 264F36.
       Per the brand guideline, normally restricted to European markets, the
       Token, and existing market activations such as restaurant facias.
       Used here for game-over copy in the SG campaign. */
    --mcd-european-green: #264F36;
    /* Grab brand green — matches game.css for cross-stylesheet consistency. */
    --grab-green:      #00B14F;
    --radius-sm:   6px;
    --radius-md:  12px;
    --radius-xl:  20px;
    --radius-pill: 9999px;
    --shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.08);
    --shadow-md: 0 6px 18px rgba(0, 0, 0, 0.10);
    --shadow-red: 0 6px 18px rgba(219, 0, 7, 0.35);
    /* Speedee is the McDonald's brand font (Bold / Regular / Light + Condensed).
       It is proprietary and not freely distributable, so it must be
       self-hosted at /assets/fonts/speedee/ if licensed. Sora / Manrope are
       kept as the visual fallback — both are geometric humanist sans
       families that closely approximate Speedee's proportions. */
    --font-display: 'Speedee', 'Sora', system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
    --font-body:    'Speedee', 'Manrope', system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
}

* { box-sizing: border-box; margin: 0; padding: 0; }
html, body { width: 100%; min-height: 100vh; -webkit-font-smoothing: antialiased; }
/* Suppress page-level scrollbars on the splash specifically. The
   splash-area is height-locked to 100dvh and already clips overflow
   internally via `overflow: hidden`; locking the body too prevents any
   ancestor scrollbar from appearing when the in-flow stamp + tagline
   group's bottom margin pushes past the viewport. */
body:has(.splash-area) { overflow: hidden; height: 100vh; height: 100dvh; }
body {
    font-family: var(--font-body);
    color: var(--mcd-black);
    /* Surrounding "off-stage" area visible on wider-than-mobile viewports.
       Solid McD red — keeps the brand voice continuous on desktop preview. */
    background: var(--mcd-red);
    display: flex;
    align-items: stretch;
    justify-content: center;
}

/* =============================================================================
   SCR-001 — Splash
   ============================================================================= */
.splash-area {
    /* Mobile-first viewport: cap to a phone-like width so the layout
       holds up on desktop preview. Phones ≤420px wide get full bleed.
       The splash must fit entirely in one screen — `100dvh` (with `100vh`
       fallback) locks the surface to the visible viewport. Combined with
       `overflow: hidden` below, anything that overflows is cropped rather
       than triggering a scroll. */
    width: 100%;
    max-width: 480px;
    height: 100vh;
    height: 100dvh;
    background: var(--mcd-red);
    background-image:
        radial-gradient(circle at 20% 20%, rgba(255, 188, 13, 0.18) 0%, transparent 35%),
        radial-gradient(circle at 80% 75%, rgba(255, 188, 13, 0.10) 0%, transparent 40%);
    position: relative;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    align-items: center;
    /* Anchor the in-flow stamp + tagline group from the bottom of the
       viewport. `margin-top: auto` is applied to .stamp-stack (below),
       which consumes free space ABOVE it and pulls the group downward.
       The absolute hero-ball / tap-hint / footer continue to sit at
       their fixed bottom offsets. */
    justify-content: flex-start;
    padding: 28px 28px 0;
    cursor: pointer;          /* whole surface is tap-to-skip */
    user-select: none;
    /* Bottom stack: footer holds tap hint → sponsor → caption; ball floats
       above the whole block with a fixed gap. */
    --splash-footer-bottom:         19px;
    --splash-caption-height:        14px;
    --splash-sponsor-lockup-height: 68px;  /* img + on-dark pill padding */
    --splash-tap-hint-height:       30px;
    --splash-tap-ball-gap:          12px;
    --splash-caption-margin:         8px;
    --splash-footer-stack: calc(
        var(--splash-tap-hint-height)
        + var(--splash-sponsor-lockup-height)
        + var(--splash-caption-margin)
        + var(--splash-caption-height)
    );
    --splash-ball-row-bottom: calc(
        var(--splash-footer-bottom)
        + var(--splash-footer-stack)
        + var(--splash-tap-ball-gap)
    );
}

/* Layer 1 — sunburst rays behind stamp.
   Sized to 140vmax so the rays always reach past the visible viewport
   diagonal — .splash-area's `overflow: hidden` clips the rest.
   The rotation centre is pinned to the stamp's visual centre via
   --sunburst-x / --sunburst-y, written by splash.js on load + resize.
   The 50% fallbacks keep the rays sensibly placed during the first
   paint, before the script measures the stamp.

   Two-stage animation on entry:
   1. `sunburst-zoom-in` (0.15–1.05s) — rays start at scale(0.25)
      (compact enough to sit behind the stamp on most viewports), then
      expand to full size with a settle-out easing curve. Forwards
      fill-mode persists the end state (scale 1).
   2. `spin` (starts 1.05s, infinite) — continuous slow rotation once
      the zoom-in completes. Includes scale(1) in both keyframes so
      the transform function-list matches and the scale persists
      cleanly across the animation hand-off. */
.splash-area .sunburst {
    position: absolute;
    top: var(--sunburst-y, 50%);
    left: var(--sunburst-x, 50%);
    width: 140vmax;
    height: 140vmax;
    transform: translate(-50%, -50%) scale(0.15);
    animation:
        sunburst-zoom-in 1.5s cubic-bezier(0.22, 0.61, 0.36, 1) 1s forwards,
        spin 60s linear infinite 2.5s;
    pointer-events: none;
}
@keyframes sunburst-zoom-in {
    from { transform: translate(-50%, -50%) scale(0.15); }
    to   { transform: translate(-50%, -50%) scale(1); }
}
@keyframes spin {
    from { transform: translate(-50%, -50%) scale(1) rotate(0deg); }
    to   { transform: translate(-50%, -50%) scale(1) rotate(360deg); }
}

@keyframes float {
    0%, 100% { transform: translateX(-50%) translateY(0); }
    50%      { transform: translateX(-50%) translateY(-40px); }
}

/* Layer 3 — soccer ball between tagline and tap hint */
.splash-area .hero-ball {
    position: absolute;
    left: 50%;
    /* Sit 6px lower than the shared ball row: the ball rests low and bounces
       UP (24px), so using its spare clearance above the tap-hint keeps the
       enlarged ball from colliding with the tagline at the bounce peak. */
    bottom: calc(var(--splash-ball-row-bottom) - 6px);
    width: 66px;
    height: 66px;
    transform: translateX(-50%);
    animation: float 2.6s ease-in-out infinite;
    pointer-events: none;
    z-index: 2;
    /* Coca-Cola match-ball cropped out of the tri-brand lockup
       (ballfifaMcD-white.png): the FIFA + McDonald's logos and the
       "OFFICIAL PARTNER" caption are cropped away via background-size /
       -position. The element is square so the % crop stays centred at any
       size — bump width/height together to resize the ball. */
    background-image: url('/assets/images/ballfifaMcD-white.png');
    background-repeat: no-repeat;
    background-size: 363.8% 176.1%;
    background-position: 7.87% 37.19%;
    filter: drop-shadow(0 6px 12px rgba(0, 0, 0, 0.28));
}

/* Layer 4 — mini prize stamps in dedicated safe zones */
.splash-area .splash-prizes {
    /* Hidden — the splash carousel (slides 2–5) already showcases each
       prize in detail, so the decorative corner mini-stamps would be
       redundant. Kept in the markup so re-enabling later is a one-line
       CSS revert. */
    display: none;
    position: absolute;
    inset: 0;
    pointer-events: none;
    z-index: 1;
}
.splash-area .mini-stamp {
    position: absolute;
    background: var(--mcd-yellow);
    color: var(--mcd-black);
    font-family: var(--font-display);
    font-weight: 800;
    font-size: 10px;
    padding: 8px 11px;
    border-radius: 14px;
    box-shadow:
        0 0 0 2px rgba(255, 255, 255, 0.9),
        0 5px 14px rgba(0, 0, 0, 0.22);
    pointer-events: none;
    line-height: 1.25;
    text-align: center;
    max-width: 112px;
}
.splash-area .mini-stamp small {
    display: block;
    font-size: 8px;
    font-weight: 700;
    color: var(--mcd-red);
    letter-spacing: 1.2px;
    margin-bottom: 2px;
}

/* Top-left — $2 voucher (swapped with cup_set).
   Vertically centred between the viewport top and the stamp's top edge
   via --stamp-top (set by splash.js). translateY(-50%) anchors the
   mini-stamp's vertical centre at that midpoint, so the gap above and
   below the box matches whatever room the stamp leaves. Falls back to
   90px (≈ historic 8.5vh on a typical mobile viewport) if JS hasn't
   run yet. */
.splash-area .mini-2 {
    top: calc(var(--stamp-top, 180px) / 2);
    left: calc(1.5% + 15% - 8%);
    bottom: auto;
    right: auto;
    transform: translateY(-50%) rotate(-7deg);
}

/* Bottom row — cup_set (swapped with $2) / ball / $5 */
.splash-area .mini-cup-set {
    bottom: calc(var(--splash-ball-row-bottom) + 24px);
    left: max(6px, calc(1% + 5%));
    top: auto;
    right: auto;
    max-width: 118px;
    font-size: 9px;
    transform: translateY(50%) rotate(-5deg);
}

/* Top-right — $5 voucher (swapped with snack_bowl).
   Same vertical-centring scheme as .mini-2 above — see that block for
   the rationale. */
.splash-area .mini-5 {
    top: calc(var(--stamp-top, 180px) / 2);
    right: calc(1.5% + 15% - 8%);
    left: auto;
    bottom: auto;
    transform: translateY(-50%) rotate(6deg);
}

/* Bottom row — cup_set / ball / snack_bowl (swapped with $5) */
.splash-area .mini-snack-bowl {
    bottom: calc(var(--splash-ball-row-bottom) + 24px);
    right: max(6px, calc(1% + 5%));
    left: auto;
    top: auto;
    max-width: 118px;
    font-size: 9px;
    transform: translateY(50%) rotate(6deg);
}

/* Layer 5a — the splash carousel: horizontally-swipeable strip of cards.
   Claims the vertical-auto space the original .stamp-stack used to
   own, so the whole strip sits at roughly the same vertical position
   as the standalone stamp did before.
   align-self: stretch overrides the splash-area's `align-items: center`
   so the carousel spans the parent's full content-box width. */
.splash-area .splash-carousel {
    position: relative;
    z-index: 2;
    align-self: stretch;
    width: auto;
    margin-top: auto;
    /* Negative margins pull the strip out past the splash-area's 28px
       padding so each slide visually fills the full viewport width. */
    margin-left:  -28px;
    margin-right: -28px;
    display: flex;
    overflow-x: auto;
    overflow-y: hidden;
    scroll-snap-type: x mandatory;
    scroll-behavior: smooth;
    -webkit-overflow-scrolling: touch;
    /* Hide the native scrollbar — the dot indicator below conveys position. */
    scrollbar-width: none;
    -ms-overflow-style: none;
}
.splash-area .splash-carousel::-webkit-scrollbar { display: none; }

.splash-area .carousel-slide {
    flex: 0 0 100%;
    /* 100% of CAROUSEL (not splash-area). min-width: 0 lets the slide
       shrink to its flex basis; horizontal overflow is clipped at the
       sides (only) so the scroll-snap calculation sees clean widths.
       Vertical overflow stays visible so the stamp's -3deg rotation
       and box-shadow don't get sliced off at the top/bottom. */
    min-width: 0;
    overflow-x: hidden;
    overflow-y: visible;
    scroll-snap-align: center;
    scroll-snap-stop: always;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 22px 28px;          /* horizontal: matches splash-area gutter; vertical: room for stamp rotation + shadow */
    box-sizing: border-box;
}

/* Layer 5b — main stamp stack (now inside the carousel, but keeps the
   same visual treatment so slide 1 looks identical to the prior splash). */
.splash-area .stamp-stack {
    position: relative;
    z-index: 2;
    top: -5px;
}
/* Reserved clearance below the tagline so the stamp+tagline group sits
   above the absolute hero-ball (anchored at bottom: 151px) without
   colliding. Increasing this value pulls the whole stamp+tagline group
   UP, because `.stamp-stack { margin-top: auto }` is the only consumer
   of remaining free space. 160px keeps the tagline a comfortable
   ~50–60px clear of the floating ball's animation arc on a typical
   mobile viewport. */
.splash-area .splash-tagline { margin-bottom: 182px; }
.splash-area .stamp-back {
    position: absolute;
    inset: 6px -6px -6px 6px;
    background: var(--mcd-yellow-soft);
    border-radius: var(--radius-xl);
    transform: rotate(2deg);
    z-index: 1;
}
.splash-area .stamp {
    position: relative;
    z-index: 2;
    background: var(--mcd-yellow);
    border-radius: var(--radius-xl);
    padding: 22px 28px;
    box-shadow:
        0 0 0 6px var(--mcd-white),
        0 0 0 8px var(--mcd-yellow),
        0 18px 32px rgba(0, 0, 0, 0.35);
    transform: rotate(-3deg);
    text-align: center;
    max-width: 280px;
}
.splash-area .stamp .corner-star {
    position: absolute;
    width: 12px;
    height: 12px;
    background: var(--mcd-red);
    clip-path: polygon(50% 0%, 61% 35%, 98% 35%, 68% 57%, 79% 91%, 50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%);
}
.splash-area .stamp .corner-star.tl { top: 8px;    left: 8px; }
.splash-area .stamp .corner-star.tr { top: 8px;    right: 8px; }
.splash-area .stamp .corner-star.bl { bottom: 8px; left: 8px; }
.splash-area .stamp .corner-star.br { bottom: 8px; right: 8px; }

.splash-area .stamp .stamp-logo-spot {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    width: fit-content;
    margin: 0 auto 10px;
    padding: 12px 18px;
    border-radius: 16px;
    background: var(--mcd-white);
    box-shadow:
        0 0 0 1px rgba(255, 255, 255, 0.75),
        0 6px 18px rgba(255, 255, 255, 0.35);
    /* Clip the zoomed logo to the rounded box; layout size is unchanged. */
    overflow: hidden;
}
.splash-area .stamp .stamp-mcd-logo {
    /* Wide tri-brand lockup (~2:1) replaces the square arches — size by width. */
    width: 180px;
    max-width: 100%;
    height: auto;
    margin: 0;
    display: block;
    object-fit: contain;
    /* Tri-brand lockup (ballfifaMcD-black.png) — show the full width so the
       outer "Official Partner / Official Sponsor" captions aren't clipped by
       the box's overflow:hidden. No zoom. */
}
.splash-area .stamp-eyebrow {
    font-family: var(--font-display);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.04em;
    color: var(--mcd-red);
    margin-bottom: 6px;
}
.splash-area .stamp-title {
    font-family: var(--font-display);
    font-weight: 900;
    font-size: 36px;
    line-height: 1;
    color: var(--mcd-black);
    margin-bottom: 10px;
}
.splash-area .stamp-title .amp { color: var(--mcd-black); }
.splash-area .stamp-bottom {
    font-size: 10px;
    font-weight: 700;
    color: var(--mcd-black);
    letter-spacing: 1.5px;
    text-transform: uppercase;
}
.splash-area .stamp-bottom .dot { margin: 0 6px; color: var(--mcd-red); }

/* ── Prize-card variant (slides 2–5 in the carousel) ────────────────
   Reuses the .stamp visual frame (yellow rounded card, double border-
   shadow, corner stars, rotation) but swaps the body content for a
   prize image + caption. */
.splash-area .stamp--prize {
    /* Tightened so the prize card's overall height (incl. -3deg rotation
       bounding box) matches the main stamp on slide 1 — otherwise slides
       2–5 overflow the top of the carousel-slide clip-box. */
    padding: 14px 22px 16px;
    width: 280px;
    max-width: 280px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 6px;
}
.splash-area .stamp--prize .prize-tag {
    font-family: var(--font-display);
    font-size: 9.5px;
    font-weight: 800;
    color: var(--mcd-red);
    letter-spacing: 1.4px;
    text-transform: uppercase;
    background: rgba(219, 0, 7, 0.10);
    padding: 3px 9px;
    border-radius: 999px;
    margin-bottom: 2px;
}
.splash-area .stamp--prize .prize-art {
    display: block;
    width: 120px;
    height: 120px;
    object-fit: contain;
    filter: drop-shadow(0 8px 14px rgba(0, 0, 0, 0.18));
}
.splash-area .stamp--prize .prize-art--voucher {
    width: 160px;
    height: 160px;
    border-radius: 10px;       /* was 18 — subtler rounding per design */
    overflow: hidden;
    object-fit: contain;
    object-position: center;
}
/* Snack-bowl prize art — taller variant. No clipping needed; the source
   PNG is already well-composed top to bottom. */
.splash-area .stamp--prize .prize-art--snack-bowl {
    width: 200px;
    height: 170px;
    object-fit: contain;
    border-radius: 14px;
    overflow: hidden;
}
/* Single-line prize name (used on slides where the title is short enough
   not to need wrapping — keeps the card vertically tighter). */
.splash-area .stamp--prize .prize-name--single { white-space: nowrap; }

/* Cup-set artwork has a red sky in the top half of the source PNG; clip
   that off and scale up the visible bottom half (the actual cup-set
   product) so it dominates the prize card. */
.splash-area .stamp--prize .prize-art--cup-set {
    width: 280px;
    height: 280px;
    /* Crop the top 35% only (red sky). The bottom of the source PNG
       is left INTACT (no clip) — per design call, the image must not
       be cut at the bottom. */
    clip-path: inset(35% 0 0 0);
    -webkit-clip-path: inset(35% 0 0 0);
    /* Negative top margin matches the clipped-out top region
       (35% × 280 = 98px) so the visible area sits where the prize-art
       slot is, instead of leaving empty space above. */
    margin-top: -98px;
    /* Negative bottom margin doesn't clip the image — it just lets the
       next sibling (the prize name) move up into the transparent
       padding below the cups in the source PNG, shrinking the visible
       yellow strip. Empirical sweet spot: -20px reduces the strip
       without the title overlapping the rendered cups. */
    margin-bottom: -20px;
}
.splash-area .stamp--prize .prize-name {
    font-family: var(--font-display);
    font-size: 13px;
    font-weight: 800;
    color: var(--mcd-black);
    line-height: 1.2;
    letter-spacing: -0.01em;
    text-align: center;
}

/* ── Stamp variant: artwork fills the frame (slide 2) ───────────────
   Mirrors the in-game scratch-reveal panel — the cup-set artwork
   covers the entire stamp interior (edge-to-edge inside the yellow
   border) with a pill + headline overlay anchored at the top. The
   outer `.stamp` frame keeps its rotation, double box-shadow border,
   and corner-star decorations; padding is zeroed so the image truly
   reaches the inner rounded-corner edge. */
.splash-area .stamp--prize-fill {
    padding: 0;
    min-height: 280px;
    overflow: hidden;
    /* Override flex-column from .stamp--prize so the absolute-positioned
       children flow over the cover-fit image instead of stacking and
       collapsing the height. */
    display: block;
}
.splash-area .stamp--prize-fill > .corner-star { z-index: 3; }
/* Slides 2 + 3 (cup-set + snack-bowl stamp prizes) — corner stars in
   McDonald's yellow against the warm/saturated artwork read with more
   contrast than red-on-red. Voucher slides (4 + 5) keep the default
   red stars from .splash-area .stamp .corner-star above. */
.splash-area .stamp--prize-fill:has(.prize-fill__img--cup-set) > .corner-star,
.splash-area .stamp--prize-fill:has(.prize-fill__img--snack-bowl) > .corner-star {
    background: var(--mcd-yellow);
}
/* Cup-set slide only — frame 21% wider (280 → 338px) than the default
   so the cup-set artwork has more horizontal canvas, and 5% shorter
   (280 → 266px) so the card reads more landscape. The image is
   bottom-anchored (object-position + transform-origin = center bottom)
   so the reduced height crops the orange sky at the TOP, never the cup
   bases at the bottom. Other prize slides keep the default 280×280. */
.splash-area .stamp--prize-fill:has(.prize-fill__img--cup-set) {
    width: 338px;
    max-width: 338px;
    min-height: 266px;
}
.splash-area .stamp--prize-fill .prize-fill__img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center bottom;
    transform: scale(1.18);
    transform-origin: center bottom;
    z-index: 0;
    display: block;
    pointer-events: none;
    /* Match the stamp's rounded corners so the image doesn't bleed into
       the yellow border-ring corner radii. */
    border-radius: var(--radius-xl);
}
/* Cup-set group shot — show the FULL six-cup artwork with no top/bottom
   crop (stakeholder feedback). contain + no zoom: the image carries its
   own red/orange background and its empty top sky sits cleanly beneath the
   pill + headline overlay. Frame (338×266 ≈ 1.27) ≈ image (1600×1280 = 1.25),
   so contain nearly fills the frame with only a hairline side gutter. */
.splash-area .stamp--prize-fill .prize-fill__img--cup-set {
    object-fit: contain;
    object-position: center;
    transform: none;
}
/* Snack-bowl artwork — anchor at 15% instead of bottom so the bowl is
   not pushed off-screen. Same anchor used by the in-game scratch-reveal
   snack-bowl modifier (.prize-img--stamp-reveal--snack-bowl). The base
   scale(1.18) is inherited from the rule above. */
.splash-area .stamp--prize-fill .prize-fill__img--snack-bowl {
    object-position: center 15%;
    /* scale(1.03) zooms just enough so the image overflows the frame on
       all four sides — covers the yellow frame background without
       cropping the bowl content. translateY removed; the asymmetric
       transform-origin (center 15%) biases the natural overflow toward
       the bottom, which keeps the bowl visually anchored. */
    transform: scale(1.08);
    transform-origin: center 15%;
}
/* Voucher artwork — contain-fit (no cropping) shrunk to 75% of the
   frame and anchored to the bottom edge via transform-origin. The
   reduced size leaves a clear top area for the pill + headline overlay
   so they sit cleanly on the stamp background instead of covering the
   voucher card. */
.splash-area .stamp--prize-fill .prize-fill__img--voucher {
    object-fit: contain;
    object-position: center bottom;
    transform: scale(0.75);
    transform-origin: center bottom;
}
/* Voucher slides (4 + 5) — white card background instead of the default
   yellow so the contained voucher artwork sits on neutral white. The
   stamp's outer yellow box-shadow ring is unchanged so the card still
   reads as a brand-styled stamp. */
.splash-area .stamp--prize-fill:has(.prize-fill__img--voucher) {
    background: var(--mcd-white);
}
/* Voucher headline in Grab brand green (matches the voucher artwork's
   GrabFood lockup). The dark text-shadow used elsewhere is dropped
   since the headline now sits on a white card body where the shadow
   reads as muddy instead of a clean drop shadow. */
.splash-area .stamp--prize-fill:has(.prize-fill__img--voucher) .prize-fill__headline {
    color: var(--grab-green);
    text-shadow: none;
}
.splash-area .stamp--prize-fill .prize-fill__tag {
    position: absolute;
    top: 22px;
    left: 50%;
    transform: translateX(-50%);
    z-index: 2;
    color: #fff;
    background: rgba(0, 0, 0, 0.55);
    padding: 5px 14px;
    border-radius: 999px;
    font-family: var(--font-display);
    font-size: 10px;
    font-weight: 800;
    letter-spacing: 1.4px;
    text-transform: uppercase;
    backdrop-filter: blur(4px);
    -webkit-backdrop-filter: blur(4px);
    white-space: nowrap;
}
.splash-area .stamp--prize-fill .prize-fill__headline {
    position: absolute;
    top: 56px;
    left: 18px;
    right: 18px;
    z-index: 2;
    color: #fff;
    font-family: var(--font-display);
    font-size: 17px;
    font-weight: 900;
    line-height: 1.2;
    text-align: center;
    text-shadow:
        0 1px 0 rgba(0, 0, 0, 0.45),
        0 2px 10px rgba(0, 0, 0, 0.7);
}
/* Slide 3 (snack-bowl) — single-line headline reads tighter when it
   sits closer to the pill; slide 2's two-line cup-set headline needs
   the extra top distance to clear the pill. Both pill and headline
   shift up by ~8px relative to the global defaults so the text sits
   more inside the upper "sky" region of the snack-bowl artwork. */
.splash-area .stamp--prize-fill:has(.prize-fill__img--snack-bowl) .prize-fill__tag {
    top: 14px;
}
.splash-area .stamp--prize-fill:has(.prize-fill__img--snack-bowl) .prize-fill__headline {
    top: 40px;
}

/* ── Dot indicator under the carousel ───────────────────────────────
   Visible, clickable, JS-synced with scroll position. */
.splash-area .splash-dots {
    position: relative;
    z-index: 2;
    /* Nudge the dots up very slightly. Relative offset (not a margin change)
       so only the dots move — the stamp group is bottom-anchored and would
       absorb a margin tweak instead. */
    top: -5px;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    margin-top: 14px;
    pointer-events: auto;
}
.splash-area .splash-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    border: none;
    padding: 0;
    background: rgba(255, 255, 255, 0.35);
    cursor: pointer;
    transition: background 0.18s ease-out, transform 0.18s ease-out;
}
.splash-area .splash-dot:hover { background: rgba(255, 255, 255, 0.55); }
.splash-area .splash-dot.is-active {
    background: var(--mcd-yellow);
    transform: scale(1.25);
}

/* Tagline + tap hint + footer */
.splash-area .splash-tagline {
    position: relative;
    z-index: 2;
    /* Nudge the tagline up a little without moving the stamp group: the group
       is bottom-anchored via margin-top:auto, so a margin change would shift
       the stamp instead. A relative offset moves only this line. */
    top: -12px;
    margin-top: 21px;
    color: var(--mcd-white);
    font-family: var(--font-display);
    /* 15px (down from 16) so "…FIFA World Cup™" (≈295px) stays on one line
       even on narrower ~360px phones; the <br> drops the 2nd line. */
    font-size: 15px;
    font-weight: 600;
    text-align: center;
    max-width: 340px;
    line-height: 1.4;
    text-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
}
.splash-area .tap-hint {
    position: absolute;
    bottom: 105px;
    left: 50%;
    transform: translateX(-50%);
    z-index: 9;
    background: rgba(255, 255, 255, 0.18);
    backdrop-filter: blur(4px);
    color: var(--mcd-white);
    font-size: 12px;
    font-weight: 600;
    padding: 8px 18px;
    border-radius: 999px;
    letter-spacing: 0.5px;
    animation: pulse 2s ease-in-out infinite;
    white-space: nowrap;
}
@keyframes pulse {
    0%, 100% { opacity: 0.6; }
    50%      { opacity: 1;   }
}
.splash-area .splash-footer {
    /* Pinned to the bottom via its own margin-bottom inset rather than
       margin-top: auto. With auto removed here, all of the flex column's
       free space is consumed by `.stamp-stack { margin-top: auto }`,
       which drops the stamp+tagline group down to (just past) vertical
       centre. The tagline's margin-bottom keeps the footer block stacked
       directly above the bottom inset, so the footer still sits flush
       to the bottom edge. */
    position: relative;
    margin-bottom: var(--splash-footer-bottom);
    left: 0;
    right: 0;
    text-align: center;
    color: var(--mcd-white);
    font-size: 11px;
    letter-spacing: 0.5px;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--splash-footer-gap, 0);
    z-index: 2;
}
.splash-area .splash-footer__caption {
    opacity: 0.7;
    margin-top: var(--splash-caption-margin);
}

/* =============================================================================
   Sponsor lockup — Coca-Cola x McDonald's co-branding (shared)
   Used in game-footer and splash-footer; loaded on every page via landing.css.
   ============================================================================= */
.sponsor-lockup {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
}
.sponsor-lockup__label {
    font-size: 9px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--mcd-grey);
}
.sponsor-lockup__img {
    display: block;
    width: 180px;
    max-width: 70%;
    height: auto;
    object-fit: contain;
}
.sponsor-lockup--on-dark .sponsor-lockup__img {
    background: #000000;
    padding: 2px 4px;
    border-radius: 6px;
}

/* =============================================================================
   SCR-002 — Invalid Link
   ============================================================================= */
.invalid-link {
    /* Same mobile cap as splash so both screens read as a phone column
       on desktop preview. */
    width: 100%;
    max-width: 480px;
    min-height: 100vh;
    background: var(--mcd-cream);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    padding: 0 32px;
    position: relative;
}
.invalid-link__icon {
    width: 72px;
    height: 72px;
    margin: 0 auto -32px;
    background: var(--mcd-yellow);
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--mcd-red);
    font-family: var(--font-display);
    font-weight: 900;
    font-size: 40px;
    line-height: 1;
    box-shadow: 0 8px 24px rgba(219, 0, 7, 0.20);
    position: relative;
    z-index: 2;
}
.invalid-link__card {
    background: var(--mcd-white);
    border-radius: var(--radius-xl);
    padding: 56px 28px 32px;
    width: 100%;
    max-width: 340px;
    text-align: center;
    box-shadow: var(--shadow-md);
    border: 1px solid var(--mcd-grey-light);
    position: relative;
}
.invalid-link__title {
    font-family: var(--font-display);
    font-weight: 800;
    font-size: 24px;
    line-height: 1.3;
    color: var(--mcd-black);
    margin-bottom: 12px;
}
.invalid-link__body {
    color: var(--mcd-charcoal);
    font-size: 15px;
    line-height: 1.5;
    margin-bottom: 24px;
}
.invalid-link__cta {
    display: inline-block;
    background: #00B14F;
    color: var(--mcd-white);
    text-decoration: none;
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 15px;
    padding: 14px 28px;
    border-radius: var(--radius-md);
    box-shadow: 0 4px 12px rgba(0, 177, 79, 0.35);
    transition: background 0.15s ease, transform 0.10s ease;
}
.invalid-link__cta:hover  { background: #008F42; }
.invalid-link__cta:active { transform: scale(0.98); }
.invalid-link__footer {
    position: absolute;
    bottom: 24px;
    left: 0;
    right: 0;
    text-align: center;
    color: var(--mcd-grey);
    font-size: 11px;
    letter-spacing: 0.5px;
}
