/* ============================================================================
   VEONARYLAND — Web shell styling
   Design: dark "premium gamer" aesthetic. Glassmorphism (frosted, high-contrast
   text), one indigo→violet→cyan accent system, GPU-only animations
   (transform/opacity) so the 60fps WebGL canvas underneath stays smooth.
   Every class/id here is referenced by index.html / AgoraBridge — names kept.
============================================================================ */

/* ==================== VARIABLES ==================== */
:root {
    --accent-1: #7b6ff5;   /* indigo  */
    --accent-2: #b07bff;   /* violet  */
    --accent-3: #4fd0ff;   /* cyan    */
    --grad-accent: linear-gradient(135deg, var(--accent-1) 0%, var(--accent-2) 60%, var(--accent-3) 120%);
    /* Darker gradient for SOLID buttons so white text stays readable
       (the bright accent gradient is for accents/text, not button fills). */
    --grad-btn: linear-gradient(135deg, #5b4fd6 0%, #7d4fd6 100%);

    --bg-0: #07080f;       /* deepest */
    --bg-1: #0b0d1a;
    --bg-2: #12152a;

    --glass-bg: rgba(255, 255, 255, 0.055);
    --glass-bg-strong: rgba(255, 255, 255, 0.09);
    --glass-border: rgba(255, 255, 255, 0.12);
    --glass-hi: rgba(255, 255, 255, 0.22);

    --text-1: #f4f6ff;
    --text-2: #aab2c9;
    --text-3: #6c7593;

    --ok: #38d39f;
    --danger: #ff5470;

    --r-sm: 0.55rem;
    --r-md: 1rem;
    --r-lg: 1.5rem;
    --r-full: 9999px;

    --sp-xs: 0.25rem;
    --sp-sm: 0.5rem;
    --sp-md: 1rem;
    --sp-lg: 1.5rem;
    --sp-xl: 2rem;

    --shadow-md: 0 8px 28px rgba(0, 0, 0, 0.35);
    --shadow-lg: 0 18px 60px rgba(0, 0, 0, 0.5);
    --glow: 0 0 28px rgba(123, 111, 245, 0.45);

    --ease: cubic-bezier(0.22, 1, 0.36, 1); /* smooth "expo-out" feel */
}

/* ==================== GLOBAL ==================== */
* { margin: 0; padding: 0; box-sizing: border-box; }

html, body {
    height: 100%;
    overflow: hidden;
}

body {
    font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
    background: var(--bg-0);
    color: var(--text-1);
    position: relative;
    width: 100vw;
    min-height: 100vh;
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
}

::selection { background: rgba(123, 111, 245, 0.4); color: #fff; }

/* ==================== ANIMATED BACKGROUND ==================== */
/* Aurora: a few large blurred orbs drifting slowly + a faint moving grid.
   All transform/opacity based → GPU, cheap. */
.animated-bg {
    position: fixed;
    inset: 0;
    z-index: 0;
    overflow: hidden;
    background:
        radial-gradient(1100px 760px at 12% -8%,  rgba(86, 76, 200, 0.40) 0%, transparent 58%),
        radial-gradient(1000px 720px at 112% 118%, rgba(120, 70, 190, 0.42) 0%, transparent 55%),
        radial-gradient(820px 640px  at 88% 6%,    rgba(45, 130, 190, 0.22) 0%, transparent 55%),
        linear-gradient(160deg, var(--bg-1) 0%, var(--bg-0) 100%);
}

/* subtle drifting grid for "digital world" feel */
.animated-bg::after {
    content: "";
    position: absolute;
    inset: -50%;
    background-image:
        linear-gradient(rgba(123, 111, 245, 0.10) 1px, transparent 1px),
        linear-gradient(90deg, rgba(123, 111, 245, 0.10) 1px, transparent 1px);
    background-size: 48px 48px;
    mask-image: radial-gradient(circle at 50% 50%, #000 0%, transparent 70%);
    -webkit-mask-image: radial-gradient(circle at 50% 50%, #000 0%, transparent 70%);
    animation: gridDrift 30s linear infinite;
    will-change: transform;
}

@keyframes gridDrift {
    from { transform: translate(0, 0); }
    to   { transform: translate(46px, 46px); }
}

.gradient-orb {
    position: absolute;
    border-radius: 50%;
    filter: blur(80px);
    opacity: 0.6;
    will-change: transform;
}
.orb-1 { width: 560px; height: 560px; background: radial-gradient(circle, var(--accent-1), transparent 70%); top: -14%; left: -10%; animation: float1 24s ease-in-out infinite; }
.orb-2 { width: 480px; height: 480px; background: radial-gradient(circle, var(--accent-2), transparent 70%); bottom: -16%; right: -12%; animation: float2 28s ease-in-out infinite; }
.orb-3 { width: 420px; height: 420px; background: radial-gradient(circle, var(--accent-3), transparent 70%); top: 42%; left: 50%; opacity: 0.42; animation: float3 32s ease-in-out infinite; }

@keyframes float1 { 0%,100% { transform: translate(0,0) scale(1); } 50% { transform: translate(60px,40px) scale(1.12); } }
@keyframes float2 { 0%,100% { transform: translate(0,0) scale(1); } 50% { transform: translate(-50px,-30px) scale(0.92); } }
@keyframes float3 { 0%,100% { transform: translate(-50%,-50%) scale(1); } 50% { transform: translate(-46%,-56%) scale(1.1); } }

/* ---- Starfield: two layers of scattered dots, slow parallax drift + twinkle.
   Pure CSS (radial-gradients), GPU-friendly. Fills the empty space behind the
   game canvas so the lobby never looks flat. ---- */
.animated-bg .stars,
.animated-bg .stars2 {
    position: absolute;
    inset: -100px;
    background-repeat: repeat;
    will-change: transform, opacity;
}
.animated-bg .stars {
    background-image:
        radial-gradient(1.5px 1.5px at 20px 30px, rgba(255,255,255,0.9), transparent),
        radial-gradient(1.5px 1.5px at 120px 80px, rgba(180,200,255,0.8), transparent),
        radial-gradient(1px 1px at 200px 160px, rgba(255,255,255,0.7), transparent),
        radial-gradient(1.5px 1.5px at 300px 60px, rgba(200,180,255,0.8), transparent),
        radial-gradient(1px 1px at 360px 220px, rgba(255,255,255,0.6), transparent);
    background-size: 400px 300px;
    animation: starDrift 90s linear infinite, twinkle 5s ease-in-out infinite;
    opacity: 0.85;
}
.animated-bg .stars2 {
    background-image:
        radial-gradient(1px 1px at 60px 120px, rgba(255,255,255,0.7), transparent),
        radial-gradient(1px 1px at 180px 40px, rgba(180,210,255,0.6), transparent),
        radial-gradient(1px 1px at 260px 200px, rgba(255,255,255,0.5), transparent),
        radial-gradient(1px 1px at 340px 140px, rgba(210,190,255,0.6), transparent);
    background-size: 500px 380px;
    animation: starDrift 140s linear infinite reverse, twinkle 7s ease-in-out infinite 1s;
    opacity: 0.6;
}
@keyframes starDrift { from { transform: translateY(0); } to { transform: translateY(-300px); } }
@keyframes twinkle  { 0%,100% { opacity: 1; } 50% { opacity: 0.55; } }

/* A soft vignette so edges feel deliberate, not just dark. */
.animated-bg .vignette {
    position: absolute;
    inset: 0;
    pointer-events: none;
    background: radial-gradient(circle at 50% 45%, transparent 55%, rgba(0,0,0,0.45) 100%);
}

/* ==================== UNITY CONTAINER / CANVAS ==================== */
#unity-container {
    position: fixed;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 1;
}
/* Extra bottom padding nudges the centered canvas slightly UP, leaving a bit
   more breathing room below it for the voice/camera control dock. */
#unity-container.unity-desktop { padding: 24px 24px 72px; }
#unity-container.unity-mobile  { padding: 56px 4px 4px; }

#unity-canvas {
    background: var(--bg-2);
    border-radius: var(--r-lg);
    /* Kept invisible until the loading overlay fades out, so the user never
       sees Unity's own splash screen / first blank frames painting on the
       canvas. JS flips this to "visible" right after the overlay is removed.
       NOTE: visibility (not display:none) so Unity can still size/init the
       canvas and WebGL context normally while it's hidden. */
    visibility: hidden;
    /* Framed, glowing edge so the canvas reads as a premium "window" into the
       world rather than a dark rectangle floating in empty space. */
    border: 1px solid rgba(123, 111, 245, 0.25);
    box-shadow:
        var(--shadow-lg),
        0 0 0 1px rgba(255, 255, 255, 0.04),
        0 0 50px rgba(123, 111, 245, 0.22),
        0 0 120px rgba(79, 208, 255, 0.10);
    display: block;
    /* Fill the available space as a large 16:9 widescreen view. The build's
       intrinsic canvas size may be square, but we override the layout box so
       the game presents as a big rectangle instead of a small square.
       Sized to the largest 16:9 box that fits the padded container:
       width is capped by viewport width, height by viewport height. */
    aspect-ratio: 16 / 9;
    /* Cap the height a little below the full viewport so the gameplay view
       isn't overwhelmingly tall, while width is driven by the 16:9 ratio so it
       stays a wide rectangle and uses the horizontal space. */
    width: min(100%, calc(82vh * 16 / 9)) !important;
    height: auto !important;
    max-width: 100%;
    max-height: 82vh;
    object-fit: cover;
}
.unity-mobile #unity-canvas { border-radius: var(--r-md); }

/* ==================== LOADING SCREEN ==================== */
#unity-loading-bar {
    position: fixed;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    /* 9999 = on top of EVERYTHING (canvas, warning banner, footer, etc.) so the
       Unity splash screen / first frames painting on the canvas are fully
       covered until we fade this out. */
    z-index: 9999;
    transition: opacity 0.6s var(--ease);
    background:
        radial-gradient(900px 600px at 50% 35%, rgba(123,111,245,0.10), transparent 70%),
        var(--bg-0);
}
#unity-loading-bar.fade-out { opacity: 0; pointer-events: none; }

.loading-content {
    position: relative;
    text-align: center;
    padding: calc(var(--sp-xl) * 1.4) var(--sp-xl) var(--sp-xl);
    background: linear-gradient(160deg, var(--glass-bg-strong), var(--glass-bg));
    backdrop-filter: blur(26px);
    -webkit-backdrop-filter: blur(26px);
    border: 1px solid var(--glass-border);
    border-radius: var(--r-lg);
    box-shadow: var(--shadow-lg), 0 0 70px rgba(123, 111, 245, 0.16);
    min-width: 440px;
    max-width: 90vw;
    animation: cardIn 0.7s var(--ease) both;
    overflow: hidden;
}
/* sheen sweep across the card */
.loading-content::before {
    content: "";
    position: absolute;
    top: 0; left: -60%;
    width: 40%; height: 100%;
    background: linear-gradient(100deg, transparent, rgba(255,255,255,0.07), transparent);
    transform: skewX(-18deg);
    animation: cardSheen 4.5s ease-in-out infinite;
}
@keyframes cardSheen { 0% { left: -60%; } 55%,100% { left: 130%; } }

@keyframes cardIn {
    from { opacity: 0; transform: translateY(26px) scale(0.97); }
    to   { opacity: 1; transform: translateY(0)    scale(1); }
}

/* ---- orbital loader ring above the wordmark ---- */
.loading-orbit {
    width: 64px;
    height: 64px;
    margin: 0 auto var(--sp-lg);
    position: relative;
}
.loading-orbit::before,
.loading-orbit::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: 50%;
    border: 2px solid transparent;
}
.loading-orbit::before {
    border-top-color: var(--accent-1);
    border-right-color: var(--accent-2);
    animation: spin 1s linear infinite;
}
.loading-orbit::after {
    inset: 10px;
    border-bottom-color: var(--accent-3);
    animation: spin 1.6s linear infinite reverse;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ---- VEONARYLAND wordmark ---- */
.brand-mark {
    font-size: 2.7rem;
    font-weight: 800;
    letter-spacing: 0.04em;
    line-height: 1;
    margin-bottom: var(--sp-sm);
    user-select: none;
}
.brand-veonary {
    background: var(--grad-accent);
    background-size: 200% auto;
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    animation: hueShift 6s linear infinite;
}
@keyframes hueShift { to { background-position: 200% center; } }
.brand-land { color: var(--text-1); opacity: 0.92; }

.brand-tagline {
    font-size: 0.82rem;
    font-weight: 600;
    letter-spacing: 0.3em;
    text-transform: uppercase;
    color: var(--text-2);
    margin-bottom: var(--sp-lg);
}

.pulse-animation { animation: brandPulse 2.4s ease-in-out infinite; }
@keyframes brandPulse { 0%,100% { transform: scale(1); } 50% { transform: scale(1.035); } }

.loading-bar-container { margin-bottom: var(--sp-md); }

#unity-progress-bar-empty {
    width: 100%;
    height: 12px;
    background: rgba(255, 255, 255, 0.07);
    border-radius: var(--r-full);
    overflow: hidden;
    position: relative;
    margin-bottom: var(--sp-sm);
    box-shadow: inset 0 1px 3px rgba(0,0,0,0.4);
}
#unity-progress-bar-full {
    width: 0%;
    height: 100%;
    background: linear-gradient(90deg, var(--accent-1), var(--accent-2), var(--accent-3), var(--accent-1));
    background-size: 300% 100%;
    border-radius: var(--r-full);
    transition: width 0.35s var(--ease);
    box-shadow: 0 0 14px rgba(123, 111, 245, 0.8);
    animation: barFlow 2.2s linear infinite;
    position: relative;
}
@keyframes barFlow { to { background-position: -300% 0; } }
/* moving highlight head on the bar */
#unity-progress-bar-full::after {
    content: "";
    position: absolute;
    top: 0; right: 0; bottom: 0;
    width: 40px;
    background: linear-gradient(90deg, transparent, rgba(255,255,255,0.55));
    border-radius: var(--r-full);
}

