/* ── Variables ──
   Cell-shade system: solid fills, ink outlines, hard offset shadows.
   The house look is the Facebook meme art: chunky bubble type, cream
   surfaces, dusk-sky backdrop. No glass, no blur, no neon. */
:root {
    /* Dusk sky */
    --sky-top: #111539;
    --sky-mid: #2b2160;
    --sky-low: #4a2c68;

    /* Ink: the cartoon outline color. Never pure black. */
    --ink: #221839;
    --ink-deep: #140e2b;
    --ink-2: #6f5c49;               /* secondary text on cream */

    /* Signature gold */
    --gold: #ffd700;
    --gold-warm: #ffb347;
    --gold-deep: #c9821b;           /* extrude / pressed edge */
    --gold-soft: #fff8e1;

    /* Cream surfaces (card + plate faces) */
    --cream: #fff6e6;
    --cream-edge: #f1e0bd;          /* deck edges, shaded cream */
    --cream-line: rgba(255, 246, 230, 0.45);

    /* Text on the sky */
    --text-primary: #f6edda;
    --text-secondary: #d9cdb9;
    --focus-ring: #ffd700;

    /* Night plates (buttons that sit on the sky, not on a card) */
    --plum: #3d2c6b;
    --plum-line: rgba(246, 237, 218, 0.28);

    /* Hard shadows: cartoon depth, one system everywhere */
    --shadow-plate: 0 5px 0 var(--ink-deep);
    --shadow-plate-lift: 0 8px 0 var(--ink-deep);
    --shadow-plate-press: 0 2px 0 var(--ink-deep);
    --shadow-card: 0 8px 0 rgba(20, 14, 43, 0.55);
}

