/* SnapBlocks — Screen-specific styling
 *
 * Components that are tied to a specific screen (splash blobs, menu hero,
 * level grid, streak calendar, shop cards, etc.). Screen templates live in
 * js/ui/screens.js and reference these classes.
 */

/* ============================================================
 * Splash
 * ============================================================ */
.sb-splash {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    padding:
        calc(40px + var(--sb-screen-safe-top))
        40px
        calc(40px + var(--sb-screen-safe-bottom));
    gap: 24px;
    background: radial-gradient(circle at 50% 30%, oklch(92% 0.05 70 / 0.6), transparent 60%);
    position: relative;
    overflow: hidden;
}
[data-theme="midnight"] .sb-splash {
    background: radial-gradient(circle at 50% 30%, oklch(40% 0.08 25 / 0.3), transparent 60%);
}
.sb-splash-blob {
    position: absolute;
    width: 240px; height: 240px;
    border-radius: 50%;
    filter: blur(40px);
    opacity: 0.45;
    z-index: 0;
    pointer-events: none;
}
.sb-splash-blob.b1 { top: 60px; left: -60px; background: var(--coral); }
.sb-splash-blob.b2 { bottom: 140px; right: -50px; background: var(--sky); }
.sb-splash-blob.b3 { top: 260px; left: 50%; width: 180px; height: 180px; background: var(--mint); transform: translateX(-50%); opacity: 0.32; }
.sb-splash > *:not(.sb-splash-blob) { position: relative; z-index: 1; }
.sb-app-intro {
    width: min(320px, 100%);
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 24px;
    opacity: 0;
    transform: translateY(12px) scale(0.98);
    /* No delay: the studio ident that this used to wait out is gone, so the
       game's own mark is the first thing on screen. */
    animation: sb-app-intro-in 620ms ease both;
}
.sb-splash-logo {
  display: grid; place-items: center;
  filter: drop-shadow(0 16px 30px rgba(0,0,0,0.22));
  animation: sb-splash-logo-in 560ms cubic-bezier(.34,1.56,.64,1) both;
}
.sb-app-logo { display: block; border-radius: 26px; }
.sb-menu-app-logo {
    width: 30px;
    height: 30px;
    border-radius: 8px;
    object-fit: cover;
}
@keyframes sb-splash-logo-in {
  from { opacity: 0; transform: scale(0.7) translateY(8px); }
  to   { opacity: 1; transform: scale(1) translateY(0); }
}
.sb-splash-loader {
    width: 80%;
    height: 6px;
    background: var(--bg-inset);
    border-radius: 3px;
    overflow: hidden;
    margin-top: 32px;
}
.sb-splash-loader-fill {
    width: 60%;
    height: 100%;
    background: var(--primary);
    border-radius: 3px;
    animation: sb-loadbar 1.8s ease-in-out infinite;
}
@keyframes sb-loadbar {
    0%   { width: 10%; }
    50%  { width: 85%; }
    100% { width: 10%; }
}
@keyframes sb-app-intro-in {
    to { opacity: 1; transform: translateY(0) scale(1); }
}
[data-reduced-motion="true"] .sb-app-intro,
[data-reduced-motion="true"] .sb-splash-logo {
    animation: none;
    opacity: 1;
    transform: none;
    filter: none;
}
[data-reduced-motion="true"] .sb-app-intro {
    gap: 16px;
    width: 280px;
}
[data-reduced-motion="true"] .sb-app-intro .sb-app-logo {
    width: 92px;
    height: 92px;
}
[data-reduced-motion="true"] .sb-app-intro .sb-wordmark {
    font-size: 32px !important;
}

/* ============================================================
 * Onboarding
 * ============================================================ */
.sb-onboarding-illust {
    width: 260px;
    height: 260px;
    position: relative;
    flex-shrink: 0;
}
.sb-onboarding-frame {
    position: absolute;
    inset: 10px;
    background: var(--bg-2);
    border-radius: 32px;
    box-shadow: var(--shadow-lift);
}
.sb-onboarding-piece {
    position: absolute;
    border-radius: 14px;
}
.sb-onboarding-slot {
    position: absolute;
    border-radius: 14px;
    border: 3px dashed color-mix(in oklab, var(--primary), transparent 30%);
    background: color-mix(in oklab, var(--primary), transparent 88%);
    box-shadow: 0 0 0 8px color-mix(in oklab, var(--primary), transparent 92%);
}
.sb-onboarding-slot.strong {
    border-style: solid;
    background: color-mix(in oklab, var(--butter), transparent 72%);
    animation: sb-hint-pulse 1.4s ease-in-out infinite;
}
.sb-onboarding-trail {
    position: absolute;
    height: 4px;
    border-radius: 999px;
    background: linear-gradient(90deg, transparent, var(--primary));
    opacity: 0.55;
}
.sb-onboarding-hint {
    position: absolute;
    right: 20px;
    top: 18px;
    width: 58px;
    height: 58px;
    border-radius: 20px;
    display: grid;
    place-items: center;
    color: oklch(35% 0.07 80);
    background: var(--butter);
    box-shadow: 0 6px 0 oklch(from var(--butter) calc(l - 0.12) c h);
    animation: sb-hint-pulse 1.4s ease-in-out infinite;
}
@keyframes sb-hint-pulse {
    0%, 100% { transform: scale(1); }
    50% { transform: scale(1.06); }
}
.sb-onboarding-sparkle {
    position: absolute;
    top: -14px;
    right: 0;
    font-size: 28px;
    animation: sb-wiggle 2.4s ease-in-out infinite;
}
@keyframes sb-wiggle {
    0%, 100% { transform: rotate(-8deg); }
    50%      { transform: rotate(12deg); }
}
.sb-onboarding-dots {
    display: flex;
    gap: 8px;
    justify-content: center;
}
.sb-onboarding-dots span {
    width: 8px; height: 8px;
    border-radius: 50%;
    background: var(--line-strong);
    transition: all 0.2s ease;
}
.sb-onboarding-dots span.active {
    width: 24px;
    border-radius: 4px;
    background: var(--primary);
}
.sb-tour-drag-piece {
    animation: sb-tour-drag 2.2s ease-in-out infinite;
    transform-origin: center;
}
@keyframes sb-tour-drag {
    0%, 100% { transform: translate(0, 0) scale(1) rotate(-4deg); }
    45%, 65% { transform: translate(96px, -94px) scale(1.18) rotate(3deg); }
}
.sb-tour-hint-orb {
    position: absolute;
    top: 48px;
    left: 50%;
    width: 82px;
    height: 82px;
    transform: translateX(-50%);
    display: grid;
    place-items: center;
    border-radius: 24px;
    color: oklch(35% 0.07 80);
    background: var(--butter);
    box-shadow: 0 10px 0 oklch(from var(--butter) calc(l - 0.12) c h), 0 18px 34px -22px var(--ink);
    animation: sb-hint-pulse 1.4s ease-in-out infinite;
}
.sb-tour-reward-card {
    position: absolute;
    left: 34px;
    right: 34px;
    bottom: 64px;
    min-height: 42px;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    border-radius: 12px;
    background: var(--bg);
    color: var(--ink);
    box-shadow: var(--shadow-soft);
    font-size: 14px;
}
.sb-tour-reward-card.second {
    bottom: 16px;
    color: var(--primary);
}
.sb-tour-daily {
    position: absolute;
    inset: 10px;
    border-radius: 32px;
    background:
        radial-gradient(circle at 78% 18%, color-mix(in oklab, var(--butter), transparent 18%), transparent 18%),
        linear-gradient(145deg, oklch(24% 0.045 285), oklch(30% 0.06 252) 58%, oklch(25% 0.05 220));
    box-shadow: var(--shadow-lift);
    overflow: hidden;
}
.sb-tour-calendar {
    position: absolute;
    left: 24px;
    right: 24px;
    bottom: 28px;
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: 6px;
}
.sb-tour-calendar span {
    height: 34px;
    display: grid;
    place-items: center;
    border-radius: 10px;
    background: rgba(255,255,255,0.12);
    color: rgba(255,250,244,0.72);
    font: 800 10px Outfit, sans-serif;
}
.sb-tour-calendar .lit,
.sb-tour-calendar .now {
    background: var(--butter);
    color: oklch(25% 0.05 80);
}
.sb-tour-calendar .now {
    box-shadow: 0 0 0 3px rgba(255,255,255,0.22);
}
.sb-tour-prism {
    position: absolute;
    top: 54px;
    left: 50%;
    width: 76px;
    height: 76px;
    transform: translateX(-50%);
    display: grid;
    place-items: center;
    border-radius: 24px;
    color: #fff;
    background: linear-gradient(135deg, var(--lilac), var(--sky));
    box-shadow: 0 14px 34px rgba(0,0,0,0.22);
    animation: sb-mix-pulse 1.8s ease-in-out infinite;
}
.sb-tour-streak {
    position: absolute;
    top: 20px;
    right: 20px;
    padding: 7px 10px;
    border-radius: 999px;
    background: rgba(255,250,244,0.16);
    color: #fffaf4;
    font: 800 12px Outfit, sans-serif;
}

/* ============================================================
 * Main Menu
 * ============================================================ */
.sb-hero-continue {
    background:
        radial-gradient(circle at 86% 8%, var(--hero-glow), transparent 38%),
        linear-gradient(145deg, var(--hero-start), var(--hero-end));
    color: var(--on-dark);
    isolation: isolate;
}
.sb-hero-continue::after {
    content: '';
    position: absolute;
    inset: 0;
    z-index: -1;
    pointer-events: none;
    background:
        linear-gradient(115deg, rgba(255,255,255,0.10), transparent 30%),
        radial-gradient(circle at 0 100%, color-mix(in oklab, var(--sky), transparent 82%), transparent 45%);
    box-shadow: inset 0 1px 0 rgba(255,255,255,0.16);
}
/* Sortpuz-style dominant Play button — takes the whole card width and
 * stands out as the obvious primary action. */
.sb-hero-play .sb-hero-play-btn {
    width: 100%;
    margin-top: 22px;
    height: 60px;
    font-size: 20px;
    font-weight: 900;
    letter-spacing: 0.02em;
    border-radius: 22px;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    box-shadow: 0 14px 28px -16px rgba(0, 0, 0, 0.58),
        inset 0 1px 0 rgba(255, 255, 255, 0.8),
        inset 0 0 0 1px rgba(20, 14, 26, 0.08);
    transition: transform 0.18s cubic-bezier(.34, 1.56, .64, 1), box-shadow 0.18s cubic-bezier(.34, 1.56, .64, 1);
    animation: sb-hero-breathe 4.8s ease-in-out infinite;
}
.sb-hero-play .sb-hero-play-btn:active {
    transform: translateY(1px) scale(0.988);
    box-shadow: 0 6px 16px -12px rgba(0, 0, 0, 0.58),
        inset 0 1px 0 rgba(255, 255, 255, 0.62);
    animation: none;
}
/* The single most important button in the game gets a slow, alive breath. */
@keyframes sb-hero-breathe {
    0%, 100% { transform: scale(1); }
    50%      { transform: scale(1.006); }
}
.sb-hero-play .sb-hero-play-btn svg {
    width: 22px;
    height: 22px;
}
.sb-hero-daily {
    background: linear-gradient(150deg, var(--lilac) 0%, var(--sky) 100%);
    color: oklch(22% 0.05 280);
    padding: 18px 18px 22px;
}
.sb-hero-remove-ads {
    background: linear-gradient(150deg, var(--mint) 0%, var(--butter) 100%);
    color: oklch(22% 0.05 160);
    padding: 18px 18px 20px;
}
.sb-hero-chip {
    background: rgba(255, 250, 244, 0.10) !important;
    color: var(--on-dark) !important;
    border-color: rgba(255, 250, 244, 0.16) !important;
    box-shadow: inset 0 1px 0 rgba(255, 250, 244, 0.08) !important;
}
.sb-hero-body { color: inherit; opacity: 0.72; }
.sb-hero-preview {
    gap: 14px;
    margin-top: 18px;
}
.sb-hero-mini {
    width: 72px; height: 72px;
    background: rgba(255, 250, 244, 0.5);
    border-radius: 14px;
    padding: 6px;
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    grid-template-rows: repeat(4, 1fr);
    gap: 2px;
    flex-shrink: 0;
}
.sb-hero-mini > span { display: block; }
.sb-mini-cell {
    border-radius: 3px;
    box-shadow:
        inset 0 1px 0 rgba(255,255,255,.26),
        0 0 0 1px rgba(9,15,28,.16);
}
.sb-mini-cell.is-filled { opacity: 1; }
.sb-mini-cell.is-empty {
    opacity: .22;
    background: rgba(255,250,244,.62);
    box-shadow: inset 0 0 0 1px rgba(255,250,244,.22);
}
.sb-hero-progress { background: rgba(255, 250, 244, 0.45); }
.sb-hero-countdown {
    font-size: 22px;
    font-weight: 700;
    line-height: 1.15;
    margin-top: 2px;
    color: inherit;
}
.sb-daily-mini {
    width: 82px;
    height: 82px;
    border-radius: 16px;
}
.sb-daily-hero-main {
    display: flex;
    align-items: center;
    gap: 14px;
    margin-top: 14px;
}
.sb-daily-play-btn {
    margin-top: 14px;
}
.sb-focus-screen-body {
    display: flex;
    flex-direction: column;
    gap: 14px;
    /* The play CTA lives inside the hero card now (no fixed action bar), so
     * only normal safe-area clearance is needed. */
    padding-bottom: calc(20px + var(--sb-screen-safe-bottom)) !important;
}
.sb-focus-hero {
    min-height: 188px;
    /* Flex item in the scrolling column — never squeeze the card, or the
     * in-card play button gets pushed out of its bounds. */
    flex-shrink: 0;
    padding: 16px;
    overflow: visible;
    background:
        radial-gradient(circle at 82% 18%, rgba(255, 250, 244, 0.16), transparent 22%),
        linear-gradient(145deg, oklch(24% 0.045 285), oklch(30% 0.06 252) 58%, oklch(25% 0.05 220));
    color: #fffaf4;
}
.sb-focus-chip {
    background: rgba(255, 250, 244, 0.12) !important;
    color: #fffaf4 !important;
    box-shadow: inset 0 0 0 1px rgba(255, 250, 244, 0.14) !important;
}
.sb-daily-streak-chip {
    background: color-mix(in oklab, var(--coral), transparent 88%) !important;
    color: var(--ink) !important;
    box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--coral), transparent 70%) !important;
}
.sb-daily-streak-chip svg {
    color: var(--coral);
}
.sb-focus-topline {
    position: relative;
    z-index: 1;
}
.sb-focus-hero-main {
    position: relative;
    z-index: 1;
    display: flex;
    align-items: flex-start;
    gap: 13px;
    margin-top: 16px;
}
.sb-focus-mini {
    width: 84px;
    height: 84px;
    border-radius: 18px;
    background: rgba(255, 250, 244, 0.12);
    box-shadow:
        inset 0 0 0 1px rgba(255, 250, 244, 0.18),
        0 18px 36px -24px #000;
    flex: 0 0 auto;
}
.sb-focus-title {
    color: #fffaf4;
    font-size: 28px;
    line-height: 1.08;
}
.sb-focus-copy {
    color: rgba(255, 250, 244, 0.72);
    margin-top: 5px;
    max-width: 190px;
    line-height: 1.32;
}
.sb-focus-meta {
    gap: 7px;
    flex-wrap: wrap;
    margin-top: 10px;
}
.sb-focus-reset {
    position: relative;
    z-index: 1;
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 12px;
    margin-top: 0;
    padding: 12px 16px;
    border-radius: 14px;
    background: var(--bg-2);
    border: 1px solid color-mix(in oklab, var(--line), transparent 24%);
    box-shadow: var(--shadow-soft);
}
.sb-focus-reset .sb-mono {
    font-weight: 800;
    font-size: 16px;
    letter-spacing: 0;
    color: var(--ink);
}
.sb-focus-play-btn {
    position: relative;
    z-index: 1;
    height: 48px;
    width: 100%;
    margin-top: 0;
    background: rgba(255, 250, 244, 0.92);
    color: oklch(24% 0.05 290);
    box-shadow: 0 3px 0 rgba(0, 0, 0, 0.24), 0 14px 24px -18px #000;
}
.sb-focus-best,
.sb-focus-rules,
.sb-focus-constellation {
    border: 1px solid color-mix(in oklab, var(--line), transparent 24%);
}
/* "Next streak N · +C" — the week-scoped home for streak-milestone coins.
   Stated BEFORE they are earned, which is the whole point: the payout is now
   something the player can aim at instead of a surprise on a random clear. */