#loading-percentage {
    font-size: 1.05rem;
    font-weight: 700;
    color: var(--text-1);
    font-variant-numeric: tabular-nums;
    margin-bottom: var(--sp-sm);
}
.loading-tip {
    font-size: 0.85rem;
    color: var(--text-2);
    font-weight: 500;
    min-height: 1.2em;
    animation: tipFade 0.6s var(--ease);
}
@keyframes tipFade { from { opacity: 0; transform: translateY(4px); } to { opacity: 0.85; transform: none; } }

/* ==================== LOADING — INDETERMINATE STATE ==================== */
/* The single loading card (#unity-loading-bar) is reused for load states with
   no measurable progress (e.g. "Entering world…", set by JS_ShowSceneCover).
   In this mode we hide the % readout and turn the progress bar into a sweeping
   indeterminate fill instead of a real width. */
#unity-loading-bar.indeterminate #loading-percentage { display: none; }
#unity-loading-bar.indeterminate #unity-progress-bar-full {
    /* A fixed-width slug that sweeps across, rather than a 0→100% fill. */
    width: 40% !important;
    animation: barFlow 2.2s linear infinite, indeterminate 1.3s var(--ease) infinite;
}
@keyframes indeterminate {
    0%   { transform: translateX(-120%); }
    100% { transform: translateX(280%); }
}