/* ── Reset ── */
*, *::before, *::after {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

html {
    height: 100%;
    /* The sky gradient lives on body, so it stops at the page edge. When a
       phone rubber-bands past that edge it paints the canvas instead, and
       an unpainted canvas is browser-default white. This is what fills the
       gutter: dark enough to read as more night sky above the page, and as
       ground continuing below the hills. */
    background-color: var(--ink-deep);
    /* The page is exactly viewport height and never scrolls, so the native
       bounce only ever revealed that bare canvas. Suppressing it hands the
       gesture to the pull-to-peek below, and stops the two fighting. */
    overscroll-behavior-y: none;
    /* A flung card sails 110vw to the right. Without this it stretches
       the viewport's scroll area to ~2.5x, and changing scroll bounds
       makes the browser re-raster the fixed starfield: every swipe blinks
       the stars out. clip (unlike hidden) creates no scroll area at all.
       Old browsers ignore it and fall back to body's overflow-x: hidden. */
    overflow-x: clip;
}

body {
    font-family: 'Nunito', system-ui, -apple-system, sans-serif;
    background: var(--sky-mid);
    background: linear-gradient(180deg, var(--sky-top) 0%, var(--sky-mid) 42%, var(--sky-low) 68%, #653a66 84%, #8c4f5c 100%);
    color: var(--text-primary);
    min-height: 100%;
    display: grid;
    place-items: center;
    padding: max(1.25rem, env(safe-area-inset-top)) max(1.25rem, env(safe-area-inset-right)) max(1.25rem, env(safe-area-inset-bottom)) max(1.25rem, env(safe-area-inset-left));
    line-height: 1.6;
    position: relative;
    overflow-y: auto;
    overflow-x: hidden;
    overscroll-behavior-y: none;
}

/* ── Starfield ──
   Stars live in the upper sky only; the horizon band belongs to the
   castle and its warm glow. */
.stars-container {
    position: fixed;
    inset: 0;
    bottom: 26%;
    pointer-events: none;
    z-index: 0;
    overflow: hidden;
}

.star {
    position: absolute;
    border-radius: 50%;
    background: #fff;
    will-change: opacity;
    animation: twinkle var(--dur, 4s) ease-in-out var(--del, 0s) infinite;
}

/* The dozen big stars get a four-point flare so the sky twinkles the
   way the meme art draws it, not like a generic particle field. */
.star--glow::before,
.star--glow::after {
    content: '';
    position: absolute;
    background: #fff;
    border-radius: 45%;
}

.star--glow::before {
    left: 50%;
    top: -115%;
    width: 30%;
    height: 330%;
    transform: translateX(-50%);
}

.star--glow::after {
    top: 50%;
    left: -115%;
    height: 30%;
    width: 330%;
    transform: translateY(-50%);
}

@keyframes twinkle {
    0%, 100% { opacity: var(--lo, 0.2); }
    50% { opacity: var(--hi, 0.8); }
}

/* ── Shooting Stars ── */
.shooting-star {
    position: fixed;
    top: 10%;
    left: 0;
    width: 100px;
    height: 1.5px;
    background: linear-gradient(to right, transparent 0%, rgba(255, 255, 255, 0.08) 20%, rgba(255, 255, 255, 0.5) 70%, #fff 100%);
    border-radius: 1px;
    opacity: 0;
    pointer-events: none;
    z-index: 0;
    transform: rotate(-35deg) translateX(-200px);
    animation: shoot 7s ease-in 5s infinite;
}

.shooting-star::after {
    content: '';
    position: absolute;
    right: -1px;
    top: -2px;
    width: 5px;
    height: 5px;
    border-radius: 50%;
    background: #fff;
    box-shadow: 0 0 6px 2px rgba(255, 255, 255, 0.7), 0 0 12px 4px rgba(255, 215, 0, 0.3);
}

.shooting-star:last-of-type {
    top: 25%;
    width: 70px;
    animation-delay: 14s;
    animation-duration: 9s;
}

@keyframes shoot {
    0% { transform: rotate(-35deg) translateX(-200px); opacity: 0; }
    4% { opacity: 1; }
    12% { opacity: 0.6; }
    18% { transform: rotate(-35deg) translateX(calc(100vw + 200px)); opacity: 0; }
    100% { transform: rotate(-35deg) translateX(calc(100vw + 200px)); opacity: 0; }
}

/* ── Horizon Glow ──
   Repurposed ambient layer: the warm band the castle sits in, per the
   house style guide ("atmospheric gradients for sky and mood"). */
.ambient-glow {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    top: auto;
    transform: none;
    width: auto;
    height: 38vh;
    background: linear-gradient(180deg, transparent 0%, rgba(214, 120, 86, 0.10) 45%, rgba(255, 157, 92, 0.22) 76%, rgba(255, 190, 120, 0.32) 100%);
    pointer-events: none;
    z-index: 0;
}

/* ── Castle Skyline ──
   Simplified silhouette, strong shapes, minimal detail: the exact
   background recipe from the brand's own style guide. */
.castle {
    position: fixed;
    left: 50%;
    bottom: 0;
    transform: translateX(-50%);
    /* Wider than the viewport on purpose: the land has to run past both
       edges, or the sky shows through at the corners. */
    width: max(102vw, 680px);
    height: auto;
    pointer-events: none;
    z-index: 0;
    display: block;
}

.castle-back {
    fill: #241b49;
}

.castle-main {
    fill: #170f33;
}

.castle-light {
    fill: #ffd784;
    animation: twinkle var(--dur, 5s) ease-in-out var(--del, 0s) infinite;
}

.castle-light:nth-of-type(odd) { --dur: 6s; --del: 1.6s; --lo: 0.35; --hi: 0.9; }
.castle-light:nth-of-type(even) { --dur: 4.5s; --del: 3s; --lo: 0.3; --hi: 0.8; }

/* A window somebody found. Ties with the :nth-of-type rules above on
   specificity and wins on source order, so it must not touch --lo/--hi. */
.castle-light.is-found {
    animation: none;
    fill: #fff4d2;
    opacity: 1;
}

.castle.is-celebrating .castle-light {
    animation: eggFlare 0.7s ease-in-out 3;
    fill: #fff4d2;
}

@keyframes eggFlare {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.3; }
}

/* A star crossing on request. Its own element rather than a reuse of the
   ambient pair, whose 7s loop we would otherwise have to fight. */
.wish-star {
    position: fixed;
    top: 15%;
    left: 0;
    width: 120px;
    height: 2px;
    background: linear-gradient(to right, transparent 0%, rgba(255, 255, 255, 0.1) 20%, rgba(255, 255, 255, 0.6) 70%, #fff 100%);
    border-radius: 1px;
    opacity: 0;
    pointer-events: none;
    z-index: 0;
    transform: rotate(-35deg) translateX(-240px);
    animation: eggWish 1.5s ease-in forwards;
}

.wish-star::after {
    content: '';
    position: absolute;
    right: -1px;
    top: -2.5px;
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: #fff;
    box-shadow: 0 0 8px 3px rgba(255, 255, 255, 0.8), 0 0 16px 6px rgba(255, 215, 0, 0.4);
}

@keyframes eggWish {
    0% { transform: rotate(-35deg) translateX(-240px); opacity: 0; }
    8% { opacity: 1; }
    75% { opacity: 0.85; }
    100% { transform: rotate(-35deg) translateX(calc(100vw + 260px)); opacity: 0; }
}

/* ── Utilidors ──
   Pull up on the ground under the castle and it lifts, showing the
   service level the park actually runs on. Kept short enough that it
   never reaches the CTA, so the sign is always the thing you read. */
.utilidor {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 0;
    height: 124px;
    display: flex;
    /* Only the top of this strip is ever uncovered, so the sign lives up
       there where a short pull already reveals it. */
    align-items: flex-start;
    justify-content: center;
    padding-top: 8px;
    background: linear-gradient(180deg, #241a3f 0%, #17102e 45%, #120c24 100%);
    box-shadow: inset 0 14px 26px rgba(0, 0, 0, 0.6);
    pointer-events: none;
    /* Parked completely below the fold. Relying on the castle to hide it
       does not work: the archway is a hole and the hills do not span the
       full width, so it showed through on wide screens. */
    transform: translateY(100%);
}

/* Rises at exactly the speed the ground lifts, so its top edge stays
   welded to the castle's bottom edge and it reads as being uncovered. */
body.is-peek .utilidor {
    transform: translateY(calc(100% - var(--lift, 0px)));
}

/* The strip light every backstage corridor has */
.utilidor::before {
    content: '';
    position: absolute;
    top: 3px;
    left: 14%;
    right: 14%;
    height: 3px;
    border-radius: 2px;
    background: rgba(255, 215, 132, 0.5);
    box-shadow: 0 0 14px 3px rgba(255, 215, 132, 0.22);
}

.utilidor__sign {
    padding: 0.5rem 1.4rem 0.45rem;
    border-radius: 12px;
    border: 2.5px solid var(--ink);
    background: var(--cream);
    box-shadow: 0 4px 0 var(--ink-deep);
    text-align: center;
}

.utilidor__title {
    display: block;
    font-family: 'Lilita One', 'Fredoka', system-ui, sans-serif;
    font-size: 1.15rem;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--ink);
    line-height: 1.2;
}

.utilidor__sub {
    display: block;
    font-size: 0.7rem;
    font-weight: 800;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--ink-2);
}

/* ── Pull to peek ──
   The page never scrolls, so the browser's rubber-band was only ever
   showing bare canvas. We take that gesture over: the scene rides the
   finger upward and what it uncovers is the corridor above, not a
   gap. --lift is written by eggs.js while the finger is down. */
body.is-peek .castle {
    transform: translateX(-50%) translateY(calc(var(--lift, 0px) * -1));
}

/* Parallax: the ground is nearest so it travels furthest, and holding the
   content back keeps the wordmark clear of the top edge at full pull. */
body.is-peek .view,
body.is-peek .ambient-glow {
    transform: translateY(calc(var(--lift, 0px) * -0.55));
}

/* Applied only on release, so the drag itself stays 1:1 with the finger */
body.is-peek.is-settling .castle,
body.is-peek.is-settling .view,
body.is-peek.is-settling .ambient-glow,
body.is-peek.is-settling .utilidor {
    transition: transform 0.44s cubic-bezier(0.16, 1, 0.3, 1);
}

/* ── Layout ── */
main {
    max-width: 800px;
    width: 100%;
    text-align: center;
    position: relative;
    z-index: 1;
}

/* ── Title ──
   The wordmark, drawn the way the memes letter their headers: chunky
   gold bubble type, ink outline, hard 3D extrude. */
h1 {
    font-family: 'Lilita One', 'Fredoka', system-ui, sans-serif;
    font-size: clamp(2.4rem, 8.5vw, 4.1rem);
    font-weight: 400;
    -webkit-user-select: none;
    user-select: none;
    -webkit-tap-highlight-color: transparent;
    color: var(--gold);
    -webkit-text-stroke: 0.045em var(--ink);
    paint-order: stroke fill;
    text-shadow:
        0 0.045em 0 var(--gold-deep),
        0 0.1em 0 var(--ink),
        0 0.22em 0.35em rgba(10, 6, 24, 0.45);
    margin-bottom: 1.25rem;
    letter-spacing: 0.01em;
    line-height: 1.15;
    position: relative;
    opacity: 0;
    animation: fadeInUp 0.9s ease-out 0.3s forwards;
}

/* ── Letter Hover Effects ── */
.letter {
    display: inline-block;
    transition: transform 0.3s ease, color 0.3s ease, text-shadow 0.3s ease;
    cursor: default;
}

/* Hand-placed jitter: each letter sits a hair off its baseline, the way
   the meme headers are lettered. Hover transforms simply override it. */
.letter:nth-child(odd) { transform: rotate(-1.6deg); }
.letter:nth-child(even) { transform: rotate(1.8deg) translateY(1px); }
.letter:nth-child(4n) { transform: rotate(-1deg) translateY(-1.5px); }

/* M - Bright Purple */
.letter:nth-child(1):hover,
.letter:nth-child(1).is-lit {
    transform: translateY(-10px) scale(1.15);
    color: #c77dff;
    text-shadow: 0 0.045em 0 #7a3fb8, 0 0.1em 0 var(--ink), 0 0.22em 0.4em rgba(199, 125, 255, 0.55);
}

/* a - Hot Pink */
.letter:nth-child(2):hover,
.letter:nth-child(2).is-lit {
    transform: rotate(15deg) scale(1.15);
    color: #ff69db;
    text-shadow: 0 0.045em 0 #b83a98, 0 0.1em 0 var(--ink), 0 0.22em 0.4em rgba(255, 105, 219, 0.55);
}

/* g - Electric Blue */
.letter:nth-child(3):hover,
.letter:nth-child(3).is-lit {
    color: #69b3ff;
    text-shadow: 0 0.045em 0 #2f6cbd, 0 0.1em 0 var(--ink), 0 0.22em 0.4em rgba(105, 179, 255, 0.55);
    animation: letterBounce 0.5s ease;
}

@keyframes letterBounce {
    0%, 100% { transform: translateY(-12px) scale(1.2); }
    50% { transform: translateY(-18px) scale(1.25); }
}

/* i - Bright Gold Sparkle */
.letter:nth-child(4):hover,
.letter:nth-child(4).is-lit {
    transform: translateY(-8px) scale(1.15);
    color: #ffe066;
    text-shadow: 0 0.045em 0 var(--gold-deep), 0 0.1em 0 var(--ink), 0 0.22em 0.4em rgba(255, 215, 0, 0.6);
}

/* c - Bright Teal */
.letter:nth-child(5):hover,
.letter:nth-child(5).is-lit {
    color: #4aeaaa;
    text-shadow: 0 0.045em 0 #1f9c68, 0 0.1em 0 var(--ink), 0 0.22em 0.4em rgba(74, 234, 170, 0.55);
    animation: letterWiggle 0.4s ease;
}

@keyframes letterWiggle {
    0%, 100% { transform: rotate(0deg) scale(1.15); }
    25% { transform: rotate(-10deg) scale(1.15); }
    75% { transform: rotate(10deg) scale(1.15); }
}

/* a - Coral */
.letter:nth-child(6):hover,
.letter:nth-child(6).is-lit {
    color: #ff6b7a;
    text-shadow: 0 0.045em 0 #c23545, 0 0.1em 0 var(--ink), 0 0.22em 0.4em rgba(255, 107, 122, 0.55);
    animation: letterPulse 0.5s ease;
}

@keyframes letterPulse {
    0%, 100% { transform: scale(1.15); }
    50% { transform: scale(1.3); }
}

/* l - Lavender */
.letter:nth-child(7):hover,
.letter:nth-child(7).is-lit {
    transform: rotate(-15deg) scale(1.15);
    color: #c9a8f0;
    text-shadow: 0 0.045em 0 #8a63c2, 0 0.1em 0 var(--ink), 0 0.22em 0.4em rgba(201, 168, 240, 0.55);
}

/* D - Royal Blue */
.letter:nth-child(8):hover,
.letter:nth-child(8).is-lit {
    transform: translateY(-10px) scale(1.2);
    color: #6b8fff;
    text-shadow: 0 0.045em 0 #3a55b8, 0 0.1em 0 var(--ink), 0 0.22em 0.4em rgba(107, 143, 255, 0.55);
}

/* a - Rose */
.letter:nth-child(9):hover,
.letter:nth-child(9).is-lit {
    color: #ff4d8d;
    text-shadow: 0 0.045em 0 #bd2a5e, 0 0.1em 0 var(--ink), 0 0.22em 0.4em rgba(255, 77, 141, 0.55);
    animation: letterShimmer 0.6s ease;
}

@keyframes letterShimmer {
    0% { transform: scale(1.15); filter: hue-rotate(0deg); }
    50% { transform: scale(1.25); filter: hue-rotate(25deg); }
    100% { transform: scale(1.15); filter: hue-rotate(0deg); }
}

/* d - Mint */
.letter:nth-child(10):hover,
.letter:nth-child(10).is-lit {
    transform: translateY(-9px) scale(1.18);
    color: #6ff0b7;
    text-shadow: 0 0.045em 0 #2fa574, 0 0.1em 0 var(--ink), 0 0.22em 0.4em rgba(111, 240, 183, 0.55);
}

/* B - Vivid Purple */
.letter:nth-child(11):hover,
.letter:nth-child(11).is-lit {
    transform: translateY(-14px) scale(1.25);
    color: #a066e0;
    text-shadow: 0 0.045em 0 #6a3aa5, 0 0.1em 0 var(--ink), 0 0.22em 0.4em rgba(160, 102, 224, 0.6);
}

/* l - Light Lavender */
.letter:nth-child(12):hover,
.letter:nth-child(12).is-lit {
    transform: rotate(20deg) scale(1.15);
    color: #d4c4f0;
    text-shadow: 0 0.045em 0 #9a85c4, 0 0.1em 0 var(--ink), 0 0.22em 0.4em rgba(212, 196, 240, 0.55);
}

/* o - Sky Blue */
.letter:nth-child(13):hover,
.letter:nth-child(13).is-lit {
    color: #7dd8f0;
    text-shadow: 0 0.045em 0 #3a97b5, 0 0.1em 0 var(--ink), 0 0.22em 0.4em rgba(125, 216, 240, 0.6);
    animation: letterBubble 0.5s ease;
}

@keyframes letterBubble {
    0%, 100% { transform: scale(1.15); }
    50% { transform: scale(1.28) translateY(-6px); }
}

/* g - Magenta */
.letter:nth-child(14):hover,
.letter:nth-child(14).is-lit {
    transform: scale(1.2);
    color: #e066d6;
    text-shadow: 0 0.045em 0 #a53a9c, 0 0.1em 0 var(--ink), 0 0.22em 0.4em rgba(224, 102, 214, 0.6);
}

/* ── Sticky hover, defused ──
   A touch device applies :hover on tap and keeps it there until you tap
   somewhere else, so the last letter you touched stayed lit for good and
   the 950ms .is-lit decay could never clear it. Most visible after the
   M-D-B egg, because that sequence ends on the B.

   :not(.is-lit) leaves the touch effect alone for its 950ms and only then
   hands the letter back to rest. The transforms restore the hand-lettered
   jitter that the hover rules had been overriding.

   Deliberately does NOT touch animation. This block is (0,4,0) and would
   out-specify the wave at h1.egg-wave .letter (0,2,1), which stopped the
   hover-stuck letter joining the M-D-B ripple. The per-letter hover
   animations are one-shot with no fill, so they need no suppressing. */
@media (hover: none) {
    .letter:nth-child(n):hover:not(.is-lit) {
        color: inherit;
        text-shadow: inherit;
        transform: rotate(-1.6deg);
    }

    .letter:nth-child(2n):hover:not(.is-lit) {
        transform: rotate(1.8deg) translateY(1px);
    }

    .letter:nth-child(4n):hover:not(.is-lit) {
        transform: rotate(-1deg) translateY(-1.5px);
    }
}

/* ── Wordmark wave ──
   The per-letter :is-lit rules above are (0,3,0) and would out-specify
   any plain class here. An animation wins regardless: animated values
   outrank normal declarations no matter what the selector weighs.
   --i is stamped on each letter by eggs.js, so one rule staggers all 14. */
h1.egg-wave .letter {
    animation: eggWave 1s ease-in-out both;
    animation-delay: calc(var(--i, 0) * 55ms);
}

@keyframes eggWave {
    0% { transform: translateY(0) scale(1); filter: hue-rotate(0deg); }
    30% { transform: translateY(-15px) scale(1.18); filter: hue-rotate(130deg); }
    60% { transform: translateY(0) scale(1.04); filter: hue-rotate(255deg); }
    100% { transform: translateY(0) scale(1); filter: hue-rotate(360deg); }
}

/* Colour only, no travel: the reduced-motion reward. */
@keyframes eggWaveCalm {
    0%, 100% { filter: hue-rotate(0deg); }
    50% { filter: hue-rotate(220deg); }
}

/* ── Title Underline ──
   A chunky painted stroke instead of a light beam. */
h1::after {
    content: '';
    position: absolute;
    bottom: -10px;
    left: 50%;
    transform: translateX(-50%);
    width: 0;
    height: 5px;
    background: var(--gold);
    border-radius: 4px;
    box-shadow: 0 3px 0 var(--ink);
    animation: underlineDraw 1s ease-out 1.3s forwards, underlineGlow 3s ease-in-out 2.5s infinite;
}

@keyframes underlineDraw {
    to { width: 62%; }
}

@keyframes underlineGlow {
    0%, 100% { opacity: 0.85; }
    50% { opacity: 1; }
}

/* ── Entrance Animation ── */
@keyframes fadeInUp {
    from {
        opacity: 0;
        transform: translateY(24px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

/* ── Tagline ── */
.tagline {
    font-size: clamp(1.05rem, 3.5vw, 1.3rem);
    color: var(--text-secondary);
    margin-bottom: 0;
    padding: 0 1rem;
    font-weight: 600;
    opacity: 0;
    animation: fadeInUp 0.8s ease-out 0.6s forwards;
}

/* ── Separator ──
   Stitch lines and the house four-point star. */
.separator {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 1rem;
    margin: 1.75rem 0 2.25rem;
    opacity: 0;
    animation: fadeInUp 0.8s ease-out 0.8s forwards;
}

.separator::before,
.separator::after {
    content: '';
    width: 48px;
    height: 0;
    border-top: 2px dashed var(--cream-line);
}

.separator span {
    color: var(--gold);
    font-size: 0.8rem;
    text-shadow: 0 2px 0 rgba(20, 14, 43, 0.6);
    animation: starPulse 2.5s ease-in-out infinite;
    line-height: 1;
}

@keyframes starPulse {
    0%, 100% { opacity: 0.45; transform: scale(1); }
    50% { opacity: 1; transform: scale(1.15); }
}

/* Held down, the star charges. Beats starPulse on specificity.
   The select/callout suppression is what stops iOS popping its text
   selection bubble halfway through a deliberate long press. */
.separator {
    -webkit-user-select: none;
    user-select: none;
    -webkit-touch-callout: none;
}

.separator.is-charging span {
    animation: eggCharge 1.5s ease-out forwards;
}

@keyframes eggCharge {
    0% { transform: scale(1); opacity: 0.5; }
    100% { transform: scale(2.7); opacity: 1; }
}

/* ── Social Buttons ── */
.social-buttons {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    align-items: center;
}

@media (min-width: 640px) {
    .social-buttons {
        flex-direction: row;
        justify-content: center;
        gap: 1.1rem;
    }
}

/* ── Social Link ──
   Label plates from the meme sheets: solid platform color, ink outline,
   hard shadow, squash on press. */
.social-link {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.7rem;
    color: #ffffff;
    text-decoration: none;
    padding: 0.85rem 1.75rem;
    border-radius: 16px;
    font-family: 'Lilita One', 'Fredoka', system-ui, sans-serif;
    font-weight: 400;
    font-size: 1.05rem;
    letter-spacing: 0.03em;
    min-width: 190px;
    min-height: 50px;
    border: 3px solid var(--ink);
    box-shadow: var(--shadow-plate);
    transition: transform 0.25s ease, box-shadow 0.25s ease;
    position: relative;
    overflow: hidden;
    opacity: 0;
    animation: fadeInUp 0.7s ease-out forwards;
}

.social-link:nth-child(1) { animation-delay: 1s; }
.social-link:nth-child(2) { animation-delay: 1.15s; }
.social-link:nth-child(3) { animation-delay: 1.3s; }

/* Gloss sweep: the cartoon shine pass */
.social-link::before {
    content: '';
    position: absolute;
    top: 0;
    left: -100%;
    width: 100%;
    height: 100%;
    background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.18), transparent);
    transition: left 0.6s ease;
}

.social-link:hover::before {
    left: 100%;
}

.social-link:hover {
    transform: translateY(-3px);
    box-shadow: var(--shadow-plate-lift);
}

.social-link:focus {
    outline: 3px solid var(--focus-ring);
    outline-offset: 3px;
}

.social-link:active {
    transform: translateY(3px);
    box-shadow: var(--shadow-plate-press);
}

/* ── Platform Variants ── */
.social-link--facebook {
    background: #1660cf;
}

.social-link--threads {
    background: #241b38;
}

.social-link--instagram {
    background: #d6306e;
}

/* ── Social Icons ── */
.social-icon {
    width: 22px;
    height: 22px;
    fill: currentColor;
    flex-shrink: 0;
    filter: drop-shadow(0 1.5px 0 rgba(20, 14, 43, 0.45));
}

.social-link span {
    min-width: 80px;
    text-align: left;
    text-shadow: 0 1.5px 0 rgba(20, 14, 43, 0.45);
}

@media (min-width: 640px) {
    .social-link span {
        min-width: 0;
        text-align: center;
    }
}

/* ── Firework Particles ── */
.sparkle {
    position: fixed;
    border-radius: 50%;
    pointer-events: none;
    z-index: 100;
}

.sparkle--out {
    animation: fireworkOut var(--dur, 0.7s) ease-out var(--del, 0s) forwards;
}

.sparkle--droop {
    animation: fireworkDroop var(--dur, 1s) ease-out var(--del, 0s) forwards;
}

.sparkle--twinkle {
    animation: fireworkTwinkle var(--dur, 0.6s) ease-out var(--del, 0s) forwards;
}

@keyframes fireworkOut {
    0% { transform: translate(0, 0) scale(1); opacity: 1; }
    40% { opacity: 1; }
    100% { transform: translate(var(--tx, 10px), var(--ty, -10px)) scale(0); opacity: 0; }
}

@keyframes fireworkDroop {
    0% { transform: translate(0, 0) scale(1); opacity: 1; }
    35% { transform: translate(calc(var(--tx, 10px) * 0.5), calc(var(--ty, -10px) * 0.5)) scale(0.85); opacity: 1; }
    100% { transform: translate(calc(var(--tx, 10px) * 0.75), calc(var(--ty, -10px) + var(--grav, 50px))) scale(0.15); opacity: 0; }
}

@keyframes fireworkTwinkle {
    0% { transform: translate(0, 0) scale(1); opacity: 1; }
    25% { opacity: 0.25; }
    50% { transform: translate(calc(var(--tx, 10px) * 0.5), calc(var(--ty, -10px) * 0.5)) scale(0.7); opacity: 1; }
    75% { opacity: 0.15; }
    100% { transform: translate(var(--tx, 10px), var(--ty, -10px)) scale(0); opacity: 0; }
}

/* ── Shape Formation (fly out → hold → disperse) ── */
.sparkle--shape {
    animation: fireworkShape var(--dur, 1.4s) ease-out var(--del, 0s) forwards;
}

@keyframes fireworkShape {
    0% { transform: translate(0, 0) scale(0.5); opacity: 0.9; }
    30% { transform: translate(var(--tx, 0px), var(--ty, 0px)) scale(1); opacity: 1; }
    100% { transform: translate(calc(var(--tx, 0px) * 1.8), calc(var(--ty, 0px) * 1.8)) scale(0); opacity: 0; }
}

/* ── Grand Finale Flash ── */
.firework-flash {
    position: fixed;
    pointer-events: none;
    z-index: 99;
    border-radius: 50%;
    background: radial-gradient(circle, rgba(255, 255, 255, 0.5) 0%, rgba(255, 255, 255, 0.15) 40%, transparent 70%);
    animation: flashFade 0.6s ease-out forwards;
    transform: translate(-50%, -50%);
}

@keyframes flashFade {
    0% { opacity: 1; width: 20px; height: 20px; }
    100% { opacity: 0; width: 240px; height: 240px; }
}

/* ── Views ── */
.view {
    display: none;
    max-width: 800px;
    width: 100%;
    text-align: center;
    position: relative;
    z-index: 1;
}

.view.is-active {
    display: block;
    animation: fadeIn 0.35s ease-out;
}

main.view {
    display: none;
}

main.view.is-active {
    display: block;
}

/* ── Play CTA (landing) ──
   The showpiece plate: gold, ticket-dashed inside. */
.play-cta {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.25rem;
    margin: 1.75rem auto 0;
    padding: 1.1rem 2rem;
    max-width: 400px;
    width: 100%;
    text-decoration: none;
    border-radius: 16px;
    background: linear-gradient(180deg, #ffdb5e, var(--gold-warm));
    border: 3px solid var(--ink);
    box-shadow: var(--shadow-plate);
    transition: transform 0.25s ease, box-shadow 0.25s ease;
    position: relative;
    overflow: hidden;
    opacity: 0;
    animation: fadeInUp 0.7s ease-out 1.45s forwards;
}

.play-cta::after {
    content: '';
    position: absolute;
    inset: 5px;
    border-radius: 10px;
    border: 2px dashed rgba(34, 24, 57, 0.3);
    pointer-events: none;
}

.play-cta::before {
    content: '';
    position: absolute;
    top: 0;
    left: -100%;
    width: 100%;
    height: 100%;
    background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.35), transparent);
    transition: left 0.6s ease;
}

.play-cta:hover::before {
    left: 100%;
}

.play-cta:hover {
    transform: translateY(-3px);
    box-shadow: var(--shadow-plate-lift);
}

.play-cta:focus {
    outline: 3px solid #fff;
    outline-offset: 3px;
}

.play-cta:active {
    transform: translateY(3px);
    box-shadow: var(--shadow-plate-press);
}

.play-cta__title {
    font-family: 'Lilita One', 'Fredoka', system-ui, sans-serif;
    font-weight: 400;
    font-size: 1.3rem;
    letter-spacing: 0.02em;
    color: var(--ink);
}

.play-cta__sub {
    font-size: 0.85rem;
    color: rgba(34, 24, 57, 0.75);
    font-weight: 700;
}

/* ── Utility ── */
.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
}

.view--play {
    max-width: 520px;
    padding: 0.5rem 0 1rem;
}

/* ── Game Header Bar ── */
.game-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    margin-bottom: 1.5rem;
}