.sb-streak-next-chip {
    flex: none;
    gap: 7px;
}
.sb-streak-next-coins {
    display: inline-flex;
    align-items: center;
    gap: 3px;
    padding-left: 7px;
    border-left: 1px solid color-mix(in oklab, var(--ink), transparent 82%);
    color: color-mix(in oklab, var(--ink), var(--butter) 24%);
    font-weight: 900;
}
.sb-streak-next-coins .sb-coin-ic { color: var(--butter); }
.sb-streak-next-coins .sb-coin-ic svg { width: 14px; height: 14px; }
.sb-focus-star-ring {
    width: 38px;
    height: 38px;
    border-radius: 50%;
    display: grid;
    place-items: center;
    background: var(--butter);
    color: oklch(30% 0.05 80);
    font: 900 16px/1 var(--font-display);
    flex-shrink: 0;
}
.sb-focus-week {
    position: relative;
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: 4px;
    margin-top: 16px;
    width: 100%;
    overflow: hidden;
}
.sb-focus-week::before {
    content: '';
    position: absolute;
    left: 8%;
    right: 8%;
    top: 17px;
    height: 2px;
    background: color-mix(in oklab, var(--line-strong), transparent 30%);
}
.sb-focus-day {
    position: relative;
    z-index: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 7px;
    min-width: 0;
}
.sb-focus-day .node {
    width: 100%;
    max-width: 34px;
    aspect-ratio: 1;
    height: auto;
    border-radius: 12px;
    display: grid;
    place-items: center;
    color: var(--ink-soft);
    background: var(--bg-inset);
    box-shadow: var(--shadow-soft);
}
.sb-focus-day.lit .node {
    color: oklch(30% 0.05 80);
    background: var(--butter);
}
.sb-focus-day.today .node {
    outline: 2px solid color-mix(in oklab, var(--primary), transparent 34%);
    outline-offset: 2px;
}
@media (max-height: 760px) {
    .sb-daily-screen-body {
        gap: 14px !important;
    }
    .sb-hero-daily {
        padding: 14px 16px 16px;
    }
    .sb-daily-hero-main {
        gap: 10px;
        margin-top: 10px;
    }
    .sb-daily-mini {
        width: 68px;
        height: 68px;
        border-radius: 14px;
    }
    .sb-hero-countdown {
        font-size: 19px;
    }
    .sb-daily-play-btn {
        height: 50px;
        margin-top: 12px;
    }
    .sb-focus-hero {
        min-height: 176px;
        padding: 14px;
    }
    .sb-focus-hero-main {
        gap: 11px;
        margin-top: 12px;
    }
    .sb-focus-mini {
        width: 74px;
        height: 74px;
        border-radius: 16px;
    }
    .sb-focus-title {
        font-size: 25px;
    }
    .sb-focus-copy {
        max-width: 210px;
    }
    .sb-focus-reset {
        padding: 10px 14px;
    }
    .sb-focus-day .node {
        max-width: 32px;
        height: auto;
        border-radius: 11px;
    }
}

.sb-menu-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 12px;
    margin-top: 16px;
}

.sb-garden-menu-card {
    margin-bottom: 14px;
    min-height: 176px;
    background:
        radial-gradient(circle at 18% 22%, color-mix(in oklab, var(--butter), transparent 55%), transparent 32%),
        linear-gradient(150deg, var(--mint) 0%, var(--sky) 58%, var(--lilac) 100%);
    color: oklch(20% 0.05 180);
}
.sb-garden-open {
    width: 38px;
    height: 38px;
    border-radius: 14px;
    display: grid;
    place-items: center;
    background: rgba(255, 250, 244, 0.48);
    flex-shrink: 0;
}
.sb-garden-hero {
    min-height: 320px;
    background:
        radial-gradient(circle at 80% 18%, color-mix(in oklab, var(--butter), transparent 45%), transparent 28%),
        linear-gradient(155deg, var(--mint) 0%, var(--sky) 52%, var(--lilac) 100%);
    color: oklch(20% 0.05 180);
}
/* The garden scene paints a small living landscape that gets richer as the
 * player restores each milestone. Visual layers (back → front):
 *   1. Sky gradient   — tinted from dawn → twilight by --sky-prog (0..1)
 *   2. Celestial body — sun (low progress) becomes moon (>= 50%)
 *   3. Clouds         — soft pill silhouettes
 *   4. Mountains      — back ridge silhouette
 *   5. Ground         — grassy mound with subtle highlight
 *   6. Fireflies      — appear as progress crosses ~30%, animate gently
 *   7. Plots          — six bespoke SVG illustrations, one per milestone
 */
.sb-garden-scene {
    position: relative;
    z-index: 1;
    height: 220px;
    margin: 14px 0 16px;
    border-radius: 28px;
    overflow: hidden;
    box-shadow: inset 0 0 0 1px rgba(255, 250, 244, 0.35);
    /* Sky shifts from a warm dawn to a deep twilight as the player progresses.
     * color-mix lets the gradient interpolate continuously instead of stepping. */
    background:
        linear-gradient(180deg,
            color-mix(in oklab, oklch(86% 0.08 80), oklch(28% 0.09 270) calc(var(--sky-prog, 0) * 90%)) 0%,
            color-mix(in oklab, oklch(78% 0.10 50), oklch(35% 0.10 290) calc(var(--sky-prog, 0) * 88%)) 100%);
    transition: background 0.6s ease;
}
.sb-garden-scene.compact {
    height: 96px;
    margin: 6px 0 12px;
    border-radius: 20px;
}

