/* ==========================================
   SalmasFlix — Base styles (html/body, scrollbar, utilities, decorations)
   Mobile-First Responsive Design

   Theme tokens + all [data-theme="..."] preset blocks live in tokens.css
   (extracted in Phase 7.1). tokens.css MUST be linked BEFORE this file.

   This file owns:
     - scrollbar design (webkit + scrollbar-color)
     - universal reset (* box-sizing + tap-highlight)
     - focus-visible / prefers-reduced-motion
     - html + body (font stack + 5-layer radial body bg + bottom-center tint)
     - body::before animated gradient (iOS PWA bottom-strip fix)
     - typography (.logo, .logo-modern, accent glow)
     - falling emojis + London landmarks + confetti + skull + hand decorations
   ========================================== */

/* ==========================================
   PHASE (this commit) — @layer nesting
   This file owns the reset + base layers. Scrollbar, `*` box-sizing,
   focus handling, body bg — all live in @layer base. The sr-only
   utilities below live in @layer utilities so they win over component
   styles when a hidden element still has a positioned component rule.
   Layer order declared at top of <head> in index.html:
     @layer tokens, reset, base, components, features, utilities, overrides;
   ========================================== */
@layer base {

/* Dark Scrollbar — applied globally and explicitly to all scrollable areas */
* {
    scrollbar-width: thin;
    scrollbar-color: rgba(var(--secondary-rgb), 0.5) rgba(13, 11, 30, 0.4);
}

::-webkit-scrollbar {
    width: 6px;
    height: 6px;
}

::-webkit-scrollbar-track {
    background: rgba(13, 11, 30, 0.4);
    border-radius: 10px;
}

::-webkit-scrollbar-thumb {
    background: linear-gradient(180deg, rgba(var(--secondary-rgb), 0.6), rgba(var(--secondary-dark-rgb), 0.8));
    border-radius: 10px;
}

::-webkit-scrollbar-thumb:hover {
    background: linear-gradient(180deg, rgba(var(--secondary-rgb), 0.9), rgba(var(--secondary-dark-rgb), 1));
}

::-webkit-scrollbar-corner {
    background: transparent;
}

/* Force visible scrollbars on mobile for queue */
@supports (-webkit-overflow-scrolling: touch) {
    .media-queue-list {
        -webkit-overflow-scrolling: touch;
    }
}

/* Reset & Base */
*,
*::before,
*::after {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
    -webkit-tap-highlight-color: transparent;
}

/* Remove default focus highlights (mouse clicks) */
*:focus {
    outline: none;
}

button:focus,
select:focus,
input:focus,
a:focus {
    outline: none;
    box-shadow: none;
}

/* Keyboard navigation focus indicators (accessibility) */
*:focus-visible {
    outline: 2px solid var(--accent-primary) !important;
    outline-offset: 2px;
}

button:focus-visible,
a:focus-visible {
    outline: 2px solid var(--accent-primary) !important;
    outline-offset: 2px;
    box-shadow: 0 0 0 4px rgba(var(--primary-rgb), 0.2) !important;
}

/* Respect reduced motion preference */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
    }
}

/* ==========================================
   PHASE 8.3 — USER-SELECTABLE MOTION TIER
   See CLAUDE.md + docs/audit/ROADMAP.md §Phase 8.3.
   `html[data-motion="reduced"]` mirrors prefers-reduced-motion (the
   user can opt-in even if their OS reports no preference). `data-motion=
   "off"` is stricter — all animations disabled outright, transitions
   flattened. Applied in public/js/core/a11y.js + a bootstrap pre-paint
   step for flash-free first frame.
   ========================================== */
html[data-motion="reduced"] *,
html[data-motion="reduced"] *::before,
html[data-motion="reduced"] *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
}
html[data-motion="off"] *,
html[data-motion="off"] *::before,
html[data-motion="off"] *::after {
    animation: none !important;
    transition: none !important;
    scroll-behavior: auto !important;
}

/* ==========================================
   PHASE 8.4 — DENSITY TIER
   --density-scale multiplies spacing values in select containers.
   1.0 = comfortable, 0.86 = compact. Only applied at strategic sites
   (nav/header/fab/profile rows) — a blanket * { padding: calc(X *
   --density-scale) } would break tons of hand-tuned layouts.
   ========================================== */
:root {
    --density-scale: 1;
}
html[data-density="compact"] {
    --density-scale: 0.86;
}

} /* end @layer base (utilities follow in their own higher-priority layer) */