.back-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.5rem 1rem;
    min-height: 42px;
    border-radius: 12px;
    border: 2.5px solid var(--ink);
    background: var(--cream);
    color: var(--ink);
    font-family: 'Nunito', system-ui, sans-serif;
    font-weight: 800;
    font-size: 0.9rem;
    text-decoration: none;
    cursor: pointer;
    box-shadow: 0 4px 0 var(--ink-deep);
    transition: transform 0.25s ease, box-shadow 0.25s ease;
}

.back-btn:hover {
    transform: translateY(-2px);
    box-shadow: 0 6px 0 var(--ink-deep);
}

.back-btn:active {
    transform: translateY(2px);
    box-shadow: 0 1px 0 var(--ink-deep);
}

.back-btn:focus {
    outline: 3px solid var(--focus-ring);
    outline-offset: 3px;
}

.game-count {
    font-family: 'Lilita One', 'Fredoka', system-ui, sans-serif;
    font-size: 0.78rem;
    font-weight: 400;
    letter-spacing: 0.14em;
    color: var(--text-secondary);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
}

.count-num {
    display: inline-block;
    font-size: 1.15rem;
    color: var(--gold);
    text-shadow: 0 2px 0 rgba(20, 14, 43, 0.7);
}

.count-num.pop {
    animation: countPop 0.35s ease;
}