/* Sun / moon — moves left → right across the sky as progress grows. */
.sb-garden-celestial {
    position: absolute;
    top: 14%;
    left: calc(8% + var(--sky-prog, 0) * 76%);
    width: 38px;
    height: 38px;
    border-radius: 50%;
    background: radial-gradient(circle at 30% 30%, #fffaf4, oklch(86% 0.15 80));
    box-shadow: 0 0 30px 4px rgba(255, 240, 200, 0.55);
    transition: left 0.6s ease, background 0.6s ease, box-shadow 0.6s ease;
}
.sb-garden-scene[data-phase="moon"] .sb-garden-celestial {
    background:
        radial-gradient(circle at 35% 35%, #fffaf4, oklch(85% 0.04 280) 60%, oklch(70% 0.06 280));
    box-shadow:
        0 0 30px 6px color-mix(in oklab, var(--lilac), transparent 50%),
        inset -10px -4px 0 -2px oklch(60% 0.05 280);
}
.sb-garden-scene.compact .sb-garden-celestial {
    width: 22px;
    height: 22px;
    top: 14%;
}

.sb-garden-clouds {
    position: absolute;
    inset: 18% 0 auto 0;
    height: 22px;
    pointer-events: none;
    background:
        radial-gradient(ellipse 32px 9px at 18% 60%, rgba(255, 250, 244, 0.55), transparent 70%),
        radial-gradient(ellipse 28px 8px at 64% 30%, rgba(255, 250, 244, 0.45), transparent 70%),
        radial-gradient(ellipse 22px 7px at 88% 70%, rgba(255, 250, 244, 0.35), transparent 70%);
    opacity: calc(1 - var(--sky-prog, 0) * 0.6);
    transition: opacity 0.6s ease;
}

.sb-garden-mountains {
    position: absolute;
    left: 0; right: 0;
    bottom: 28%;
    height: 64px;
    background:
        linear-gradient(135deg, transparent 50%, color-mix(in oklab, var(--mint), var(--ink) 35%) 50%) 0 100%/40px 64px no-repeat,
        linear-gradient(225deg, transparent 50%, color-mix(in oklab, var(--mint), var(--ink) 35%) 50%) 40px 100%/40px 64px no-repeat,
        linear-gradient(135deg, transparent 50%, color-mix(in oklab, var(--sky),  var(--ink) 30%) 50%) 80px 100%/56px 64px no-repeat,
        linear-gradient(225deg, transparent 50%, color-mix(in oklab, var(--sky),  var(--ink) 30%) 50%) 136px 100%/56px 64px no-repeat;
    background-repeat: repeat-x;
    opacity: 0.7;
    pointer-events: none;
}
.sb-garden-scene.compact .sb-garden-mountains { display: none; }

.sb-garden-ground {
    position: absolute;
    left: -4%;
    right: -4%;
    bottom: 0;
    height: 30%;
    border-radius: 50% 50% 0 0 / 70% 70% 0 0;
    background:
        linear-gradient(180deg,
            color-mix(in oklab, var(--mint), var(--ink) 18%),
            color-mix(in oklab, var(--mint), var(--ink) 30%));
    box-shadow: inset 0 8px 0 -4px rgba(255, 250, 244, 0.25);
}

.sb-garden-firefly {
    position: absolute;
    width: 4px;
    height: 4px;
    border-radius: 50%;
    background: #fff7d6;
    box-shadow: 0 0 10px 2px rgba(255, 240, 180, 0.85);
    animation: sb-firefly 3.6s ease-in-out infinite;
    pointer-events: none;
}
@keyframes sb-firefly {
    0%, 100% { opacity: 0.1; transform: translate(0, 0); }
    50%      { opacity: 1;   transform: translate(8px, -6px); }
}

.sb-garden-plot {
    position: absolute;
    left: calc(7% + var(--plot) * 14.5%);
    bottom: 16px;
    width: 46px;
    height: 84px;
    color: var(--accent);
    transform-origin: bottom center;
    transition: opacity 0.4s ease, transform 0.4s ease, filter 0.4s ease;
    /* Locked = ghosted silhouette so the player can see "what's coming". */
    opacity: 0.32;
    filter: grayscale(0.6) brightness(0.85);
    transform: scale(0.78);
}
.sb-garden-plot svg {
    width: 100%;
    height: 100%;
    display: block;
    overflow: visible;
}
.sb-garden-scene.compact .sb-garden-plot {
    width: 28px;
    height: 50px;
    bottom: 10px;
}
.sb-garden-plot.restored {
    opacity: 1;
    filter: none;
    transform: scale(1);
    animation: sb-garden-sway 4s ease-in-out infinite;
    animation-delay: calc(var(--plot) * -0.32s);
}
.sb-garden-plot.celebrate {
    animation: sb-garden-pop 1.2s cubic-bezier(.2, 1.5, .4, 1) 1, sb-garden-sway 4s ease-in-out 1.2s infinite;
}
@keyframes sb-garden-pop {
    0%   { transform: scale(0.4) translateY(20px); opacity: 0; }
    55%  { transform: scale(1.15); opacity: 1; }
    100% { transform: scale(1); }
}
.sb-garden-row {
    display: flex;
    gap: 12px;
    align-items: center;
    padding: 14px 16px;
    border-radius: var(--radius);
    background: var(--bg-2);
    box-shadow: var(--shadow-soft);
}
.sb-garden-row.locked {
    opacity: 0.58;
}
.sb-garden-row.active {
    box-shadow: var(--shadow-lift);
    outline: 2px solid color-mix(in oklab, var(--primary), transparent 55%);
}
.sb-garden-row-icon {
    width: 44px;
    height: 44px;
    border-radius: 15px;
    background: var(--accent);
    color: var(--ink);
    display: grid;
    place-items: center;
    flex-shrink: 0;
}
.sb-garden-ad-btn {
    width: auto;
    min-width: 106px;
    height: 42px;
    padding: 0 14px;
    border-radius: 14px;
    font-size: 14px;
    flex-shrink: 0;
}
.sb-garden-reward {
    border: 1px solid color-mix(in oklab, var(--mint), transparent 55%);
}
@keyframes sb-garden-sway {
    0%, 100% { transform: rotate(-1.5deg); }
    50%      { transform: rotate(1.5deg); }
}
@media (max-height: 760px) {
    .sb-garden-hero  { min-height: 290px; }
    .sb-garden-scene { height: 170px; }
    .sb-garden-plot  { height: 70px; bottom: 12px; }
    .sb-garden-ad-btn { min-width: 94px; padding: 0 10px; }
}
.sb-menu-tile {
    background: linear-gradient(155deg, var(--surface-top), var(--surface-bottom));
    border-radius: var(--radius-lg);
    padding: 17px;
    display: flex;
    flex-direction: column;
    gap: 10px;
    min-height: 116px;
    box-shadow: var(--shadow-soft);
    cursor: pointer;
    position: relative;
    overflow: hidden;
    border: 1px solid var(--hairline);
    color: inherit;
    text-align: left;
    transition: transform 0.18s cubic-bezier(.34, 1.56, .64, 1), box-shadow 0.18s ease;
}
.sb-menu-tile:active { transform: translateY(1px) scale(0.96); }
@media (hover: hover) {
    .sb-menu-tile:hover { transform: translateY(-2px); box-shadow: var(--shadow-lift); }
}
.sb-tile-icon {
    width: 40px; height: 40px;
    border-radius: 13px;
    display: flex; align-items: center; justify-content: center;
    color: var(--ink);
    border: 1px solid color-mix(in oklab, white, transparent 62%);
    box-shadow: 0 8px 18px -14px color-mix(in oklab, var(--ink), transparent 45%);
}
.sb-tile-dot {
    position: absolute;
    top: 14px; right: 14px;
    width: 10px; height: 10px;
    background: var(--primary);
    border-radius: 50%;
}

/* ============================================================
 * Level Select
 * ============================================================ */
.sb-level-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 12px;
}
.sb-level-node {
    aspect-ratio: 1;
    background: var(--bg-2);
    border-radius: 20px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    position: relative;
    box-shadow: var(--shadow-soft);
    cursor: pointer;
    gap: 3px;
    color: var(--ink);
}
.sb-level-node .num {
    font-weight: 900;
    font-size: 22px;
    letter-spacing: -0.01em;
    color: var(--ink);
}
.sb-level-node .stars {
    display: flex;
    gap: 2px;
}
.sb-level-node {
    transition: transform 0.08s ease;
}
.sb-level-node:not(.locked):active {
    transform: translateY(1px) scale(0.96);
}
@media (hover: hover) {
    .sb-level-node:not(.locked):hover {
        transform: translateY(-2px);
        box-shadow: var(--shadow-lift);
    }
}
.sb-level-node.locked {
    opacity: 0.55;
    color: var(--ink-soft);
    cursor: default;
}
.sb-level-node.locked .num { color: var(--ink-soft); }
.sb-level-node.current {
    background: var(--primary);
    color: var(--primary-ink);
    box-shadow: 0 4px 0 var(--primary-shade),
                0 12px 20px -8px oklch(58% 0.17 28 / 0.35);
}
.sb-level-node.current .num { color: var(--primary-ink); }
.sb-level-node .boss-ring {
    position: absolute;
    inset: -3px;
    border-radius: 22px;
    background: conic-gradient(var(--butter), var(--coral), var(--mint), var(--sky), var(--butter));
    z-index: -1;
}
.sb-level-banner-icon {
    width: 42px; height: 42px;
    border-radius: 14px;
    background: var(--primary);
    color: var(--primary-ink);
    display: flex; align-items: center; justify-content: center;
    flex-shrink: 0;
}
.sb-level-banner-icon.sb-bg-butter { color: var(--ink); }

/* ============================================================
 * Gameplay HUD
 * ============================================================ */
/* Game screen shows canvas through the middle — background must be transparent
 * and the screen itself must not block pointer events (so canvas can receive
 * drag/drop). Only the HUD chrome at top and bottom opts back in. */
.sb-screen[data-screen="game"] {
    background: transparent;
    pointer-events: none;
}
.sb-screen[data-screen="game"] .sb-game-top,
.sb-screen[data-screen="game"] .sb-control-bar {
    pointer-events: auto;
}
/* The play HUD sits directly on the page background — no bar, no blur, no
   divider. The old translucent header was a strip of chrome competing with the
   board for attention; floating the three controls reads calmer and gives the
   board more room. */
.sb-game-top {
    padding:
        calc(10px + var(--sb-game-safe-top))
        calc(14px + var(--sb-safe-right))
        6px
        calc(14px + var(--sb-safe-left));
    box-sizing: border-box;
    flex-shrink: 0;
}
/* hint · solve | blocks · chip | coins · menu */
.sb-hud {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 7px;
}
/* Three clusters, not three items. The side clusters both flex:1 so the count
   stays optically centred whether the left holds one button or two — with a
   plain space-between, adding Solve shoved the count off-axis.
 *
 * The shrink rules here are load-bearing, not tidiness. The sides deliberately
 * keep min-width:auto so they can never shrink below their buttons; the centre
 * is the only cluster allowed to give way. Getting this backwards (sides
 * min-width:0, centre flex:0 0 auto) is what let the count pill ride over the
 * Solve button on special levels, where the Pulse/Prism chip adds a fourth
 * item to a row that was already full. */
.sb-hud-side {
    flex: 1 1 auto;
    display: flex;
    align-items: center;
    gap: 6px;
}
.sb-hud-side-end { justify-content: flex-end; }
.sb-hud-center {
    display: flex;
    align-items: center;
    gap: 5px;
    min-width: 0;
    flex: 0 1 auto;
}
/* Circular controls, matched size, so left and right read as a pair framing
   the count. */
.sb-hud-btn {
    flex: 0 0 auto;
    width: 42px;
    height: 42px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 2px;
    border: 1px solid var(--hairline);
    border-radius: 999px;
    background: linear-gradient(160deg, var(--surface-top), var(--surface-bottom));
    box-shadow: var(--shadow-control);
    color: var(--ink-2);
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    transition: transform 0.08s ease;
}
.sb-hud-btn:active { transform: translateY(1px) scale(0.97); }
/* Hint is the one spend action on the screen, so it carries the accent.
   Both help buttons used to stack icon-over-cost in a column; the cost digit
   is gone (it read as a balance, see gameScreen), so they are plain centred
   icon buttons again and the icon gets the whole circle. */
.sb-hud-hint {
    background: linear-gradient(145deg, #FFF6A6 0%, #FFD52A 70%, #F6B900 100%);
    border-color: #E8B70A;
    color: #4A2E00;
    box-shadow:
        0 6px 13px rgba(218, 159, 0, .2),
        inset 0 1px 0 rgba(255, 255, 255, .8);
    overflow: visible;
}
/* Solve shares the bulb language but uses a bright mint material and checkmark. */
.sb-hud-solve {
    background: linear-gradient(145deg, #C8FFE8 0%, #4BE1A7 70%, #20C889 100%);
    border-color: #21B57B;
    color: #064534;
    box-shadow:
        0 6px 13px rgba(15, 154, 105, .2),
        inset 0 1px 0 rgba(255, 255, 255, .78);
    overflow: visible;
}
.sb-hud-hint svg,
.sb-hud-solve svg { width: 25px; height: 25px; }
/* The count is a status readout, not a headline. It was competing with the
   two action pills beside it, and the extra Solve button left less room, so
   the type steps down and the pill tightens rather than the pill growing. */
.sb-hud-count {
    display: inline-flex;
    align-items: baseline;
    gap: 4px;
    height: 34px;
    padding: 0 9px;
    border-radius: 999px;
    background: var(--surface-raised);
    border: 1px solid var(--hairline);
    box-shadow: var(--shadow-soft);
    line-height: 34px;
}
.sb-hud-count .sb-mono {
    font-size: 11px;
    font-weight: 900;
    color: var(--ink);
}
.sb-hud-count-label {
    font-size: 7px;
    font-weight: 800;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--ink-soft);
}
/* Special level: the chip needs the room more than the word "BLOCKS" does.
   "0/6" already reads as a count without it, and the chip carries meaning the
   player cannot infer from anywhere else on screen. */
.sb-hud-center-chip .sb-hud-count-label { display: none; }
.sb-hud-center-chip .sb-hud-count { padding: 0 7px; }
/* icons.powerPulse / icons.prismMix ship at 22-23px intrinsic, which is nearly
   the chip's whole 28px min-height and the single widest item in the centre
   cluster. Cap them here rather than editing the shared icon markup, which is
   drawn at full size on the level-intro and complete screens. */
.sb-hud-center .sb-chip {
    padding-inline: 8px;
    gap: 5px;
    font-size: 11.5px;
}
.sb-hud-center .sb-chip svg { width: 15px; height: 15px; flex: 0 0 auto; }
/* Nothing in the row may outgrow its box — the count and the chip both clip
   rather than push a neighbour out of the way. */
.sb-hud-count,
.sb-hud-center .sb-chip {
    flex: 0 1 auto;
    min-width: 0;
    white-space: nowrap;
    /* min-width:0 only lets these boxes get narrower; with nowrap the text
       still painted outside them and across the Solve button. Clipping here
       rather than on .sb-hud-center is deliberate — an element's overflow does
       not clip its own box-shadow, so both pills keep their lift. */
    overflow: hidden;
}
/* Compact HUD variant of the complete-screen coin pill. A modifier, not an
   edit to .sb-coin-pill, because the base pill is still used at full size on
   the complete screen. It sits in the end cluster, which is flex:1 1 auto with
   no min-width:0 — so the pill must never shrink either, or the balance would
   clip instead of the centre yielding. */
.sb-coin-pill.sb-hud-coins {
    flex: 0 0 auto;
    min-height: 30px;
    padding: 0 8px;
    gap: 4px;
    font-size: 11.5px;
    white-space: nowrap;
}
.sb-hud-coins .sb-coin-ic svg { width: 14px; height: 14px; }
/* .sb-mono resets weight to 500; at HUD size that reads too light beside the
   900-weight block count. Mono advance width is unaffected by weight, so this
   does not move any of the fit arithmetic. */
.sb-hud-coins .sb-mono { font-weight: 800; }
/* Keep the title to a single line so the header height stays fixed and never
   overlaps the board (Prism Challenge titles used to wrap to 2-3 lines). */
.sb-game-title {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    color: var(--ink-2);
    letter-spacing: 0.12em;
}
/* Prism Challenge reads as visually distinct in the HUD. */
.sb-game-title-prism { color: var(--lilac); }
.sb-game-title-prism svg { vertical-align: -2px; }
.sb-hint-chip {
    height: 38px;
    min-width: 54px;
    padding: 0 11px;
    border: 0;
    border-radius: 15px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    background: var(--butter);
    color: oklch(35% 0.07 80);
    box-shadow: var(--shadow-soft);
    font-weight: 900;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
}
.sb-hint-chip svg {
    width: 19px;
    height: 19px;
}
.sb-hint-chip:active { transform: translateY(1px); }
.sb-daily-hud-badge {
    display: inline-flex;
    align-items: center;
    height: 16px;
    margin-left: 6px;
    padding: 0 6px;
    border-radius: 999px;
    background: var(--butter);
    color: oklch(35% 0.07 80);
    font-size: 9px;
    font-weight: 900;
    letter-spacing: 0.08em;
    vertical-align: 1px;
}
.sb-control-bar {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding:
        8px
        calc(20px + var(--sb-safe-right))
        calc(12px + var(--sb-game-safe-bottom))
        calc(20px + var(--sb-safe-left));
    background: linear-gradient(to top,
        color-mix(in oklab, var(--surface-glass), var(--bg) 8%) 0%,
        color-mix(in oklab, var(--surface-glass), transparent 4%) 78%,
        transparent 100%);
    border-top: 1px solid color-mix(in oklab, var(--hairline), transparent 18%);
    -webkit-backdrop-filter: blur(14px) saturate(1.08);
    backdrop-filter: blur(14px) saturate(1.08);
    box-shadow: 0 -16px 30px -28px color-mix(in oklab, var(--ink), transparent 40%);
    box-sizing: border-box;
    flex-shrink: 0;
}
.sb-ctrl {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
    flex: 1 1 0;
    min-width: 0;
    color: var(--ink);
    cursor: pointer;
    background: transparent;
    border: 0;
    min-height: 54px;
    padding: 5px 2px;
    -webkit-tap-highlight-color: transparent;
    transition: transform 0.08s ease;
}
.sb-ctrl:active { transform: translateY(1px); }
/* The Hint control reads as the "spend coins" action — give its disc a tint. */
.sb-ctrl-hint .sb-ctrl-icon { background: color-mix(in oklab, var(--butter), var(--bg-2) 55%); }
.sb-ctrl-icon {
    width: 44px; height: 44px;
    border-radius: 15px;
    background: linear-gradient(155deg, var(--surface-top), var(--surface-bottom));
    display: flex; align-items: center; justify-content: center;
    border: 1px solid var(--hairline);
    box-shadow: var(--shadow-control);
    color: var(--ink);
}
.sb-ctrl.muted .sb-ctrl-icon {
    opacity: 0.55;
}
.sb-ctrl.muted .sb-ctrl-label {
    color: var(--line-strong);
}
.sb-ctrl-icon.hint {
    background: var(--butter);
    color: oklch(35% 0.07 80);
}
.sb-ctrl-label {
    font-size: 10px;
    font-weight: 800;
    letter-spacing: 0.06em;
    color: var(--ink-soft);
    white-space: nowrap; /* "Solve · 15" must not wrap in the 6-button bar */
}
.sb-game-settings-sheet {
    padding-top: 22px;
}
/* Level actions inside the pause/menu sheet — the old bottom control bar's
   Undo / Reset / Solve, plus Settings. Sized to fit four across on a 360px
   phone without wrapping. */
.sb-sheet-actions {
    display: flex;
    gap: 8px;
    margin-top: 18px;
}
.sb-sheet-action {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    flex: 1 1 0;
    min-width: 0;
    padding: 12px 4px 10px;
    border: 1px solid var(--hairline);
    border-radius: var(--radius);
    background: linear-gradient(160deg, var(--surface-top), var(--surface-bottom));
    box-shadow: var(--shadow-soft);
    color: var(--ink);
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    transition: transform 0.08s ease;
}
.sb-sheet-action:active { transform: translateY(1px); }
.sb-sheet-action-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--ink-2);
}
.sb-sheet-action-icon svg { width: 21px; height: 21px; }
/* .sb-solve-action / .sb-solve-action-icon lived here for the pause sheet's
   Solve tile. Solve moved to the HUD (.sb-hud-solve), so those rules are gone
   rather than left behind as dead selectors. */
.sb-sheet-action-label {
    font-size: 9.5px;
    font-weight: 800;
    letter-spacing: 0.04em;
    color: var(--ink-soft);
    white-space: nowrap;
}

/* Premium Hint + Solve assets
   ---------------------------
   The shared bulb silhouette makes both help actions instantly related. Bright
   gold/mint materials separate their meaning; motion runs on arrival and tap,
   never as a permanently pulsing spend button. */
.sb-premium-icon {
    display: block;
    overflow: visible;
}
.sb-premium-icon *,
.sb-premium-help-action {
    transform-box: fill-box;
    transform-origin: center;
}

.sb-premium-help-action .sb-help-halo {
    animation: sb-help-halo-arrive 660ms 120ms ease-out both;
}
.sb-premium-help-action .sb-help-rays {
    animation: sb-help-rays-arrive 600ms 220ms cubic-bezier(.2,.9,.2,1) both;
}
.sb-premium-help-action .sb-help-bulb-group {
    animation: sb-help-bulb-arrive 580ms 70ms cubic-bezier(.34,1.56,.64,1) both;
}
.sb-hud-solve .sb-solve-symbol {
    stroke-dasharray: 12;
    animation: sb-solve-check-arrive 520ms 390ms ease-out both;
}

.sb-premium-help-action.sb-help-activated .sb-help-bulb-group {
    animation: sb-help-bulb-tap 650ms cubic-bezier(.2,.8,.2,1) both;
}
.sb-premium-help-action.sb-help-activated .sb-help-halo {
    animation: sb-help-halo-tap 720ms ease-out both;
}
.sb-premium-help-action.sb-help-activated .sb-help-rays {
    animation: sb-help-rays-tap 650ms cubic-bezier(.2,.9,.2,1) both;
}
.sb-hud-hint.sb-help-activated .sb-hint-symbol {
    animation: sb-hint-mark-tap 580ms cubic-bezier(.34,1.56,.64,1) both;
}
.sb-hud-solve.sb-help-activated .sb-solve-symbol {
    animation: sb-solve-check-tap 650ms ease-out both;
}

@keyframes sb-help-bulb-arrive {
    from { opacity: 0; transform: translateY(2px) scale(.68) rotate(-7deg); }
    to { opacity: 1; transform: none; }
}
@keyframes sb-help-halo-arrive {
    from { opacity: 0; transform: scale(.4); }
    to { opacity: 1; transform: scale(1); }
}
@keyframes sb-help-rays-arrive {
    from { opacity: 0; transform: scale(.52); }
    to { opacity: 1; transform: scale(1); }
}
@keyframes sb-solve-check-arrive {
    from { opacity: 0; stroke-dashoffset: 12; }
    to { opacity: 1; stroke-dashoffset: 0; }
}
@keyframes sb-help-bulb-tap {
    0%, 100% { transform: none; filter: brightness(1); }
    28% { transform: translateY(1px) scale(.9) rotate(-4deg); filter: brightness(.96); }
    58% { transform: translateY(-1px) scale(1.11) rotate(3deg); filter: brightness(1.12); }
}
@keyframes sb-help-halo-tap {
    0% { opacity: .3; transform: scale(.62); }
    52% { opacity: 1; transform: scale(1.18); }
    100% { opacity: 0; transform: scale(1.48); }
}
@keyframes sb-help-rays-tap {
    0% { opacity: .28; transform: scale(.66); }
    46% { opacity: 1; transform: scale(1.22); }
    100% { opacity: .92; transform: scale(1); }
}
@keyframes sb-hint-mark-tap {
    0%, 100% { transform: none; }
    34% { transform: translateY(1px) scale(.78); }
    65% { transform: translateY(-.5px) scale(1.2); }
}
@keyframes sb-solve-check-tap {
    0% { opacity: .2; stroke-dashoffset: 12; transform: scale(.78); }
    55% { opacity: 1; stroke-dashoffset: 0; transform: scale(1.18); }
    100% { opacity: 1; stroke-dashoffset: 0; transform: scale(1); }
}