/* ==================== AUTH OVERLAY ==================== */
.auth-overlay {
    position: fixed;
    inset: 0;
    z-index: 3000;
    display: none;
    align-items: center;
    justify-content: center;
    background: rgba(6, 8, 16, 0.72);
    backdrop-filter: blur(14px);
    -webkit-backdrop-filter: blur(14px);
}
.auth-overlay.visible { display: flex; animation: fadeIn 0.5s var(--ease); }
.auth-overlay.hidden  { animation: fadeOut 0.5s var(--ease) forwards; }

@keyframes fadeIn  { from { opacity: 0; } to { opacity: 1; } }
@keyframes fadeOut { from { opacity: 1; } to { opacity: 0; pointer-events: none; } }

.auth-card {
    position: relative;
    background: linear-gradient(160deg, var(--glass-bg-strong), var(--glass-bg));
    backdrop-filter: blur(30px);
    -webkit-backdrop-filter: blur(30px);
    border: 1px solid var(--glass-border);
    border-radius: var(--r-lg);
    padding: calc(var(--sp-xl) * 1.1) var(--sp-xl);
    box-shadow: var(--shadow-lg), 0 0 60px rgba(123, 111, 245, 0.14);
    text-align: center;
    width: 92%;
    max-width: 430px;
    animation: cardIn 0.6s var(--ease) 0.05s both;
    overflow: hidden;
}
/* animated gradient hairline at the top edge */
.auth-card::before {
    content: "";
    position: absolute;
    top: 0; left: 0; right: 0;
    height: 2px;
    background: var(--grad-accent);
    background-size: 200% auto;
    animation: hueShift 5s linear infinite;
    z-index: 2;
}
/* cursor-follow glow (premium touch). --mx/--my set from JS in index.html;
   defaults keep it centered if JS doesn't run. */