@keyframes countPop {
    0% { transform: scale(1); }
    45% { transform: scale(1.35); }
    100% { transform: scale(1); }
}

/* ── The Deck ── */
.deck-area {
    position: relative;
    perspective: 1200px;
    /* Horizontal moves belong to the swipe handler; keep vertical native */
    touch-action: pan-y;
    /* Mouse drags must move the card, never select its text */
    -webkit-user-select: none;
    user-select: none;
    margin: 0 auto;
    text-align: center;
}

.deck-edge {
    position: absolute;
    inset: 0;
    border-radius: 20px;
    border: 2.5px solid var(--ink);
    background: var(--cream-edge);
    pointer-events: none;
    transition: transform 0.2s ease;
}

.deck-edge--a { transform: rotate(2deg) translateY(8px); }
.deck-edge--b { transform: rotate(-1.6deg) translateY(4px); }

/* While a card is being pulled away, the deck rises to meet the deal */
.deck-area.is-dragging .deck-edge--a {
    transform: rotate(1.2deg) translateY(5px);
}

.deck-area.is-dragging .deck-edge--b {
    transform: rotate(-1deg) translateY(2px);
}

/* ── Card Chassis ── */
.game-card {
    --ac: 255, 215, 0;
    position: relative;
    z-index: 1;
    -webkit-tap-highlight-color: transparent;
}