[data-reduced-motion="true"] .sb-premium-icon *,
[data-reduced-motion="true"] .sb-premium-help-action,
[data-reduced-motion="true"] .sb-premium-help-action * {
    animation: none !important;
    transition: none !important;
    transform: none !important;
}
@media (prefers-reduced-motion: reduce) {
    .sb-premium-icon *,
    .sb-premium-help-action,
    .sb-premium-help-action * {
        animation: none !important;
        transition: none !important;
        transform: none !important;
    }
}

/* ============================================================
 * Pause / Ad sheet pieces
 * ============================================================ */
.sb-pause-icon {
    width: 64px;
    height: 64px;
    margin: 0 auto 16px;
    border-radius: 20px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--ink);
}
.sb-ad-preview {
    width: 100%;
    aspect-ratio: 16 / 9;
    background: linear-gradient(135deg, var(--sky), var(--lilac));
    border-radius: 20px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: #fffaf4;
    font-weight: 900;
    font-size: 18px;
    letter-spacing: 0.02em;
    position: relative;
    overflow: hidden;
}
.sb-ad-preview::after {
    content: 'ad preview';
    position: absolute;
    top: 10px; left: 12px;
    font-family: var(--font-mono);
    font-size: 10px;
    font-weight: 700;
    opacity: 0.8;
    letter-spacing: 0.1em;
}

/* ============================================================
 * Level Complete
 * ============================================================ */
.sb-complete-header {
    padding-top: calc(16px + var(--sb-screen-safe-top));
    padding-left: calc(20px + var(--sb-safe-left));
    padding-right: calc(20px + var(--sb-safe-right));
}
.sb-complete-body {
    padding-bottom: calc(14px + var(--sb-screen-safe-bottom)) !important;
}
.sb-complete-actions {
    padding-bottom: 6px;
    animation: sb-complete-rise 0.55s 0.95s ease backwards;
}
.sb-confetti-host {
    position: absolute;
    inset: 0;
    pointer-events: none;
    overflow: hidden;
    z-index: 0;
}
.sb-confetti-piece {
    position: absolute;
    width: 8px;
    height: 12px;
    border-radius: 2px;
    animation: sb-confetti-fall 3s ease-out forwards;
}
.sb-burst-host {
    position: absolute;
    inset: 0;
    pointer-events: none;
}
.sb-burst-ray {
    position: absolute;
    left: 50%;
    top: 48px;
    width: 6px;
    height: 28px;
    border-radius: 999px;
    background: var(--c);
    transform-origin: 50% 78px;
    opacity: 0;
    animation: sb-burst-ray 0.72s ease-out forwards;
}
.sb-complete-hero {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    margin-top: 2px;
    animation: sb-complete-rise 0.5s 0.08s ease backwards;
}
/* Compact hero: shrinks the medal + title so the primary result still reads
 * as a "moment" without pushing the actions below the fold on small screens. */
.sb-complete-hero-compact {
    gap: 4px;
    margin-top: 0;
}
.sb-complete-hero-compact .sb-h-xl {
    font-size: 26px;
}
.sb-complete-hero-compact .sb-body {
    font-size: 13px;
}
.sb-complete-medal {
    width: 70px;
    height: 70px;
    border-radius: 22px;
    background: linear-gradient(145deg, var(--butter), var(--coral));
    color: var(--primary-ink);
    display: flex;
    align-items: center;
    justify-content: center;
    box-shadow:
        0 5px 0 rgba(0, 0, 0, 0.18),
        0 18px 32px -18px rgba(0, 0, 0, 0.3);
    animation: sb-medal-pop 0.72s cubic-bezier(0.2, 1.45, 0.34, 1) both;
}
.sb-complete-hero-compact .sb-complete-medal {
    width: 56px;
    height: 56px;
    border-radius: 18px;
}
.sb-complete-hero-compact .sb-complete-medal svg {
    width: 26px;
    height: 26px;
}

/* Celebration tier accents — wrap the hero, lighten with a subtle wash so the
 * tier "feels" different without needing per-tier illustrations. */
.sb-complete-tier-flawless .sb-complete-medal {
    animation: sb-medal-pop 0.72s cubic-bezier(0.2, 1.45, 0.34, 1) both,
               sb-medal-glow 2.4s ease-in-out 0.8s infinite;
}
.sb-complete-tier-solid    .sb-complete-medal { box-shadow: 0 5px 0 rgba(0,0,0,0.15), 0 14px 24px -14px rgba(0,0,0,0.25); }
.sb-complete-tier-cleared  .sb-complete-medal { box-shadow: 0 3px 0 rgba(0,0,0,0.12), 0 10px 18px -12px rgba(0,0,0,0.2); }
@keyframes sb-medal-glow {
    0%, 100% { filter: brightness(1); transform: scale(1); }
    50%      { filter: brightness(1.15); transform: scale(1.04); }
}

/* Achievement badges (Speedrun / New Best) — drop in below the main result. */
.sb-badge-row {
    animation: sb-complete-rise 0.5s 1.0s ease backwards;
    border: 1px solid var(--line, rgba(0,0,0,0.08));
}
.sb-badge-speedrun { border-color: color-mix(in oklab, var(--sky), transparent 55%); }
.sb-badge-newbest  { border-color: color-mix(in oklab, var(--coral), transparent 55%); }
/* The "+N coins earned" and trophy card breakdown lines can run long once a
 * few sources land in the same clear — keep them to one line. */
.sb-coins-earned-bits {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.sb-complete-trophy-card { padding: 8px 12px; }
.sb-complete-trophy-card .sb-pause-icon { width: 34px !important; height: 34px !important; }

/* Secondary achievements (new best / speedrun / streak / mixes / objective /
 * spare trophies) as small wrapping pill chips instead of full-width cards —
 * this is what keeps the complete screen's action buttons above the fold. */
.sb-badge-chip-row {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 6px;
    animation: sb-complete-rise 0.5s 1.0s ease backwards;
}
.sb-badge-chip {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 5px 10px 5px 7px;
    border-radius: 999px;
    font: 800 12px/1 var(--font-display);
    color: var(--ink);
    background: var(--bg-inset);
    box-shadow: inset 0 0 0 1px var(--line, rgba(0,0,0,0.08));
    white-space: nowrap;
}
.sb-badge-chip-ic {
    display: inline-flex;
    width: 18px;
    height: 18px;
    flex: none;
}
.sb-badge-chip-ic svg { width: 14px; height: 14px; }
.sb-badge-chip.tint-sky    { background: color-mix(in oklab, var(--sky), var(--bg-inset) 55%);    box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--sky), transparent 55%); }
.sb-badge-chip.tint-coral  { background: color-mix(in oklab, var(--coral), var(--bg-inset) 55%);  box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--coral), transparent 55%); }
.sb-badge-chip.tint-butter { background: color-mix(in oklab, var(--butter), var(--bg-inset) 55%); box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--butter), transparent 55%); }
.sb-badge-chip.tint-lilac  { background: color-mix(in oklab, var(--lilac), var(--bg-inset) 55%);  box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--lilac), transparent 55%); }
.sb-badge-chip.tint-mint   { background: color-mix(in oklab, var(--mint), var(--bg-inset) 55%);   box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--mint), transparent 55%); }
[data-reduced-motion="true"] .sb-badge-chip-row { animation: none; }

/* Prominent "double it" ad CTA — the strongest secondary action on the
 * complete screen, so it reads as gold/premium rather than a quiet ghost btn. */
.sb-double-inline {
    width: 100%;
    min-height: 48px;
    background: linear-gradient(180deg,
        color-mix(in oklab, var(--butter), white 30%) 0%,
        var(--butter) 55%,
        color-mix(in oklab, var(--butter), black 8%) 100%) !important;
    color: oklch(32% 0.07 80) !important;
    font-weight: 900;
    box-shadow: 0 4px 0 color-mix(in oklab, var(--butter), black 22%),
        0 14px 24px -14px rgba(0, 0, 0, 0.35),
        inset 0 1px 0 rgba(255, 255, 255, 0.5);
}
.sb-double-inline:active {
    box-shadow: 0 1px 0 color-mix(in oklab, var(--butter), black 22%);
}

/* Compact "Today's goals" strip — a label + up to 3 tiny status chips instead
 * of the full goalRow cards (the menu keeps those in full). */
.sb-complete-goals-strip {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 4px 2px;
    text-align: left;
}
.sb-goals-strip-label { flex: none; }
.sb-goals-strip-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    flex: 1;
}
.sb-goal-chip {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 5px 9px;
    border-radius: 999px;
    background: var(--bg-inset);
    box-shadow: inset 0 0 0 1px var(--line, rgba(0,0,0,0.08));
}
.sb-goal-chip-ic {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 18px;
    height: 18px;
    border-radius: 6px;
    flex: none;
}
.sb-goal-chip-ic svg { width: 14px; height: 14px; }
.sb-goal-chip-val {
    font: 800 11px/1 var(--font-mono);
    color: var(--ink-soft);
    display: inline-flex;
    align-items: center;
}
.sb-goal-chip-val svg { width: 12px; height: 12px; }
.sb-goal-chip.done .sb-goal-chip-val { color: var(--mint); }
.sb-goal-chip.done .sb-goal-chip-ic { opacity: 0.65; }
.sb-goal-chip.fresh {
    animation: sb-goal-pop 0.5s 1s cubic-bezier(0.34, 1.56, 0.64, 1) backwards;
}
[data-reduced-motion="true"] .sb-goal-chip.fresh { animation: none; }

/* One-line nudge toward the next Faded World restoration — sits quietly
 * above the actions instead of taking a full card's worth of height. */
.sb-restore-nudge-line {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    font-size: 12px;
    color: var(--ink-soft);
    padding: 0 8px;
}
.sb-restore-nudge-ic {
    display: inline-flex;
    width: 14px;
    height: 14px;
    color: var(--mint);
}
.sb-restore-nudge-ic svg { width: 14px; height: 14px; }
.sb-complete-medal svg {
    width: 34px;
    height: 34px;
}
.sb-star-row {
    animation: sb-complete-rise 0.45s 0.28s ease backwards;
}
.sb-complete-stats {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 10px;
    animation: sb-complete-rise 0.5s 0.72s ease backwards;
}
.sb-complete-stat {
    transform-origin: center;
    animation: sb-stat-pop 0.44s ease backwards;
}
.sb-complete-stat:nth-child(1) { animation-delay: 0.72s; }
.sb-complete-stat:nth-child(2) { animation-delay: 0.84s; }
@keyframes sb-confetti-fall {
    0%   { transform: translateY(-20px) rotate(0);     opacity: 0; }
    20%  { opacity: 1; }
    100% { transform: translateY(720px) rotate(520deg); opacity: 0; }
}
.sb-star {
    width: 44px;
    height: 44px;
    animation:
        sb-star-pop 0.62s cubic-bezier(0.2, 1.55, 0.36, 1) backwards,
        sb-star-twinkle 1.8s ease-in-out infinite;
    animation-delay: calc(0.34s + var(--i) * 0.18s), calc(1.1s + var(--i) * 0.16s);
}
.sb-star.filled { color: var(--butter); filter: drop-shadow(0 2px 4px oklch(70% 0.15 90 / 0.4)); }
.sb-star.empty  { color: var(--line-strong); }
.sb-star.big    { width: 55px; height: 55px; filter: drop-shadow(0 4px 8px oklch(70% 0.15 90 / 0.5)); }
@keyframes sb-star-pop {
    0%   { transform: translateY(16px) scale(0.15) rotate(-28deg); opacity: 0; }
    58%  { transform: translateY(-8px) scale(1.24) rotate(9deg);  opacity: 1; }
    100% { transform: translateY(0) scale(1) rotate(0); opacity: 1; }
}
@keyframes sb-star-twinkle {
    0%, 100% { filter: brightness(1) drop-shadow(0 2px 4px oklch(70% 0.15 90 / 0.36)); }
    50%      { filter: brightness(1.12) drop-shadow(0 4px 9px oklch(70% 0.15 90 / 0.50)); }
}
@keyframes sb-medal-pop {
    0%   { transform: translateY(14px) scale(0.2) rotate(-18deg); opacity: 0; }
    64%  { transform: translateY(-5px) scale(1.12) rotate(8deg); opacity: 1; }
    100% { transform: translateY(0) scale(1) rotate(0); opacity: 1; }
}
@keyframes sb-burst-ray {
    0%   { transform: rotate(var(--a)) translateY(0) scaleY(0.2); opacity: 0; }
    34%  { opacity: 0.95; }
    100% { transform: rotate(var(--a)) translateY(-42px) scaleY(0.05); opacity: 0; }
}
@keyframes sb-complete-rise {
    0%   { transform: translateY(16px); opacity: 0; }
    100% { transform: translateY(0); opacity: 1; }
}
@keyframes sb-stat-pop {
    0%   { transform: translateY(10px) scale(0.94); opacity: 0; }
    100% { transform: translateY(0) scale(1); opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
    .sb-complete-hero,
    .sb-complete-medal,
    .sb-star,
    .sb-complete-stats,
    .sb-complete-stat,
    .sb-complete-actions {
        animation: none !important;
    }
}

/* Clean solved-board completion screen. The board snapshot is intentionally
 * the largest object; reward and navigation stay compact and predictable. */
.sb-complete-clean {
    box-sizing: border-box;
    width: 100%;
    min-height: 100%;
    padding:
        calc(14px + var(--sb-screen-safe-top))
        calc(28px + var(--sb-safe-right))
        calc(10px + var(--sb-screen-safe-bottom))
        calc(28px + var(--sb-safe-left));
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
    /* This element IS the .sb-screen-body, and a flat `overflow: hidden` here
       beat that class's overflow-y:auto (same specificity, later file). Its
       children are all flex:none, so once the stack was taller than the stage
       — short viewport, landscape, split-screen, or simply a 640-700px stage
       where the max-height:650 tuning below has not engaged yet — the Next /
       Replay / Share row was clipped away with no way to scroll to it.
       Horizontal hiding is still wanted: the card's arrival animation
       overshoots sideways. */
    overflow-x: hidden;
    overflow-y: auto;
    text-align: center;
}
.sb-complete-clean-title {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
    flex: none;
    animation: sb-complete-rise 0.46s 0.05s ease backwards;
}
.sb-complete-clean-title .sb-label {
    color: var(--primary);
    font-size: 12px;
    letter-spacing: 0.13em;
}
.sb-complete-clean-heading {
    margin: 0;
    color: var(--ink);
    font: 850 38px/1 var(--font-display);
    letter-spacing: -0.035em;
}
.sb-complete-puzzle-card {
    width: min(260px, 72vw);
    margin: 0;
    flex: none;
    overflow: hidden;
    border: 1px solid var(--hairline);
    border-radius: 18px;
    background: var(--card);
    box-shadow:
        0 18px 34px -24px rgba(38, 28, 48, 0.42),
        0 4px 12px rgba(38, 28, 48, 0.06);
    transform-origin: 50% 76%;
    animation: sb-complete-card-arrive 0.72s 0.14s cubic-bezier(0.22, 1.35, 0.36, 1) backwards;
}
.sb-complete-snapshot {
    width: 100%;
    aspect-ratio: 1;
    overflow: hidden;
    background: var(--bg);
    border-bottom: 1px solid var(--line);
}
.sb-complete-snapshot img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    animation: sb-complete-snapshot-settle 0.72s 0.2s cubic-bezier(0.22, 1, 0.36, 1) backwards;
}
.sb-complete-snapshot-fallback {
    width: 100%;
    height: 100%;
    display: grid;
    place-items: center;
    color: var(--primary);
    background: var(--bg-inset);
}
.sb-complete-snapshot-fallback svg {
    width: 64px;
    height: 64px;
}
.sb-complete-card-stars {
    height: 50px;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 12px;
    background: var(--card);
}
.sb-complete-card-star {
    display: inline-flex;
    width: 35px;
    height: 35px;
    animation: sb-star-pop 0.56s cubic-bezier(0.2, 1.55, 0.36, 1) backwards;
    animation-delay: calc(0.42s + var(--i) * 0.14s);
}
.sb-complete-card-star svg {
    width: 100%;
    height: 100%;
}
.sb-complete-card-star.filled {
    color: var(--butter);
    filter: drop-shadow(0 3px 4px color-mix(in oklab, var(--butter), transparent 58%));
}
.sb-complete-card-star.empty {
    color: var(--line-strong);
}
.sb-complete-reward {
    min-height: 72px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 7px;
    flex: none;
}
.sb-complete-reward-line {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 9px;
    color: var(--ink);
    font: 800 18px/1 var(--font-display);
    animation: sb-complete-rise 0.45s 0.62s ease backwards;
}
.sb-complete-reward-coin {
    width: 30px;
    height: 30px;
    display: grid;
    place-items: center;
    border-radius: 10px;
    color: oklch(35% 0.08 80);
    background: var(--butter);
    box-shadow: 0 3px 0 color-mix(in oklab, var(--butter), black 16%);
}
.sb-complete-reward-coin svg {
    width: 19px;
    height: 19px;
}
.sb-complete-double-btn {
    min-height: 40px;
    padding: 9px 16px;
    border: 1px solid color-mix(in oklab, var(--butter), var(--ink) 13%);
    border-radius: 999px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 7px;
    color: color-mix(in oklab, var(--ink), var(--butter) 20%);
    background: color-mix(in oklab, var(--butter), var(--card) 70%);
    box-shadow: 0 5px 12px -9px rgba(38, 28, 48, 0.5);
    font: 800 12px/1 var(--font-display);
    letter-spacing: 0.015em;
    cursor: pointer;
    animation: sb-complete-rise 0.45s 0.72s ease backwards;
}
.sb-complete-double-btn svg {
    width: 15px;
    height: 15px;
}
.sb-complete-double-btn:active {
    transform: translateY(1px);
    box-shadow: none;
}
.sb-complete-double-btn:disabled {
    cursor: wait;
    opacity: 0.72;
}
.sb-complete-doubled {
    min-height: 40px;
    display: inline-flex;
    align-items: center;
    gap: 7px;
    color: var(--mint);
    font: 800 13px/1 var(--font-display);
}
/* Day-scoped acknowledgements on the clean complete screen (a Today's Goal
 * finishing, a streak milestone). Reuses .sb-badge-chip and carries NO coin
 * figure on purpose: those coins are already credited and are reported on the
 * menu's goals card, so putting a number here would drop day-scoped money back
 * onto a level-scoped headline — the exact thing that made the reward look
 * random. This is a receipt, not a payout, so it stays small and last. */
