/* Kellerkind Web — a custom, modern idle-tycoon look. No framework, no build.
   Dark neon aesthetic, glassy cards, big touch targets, mobile-first with safe-area
   support so it feels native inside the Pi Browser and on phones. */

:root {
    /* Deep near-black base. IMPORTANT: this is also the solid colour that fills the
       iOS home-indicator safe-area strip. On iOS standalone (black-translucent) a
       position:fixed; inset:0 shell does NOT always paint into that bottom strip —
       html/body paints it instead. If this base differs from what the fixed overlays
       fade to at their bottom (.app/.landing/.paywall all bottom out at ~#04070d),
       that strip reads as a visible seam above the home indicator. Keep this EQUAL to
       those overlay bottoms so the strip is invisible whether or not the fixed layer
       reaches the physical edge. (This was the real cause of the persistent iOS gap.) */
    --bg-0: #04070d;
    --bg-1: #0c1424;
    /* Opaque colour that MATCHES the app shell's own background at the top of the
       content column. The sticky tab bar is filled with this, so it is invisible
       against the column (and the cards scroll opaquely underneath it). */
    --seg-bg: #090e1a;
    --surface: rgba(22, 33, 54, 0.72);
    --surface-2: rgba(30, 44, 70, 0.65);
    --stroke: rgba(120, 160, 220, 0.16);
    --stroke-strong: rgba(120, 200, 160, 0.4);

    --neon: #37f2a3;
    --neon-soft: #6bffc2;
    --gold: #ffd23f;
    --gold-soft: #ffe487;
    --danger: #ff5d6c;

    --text: #eaf2ff;
    --muted: #9db0cf;
    --muted-2: #7789ab;

    --r-lg: 22px;
    --r-md: 16px;
    --r-sm: 11px;
    --shadow: 0 18px 40px -20px rgba(0, 0, 0, 0.8);
    --glow: 0 0 24px -4px var(--neon);

    --nav-h: 74px;
    --max-w: 620px;

    /* iOS safe-area insets (notch/Dynamic Island + home indicator). Real device
       values when installed as a PWA; 0 otherwise. Overridable in tests. */
    --sat: env(safe-area-inset-top, 0px);
    --sab: env(safe-area-inset-bottom, 0px);
    --sal: env(safe-area-inset-left, 0px);
    --sar: env(safe-area-inset-right, 0px);

    /* Gap between the floating bottom nav and the physical screen edge. The nav is a
       FLOATING capsule (by design), so it must clear the home indicator — but the full
       safe-area inset (~34px) floated it too high and left a large empty band below it.
       Use only HALF the inset plus a small fixed float: the capsule sits noticeably
       tighter to the edge while its 74px body still clears the indicator. On devices
       with no home indicator (env = 0) this is just 7px. Content padding + toasts key
       off the same variable so they always clear the nav wherever it lands. */
    /* Floating bottom-nav gap — ROBUST against iOS's unreliable cold-start insets.
       clamp() pins it to a sane range no matter what env() reports at launch:
         • normal (inset ~34px) → 7 + 34*0.5 = 24px (the tight look we want)
         • cold-start inset = 0  → floored to 18px  (never clips the home indicator)
         • bogus/inflated inset  → capped at 40px    (never "too much space")
       So it can't break whether env() is 0, correct, or inflated on cold start.
       Content padding + toasts key off this same value. */
    --nav-gap: clamp(18px, calc(7px + env(safe-area-inset-bottom, 0px) * 0.5), 40px);

    font-family: "Inter", "Segoe UI", system-ui, -apple-system, Roboto, sans-serif;
}

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
/* Stop iOS Safari from auto-inflating text: it enlarges type in some blocks,
   which pushes grid/flex children past the viewport (the achievements sheet was
   overflowing on iPhone while Chromium rendered it fine). */
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
/* Disable text selection / long-press copy across the game UI. Inputs stay editable
   (see the input/textarea override below) so login, keys and renaming still work. */
html { -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; -webkit-touch-callout: none; }
input, textarea { -webkit-user-select: text; -moz-user-select: text; -ms-user-select: text; user-select: text; -webkit-touch-callout: default; }

html, body {
    margin: 0;
    /* Full dynamic-viewport height. Using 100% here made iOS standalone clamp the
       page to the SAFE-AREA height and clip the 100dvh .app at the bottom, so the
       body background showed through as a seam above the home indicator. 100dvh
       matches the app shell exactly. */
    height: 100dvh;
    background: var(--bg-0);
    color: var(--text);
    overscroll-behavior: none;
    overflow: hidden; /* only the inner content scrolls — never the whole page */
}

body {
    /* Ambient aurora backdrop behind the centered app shell. No bottom-anchored glow:
       iOS can clip position:fixed elements at the home-indicator, so the safe-area
       strip shows THIS background — keep its bottom flat/dark so it matches the app
       bottom and never reads as a seam. */
    background:
        radial-gradient(1100px 700px at 15% -10%, rgba(55, 242, 163, 0.14), transparent 60%),
        radial-gradient(900px 650px at 110% 10%, rgba(255, 210, 63, 0.10), transparent 55%),
        var(--bg-0);
    background-attachment: fixed;
}

/* ── App shell ─────────────────────────────────────────────────────────────── */
.app {
    max-width: var(--max-w);
    margin: 0 auto;
    /* Pin to ALL four screen edges. 100dvh alone left a seam at the bottom on iOS
       standalone (dvh under-reports the home-indicator strip); inset:0 forces the
       shell to reach the real bottom edge regardless of how iOS measures dvh. */
    position: fixed; inset: 0; z-index: 1;
    display: flex;
    flex-direction: column;
    background: linear-gradient(180deg, rgba(10, 16, 29, 0.80), rgba(6, 10, 17, 0.90));
    backdrop-filter: blur(26px) saturate(1.06);
    -webkit-backdrop-filter: blur(26px) saturate(1.06);
    border-left: 1px solid rgba(255,255,255,0.08);
    border-right: 1px solid rgba(255,255,255,0.08);
    box-shadow: 0 0 70px -12px rgba(0,0,0,0.55);
    overflow: hidden;
}

/* ── Top bar + KPIs ────────────────────────────────────────────────────────── */
.topbar {
    padding: calc(var(--sat) + 12px) 16px 12px;
    background: linear-gradient(180deg, rgba(10, 17, 30, 0.95), rgba(10, 17, 30, 0.55));
    border-bottom: 1px solid var(--stroke);
    backdrop-filter: blur(10px);
    z-index: 5;
}

/* ── Day/night window: the view onto the world, grows with the empire ──────── */
/* Cross-fadable sky: the gradient is built from four <color> custom properties,
   and @property makes those colours TRANSITIONABLE — so a phase change (e.g.
   22:00 dusk→night) eases over ~1s instead of snapping straight to night. */