/* Entrance animations are opt-in: only freshly dealt cards get one.
   A promoted peek card has none to restart, so it stays put. */
.game-card.deal-in {
    animation: dealIn 0.42s cubic-bezier(0.16, 1, 0.3, 1);
}

/* Brand pop accents: bubblegum pink, lavender, Pascal green, Crinkle blue */
.card--pick { --ac: 255, 111, 156; }
.card--talk { --ac: 185, 138, 240; }
.card--joke { --ac: 78, 207, 131; }
.card--emoji { --ac: 88, 167, 255; }

.game-card.deal-out {
    animation: dealOut 0.18s ease-in forwards;
}

@keyframes dealIn {
    from { opacity: 0; transform: translateY(32px) rotate(2deg) scale(0.97); }
    to { opacity: 1; transform: none; }
}

@keyframes dealOut {
    to { opacity: 0; transform: translateY(-22px) rotate(-1deg) scale(0.98); }
}

.game-card.deal-back {
    animation: dealInBack 0.42s cubic-bezier(0.16, 1, 0.3, 1);
}

.game-card.deal-out-back {
    animation: dealOutBack 0.18s ease-in forwards;
}

/* A flung card leaves the layout so its replacement deals in under it */
.game-card.is-flung {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    z-index: 2;
    pointer-events: none;
}