.sb-complete-day-badges {
    max-width: 100%;
    flex: none;
}
.sb-complete-day-badges .sb-badge-chip {
    max-width: 100%;
    font-size: 11px;
    padding: 4px 9px 4px 6px;
}
.sb-complete-day-badges .sb-badge-chip-ic { width: 15px; height: 15px; }
.sb-complete-day-badges .sb-badge-chip-ic svg { width: 13px; height: 13px; }
.sb-complete-clean-actions {
    width: 100%;
    margin-top: auto;
    display: flex;
    flex-direction: column;
    gap: 9px;
    flex: none;
    animation: sb-complete-rise 0.52s 0.82s ease backwards;
}
.sb-complete-next {
    min-height: 54px;
    text-transform: none;
}
.sb-complete-secondary-actions {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 10px;
}
.sb-complete-secondary-btn {
    min-width: 0;
    min-height: 48px;
    border: 1px solid var(--line-strong) !important;
    border-radius: 16px !important;
    color: var(--ink) !important;
    background: color-mix(in oklab, var(--card), transparent 6%) !important;
    box-shadow: 0 8px 18px -16px rgba(38, 28, 48, 0.6) !important;
    font-weight: 800;
}
.sb-complete-secondary-btn:active {
    transform: translateY(1px);
    box-shadow: none !important;
}
@keyframes sb-complete-card-arrive {
    0% {
        transform: translateY(24px) scale(0.9) rotate(-1.4deg);
        opacity: 0;
    }
    64% {
        transform: translateY(-3px) scale(1.018) rotate(0.35deg);
        opacity: 1;
    }
    100% {
        transform: translateY(0) scale(1) rotate(0);
        opacity: 1;
    }
}
@keyframes sb-complete-snapshot-settle {
    0% { transform: scale(1.07); filter: saturate(0.82); }
    100% { transform: scale(1); filter: saturate(1); }
}
@media (max-height: 650px) {
    .sb-complete-clean {
        gap: 7px;
        padding-top: calc(8px + var(--sb-screen-safe-top));
        padding-bottom: calc(6px + var(--sb-screen-safe-bottom));
    }
    .sb-complete-clean-title { gap: 2px; }
    .sb-complete-clean-heading { font-size: 32px; }
    .sb-complete-puzzle-card { width: min(220px, 62vw); }
    .sb-complete-card-stars { height: 42px; }
    .sb-complete-card-star { width: 30px; height: 30px; }
    .sb-complete-reward { min-height: 62px; gap: 5px; }
    /* Short screens: the chips are the least load-bearing row here, so they
       give up their padding before the reward line or the actions do. */
    .sb-complete-day-badges .sb-badge-chip { padding: 3px 8px 3px 5px; font-size: 10px; }
    .sb-complete-next { min-height: 50px; }
    .sb-complete-secondary-btn { min-height: 44px; }
}
[data-reduced-motion="true"] .sb-complete-clean-title,
[data-reduced-motion="true"] .sb-complete-puzzle-card,
[data-reduced-motion="true"] .sb-complete-snapshot img,
[data-reduced-motion="true"] .sb-complete-card-star,
[data-reduced-motion="true"] .sb-complete-reward-line,
[data-reduced-motion="true"] .sb-complete-double-btn,
[data-reduced-motion="true"] .sb-complete-day-badges,
[data-reduced-motion="true"] .sb-complete-clean-actions {
    animation: none !important;
}

/* Browser build — the complete screen without the rewarded-ad row.
 *
 * caps.ads is false off-device, so stageCompleteRewards() (ui/index.js) stages
 * no offer and the inline "2× reward · watch ad" button can never render. Two
 * things then went empty at once: .sb-complete-reward kept a 72px min-height
 * reserved for a button that is not coming, and the slack that leaves pooled in
 * a single place, because .sb-complete-clean-actions pins itself to the bottom
 * with margin-top:auto. The result was one ~120px hole between the last chip and
 * Next — the screen read as something with a piece missing.
 *
 * Shrinking the stack to its content would only move the hole to the bottom of
 * the frame, so the space is spent instead. The snapshot card is the hero here
 * and takes most of it; whatever is left is split evenly by giving the reward
 * section its own auto margin — CSS divides free space equally between multiple
 * auto margins, so the card stays under the title, the actions stay in thumb
 * reach, and no single gap dominates. When the stack does overflow (a short
 * window) both auto margins resolve to 0 and the body scrolls as before.
 *
 * On the guard selector see the header of css/layout.css. Android is untouched:
 * it still stages the offer, and every value above is additive here — nothing is
 * removed. It also must stay guarded rather than keyed on the offer's absence,
 * since Android legitimately renders this screen with no offer on a replay.
 * ============================================================ */
:root[data-platform]:not([data-platform="android"]) .sb-complete-puzzle-card {
    width: min(300px, 72vw);
}
:root[data-platform]:not([data-platform="android"]) .sb-complete-reward {
    min-height: 0;
    margin-top: auto;
}

/* ============================================================
 * Trophies
 * ============================================================ */
/* Trophy case — hero + medal grid */
.sb-trophy-hero {
    display: flex; align-items: center; gap: 16px;
    background: linear-gradient(135deg, var(--bg-2), var(--bg-inset));
    /* The body is a flex column; without this the hero collapses (clipping its
       ring) when the trophy grids below make the content taller than the body. */
    flex-shrink: 0;
}
.sb-trophy-grid { flex-shrink: 0; }
.sb-trophy-hero-ring {
    width: 76px; height: 76px; flex-shrink: 0;
    border-radius: 50%;
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    /* conic progress ring driven by --pct */
    background: conic-gradient(var(--butter) calc(var(--pct, 0) * 1%), var(--line) 0);
    position: relative;
}
.sb-trophy-hero-ring::before {
    content: ''; position: absolute; inset: 7px; border-radius: 50%;
    background: var(--bg-2);
}
.sb-trophy-hero-ring span { position: relative; font: 900 24px/1 var(--font-display); color: var(--ink); }
.sb-trophy-hero-ring small { position: relative; font: 700 11px/1 var(--font-display); color: var(--ink-soft); margin-top: 2px; }
.sb-trophy-hero-stats { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 8px; font-weight: 700; color: var(--ink-2); }
.sb-trophy-hero-stats span { display: inline-flex; align-items: center; gap: 5px; }
.sb-trophy-hero-stats svg { width: 15px; height: 15px; }

.sb-trophy-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.sb-trophy-tile {
    position: relative;
    display: flex; flex-direction: column; align-items: center; text-align: center;
    gap: 6px; padding: 16px 12px 14px;
    border-radius: var(--radius-lg);
    background: var(--bg-2);
    box-shadow: var(--shadow-soft);
    overflow: hidden;
}
.sb-trophy-tile.earned { box-shadow: var(--shadow-soft), inset 0 0 0 1.5px color-mix(in oklab, var(--tc, var(--butter)), transparent 55%); }
.sb-trophy-tile.earned::after {
    /* soft diagonal shine on earned tiles */
    content: ''; position: absolute; inset: 0;
    background: linear-gradient(120deg, transparent 40%, rgba(255,255,255,0.18) 50%, transparent 60%);
    pointer-events: none;
}
.sb-trophy-medal {
    width: 56px; height: 56px; border-radius: 50%;
    display: inline-flex; align-items: center; justify-content: center;
    color: #fff; position: relative;
    background: var(--tc, var(--butter));
    box-shadow: inset 0 2px 0 rgba(255,255,255,0.4), inset 0 -3px 6px rgba(0,0,0,0.18), 0 4px 10px -4px var(--tc, var(--butter));
}
.sb-trophy-medal svg { width: 26px; height: 26px; }
.sb-trophy-tile.locked .sb-trophy-medal {
    background: var(--bg-inset); color: var(--ink-soft);
    box-shadow: inset 0 0 0 1px var(--line);
}
.sb-trophy-check {
    position: absolute; right: -3px; bottom: -3px;
    width: 22px; height: 22px; border-radius: 50%;
    background: var(--mint); color: #0b3b2b;
    display: inline-flex; align-items: center; justify-content: center;
    box-shadow: 0 0 0 2px var(--bg-2);
    z-index: 2;
}
.sb-trophy-check svg { width: 13px; height: 13px; }
.sb-trophy-title { font: 800 14px/1.15 var(--font-display); color: var(--ink); }
.sb-trophy-sub { font-size: 11.5px; color: var(--ink-soft); line-height: 1.3; }
.sb-trophy-bar { width: 100%; margin-top: 4px; }
.sb-trophy-prog { font-size: 11px; color: var(--ink-soft); }
.sb-trophy-earned { font: 800 11px/1 var(--font-display); color: var(--mint); display: inline-flex; align-items: center; gap: 4px; }
.sb-trophy-earned svg { width: 13px; height: 13px; }

/* ============================================================
 * Daily — streak calendar
 * ============================================================ */
.sb-streak-grid {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: 8px;
}
.sb-streak-day {
    aspect-ratio: 1;
    border-radius: 16px;
    background: var(--bg-2);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 4px;
    box-shadow: var(--shadow-soft);
    position: relative;
}
.sb-streak-day .day-num {
    font-size: 11px;
    font-weight: 800;
    color: var(--ink-soft);
    letter-spacing: 0.06em;
}
.sb-streak-day.claimed {
    background: var(--mint);
    color: oklch(25% 0.05 160);
}
.sb-streak-day.claimed .day-num { color: oklch(25% 0.05 160); }
.sb-streak-day.today {
    background: var(--primary);
    color: var(--primary-ink);
    box-shadow: 0 4px 0 var(--primary-shade),
                0 12px 20px -8px oklch(58% 0.17 28 / 0.35);
}
.sb-streak-day.today .day-num { color: var(--primary-ink); }

/* ============================================================
 * Shop
 * ============================================================ */
.sb-shop-card {
    position: relative;
    background: var(--bg-2);
    border-radius: var(--radius-lg);
    padding: 16px 14px 18px;
    text-align: center;
    box-shadow: var(--shadow-soft);
    cursor: pointer;
    color: inherit;
    border: 0;
    transition: transform 0.08s ease;
}
.sb-shop-card:active { transform: translateY(1px); }
.sb-shop-icon {
    width: 48px; height: 48px;
    margin: 0 auto;
    border-radius: 14px;
    display: flex; align-items: center; justify-content: center;
    color: var(--ink);
}
.sb-price-tag {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    height: 36px;
    padding: 0 14px;
    border-radius: 12px;
    background: var(--primary);
    color: var(--primary-ink);
    font-weight: 900;
    font-size: 14px;
    margin-top: 10px;
    box-shadow: 0 3px 0 var(--primary-shade);
}
.sb-shop-card.best {
    background: oklch(from var(--butter) calc(l - 0.02) c h / 0.3);
    border: 2px solid var(--butter);
}
[data-theme="midnight"] .sb-shop-card.best {
    background: oklch(from var(--butter) l c h / 0.12);
}
.sb-badge-ribbon {
    position: absolute;
    top: -8px; left: 50%;
    transform: translateX(-50%);
    background: var(--coral);
    color: var(--primary-ink);
    padding: 3px 10px;
    border-radius: 999px;
    font-size: 10px;
    font-weight: 900;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    white-space: nowrap;
}
.sb-shop-swatch {
    height: 80px;
    border-radius: 12px;
    margin: 6px 0;
    box-shadow: inset 0 0 0 1px var(--line);
}

/* ============================================================
 * Settings
 * ============================================================ */