.auth-card::after {
    content: "";
    position: absolute;
    inset: 0;
    background: radial-gradient(420px circle at var(--mx, 50%) var(--my, 0%),
                rgba(123, 111, 245, 0.18), transparent 45%);
    opacity: 0;
    transition: opacity 0.4s var(--ease);
    pointer-events: none;
}
.auth-card:hover::after { opacity: 1; }

.auth-title {
    font-size: 1.9rem;
    font-weight: 800;
    letter-spacing: -0.01em;
    margin-bottom: var(--sp-xs);
    background: linear-gradient(120deg, #fff 30%, var(--accent-2));
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
}
.auth-subtitle {
    font-size: 0.95rem;
    color: var(--text-2);
    margin-bottom: var(--sp-xl);
    font-weight: 500;
}

.auth-form { width: 100%; margin-bottom: var(--sp-md); }

.auth-input {
    width: 100%;
    padding: 0.85rem 1rem;
    border: 1px solid var(--glass-border);
    border-radius: var(--r-md);
    background: rgba(255, 255, 255, 0.04);
    color: var(--text-1);
    font-size: 0.95rem;
    font-family: inherit;
    margin-bottom: var(--sp-sm);
    transition: border-color 0.2s var(--ease), background 0.2s var(--ease), box-shadow 0.2s var(--ease);
}
.auth-input::placeholder { color: var(--text-3); }
.auth-input:focus {
    outline: none;
    border-color: rgba(123, 111, 245, 0.8);
    background: rgba(255, 255, 255, 0.07);
    box-shadow: 0 0 0 3px rgba(123, 111, 245, 0.18);
}

.auth-btn {
    position: relative;
    width: 100%;
    padding: 0.85rem 1.25rem;
    border: 1px solid var(--glass-border);
    border-radius: var(--r-md);
    font-size: 0.95rem;
    font-weight: 600;
    font-family: inherit;
    cursor: pointer;
    transition: transform 0.18s var(--ease), box-shadow 0.18s var(--ease), background 0.18s var(--ease), border-color 0.18s var(--ease);
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--sp-sm);
    margin-bottom: var(--sp-md);
    overflow: hidden;
}
.auth-btn:active { transform: translateY(0) scale(0.99); }