/* The destination card peeks through with its real content mid-drag */
.game-card.is-under {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    z-index: 0;
    pointer-events: none;
    animation: none;
}

@keyframes dealInBack {
    from { opacity: 0; transform: translateY(-28px) rotate(-1.5deg) scale(0.97); }
    to { opacity: 1; transform: none; }
}

@keyframes dealOutBack {
    to { opacity: 0; transform: translateY(26px) rotate(1deg) scale(0.98); }
}

.flip-wrap {
    position: relative;
    transform-style: preserve-3d;
    transition: transform 0.55s cubic-bezier(0.4, 0.15, 0.2, 1);
}

.game-card.is-flipped .flip-wrap {
    transform: rotateY(180deg);
}

/* Card faces are cream game cards with ink outlines and a cel-shade
   bottom edge, like the props on the meme sheets. */
.card-face {
    position: relative;
    min-height: 340px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 1rem;
    padding: 1.6rem 1.4rem 1.8rem;
    border-radius: 20px;
    border: 3px solid var(--ink);
    background: var(--cream);
    box-shadow: inset 0 -6px 0 rgba(201, 130, 27, 0.18), var(--shadow-card);
    -webkit-backface-visibility: hidden;
    backface-visibility: hidden;
    overflow: hidden;
    color: var(--ink);
}

.card-face--back {
    position: absolute;
    inset: 0;
    transform: rotateY(180deg);
}

/* ── Hiding the face that turned away ──
   backface-visibility is not inherited, so while the face itself computes
   to hidden, its children compute to visible. Mid-flip the browser gives
   the button its own compositing layer, it escapes the parent's backface
   cull, and you see "Reveal the punchline" mirrored over the answer.

   So the face is taken out entirely, switched at the halfway mark of the
   0.55s turn. visibility is a discrete property, so the delay is what
   times it; keep the two in step if the flip duration ever changes. It
   also stops the hidden face's buttons being tappable, which they were. */
.card-face {
    transition: visibility 0s linear 0.275s;
}

.card-face--back {
    visibility: hidden;
}

.game-card.is-flipped .card-face--back {
    visibility: visible;
}

.game-card.is-flipped .card-face:not(.card-face--back) {
    visibility: hidden;
}

/* ── Type Chip ──
   The folder-tab label from the meme sheets: solid accent, ink text. */
.card-chip {
    position: relative;
    overflow: hidden;
    font-family: 'Lilita One', 'Fredoka', system-ui, sans-serif;
    font-size: 0.72rem;
    font-weight: 400;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--ink);
    padding: 0.4rem 1rem 0.34rem;
    border-radius: 999px;
    border: 2px solid var(--ink);
    background: rgb(var(--ac));
    box-shadow: 0 2.5px 0 rgba(20, 14, 43, 0.55);
}

.card-chip::after {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    width: 55%;
    height: 100%;
    background: linear-gradient(105deg, transparent, rgba(255, 255, 255, 0.45), transparent);
    transform: translateX(-160%) skewX(-18deg);
    animation: chipGlint 0.9s ease-out 0.35s forwards;
}

@keyframes chipGlint {
    to { transform: translateX(300%) skewX(-18deg); }
}

/* ── Card Text ── */
.card-lead {
    font-size: 0.95rem;
    font-weight: 800;
    color: var(--ink-2);
}

.card-text {
    font-size: clamp(1.2rem, 4.6vw, 1.5rem);
    font-weight: 800;
    line-height: 1.45;
    color: var(--ink);
}

/* Intro card footnote: the trust line, quieter than the lead */
.intro-meta {
    font-size: 0.8rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    color: var(--ink-2);
    opacity: 0.85;
}

/* ── Intro card: a ticket, not a deck card ──
   Wears the landing CTA's gold so the gold thing you tapped and the
   gold card that greets you read as one object. The dashed inset ring
   is the admission-ticket wink behind "Deal me in". */
/* The resume card rides along: same ticket, different errand, so a
   group coming back off a ride recognises it before reading it. */