[data-screen="settings"] .sb-screen-body {
    padding-top: 16px;
}
[data-screen="settings"] .sb-card {
    padding: 18px;
}
.sb-avatar {
    width: 60px; height: 60px;
    border-radius: 20px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: #fffaf4;
    font-weight: 900;
    font-size: 22px;
    flex-shrink: 0;
    border: 1px solid color-mix(in oklab, white, transparent 48%);
    box-shadow:
        inset 0 1px 0 color-mix(in oklab, white, transparent 52%),
        0 12px 22px -16px color-mix(in oklab, var(--ink), transparent 38%);
}
.sb-cloud-account {
    display: flex;
    flex-direction: column;
    gap: 12px;
}
.sb-cloud-account-head {
    display: flex;
    align-items: center;
    gap: 14px;
    min-width: 0;
}
.sb-cloud-account-head .sb-grow { min-width: 0; }
.sb-cloud-status {
    display: flex;
    align-items: center;
    gap: 8px;
    min-height: 28px;
    padding: 6px 10px;
    border-radius: 10px;
    background: color-mix(in oklab, var(--bg-inset), var(--bg) 14%);
    border: 1px solid color-mix(in oklab, var(--hairline), transparent 18%);
    color: var(--ink-2);
    font-size: 12px;
    font-weight: 700;
    line-height: 1.35;
}
.sb-cloud-status svg { width: 16px; height: 16px; flex: 0 0 auto; }
.sb-cloud-status.success { color: var(--primary); }
.sb-cloud-status.warning { color: color-mix(in oklab, var(--butter), var(--ink) 38%); }
.sb-cloud-status.error { color: color-mix(in oklab, var(--coral), var(--ink) 28%); }
.sb-cloud-action {
    min-height: 48px;
    height: auto;
    padding: 12px 16px;
    font-size: 14px;
}
.sb-cloud-spinner {
    display: inline-flex;
    animation: sb-cloud-spin .9s linear infinite;
}
@keyframes sb-cloud-spin { to { transform: rotate(360deg); } }

.sb-cloud-conflict-sheet {
    display: flex;
    flex-direction: column;
    gap: 14px;
}
.sb-cloud-conflict-head { gap: 12px; }
.sb-cloud-conflict-head h2 { margin: 2px 0 0; }
.sb-cloud-conflict-sheet > .sb-body { margin: 0; }
.sb-cloud-guidance {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    padding: 10px 12px;
    border-radius: 12px;
    background: color-mix(in oklab, var(--sky), transparent 86%);
    color: var(--ink-soft);
    font-size: 12px;
    line-height: 1.4;
}
.sb-cloud-guidance svg { width: 18px; height: 18px; flex: 0 0 auto; }
.sb-cloud-options {
    display: grid;
    grid-template-columns: 1fr;
    gap: 10px;
}
.sb-cloud-choice {
    width: 100%;
    min-height: 116px;
    padding: 13px;
    border: 2px solid var(--line-strong);
    border-radius: 16px;
    background: var(--bg-2);
    color: var(--ink);
    font: inherit;
    text-align: left;
    cursor: pointer;
    box-shadow: var(--shadow-soft);
}
.sb-cloud-choice.selected {
    border-color: var(--primary);
    box-shadow: 0 0 0 3px color-mix(in oklab, var(--primary), transparent 78%), var(--shadow-soft);
}
.sb-cloud-choice-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
}
.sb-cloud-recommended {
    padding: 4px 8px;
    border-radius: 999px;
    background: color-mix(in oklab, var(--mint), transparent 55%);
    color: color-mix(in oklab, var(--primary), var(--ink) 20%);
    font-size: 10px;
    font-weight: 900;
    text-transform: uppercase;
    letter-spacing: .04em;
}
.sb-cloud-stats {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 6px;
    margin-top: 10px;
}
.sb-cloud-stats > span {
    display: flex;
    flex-direction: column;
    min-height: 44px;
    padding: 6px 7px;
    border-radius: 9px;
    background: var(--bg-inset);
}
.sb-cloud-stats b { font-size: 13px; }
.sb-cloud-stats small { margin-top: 2px; color: var(--ink-soft); font-size: 10px; }
.sb-cloud-date { display: block; margin-top: 7px; }
.sb-cloud-conflict-actions { display: flex; flex-direction: column; gap: 8px; }
.sb-cloud-conflict-actions .sb-btn { min-height: 48px; height: auto; padding: 12px 16px; font-size: 15px; }
.sb-cloud-overwrite-note { text-align: center; min-height: 18px; }
[data-reduced-motion="true"] .sb-cloud-spinner { animation: none; }

@media (max-width: 360px) {
    .sb-cloud-choice { padding: 11px; }
    .sb-cloud-stats { gap: 4px; }
    .sb-cloud-stats > span { padding-inline: 5px; }
}

/* ============================================================
 * Faded World — map banner, place cards, reveal
 * ============================================================ */

/* Procedural scene container: grey when faded, full color when lit. */
.sb-place-scene, .sb-worldmap-scene, .sb-reveal-scene {
  position: relative;
  width: 100%;
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--bg-inset);
}
.sb-place-scene svg, .sb-worldmap-scene svg, .sb-reveal-scene svg {
  display: block;
  width: 100%;
  height: 100%;
}
.faded { filter: grayscale(1) brightness(1.04) contrast(.92); }
.lit   { filter: grayscale(0); }

/* Staged restoration: a scene heals in 3 acts. Elements are tagged s1/s2/s3;
   the container's data-stage says how many acts are restored. Anything above
   the current stage stays grey, and transitions to color when its act lands. */
.sb-scene .rg { transition: filter 1.1s ease; }
.sb-scene[data-stage="0"] .rg { filter: grayscale(1) brightness(1.05) contrast(.9); }
.sb-scene[data-stage="1"] .s2,
.sb-scene[data-stage="1"] .s3,
.sb-scene[data-stage="2"] .s3 { filter: grayscale(1) brightness(1.05) contrast(.9); }
/* stage 3 = no filter (full color) */

/* Living details — only on the focal scenes (menu banner + reveal), never on
   the many map thumbnails, to keep the list cheap. Reduced-motion safe. */
.sb-worldmap-scene .sc-cloud,
.sb-reveal-scene   .sc-cloud { animation: sc-drift 22s ease-in-out infinite alternate; animation-delay: var(--cd, 0s); }
.sb-worldmap-scene .sc-sun,
.sb-reveal-scene   .sc-sun { transform-box: fill-box; transform-origin: center; animation: sc-sun-pulse 5s ease-in-out infinite; }
.sb-worldmap-scene .sc-water,
.sb-reveal-scene   .sc-water { animation: sc-shimmer 3.6s ease-in-out infinite; }
.sb-worldmap-scene .sc-tree,
.sb-reveal-scene   .sc-tree { transform-box: fill-box; transform-origin: bottom center; animation: sc-sway 6s ease-in-out infinite alternate; animation-delay: var(--td, 0s); }
.sb-worldmap-scene .sc-flower,
.sb-reveal-scene   .sc-flower { transform-box: fill-box; transform-origin: center; animation: sc-pop-soft 4s ease-in-out infinite; animation-delay: var(--fd, 0s); }
.sb-worldmap-scene .sc-star,
.sb-reveal-scene   .sc-star { animation: sc-twinkle 2.6s ease-in-out infinite; animation-delay: var(--sd, 0s); }
.sb-worldmap-scene .sc-halo,
.sb-reveal-scene   .sc-halo { transform-box: fill-box; transform-origin: center; animation: sc-sun-pulse 5s ease-in-out infinite; }
.sb-worldmap-scene .sc-boat,
.sb-reveal-scene   .sc-boat { animation: sc-bob 3.2s ease-in-out infinite; }
.sb-worldmap-scene .sc-window,
.sb-reveal-scene   .sc-window { animation: sc-twinkle 3.4s ease-in-out infinite; }
.sb-worldmap-scene .sc-firefly,
.sb-reveal-scene   .sc-firefly { animation: sc-firefly 3.8s ease-in-out infinite; animation-delay: var(--gd, 0s); }
.sb-worldmap-scene .sc-butterfly,
.sb-reveal-scene   .sc-butterfly { animation: sc-flutter 4.6s ease-in-out infinite alternate; animation-delay: var(--bd, 0s); }
@keyframes sc-drift { to { transform: translateX(22px); } }
@keyframes sc-sun-pulse { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.05); opacity: .94; } }
@keyframes sc-shimmer { 0%, 100% { opacity: .92; } 50% { opacity: .68; } }
@keyframes sc-sway { to { transform: rotate(2.5deg); } }
@keyframes sc-pop-soft { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.14); } }
@keyframes sc-twinkle { 0%, 100% { opacity: .9; } 50% { opacity: .35; } }
@keyframes sc-bob { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-3px) rotate(-1.5deg); } }
@keyframes sc-firefly {
  0%, 100% { opacity: .15; transform: translate(0, 0); }
  40%      { opacity: 1;   transform: translate(5px, -7px); }
  70%      { opacity: .5;  transform: translate(-4px, -12px); }
}
@keyframes sc-flutter {
  0%   { transform: translate(0, 0); }
  50%  { transform: translate(8px, -9px) rotate(6deg); }
  100% { transform: translate(-6px, -4px) rotate(-5deg); }
}
[data-reduced-motion="true"] .sc-cloud,
[data-reduced-motion="true"] .sc-sun,
[data-reduced-motion="true"] .sc-halo,
[data-reduced-motion="true"] .sc-water,
[data-reduced-motion="true"] .sc-tree,
[data-reduced-motion="true"] .sc-star,
[data-reduced-motion="true"] .sc-boat,
[data-reduced-motion="true"] .sc-window,
[data-reduced-motion="true"] .sc-firefly,
[data-reduced-motion="true"] .sc-butterfly,
[data-reduced-motion="true"] .sc-flower { animation: none; }

/* Level intro screen — scene + name + goal + Start. */
.sb-level-intro {
    display: flex;
    flex-direction: column;
    gap: 18px;
    padding-top: 8px;
    padding-bottom: 24px;
}
.sb-intro-scene {
    height: clamp(150px, 28dvh, 200px);
    flex-shrink: 0; /* don't let the flex column squash the scene */
    border-radius: var(--radius-lg);
    overflow: hidden;
    box-shadow: var(--shadow-lift), inset 0 0 0 1px rgba(0,0,0,.05);
    animation: sb-intro-pop 520ms cubic-bezier(.34,1.56,.64,1) both;
}
.sb-intro-scene svg { display: block; width: 100%; height: 100%; }
.sb-intro-head { text-align: center; }
.sb-intro-num { line-height: 1; }
.sb-intro-place { color: var(--ink-soft); margin-top: 4px; font-weight: 600; }
.sb-intro-stats {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 10px;
}
.sb-intro-stat {
    background: var(--bg-2);
    border-radius: var(--radius);
    padding: 12px 6px;
    text-align: center;
    box-shadow: var(--shadow-soft);
}
.sb-intro-stat-val { font: 800 16px/1.1 var(--font-display); color: var(--ink); }
.sb-intro-stat .sb-label { margin-top: 5px; }
.sb-intro-goal {
    display: flex; align-items: center; gap: 14px;
    padding: 16px;
    animation: sb-intro-rise 460ms ease 80ms both;
}
.sb-intro-start {
    margin-top: auto;
    animation: sb-intro-rise 460ms ease 160ms both;
}
@keyframes sb-intro-pop {
    from { opacity: 0; transform: scale(0.94); }
    to   { opacity: 1; transform: scale(1); }
}
@keyframes sb-intro-rise {
    from { opacity: 0; transform: translateY(10px); }
    to   { opacity: 1; transform: translateY(0); }
}
[data-reduced-motion="true"] .sb-intro-scene,
[data-reduced-motion="true"] .sb-intro-goal,
[data-reduced-motion="true"] .sb-intro-start { animation: none; }

/* Menu hero banner — sits on a soft gradient world-card. */
.sb-worldmap-banner {
  background: linear-gradient(135deg, var(--bg-2), var(--bg-inset));
  display: flex; flex-direction: column; gap: 12px;
}
.sb-worldmap-scene { height: 132px; box-shadow: inset 0 0 0 1px rgba(0,0,0,.05); }

/* Map screen */
.sb-map-scroll { display: flex; flex-direction: column; gap: 12px; padding-bottom: 28px; overflow-y: auto; }
.sb-map-scroll > * { flex: 0 0 auto; }
.sb-map-land {
  font-size: 12px; letter-spacing: .16em; text-transform: uppercase;
  color: var(--ink-soft); font-weight: 800; margin: 12px 4px 2px;
}
.sb-place-card {
  position: relative;
  border-radius: var(--radius-lg);
  background: var(--bg-2);
  box-shadow: var(--shadow-lift);
  padding: 10px;
  overflow: hidden;
  transition: transform .14s ease;
}
.sb-place-card[data-action] { cursor: pointer; }
.sb-place-card[data-action]:active { transform: scale(.985); }
.sb-place-card.locked { opacity: .82; }
.sb-place-scene { height: 116px; }

/* Before / After scene viewer (sheet overlay) */
/* Percentage, not vh: the sheet's containing block is the overlay inside
   #sb-stage, and vh is the window — wrong wherever the stage is smaller than
   the window (tablets, foldables, desktop), and wrong on mobile browsers whose
   vh ignores retracting chrome. The 16px inset from .sb-sheet still applies. */