.auth-btn.primary {
    background: var(--grad-btn);
    background-size: 160% auto;
    color: #fff;
    border-color: transparent;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.35); /* keep label crisp on the fill */
    /* Glow reduced ~30% vs the in-game dock so the login reads premium, not
       gamey. Scoped here (not via --glow) so the HUD's accent glow is unchanged. */
    box-shadow: 0 6px 20px rgba(91, 79, 214, 0.28);
}
.auth-btn.primary:hover {
    transform: translateY(-2px);
    background-position: right center;
    /* ~30% softer than the dock glow: lift shadow 0.55→0.38, and a scoped accent
       halo (0.45→0.30) instead of the shared --glow token. */
    box-shadow: 0 10px 30px rgba(91, 79, 214, 0.38), 0 0 28px rgba(123, 111, 245, 0.30);
}
.auth-btn.secondary {
    background: var(--glass-bg);
    color: var(--text-1);
}
.auth-btn.secondary:hover {
    transform: translateY(-2px);
    background: var(--glass-bg-strong);
    border-color: rgba(123, 111, 245, 0.5);
    box-shadow: var(--shadow-md);
}

.google-icon { width: 20px; height: 20px; }

.auth-toggle-text { margin-top: var(--sp-xs); font-size: 0.88rem; color: var(--text-2); }
.auth-link {
    color: var(--accent-2);
    text-decoration: none;
    font-weight: 600;
    margin-left: 4px;
    transition: color 0.2s var(--ease);
}
.auth-link:hover { color: var(--accent-3); text-decoration: underline; }