/* ==========================================
   PHASE 8.2 — SCREEN-READER-ONLY UTILITIES
   .sr-only:        completely hidden visually, exposed to AT.
   .sr-only-focusable: hidden until keyboard-focused (skip links).
   The inline-ish `clip-path: inset(50%)` is the modern variant
   (clip: rect(0,0,0,0) is deprecated but kept for Safari <14.5).

   Live in @layer utilities so they out-prioritize @layer components /
   @layer features — this is what lets us DROP the !important salad that
   used to defend .sr-only from decorated elements.
   ========================================== */
@layer utilities {
.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}
.sr-only-focusable {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}
.sr-only-focusable:focus,
.sr-only-focusable:focus-visible,
.sr-only-focusable:active {
    position: fixed;
    top: 12px;
    left: 12px;
    width: auto;
    height: auto;
    padding: 10px 18px;
    margin: 0;
    overflow: visible;
    clip: auto;
    clip-path: none;
    white-space: normal;
    z-index: var(--z-critical, 9999);
    background: var(--primary);
    color: var(--btn-primary-color, #0d0b1e);
    font-family: 'Outfit', sans-serif;
    font-weight: 700;
    font-size: 0.85rem;
    text-decoration: none;
    border-radius: 10px;
    box-shadow: 0 0 0 2px rgba(var(--primary-rgb), 0.4), 0 10px 30px rgba(0, 0, 0, 0.4);
    outline: none;
}

} /* end @layer utilities (base resumes below for html/body/typography) */