.sb-scene-viewer { max-height: 88%; overflow-y: auto; }
.sb-scene-compare { display: flex; flex-direction: column; gap: 12px; }
.sb-scene-frame { position: relative; border-radius: var(--radius); overflow: hidden; box-shadow: inset 0 0 0 1px rgba(0,0,0,.06); }
.sb-scene-large { height: 168px; }
.sb-scene-large svg { display: block; width: 100%; height: 100%; }
.sb-scene-tag {
  position: absolute; left: 10px; bottom: 10px;
  padding: 4px 12px; border-radius: 999px;
  font: 800 11px/1 var(--font-display); letter-spacing: .08em; text-transform: uppercase;
  background: rgba(20,16,28,0.55); color: #fff; backdrop-filter: blur(3px);
}
.sb-scene-tag.lit { background: var(--mint); color: oklch(25% 0.05 160); }
.sb-place-meta {
  display: flex; align-items: baseline; justify-content: space-between;
  padding: 10px 6px 4px; gap: 10px;
}
.sb-place-name { font-weight: 800; font-size: 16px; color: var(--ink); }
.sb-place-sub  { font-size: 12.5px; color: var(--ink-soft); font-weight: 600; }
.sb-place-card.active { box-shadow: 0 0 0 2px var(--coral), var(--shadow-lift); }
.sb-place-bar {
  height: 8px; border-radius: 6px; background: var(--bg-inset);
  margin: 2px 6px 6px; overflow: hidden;
}
.sb-place-bar > span {
  display: block; height: 100%; border-radius: 6px;
  background: linear-gradient(90deg, var(--coral), var(--butter, #ecc957), var(--mint));
}
.sb-place-badge {
  position: absolute; top: 16px; right: 16px;
  width: 30px; height: 30px; border-radius: 50%;
  background: var(--mint); color: #fff;
  display: flex; align-items: center; justify-content: center;
  font-weight: 900; box-shadow: 0 4px 12px rgba(0,0,0,.18);
}

/* Place-restored reveal */
.sb-reveal {
  flex: 1;
  /* Scroll when the celebration content is taller than the screen (short
     phones) — `safe center` keeps it centered when it fits but never clips the
     top/bottom (incl. the Continue button) when it doesn't. */
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  display: flex; flex-direction: column; align-items: center;
  justify-content: safe center; text-align: center; gap: 12px;
  padding: 24px 22px calc(24px + var(--sb-screen-safe-bottom));
  box-sizing: border-box;
}
.sb-reveal::-webkit-scrollbar { display: none; }
/* In this column layout, sb-grow's flex-grow would stretch buttons to fill the
   vertical space — pin them to a normal height and full (capped) width. */
.sb-reveal .sb-btn { flex: 0 0 auto; width: 100%; max-width: 360px; }
.sb-reveal-tag {
  font-size: 12px; letter-spacing: .18em; text-transform: uppercase;
  color: var(--coral); font-weight: 800;
}
.sb-reveal-title { font-size: 30px; font-weight: 900; color: var(--ink); letter-spacing: -.5px; }
.sb-reveal-scene {
  width: 100%; max-width: 440px; height: clamp(150px, 30dvh, 220px); margin: 8px 0;
  flex-shrink: 0; /* keep its height; the container scrolls instead of squashing it */
  box-shadow: var(--shadow-lift);
}
.sb-reveal-name { font-size: 22px; font-weight: 800; color: var(--ink); }
.sb-reveal-sub  { font-size: 14px; color: var(--ink-soft); margin-bottom: 8px; }
[data-reduced-motion="true"] .sb-place-scene,
[data-reduced-motion="true"] .sb-worldmap-scene,
[data-reduced-motion="true"] .sb-reveal-scene { transition: none; }

/* Alchemist Lab */

/* ============================================================
 * Game-feel — reveal/celebration juice
 * ============================================================ */

/* Confetti burst (DOM particles fired from JS) */
.sb-confetti {
  position: fixed; inset: 0; pointer-events: none; z-index: 999;
  overflow: hidden;
}
.sb-confetti i {
  position: fixed; width: 10px; height: 10px; border-radius: 2px;
  opacity: 0; transform: translate(-50%, -50%);
  animation: sb-confetti-fly 1.1s cubic-bezier(.15, .7, .3, 1) forwards;
}
@keyframes sb-confetti-fly {
  0%   { opacity: 1; transform: translate(-50%, -50%) rotate(0deg) scale(1); }
  100% { opacity: 0; transform: translate(calc(-50% + var(--dx)), calc(-50% + var(--dy))) rotate(var(--rot)) scale(.4); }
}

/* Reveal screen entrance — staged so the moment feels composed */
.sb-reveal-tag   { animation: sb-rise .5s both .05s; }
.sb-reveal-title { animation: sb-pop .55s both .12s; }
.sb-reveal-scene { animation: sb-scene-in .6s both .2s; }
.sb-reveal-name  { animation: sb-rise .5s both .55s; }
.sb-reveal-sub   { animation: sb-rise .5s both .68s; }
.sb-reveal .sb-btn { animation: sb-rise .5s both .8s; }

/* When the scene flips to .lit it gives a gentle spring "bloom" */
.sb-reveal-scene.lit { animation: sb-bloom .7s ease both; }

@keyframes sb-rise {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: translateY(0); }
}
@keyframes sb-pop {
  0%   { opacity: 0; transform: scale(.7); }
  60%  { opacity: 1; transform: scale(1.08); }
  100% { transform: scale(1); }
}
@keyframes sb-scene-in {
  from { opacity: 0; transform: scale(.92) translateY(10px); }
  to   { opacity: 1; transform: scale(1) translateY(0); }
}
@keyframes sb-bloom {
  0%   { transform: scale(.97); }
  45%  { transform: scale(1.025); }
  100% { transform: scale(1); }
}

/* Map: restored badge pops in; active card breathes once */
.sb-place-badge { animation: sb-pop .5s both; }
.sb-place-card.active { animation: sb-active-breathe 2.4s ease-in-out infinite; }
@keyframes sb-active-breathe {
  0%, 100% { box-shadow: 0 0 0 2px var(--coral), var(--shadow-lift); }
  50%      { box-shadow: 0 0 0 3px var(--coral), var(--shadow-lift); }
}

[data-reduced-motion="true"] .sb-reveal-tag,
[data-reduced-motion="true"] .sb-reveal-title,
[data-reduced-motion="true"] .sb-reveal-scene,
[data-reduced-motion="true"] .sb-reveal-name,
[data-reduced-motion="true"] .sb-reveal-sub,
[data-reduced-motion="true"] .sb-reveal .sb-btn,
[data-reduced-motion="true"] .sb-place-badge,
[data-reduced-motion="true"] .sb-place-card.active { animation: none; }

/* Onboarding mix visual (yellow + blue = green) */
.sb-onboarding-mixop {
  position: absolute; font-size: 30px; font-weight: 800; color: var(--ink-soft);
}
.sb-onboarding-mixresult { animation: sb-mix-pulse 1.6s ease-in-out infinite; }
@keyframes sb-mix-pulse {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.08); }
}
[data-reduced-motion="true"] .sb-onboarding-mixresult,
[data-reduced-motion="true"] .sb-tour-drag-piece,
[data-reduced-motion="true"] .sb-tour-prism,
[data-reduced-motion="true"] .sb-tour-hint-orb { animation: none; }

/* ============================================================
 * Reward sheet (hints earned + double-via-ad)
 * ============================================================ */