.auth-divider {
    display: flex;
    align-items: center;
    text-align: center;
    margin: var(--sp-lg) 0;
    color: var(--text-3);
    font-size: 0.78rem;
    font-weight: 600;
    letter-spacing: 0.08em;
}
.auth-divider::before, .auth-divider::after {
    content: ""; flex: 1; border-bottom: 1px solid var(--glass-border);
}
.auth-divider span { padding: 0 var(--sp-md); }

/* ==================== TOP-LEFT CONTROL DOCK (voice/cam/screen) ==================== */
/* The in-world control dock: one cohesive glass bar, not a loose row of pills.
   It overlays the 3D world, so it uses the glass treatment from the design
   system. The blur is small-area (just the dock), so it's cheap on WebGL — the
   perf rule only bans full-screen backdrop blur. */
#voice-controls {
    position: fixed;
    bottom: 18px;                 /* docked at the BOTTOM, centered */
    left: 50%;
    transform: translateX(-50%);
    z-index: 1100;                /* above the footer bar */
    display: none;                /* shown by JS when in the game scene */
    align-items: center;
    gap: var(--sp-xs);
    /* unified glass dock surface */
    padding: 7px;
    background: rgba(10, 11, 18, 0.65);
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    border: 0.5px solid rgba(255, 255, 255, 0.12);
    border-radius: 14px;
    box-shadow: var(--shadow-lg), inset 0 1px 0 rgba(255, 255, 255, 0.06);
}
#voice-controls.visible { display: flex; animation: dockIn 0.45s var(--ease); }
@keyframes dockIn { from { opacity: 0; transform: translate(-50%, 14px); } to { opacity: 1; transform: translate(-50%, 0); } }

.glass-panel {
    background: var(--glass-bg);
    backdrop-filter: blur(20px);
    -webkit-backdrop-filter: blur(20px);
    border: 1px solid var(--glass-border);
    border-radius: var(--r-md);
    padding: var(--sp-xs);
    box-shadow: var(--shadow-md);
}

/* Buttons read as segments INSIDE the glass dock: nearly borderless at rest so
   they don't look like glass-on-glass; the active/muted fills still pop. */
.voice-btn {
    position: relative;                     /* anchor for the .key-hint badge */
    display: flex;
    align-items: center;
    gap: 0.55rem;
    padding: 0.5rem 1.05rem 0.5rem 0.6rem;
    background: transparent;
    border: 1px solid transparent;
    border-radius: var(--r-full);          /* pill shape */
    color: var(--text-1);
    font-size: 0.88rem;
    font-weight: 500;
    font-family: inherit;
    cursor: pointer;
    transition: transform 0.16s var(--ease), background 0.16s var(--ease), border-color 0.16s var(--ease), box-shadow 0.16s var(--ease);
    white-space: nowrap;
}
/* icon sits in its own soft chip — gives the button a polished, app-like look */
.voice-btn svg {
    width: 18px; height: 18px;
    padding: 5px;
    box-sizing: content-box;
    background: rgba(255, 255, 255, 0.07);
    border-radius: 50%;
    transition: transform 0.16s var(--ease), background 0.16s var(--ease);
    flex: none;
}
/* keyboard shortcut badge in the top-right corner of the button (e.g. "T") */
.key-hint {
    position: absolute;
    top: -4px;
    right: -2px;
    min-width: 15px;
    height: 15px;
    padding: 0 3px;
    box-sizing: border-box;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0.62rem;
    font-weight: 700;
    line-height: 1;
    color: var(--text-1);
    background: rgba(255, 255, 255, 0.16);
    border: 1px solid rgba(255, 255, 255, 0.22);
    border-radius: 4px;
    pointer-events: none;
}
.voice-btn:hover {
    transform: translateY(-1px);
    background: rgba(255, 255, 255, 0.07);
    border-color: rgba(255, 255, 255, 0.10);
}
.voice-btn:hover svg { transform: scale(1.08); }
.voice-btn:active { transform: translateY(0) scale(0.98); }