@property --sky-1 { syntax: "<color>"; inherits: false; initial-value: #050a18; }
@property --sky-2 { syntax: "<color>"; inherits: false; initial-value: #0b1430; }
@property --sky-3 { syntax: "<color>"; inherits: false; initial-value: #141e42; }
@property --sky-4 { syntax: "<color>"; inherits: false; initial-value: #141e42; }

.sky {
    position: relative; overflow: hidden;
    height: 150px; margin: 0 0 10px; border-radius: 18px;
    border: 1px solid rgba(255,255,255,0.14);
    background: linear-gradient(180deg, var(--sky-1) 0%, var(--sky-2) 46%, var(--sky-3) 78%, var(--sky-4) 100%);
    box-shadow:
        inset 0 1px 0 rgba(255,255,255,0.18),
        inset 0 0 0 1px rgba(0,0,0,0.25),
        inset 0 -16px 32px -20px rgba(0,0,0,0.85),
        0 10px 28px -18px rgba(0,0,0,0.7);
    transition: height .6s cubic-bezier(.4,0,.2,1),
        --sky-1 1s ease, --sky-2 1s ease, --sky-3 1s ease, --sky-4 1s ease;
}
.sky.hidden { display: none; }
/* soft glass sheen sweeping across the window */
.sky::after {
    content: ""; position: absolute; inset: 0; pointer-events: none; border-radius: inherit;
    background: linear-gradient(118deg, rgba(255,255,255,0.14) 0%, rgba(255,255,255,0.04) 26%, rgba(255,255,255,0) 44%);
}
/* window opens up scene by scene: Kellerluke → Bürofenster → Konzernturm → Skyline */
/* the hero banner grows a little with the empire, but always tall enough to hold
   the brand overlay (top) and the KPI cards (bottom) */
.sky.tier-basement { height: 150px; }
.sky.tier-office   { height: 162px; }
.sky.tier-tower    { height: 178px; }
.sky.tier-skyline  { height: 196px; }

/* ambient scene switched off: keep the banner (it holds brand + KPIs), just drop
   the animated sky to a neutral surface */
/* "Window off" is a dark neutral banner in BOTH themes — a switched-off sky screen.
   Keeping it dark (not light in the light theme) guarantees the light HUD text on
   the dark glass cards stays readable. */
.sky.scene-off { --sky-1:#131d30; --sky-2:#101828; --sky-3:#0d1421; --sky-4:#0d1421; }
.sky.scene-off .sky-stars, .sky.scene-off .sky-clouds, .sky.scene-off .sky-cel, .sky.scene-off .sky-scape { display: none; }

/* ── Variant-3 HUD overlays on the sky banner ─────────────────────────────────── */
.hero-top { position: absolute; top: 12px; left: 12px; right: 12px; z-index: 3;
    display: flex; align-items: flex-start; justify-content: space-between; gap: 8px; }
.hero-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; justify-content: flex-end; }
.hero-brand { display: flex; align-items: center; gap: 9px; padding: 6px 13px 6px 8px; border-radius: 13px; }
.hero-brand .logo-img { width: 28px; height: 28px; border-radius: 8px; flex: none; }
/* The HUD always sits on the DARK glass, so its accents use FIXED light colours,
   never the theme's --neon-soft/--gold-soft (which are dark in the light theme and
   would vanish on the dark glass). */
.hero-brand .name { font-weight: 800; font-size: 17px; letter-spacing: .2px;
    background: linear-gradient(90deg, #6bffc2, #ffe487); -webkit-background-clip: text; background-clip: text; color: transparent; }

/* frosted-glass base for every element that sits ON the sky */
.sky .glass, .hero-actions .icon-btn, .kpi {
    -webkit-backdrop-filter: blur(9px) saturate(1.12); backdrop-filter: blur(9px) saturate(1.12);
    box-shadow: 0 6px 16px -10px rgba(0,0,0,0.55), inset 0 1px 0 rgba(255,255,255,0.10);
}
/* The HUD elements carry LIGHT text, so their frosted panel must stay dark enough
   to read on ANY sky — night (dark), day (light blue), or the neutral "window off"
   banner (light in the light theme). Hence a fairly opaque dark base, not a faint
   tint. */
.hero-brand.glass, .sky-cap.glass, .hero-actions .icon-btn {
    background: rgba(12,17,30,0.60); border: 1px solid rgba(255,255,255,0.18); color: #f1f5fb;
}
.hero-actions .icon-btn { width: 34px; height: 34px; border-radius: 11px; }
.sky-cap.glass { color: #f3f6fb; text-shadow: 0 1px 2px rgba(0,0,0,0.5); }
.sky-bonus.glass { text-shadow: 0 1px 2px rgba(0,0,0,0.45); }

.hero-kpis { position: absolute; left: 12px; right: 12px; bottom: 12px; z-index: 3; display: flex; gap: 10px; }
.kpi { flex: 1; min-width: 0; display: flex; align-items: center; gap: 10px; padding: 9px 12px; border-radius: 13px;
    background: rgba(12,17,30,0.66); border: 1px solid rgba(255,255,255,0.16); }
.kpi.cv { --tint: 55,242,163; } .kpi.cash { --tint: 55,242,163; } .kpi.rps { --tint: 255,210,63; }
.kpi-ic { flex: none; width: 32px; height: 32px; border-radius: 9px; display: grid; place-items: center; font-size: 16px;
    background: rgba(var(--tint,55,242,163),0.18); border: 1px solid rgba(var(--tint,55,242,163),0.34); }
.kpi-b { min-width: 0; }
.kpi .label { font-size: 9.5px; text-transform: uppercase; letter-spacing: .7px; font-weight: 800; color: #c6d2e4; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.kpi .val { font-size: 18px; font-weight: 800; margin-top: 1px; line-height: 1.1; color: #fff; }
.kpi.cv .val { background: linear-gradient(90deg, #ffffff, #6bffc2); -webkit-background-clip: text; background-clip: text; color: transparent; }
.kpi.cash .val { color: #6bffc2; }
.kpi.rps .val { color: #ffe487; }

/* The KPI cards + the next-milestone card share a stack pinned to the bottom of
   the sky HUD; the banner grows a little to make room for the milestone card. */
.hero-bottom { position: absolute; left: 12px; right: 12px; bottom: 12px; z-index: 3; display: flex; flex-direction: column; gap: 8px; }
.hero-bottom .hero-kpis { position: static; left: auto; right: auto; bottom: auto; }
.sky.has-goal.tier-basement { height: 198px; }
.sky.has-goal.tier-office   { height: 210px; }
.sky.has-goal.tier-tower    { height: 226px; }
.sky.has-goal.tier-skyline  { height: 244px; }

/* Large screens: lay the three KPIs and the milestone out as FOUR equal cards in
   ONE row along the bottom of the (unchanged, full-height) sky — better use of the
   width and more skyline shows above. `display:contents` lets the three .kpi cards
   join the milestone as direct flex items. Smaller windows keep the stacked layout
   (3 KPIs + milestone below); phones have their own minimal HUD (≤560px). */
@media (min-width: 768px) {
    .sky.has-goal .hero-bottom { flex-direction: row; align-items: stretch; gap: 10px; }
    .sky.has-goal .hero-bottom .hero-kpis { display: contents; }
    .sky.has-goal .hero-bottom .goal { flex: 1; min-width: 0; }
    .sky.has-goal .hero-bottom .kpi { align-self: stretch; }
}

/* narrow screens: keep the three KPI cards but tighten them so they fit */
@media (max-width: 560px) {
    .kpi { padding: 8px 9px; gap: 8px; }
    .kpi-ic { width: 28px; height: 28px; font-size: 14px; }
    .kpi .val { font-size: 15px; }
    .kpi .label { font-size: 8.5px; letter-spacing: .4px; }
    .hero-brand .name { font-size: 15px; }
}

/* Phones: a minimal, flat status bar instead of the immersive sky window (which
   is too tall to sit above every screen). Only the KPIs + the milestone remain,
   on the day/night colour gradient. The whole top row — brand, live bonus chip
   and theme toggle — is dropped (theme lives in Profil → Einstellungen; the bonus
   still applies, it's just not shown). ~105px instead of ~170px. */
@media (max-width: 560px) {
    .sky.has-goal { height: auto !important; display: flex; flex-direction: column; gap: 6px; padding: 9px 10px; border-radius: 14px; }
    /* keep only the gradient — drop the scene layers + glass sheen */
    .sky.has-goal .sky-stars, .sky.has-goal .sky-clouds, .sky.has-goal .sky-cel, .sky.has-goal .sky-scape { display: none; }
    .sky.has-goal::after { display: none; }
    .sky.has-goal .hero-top { display: none; }                   /* drop brand + bonus + theme toggle entirely */
    .sky.has-goal .hero-bottom { position: static; left: auto; right: auto; bottom: auto; gap: 6px; }
    .hero-kpis { gap: 7px; }
    .kpi { padding: 8px 9px; gap: 0; }
    .kpi-ic { display: none; }              /* value gets the full card width */
    .kpi-b { width: 100%; }
    .kpi .label { font-size: 8px; letter-spacing: .2px; }
    .kpi .val { font-size: 13px; white-space: nowrap; letter-spacing: -.2px; }
    /* milestone: a borderless single line — ring (shows %), flag + short name, thin
       bar. The .sky.has-goal prefix raises specificity so these win over the base
       .goal card rules that appear later in the file. */
    .sky.has-goal .goal { padding: 3px 2px 7px; gap: 8px; background: none; border: none; box-shadow: none; }
    .sky.has-goal .goal .ring { width: 28px; height: 28px; }
    .sky.has-goal .goal .ring span { font-size: 8.5px; }
    .sky.has-goal .goal .ring::after { inset: 2.5px; }
    .sky.has-goal .goal-k { display: none; }
    .sky.has-goal .goal-n { font-size: 12.5px; }
    .sky.has-goal .goal-n::before { content: "🏁 "; }
    .sky.has-goal .goal-n .sub { display: none; }
}

/* Short viewports (a phone in LANDSCAPE): the tall immersive sky window would
   swallow the whole screen and leave no room for content. Collapse it into a flat,
   compact strip — KPIs (icons kept, there's width to spare) + a one-line milestone
   — so the content area gets the height. Triggered by height, so it complements the
   max-width phone rules above without touching tablets/desktops (they're taller). */
@media (max-height: 560px) and (min-width: 561px) {
    :root { --nav-h: 60px; }
    /* Collapse the big day/night window into a flat compact strip on ALL short
       viewports — with OR without an active milestone goal (previously only
       .has-goal collapsed, so a goalless view kept the tall scene and ate the
       screen in landscape). */
    .sky { height: auto !important; min-height: 0; display: flex; flex-direction: column; gap: 6px; padding: 8px 12px; border-radius: 16px; margin-bottom: 8px; }
    .sky .sky-stars, .sky .sky-clouds, .sky .sky-cel, .sky .sky-scape { display: none; }
    .sky::after { display: none; }
    .sky .hero-top { display: none; }                              /* drop the brand/bonus/theme row */
    .sky .hero-bottom { position: static; left: auto; right: auto; bottom: auto; gap: 6px; }
    .sky .kpi { padding: 7px 11px; }
    .sky .kpi .val { font-size: 16px; }
    .sky.has-goal .goal { padding: 4px 10px; }
    .sky.has-goal .goal .ring { width: 34px; height: 34px; }
    .sky.has-goal .goal .ring span { font-size: 9.5px; }
    .sky.has-goal .goal-k { display: none; }                        /* one-line milestone */
    .sky.has-goal .goal-n .sub { display: none; }
}

/* Dialogs on short viewports (phone landscape): the big KEL artwork would fill the
   whole modal and push the action buttons off-screen. Shrink the imagery and tighten
   spacing so the title, text and buttons fit (portrait phones are taller than 560px
   and keep the full-size look). */
@media (max-height: 560px) {
    .modal { max-height: calc(100dvh - var(--sat) - var(--sab) - 24px); padding: 14px 16px; }
    .modal h2 { font-size: 17px; }
    .modal .sub { margin-bottom: 10px; }
    .modal-actions { margin-top: 10px; }
    /* .modal-prefixed so these win over the base image rules regardless of source order */
    .modal .kel-banner { max-width: 118px; margin: 0 auto 10px; }
    .modal .kel-react { width: 66px; height: 66px; margin: 0 auto 8px; border-radius: 16px; }
    .modal .kel-avatar { width: 56px; height: 56px; }
    .modal .streak-row { margin: 8px 0 4px; }
    .modal .daily-amt { font-size: 22px; margin: 4px 0 2px; }
    .modal .pre { font-size: 13px; }
}

/* phase sky colours (the sky is the real sky — identical in light & dark). Only
   the four colour stops change; @property eases between them. */
.sky.phase-night  { --sky-1:#050a18; --sky-2:#0b1430; --sky-3:#141e42; --sky-4:#141e42; }
.sky.phase-dawn   { --sky-1:#223055; --sky-2:#6a4a72; --sky-3:#c07a6a; --sky-4:#eaa571; }
.sky.phase-day    { --sky-1:#2b63b8; --sky-2:#4f97e0; --sky-3:#9cc8ee; --sky-4:#cfe6f7; }
.sky.phase-golden { --sky-1:#363463; --sky-2:#8a5450; --sky-3:#b25f3d; --sky-4:#f4ad4f; }
.sky.phase-dusk   { --sky-1:#12153a; --sky-2:#452760; --sky-3:#732e5e; --sky-4:#9a3d6b; }

/* twinkling stars — fade in at dusk/night only */
.sky-stars {
    position: absolute; inset: 0; opacity: 0; transition: opacity .9s ease; pointer-events: none;
    background-image:
        radial-gradient(1px 1px at 12% 28%, #fff, transparent), radial-gradient(1px 1px at 28% 62%, rgba(255,255,255,.8), transparent),
        radial-gradient(1px 1px at 46% 34%, #fff, transparent), radial-gradient(1px 1px at 63% 55%, rgba(255,255,255,.75), transparent),
        radial-gradient(1px 1px at 78% 26%, #fff, transparent), radial-gradient(1px 1px at 90% 48%, rgba(255,255,255,.7), transparent);
    background-repeat: no-repeat; animation: twinkle 4s ease-in-out infinite;
}
.sky.phase-night .sky-stars, .sky.phase-dusk .sky-stars { opacity: .85; }

/* drifting clouds — real puffy clouds, visible while it is light out. Each cloud is
   built from overlapping soft radial "puffs" so it reads as a cloud, not a smudge. */
.sky-clouds { position: absolute; inset: 0; opacity: 0; transition: opacity .9s ease; pointer-events: none; }
.sky.phase-day .sky-clouds, .sky.phase-dawn .sky-clouds, .sky.phase-golden .sky-clouds { opacity: 1; }
.sky-cloud {
    position: absolute; height: 30px;
    background:
        radial-gradient(closest-side at 24% 74%, rgba(255,255,255,.97), rgba(255,255,255,0)),
        radial-gradient(closest-side at 46% 54%, #fff, rgba(255,255,255,0)),
        radial-gradient(closest-side at 64% 66%, rgba(255,255,255,.97), rgba(255,255,255,0)),
        radial-gradient(closest-side at 82% 78%, rgba(255,255,255,.92), rgba(255,255,255,0));
    background-repeat: no-repeat;
    background-size: 44% 78%, 60% 128%, 52% 96%, 40% 74%;
    filter: blur(.6px) drop-shadow(0 2px 4px rgba(90,120,165,.22));
}
/* dawn/golden tint the clouds warm so they don't glow pure white against a sunset */
.sky.phase-dawn .sky-cloud, .sky.phase-golden .sky-cloud { filter: blur(.6px) drop-shadow(0 2px 4px rgba(120,80,60,.3)) saturate(.9) brightness(.96); }
/* Each cloud has its OWN drift: it fades in on the left, crosses the banner while
   gently growing/shrinking, and fades out on the right — so it never pops in or out.
   Different keyframes + speeds + offsets keep the three from ever looking identical. */
/* Kept in the upper band (above the KPI/goal cards and clear of the darker
   sky-scape at the bottom) and staggered so at least one is always crossing the
   visible strip — otherwise the short window showed no clouds at all. */
.sky-cloud.a { top: 20%; width: 104px; animation: skydriftA 62s linear infinite;  animation-delay: -18s; }
.sky-cloud.b { top: 34%; width: 78px;  animation: skydriftB 84s linear infinite;  animation-delay: -55s; }
.sky-cloud.c { top: 26%; width: 128px; animation: skydriftC 106s linear infinite; animation-delay: -86s; }

/* sun / moon disc — position driven by --sky-x / --sky-y from the clock */
.sky-cel {
    position: absolute; left: var(--sky-x, 50%); top: var(--sky-y, 32%);
    width: 16px; height: 16px; border-radius: 50%; transform: translate(-50%,-50%);
    transition: left 2.5s ease, top 2.5s ease, background .9s ease, box-shadow .9s ease; pointer-events: none;
}
.sky.phase-day .sky-cel {
    background: radial-gradient(circle at 50% 50%, #fffdf6 0%, #fff0c0 32%, #ffd257 60%, rgba(255,200,80,0) 78%);
    box-shadow: 0 0 6px 2px rgba(255,247,222,0.95), 0 0 26px 8px rgba(255,208,96,0.55);
}
.sky.phase-dawn .sky-cel, .sky.phase-golden .sky-cel {
    background: radial-gradient(circle at 50% 50%, #fff5db 0%, #ffd591 32%, #ff9f4b 62%, rgba(255,128,58,0) 80%);
    box-shadow: 0 0 7px 2px rgba(255,224,168,0.9), 0 0 28px 9px rgba(255,150,72,0.55);
}
.sky.phase-night .sky-cel, .sky.phase-dusk .sky-cel {
    background: radial-gradient(circle at 38% 34%, #ffffff 0%, #e9eefb 30%, #ccd6ec 62%, #a9b4d2 100%);
    box-shadow: inset -3px -3px 6px -2px rgba(60,72,110,0.5), 0 0 5px 1px rgba(240,244,255,0.6), 0 0 20px 5px rgba(200,214,250,0.4);
}

/* clean atmospheric horizon at the bottom of the window (no buildings): a soft
   grounding plus a warm distant city-glow at dusk/night */
.sky-scape {
    position: absolute; left: 0; right: 0; bottom: 0; height: 55%;
    background: linear-gradient(to top, rgba(2,4,10,0.5), rgba(2,4,10,0.12) 55%, rgba(2,4,10,0) 100%);
    transition: height .6s ease; pointer-events: none;
}
.sky.phase-night .sky-scape, .sky.phase-dusk .sky-scape {
    background:
        radial-gradient(120% 90% at 50% 100%, rgba(255,176,92,0.28), rgba(255,150,80,0) 62%),
        linear-gradient(to top, rgba(2,4,10,0.5), rgba(2,4,10,0.12) 55%, rgba(2,4,10,0) 100%);
}

/* Info bar under the sky window: the phase label (left) + the live bonus (right),
   as two frosted pills. Kept OUT of the scene so the moving sun/moon is never
   covered. */
.sky-bar { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin: 0 2px 12px; }
.sky-bar.hidden { display: none; }
.sky-cap {
    display: inline-flex; align-items: center; gap: 5px;
    padding: 4px 11px 4px 10px; border-radius: 999px;
    font-size: 11.5px; font-weight: 800; letter-spacing: .2px; white-space: nowrap;
    color: var(--text);
    background: var(--surface);
    border: 1px solid var(--stroke);
    box-shadow: inset 0 1px 0 rgba(255,255,255,0.06);
}
/* current time-of-day effect. Always visible; the colour tracks the active bonus
   (warm by day, cool by night, muted during the neutral transitions or off). */
.sky-bonus {
    display: inline-flex; align-items: center; gap: 5px;
    padding: 4px 11px; border-radius: 999px;
    font-size: 11.5px; font-weight: 800; letter-spacing: .2px; white-space: nowrap;
    color: #fff8e6;
    background: rgba(255, 176, 60, 0.16);
    border: 1px solid rgba(255, 200, 110, 0.38);
    box-shadow: inset 0 1px 0 rgba(255,255,255,0.10);
}
/* The bonus pill sits on the same dark frosted base (via .glass); the state only
   tints the TEXT + BORDER, never a light background — so it stays readable on any
   sky, warm by day, cool by night, muted when neutral/off. */
.sky-bonus.glass { background: rgba(12,17,30,0.60); }
.sky-bonus.bonus-day   { color: #ffdf9e; border-color: rgba(255, 200, 110, 0.5); }
.sky-bonus.bonus-night { color: #bcd3ff; border-color: rgba(150, 190, 255, 0.5); }
.sky-bonus.bonus-neutral { color: #dfe6f2; border-color: rgba(200, 214, 240, 0.36); }
.sky-bonus.bonus-off   { color: #c7d0de; border-color: rgba(190, 205, 230, 0.3); }
.sky-bonus.hidden { display: none; }
/* The bonus chip always sits on the dark sky banner (both themes), so it keeps its
   light-on-dark colours regardless of the UI theme — no light-theme override. */

.amb-greet { font-size: 12.5px; font-weight: 700; color: var(--gold-soft); margin-bottom: 10px; font-style: italic; }

/* ══ Immersive animated backdrop — fills the empty side-space around the app ══
   The scene reflects the real time of day, so it is identical in light & dark;
   only the app column (glass) changes with the theme. */
@property --as-1 { syntax: "<color>"; inherits: false; initial-value: #04070f; }
@property --as-2 { syntax: "<color>"; inherits: false; initial-value: #0a1330; }
@property --as-3 { syntax: "<color>"; inherits: false; initial-value: #0d1836; }
@property --as-4 { syntax: "<color>"; inherits: false; initial-value: #101a3d; }
#ambient-sky {
    position: fixed; inset: 0; z-index: 0; overflow: hidden; pointer-events: none;
    background: linear-gradient(180deg, var(--as-1) 0%, var(--as-2) 44%, var(--as-3) 78%, var(--as-4) 100%);
    transition: --as-1 1.1s ease, --as-2 1.1s ease, --as-3 1.1s ease, --as-4 1.1s ease, opacity .6s ease;
    /* The sky lives up top and dissolves into the page's own background toward the
       middle/bottom, so there is no hard horizon and it blends into the theme. */
    -webkit-mask-image: linear-gradient(to bottom, #000 0%, #000 42%, transparent 88%);
            mask-image: linear-gradient(to bottom, #000 0%, #000 42%, transparent 88%);
}
#ambient-sky.off { display: none; }
/* horizon haze — atmospheric depth where the sky meets the skyline */
#ambient-sky::before {
    content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 34vh; pointer-events: none;
    background: linear-gradient(to top, rgba(210,228,245,0.16), rgba(210,228,245,0) 100%);
    transition: background 1.1s ease;
}
#ambient-sky.phase-dawn::before, #ambient-sky.phase-golden::before { background: linear-gradient(to top, rgba(255,196,140,0.20), rgba(255,186,130,0) 100%); }
#ambient-sky.phase-night::before, #ambient-sky.phase-dusk::before { background: linear-gradient(to top, rgba(150,170,220,0.10), rgba(150,170,220,0) 100%); }
#ambient-sky.phase-night  { --as-1:#04070f; --as-2:#0a1330; --as-3:#0d1836; --as-4:#101a3d; }
#ambient-sky.phase-dawn   { --as-1:#1a2444; --as-2:#59496f; --as-3:#b9795c; --as-4:#e6a86f; }
#ambient-sky.phase-day    { --as-1:#1f5fb8; --as-2:#3f88d6; --as-3:#86bfe4; --as-4:#cbe6f6; }
#ambient-sky.phase-golden { --as-1:#2b2c63; --as-2:#74495f; --as-3:#c15c38; --as-4:#f2a24c; }
#ambient-sky.phase-dusk   { --as-1:#0c1030; --as-2:#35205a; --as-3:#742e5c; --as-4:#9a3d6b; }

/* LIGHT THEME backdrop: a realistic dark night sky next to a white UI looks
   broken. In light mode the full-viewport backdrop becomes a soft, airy pastel
   sky (still phase-tinted) that harmonises with the light surface; the star field
   is hidden (white stars would vanish/clash) and the game runs the canvas loop
   only in dark mode. The framed sky WINDOW stays realistic in both themes. */
:root[data-theme="light"] #ambient-sky.phase-night  { --as-1:#c3d0ea; --as-2:#d6dff1; --as-3:#e6edf8; --as-4:#f1f5fb; }
:root[data-theme="light"] #ambient-sky.phase-dusk   { --as-1:#d7cde6; --as-2:#e5dbee; --as-3:#efe6f2; --as-4:#f6eff6; }
:root[data-theme="light"] #ambient-sky.phase-dawn   { --as-1:#f3ddce; --as-2:#f7e7d9; --as-3:#fbf1e7; --as-4:#fdf8f1; }
:root[data-theme="light"] #ambient-sky.phase-day    { --as-1:#9ecbf1; --as-2:#bcdaf4; --as-3:#d8e9f8; --as-4:#eef6fc; }
:root[data-theme="light"] #ambient-sky.phase-golden { --as-1:#f2d6bd; --as-2:#f7e4cf; --as-3:#fbefe0; --as-4:#fefaf2; }
:root[data-theme="light"] .as-starfield { display: none; }
/* In the light theme the sky is pale, so white clouds need a soft shadow to read
   as clouds instead of vanishing. Keep each layer's own blur, just add depth. */
:root[data-theme="light"] .as-cloud.a, :root[data-theme="light"] .as-cloud.c { filter: blur(9px) drop-shadow(0 5px 11px rgba(96,128,170,.30)); }
:root[data-theme="light"] .as-cloud.b, :root[data-theme="light"] .as-cloud.d { filter: blur(7px) drop-shadow(0 4px 8px rgba(96,128,170,.24)); }

/* Real star field (canvas). Fades in at night/dusk; the JS render loop only runs
   during those phases, so it costs nothing by day. */
.as-starfield {
    position: absolute; inset: 0; pointer-events: none;
    opacity: 0; transition: opacity 1.3s ease;
}
#ambient-sky.phase-night .as-starfield, #ambient-sky.phase-dusk .as-starfield { opacity: 1; }

/* sun / moon — a real celestial body: a bright disc with a layered atmospheric
   bloom, not a flat cartoon dot */
.as-cel {
    position: absolute; left: var(--as-x, 50%); top: var(--as-y, 24%);
    width: 52px; height: 52px; border-radius: 50%; transform: translate(-50%,-50%);
    transition: left 2.5s ease, top 2.5s ease, background 1.1s ease, box-shadow 1.1s ease; will-change: left, top;
}
.as-cel::before { content: ""; position: absolute; inset: 0; border-radius: 50%; }
/* SUN — white-hot core → warm corona, with a soft breathing bloom */
#ambient-sky.phase-day .as-cel {
    background: radial-gradient(circle at 50% 50%, #fffdf6 0%, #fff2c6 24%, #ffd45e 46%, rgba(255,198,74,0.35) 64%, rgba(255,190,70,0) 73%);
    box-shadow: 0 0 10px 2px rgba(255,248,222,0.95), 0 0 64px 20px rgba(255,208,96,0.5), 0 0 170px 66px rgba(255,194,84,0.30);
    animation: bloom 8s ease-in-out infinite;
}
#ambient-sky.phase-dawn .as-cel, #ambient-sky.phase-golden .as-cel {
    background: radial-gradient(circle at 50% 50%, #fff5db 0%, #ffd591 28%, #ff9f4b 50%, rgba(255,128,58,0.32) 66%, rgba(255,120,55,0) 75%);
    box-shadow: 0 0 12px 3px rgba(255,224,168,0.9), 0 0 72px 24px rgba(255,150,72,0.5), 0 0 190px 74px rgba(255,120,60,0.30);
    animation: bloom 9s ease-in-out infinite;
}
/* MOON — shaded sphere (volume) + cool halo + faint craters */
#ambient-sky.phase-night .as-cel, #ambient-sky.phase-dusk .as-cel {
    background: radial-gradient(circle at 38% 34%, #ffffff 0%, #eef2fb 26%, #ccd6ec 58%, #a9b4d2 84%, #97a3c4 100%);
    box-shadow: inset -6px -6px 14px -6px rgba(60,72,110,0.55), 0 0 8px 1px rgba(240,244,255,0.6), 0 0 50px 12px rgba(198,212,250,0.28), 0 0 130px 44px rgba(176,194,244,0.16);
}
#ambient-sky.phase-night .as-cel::before, #ambient-sky.phase-dusk .as-cel::before {
    opacity: .5;
    background:
        radial-gradient(5px 5px at 60% 40%, rgba(120,132,166,0.55), transparent 62%),
        radial-gradient(7px 7px at 43% 60%, rgba(120,132,166,0.45), transparent 64%),
        radial-gradient(3.5px 3.5px at 68% 66%, rgba(120,132,166,0.5), transparent 60%),
        radial-gradient(3px 3px at 34% 40%, rgba(120,132,166,0.4), transparent 60%);
}

/* parallax clouds — layered soft lumps (puffy) and thin wisps (cirrus) for a
   believable sky rather than uniform white blobs */
.as-clouds { position: absolute; inset: 0; opacity: 0; transition: opacity 1.1s ease; }
#ambient-sky.phase-day .as-clouds { opacity: .85; }
#ambient-sky.phase-dawn .as-clouds, #ambient-sky.phase-golden .as-clouds { opacity: .9; }
#ambient-sky.phase-dusk .as-clouds { opacity: .4; }
.as-cloud { position: absolute; filter: blur(9px); --cl: 255,255,255; }
/* puffy cumulus: several soft lumps of different size fused together */
.as-cloud.a, .as-cloud.c {
    height: 90px;
    background:
        radial-gradient(closest-side at 22% 68%, rgba(var(--cl),0.75), rgba(var(--cl),0) 70%),
        radial-gradient(closest-side at 40% 44%, rgba(var(--cl),0.9), rgba(var(--cl),0) 72%),
        radial-gradient(closest-side at 58% 58%, rgba(var(--cl),0.82), rgba(var(--cl),0) 70%),
        radial-gradient(closest-side at 76% 66%, rgba(var(--cl),0.7), rgba(var(--cl),0) 70%),
        radial-gradient(closest-side at 50% 82%, rgba(var(--cl),0.6), rgba(var(--cl),0) 62%);
}
.as-cloud.a { top: 15%; width: 300px; opacity: .7; animation: asdrift 150s linear infinite; }
.as-cloud.c { top: 46%; width: 380px; opacity: .5; animation: asdrift 240s linear infinite; animation-delay: -140s; }
/* thin high wisps (cirrus) */
.as-cloud.b, .as-cloud.d {
    height: 26px; border-radius: 100px;
    background: linear-gradient(90deg, rgba(var(--cl),0) 0%, rgba(var(--cl),0.5) 30%, rgba(var(--cl),0.6) 55%, rgba(var(--cl),0.35) 75%, rgba(var(--cl),0) 100%);
    filter: blur(7px);
}
.as-cloud.b { top: 26%; width: 320px; opacity: .5; animation: asdrift 190s linear infinite; animation-delay: -70s; }
.as-cloud.d { top: 9%;  width: 240px; opacity: .4; animation: asdrift 165s linear infinite; animation-delay: -110s; }
/* warm tint at golden hour / dawn */
#ambient-sky.phase-golden .as-cloud, #ambient-sky.phase-dawn .as-cloud { --cl: 255, 224, 190; }

/* shooting star (night only, rare) */
/* Meteor: the bright head (right end of the gradient) must LEAD the motion. The
   streak is tilted 18° and travels down-right along that same 18° vector, so the
   glowing head goes first and the faint tail trails behind — real physics. */
.as-shoot { position: absolute; top: 12%; left: 14%; width: 120px; height: 2px; opacity: 0;
    background: linear-gradient(90deg, rgba(255,255,255,0), #fff); border-radius: 2px; transform: rotate(18deg); }
#ambient-sky.phase-night .as-shoot { animation: shoot 14s ease-in infinite; }

/* (No skyline/ground band: the backdrop now dissolves into the page background
   via the mask on #ambient-sky, so there is no hard horizon to draw.) */

@keyframes twinkle { 0%,100% { opacity: var(--tw, .85); } 50% { opacity: calc(var(--tw, .85) * .55); } }
@keyframes skydriftA {
    0%   { transform: translateX(-160px) scale(0.80); opacity: 0; }
    12%  { opacity: 1; }
    50%  { transform: translateX(480px)  scale(1.10); }
    88%  { opacity: 1; }
    100% { transform: translateX(1120px) scale(0.95); opacity: 0; }
}
@keyframes skydriftB {
    0%   { transform: translateX(-120px) scale(1.05); opacity: 0; }
    16%  { opacity: 0.85; }
    55%  { transform: translateX(560px)  scale(0.90); opacity: 0.85; }
    90%  { opacity: 0; }
    100% { transform: translateX(1180px) scale(1.00); opacity: 0; }
}
@keyframes skydriftC {
    0%   { transform: translateX(-200px) scale(1.00); opacity: 0; }
    14%  { opacity: 0.66; }
    52%  { transform: translateX(500px)  scale(1.18); opacity: 0.66; }
    86%  { opacity: 0; }
    100% { transform: translateX(1080px) scale(1.05); opacity: 0; }
}
@keyframes asdrift { from { transform: translateX(-340px); } to { transform: translateX(110vw); } }
@keyframes flicker { 0%,100% { opacity: 1; } 45% { opacity: .82; } 70% { opacity: .95; } }
@keyframes shoot { 0%,92% { opacity: 0; transform: translate(0,0) rotate(18deg); } 93% { opacity: 1; } 100% { opacity: 0; transform: translate(300px,98px) rotate(18deg); } }
@keyframes bloom { 0%,100% { opacity: 1; } 50% { opacity: .9; } }

@media (prefers-reduced-motion: reduce) {
    .sky-cloud, .as-cloud, .as-stars, .sky-stars, .as-city-lights, .as-shoot { animation: none !important; }
    .as-cel, .sky-cel { transition: background 1.1s ease, box-shadow 1.1s ease !important; }
}

.brand-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; }

.brand {
    display: flex; align-items: center; gap: 9px;
    font-weight: 800; font-size: 17px; letter-spacing: 0.2px;
}
.brand .logo {
    width: 30px; height: 30px; border-radius: 9px;
    display: grid; place-items: center; font-size: 17px;
    background: linear-gradient(135deg, rgba(55,242,163,0.9), rgba(255,210,63,0.85));
    box-shadow: var(--glow);
}
.brand .name { background: linear-gradient(90deg, var(--neon-soft), var(--gold-soft)); -webkit-background-clip: text; background-clip: text; color: transparent; }

.share-chip {
    display: flex; align-items: center; gap: 6px;
    padding: 6px 11px; border-radius: 999px; font-size: 12.5px; font-weight: 700;
    color: var(--gold-soft);
    background: rgba(255, 210, 63, 0.10);
    border: 1px solid rgba(255, 210, 63, 0.3);
}

.stats { display: flex; gap: 10px; margin-top: 12px; }
.stat {
    flex: 1; min-width: 0; padding: 11px 13px; border-radius: var(--r-md);
    display: flex; align-items: center; gap: 11px;
    background: linear-gradient(165deg, rgba(255,255,255,0.06), rgba(255,255,255,0)), var(--surface);
    border: 1px solid var(--stroke); position: relative; overflow: hidden;
    box-shadow: 0 6px 18px -14px rgba(0,0,0,0.55);
}
/* a slim coloured accent rail down the left edge, per KPI */
.stat::before {
    content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 3px;
    background: var(--accent, var(--neon)); opacity: .9;
}
.stat.cv   { --accent: linear-gradient(180deg, var(--neon), var(--gold)); --tint: 55,242,163; }
.stat.cash { --accent: var(--neon); --tint: 55,242,163; }
.stat.rps  { --accent: var(--gold); --tint: 255,210,63; }
/* icon tile — tinted to match the KPI's accent */
.stat-ic {
    flex: none; width: 34px; height: 34px; border-radius: 10px; font-size: 17px;
    display: grid; place-items: center;
    background: rgba(var(--tint, 55,242,163), 0.14);
    border: 1px solid rgba(var(--tint, 55,242,163), 0.28);
}
.stat-b { min-width: 0; }
.stat .label { font-size: 10px; color: var(--muted); text-transform: uppercase; letter-spacing: 0.8px; font-weight: 800; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.stat .val { font-size: 20px; font-weight: 800; margin-top: 3px; letter-spacing: .2px; line-height: 1.1; }
.stat.cash .val { color: var(--neon-soft); text-shadow: 0 0 18px rgba(55, 242, 163, 0.35); }
.stat.rps .val { color: var(--gold-soft); }
.val.pop { animation: pop 0.25s ease; }
.stat.rps .val.warn { color: var(--danger); text-shadow: none; }
@keyframes pop { 0% { transform: scale(1); } 40% { transform: scale(1.09); } 100% { transform: scale(1); } }

/* thin demo timer strip under the header */
.demo-strip {
    margin-top: 10px; display: flex; align-items: center; gap: 10px;
    font-size: 12px; color: var(--muted);
    font-variant-numeric: tabular-nums;
}
/* Fixed-width, non-wrapping timer text: keeps the flex bar from resizing (and the
   fill from visually jumping) as the countdown digits change each second. */
.demo-strip .demo-t { flex: none; min-width: 76px; white-space: nowrap; }
.demo-strip .bar { flex: 1; height: 6px; border-radius: 4px; background: rgba(255,255,255,0.08); overflow: hidden; }
.demo-strip .bar > i { display: block; height: 100%; background: linear-gradient(90deg, var(--neon), var(--gold)); border-radius: 4px; }
.demo-strip.hidden { display: none; }
.demo-strip .buy { color: var(--gold-soft); font-weight: 700; cursor: pointer; }

/* ── Content ───────────────────────────────────────────────────────────────── */
.content {
    /* Content padding lives in vars so the sticky .seg-bar can mirror it with negative
       margins and always span edge-to-edge — no matter the breakpoint. Custom props
       inherit, so the child .seg-bar picks these up automatically. */
    --cpt: 16px; --cpx: 14px; --cpb: calc(var(--nav-h) + var(--nav-gap) + 18px);
    flex: 1; overflow-y: auto; -webkit-overflow-scrolling: touch;
    padding: var(--cpt) var(--cpx) var(--cpb);
    /* No own background — the column shows the app shell's background exactly like the
       sidebar/topbar do, so the content area is never a differently-coloured panel. */
    scrollbar-width: thin; scrollbar-color: var(--stroke) transparent;
}
.content::-webkit-scrollbar { width: 7px; }
.content::-webkit-scrollbar-thumb { background: var(--stroke); border-radius: 4px; }
/* Let vertical scroll stay native while horizontal drags feed the tab pager (JS);
   the wealth segment bar keeps its own horizontal scroll. */
.content { touch-action: pan-y; }
.seg-bar { touch-action: pan-x; }
/* ViewPager: a fixed overlay holds a two-pane track that follows the finger. */
.pager-track { display: flex; height: 100%; will-change: transform; }
.pager-track > .pager-pane { flex: 0 0 100%; width: 100%; height: 100%; }
.pager-overlay .pager-pane { -webkit-overflow-scrolling: touch; }
/* Isolate the drag surface: its transform/paint can't trigger layout or style recalc
   of the rest of the page, so the swipe stays cheap even with heavy tab content. */
.pager-overlay { contain: layout paint; }

.section-title { font-size: 13px; font-weight: 700; color: var(--muted); text-transform: uppercase; letter-spacing: 0.8px; margin: 4px 4px 12px; }
/* A section title that sits directly inside a grid list (e.g. "Active learning")
   must span every column, otherwise it takes the first cell and pushes the first
   item into column 2 (top-right instead of top-left). */
.full-col { grid-column: 1 / -1; }
/* Skill category headers: clear separation between groups, consistent with the
   spacing rhythm on the Earn tab. */
.cat-title { margin-top: 26px; }


/* ── Cards ─────────────────────────────────────────────────────────────────── */
.card {
    background: var(--surface); border: 1px solid var(--stroke);
    border-radius: var(--r-md); box-shadow: var(--shadow);
}

.list { display: flex; flex-direction: column; gap: 10px; }

.venture {
    display: flex; align-items: center; gap: 12px; padding: 12px;
    border-radius: var(--r-md); border: 1px solid var(--stroke);
    background: var(--surface); position: relative; overflow: hidden;
}
.venture::before { /* level progress glow along the left edge */
    content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 4px;
    background: linear-gradient(180deg, var(--neon), var(--gold)); opacity: 0.85;
}
.venture .badge {
    width: 52px; height: 52px; flex: none; border-radius: 14px; font-size: 26px;
    display: grid; place-items: center; background: var(--surface-2); border: 1px solid var(--stroke);
}
.venture .info { flex: 1; min-width: 0; }
.venture .vname { font-weight: 800; font-size: 15px; display: flex; align-items: center; gap: 8px; }
.venture .lvl { font-size: 12px; font-weight: 700; color: var(--muted); background: rgba(255,255,255,0.05); padding: 1px 8px; border-radius: 999px; white-space: nowrap; flex: none; }
.venture .vrps { font-size: 12.5px; color: var(--gold-soft); margin-top: 3px; }
.venture .vsub { font-size: 11.5px; color: var(--muted-2); margin-top: 1px; }

.buy-btn {
    flex: none; min-width: 104px; padding: 11px 12px; border: none; cursor: pointer;
    border-radius: var(--r-sm); font-weight: 800; font-size: 13px; color: #06251a;
    background: linear-gradient(135deg, var(--neon-soft), var(--neon));
    transition: transform 0.06s ease, filter 0.15s ease; text-align: center; line-height: 1.15;
}
.buy-btn .c-label { font-size: 10px; font-weight: 700; opacity: 0.65; display: block; }
.buy-btn:active { transform: scale(0.97); }
.buy-btn:disabled { background: rgba(255,255,255,0.06); color: var(--muted-2); cursor: not-allowed; }

.venture.locked { opacity: 0.55; filter: grayscale(0.6); transition: opacity .25s ease, filter .25s ease; }
.venture.locked .badge { color: var(--muted-2); }
/* A jump highlight must look IDENTICAL on a still-locked target as on an unlocked
   one. The locked dimming (opacity + grayscale) affects the whole element —
   including the highlight's border and glow — so it would wash the neon ring out.
   Force full opacity + full colour while the highlight plays; it eases back to the
   dimmed state when the highlight ends. */
.venture.locked.hl { opacity: 1; filter: none; }

/* buy-amount toggle */
.amount-toggle { display: inline-flex; background: var(--surface); border: 1px solid var(--stroke); border-radius: 999px; padding: 3px; gap: 3px; }
.amount-toggle button { border: none; background: transparent; color: var(--muted); font-weight: 800; font-size: 12.5px; padding: 6px 14px; border-radius: 999px; cursor: pointer; }
.amount-toggle button.active { background: var(--neon); color: #052018; }

.toolbar { display: flex; align-items: center; justify-content: space-between; margin-bottom: 12px; }

/* upgrade card */
.upgrade { display: flex; align-items: center; gap: 12px; padding: 12px; }
.upgrade .badge { width: 46px; height: 46px; flex: none; border-radius: 12px; font-size: 22px; display: grid; place-items: center; background: var(--surface-2); border: 1px solid var(--stroke); }
.upgrade .uname { font-weight: 800; font-size: 14.5px; }
.upgrade .udesc { font-size: 12px; color: var(--muted); margin-top: 2px; }

/* ── Generic buttons ───────────────────────────────────────────────────────── */
.btn { border: none; cursor: pointer; border-radius: var(--r-md); font-weight: 800; font-size: 15px; padding: 14px 18px; transition: transform 0.06s ease, filter 0.15s ease; }
.btn:active { transform: scale(0.98); }
.btn.primary { color: #06251a; background: linear-gradient(135deg, var(--neon-soft), var(--neon)); box-shadow: 0 12px 26px -14px rgba(55,242,163,0.8); }
.btn.gold { color: #2a1c00; background: linear-gradient(135deg, var(--gold-soft), var(--gold)); box-shadow: 0 12px 26px -14px rgba(255,210,63,0.8); }
.btn.ghost { background: var(--surface); color: var(--text); border: 1px solid var(--stroke); }
.btn.danger { background: rgba(255,93,108,0.12); color: var(--danger); border: 1px solid rgba(255,93,108,0.4); }
.btn.block { width: 100%; }
.btn:disabled { opacity: 0.5; cursor: not-allowed; }

.link { color: var(--neon-soft); font-weight: 700; cursor: pointer; background: none; border: none; font-size: 13.5px; }

/* ── Bottom navigation ─────────────────────────────────────────────────────── */
/* Floating bottom bar: a rounded capsule just above the home indicator. Deliberately
   NO backdrop-filter — a per-frame blur of the moving pager underneath was the swipe
   bottleneck on Android/Blink. Instead it carries a subtle, near-opaque solid tint so
   it reads cleanly over any content while scrolling, with nothing to toggle. */
.nav {
    position: absolute; left: 12px; right: 12px; bottom: var(--nav-gap);
    height: var(--nav-h);
    display: flex; align-items: stretch;
    border-radius: 30px; overflow: hidden; isolation: isolate;
    /* Subtle, near-opaque cool-dark tint — no blur needed to stay legible over content. */
    background: linear-gradient(180deg, rgba(30,38,56,0.94), rgba(16,22,34,0.94));
    border: none;
    /* outer drop shadow (float) + a bright top rim + an inner bottom shade so the
       body reads as a CONVEX slab, not a flat card. */
    box-shadow:
        0 18px 42px -14px rgba(0,0,0,0.60),
        0 3px 10px -5px rgba(0,0,0,0.50),
        inset 0 1px 0 rgba(255,255,255,0.18),
        inset 0 -12px 22px -16px rgba(0,0,0,0.55);
    z-index: 10;
}
/* Convex top gloss + a faint diagonal sheen: the light that pools on curved glass. */
.nav::before {
    content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none; z-index: 0;
    background:
        linear-gradient(180deg, rgba(255,255,255,0.16), rgba(255,255,255,0) 26%),
        radial-gradient(130% 92% at 50% -38%, rgba(255,255,255,0.13), transparent 62%),
        linear-gradient(118deg, rgba(255,255,255,0.10) 0%, rgba(255,255,255,0) 24%, rgba(255,255,255,0) 72%, rgba(255,255,255,0.05) 100%);
}
/* True specular rim — a gradient BORDER that hugs the capsule: brightest along the
   top edge, catching the light again faintly at the bottom, like a lens bezel. Done
   with a masked padding-box so it follows the rounded corners (works on iOS Safari,
   unlike SVG-filter backdrops which are Chrome-only). */
.nav::after {
    content: ""; position: absolute; inset: 0; border-radius: inherit; padding: 1.3px; pointer-events: none; z-index: 4;
    background: linear-gradient(158deg, rgba(255,255,255,0.78), rgba(255,255,255,0.12) 26%, rgba(255,255,255,0.04) 60%, rgba(255,255,255,0.32) 100%);
    -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    -webkit-mask-composite: xor;
    mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    mask-composite: exclude;
}
.nav-btn { flex: 1; border: none; background: transparent; color: var(--muted-2); cursor: pointer;
    /* iOS Safari draws a native rounded-rect bezel around <button> unless appearance is
       reset — that was the faint "square" showing around each nav icon in both themes. */
    -webkit-appearance: none; appearance: none; -webkit-tap-highlight-color: transparent;
    display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px; font-size: 11px; font-weight: 700; position: relative; z-index: 0; }
.nav-btn .ic { font-size: 22px; transition: transform 0.15s ease; }
.nav-btn.active { color: var(--neon-soft); }
/* No drop-shadow glow here: on a solid rectangular emoji it renders as a rectangular
   halo that reads as a "box" around the icon. The pill + scale + colored label already
   mark the active tab clearly. */
.nav-btn.active .ic { transform: translateY(-2px) scale(1.12); }
/* Shared translucent green glass pill that GLIDES between tabs (iOS-style). It sits
   behind the buttons; its position/width is set in JS and transitions smoothly. */
.nav-pill {
    position: absolute; top: 7px; bottom: 7px; left: 0; width: 0; z-index: 0;
    will-change: left, width, transform;
    border-radius: 21px; opacity: 0; pointer-events: none;
    /* A convex lozenge of green-tinted glass. NO backdrop-filter: its blur/brightness
       had to be toggled off mid-swipe (for GPU), which then popped visibly back on when
       the pill settled. The gradient + white top-highlight + border + glow carry the
       "bright active tab" look on their own — slightly lifted here to replace the boost
       the filter gave — so the pill looks IDENTICAL while moving and at rest (no pop),
       and costs nothing per frame. */
    background:
        linear-gradient(180deg, rgba(55,242,163,0.36), rgba(55,242,163,0.10)),
        radial-gradient(120% 82% at 50% -6%, rgba(255,255,255,0.30), transparent 60%);
    border: 1px solid rgba(120,255,205,0.48);
    box-shadow:
        inset 0 1px 0.5px rgba(255,255,255,0.60),
        inset 0 -6px 11px -7px rgba(0,0,0,0.28),
        0 7px 18px -7px rgba(55,242,163,0.55);
    /* Only opacity animates by default. The left/width GLIDE is opt-in via `.glide`,
       added ONLY for a real user tab-switch — so re-positioning on resize/rotation
       (where .glide is removed) snaps instantly and can never look like the active
       item slid across when returning from landscape. */
    transition: opacity 0.2s ease;
}
.nav-pill.glide { transition: left 0.42s cubic-bezier(0.34, 1.32, 0.5, 1), width 0.42s cubic-bezier(0.34, 1.32, 0.5, 1), opacity 0.2s ease; }
.nav-pill.on { opacity: 1; }
/* Liquid-glass "blob": as the pill hops to a new tab it briefly elongates then settles,
   like a drop of glass flowing sideways. Position rides on `left` (above); this keyframe
   owns `transform` so the two compose cleanly. transform-origin is set in JS toward the
   direction of travel so the stretch leads into the destination. */
.nav-pill.liquid { animation: navPillLiquid 0.4s cubic-bezier(0.34, 1.04, 0.4, 1); }
@keyframes navPillLiquid {
    0%   { transform: scaleX(1); }
    45%  { transform: scaleX(1.13); }
    75%  { transform: scaleX(0.98); }
    100% { transform: scaleX(1); }
}
@media (prefers-reduced-motion: reduce) { .nav-pill.liquid { animation: none; } }
.nav-btn { z-index: 1; } /* keep icon+label above the gliding pill */

/* ── Prestige panel ────────────────────────────────────────────────────────── */
.hero { text-align: center; padding: 26px 18px; border-radius: var(--r-lg); border: 1px solid var(--stroke-strong);
    background: radial-gradient(400px 200px at 50% -20%, rgba(255,210,63,0.18), transparent 70%), var(--surface); margin-bottom: 16px; }
.hero .big { font-size: 40px; font-weight: 900; background: linear-gradient(90deg, var(--gold-soft), var(--neon-soft)); -webkit-background-clip: text; background-clip: text; color: transparent; }
.hero .cap { color: var(--muted); font-size: 13px; margin-top: 4px; }

.kv { display: flex; justify-content: space-between; padding: 12px 14px; border-bottom: 1px solid var(--stroke); font-size: 14px; }
.kv:last-child { border-bottom: none; }
.kv .v { font-weight: 800; color: var(--neon-soft); }

/* ── Modals + toasts ───────────────────────────────────────────────────────── */
/* Safe-area aware padding so a centered modal (onboarding, daily reward, dialogs)
   never collides with the notch/Dynamic Island at the top or the home indicator at
   the bottom — this was why the onboarding heading sat right under the status bar. */
.modal-backdrop { position: fixed; inset: 0; background: rgba(4,7,13,0.7); backdrop-filter: blur(4px); display: grid; place-items: center; z-index: 100; padding: calc(var(--sat) + 18px) calc(var(--sar) + 18px) calc(var(--sab) + 18px) calc(var(--sal) + 18px); animation: fade 0.2s ease; }
@keyframes fade { from { opacity: 0; } to { opacity: 1; } }
/* Cap the height to the padded (safe) area so a tall modal can't overflow back into
   the notch/indicator instead of scrolling inside itself. */
.modal { width: 100%; max-width: 440px; background: linear-gradient(180deg, #131f34, #0d1526); border: 1px solid var(--stroke); border-radius: var(--r-lg); box-shadow: var(--shadow); padding: 22px; animation: rise 0.25s ease; max-height: calc(100dvh - var(--sat) - var(--sab) - 36px); overflow-y: auto; }
/* No dialog content may push past the viewport: wrap long words, never scroll
   sideways (guards every modal/sheet on narrow phones). */
.modal, .sheet { overflow-wrap: break-word; }
.modal, .sheet-body { overflow-x: hidden; }
@keyframes rise { from { transform: translateY(16px); opacity: 0; } to { transform: translateY(0); opacity: 1; } }
.modal h2 { margin: 0 0 4px; font-size: 20px; }
.modal .sub { color: var(--muted); font-size: 13.5px; margin-bottom: 16px; }
.field { margin-bottom: 12px; }
.field label { display: block; font-size: 12px; color: var(--muted); margin-bottom: 6px; font-weight: 700; }
.input { width: 100%; padding: 13px 14px; border-radius: var(--r-sm); border: 1px solid var(--stroke); background: rgba(6,10,18,0.7); color: var(--text); font-size: 15px; }
.input:focus { outline: none; border-color: var(--stroke-strong); box-shadow: 0 0 0 3px rgba(55,242,163,0.12); }
.pw-wrap { position: relative; display: flex; align-items: center; }
.pw-wrap .input { padding-right: 46px; }
.pw-toggle { position: absolute; top: 50%; transform: translateY(-50%); right: 6px; background: none; border: 0; cursor: pointer; font-size: 17px; line-height: 1; padding: 6px 8px; opacity: 0.65; border-radius: 8px; }
.pw-toggle:hover { opacity: 1; }
.form-error { color: var(--danger); font-size: 13px; margin: 4px 2px 10px; }
.form-info { color: var(--neon-soft); font-size: 13px; margin: 4px 2px 10px; }
.modal-actions { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 8px; }
.modal-actions .btn { flex: 1 1 40%; min-width: 0; }

.toast-wrap { position: fixed; left: 0; right: 0; bottom: calc(var(--nav-h) + var(--nav-gap) + 14px); display: flex; flex-direction: column; align-items: center; gap: 8px; z-index: 120; pointer-events: none; }
.toast { pointer-events: auto; background: #16233c; border: 1px solid var(--stroke-strong); color: var(--text); padding: 11px 16px; border-radius: 999px; font-size: 13.5px; font-weight: 700; box-shadow: var(--shadow); animation: rise 0.2s ease; }
.toast.good { border-color: var(--stroke-strong); }
.toast.bad { border-color: rgba(255,93,108,0.5); color: #ffd7db; }

.badge-pill { display: inline-flex; align-items: center; gap: 6px; padding: 5px 12px; border-radius: 999px; font-size: 12.5px; font-weight: 800; }
.badge-pill.demo { color: var(--gold-soft); background: rgba(255,210,63,0.1); border: 1px solid rgba(255,210,63,0.35); }
.badge-pill.pro { color: var(--neon-soft); background: rgba(55,242,163,0.1); border: 1px solid var(--stroke-strong); }

/* ── Paywall overlay ───────────────────────────────────────────────────────── */
/* z-index 90: above the game shell, below the modal-backdrop (100) so the login
   dialog opened from here renders ON TOP instead of behind. */
/* Login / paywall are FULL-SCREEN gates BEFORE the game — they must be fully
   opaque so the ambient sky and the game behind never bleed through (that faint
   "washed-out weather" look). No backdrop-filter here: there is nothing to see. */
.paywall, .landing { position: fixed; inset: 0; z-index: 90; background: #04070d; display: grid; place-items: center;
    padding: calc(var(--sat) + 20px) calc(var(--sar) + 20px) calc(var(--sab) + 20px) calc(var(--sal) + 20px); }
.paywall .box, .landing .box { max-width: 460px; width: 100%; text-align: center; background: linear-gradient(180deg, #14213a, #0c1220); border: 1px solid var(--stroke-strong); border-radius: var(--r-lg); padding: 30px 24px; box-shadow: var(--shadow); }
.paywall .lock { font-size: 46px; }
.paywall h2, .landing h2 { font-size: 24px; margin: 10px 0 6px; }
.paywall p, .landing p { color: var(--muted); font-size: 14.5px; line-height: 1.5; }
.paywall .actions, .landing .actions { display: flex; flex-direction: column; gap: 10px; margin-top: 20px; }

/* Landing / hero page (after logout, or for a returning logged-out device). */
.landing { background: radial-gradient(120% 90% at 80% -10%, #14213a, #04070d); overflow-y: auto;
    padding: calc(var(--sat) + 24px) calc(var(--sar) + 18px) calc(var(--sab) + 24px) calc(var(--sal) + 18px); place-items: center; }
.landing .l-theme { position: fixed; top: calc(var(--sat) + 16px); right: calc(var(--sar) + 16px); z-index: 2; }
.l-hero { display: grid; grid-template-columns: 1fr; gap: 22px; align-items: center; width: 100%; max-width: 1040px; margin: auto; }
.l-art { order: -1; display: flex; justify-content: center; }
/* Rounded card shape with a soft edge-fade so the crop blends into the page in
   BOTH themes. Generous border-radius rounds the corners; two gently intersected
   linear masks feather only the outer few percent so the rounding stays visible. */
.l-hero-img { width: 100%; max-width: 250px; border-radius: 34px;
    -webkit-mask-image: linear-gradient(to right, transparent 0, #000 7%, #000 93%, transparent 100%), linear-gradient(to bottom, transparent 0, #000 5%, #000 94%, transparent 100%);
    -webkit-mask-composite: source-in;
    mask-image: linear-gradient(to right, transparent 0, #000 7%, #000 93%, transparent 100%), linear-gradient(to bottom, transparent 0, #000 5%, #000 94%, transparent 100%);
    mask-composite: intersect;
    filter: drop-shadow(0 14px 30px rgba(0,0,0,0.45)) drop-shadow(0 0 44px rgba(55,242,163,0.12)); }
.l-copy { text-align: center; }
.l-brand { display: flex; align-items: center; justify-content: center; gap: 12px; }
.landing .l-logo-tile { width: 60px; height: 60px; border-radius: 16px; overflow: hidden; box-shadow: 0 14px 34px -16px rgba(0,0,0,0.6); }
.landing .l-logo { display: block; width: 100%; height: 100%; object-fit: cover; transform: scale(1.13); }
.landing .l-name { font-weight: 900; font-size: 30px; letter-spacing: 0.5px; background: linear-gradient(90deg, var(--neon-soft), var(--gold-soft)); -webkit-background-clip: text; background-clip: text; color: transparent; }
.l-headline { font-size: 26px; line-height: 1.2; font-weight: 900; margin: 16px 0 8px; color: var(--text); }
.l-sub { color: var(--muted); font-size: 14.5px; line-height: 1.55; max-width: 460px; margin: 0 auto; }
.l-chips { display: flex; flex-wrap: wrap; gap: 8px; justify-content: center; margin: 18px 0 22px; }
.l-chip { font-size: 12px; font-weight: 700; color: var(--text); background: rgba(255,255,255,0.05); border: 1px solid var(--stroke); border-radius: 999px; padding: 6px 12px; }
.l-actions { display: flex; flex-direction: column; gap: 10px; max-width: 380px; margin: 0 auto; }
.l-foot { text-align: center; margin: 26px auto 10px; font-size: 12.5px; color: var(--muted); display: flex; gap: 10px; justify-content: center; align-items: center; }
.l-foot a { color: var(--muted); text-decoration: underline; }
.l-foot a:hover { color: var(--text); }
.l-foot-sep { opacity: 0.5; }
@media (min-width: 900px) {
    .l-hero { grid-template-columns: 1.05fr 0.95fr; gap: 40px; }
    .l-art { order: 1; }
    .l-hero-img { max-width: 300px; }
    .l-copy { text-align: left; }
    .l-brand { justify-content: flex-start; }
    .l-sub, .l-actions { margin-left: 0; }
    .l-chips { justify-content: flex-start; }
    .l-headline { font-size: 34px; }
}
:root[data-theme="light"] .l-chip { background: rgba(20,40,80,0.05); }
:root[data-theme="light"] .paywall, :root[data-theme="light"] .landing { background: #e9eef7; }
:root[data-theme="light"] .landing { background: radial-gradient(120% 90% at 50% 0%, #eaf0f9, #dbe4f2); }
:root[data-theme="light"] .paywall .box, :root[data-theme="light"] .landing .box { background: linear-gradient(180deg, #ffffff, #f2f6fc); }

/* Company-value mini area chart (IPO & Press segment). */
.vchart-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; margin-bottom: 8px; }
.vchart-title { font-weight: 800; font-size: 13px; color: var(--muted); }
.vchart-cur { font-weight: 900; font-size: 20px; color: var(--neon); letter-spacing: -0.01em; }
.vchart-plot { position: relative; height: 150px; }
.vchart-svg { width: 100%; height: 150px; display: block; }
.vchart-grid { stroke: rgba(255,255,255,0.06); stroke-width: 1; vector-effect: non-scaling-stroke; }
.vchart-area { fill: url(#vcgrad); stroke: none; }
.vchart-line { stroke: var(--neon); stroke-width: 2.5; fill: none; vector-effect: non-scaling-stroke; stroke-linejoin: round; stroke-linecap: round; }
.vchart-dot { position: absolute; right: 0; width: 9px; height: 9px; border-radius: 50%; background: var(--neon); transform: translateY(-50%); box-shadow: 0 0 0 3px rgba(55,242,163,0.20), 0 0 10px rgba(55,242,163,0.75); }
.vchart-ymax, .vchart-ymin { position: absolute; left: 3px; font-size: 10.5px; font-weight: 700; color: var(--muted); pointer-events: none; background: rgba(4,7,13,0.55); padding: 1px 6px; border-radius: 6px; }
.vchart-ymax { top: 1px; } .vchart-ymin { bottom: 5px; }
.vchart-x { display: flex; justify-content: space-between; margin-top: 6px; font-size: 11px; color: var(--muted); font-weight: 600; }
:root[data-theme="light"] .vchart-grid { stroke: rgba(0,0,0,0.07); }
:root[data-theme="light"] .vchart-ymax, :root[data-theme="light"] .vchart-ymin { background: rgba(255,255,255,0.7); }

/* Generated share image preview (📤 Fortschritt teilen). */
.share-preview { display: block; width: 100%; max-width: 340px; margin: 0 auto; border-radius: 18px; box-shadow: var(--shadow); }

/* KEL — the game's character, shown in onboarding, the paywall and the profile. */
.kel-banner { display: block; width: 100%; max-width: 320px; border-radius: 16px; margin: 2px auto 16px; box-shadow: 0 20px 44px -22px rgba(0,0,0,0.7); }
.kel-avatar { display: block; width: 92px; height: 92px; border-radius: 50%; object-fit: cover; object-position: 50% 20%; margin: 0 auto; border: 2px solid var(--stroke-strong); box-shadow: 0 0 30px -8px var(--neon); }
.kel-celebrate { display: block; width: 200px; height: 200px; object-fit: cover; object-position: 50% 22%; margin: 0 auto 12px; border-radius: 26px; border: 2px solid var(--stroke-strong); box-shadow: 0 18px 40px -20px rgba(0,0,0,0.7), 0 0 34px -10px var(--neon); }
/* Framed KEL reaction portrait inside a modal body (surprised / sad / determined …). */
.kel-react { display: block; width: 128px; height: 128px; object-fit: cover; object-position: 50% 20%; margin: 2px auto 14px; border-radius: 22px; border: 2px solid var(--stroke-strong); box-shadow: 0 14px 32px -18px rgba(0,0,0,0.7), 0 0 26px -12px var(--neon); }
/* Toast carrying a small round KEL face. */
.toast-kel { display: flex; align-items: center; gap: 10px; }
.toast-face { width: 34px; height: 34px; border-radius: 50%; object-fit: cover; object-position: 50% 18%; flex: 0 0 auto; border: 1.5px solid var(--stroke-strong); }

/* ── Automation: company health, managers, policies ─────────────────────────── */
.health { margin: 2px 0 4px; }
.health-top { display: flex; justify-content: space-between; align-items: center; font-size: 12.5px; font-weight: 700; color: var(--muted); }
.health-val { font-weight: 900; }
.health-val.good, .health-bar > i.good { color: var(--neon-soft); }
.health-val.warn, .health-bar > i.warn { color: var(--gold-soft); }
.health-val.bad, .health-bar > i.bad { color: var(--danger); }
.health-bar { height: 9px; border-radius: 6px; background: rgba(255,255,255,0.08); overflow: hidden; margin-top: 6px; }
.health-bar > i { display: block; height: 100%; border-radius: 6px; transition: width 0.4s ease; background: currentColor; }
.manager { transition: border-color 0.2s ease; }
.manager.on { border-color: var(--stroke-strong); box-shadow: 0 0 22px -12px var(--neon), var(--shadow); }
.mgr-head { display: flex; align-items: center; gap: 12px; }
.mgr-ic { width: 42px; height: 42px; border-radius: 12px; display: grid; place-items: center; font-size: 22px; background: var(--surface-2); border: 1px solid var(--stroke); flex: 0 0 auto; }
.policy-row { display: flex; gap: 6px; margin-top: 10px; }
.policy { flex: 1; padding: 8px 6px; border-radius: 10px; font-size: 12px; font-weight: 700; cursor: pointer;
    color: var(--muted); background: rgba(255,255,255,0.04); border: 1px solid var(--stroke); transition: all 0.15s ease; }
.policy.on { color: #06251a; background: var(--neon); border-color: var(--neon); }

/* Side-hustle running footer: label + live remaining-time countdown. */
.sh-foot { display: flex; justify-content: space-between; align-items: center; margin-top: 6px; }
.sh-rem { font-weight: 800; color: var(--text); font-variant-numeric: tabular-nums; }
.cele-thr { text-align: center; font-size: 24px; font-weight: 900; color: var(--gold-soft); }
.cele-unlocks { margin-top: 12px; text-align: center; font-weight: 800; color: var(--neon-soft); font-size: 13px; background: rgba(55,242,163,0.08); border: 1px solid var(--stroke-strong); border-radius: 12px; padding: 10px 12px; }

/* Locked wealth feature: gradient lock badge + progress toward the unlock value. */
.feature-lock { text-align: center; padding: 34px 24px; display: flex; flex-direction: column; align-items: center; gap: 12px; }
.feature-lock .fl-badge { width: 76px; height: 76px; border-radius: 50%; display: grid; place-items: center; font-size: 34px; background: radial-gradient(circle at 50% 32%, rgba(55,242,163,0.20), rgba(255,255,255,0.02)); border: 1px solid var(--stroke-strong); box-shadow: 0 0 44px -12px var(--neon); }
.feature-lock .fl-title { font-weight: 900; font-size: 19px; }
.feature-lock .fl-blurb { font-size: 13px; max-width: 340px; line-height: 1.5; }
.feature-lock .fl-prog { width: 100%; max-width: 320px; height: 8px; border-radius: 999px; background: rgba(255,255,255,0.08); overflow: hidden; margin-top: 4px; }
.feature-lock .fl-prog i { display: block; height: 100%; border-radius: 999px; background: linear-gradient(90deg, var(--neon), var(--neon-soft)); box-shadow: 0 0 14px -3px var(--neon); transition: width 0.4s ease; }
.feature-lock .fl-meta { width: 100%; max-width: 320px; display: flex; justify-content: space-between; align-items: center; gap: 10px; }
.feature-lock .fl-pct { font-size: 12px; font-weight: 800; color: var(--gold-soft); }
:root[data-theme="light"] .feature-lock .fl-badge { background: radial-gradient(circle at 50% 32%, rgba(20,150,95,0.14), rgba(20,40,80,0.02)); }
:root[data-theme="light"] .feature-lock .fl-prog { background: rgba(20,40,80,0.10); }

/* profile rows */
.prow { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 14px; }
.prow + .prow { border-top: 1px solid var(--stroke); }
.prow .t { font-weight: 700; font-size: 14.5px; }
.prow .d { font-size: 12.5px; color: var(--muted); margin-top: 2px; }

.lb-row { display: flex; align-items: center; gap: 12px; padding: 11px 14px; border-bottom: 1px solid var(--stroke); }
.lb-row:last-child { border-bottom: none; }
.lb-rank { width: 28px; font-weight: 900; color: var(--gold-soft); text-align: center; }
.lb-name { flex: 1; font-weight: 700; font-size: 14px; }
.lb-val { color: var(--neon-soft); font-weight: 800; font-size: 13.5px; }

.center-col { display: flex; flex-direction: column; gap: 10px; }
.spacer { height: 8px; }
.muted { color: var(--muted); }
.tiny { font-size: 12px; }
.hidden { display: none !important; }

/* Splash */
#splash { position: fixed; inset: 0; display: grid; place-items: center; background: var(--bg-0); z-index: 500; transition: opacity 0.4s ease; }
#splash.gone { opacity: 0; pointer-events: none; }
#splash .s-logo { font-size: 60px; animation: bob 1.4s ease-in-out infinite; }
@keyframes bob { 0%,100% { transform: translateY(0); } 50% { transform: translateY(-10px); } }
#splash .s-name { margin-top: 14px; font-weight: 900; font-size: 22px; background: linear-gradient(90deg, var(--neon-soft), var(--gold-soft)); -webkit-background-clip: text; background-clip: text; color: transparent; }

@media (min-width: 640px) {
    /* Fill the full viewport height — no floating card, no wasted space, no page scroll. */
    .app { height: 100dvh; margin: 0 auto; }
}

/* ── Full-game additions ─────────────────────────────────────────────────────── */
.stat .val { font-size: 19px; }
.stat.cash .val, .stat.rps .val { font-size: 19px; }
/* Next-milestone card — lives inside the sky HUD as a 4th glass element, in the
   same dark-glass/light-text language as the KPI cards + phase pills so it stays
   readable on any sky (night/day/off) in both themes. */
.goal { position: relative; display: flex; align-items: center; gap: 11px; padding: 8px 13px; border-radius: 13px; overflow: hidden;
    background: rgba(12,17,30,0.66); border: 1px solid rgba(255,225,150,0.30); color: #f3f6fb;
    -webkit-backdrop-filter: blur(9px) saturate(1.12); backdrop-filter: blur(9px) saturate(1.12);
    box-shadow: 0 6px 16px -10px rgba(0,0,0,0.55), inset 0 1px 0 rgba(255,255,255,0.10); }
/* Once the very last milestone is reached there is no next goal — the card is emptied,
   so hide it entirely instead of leaving an empty bar. */
.sky:not(.has-goal) .goal { display: none; }
.goal .ring { position: relative; flex: none; width: 38px; height: 38px; border-radius: 50%; display: grid; place-items: center;
    background: conic-gradient(#ffd23f calc(var(--p,0)*1%), rgba(255,255,255,0.16) 0); }
.goal .ring::after { content: ""; position: absolute; inset: 3px; border-radius: 50%; background: #141b2b; }
.goal .ring span { position: relative; z-index: 1; font-size: 10.5px; font-weight: 900; letter-spacing: -0.4px; color: #ffe487; }
.goal .ring span i { font-style: normal; font-size: 0.55em; font-weight: 800; opacity: 0.8; margin-left: 0.3px; }
.goal-t { min-width: 0; flex: 1; }
.goal-k { font-size: 9.5px; text-transform: uppercase; letter-spacing: 0.6px; font-weight: 800; color: #ffdf9e; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.goal-n { font-size: 15px; font-weight: 800; color: #f3f6fb; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; text-shadow: 0 1px 2px rgba(0,0,0,0.5); margin-top: 1px; }
.goal-n .sub { font-weight: 600; color: #c6d2e4; }
.goal-track { position: absolute; left: 0; bottom: 0; height: 3px; width: 100%; background: rgba(255,255,255,0.09); }
.goal-track i { display: block; height: 100%; background: linear-gradient(90deg, #ffd23f, #ffe487); box-shadow: 0 0 8px rgba(255,210,63,0.6); }
.goal.clickable { cursor: pointer; -webkit-tap-highlight-color: transparent; }
.goal.clickable > * { pointer-events: none; }
.goal.clickable:hover { filter: brightness(1.08); }
.goal.clickable:active { filter: brightness(0.96); }

.cat-head { font-size: 11px; font-weight: 800; letter-spacing: 0.6px; text-transform: uppercase; color: var(--muted-2); margin: 12px 4px 2px; }
.badge.sm { width: 42px; height: 42px; font-size: 21px; border-radius: 12px; }
.venture.skill .badge.sm { width: 38px; height: 38px; font-size: 18px; }

.btn-col { display: flex; flex-direction: column; gap: 5px; align-items: stretch; }
.btn-col2 { display: flex; flex-direction: column; gap: 4px; }
.mini-btn { border: 1px solid var(--stroke); background: var(--surface); color: var(--text); border-radius: 9px; font-weight: 800; font-size: 12px; padding: 7px 10px; cursor: pointer; min-width: 44px; }
.mini-btn.buy { background: linear-gradient(135deg, var(--neon-soft), var(--neon)); color: #06251a; border: none; }
.mini-btn:active { transform: scale(0.96); }
/* Can't afford it → the button must LOOK inactive, not stay green. Mirrors
   .buy-btn:disabled; the green .mini-btn.buy needs an explicit override or its
   gradient would persist (that made unaffordable +1/+10 buttons look buyable). */
.mini-btn:disabled, .mini-btn.buy:disabled { background: rgba(255,255,255,0.06); color: var(--muted-2); border: 1px solid transparent; cursor: not-allowed; transform: none; }

.dots { display: inline-flex; gap: 3px; margin-left: 6px; vertical-align: middle; }
/* Inside a venture/skill row the name takes the flexible space and the level
   indicator (dots or the "Lv N" pill) is pinned to a fixed right-hand column, so
   it never jumps around with each name's length or floats beside a 2-line name. */
.venture .vname .vn { flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere; }
.venture .vname .dots, .venture .vname .lvl { flex: none; margin-left: 8px; }
.dots i { width: 7px; height: 7px; border-radius: 50%; background: rgba(255,255,255,0.14); }
.dots i.on { background: var(--neon); }
.lock-tag { font-size: 11px; color: var(--gold-soft); font-weight: 700; }

.progress { height: 7px; border-radius: 4px; background: rgba(255,255,255,0.08); overflow: hidden; margin-top: 6px; }
.progress > i { display: block; height: 100%; background: linear-gradient(90deg, var(--neon), var(--neon-soft)); border-radius: 4px; transition: width 0.4s linear; }
.learn-row { display: flex; align-items: center; gap: 10px; padding: 10px 12px; border-radius: var(--r-md); border: 1px solid var(--stroke); background: var(--surface); }

.side-hustle { padding: 14px; margin-bottom: 14px; }
.sh-title { font-weight: 800; font-size: 14px; margin-bottom: 10px; }
.gig-row { display: flex; gap: 8px; }
.gig { flex: 1; background: var(--surface-2); border: 1px solid var(--stroke); border-radius: 12px; padding: 10px 6px; cursor: pointer; display: flex; flex-direction: column; align-items: center; gap: 3px; color: var(--text); }
.gig:active { transform: scale(0.97); }

/* The segment menu (Apps · Aktien · … · Prestige) is NOT floating/sticky. It is a
   fixed HEADER that sits ABOVE the scroll area: `.content.has-seghead` becomes a
   non-scrolling flex column, the menu is a flex:none header, and the cards live in the
   .seg-scroll box below — which is the only thing that scrolls. So the menu simply sits
   over the scrollable region and the content scrolls under it, no panel, no float. */
.content.has-seghead {
    overflow: hidden;                 /* the inner .seg-scroll scrolls, not .content */
    display: flex; flex-direction: column; min-height: 0;
    padding: 0;                       /* the header and the scroll box carry their own */
}
.seg-scroll {
    flex: 1 1 auto; min-height: 0;
    overflow-y: auto; -webkit-overflow-scrolling: touch;
    padding: 8px var(--cpx, 14px) var(--cpb, 24px);
    scrollbar-width: thin; scrollbar-color: var(--stroke) transparent;
}
.seg-scroll::-webkit-scrollbar { width: 7px; }
.seg-scroll::-webkit-scrollbar-thumb { background: var(--stroke); border-radius: 4px; }
.seg-bar {
    display: flex; gap: 4px; overflow-x: auto; scrollbar-width: none;
    flex: 0 0 auto;                   /* fixed header row — never scrolls, never floats */
    padding: var(--cpt, 16px) var(--cpx, 14px) 10px;
}
.seg-bar::-webkit-scrollbar { display: none; }
.seg { flex: none; border: 1px solid var(--stroke); background: var(--surface); color: var(--muted); font-weight: 800; font-size: 12.5px; padding: 8px 14px; border-radius: 999px; cursor: pointer; white-space: nowrap; }
.seg.active { background: var(--neon); color: #052018; border-color: transparent; box-shadow: 0 6px 16px -10px var(--neon); }

.kv-card { margin-bottom: 12px; }
/* Opportunity countdown: a slim bar that drains over the offer's TTL and turns
   red in the final quarter, then the dialog auto-closes when it hits zero. */
.opp-timer { height: 5px; border-radius: 999px; background: rgba(255,255,255,0.10); overflow: hidden; margin: 4px 2px 14px; }
.opp-timer i { display: block; height: 100%; width: 100%; border-radius: inherit; background: linear-gradient(90deg, #37f2a3, #ffd23f); transition: width 0.12s linear, background 0.3s ease; }
.opp-timer i.low { background: linear-gradient(90deg, #ff9f4b, #ff5d6c); }
.event-row { display: flex; align-items: center; gap: 10px; padding: 9px 12px; border-radius: 12px; border: 1px solid var(--stroke); background: var(--surface); }
.event-row .ev-ic { font-size: 17px; line-height: 1; flex: 0 0 auto; }
.event-row .ev-txt { flex: 1; min-width: 0; }
.event-row .ev-title { font-size: 13px; font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.event-row .ev-desc { font-size: 11.5px; color: var(--muted); margin-top: 1px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.event-row .ev-meta { flex: 0 0 auto; font-weight: 700; white-space: nowrap; }

.prow-list { overflow: hidden; }
.prow.go { cursor: pointer; }
.prow.go:active { background: rgba(255,255,255,0.03); }
/* whole-row-clickable settings rows (Firmenname, Sprache, Design …) */
.prow.tap { cursor: pointer; transition: background .12s ease; }
.prow.tap:hover { background: rgba(255,255,255,0.04); }
:root[data-theme="light"] .prow.tap:hover { background: rgba(20,40,80,0.04); }
.prow.tap:active { background: rgba(255,255,255,0.06); }
.chev { color: var(--muted-2); font-size: 20px; font-weight: 400; }
/* Accordion caret: points down, flips up when its panel is open. */
.chev.caret { font-size: 22px; line-height: 1; transition: transform 0.2s ease; }
.help-head.open .chev.caret { transform: rotate(180deg); }

/* minmax(0,1fr) lets the columns shrink below their content's min-content so a
   long unbreakable word can never push the grid past the sheet width. */
.ach-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
.ach { background: var(--surface); border: 1px solid var(--stroke); border-radius: 14px; padding: 12px 8px; text-align: center; opacity: 0.5; }
.ach.got { opacity: 1; }
.ach.got.common { border-color: rgba(150,170,200,0.5); }
.ach.got.rare { border-color: rgba(90,170,255,0.6); box-shadow: 0 0 16px -6px rgba(90,170,255,0.5); }
.ach.got.epic { border-color: rgba(190,120,255,0.6); box-shadow: 0 0 16px -6px rgba(190,120,255,0.5); }
.ach.got.legendary { border-color: var(--gold); box-shadow: 0 0 18px -5px rgba(255,210,63,0.6); }
.ach-ic { font-size: 26px; }
.ach-nm { font-size: 10.5px; font-weight: 700; margin-top: 5px; line-height: 1.2; overflow-wrap: anywhere; }
.ach-r { font-size: 10px; color: var(--muted); font-weight: 700; margin-top: 3px; letter-spacing: 0.3px; }
.ach-date { font-size: 9px; color: var(--neon-soft); margin-top: 3px; font-weight: 700; }
.ach-desc { font-size: 9px; color: var(--muted); margin-top: 3px; line-height: 1.25; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; overflow-wrap: anywhere; }
.progress.sm { height: 5px; margin-top: 6px; }
/* Profile stats grid */
.stat-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; margin-bottom: 14px; }
.stat-card { background: var(--surface); border: 1px solid var(--stroke); border-radius: 14px; padding: 14px 10px; text-align: center; }
.stat-card .sc-ic { font-size: 22px; }
.stat-card .sc-val { font-weight: 900; font-size: 16px; margin-top: 4px; }
.stat-card .sc-lbl { font-size: 10px; color: var(--muted); margin-top: 3px; text-transform: uppercase; letter-spacing: 0.4px; }
/* clickable stat tiles — either navigate to a screen or open an info dialog */
.stat-card.tap { cursor: pointer; position: relative; transition: transform .12s ease, border-color .15s ease, box-shadow .15s ease; }
.stat-card.tap:hover { transform: translateY(-1px); border-color: var(--stroke-strong); box-shadow: 0 6px 16px -12px rgba(0,0,0,0.45); }
:root[data-theme="light"] .stat-card.tap:hover { box-shadow: 0 6px 14px -12px rgba(20,40,80,0.28); }
.stat-card.tap:active { transform: translateY(0); }
.stat-card .sc-go { position: absolute; top: 7px; right: 9px; font-size: 15px; font-weight: 800; line-height: 1; color: var(--muted); opacity: .45; }
.stat-card.tap:hover .sc-go { opacity: .8; }
@media (min-width: 980px) { .stat-grid { grid-template-columns: repeat(3, 1fr); } }

.ms { padding: 14px; opacity: 0.6; }
.ms.reached { opacity: 1; border-color: var(--stroke-strong); }
.ms-h { display: flex; align-items: center; gap: 8px; font-weight: 800; font-size: 14px; }
.ms-date { margin-left: auto; font-size: 11px; color: var(--neon-soft); font-weight: 700; white-space: nowrap; }
.ms-ic { color: var(--neon-soft); }
.ms-thr { color: var(--gold-soft); font-weight: 800; font-size: 13px; margin: 4px 0; }
.ms-f { font-size: 12px; color: var(--neon-soft); margin-bottom: 4px; }
.ms-why { line-height: 1.4; }

.help { overflow: hidden; }
.help-head { display: flex; align-items: center; justify-content: space-between; padding: 14px; font-weight: 700; font-size: 14px; cursor: pointer; }
.help-body { padding: 0 14px 14px; color: var(--muted); font-size: 13px; line-height: 1.55; }
.pre { white-space: pre-wrap; line-height: 1.55; }
.hintbox { margin-top: 14px; padding: 12px; border-radius: var(--r-sm); background: rgba(55,242,163,0.08); border: 1px solid var(--stroke-strong); color: var(--neon-soft); font-size: 13px; }

.sheet-bd { align-items: flex-end; padding: 0; }
.sheet { width: 100%; max-width: var(--max-w); margin: 0 auto; background: linear-gradient(180deg, #101a2e, #0a1120); border-top-left-radius: 24px; border-top-right-radius: 24px; max-height: 90dvh; display: flex; flex-direction: column; animation: rise 0.28s ease; border: 1px solid var(--stroke); }
.sheet-head { display: flex; align-items: center; justify-content: space-between; padding: 18px 18px 12px; border-bottom: 1px solid var(--stroke); }
.sheet-head h2 { margin: 0; font-size: 18px; }
.sheet-x { background: var(--surface); border: 1px solid var(--stroke); color: var(--text); width: 34px; height: 34px; border-radius: 50%; font-size: 15px; cursor: pointer; }
.sheet-body { overflow-y: auto; padding: 16px; padding-bottom: calc(var(--sab) + 24px); }

/* ── Social dashboard (friends, requests, mailbox, chat) ─────────────────────── */
.social-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 12px; }
.soc-tiles { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
.soc-tile { display: flex; flex-direction: column; align-items: center; gap: 3px; padding: 13px 6px 11px; border-radius: 16px;
    background: var(--surface-2); border: 1px solid var(--stroke); color: var(--text); cursor: pointer; transition: transform .12s ease, border-color .15s ease; }
.soc-tile:active { transform: scale(0.97); }
.soc-tile.has { border-color: var(--stroke-strong); }
.soc-tile .soc-ic { font-size: 22px; line-height: 1; margin-bottom: 2px; }
.soc-tile .soc-n { font-size: 19px; font-weight: 900; color: var(--muted-2); line-height: 1; }
.soc-tile .soc-n.friends { color: var(--neon-soft); }
.soc-tile .soc-n.warn { color: var(--gold-soft); }
.soc-tile .soc-n.hot { color: #ff6a86; }
.soc-tile .soc-lbl { font-size: 11.5px; font-weight: 700; color: var(--muted); }
.soc-badge { min-width: 18px; height: 18px; padding: 0 5px; border-radius: 9px;
    background: var(--neon); color: #04120b; font-size: 11px; font-weight: 800; display: inline-flex; align-items: center; justify-content: center; box-shadow: 0 2px 6px -2px rgba(0,0,0,0.5); }
.soc-badge.warn { background: #ffcf3f; color: #3a2a00; }
.soc-badge.hot { background: #ff5a7a; color: #fff; }

/* Bottom-nav notification badge (unread DMs + friend requests) on the Profile tab. */
.nav-btn .ic { position: relative; }
.nav-badge { position: absolute; top: -5px; right: -12px; min-width: 17px; height: 17px; padding: 0 4px; border-radius: 9px;
    background: #ff4d6d; color: #fff; font-size: 10.5px; font-weight: 800; line-height: 17px; text-align: center;
    box-shadow: 0 2px 7px -1px rgba(255,77,109,0.7), 0 0 0 2px rgba(10,17,32,0.9); pointer-events: none; }
:root[data-theme="light"] .nav-badge { box-shadow: 0 2px 7px -1px rgba(255,77,109,0.6), 0 0 0 2px rgba(255,255,255,0.95); }

.soc-seg { display: flex; gap: 6px; margin-bottom: 14px; }
.soc-seg-b { flex: 1; padding: 9px 6px; border-radius: 12px; border: 1px solid var(--stroke); background: var(--surface-2);
    color: var(--muted); font-size: 12.5px; font-weight: 700; cursor: pointer; white-space: nowrap; }
.soc-seg-b.on { color: var(--neon-soft); background: linear-gradient(180deg, rgba(55,242,163,0.16), rgba(55,242,163,0.04)); border-color: rgba(55,242,163,0.32); }

.soc-add { display: flex; gap: 8px; margin-bottom: 14px; }
.soc-add .input { flex: 1; }
.soc-list { display: flex; flex-direction: column; gap: 8px; }
.soc-row { display: flex; align-items: center; gap: 11px; padding: 10px 12px; border-radius: 14px; background: var(--surface-2); border: 1px solid var(--stroke); }
.soc-row.soc-clickable { cursor: pointer; }
.soc-row.soc-clickable:active { transform: scale(0.99); }
.soc-av { position: relative; width: 40px; height: 40px; flex: 0 0 40px; }
.soc-av-i { width: 40px; height: 40px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-weight: 900; font-size: 17px;
    color: #04120b; background: linear-gradient(150deg, var(--neon), #24c15f); }
.soc-dot { position: absolute; right: -1px; bottom: -1px; width: 12px; height: 12px; border-radius: 50%; background: #64748b; border: 2px solid #0a1120; z-index: 1; }
.soc-dot.on { background: var(--neon); box-shadow: 0 0 7px rgba(55,242,163,0.8); }
.soc-main { flex: 1; min-width: 0; }
.soc-name { font-weight: 800; font-size: 14.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.soc-status { font-size: 12.5px; color: var(--gold-soft); margin: 1px 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.soc-actions { display: flex; align-items: center; gap: 6px; flex: 0 0 auto; }
.soc-empty { text-align: center; color: var(--muted); padding: 30px 16px; font-size: 14px; }
.soc-chips { display: flex; flex-wrap: wrap; gap: 7px; margin-top: 10px; }
.soc-chip { padding: 7px 12px; border-radius: 999px; border: 1px solid var(--stroke); background: var(--surface-2); color: var(--text); font-size: 13px; cursor: pointer; }

/* Network as a profile row (extracted from the old card-in-card) */
.prow.prow-2 { align-items: center; }
.prow-tt { min-width: 0; }
.prow-sub { font-size: 12px; color: var(--muted); margin-top: 2px; }
.prow-right { display: flex; align-items: center; gap: 8px; flex: 0 0 auto; }
.prow-badge { min-width: 20px; height: 20px; padding: 0 6px; border-radius: 10px; background: #ff4d6d; color: #fff;
    font-size: 12px; font-weight: 800; display: inline-flex; align-items: center; justify-content: center; }

/* Chat thread */
.chat-report { margin-left: 8px; background: none; border: none; color: var(--muted); font-size: 11px; font-weight: 700; cursor: pointer; padding: 0; opacity: 0.75; }
.chat-report:hover { opacity: 1; color: #ff6a86; }
.chat-body { display: flex; flex-direction: column; gap: 8px; padding: 4px 2px; max-height: 56dvh; overflow-y: auto; }
.chat-msg { display: flex; flex-direction: column; align-items: flex-start; max-width: 82%; }
.chat-msg.mine { align-self: flex-end; align-items: flex-end; }
.chat-bubble { padding: 9px 13px; border-radius: 16px; font-size: 14px; line-height: 1.35; word-break: break-word;
    background: var(--surface-2); border: 1px solid var(--stroke); border-bottom-left-radius: 5px; }
.chat-msg.mine .chat-bubble { color: #04120b; background: linear-gradient(160deg, var(--neon), #24c15f); border: none; border-bottom-left-radius: 16px; border-bottom-right-radius: 5px; }
.chat-time { font-size: 10.5px; color: var(--muted); margin: 2px 6px 0; }
.chat-composer { display: flex; gap: 8px; padding-top: 12px; margin-top: 8px; border-top: 1px solid var(--stroke); }
.chat-composer .input { flex: 1; }
.chat-send { padding: 0 16px; font-size: 17px; }

:root[data-theme="light"] .soc-dot { border-color: #fff; }
:root[data-theme="light"] .soc-av-i, :root[data-theme="light"] .chat-msg.mine .chat-bubble { color: #fff; }

.gig-list { display: flex; flex-direction: column; gap: 8px; }
.gig-wide { display: flex; align-items: center; gap: 10px; background: var(--surface-2); border: 1px solid var(--stroke); border-radius: 12px; padding: 11px 14px; cursor: pointer; color: var(--text); }
.gig-wide:active { transform: scale(0.99); }

/* ══════════════════════════════════════════════════════════════════════════════
   Premium pass v2 — real logo, richer palette, desktop wide layout, hover polish
   ══════════════════════════════════════════════════════════════════════════════ */

/* logo image (replaces emoji) */
/* The logo PNG bakes in its own rounded tile + transparent padding, so a box-shadow
   would frame the padded box (a pale halo). A drop-shadow follows the tile's alpha. */
.brand .logo-img { width: 34px; height: 34px; filter: drop-shadow(0 2px 5px rgba(0,0,0,0.35)) drop-shadow(0 0 9px rgba(55,242,163,0.28)); }
.brand .name { font-size: 18px; letter-spacing: 0.3px; }
#splash .s-logo-tile { width: 104px; height: 104px; border-radius: 26px; overflow: hidden; margin: 0 auto; box-shadow: 0 0 60px -8px var(--neon); animation: bob 1.6s ease-in-out infinite; }
#splash .s-logo-img { display: block; width: 100%; height: 100%; object-fit: cover; transform: scale(1.13); }

/* richer ambient backdrop + subtle vignette. Top glows only — the bottom stays a flat
   dark so the iOS safe-area strip (which can show through under a clipped fixed layer)
   matches the app bottom and never reads as a seam. */
body {
    background:
        radial-gradient(1200px 760px at 12% -12%, rgba(55, 242, 163, 0.16), transparent 60%),
        radial-gradient(1000px 720px at 112% 6%, rgba(255, 210, 63, 0.12), transparent 55%),
        #04070d;
    background-attachment: fixed;
}

/* KPI cards: the icon tile + coloured left accent rail come from the base .stat
   rules; here we only give the company-value figure a subtle gradient sheen.
   (Earlier this block re-declared .stat and .stat::before and quietly overrode the
   redesign — don't reintroduce a full-width top seam here, it kills the rail.) */
.stat.cv .val { background: linear-gradient(90deg, var(--text), var(--neon-soft)); -webkit-background-clip: text; background-clip: text; color: transparent; }

/* cards a touch deeper + rounded, with soft depth */
.card, .venture, .learn-row, .event-row, .gig-wide, .gig { box-shadow: 0 12px 30px -20px rgba(0,0,0,0.8); }

/* buttons: crisper gradients + glow */
.buy-btn { box-shadow: 0 8px 18px -12px rgba(55,242,163,0.7); }
.btn.gold, .seg.active, .amount-toggle button.active { box-shadow: 0 10px 22px -13px rgba(255,210,63,0.7); }

/* nicer scrollbar-less section rhythm */
.section-title { color: var(--muted); }

/* ── DESKTOP: use the full width — left rail + multi-column content ─────────── */
@media (min-width: 980px) {
    body { align-items: flex-start; }
    .app {
        max-width: 1340px;
        height: 100dvh;
        margin: 0 auto;
        display: grid;
        grid-template-columns: 252px 1fr;
        grid-template-rows: auto 1fr;
        overflow: hidden;
        border-left: 1px solid var(--stroke);
        border-right: 1px solid var(--stroke);
    }
    .topbar { grid-column: 1 / -1; grid-row: 1; padding: 20px 26px 16px; }
    .brand { font-size: 20px; }
    .brand .logo-img { width: 40px; height: 40px; }
    .brand .name { font-size: 22px; }
    .stats { gap: 14px; }
    .stat { padding: 14px 18px; }
    .stat .val { font-size: 22px; }
    .stat.cash .val, .stat.rps .val { font-size: 22px; }

    .nav {
        grid-column: 1; grid-row: 2;
        position: static; height: auto; width: auto;
        flex-direction: column; align-items: stretch; justify-content: flex-start;
        padding: 18px 14px; gap: 6px;
        border-radius: 0; overflow: visible; box-shadow: none;
        border: none; border-right: 1px solid var(--stroke);
        background: linear-gradient(180deg, rgba(12,19,33,0.55), rgba(8,12,20,0.15));
        backdrop-filter: none; -webkit-backdrop-filter: none;
    }
    .nav::before, .nav::after { display: none; } /* no floating-capsule glass on the rail */
    .nav-pill { display: none; } /* sidebar uses its own active-row background below */
    .nav-btn { flex: none; flex-direction: row; justify-content: flex-start; gap: 14px; padding: 14px 16px; border-radius: 14px; font-size: 15px; font-weight: 700; color: var(--muted); }
    .nav-btn:hover { background: rgba(255,255,255,0.04); color: var(--text); }
    .nav-btn .ic { font-size: 22px; }
    .nav-btn.active { background: linear-gradient(90deg, rgba(55,242,163,0.16), rgba(255,210,63,0.04)); color: var(--neon-soft); }
    .nav-btn.active::after { content: ""; top: auto; left: 5px; width: 3.5px; height: 24px; border-radius: 3px; }

    .content { grid-column: 2; grid-row: 2; --cpt: 22px; --cpx: 28px; --cpb: 30px; }
    .content .list { display: grid; grid-template-columns: repeat(auto-fill, minmax(370px, 1fr)); gap: 12px; align-content: start; }
    .content .list > .cat-head { grid-column: 1 / -1; }
    .side-hustle, .toolbar, .seg-bar, .hero { max-width: 1000px; }
    .gig-list { max-width: 1000px; }

    /* hover affordances */
    .venture, .card.upgrade, .gig-wide, .prow.go, .help-head, .ach.got, .seg { transition: transform .12s ease, border-color .15s ease, box-shadow .15s ease, filter .15s ease; }
    .venture:hover, .gig-wide:hover, .prow.go:hover, .ach.got:hover { transform: translateY(-1px); border-color: var(--stroke-strong); box-shadow: 0 6px 16px -12px rgba(0,0,0,0.45); }
    :root[data-theme="light"] .venture:hover, :root[data-theme="light"] .gig-wide:hover, :root[data-theme="light"] .prow.go:hover, :root[data-theme="light"] .ach.got:hover { box-shadow: 0 6px 14px -12px rgba(20,40,80,0.28); }
    .buy-btn:hover:not(:disabled), .btn:hover:not(:disabled), .mini-btn:hover:not(:disabled) { filter: brightness(1.07); }

    /* sheets become a large centered modal */
    .sheet-bd { align-items: center; padding: 26px; }
    .sheet { max-width: 920px; border-radius: 24px; max-height: 86dvh; }
    .ach-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

@media (min-width: 1280px) {
    .content .list { grid-template-columns: repeat(auto-fill, minmax(400px, 1fr)); }
    .ach-grid { grid-template-columns: repeat(5, minmax(0, 1fr)); }
}

/* Phone in LANDSCAPE (wide but short): give the scarce vertical height back to the
   content and use the horizontal space. The nav moves to a compact LEFT rail (like
   the desktop sidebar) instead of eating height at the bottom; the already-collapsed
   sky sits as a slim strip across the top; the content fills the rest and lays its
   lists out in two columns. Placed after the base rules so it wins the cascade;
   scoped below 980px so the real desktop layout is untouched. */
@media (max-height: 560px) and (min-width: 640px) and (max-width: 979px) {
    body { align-items: flex-start; }
    .app {
        max-width: none; height: 100dvh; margin: 0;
        display: grid; grid-template-columns: 84px 1fr; grid-template-rows: auto 1fr;
        overflow: hidden;
        /* Landscape: the notch/Dynamic Island sits on one SIDE — keep the whole app
           (esp. the left nav rail) clear of it; the body gradient fills behind. */
        padding-left: var(--sal); padding-right: var(--sar);
    }
    /* Nav is a FULL-HEIGHT left rail (top→bottom); the sky/topbar sits only in the
       right column so it stays a slim strip and the content gets the height. */
    .topbar { grid-column: 2; grid-row: 1; }
    .nav {
        grid-column: 1; grid-row: 1 / -1;
        position: static; inset: auto; height: auto; width: auto;
        flex-direction: column; align-items: stretch; justify-content: flex-start;
        gap: 6px; padding: 10px 8px calc(10px + var(--sab));
        border-radius: 0; overflow-y: auto; box-shadow: none;
        border: none; border-right: 1px solid rgba(255,255,255,0.10);
        background: linear-gradient(180deg, rgba(20,28,44,0.5), rgba(12,18,30,0.25));
        -webkit-backdrop-filter: blur(20px) saturate(1.6); backdrop-filter: blur(20px) saturate(1.6);
    }
    .nav::before, .nav::after { display: none; } /* no floating-capsule glass on the rail */
    .nav-pill { display: none; } /* no gliding pill in the rail */
    .nav-btn { flex: none; flex-direction: column; gap: 3px; padding: 10px 4px; border-radius: 14px; font-size: 10px; z-index: 0; }
    .nav-btn .ic { font-size: 20px; }
    .nav-btn.active { color: var(--neon-soft); background: linear-gradient(180deg, rgba(55,242,163,0.20), rgba(55,242,163,0.05)); border: 1px solid rgba(55,242,163,0.30); }
    .content { grid-column: 2; grid-row: 2; overflow-y: auto; --cpt: 12px; --cpx: 16px; --cpb: calc(16px + var(--sab)); }
    .content .list { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 10px; align-content: start; }
    .content .list > .cat-head { grid-column: 1 / -1; }
}

/* ══════════════════════════════════════════════════════════════════════════════
   UX pass v3 — disabled buttons, spinner, requires-link + jump highlight,
   theme toggle, and a full light theme.
   ══════════════════════════════════════════════════════════════════════════════ */

/* disabled buttons must not keep their colored glow (looked "weird") */
.buy-btn:disabled, .btn:disabled, .mini-btn:disabled { box-shadow: none !important; filter: none; }

/* inline loading spinner (inherits button text color) */
.spin { display: inline-block; width: 16px; height: 16px; border: 2px solid rgba(127,127,127,0.35); border-top-color: currentColor; border-radius: 50%; animation: spin 0.6s linear infinite; vertical-align: middle; }
@keyframes spin { to { transform: rotate(360deg); } }

/* clickable "Requires: <skill>" links */
.req-link { color: var(--neon-soft); font-weight: 700; text-decoration: underline; text-underline-offset: 2px; cursor: pointer; }
.req-link:hover { color: var(--neon); }

/* jump-to-skill/asset highlight — a subtle brand-colored ring that fades
   (professional), exactly as in the original game. No background wash, so text
   stays readable; a per-theme keyframe keeps the ring colour correct on both the
   dark and the light surface. */
.venture.hl { animation: hlpulse 2.2s ease; position: relative; z-index: 2; }
@keyframes hlpulse {
    0%   { box-shadow: 0 0 0 0 rgba(55,242,163,0); border-color: var(--stroke); }
    12%  { box-shadow: 0 0 0 3px rgba(55,242,163,0.95), 0 0 36px -2px rgba(55,242,163,0.75); border-color: rgba(55,242,163,1); }
    72%  { box-shadow: 0 0 0 3px rgba(55,242,163,0.80), 0 0 30px -3px rgba(55,242,163,0.60); border-color: rgba(55,242,163,0.92); }
    100% { box-shadow: 0 0 0 0 rgba(55,242,163,0); border-color: var(--stroke); }
}
:root[data-theme="light"] .venture.hl { animation: hlpulse-light 2.2s ease; }
@keyframes hlpulse-light {
    0%   { box-shadow: 0 0 0 0 rgba(16,168,108,0); border-color: var(--stroke); }
    12%  { box-shadow: 0 0 0 3px rgba(16,168,108,0.92), 0 0 30px -2px rgba(16,168,108,0.6); border-color: rgba(16,168,108,1); }
    72%  { box-shadow: 0 0 0 3px rgba(16,168,108,0.74), 0 0 24px -3px rgba(16,168,108,0.46); border-color: rgba(16,168,108,0.9); }
    100% { box-shadow: 0 0 0 0 rgba(16,168,108,0); border-color: var(--stroke); }
}

/* theme toggle button (top-right, like the desktop app's sun/moon) */
.top-actions { display: flex; align-items: center; gap: 8px; }
.icon-btn { width: 38px; height: 38px; flex: none; border-radius: 12px; border: 1px solid var(--stroke); background: var(--surface); color: var(--text); font-size: 17px; cursor: pointer; display: grid; place-items: center; transition: filter .15s ease, border-color .15s ease, transform .06s ease; }
.icon-btn:hover { border-color: var(--stroke-strong); filter: brightness(1.08); }
.icon-btn:active { transform: scale(0.94); }

/* ── LIGHT THEME ─────────────────────────────────────────────────────────────── */
:root[data-theme="light"] {
    --bg-0: #e9edf5;
    --seg-bg: #fbfcff;
    --surface: rgba(255,255,255,0.92);
    --surface-2: #eef2f9;
    --stroke: rgba(20,40,80,0.12);
    --stroke-strong: rgba(16,150,105,0.5);
    --neon: #10a86c;
    --neon-soft: #0a7a4e;
    --gold: #c98f00;
    --gold-soft: #85610a;
    --danger: #e23b4e;
    --text: #10192a;
    --muted: #51617a;
    --muted-2: #64728c;
    --shadow: 0 14px 30px -20px rgba(20,40,80,0.28);
    --glow: 0 0 18px -6px rgba(16,168,108,0.5);
}
:root[data-theme="light"] body {
    background:
        radial-gradient(1100px 700px at 12% -12%, rgba(16,168,108,0.12), transparent 60%),
        radial-gradient(1000px 720px at 112% 6%, rgba(201,143,0,0.10), transparent 55%),
        radial-gradient(1200px 1000px at 50% 128%, rgba(70,120,255,0.09), transparent 60%),
        #e9edf5;
}
:root[data-theme="light"] .app { background: linear-gradient(180deg, rgba(252,253,255,0.90), rgba(240,244,250,0.94)); border-left-color: rgba(20,40,80,0.10); border-right-color: rgba(20,40,80,0.10); }
:root[data-theme="light"] .topbar { background: linear-gradient(180deg, rgba(255,255,255,0.96), rgba(255,255,255,0.7)); }
:root[data-theme="light"] .stat { background: linear-gradient(165deg, #ffffff, #eef3fa); border-color: rgba(20,40,80,0.16); box-shadow: 0 8px 18px -14px rgba(20,40,80,0.4); }
:root[data-theme="light"] .stat.cv .val { color: var(--text); -webkit-text-fill-color: var(--text); background: none; }
:root[data-theme="light"] .nav { background: linear-gradient(180deg, rgba(252,253,255,0.96), rgba(236,243,252,0.96)); box-shadow: 0 18px 42px -14px rgba(20,40,80,0.26), 0 3px 10px -5px rgba(20,40,80,0.14), inset 0 1px 0 rgba(255,255,255,0.9), inset 0 -12px 22px -16px rgba(20,40,80,0.12); }
:root[data-theme="light"] .nav::before { background: linear-gradient(180deg, rgba(255,255,255,0.52), rgba(255,255,255,0) 30%), radial-gradient(130% 92% at 50% -38%, rgba(255,255,255,0.42), transparent 62%); }
:root[data-theme="light"] .nav::after { background: linear-gradient(158deg, rgba(255,255,255,0.95), rgba(255,255,255,0.32) 26%, rgba(120,150,190,0.16) 60%, rgba(255,255,255,0.6) 100%); }
:root[data-theme="light"] .nav-pill { background: linear-gradient(180deg, rgba(32,193,95,0.24), rgba(32,193,95,0.06)), radial-gradient(120% 82% at 50% -6%, rgba(255,255,255,0.5), transparent 60%); border-color: rgba(32,193,95,0.38); }
:root[data-theme="light"] .modal, :root[data-theme="light"] .sheet { background: linear-gradient(180deg, #ffffff, #f4f7fc); }
:root[data-theme="light"] .modal-backdrop { background: rgba(30,45,70,0.32); }
:root[data-theme="light"] .toast { background: #ffffff; color: var(--text); }
:root[data-theme="light"] .paywall { background: #e9eef7; }
:root[data-theme="light"] .paywall .box { background: linear-gradient(180deg, #ffffff, #f2f6fc); }
:root[data-theme="light"] .input { background: #ffffff; }
:root[data-theme="light"] .demo-strip .bar, :root[data-theme="light"] .progress { background: rgba(20,40,80,0.10); }
/* Empty progress/meter tracks need a visible fill on light backgrounds too (their
   coloured fills already show; the white-based track would otherwise vanish). */
:root[data-theme="light"] .health-bar, :root[data-theme="light"] .opp-timer { background: rgba(20,40,80,0.10); }
:root[data-theme="light"] .seg.active { background: var(--neon-soft); color: #ffffff; box-shadow: 0 6px 16px -10px var(--neon-soft); }
:root[data-theme="light"] .dots i { background: rgba(20,40,80,0.20); }
/* Filled dots must stay green in light mode too — the rule above is more specific
   than `.dots i.on`, so without this the whole progress track looked uniformly grey. */
:root[data-theme="light"] .dots i.on { background: var(--neon); }
:root[data-theme="light"] .lvl { background: rgba(20,40,80,0.06); }
:root[data-theme="light"] .buy-btn:disabled, :root[data-theme="light"] .btn:disabled,
:root[data-theme="light"] .mini-btn:disabled, :root[data-theme="light"] .mini-btn.buy:disabled { background: rgba(20,40,80,0.07); color: var(--muted-2); border-color: transparent; }
:root[data-theme="light"] .card, :root[data-theme="light"] .venture, :root[data-theme="light"] .learn-row, :root[data-theme="light"] .event-row, :root[data-theme="light"] .gig-wide, :root[data-theme="light"] .gig { box-shadow: 0 10px 26px -20px rgba(20,40,80,0.35); }

/* ── Phones: density pass ────────────────────────────────────────────────────
   Placed at the END of the file so it wins the source-order cascade over the
   base .content/.venture/.stat-card/.kel-avatar rules (same specificity). Tighter
   padding so more content fits per screen; no font/touch-target shrink. */
@media (max-width: 560px) {
    /* Bottom padding must clear the FLOATING nav (bottom: var(--nav-gap)) — otherwise
       the last content (e.g. the profile footer) hides behind the translucent bar.
       Mirror the base rule so both track the tightened nav gap. */
    .content { --cpt: 13px; --cpx: 12px; --cpb: calc(var(--nav-h) + var(--nav-gap) + 18px); }
    .list { gap: 8px; }
    .venture { padding: 10px; gap: 10px; }
    .venture .badge { width: 46px; height: 46px; font-size: 23px; }
    .venture.skill .badge.sm { width: 40px; height: 40px; font-size: 17px; }
    .section-title { margin: 2px 4px 9px; }
    .cat-title { margin-top: 20px; }
    .stat-grid { gap: 8px; margin-bottom: 12px; }
    .stat-card { padding: 11px 8px; }
    .prow { padding: 12px 13px; }
    /* profile hero: smaller avatar + tighter greeting reclaim a chunk of height */
    .kel-avatar { width: 74px; height: 74px; }
    .amb-greet { margin-bottom: 8px; }
}

/* ── Engagement features: golden bug, daily streak, tech event, app portfolio ── */
/* A lifelike crawler: the button carries the meandering stop-and-go PATH, while
   the inner .bug-b glyph does a fast leg-scuttle jitter, so it reads like a real
   bug scuttling and pausing rather than sliding in a straight line. Generous
   padding + touch-action make it an easy, reliable tap target. */
.bug { position: fixed; z-index: 200; font-size: 32px; line-height: 1; background: none; border: none; cursor: pointer;
    padding: 16px; filter: drop-shadow(0 2px 4px rgba(0,0,0,0.5)); animation-timing-function: ease-in-out; animation-fill-mode: forwards;
    -webkit-tap-highlight-color: transparent; touch-action: manipulation; will-change: transform; }
.bug .bug-b { display: inline-block; }
/* Face the direction of travel: the 🐛/🪲 glyph is drawn facing left, so mirror
   it when the bug crawls to the right (.ltr). Moving left keeps the default. */
.bug.ltr .bug-b { transform: scaleX(-1); }
.bug .bug-g { display: inline-block; animation: bugScuttle 0.14s ease-in-out infinite; will-change: transform; }
.bug.ltr { left: -60px; animation-name: bugLtr; }
.bug.rtl { right: -60px; animation-name: bugRtl; }
.bug.golden { filter: drop-shadow(0 0 9px rgba(255,210,63,0.95)); }
.bug.squashed { animation: none !important; transform: scale(1.5) !important; transition: transform 0.12s ease; }
.bug.squashed .bug-g { animation: none !important; }
/* Horizontal progress advances in uneven dashes with tiny near-static "pauses"
   (the ~1vw plateaus), plus a gentle vertical wander and body-turn rotation. */
@keyframes bugLtr {
    0%   { transform: translate(0, 0) rotate(-3deg); }
    6%   { transform: translate(10vw, -1.4vh) rotate(7deg); }
    11%  { transform: translate(11vw, -1.2vh) rotate(2deg); }
    20%  { transform: translate(28vw, 1.6vh) rotate(8deg); }
    25%  { transform: translate(29vw, 1.7vh) rotate(1deg); }
    37%  { transform: translate(47vw, -1.8vh) rotate(7deg); }
    43%  { transform: translate(48vw, -1.6vh) rotate(0deg); }
    56%  { transform: translate(68vw, 1.4vh) rotate(8deg); }
    62%  { transform: translate(69vw, 1.5vh) rotate(2deg); }
    77%  { transform: translate(90vw, -1vh) rotate(7deg); }
    83%  { transform: translate(91vw, -0.8vh) rotate(1deg); }
    100% { transform: translate(114vw, 0.4vh) rotate(4deg); }
}
@keyframes bugRtl {
    0%   { transform: translate(0, 0) rotate(3deg); }
    6%   { transform: translate(-10vw, -1.4vh) rotate(-7deg); }
    11%  { transform: translate(-11vw, -1.2vh) rotate(-2deg); }
    20%  { transform: translate(-28vw, 1.6vh) rotate(-8deg); }
    25%  { transform: translate(-29vw, 1.7vh) rotate(-1deg); }
    37%  { transform: translate(-47vw, -1.8vh) rotate(-7deg); }
    43%  { transform: translate(-48vw, -1.6vh) rotate(0deg); }
    56%  { transform: translate(-68vw, 1.4vh) rotate(-8deg); }
    62%  { transform: translate(-69vw, 1.5vh) rotate(-2deg); }
    77%  { transform: translate(-90vw, -1vh) rotate(-7deg); }
    83%  { transform: translate(-91vw, -0.8vh) rotate(-1deg); }
    100% { transform: translate(-114vw, 0.4vh) rotate(-4deg); }
}
@keyframes bugScuttle { 0% { transform: rotate(-3.5deg) translateY(0); } 50% { transform: rotate(3.5deg) translateY(-1.5px); } 100% { transform: rotate(-3.5deg) translateY(0); } }
@media (prefers-reduced-motion: reduce) { .bug { animation-duration: 0s !important; left: auto; right: 16px; top: 50vh !important; } .bug .bug-g { animation: none !important; } }

.streak-row { display: flex; justify-content: center; gap: 8px; margin: 14px 0 6px; }
.streak-dot { width: 32px; height: 32px; border-radius: 50%; display: grid; place-items: center; font-size: 15px;
    background: rgba(255,255,255,0.05); border: 1px solid var(--stroke); color: var(--muted-2); }
.streak-dot.on { background: rgba(255,210,63,0.15); border-color: rgba(255,210,63,0.5); }
.daily-amt { text-align: center; font-size: 30px; font-weight: 900; margin: 8px 0 2px;
    background: linear-gradient(90deg, var(--gold-soft), var(--neon-soft)); -webkit-background-clip: text; background-clip: text; color: transparent; }

.tech-banner { display: flex; align-items: center; gap: 10px; padding: 10px 14px; border-radius: 14px; margin-bottom: 12px;
    font-size: 13px; font-weight: 700; color: #fff8e6; line-height: 1.3;
    background: linear-gradient(100deg, rgba(255,176,60,0.22), rgba(124,58,237,0.18)); border: 1px solid rgba(255,200,110,0.4); }
.tech-banner .te-ic { font-size: 22px; flex: none; }
.tech-banner b { color: var(--gold-soft); }
.tech-banner .te-mult { margin-left: auto; font-weight: 900; color: var(--gold-soft); white-space: nowrap; font-size: 15px; }
:root[data-theme="light"] .tech-banner { color: #6b4a12; }

.app-stars { color: var(--gold-soft); letter-spacing: 1px; background: none !important; padding: 0 !important; }
.app-review { font-style: italic; opacity: 0.82; }

/* ── iOS standalone cold-start viewport fix (verified on-device) ─────────────────
   On launch in an installed PWA, iOS reports the viewport height (innerHeight / dvh /
   svh / visualViewport / the containing block used by position:fixed) ~62px SHORT —
   it excludes the top safe area — until a device rotation forces a recompute. That
   made `.app { position:fixed; inset:0 }` end ~62px above the real bottom, leaving a
   gap AND floating the bottom nav far too high ("Lücke unten" / "zu viel Abstand").
   `100lvh` (large-viewport-height) reports the FULL screen height correctly even on
   cold start (measured: lvh=874 while dvh/innerHeight=812). So in standalone we size
   the shell, splash and body by 100lvh instead of relying on the buggy inset:0/dvh.
   Placed last so it wins by source order; `bottom:auto` lets the height drive. */
@media (display-mode: standalone) {
    html, body { height: 100lvh; }
    /* Every full-screen fixed overlay that used inset:0 (which cold-starts 62px short)
       must also be sized by 100lvh so it fills the real screen: the app shell + splash,
       the ambient backdrop, all modals/sheets (.modal-backdrop), and the landing /
       paywall / device-lock / suspension screens (.paywall, .landing). */
    .app, #splash, #ambient-sky, .modal-backdrop, .paywall, .landing { height: 100lvh; bottom: auto; }
}

/* ── Arcade ("Kel Run") — full-screen premium jump-and-run overlay ─────────────
   Sits above everything (nav z-10, modal-backdrop z-100). Its own always-dark neon
   look regardless of theme — it's a game screen, not part of the app chrome. */
body.kk-arcade-open { overflow: hidden; }
.ka-root {
    position: fixed; inset: 0; z-index: 200; background: #0a1224;
    overflow: hidden; touch-action: none; user-select: none; -webkit-user-select: none;
    animation: fade 0.2s ease;
}
.ka-canvas { display: block; width: 100%; height: 100%; }
.ka-hud {
    position: absolute; top: 0; left: 0; z-index: 2; pointer-events: none;
    display: flex; flex-direction: column; align-items: flex-start; gap: 2px;
    padding: calc(var(--sat, 0px) + 12px) 16px 0 calc(var(--sal, 0px) + 16px);
    color: #eaf2ff; text-shadow: 0 2px 10px rgba(0,0,0,0.6);
}
/* HUD figures scale with the viewport so they stay big & legible in a large browser
   window too (they were tiny on desktop). */
.ka-score { font-size: clamp(36px, 6.4vw, 68px); font-weight: 900; letter-spacing: 0.5px; line-height: 1;
    background: linear-gradient(180deg, #ffffff, #9fe9cf); -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent;
    filter: drop-shadow(0 2px 8px rgba(0,0,0,0.55)); }
.ka-score-lbl { font-size: clamp(10px, 1.2vw, 15px); font-weight: 800; letter-spacing: 3px; color: #7fd8b6; margin-top: 2px; }
.ka-hud-row { display: flex; align-items: center; gap: 9px; margin-top: 7px; }
.ka-time { font-size: clamp(16px, 2.5vw, 30px); font-weight: 800; color: #eaf2ff; font-variant-numeric: tabular-nums; }
.ka-hud-sep { color: #4f6076; }
.ka-best { font-size: clamp(12px, 1.6vw, 20px); font-weight: 700; color: #9fe9cf; }
/* Top-centre world banner: a stylish glass pill tinted with the world's accent. */
.ka-worldbar {
    position: absolute; top: calc(var(--sat, 0px) + 14px); left: 50%; transform: translateX(-50%);
    z-index: 3; pointer-events: none; display: flex; align-items: center; gap: 9px;
    padding: 8px 18px; border-radius: 999px; white-space: nowrap;
    background: linear-gradient(180deg, rgba(12,18,32,0.82), rgba(12,18,32,0.62));
    border: 1.5px solid rgba(var(--wbrgb, 32,224,160), 0.6);
    box-shadow: 0 8px 24px -10px rgba(0,0,0,0.6), 0 0 20px -4px rgba(var(--wbrgb, 32,224,160), 0.5), inset 0 1px 0 rgba(255,255,255,0.12);
    -webkit-backdrop-filter: blur(9px) saturate(1.15); backdrop-filter: blur(9px) saturate(1.15);
    animation: ka-wb-in 0.4s cubic-bezier(.2,.9,.3,1.2) both;
}
.ka-worldbar.hidden { display: none; }
.ka-worldbar .wb-em { font-size: clamp(17px, 2.2vw, 26px); line-height: 1; }
.ka-worldbar .wb-nm { font-size: clamp(14px, 1.9vw, 22px); font-weight: 900; letter-spacing: 0.4px;
    color: #fff; text-shadow: 0 1px 3px rgba(0,0,0,0.5); }
@keyframes ka-wb-in { from { opacity: 0; transform: translate(-50%, -10px) scale(0.9); } to { opacity: 1; transform: translate(-50%, 0) scale(1); } }
.ka-back {
    /* Above the overlay (z 4) so it's always visible AND clickable — even while the
       start/game-over card is up. Solid enough to read against any world behind it. */
    position: absolute; z-index: 6; top: calc(var(--sat, 0px) + 10px); right: calc(var(--sar, 0px) + 12px);
    width: 42px; height: 42px; border-radius: 999px; border: 1px solid rgba(255,255,255,0.35);
    background: rgba(14,22,40,0.82); color: #fff; font-size: 19px; cursor: pointer;
    display: grid; place-items: center; line-height: 1;
    box-shadow: 0 6px 18px -6px rgba(0,0,0,0.7);
    -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
}
.ka-back:hover { background: rgba(24,34,56,0.92); border-color: rgba(255,255,255,0.5); }
.ka-back:active { transform: scale(0.94); }
.ka-overlay {
    position: absolute; inset: 0; z-index: 4; display: none; place-items: center;
    padding: calc(var(--sat, 0px) + 16px) 18px calc(var(--sab, 0px) + 16px);
    /* Keep the world preview behind the card readable — light dim, barely any blur. */
    background: rgba(6,10,20,0.32); -webkit-backdrop-filter: blur(1.5px); backdrop-filter: blur(1.5px);
    overflow-y: auto;
}
.ka-overlay.show { display: grid; animation: fade 0.2s ease; }
.ka-card {
    box-sizing: border-box; width: min(600px, 96vw); display: flex; flex-direction: column; align-items: center; gap: 15px;
    text-align: center; padding: 30px 30px 26px; border-radius: 26px;
    background: linear-gradient(180deg, rgba(22,30,52,0.94), rgba(12,18,34,0.97));
    border: 1px solid rgba(32,224,160,0.28);
    box-shadow: 0 34px 90px -30px rgba(0,0,0,0.82), inset 0 1px 0 rgba(255,255,255,0.08);
    color: #eaf2ff;
}
.ka-hero { width: 128px; height: 128px; object-fit: cover; border-radius: 50%; border: 3px solid rgba(32,224,160,0.55);
    box-shadow: 0 8px 22px -6px rgba(32,224,160,0.5), inset 0 0 0 1px rgba(255,255,255,0.12); }
.ka-h { font-size: 30px; font-weight: 900; letter-spacing: 1px; }
.ka-p { font-size: 14.5px; line-height: 1.5; color: #c3cfe4; margin: 0; }
.ka-score-big { font-size: 52px; font-weight: 900; color: #FFD700; line-height: 1; text-shadow: 0 4px 24px rgba(255,215,0,0.4); }
.ka-btn {
    width: 100%; border: none; cursor: pointer; border-radius: 14px; font-weight: 800; font-size: 16px;
    padding: 14px 18px; transition: transform 0.06s ease, filter 0.15s ease;
}
.ka-btn:active { transform: scale(0.98); }
.ka-btn.primary { color: #06251a; background: linear-gradient(135deg, #7ff4c6, #20E0A0); box-shadow: 0 12px 26px -14px rgba(32,224,160,0.8); }
.ka-btn.ghost { background: rgba(255,255,255,0.06); color: #eaf2ff; border: 1px solid rgba(255,255,255,0.14); }
/* World-select hub (start screen) */
.ka-worlds { display: flex; flex-wrap: wrap; gap: 7px; justify-content: center; width: 100%; }
.ka-world { display: flex; flex-direction: column; align-items: center; gap: 4px; min-width: 108px; flex: 1 1 108px; max-width: 150px;
    padding: 13px 8px; border-radius: 15px; cursor: pointer; color: #eaf2ff;
    background: rgba(255,255,255,0.05); border: 1px solid rgba(255,255,255,0.12); transition: transform .06s ease, border-color .15s ease; }
.ka-world:active { transform: scale(0.96); }
.ka-world .kw-em { font-size: 30px; line-height: 1; }
.ka-world .kw-n { font-size: 15px; font-weight: 800; }
.ka-world .kw-s { font-size: 11px; color: #9fb0c8; }
.ka-world.sel { border-color: #20E0A0; background: rgba(32,224,160,0.14); box-shadow: 0 6px 16px -10px rgba(32,224,160,0.6); }
.ka-world.locked { opacity: 0.5; cursor: default; }
.ka-world.locked .kw-s { color: #ffd24a; }
.ka-world.staff { border-color: rgba(255,210,74,0.55); background: linear-gradient(180deg, rgba(255,210,74,0.14), rgba(74,163,255,0.10)); }
.ka-world.staff .kw-s { color: #ffd24a; font-weight: 800; }
.ka-wnote { width: 100%; text-align: center; font-size: 11px; color: #9fb0c8; margin-top: 2px; }
.ka-wprog { width: 100%; height: 6px; border-radius: 999px; background: rgba(255,255,255,0.1); overflow: hidden; }
.ka-wprog i { display: block; height: 100%; background: linear-gradient(90deg, #20E0A0, #7ff4c6); }
.ka-unlock { width: 100%; box-sizing: border-box; font-size: 13px; font-weight: 800; color: #7ff4c6;
    background: rgba(32,224,160,0.12); border: 1px solid rgba(32,224,160,0.32); border-radius: 10px; padding: 8px 10px; }
.ka-keys { width: 100%; font-size: 11px; font-weight: 600; color: #8aa0bd; letter-spacing: 0.2px; margin-top: -2px; }
.ka-btn:focus-visible, .ka-world:focus-visible { outline: 3px solid #7ff4c6; outline-offset: 2px; }
.ka-btn:focus-visible { box-shadow: 0 0 0 4px rgba(127,244,198,0.25); }
.ka-board { width: 100%; margin-top: 4px; text-align: left; }
.ka-board-h { font-size: 13px; font-weight: 800; color: #9fe9cf; text-transform: uppercase; letter-spacing: 0.6px; margin-bottom: 8px; text-align: center; }
.ka-board-empty { font-size: 13px; color: #93a1bd; text-align: center; padding: 6px 0; }
.ka-board-row { display: flex; align-items: center; gap: 10px; padding: 7px 10px; border-radius: 10px; font-size: 14px; }
.ka-board-row:nth-child(even) { background: rgba(255,255,255,0.03); }
.ka-board-row.me { background: rgba(32,224,160,0.14); border: 1px solid rgba(32,224,160,0.3); font-weight: 800; }
.ka-board-row .ka-rank { width: 34px; color: #FFD700; font-weight: 800; }
.ka-board-row .ka-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ka-board-row .ka-val { font-weight: 800; color: #9fe9cf; }
/* Landscape on a phone (short viewport): the start/game-over card must never be
   taller than the screen. Top-align + scroll, and compact every element so it
   fits without an awkward scroll. The canvas itself always fills the viewport. */
@media (orientation: landscape) and (max-height: 560px) {
    .ka-overlay { place-items: start center; padding: 10px 16px calc(var(--sab, 0px) + 10px); }
    .ka-card { gap: 7px; padding: 13px 20px; width: min(470px, 100%); border-radius: 16px; margin: auto; }
    .ka-hero { width: 58px; height: 58px; }
    .ka-h { font-size: 19px; letter-spacing: 0.5px; }
    .ka-p { font-size: 12px; line-height: 1.35; }
    .ka-score-big { font-size: 34px; }
    .ka-btn { padding: 9px 16px; font-size: 14px; border-radius: 12px; }
    .ka-board { margin-top: 0; }
    .ka-board-h { margin-bottom: 4px; }
    .ka-board-row { padding: 4px 9px; font-size: 12px; }
    .ka-back { width: 36px; height: 36px; font-size: 16px; }
}
/* Very small heights (tiny landscape phones): drop the hero image entirely. */
@media (orientation: landscape) and (max-height: 400px) {
    .ka-hero { display: none; }
    .ka-card { gap: 6px; padding: 11px 18px; }
}