@layer base {

html {
    font-size: 16px;
    scroll-behavior: smooth;
    -webkit-text-size-adjust: 100%;
    height: 100%;
    overflow: hidden;
}

body {
    font-family: 'Outfit', -apple-system, BlinkMacSystemFont, sans-serif;
    background:
        radial-gradient(ellipse at 20% 0%, rgba(var(--secondary-rgb), 0.1) 0%, transparent 50%),
        radial-gradient(ellipse at 80% 100%, rgba(var(--primary-rgb), 0.18) 0%, transparent 50%),
        radial-gradient(ellipse at 50% 50%, rgba(var(--primary-rgb), 0.06) 0%, transparent 70%),
        radial-gradient(ellipse at 10% 90%, rgba(var(--primary-rgb), 0.08) 0%, transparent 40%),
        /* Bottom-center fill. Without this, the bottom ~40-60px render as
           near-solid var(--bg-dark) while the rest of the page carries ~10-20%
           primary/secondary tint from the four corner radials above. On iOS
           PWA standalone (viewport-fit=cover + black-translucent), that
           exposed strip reads as a distinct "bottom bar" — the eye catches
           the tint discontinuity between the lit mid-body and the dark strip
           behind / under the home-indicator. A large low-tension ellipse
           anchored slightly BELOW the viewport (50% 105%) pulls secondary
           tint across the full bottom edge symmetrically with the top's
           secondary corner at 20% 0%, so the page reads as edge-to-edge
           tinted glass rather than "content then dark bar". */
        radial-gradient(ellipse 85% 35% at 50% 105%, rgba(var(--secondary-rgb), 0.12) 0%, transparent 70%),
        var(--bg-dark);
    color: var(--text-primary);
    height: 100%;
    width: 100%;
    overflow: hidden;
    position: relative;
    /* No safe-area padding here — content flows edge-to-edge into the status bar
       and home indicator regions (iOS 26 / Liquid Glass convention).
       Individual anchors (header, FAB, scrollable bottoms) apply their own
       env(safe-area-inset-*) so nothing is hidden under system chrome. */
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    /* iOS rubberband / overscroll prevention. `overflow: hidden` above
       handles desktop, but iOS Safari still allows the body to "rubberband"
       when no inner scroll container catches the swipe (i.e. on tabs whose
       inner content is shorter than the viewport, like an empty diary).
       overscroll-behavior: none kills the chain so the body itself never
       moves — only inner scrollers (.diary-blocks-wrap, .gallery-section,
       etc.) scroll, and only when their content overflows. */
    overscroll-behavior: none;
}

/* Global tap-feedback class — added by features/haptic-tap.ts on
   pointerdown / touchstart to selected interactive elements,
   removed on pointerup / touchend / cancel. Real haptic vibration
   fires alongside via SfxHaptics on platforms that allow it
   (Android Chrome + iOS Capacitor PWA). On iOS Safari (regular
   browser AND "Add to Home Screen" PWA) Apple blocks all web
   vibration APIs, so this visual press is the only feedback the
   user gets — bumped to a more noticeable 0.94 scale + slight
   brightness reduction so it actually FEELS like something
   happened on tap. transition is fast (90ms in) so it's snappy.

   `:where()` keeps specificity at 0,0,0 so existing :active rules
   on individual buttons aren't overridden. */
:where(.sfx-pressed) {
    transform: scale(0.94);
    filter: brightness(0.92);
    transition: transform 90ms cubic-bezier(0.4, 0, 0.2, 1),
                filter 90ms cubic-bezier(0.4, 0, 0.2, 1);
}
:where(.sfx-pressed.video-card,
       .sfx-pressed.show-card,
       .sfx-pressed.book-card,
       .sfx-pressed.media-queue-item) {
    /* Larger surfaces get a subtler scale — 0.94 reads dramatic on a
       big card. 0.97 is enough to register press without feeling
       jumpy. */
    transform: scale(0.97);
}

/* Chat-panel body lock (mobile only — desktop panel is anchored by the
   FAB, no need for body lock). Single class wraps every lock primitive
   so removing the class atomically clears the entire lock — no chance
   of leaving one inline style behind, which was the legacy bug where
   chat-close left body in a half-locked state where iOS rubberband
   suddenly worked. The CSS variable carries the saved scrollY so we
   can restore the user's exact scroll position on close. */
body.sfx-body-locked {
    position: fixed;
    top: var(--sfx-locked-scroll-y, 0);
    left: 0;
    right: 0;
    width: 100%;
    overflow: hidden;
    overscroll-behavior: none;
    touch-action: none;
}

/* Animated Moving Gradient Background */
body::before {
    content: '';
    position: fixed;
    inset: 0;
    z-index: -1;
    background:
        radial-gradient(ellipse 80% 50% at 20% 30%, rgba(var(--secondary-rgb), 0.3) 0%, transparent 50%),
        radial-gradient(ellipse 60% 40% at 80% 70%, rgba(var(--secondary-alt-rgb), 0.2) 0%, transparent 50%),
        radial-gradient(ellipse 70% 60% at 50% 50%, rgba(var(--secondary-dark-rgb), 0.15) 0%, transparent 60%),
        /* Bottom-edge coverage on the animated layer too, for the same reason
           as the body bg: the mid-body is richly tinted but the bottom strip
           renders as exposed bg-dark, creating a perceived "bar" under iOS
           PWA. Anchored below the viewport so the tint only bleeds upward. */
        radial-gradient(ellipse 90% 45% at 50% 108%, rgba(var(--secondary-rgb), 0.2) 0%, transparent 65%),
        var(--bg-dark);
    background-size: 200% 200%, 200% 200%, 200% 200%, 100% 100%, 100% 100%;
    animation: gradientMove 15s ease-in-out infinite;
    animation-play-state: running;
}

/* Pause background animation when tab is not visible */
.page-hidden body::before {
    animation-play-state: paused;
}

@keyframes gradientMove {
    0% {
        background-position: 0% 0%, 100% 100%, 50% 50%, 0% 0%;
    }

    25% {
        background-position: 50% 30%, 30% 70%, 70% 30%, 0% 0%;
    }

    50% {
        background-position: 100% 100%, 0% 0%, 30% 70%, 0% 0%;
    }

    75% {
        background-position: 30% 70%, 70% 30%, 50% 50%, 0% 0%;
    }

    100% {
        background-position: 0% 0%, 100% 100%, 50% 50%, 0% 0%;
    }
}

/* .hidden lives in @layer utilities (see below) so we can drop the
   !important; utilities beats features + components per the layer stack. */

/* Twemoji styling */
img.emoji {
    height: 1em;
    width: 1em;
    margin: 0 .05em 0 .1em;
    vertical-align: -0.1em;
}

/* Typography */
.logo {
    font-size: clamp(1.5rem, 5vw, 2.5rem);
    font-weight: 800;
    letter-spacing: -1px;
    text-transform: uppercase;
}

.logo .accent {
    background: linear-gradient(135deg, var(--accent-primary), var(--accent-secondary));
    background-clip: text; -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
    filter: drop-shadow(0 0 20px var(--accent-glow));
}

/* Modern Logo */
.logo-modern {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.75rem;
    font-size: clamp(2rem, 8vw, 3.5rem);
    font-weight: 800;
    letter-spacing: -2px;
    margin: 0;
    position: relative;
}

.logo-modern.centered {
    justify-content: center;
    text-align: center;
    width: 100%;
}

.logo-modern .logo-icon {
    font-size: 1em;
    filter: drop-shadow(0 0 20px var(--accent-glow-purple));
    animation: iconPulse 2s ease-in-out infinite;
}

.logo-modern .logo-image {
    height: clamp(50px, 10vw, 80px);
    width: auto;
    border-radius: 50%;
    filter: drop-shadow(0 0 15px var(--accent-glow-purple));
    animation: iconPulse 2s ease-in-out infinite;
}

@keyframes iconPulse {

    0%,
    100% {
        transform: scale(1);
    }

    50% {
        transform: scale(1.1);
    }
}

.logo-modern .logo-text {
    background: linear-gradient(135deg, #fff 0%, #e0e0e0 100%);
    background-clip: text; -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
    text-shadow: none;
    position: relative;
}

.logo-modern .accent {
    background: linear-gradient(135deg, var(--accent-primary), var(--accent-secondary), var(--accent-tertiary));
    background-clip: text; -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
    filter: drop-shadow(0 0 30px var(--accent-glow));
    animation: accentGlow 3s ease-in-out infinite alternate;
}

@keyframes accentGlow {
    0% {
        filter: drop-shadow(0 0 20px var(--accent-glow));
    }

    100% {
        filter: drop-shadow(0 0 40px var(--accent-glow-purple));
    }
}

.tagline {
    color: var(--text-secondary);
    font-size: clamp(0.9rem, 3vw, 1.2rem);
    font-weight: 400;
    margin-top: var(--spacing-md);
    letter-spacing: 0.5px;
}

.hint {
    color: var(--text-muted);
    font-size: clamp(0.75rem, 2vw, 0.9rem);
    margin-top: var(--spacing-lg);
    font-style: italic;
}

/* ==========================================
   FALLING EMOJIS
   ========================================== */

.falling-emojis {
    position: fixed;
    inset: 0;
    pointer-events: none;
    overflow: hidden;
    z-index: 0;
}

.falling-emoji {
    position: absolute;
    font-size: clamp(1.25rem, 3vw, 2rem);
    top: -50px;
    animation: emojiFloat linear infinite;
    opacity: 0.6;
    contain: layout style;
}

@media (prefers-reduced-motion: reduce) {
    .falling-emoji { display: none; }
}

@keyframes emojiFloat {
    0% {
        transform: translateY(0) rotate(0deg);
        opacity: 0;
    }

    10% {
        opacity: 0.6;
    }

    90% {
        opacity: 0.6;
    }

    100% {
        transform: translateY(100vh) rotate(360deg);
        opacity: 0;
    }
}

/* ==========================================
   LONDON LANDMARKS + TEXT BACKGROUND
   ========================================== */
.london-bg {
    position: fixed;
    inset: 0;
    pointer-events: none;
    z-index: 0;
    overflow: hidden;
}
.london-bg > * {
    position: absolute;
}
/* SVG landmarks — themed primary color, faded but readable */
.london-icon {
    color: rgba(var(--primary-rgb), 0.04);
    filter: drop-shadow(0 0 1px rgba(var(--primary-rgb), 0.06));
}
/* Positions, sizes, rotations for each landmark */
.li1 { width: 160px; top: 3%; left: 2%; transform: rotate(-2deg); }
.li2 { width: 340px; bottom: 2%; right: 0%; }
.li3 { width: 180px; top: 25%; right: 2%; transform: rotate(3deg); }
.li4 { width: 300px; bottom: 15%; left: 3%; transform: rotate(-1deg); }
.li5 { width: 60px; top: 50%; left: 16%; transform: rotate(5deg); }
.li6 { width: 200px; top: 8%; right: 10%; transform: rotate(-3deg); }
.li7 { width: 70px; bottom: 38%; right: 18%; }
.li8 { width: 80px; top: 62%; left: 38%; transform: rotate(8deg); }
.li9 { width: 120px; top: 40%; left: 50%; transform: rotate(-5deg); }
.li10 { width: 55px; top: 75%; right: 8%; transform: rotate(10deg); }
.li11 { width: 50px; bottom: 5%; left: 40%; transform: rotate(-12deg); }
.li12 { width: 70px; top: 18%; left: 22%; transform: rotate(6deg); }
.li13 { width: 90px; bottom: 30%; right: 5%; transform: rotate(-4deg); }
/* Scattered text — horizontal, vertical, flipped, curved */
.london-text {
    font-family: 'Outfit', sans-serif;
    font-weight: 700;
    color: rgba(var(--primary-rgb), 0.055);
    white-space: nowrap;
    text-transform: uppercase;
    letter-spacing: 1.5px;
}
.london-text.t1 { font-size: 0.8rem; top: 6%; left: 12%; transform: rotate(-3deg); }
.london-text.t2 { font-size: 1rem; top: 22%; right: 8%; transform: rotate(2deg); }
.london-text.t3 { font-size: 0.6rem; top: 42%; left: 15%; writing-mode: vertical-rl; }
.london-text.t4 { font-size: 0.75rem; bottom: 12%; right: 5%; transform: rotate(4deg); }
.london-text.t5 { font-size: 1.1rem; bottom: 32%; left: 2%; transform: rotate(-8deg); }
.london-text.t6 { font-size: 0.65rem; top: 72%; right: 22%; transform: rotate(5deg); }
.london-text.t7 { font-size: 0.9rem; top: 16%; left: 40%; transform: rotate(-15deg); }
.london-text.t8 { font-size: 0.55rem; bottom: 48%; left: 30%; writing-mode: vertical-rl; }
.london-text.t9 { font-size: 0.7rem; top: 85%; left: 20%; transform: rotate(12deg); }
.london-text.t10 { font-size: 1.2rem; top: 52%; right: 30%; transform: rotate(-6deg); }
.london-text.t11 { font-size: 1.4rem; bottom: 8%; left: 45%; transform: rotate(-7deg); }
.london-text.t12 { font-size: 0.85rem; top: 35%; left: 55%; writing-mode: vertical-rl; }
.london-text.t13 { font-size: 0.75rem; top: 92%; right: 15%; transform: rotate(-3deg); }
.london-text.t14 { font-size: 1.0rem; top: 78%; left: 5%; writing-mode: vertical-rl; }
.london-text.t15 { font-size: 0.6rem; top: 60%; left: 60%; transform: rotate(8deg); }
@media (prefers-reduced-motion: reduce) {
    .london-bg { display: none; }
}

/* ==========================================
   FALLING SKULLS (for lose animation)
   ========================================== */

.falling-skull {
    position: absolute;
    top: -50px;
    pointer-events: none;
    animation: skullFall linear forwards;
    opacity: 0.8;
    z-index: 100;
}

@keyframes skullFall {
    0% {
        transform: translateY(0) rotate(0deg);
        opacity: 0;
    }

    10% {
        opacity: 0.8;
    }

    90% {
        opacity: 0.8;
    }

    100% {
        transform: translateY(100vh) rotate(360deg);
        opacity: 0;
    }
}

/* ==========================================
   GAME CONFETTI (for win animation)
   ========================================== */

.game-confetti-piece {
    position: absolute;
    top: -10px;
    pointer-events: none;
    animation: confettiFall linear forwards;
    z-index: 100;
}

@keyframes confettiFall {
    0% {
        transform: translateY(0) rotate(0deg);
        opacity: 0;
    }

    10% {
        opacity: 1;
    }

    90% {
        opacity: 1;
    }

    100% {
        transform: translateY(100vh) rotate(360deg);
        opacity: 0;
    }
}

/* ==========================================
   SHAKING HANDS (for draw animation)
   ========================================== */

.shaking-hand {
    position: absolute;
    top: -50px;
    pointer-events: none;
    animation: handShake linear forwards;
    z-index: 100;
}

@keyframes handShake {
    0% {
        transform: translateY(0) rotate(0deg);
        opacity: 0;
    }

    10% {
        opacity: 1;
    }

    90% {
        opacity: 1;
    }

    100% {
        transform: translateY(100vh) rotate(360deg);
        opacity: 0;
    }
}

} /* end @layer base */

/* ==========================================
   @layer utilities — tiny utility stragglers.
   Winning over @layer features lets these rules work without
   !important. Keep this block minimal — if a rule deserves a
   standalone file (scrollbars, etc), move it out.
   ========================================== */
@layer utilities {

/* Display-none helper used by ~50 JS callers. No !important needed —
   utilities out-prioritizes features/components by the declared layer
   stack in index.html. */
.hidden {
    display: none;
}

} /* end @layer utilities */