/* active = mic/cam/screen on → filled accent (darker fill = readable text) */
.voice-btn.active {
    background: var(--grad-btn);
    background-size: 160% auto;
    border-color: transparent;
    color: #fff;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.35);
    box-shadow: var(--glow);
}
.voice-btn.active svg { background: rgba(255, 255, 255, 0.18); }

/* muted = voice enabled but mic off → unmistakably red, no accent glow, so it
   never reads as "live". Takes precedence over .active (the JS removes .active
   when muting, but this also wins on specificity if both are ever present). */
.voice-btn.muted,
.voice-btn.active.muted {
    background: #ff4444;
    background-size: auto;
    border-color: transparent;
    color: #fff;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.35);
    box-shadow: none;
}
.voice-btn.muted svg { background: rgba(255, 255, 255, 0.18); }

/* ---- "mic is LIVE" indicator: a clean pulsing dot + label, not bars ---- */
.voice-indicator {
    display: none;
    align-items: center;
    gap: 0.45rem;
    padding: 0.4rem 0.8rem 0.4rem 0.6rem;
    border-radius: var(--r-full);
    background: rgba(56, 211, 159, 0.12);
    border: 1px solid rgba(56, 211, 159, 0.35);
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    color: var(--ok);
    text-transform: uppercase;
}
.voice-indicator.active { display: inline-flex; animation: dockIn 0.3s var(--ease); }
.voice-indicator::after { content: "LIVE"; }
/* pulsing dot (each .wave-bar element is reused as the dot / its rings — but we
   only need one visual dot, so style the first and hide the rest) */
.wave-bar {
    position: relative;
    width: 9px; height: 9px;
    background: var(--ok);
    border-radius: 50%;
    box-shadow: 0 0 0 0 rgba(56, 211, 159, 0.6);
    animation: livePulse 1.6s ease-out infinite;
}
.wave-bar:nth-child(n+2) { display: none; } /* keep markup, show one dot */
@keyframes livePulse {
    0%   { box-shadow: 0 0 0 0 rgba(56, 211, 159, 0.55); }
    70%  { box-shadow: 0 0 0 9px rgba(56, 211, 159, 0); }
    100% { box-shadow: 0 0 0 0 rgba(56, 211, 159, 0); }
}

/* ==================== FOOTER ==================== */
#unity-footer {
    position: fixed;
    bottom: 0; left: 0; right: 0;
    height: 56px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0 var(--sp-lg);
    background: linear-gradient(0deg, rgba(7,8,15,0.85), transparent);
    z-index: 1000;
}
.unity-mobile #unity-footer { display: none; }
.footer-left, .footer-right { display: flex; align-items: center; gap: var(--sp-md); }

#unity-build-title { font-size: 1.05rem; font-weight: 800; letter-spacing: 0.03em; }
#unity-build-title .brand-veonary {
    background: var(--grad-accent);
    background-size: 200% auto;
    -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent;
    animation: hueShift 6s linear infinite;
}
#unity-build-title .brand-land { color: var(--text-1); opacity: 0.9; }

.control-btn {
    width: 42px; height: 42px;
    background: var(--glass-bg);
    border: 1px solid var(--glass-border);
    border-radius: var(--r-sm);
    color: var(--text-1);
    cursor: pointer;
    display: flex; align-items: center; justify-content: center;
    transition: transform 0.16s var(--ease), background 0.16s var(--ease), box-shadow 0.16s var(--ease), border-color 0.16s var(--ease);
}
.control-btn:hover {
    background: var(--glass-bg-strong);
    border-color: rgba(123,111,245,0.5);
    transform: translateY(-2px);
    box-shadow: var(--glow);
}
.control-btn:active { transform: translateY(0); }

/* ==================== AGORA VIDEO TILES ==================== */
/* Participant video tiles, pinned TOP-RIGHT as glass tiles (per the HUD design).
   The tile DOM/classes are generated by AgoraBridge.jslib — only styled here. */