.sb-reward-sheet .sb-reward-body {
  display: flex; flex-direction: column; align-items: center;
  text-align: center; padding: 6px 6px 8px;
}
.sb-reward-orb {
  width: 84px; height: 84px; border-radius: 26px;
  display: grid; place-items: center; color: #fff;
  background: linear-gradient(135deg, var(--butter), var(--coral));
  box-shadow: 0 12px 30px rgba(226, 96, 79, 0.3);
  margin-bottom: 10px; animation: sb-pop 0.6s both;
}
.sb-reward-orb svg { width: 42px; height: 42px; }
.sb-reward-amount { font-size: 46px; font-weight: 900; color: var(--ink); line-height: 1; }
.sb-reward-label { font-size: 15px; color: var(--ink-soft); font-weight: 700; margin-top: 6px; }
.sb-reward-double { background: linear-gradient(135deg, #e2604f, #d7a72f) !important; color: #fffaf4 !important; }
[data-reduced-motion="true"] .sb-reward-orb { animation: none; }

/* ============================================================
 * Today's Goals — daily missions (menu card + complete strip)
 * ============================================================ */
.sb-goals-card {
    display: flex;
    flex-direction: column;
    gap: 12px;
}
[data-screen="menu"] .sb-screen-body {
    padding-top: 16px;
}
[data-screen="menu"] .sb-goals-card { margin-top: 16px; }
.sb-goal-row {
    display: flex;
    align-items: center;
    gap: 12px;
    min-height: 38px;
}
.sb-goal-ic {
    width: 36px;
    height: 36px;
    border-radius: 12px;
    display: flex;
    align-items: center;
    justify-content: center;
    flex: none;
}
.sb-goal-ic svg { width: 17px; height: 17px; }
.sb-goal-main { flex: 1; min-width: 0; }
.sb-goal-label {
    font-weight: 800;
    font-size: 13px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.sb-goal-bar { margin-top: 5px; }
.sb-goal-count {
    font-size: 12px;
    font-weight: 700;
    color: var(--ink-soft);
    flex: none;
}
.sb-goal-reward {
    display: inline-flex;
    align-items: center;
    gap: 3px;
    font-weight: 800;
    font-size: 12px;
    color: oklch(52% 0.1 80);
    flex: none;
}
.sb-goal-reward .sb-coin-ic svg { width: 14px; height: 14px; }
/* The day-scoped coin ledger. Goal coins are auto-credited the instant a goal
   completes and are no longer part of the level-complete headline, so this line
   is where the player reads what today has paid — and what today still owes. */
.sb-goals-ledger {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-top: 2px;
    padding-top: 10px;
    border-top: 1px solid var(--line);
    color: var(--ink-soft);
    font-size: 12px;
    font-weight: 700;
    line-height: 1.35;
}
.sb-goals-ledger strong {
    color: color-mix(in oklab, var(--ink), var(--butter) 22%);
    font-weight: 900;
}
.sb-goals-ledger .sb-coin-ic { display: inline-flex; flex: none; color: var(--butter); }
.sb-goals-ledger .sb-coin-ic svg { width: 15px; height: 15px; }
.sb-goal-done-ic { color: var(--mint); flex: none; display: inline-flex; }
.sb-goal-row.done .sb-goal-label { color: var(--ink-soft); }
.sb-goal-row.done .sb-goal-ic { opacity: 0.55; }
.sb-goal-row.done .sb-goal-bar > span { background: var(--mint); }
/* A goal that completed on this very clear pops in on the complete screen. */
.sb-goal-row.fresh {
    animation: sb-goal-pop 0.55s 1.1s cubic-bezier(0.34, 1.56, 0.64, 1) backwards;
}
@keyframes sb-goal-pop {
    0%   { transform: scale(0.9); opacity: 0; }
    100% { transform: scale(1);   opacity: 1; }
}
[data-reduced-motion="true"] .sb-goal-row.fresh { animation: none; }
.sb-complete-goals {
    padding: 14px 16px;
    text-align: left;
}
/* Coins chip on the Faded World reveal (those clears skip the complete screen) */
.sb-reveal-coins {
    margin-top: 6px;
    background: color-mix(in oklab, var(--butter), transparent 78%);
    box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--butter), transparent 55%);
    font-weight: 800;
}

/* =========================================================================
   Treasure levels — golden recurring levels (~every 9th) with a guaranteed
   coin chest on first clear. Gilds the HUD title, the level-intro scene, the
   menu "up next" chip, and the complete-screen nudge line. Kept subtle:
   token-driven so it reads correctly in every theme (cream/midnight/etc).
   ========================================================================= */

/* HUD title — reads distinct from the normal "Level NN" and Prism titles. */
.sb-game-title-treasure {
    color: color-mix(in oklab, var(--butter), var(--ink) 15%);
    font-weight: 900;
}

/* Compact-phone tuning: preserve 48px primary touch targets while reclaiming
 * horizontal space on the narrowest phones. */
@media (max-width: 370px) {
    .sb-hud-btn { width: 40px; height: 40px; }
    .sb-hud-side { gap: 5px; }
    .sb-hud-count { height: 31px; line-height: 31px; padding: 0 8px; }
    .sb-hud-center-chip .sb-hud-count { padding: 0 7px; }
    .sb-hud-count .sb-mono { font-size: 10.5px; }
    /* Five HUD elements on a 360px phone is the tightest case in the app. The
       "BLOCKS" label is the only redundant token — the x/y reads as a count on
       its own — so it goes first, before anything touchable shrinks further. */
    .sb-hud-count-label { display: none; }
    .sb-game-top {
        padding-left: calc(12px + var(--sb-safe-left));
        padding-right: calc(12px + var(--sb-safe-right));
    }
    .sb-hud { gap: 6px; }
    .sb-hud-center { gap: 4px; }
    .sb-hud-center .sb-chip { padding-inline: 7px; gap: 4px; font-size: 11px; }
    .sb-hud-center .sb-chip svg { width: 14px; height: 14px; }
    .sb-coin-pill { padding-inline: 9px; }
    .sb-coin-pill.sb-hud-coins { padding: 0 7px; gap: 3px; font-size: 11px; }
    .sb-hud-coins .sb-coin-ic svg { width: 13px; height: 13px; }
    .sb-sheet-actions { gap: 6px; }
    .sb-sheet-action { padding-inline: 2px; }
    .sb-sheet-action-label { font-size: 9px; letter-spacing: 0.02em; }
    /* Tutorial still uses the control bar. */
    .sb-control-bar {
        padding-left: calc(12px + var(--sb-safe-left));
        padding-right: calc(12px + var(--sb-safe-right));
    }
    .sb-ctrl-icon { width: 42px; height: 42px; }
    .sb-ctrl-label { font-size: 9.5px; letter-spacing: 0.04em; }
    .sb-menu-grid { gap: 10px; }
    .sb-menu-tile { padding: 15px; }
    /* The day-scoped coin surfaces. All three are text-with-a-coin next to
       other content on the narrowest common Android width, so they trim type
       and gaps rather than wrapping into the row beside them. */
    .sb-goals-ledger { font-size: 11px; gap: 5px; }
    .sb-goals-ledger .sb-coin-ic svg { width: 14px; height: 14px; }
    .sb-streak-next-chip { padding-inline: 9px; gap: 6px; font-size: 11px; }
    .sb-streak-next-coins { padding-left: 6px; gap: 2px; }
    .sb-streak-next-coins .sb-coin-ic svg { width: 13px; height: 13px; }
    .sb-complete-day-badges .sb-badge-chip { font-size: 10px; padding: 4px 8px 4px 5px; }
}

/* Sub-360px phones (320-359 CSS px). HUD only — 360px is the common Android
 * width and keeps the fuller chrome above; this tier exists for the genuinely
 * narrow devices where five HUD items plus a chip plus a four-digit balance
 * stop fitting.
 *
 * The one structural concession: on a chip-bearing level the block count drops
 * its pill chrome and becomes bare digits. The chip carries meaning the player
 * cannot get anywhere else on screen, so the count gives up decoration before
 * the chip gives up legibility — the same reasoning that retires the "BLOCKS"
 * label at 370px. Touch targets are untouched. */
@media (max-width: 359px) {
    .sb-game-top {
        padding-left: calc(9px + var(--sb-safe-left));
        padding-right: calc(9px + var(--sb-safe-right));
    }
    .sb-hud { gap: 5px; }
    .sb-hud-center { gap: 3px; }
    .sb-hud-center-chip .sb-hud-count {
        padding: 0 2px;
        background: none;
        border-color: transparent;
        box-shadow: none;
    }
    .sb-hud-center .sb-chip { padding-inline: 6px; }
    .sb-coin-pill.sb-hud-coins { padding: 0 6px; font-size: 10.5px; }
    .sb-hud-coins .sb-coin-ic svg { width: 12px; height: 12px; }
}

/* Level-intro scene gets a golden ring/glow + a slow shimmer pulse. */
.sb-intro-treasure .sb-intro-scene {
    box-shadow: var(--shadow-lift),
        inset 0 0 0 1px rgba(0,0,0,.05),
        0 0 0 3px color-mix(in oklab, var(--butter), transparent 35%),
        0 0 26px color-mix(in oklab, var(--butter), transparent 55%);
    animation: sb-intro-pop 520ms cubic-bezier(.34,1.56,.64,1) both,
        sb-treasure-shimmer 3.6s ease-in-out 520ms infinite;
}
@keyframes sb-treasure-shimmer {
    0%, 100% { filter: brightness(1); }
    50%      { filter: brightness(1.06); }
}
[data-reduced-motion="true"] .sb-intro-treasure .sb-intro-scene {
    animation: none;
}

/* Menu hero "up next" chip when the queued level is a Treasure level. */
.sb-hero-chip-treasure {
    background: linear-gradient(150deg,
        color-mix(in oklab, var(--butter), white 25%) 0%,
        var(--butter) 100%) !important;
    color: oklch(30% 0.07 80) !important;
    font-weight: 800;
    animation: sb-treasure-chip-pulse 1.8s ease-in-out infinite alternate;
}
@keyframes sb-treasure-chip-pulse {
    from { transform: scale(1); }
    to   { transform: scale(1.05); }
}
[data-reduced-motion="true"] .sb-hero-chip-treasure {
    animation: none;
}

/* Complete-screen nudge line — gold variant swapped in when a chest is 1-2
   levels away (replaces, never joins, the restore nudge). */
.sb-treasure-nudge-line {
    color: color-mix(in oklab, var(--butter), var(--ink) 25%);
    font-weight: 700;
}
.sb-treasure-nudge-ic {
    color: var(--butter);
}

/* =========================================================================
   Premium semantic icon assets + Prism Pulse special levels
   ========================================================================= */

.sb-tile-icon,
.sb-level-banner-icon,
.sb-pause-icon,
.sb-complete-medal,
.sb-trophy-medal {
    position: relative;
    isolation: isolate;
    overflow: hidden;
}
.sb-trophy-medal {
    /* The earned check badge intentionally sits outside the medal edge. */
    overflow: visible;
}
.sb-tile-icon::before,
.sb-level-banner-icon::before,
.sb-pause-icon::before {
    content: '';
    position: absolute;
    inset: 1px 2px auto;
    height: 42%;
    border-radius: inherit;
    background: linear-gradient(180deg, rgba(255,255,255,.48), rgba(255,255,255,0));
    opacity: .55;
    pointer-events: none;
    z-index: -1;
}
.sb-tile-icon svg,
.sb-level-banner-icon svg,
.sb-pause-icon svg {
    width: 22px;
    height: 22px;
    filter: drop-shadow(0 2px 2px rgba(22, 15, 30, .1));
}
.sb-icon-world {
    border-radius: 13px;
    background: linear-gradient(145deg,
        color-mix(in oklab, var(--sky), white 28%),
        color-mix(in oklab, var(--lilac), var(--mint) 22%));
}
.sb-icon-trophy {
    border-radius: 50% 50% 42% 42%;
    background: linear-gradient(145deg, color-mix(in oklab, var(--butter), white 20%), color-mix(in oklab, var(--butter), var(--coral) 28%));
}
.sb-icon-calendar {
    border-radius: 11px 11px 15px 15px;
    background: linear-gradient(145deg, color-mix(in oklab, var(--coral), white 18%), color-mix(in oklab, var(--rose), var(--coral) 52%));
}

.sb-bg-pulse {
    color: #fff;
    background: linear-gradient(145deg, #8c63ff 0%, #6b78ff 48%, #36c9ff 100%) !important;
    box-shadow: inset 0 1px 0 rgba(255,255,255,.42), 0 8px 20px -10px rgba(107,120,255,.8);
}
.sb-bg-pulse svg { filter: drop-shadow(0 2px 3px rgba(29,20,70,.28)); }
.sb-game-title-pulse {
    color: #7954e8;
    font-weight: 900;
}
.sb-game-title-pulse svg,
.sb-game-title svg {
    width: 17px;
    height: 17px;
    vertical-align: -4px;
}
.sb-pulse-chip {
    color: #6947dc;
    background: linear-gradient(135deg,
        color-mix(in oklab, #8c63ff, var(--bg-inset) 72%),
        color-mix(in oklab, #36c9ff, var(--bg-inset) 78%));
    box-shadow: inset 0 0 0 1px color-mix(in oklab, #8c63ff, transparent 64%);
}
.sb-pulse-chip svg { width: 16px; height: 16px; }
.sb-pulse-chip.pulse { animation: sb-pulse-meter-charge .62s cubic-bezier(.2,1.5,.35,1); }
@keyframes sb-pulse-meter-charge {
    0% { transform: scale(.86); filter: brightness(1); }
    45% { transform: scale(1.16); filter: brightness(1.32); box-shadow: 0 0 18px rgba(140,99,255,.48); }
    100% { transform: scale(1); filter: brightness(1); }
}
.sb-pulse-coach .sb-coachmark-bubble {
    box-shadow: var(--shadow-lift), inset 0 0 0 1px color-mix(in oklab, #8c63ff, transparent 62%);
}
.sb-pulse-coach .sb-h-sm { color: #704be0; display: flex; align-items: center; gap: 7px; }
.sb-pulse-coach .sb-h-sm svg { width: 20px; height: 20px; }

/* ============================================================
 * CrazyGames landscape product shell
 *
 * These rules intentionally live behind the exact portal target. Android and
 * ordinary web keep the proven phone compositions. The portal uses the same
 * 760 x 520 logical frame on every screen, then spends that width with real
 * columns instead of scaling a 400 x 700 phone strip.
 * ============================================================ */
:root[data-platform="crazygames"] .sb-app-header {
    min-height: 64px;
    padding: 10px 22px 9px;
}
:root[data-platform="crazygames"] .sb-screen-body.sb-px {
    padding-left: 22px;
    padding-right: 22px;
}
:root[data-platform="crazygames"] .sb-screen-body {
    padding-bottom: 14px !important;
    scroll-padding-bottom: 14px;
}

/* Main menu: Play owns the left; goals and destinations form the right rail. */
:root[data-platform="crazygames"][data-screen="menu"] .sb-screen-body {
    display: grid;
    grid-template-columns: minmax(0, .9fr) minmax(0, 1.1fr);
    grid-template-rows: minmax(0, 1fr) auto;
    gap: 12px;
    overflow: hidden;
}
:root[data-platform="crazygames"][data-screen="menu"] .sb-hero-play {
    grid-row: 1 / 3;
    min-height: 0;
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding: 24px;
}
:root[data-platform="crazygames"][data-screen="menu"] .sb-hero-play .sb-hero-play-btn {
    margin-top: 28px;
}
:root[data-platform="crazygames"][data-screen="menu"] .sb-goals-card {
    min-height: 0;
    padding: 13px 16px;
}
:root[data-platform="crazygames"][data-screen="menu"] .sb-goal-row {
    padding-block: 7px;
}
:root[data-platform="crazygames"][data-screen="menu"] .sb-menu-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 10px;
}
:root[data-platform="crazygames"][data-screen="menu"] .sb-menu-tile {
    min-height: 76px;
    padding: 11px;
}

/* Level intro: scene on the left, decision information on the right. */
:root[data-platform="crazygames"][data-screen="level-intro"] .sb-level-intro {
    display: grid;
    grid-template-columns: minmax(0, 1.08fr) minmax(0, .92fr);
    grid-template-rows: auto auto auto 1fr auto;
    column-gap: 18px;
    row-gap: 11px;
    padding-top: 10px;
    overflow: hidden;
}
:root[data-platform="crazygames"][data-screen="level-intro"] .sb-level-intro > .sb-card-inset {
    grid-column: 1 / -1;
}
:root[data-platform="crazygames"][data-screen="level-intro"] .sb-intro-scene {
    grid-column: 1;
    grid-row: 1 / 6;
    width: 100%;
    height: 100%;
    min-height: 330px;
}
:root[data-platform="crazygames"][data-screen="level-intro"] .sb-intro-head,
:root[data-platform="crazygames"][data-screen="level-intro"] .sb-intro-stats,
:root[data-platform="crazygames"][data-screen="level-intro"] .sb-intro-goal,
:root[data-platform="crazygames"][data-screen="level-intro"] .sb-intro-start {
    grid-column: 2;
}
:root[data-platform="crazygames"][data-screen="level-intro"] .sb-intro-head { text-align: left; }
:root[data-platform="crazygames"][data-screen="level-intro"] .sb-intro-stat { padding: 10px 4px; }
:root[data-platform="crazygames"][data-screen="level-intro"] .sb-intro-goal { padding: 13px; }

/* Completion: solved board remains the visual hero, actions remain visible. */
:root[data-platform="crazygames"][data-screen="complete"] .sb-complete-clean {
    display: grid;
    grid-template-columns: minmax(0, .9fr) minmax(300px, 1.1fr);
    grid-template-rows: auto 1fr auto;
    align-items: center;
    column-gap: 28px;
    row-gap: 10px;
    padding: 20px 34px 18px;
    overflow: hidden;
    text-align: left;
}
:root[data-platform="crazygames"][data-screen="complete"] .sb-complete-clean-title {
    grid-column: 2;
    align-items: flex-start;
}
:root[data-platform="crazygames"][data-screen="complete"] .sb-complete-puzzle-card {
    grid-column: 1;
    grid-row: 1 / 4;
    width: min(330px, 100%);
    justify-self: center;
}
:root[data-platform="crazygames"][data-screen="complete"] .sb-complete-reward {
    grid-column: 2;
    align-items: center;
    justify-self: stretch;
    text-align: center;
    margin: 0;
}
:root[data-platform="crazygames"][data-screen="complete"] .sb-complete-day-badges,
:root[data-platform="crazygames"][data-screen="complete"] .sb-complete-day-badges .sb-badge-chip-row {
    justify-content: center;
}
:root[data-platform="crazygames"][data-screen="complete"] .sb-complete-clean-actions {
    grid-column: 2;
    width: 100%;
    margin: 0;
}

/* Daily: the challenge hero and reset live left; proof/progression live right. */
:root[data-platform="crazygames"][data-screen="daily"] .sb-focus-screen-body {
    display: grid;
    grid-template-columns: minmax(0, .92fr) minmax(0, 1.08fr);
    grid-template-rows: auto minmax(0, 1fr) auto;
    gap: 12px 16px;
    overflow: hidden;
}
:root[data-platform="crazygames"][data-screen="daily"] .sb-focus-hero {
    grid-column: 1;
    grid-row: 1 / 3;
    min-height: 0;
    height: 100%;
    display: flex;
    flex-direction: column;
}
:root[data-platform="crazygames"][data-screen="daily"] .sb-focus-play-btn { margin-top: auto !important; }
:root[data-platform="crazygames"][data-screen="daily"] .sb-focus-reset {
    grid-column: 1;
    grid-row: 3;
}
:root[data-platform="crazygames"][data-screen="daily"] .sb-focus-best {
    grid-column: 2;
    grid-row: 1;
}
:root[data-platform="crazygames"][data-screen="daily"] .sb-focus-constellation {
    grid-column: 2;
    grid-row: 2;
    min-height: 0;
}
:root[data-platform="crazygames"][data-screen="daily"] .sb-focus-rules {
    grid-column: 2;
    grid-row: 3;
}

/* Progress collections use the width to show meaningful density. */
:root[data-platform="crazygames"][data-screen="levels"] .sb-level-grid {
    grid-template-columns: repeat(10, minmax(0, 1fr));
}
:root[data-platform="crazygames"][data-screen="trophies"] .sb-trophy-grid {
    grid-template-columns: repeat(4, minmax(0, 1fr));
}
:root[data-platform="crazygames"][data-screen="trophies"] .sb-trophy-tile {
    padding: 12px 8px;
}
:root[data-platform="crazygames"][data-screen="map"] .sb-map-scroll {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    align-content: start;
    gap: 12px;
}
:root[data-platform="crazygames"][data-screen="map"] .sb-map-land { grid-column: 1 / -1; }
:root[data-platform="crazygames"][data-screen="map"] .sb-place-scene { height: 92px; }
:root[data-platform="crazygames"][data-screen="settings"] .sb-screen-body,
:root[data-platform="crazygames"][data-screen="shop"] .sb-screen-body {
    display: grid !important;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    align-content: start;
    gap: 14px !important;
}

/* Tour/replay remains available from Info, but becomes a desktop spread. */
:root[data-platform="crazygames"][data-screen="onboarding"] .sb-screen-body {
    display: grid !important;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    grid-template-rows: 1fr auto auto;
    gap: 14px 30px !important;
    padding-top: 16px !important;
    text-align: left !important;
}
:root[data-platform="crazygames"][data-screen="onboarding"] .sb-onboarding-illust {
    grid-column: 1;
    grid-row: 1 / 4;
    align-self: center;
}
:root[data-platform="crazygames"][data-screen="onboarding"] .sb-screen-body > .sb-col {
    grid-column: 2;
    align-self: end;
    max-width: none !important;
}
:root[data-platform="crazygames"][data-screen="onboarding"] .sb-onboarding-dots,
:root[data-platform="crazygames"][data-screen="onboarding"] .sb-screen-body > .sb-row {
    grid-column: 2;
}

/* Restoration reveal: the restored world is the hero, with the reward copy
   and actions grouped beside it instead of stacked into a tall phone flow. */
:root[data-platform="crazygames"][data-screen="reveal"] .sb-reveal {
    display: grid;
    grid-template-columns: minmax(0, 1.12fr) minmax(260px, .88fr);
    grid-template-rows: auto auto auto auto 1fr auto auto;
    align-items: center;
    justify-content: stretch;
    gap: 8px 24px;
    padding: 24px 34px;
    overflow: hidden;
    text-align: left;
}
:root[data-platform="crazygames"][data-screen="reveal"] .sb-reveal-scene {
    grid-column: 1;
    grid-row: 1 / 8;
    width: 100%;
    max-width: none;
    height: 100%;
    min-height: 360px;
    margin: 0;
}
:root[data-platform="crazygames"][data-screen="reveal"] .sb-reveal > :not(.sb-reveal-scene) {
    grid-column: 2;
}
:root[data-platform="crazygames"][data-screen="reveal"] .sb-reveal .sb-btn {
    width: 100%;
    max-width: none;
    margin-top: 0 !important;
}

/* Sheets are desktop dialogs inside the landscape frame, not wide bottom bars. */
:root[data-platform="crazygames"] .sb-overlay { align-items: center; padding: 16px; }
:root[data-platform="crazygames"] .sb-sheet {
    width: min(460px, calc(100% - 32px));
    max-height: calc(100% - 32px);
    border-radius: 24px;
}

/* Gameplay chrome aligns with the board/cabinet rather than stretching three
   equal groups across unrelated regions. */
:root[data-platform="crazygames"][data-screen="game"] .sb-game-top {
    padding: 10px 16px 4px;
}
:root[data-platform="crazygames"][data-screen="game"] .sb-hud {
    display: grid;
    grid-template-columns: 180px 180px minmax(0, 1fr);
    gap: 0;
}
:root[data-platform="crazygames"][data-screen="game"] .sb-hud-side:first-child { justify-content: flex-start; }
:root[data-platform="crazygames"][data-screen="game"] .sb-hud-center { justify-content: center; }
:root[data-platform="crazygames"][data-screen="game"] .sb-hud-side-end { justify-content: flex-end; }
:root[data-platform="crazygames"][data-screen="game"] .sb-coachmark {
    /* First-encounter guidance belongs to the board, never over the pieces
       cabinet. Board occupies logical x=60..360; the tray starts at x=410. */
    position: absolute;
    z-index: 4;
    top: 156px;
    left: 52px;
    width: 316px;
    margin: 0;
    align-items: center;
}
:root[data-platform="crazygames"][data-screen="game"] .sb-coachmark-bubble {
    width: 100%;
    box-sizing: border-box;
}

@media (prefers-reduced-motion: reduce) {
    :root[data-platform="crazygames"] .sb-screen.active:not([data-screen="game"]) * {
        scroll-behavior: auto;
    }
}
.sb-intro-pulse .sb-intro-scene {
    box-shadow: var(--shadow-lift),
        0 0 0 3px color-mix(in oklab, #8c63ff, transparent 48%),
        -14px 8px 38px color-mix(in oklab, #8c63ff, transparent 76%),
        14px -6px 34px color-mix(in oklab, #36c9ff, transparent 78%);
    animation: sb-intro-pop 520ms cubic-bezier(.34,1.56,.64,1) both,
        sb-pulse-scene-breathe 3.2s ease-in-out 620ms infinite;
}
@keyframes sb-pulse-scene-breathe {
    0%,100% { filter: saturate(1); }
    50% { filter: saturate(1.08) brightness(1.035); }
}
.sb-hero-chip-pulse {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    color: #fff !important;
    background: linear-gradient(135deg, #8c63ff, #5b8df7 56%, #36c9ff) !important;
    box-shadow: inset 0 1px 0 rgba(255,255,255,.38), 0 6px 16px -9px rgba(73,82,224,.85);
    animation: sb-pulse-chip-breathe 1.7s ease-in-out infinite alternate;
}
.sb-hero-chip-pulse svg { width: 15px; height: 15px; }
@keyframes sb-pulse-chip-breathe { to { transform: scale(1.045); filter: brightness(1.08); } }
.sb-pulse-nudge-line { color: #704be0; font-weight: 750; }
.sb-pulse-nudge-line .sb-restore-nudge-ic { color: #7a55ea; }

[data-reduced-motion="true"] .sb-pulse-chip.pulse,
[data-reduced-motion="true"] .sb-intro-pulse .sb-intro-scene,
[data-reduced-motion="true"] .sb-hero-chip-pulse { animation: none; }
.sb-rating-stars svg {
    width: 24px;
    height: 24px;
    flex: 0 0 auto;
}