.card--intro .card-face,
.card--resume .card-face {
    background: linear-gradient(180deg, #ffe9ad, #ffd781);
}

.card--intro .card-face::after,
.card--resume .card-face::after {
    content: '';
    position: absolute;
    inset: 7px;
    border-radius: 14px;
    border: 2px dashed rgba(34, 24, 57, 0.3);
    pointer-events: none;
}

.card-face--back .card-text {
    font-size: clamp(1.35rem, 5.2vw, 1.7rem);
}

/* ── Choice Option (WYR + Lightning) ── */
.card-opt {
    width: 100%;
    min-height: 58px;
    padding: 0.95rem 1.1rem;
    border-radius: 14px;
    border: 2.5px solid var(--ink);
    background: rgba(var(--ac), 0.16);
    color: var(--ink);
    font-family: 'Nunito', system-ui, sans-serif;
    font-weight: 800;
    font-size: clamp(1rem, 3.9vw, 1.15rem);
    line-height: 1.35;
    cursor: pointer;
    box-shadow: 0 4px 0 rgba(20, 14, 43, 0.7);
    transition: transform 0.22s ease, opacity 0.22s ease, background 0.22s ease, box-shadow 0.22s ease;
}

.card-opt:focus-visible {
    outline: 3px solid var(--ink);
    outline-offset: 3px;
}

.card-opt:active {
    transform: translateY(3px);
    box-shadow: 0 1px 0 rgba(20, 14, 43, 0.7);
}

.card-opt.is-picked {
    transform: scale(1.02);
    background: linear-gradient(180deg, #ffdb5e, var(--gold-warm));
    box-shadow: 0 4px 0 var(--gold-deep);
    color: var(--ink);
}

.card-face.has-pick .card-opt:not(.is-picked) {
    opacity: 0.45;
    transform: scale(0.97);
}

/* ── OR Star (WYR) ── */
.or-star {
    position: relative;
    width: 46px;
    height: 46px;
    margin: 0.05rem auto;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    border-radius: 50%;
    border: 2.5px solid var(--ink);
    background: var(--gold);
    color: var(--ink);
    box-shadow: 0 3px 0 rgba(20, 14, 43, 0.55);
    font-family: 'Lilita One', 'Fredoka', system-ui, sans-serif;
    font-size: 0.82rem;
    font-weight: 400;
    letter-spacing: 0.08em;
}

.or-star::before {
    content: '';
    position: absolute;
    inset: -8px;
    border-radius: 50%;
    background: radial-gradient(circle 2.5px at 50% 2px, var(--gold-deep) 40%, transparent 70%);
    animation: orbit 6s linear infinite;
}

@keyframes orbit {
    to { transform: rotate(360deg); }
}

/* ── VS Badge (This or That) ──
   The house asset from the meme system: round badge, blue and red
   split, lightning bolt. Fixed colors on purpose — like the gold,
   it is the same badge everywhere the brand uses it. */
.vs-divider {
    position: relative;
    width: 44px;
    height: 44px;
    margin: 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    /* Hard split, not a blend: the house style is cel-shaded edges */
    background: linear-gradient(105deg, #3b7dd8 50%, #e04848 50%);
    border: 2.5px solid var(--ink);
    box-shadow: 0 3px 0 rgba(20, 14, 43, 0.55);
    font-family: 'Lilita One', 'Fredoka', system-ui, sans-serif;
    font-size: 1rem;
    font-weight: 400;
    color: #fff;
    letter-spacing: 0.03em;
    text-shadow: 0 1.5px 0 rgba(20, 14, 43, 0.6);
}

.vs-divider::after {
    content: '\26A1';
    position: absolute;
    top: -8px;
    right: -7px;
    font-size: 0.7rem;
    filter: drop-shadow(0 1px 1px rgba(0, 0, 0, 0.4));
}

/* ── Table Talk ── */
.talk-seal {
    width: 36px;
    height: 36px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    border: 2.5px solid var(--ink);
    background: var(--gold);
    color: var(--ink);
    box-shadow: 0 3px 0 rgba(20, 14, 43, 0.55);
    font-size: 0.9rem;
}

.card--talk .card-face::after {
    content: '';
    position: absolute;
    top: -60%;
    left: 0;
    width: 55%;
    height: 220%;
    background: linear-gradient(100deg, transparent, rgba(185, 138, 240, 0.1) 44%, rgba(255, 255, 255, 0.35) 50%, rgba(185, 138, 240, 0.1) 56%, transparent);
    transform: translateX(-240%) rotate(8deg);
    animation: foilSweep 9s ease-in-out infinite;
    pointer-events: none;
}

@keyframes foilSweep {
    0%, 72% { transform: translateX(-240%) rotate(8deg); }
    92%, 100% { transform: translateX(440%) rotate(8deg); }
}

/* ── Emoji Guess ── */
.emoji-clue {
    font-size: clamp(2.2rem, 10vw, 3.1rem);
    line-height: 1.3;
    letter-spacing: 0.14em;
    /* Emoji paint their own colors; a soft accent halo ties them in */
    filter: drop-shadow(0 3px 0 rgba(var(--ac), 0.35));
}

/* ── Dad Joke Reveal ── */
.reveal-btn {
    margin-top: 0.35rem;
    padding: 0.85rem 1.7rem;
    min-height: 50px;
    border-radius: 14px;
    border: 2.5px solid var(--ink);
    background: rgb(var(--ac));
    color: var(--ink);
    font-family: 'Lilita One', 'Fredoka', system-ui, sans-serif;
    font-weight: 400;
    font-size: 1.05rem;
    letter-spacing: 0.02em;
    cursor: pointer;
    box-shadow: 0 4px 0 rgba(20, 14, 43, 0.7);
    transition: transform 0.22s ease, box-shadow 0.22s ease;
}

.reveal-btn:hover {
    transform: translateY(-2px);
    box-shadow: 0 6px 0 rgba(20, 14, 43, 0.7);
}

.reveal-btn:focus-visible {
    outline: 3px solid var(--ink);
    outline-offset: 3px;
}

.reveal-btn:active {
    transform: translateY(3px);
    box-shadow: 0 1px 0 rgba(20, 14, 43, 0.7);
}

/* The quiet way out of the resume card. Findable, never competing with
   the gold button above it — resuming is what almost everyone wants. */
.card-quiet {
    margin-top: -0.4rem;
    padding: 0.45rem 0.9rem;
    border: 0;
    background: none;
    color: var(--ink-2);
    font-family: 'Nunito', system-ui, sans-serif;
    font-size: 0.9rem;
    font-weight: 800;
    text-decoration: underline;
    text-underline-offset: 3px;
    border-radius: 8px;
    cursor: pointer;
    transition: color 0.22s ease;
}

.card-quiet:hover {
    color: var(--ink);
}

.card-quiet:focus-visible {
    outline: 3px solid var(--ink);
    outline-offset: 3px;
}

/* ── Control Row ── */
.ctrl-row {
    display: flex;
    align-items: stretch;
    justify-content: center;
    gap: 0.6rem;
    margin-top: 1.5rem;
}

.ctrl-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    min-height: 52px;
    border-radius: 14px;
    font-family: 'Lilita One', 'Fredoka', system-ui, sans-serif;
    font-weight: 400;
    letter-spacing: 0.02em;
    cursor: pointer;
    transition: transform 0.25s ease, box-shadow 0.25s ease, color 0.25s ease, opacity 0.25s ease;
}

.ctrl-btn:focus-visible {
    outline: 3px solid var(--focus-ring);
    outline-offset: 3px;
}

.ctrl-btn:active:not(:disabled) {
    transform: translateY(3px);
    box-shadow: var(--shadow-plate-press);
}

/* Night plates: plum against the sky, so the cream card stays the star */
.ctrl-btn--prev {
    padding: 0.8rem 1.15rem;
    font-size: 0.95rem;
    border: 2.5px solid var(--ink);
    background: var(--plum);
    color: var(--text-primary);
    box-shadow: var(--shadow-plate);
}

.ctrl-btn--prev:hover:not(:disabled) {
    transform: translateY(-2px);
    box-shadow: var(--shadow-plate-lift);
}

.ctrl-btn--prev:disabled {
    opacity: 0.35;
    cursor: default;
}

/* Quiet by default: when the card has answers, the answers lead */
.ctrl-btn--next {
    flex: 1;
    max-width: 230px;
    padding: 0.85rem 1.8rem;
    font-size: 1.1rem;
    border: 2.5px solid var(--ink);
    background: var(--plum);
    color: var(--text-primary);
    box-shadow: var(--shadow-plate);
}

.ctrl-btn--next:hover {
    transform: translateY(-2px);
    box-shadow: var(--shadow-plate-lift);
}

/* Nothing to tap on the card, so moving on is the action */
.ctrl-btn--next.is-lead {
    background: linear-gradient(180deg, #ffdb5e, var(--gold-warm));
    color: var(--ink);
    animation: nextPulse 2.4s ease-in-out infinite;
}

.ctrl-btn--next.is-lead:hover {
    color: var(--ink);
    box-shadow: var(--shadow-plate-lift);
}

.ctrl-btn--next.is-lead:focus-visible {
    outline: 3px solid #fff;
}

@keyframes nextPulse {
    0%, 100% { box-shadow: var(--shadow-plate); }
    50% { box-shadow: 0 5px 0 var(--ink-deep), 0 0 22px rgba(255, 215, 0, 0.28); }
}

/* ── Footer Brand ──
   The watermark, exactly as it signs every photo post: small, quiet,
   centered at the bottom of the frame. */
.footer-brand {
    display: flex;
    align-items: center;
    justify-content: center;
    margin-top: 2.25rem;
    font-size: 0.85rem;
    color: rgba(246, 237, 218, 0.6);
    font-weight: 600;
}

.footer-brand__text {
    white-space: nowrap;
}

.footer-brand a {
    color: var(--gold);
    text-decoration: none;
    font-weight: 800;
}

.footer-brand a:hover {
    text-decoration: underline;
}

.footer-brand a:focus {
    outline: 3px solid var(--focus-ring);
    outline-offset: 2px;
    border-radius: 4px;
}

/* ── Reduced Motion ── */
@media (prefers-reduced-motion: reduce) {
    body {
        overflow: auto;
    }

    h1 {
        animation: fadeIn 0.5s ease-out forwards;
    }

    h1::after {
        animation: underlineDrawSimple 0.6s ease-out 0.5s forwards;
    }

    .tagline,
    .separator {
        animation: fadeIn 0.5s ease-out 0.3s forwards;
    }

    .social-link {
        animation: fadeIn 0.5s ease-out 0.4s forwards;
    }

    .social-link:nth-child(1),
    .social-link:nth-child(2),
    .social-link:nth-child(3) {
        animation-delay: 0.4s;
    }

    .shooting-star {
        display: none;
    }

    .star {
        animation: none !important;
    }

    .castle-light {
        animation: none;
        opacity: 0.7;
    }

    /* Eggs still pay out here, in colour rather than movement. */
    .castle-light.is-found,
    .castle.is-celebrating .castle-light {
        animation: none;
        opacity: 1;
        fill: #fff4d2;
    }

    h1.egg-wave .letter {
        animation: eggWaveCalm 1.4s ease-in-out both;
        animation-delay: calc(var(--i, 0) * 40ms);
    }

    .wish-star {
        display: none;
    }

    .separator span {
        animation: none;
        opacity: 0.7;
    }

    .separator.is-charging span {
        animation: none;
        transform: none;
    }

    /* The reward here is a sign you read, so it still arms; it just
       arrives instead of sliding. */
    .utilidor {
        transition: none;
    }

    .letter:hover,
    .letter.is-lit {
        transform: none !important;
        animation: none !important;
    }

    .letter:nth-child(n):hover,
    .letter:nth-child(n).is-lit {
        transform: none;
        animation: none;
    }

    .social-link {
        transition: background 0.2s ease;
    }

    .social-link:hover,
    .social-link:active {
        transform: none;
        box-shadow: var(--shadow-plate);
    }

    .social-link::before {
        display: none;
    }

    .sparkle,
    .firework-flash {
        display: none;
    }

    .play-cta {
        animation: fadeIn 0.5s ease-out 0.5s forwards;
    }

    .play-cta::before {
        display: none;
    }

    .play-cta:hover,
    .play-cta:active {
        transform: none;
        box-shadow: var(--shadow-plate);
    }

    .view.is-active {
        animation: none;
    }

    .game-card,
    .card-chip::after,
    .or-star::before,
    .count-num.pop,
    .ctrl-btn--next {
        animation: none !important;
    }

    .card--talk .card-face::after {
        display: none;
    }

    .flip-wrap {
        transition: none;
    }

    .card-face {
        transition: none;
    }

    .card-opt.is-picked,
    .card-face.has-pick .card-opt:not(.is-picked) {
        transform: none;
    }

    .card-opt:hover,
    .card-opt:active,
    .reveal-btn:hover,
    .reveal-btn:active,
    .ctrl-btn:hover,
    .ctrl-btn:active,
    .back-btn:hover,
    .back-btn:active {
        transform: none;
    }
}

/* ── Settled home ──
   The entrance choreography is a first-load performance. Once the game
   has been opened, home must never depend on those animations re-running
   (iOS Safari won't re-run them after a display toggle). */
body.is-settled h1,
body.is-settled .tagline,
body.is-settled .separator,
body.is-settled .social-link,
body.is-settled .play-cta {
    opacity: 1;
    animation: none;
}

body.is-settled h1::after {
    width: 62%;
    animation: underlineGlow 3s ease-in-out infinite;
}

/* Last in source on purpose: same specificity as the settled glow rule
   above, so order is what keeps reduced motion glow-free */
@media (prefers-reduced-motion: reduce) {
    body.is-settled h1::after {
        animation: none;
    }
}

@keyframes fadeIn {
    from { opacity: 0; }
    to { opacity: 1; }
}

@keyframes underlineDrawSimple {
    to { width: 62%; }
}
