/* ── Swoop arc (experimental alternative supergraphic) ───────────────────────
   An alternative to the fixed top-right corner arc in home.css: a ribbon that
   enters from the lower left, runs behind the game tiles, and exits the top.

   This file is only loaded by public/index.html. Loading it is what swaps the
   two marks — remove the <link> and <script> from the homepage <head> and the
   original corner arc returns untouched. See public/arc-swoop.js.

   Sizing, viewBox and the band paths are all set by the script; everything
   here is presentation only. */

.arc-swoop {
    position: absolute;
    top: 0;
    left: 0;
    z-index: 0;
    pointer-events: none;
    /* The bands are generated as polylines that can sit slightly outside the
       viewBox at the very ends; don't clip them. */
    overflow: visible;
}

.arc-swoop path {
    fill: none;
    stroke-linecap: butt;
    stroke-linejoin: round;
    /* pathLength="1" is set on each band, so the whole curve is one dash unit
       and the offset can be animated from fully-hidden (1) to fully-drawn (0). */
    stroke-dasharray: 1;
    stroke-dashoffset: 1;
}

/* Final resting state — also what a resize redraw lands on, so the reveal
   never replays after the initial load. */
.arc-swoop.is-static path {
    stroke-dashoffset: 0;
}

.arc-swoop.is-drawing path {
    animation: arc-swoop-draw 1.4s cubic-bezier(.22, .61, .36, 1) forwards;
}

@keyframes arc-swoop-draw {
    from { stroke-dashoffset: 1; }
    to   { stroke-dashoffset: 0; }
}

/* Above the mobile breakpoint the swoop replaces the corner arc. */
@media (min-width: 769px) {
    .arc {
        display: none;
    }
}

/* Below it the cards stack vertically, so a horizontal run "behind the tiles"
   has no meaning — fall back to the original corner arc. The script also skips
   building the SVG at these widths; this is belt and braces. */
@media (max-width: 768px) {
    .arc-swoop {
        display: none;
    }
}

/* ── Cards lit by the passing ribbon ─────────────────────────────────────────
   The script sets data-arc-cards="armed" on <html> synchronously, before first
   paint, then lights each card as the ribbon slips under it. The attribute is
   only ever set on desktop with motion allowed, and is removed again once the
   sequence finishes or a safety timer fires — so every other path (mobile, no
   JS, a thrown error, reduced motion) leaves the cards plainly visible.

   `.game-card ~ .game-card` deliberately spares the FIRST card: it stays
   visible throughout, covering the tight elbow where the ribbon turns out of
   its climb into the run. Written as a sibling selector rather than
   :not(:first-child) so it keeps working if anything else is ever added to the
   grid ahead of the cards. */
@media (min-width: 769px) {
    :root[data-arc-cards="armed"] .game-card ~ .game-card {
        opacity: 0;
        transform: translateY(14px);
    }

    :root[data-arc-cards="armed"] .game-card ~ .game-card.is-lit {
        opacity: 1;
        transform: none;
        transition: opacity .5s ease-out, transform .5s cubic-bezier(.22, .61, .36, 1);
    }
}

/* ── Footer scrim ────────────────────────────────────────────────────────────
   The ribbon enters through the footer, and the footer's muted --text-label
   drops to ~1.15 contrast where it crosses the orange band — unreadable. A flat
   translucent wash isn't enough (88% still only reaches ~3.5), so this fades to
   FULLY opaque before the text band: transparent at the top edge, so the ribbon
   is still seen sliding underneath, solid by the time it reaches the type,
   which restores the 4.57 the text has on the plain page.

   Filling with --page-bg is what makes it invisible: .footer is only as wide as
   .page, but a page-coloured fill has no discernible edge against the page. */
@media (min-width: 769px) {
    .footer {
        /* Solid by 30%: the highest text in the footer starts at ~32%. */
        background: linear-gradient(to bottom, transparent 0, var(--page-bg) 30%);
    }
}

/* ── Eyebrow bar shadow ──────────────────────────────────────────────────────
   The ribbon leaves through the top of the page and is cut dead by the sticky
   eyebrow bar's hard bottom edge. A soft shadow gives it something to slide
   under, echoing the way the footer scrim catches it at the other end.

   Kept at every width — unlike the footer scrim, this reads as ordinary sticky
   header polish, and on mobile it softens the corner arc the same way. Split by
   theme because a shadow tuned for cream disappears on the dark page, following
   the --shadow-card pattern in home.css. */
.sticker-strip {
    box-shadow: 0 4px 14px rgba(43, 43, 40, .22);
}

:root[data-theme="dark"] .sticker-strip {
    box-shadow: 0 4px 16px rgba(0, 0, 0, .45);
}

@media (prefers-reduced-motion: reduce) {
    .arc-swoop path {
        stroke-dashoffset: 0;
    }

    .arc-swoop.is-drawing path {
        animation: none;
    }

    /* Belt and braces — arm() already declines to hide anything here. */
    :root[data-arc-cards="armed"] .game-card ~ .game-card {
        opacity: 1;
        transform: none;
        transition: none;
    }
}