#agora-tiles {
    position: fixed;
    top: var(--sp-lg);
    right: var(--sp-lg);
    z-index: 1000;
    display: flex;
    flex-direction: column;
    gap: var(--sp-sm);
    align-items: flex-end;
    /* Cap the stack height so many cameras don't run off the top of the screen;
       extra tiles scroll instead. pointer-events auto so the column is
       scrollable (individual tiles re-enable too). */
    max-height: 80vh;
    overflow-y: auto;
    overflow-x: hidden;
    padding: 2px;            /* room for tile borders/scroll */
    pointer-events: auto;
    /* thin, themed scrollbar */
    scrollbar-width: thin;
    scrollbar-color: rgba(123, 111, 245, 0.5) transparent;
}
#agora-tiles::-webkit-scrollbar { width: 6px; }
#agora-tiles::-webkit-scrollbar-thumb {
    background: rgba(123, 111, 245, 0.5);
    border-radius: var(--r-full);
}
#agora-tiles::-webkit-scrollbar-track { background: transparent; }
.agora-tile {
    width: 210px; height: 132px;
    /* Glass frame around the video: dark glass backing shows through letterboxed
       edges, with the system's 0.5px hairline + 14px radius so tiles match the
       dock and panels. */
    background: rgba(10, 11, 18, 0.65);
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    border-radius: 14px;
    overflow: hidden;
    border: 0.5px solid rgba(255, 255, 255, 0.12);
    box-shadow: var(--shadow-lg);
    position: relative;
    pointer-events: auto;
    animation: tileIn 0.4s var(--ease);
}
@keyframes tileIn { from { opacity: 0; transform: translateX(20px) scale(0.95); } to { opacity: 1; transform: none; } }
.agora-tile-video { width: 100%; height: 100%; }
.agora-tile-video video { width: 100% !important; height: 100% !important; object-fit: cover; }
.agora-tile-label {
    position: absolute;
    bottom: 0; left: 0; right: 0;
    padding: 4px 9px;
    font-size: 0.74rem;
    font-weight: 500;
    color: rgba(255, 255, 255, 0.92);
    background: linear-gradient(0deg, rgba(0,0,0,0.72), transparent);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* ==================== WARNING BANNER ==================== */
#unity-warning {
    position: fixed;
    left: 50%; top: 4%;
    transform: translateX(-50%);
    background: var(--glass-bg-strong);
    backdrop-filter: blur(20px);
    -webkit-backdrop-filter: blur(20px);
    border: 1px solid var(--glass-border);
    border-radius: var(--r-md);
    padding: var(--sp-md);
    display: none;
    z-index: 2001;
    max-width: 90%;
}
#unity-warning > div { padding: var(--sp-sm); border-radius: var(--r-sm); margin-bottom: var(--sp-sm); }

/* ==================== UTILITY ==================== */
.hidden { display: none !important; }
.fade-out { opacity: 0 !important; }

/* ==================== RESPONSIVE ==================== */
@media (max-width: 768px) {
    #voice-controls { bottom: 10px; gap: 6px; }
    .loading-content { min-width: 0; width: 90%; padding: var(--sp-xl) var(--sp-lg); }
    .brand-mark { font-size: 2.1rem; }
    .brand-tagline { font-size: 0.7rem; letter-spacing: 0.22em; }
    .auth-card { padding: var(--sp-xl) var(--sp-lg); }
    .auth-title { font-size: 1.6rem; }
    .voice-text, .cam-text, .screen-text, .chat-text { display: none; } /* icons only on mobile */
    .voice-btn { padding: 0.55rem 0.7rem; }
    .agora-tile { width: 130px; height: 84px; }
    .gradient-orb { filter: blur(64px); }
}

@media (max-width: 480px) {
    .brand-mark { font-size: 1.8rem; }
    #loading-percentage { font-size: 0.95rem; }
}

/* ==================== REDUCED MOTION ==================== */
/* Respect users who ask for less motion — disable the looping decorative anims. */
@media (prefers-reduced-motion: reduce) {
    .animated-bg::after,
    .animated-bg .stars,
    .animated-bg .stars2,
    .gradient-orb,
    .brand-veonary,
    #unity-build-title .brand-veonary,
    .auth-card::before,
    #unity-progress-bar-full,
    .loading-content::before,
    .loading-orbit::before,
    .loading-orbit::after,
    #unity-loading-bar.indeterminate #unity-progress-bar-full,
    .pulse-animation,
    .wave-bar,
    .voice-btn.active {
        animation: none !important;
    }
}
