/* ===================================================================
   ALI PLATFORM — Design System
   Theme: "Optical Verification Lab" — national certification meets
   precision optics. Ink-graphite surfaces, a brass/gold "seal" accent
   for authority, and a verifying teal/laser accent for scan + success
   states. Deliberately NOT purple-blue-glassmorphism.

   Tokens:
   --bg-*        ink/graphite depth layers
   --accent      brass/gold  — certification, seals, authority
   --accent-2    verify teal — scanning, confirmation, live state
   --radius*     soft-precision geometry (rounded but not bubbly)
   --shadow      long, low, "under glass on a lab bench" shadow
   --glass-*     lamination / laminated ID-card glass parameters
   =================================================================== */

:root {
    --bg-1: #07090d;
    --bg-2: #0d1116;
    --bg-3: #141a21;
    --surface: rgba(233, 238, 246, 0.045);
    --surface-strong: rgba(233, 238, 246, 0.09);
    --text: #eef1f6;
    --text-muted: #8b93a3;

    --accent: #d4af5a;           /* brass / certification seal */
    --accent-soft: #f2d896;
    --accent-2: #24e6c4;         /* verify teal / scan laser */
    --accent-2-soft: #8bf7e2;
    --accent-gradient: linear-gradient(120deg, #b5872f 0%, #e8c876 22%, #d4af5a 45%, #24e6c4 78%, #16b89c 100%);
    --accent-gradient-2: linear-gradient(120deg, #16b89c 0%, #24e6c4 40%, #d4af5a 100%);
    --accent-gradient-btn: linear-gradient(115deg, #dcb865 0%, #f2d896 30%, #d4af5a 55%, #3ff0d0 100%);

    --success: #35d999;
    --danger: #ff5c72;
    --warning: #e8b73c;

    --radius: 18px;
    --radius-sm: 12px;
    --shadow: 0 24px 70px rgba(0, 0, 0, 0.45);
    --transition: 0.28s cubic-bezier(0.22, 0.61, 0.36, 1);
    --transition-liquid: 0.55s cubic-bezier(0.34, 1.56, 0.64, 1);

    --glass-blur: 22px;
    --glass-border: rgba(233, 238, 246, 0.09);

    --led-speed: 4.2s;
}

@property --ali-angle {
    syntax: '<angle>';
    inherits: false;
    initial-value: 0deg;
}

* {
    box-sizing: border-box;
    -webkit-tap-highlight-color: transparent;
}

html, body {
    margin: 0;
    padding: 0;
    width: 100%;
    min-height: 100%;
    background: var(--bg-1);
    color: var(--text);
    font-family: 'Inter', 'Plus Jakarta Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
    font-size: 15px;
    line-height: 1.55;
    overflow-x: hidden;
}

/* Base atmosphere: ink gradient + fine "optical grid" ruling, reminiscent
   of a verification lab bench / precision instrument backdrop. */
body::before {
    content: '';
    position: fixed;
    inset: 0;
    z-index: -3;
    background:
        radial-gradient(circle at 12% 8%, rgba(212, 175, 90, 0.10), transparent 42%),
        radial-gradient(circle at 88% 84%, rgba(36, 230, 196, 0.08), transparent 45%),
        var(--bg-1);
}

body::after {
    content: '';
    position: fixed;
    inset: 0;
    z-index: -2;
    background-image:
        linear-gradient(rgba(233, 238, 246, 0.035) 1px, transparent 1px),
        linear-gradient(90deg, rgba(233, 238, 246, 0.035) 1px, transparent 1px);
    background-size: 34px 34px;
    mask-image: radial-gradient(ellipse 80% 70% at 50% 20%, #000 0%, transparent 75%);
    opacity: 0.6;
}

/* Filmic grain — a whisper of texture over everything so surfaces read
   as physical material rather than flat digital color. */
body {
    position: relative;
}

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

.ali-grain {
    position: fixed;
    inset: 0;
    z-index: 999;
    pointer-events: none;
    opacity: 0.035;
    mix-blend-mode: overlay;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* Canvas layer injected by effects.js — sits behind #app, produces the
   real-time metaball "liquid" ambience. Purely decorative & optional. */
#ali-metaball-canvas {
    position: fixed;
    inset: 0;
    z-index: -1;
    width: 100%;
    height: 100%;
    pointer-events: none;
    filter: blur(26px) contrast(24) saturate(1.15);
    opacity: 0.55;
    mix-blend-mode: screen;
}

@media (prefers-reduced-motion: reduce) {
    #ali-metaball-canvas { display: none; }
}

#app {
    max-width: 480px;
    margin: 0 auto;
    min-height: 100vh;
    position: relative;
}

@media (min-width: 1024px) {
    #app {
        max-width: 1200px;
        display: flex;
        flex-direction: column;
    }
}

/* ===================================================================
   SPLASH — cinematic 4-stage sequence
   Stage classes are toggled by effects.js on #splash:
   is-stage-1 (gather) -> is-stage-2 (liquid fill) ->
   is-stage-3 (flash)  -> is-stage-4 (light-reveal text)
   The original markup (.splash-logo / .splash-name / .splash-tagline)
   is preserved untouched; effects.js only injects sibling decoration
   layers and toggles classes/attributes.
   =================================================================== */
.splash {
    position: fixed;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    z-index: 1000;
    background: var(--bg-1);
    overflow: hidden;
    transition: opacity 0.6s ease, visibility 0.6s ease;
}

.splash.hidden {
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
}

/* Parallax depth layers injected by effects.js */
.splash-depth {
    position: absolute;
    inset: -10%;
    pointer-events: none;
}

.splash-layer-stars {
    background-image:
        radial-gradient(1px 1px at 12% 22%, rgba(255,255,255,.55), transparent 60%),
        radial-gradient(1px 1px at 78% 14%, rgba(255,255,255,.4), transparent 60%),
        radial-gradient(1.5px 1.5px at 34% 68%, rgba(255,255,255,.5), transparent 60%),
        radial-gradient(1px 1px at 62% 78%, rgba(255,255,255,.35), transparent 60%),
        radial-gradient(1.5px 1.5px at 88% 55%, rgba(255,255,255,.4), transparent 60%),
        radial-gradient(1px 1px at 20% 85%, rgba(255,255,255,.3), transparent 60%);
    animation: aliDrift 14s linear infinite;
    opacity: 0.7;
}

.splash-layer-fog {
    background:
        radial-gradient(ellipse 60% 40% at 50% 55%, rgba(36, 230, 196, 0.10), transparent 70%),
        radial-gradient(ellipse 50% 35% at 30% 30%, rgba(212, 175, 90, 0.08), transparent 70%);
    animation: aliFog 9s ease-in-out infinite;
}

.splash-layer-grid {
    background-image:
        linear-gradient(rgba(233, 238, 246, 0.05) 1px, transparent 1px),
        linear-gradient(90deg, rgba(233, 238, 246, 0.05) 1px, transparent 1px);
    background-size: 28px 28px;
    mask-image: radial-gradient(ellipse 70% 55% at 50% 55%, #000 0%, transparent 78%);
    opacity: 0;
}

.splash.is-stage-3 .splash-layer-grid,
.splash.is-stage-4 .splash-layer-grid {
    opacity: 0.5;
    animation: aliScan 2.4s linear infinite;
}

@keyframes aliDrift {
    from { transform: translate3d(0,0,0); }
    to   { transform: translate3d(-3%, -2%, 0); }
}

@keyframes aliFog {
    0%, 100% { transform: scale(1) translateY(0); opacity: 0.8; }
    50% { transform: scale(1.08) translateY(-2%); opacity: 1; }
}

@keyframes aliScan {
    0% { background-position: 0 0; }
    100% { background-position: 0 28px; }
}

/* Particle canvas for stage 1 (gather) + stage 2 (liquid fill) */
.splash-particles {
    position: absolute;
    inset: 0;
    z-index: 2;
    opacity: 0;
    transition: opacity 0.4s ease;
}

.splash.is-stage-1 .splash-particles,
.splash.is-stage-2 .splash-particles {
    opacity: 1;
}

/* Flash — stage 3 */
.splash-flash {
    position: absolute;
    inset: 0;
    z-index: 5;
    background: radial-gradient(circle at 50% 50%, rgba(255,255,255,0.95), rgba(47,224,194,0.4) 35%, transparent 70%);
    opacity: 0;
    pointer-events: none;
}

.splash.is-stage-3 .splash-flash {
    animation: aliFlash 0.45s cubic-bezier(0.16, 1, 0.3, 1) both;
}

@keyframes aliFlash {
    0% { opacity: 0; transform: scale(0.6); }
    35% { opacity: 1; transform: scale(1.3); }
    100% { opacity: 0; transform: scale(2.2); }
}

.splash.is-stage-3,
.splash.is-stage-4 {
    animation: aliCameraPulse 0.5s ease-out;
}

@keyframes aliCameraPulse {
    /* No `blur()` here anymore — blurring a full-screen fixed element
       forces the browser to re-rasterize that entire composited layer
       every frame, which is one of the most expensive things you can
       ask a phone's GPU to do, especially inside Telegram's embedded
       WebView. Combined with the particle canvas + letter reveal all
       animating at the same moment, that's what was reading as the
       splash "freezing" right when it opened on mobile. Brightness
       alone gives the same camera-flash punch for a fraction of the
       cost. */
    0% { filter: brightness(1); }
    30% { filter: brightness(1.5); }
    100% { filter: brightness(1); }
}

/* Emblem — the two <circle> rings from index.php had ZERO styling
   before this fix (no fill:none/stroke), so browsers rendered them
   with the SVG default (solid black fill) at the SVG's default
   intrinsic 300x150 box — that solid black blob was the "qora dog'"
   bug. Fixed + upgraded into a glowing dual-ring orbital frame that
   holds the ALI badge at its center. */
.splash-emblem {
    position: relative;
    z-index: 6;
    width: 168px;
    height: 168px;
    display: grid;
    place-items: center;
}

.splash-emblem svg {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    opacity: 0;
    transform: scale(0.55) rotate(-40deg);
    overflow: visible;
}

.splash.is-stage-1 .splash-emblem svg {
    animation: aliRingReveal 0.95s cubic-bezier(0.22, 0.61, 0.36, 1) forwards;
}

.splash.is-stage-2 .splash-emblem svg,
.splash.is-stage-3 .splash-emblem svg,
.splash.is-stage-4 .splash-emblem svg {
    opacity: 1;
    transform: scale(1) rotate(0deg);
}

@keyframes aliRingReveal {
    0% { opacity: 0; transform: scale(0.55) rotate(-40deg); }
    100% { opacity: 1; transform: scale(1) rotate(0deg); }
}

.emblem-ring {
    fill: none;
    stroke-width: 1.4;
    stroke-linecap: round;
    /* transform-origin is in the SVG's own viewBox units (0 0 100 100),
       so 50 50 already IS the circle's exact center with no extra
       reference-box needed. The previous `transform-box: fill-box`
       is inconsistently supported (notably inside Telegram's embedded
       WebView / older mobile Safari), and when unsupported the browser
       falls back to rotating around the SVG viewport's top-left corner
       instead of the ring's center — which is exactly what made the
       ring look like it was "swinging out" with half of it missing.
       Dropping fill-box and relying on the default (view-box) reference
       fixes that everywhere. */
    transform-origin: 50px 50px;
}

.emblem-ring.ring-outer {
    stroke: url(#emblem-grad);
    /* Full circle — this used to be a partial arc (stroke-dasharray:
       165 124, i.e. only ~57% of the ring actually drawn), which read
       as a broken/incomplete ring ("sirkular chiziqlar ... yarmi
       ko'rinmay qolyapdi"). A complete stroke still feels alive because
       the gradient itself sweeps around as it spins. */
    opacity: 0.9;
    filter: drop-shadow(0 0 6px rgba(36, 230, 196, 0.55));
    animation: aliRingSpin 7s linear infinite;
}

.emblem-ring:not(.ring-outer) {
    stroke: rgba(233, 238, 246, 0.35);
    stroke-dasharray: 3 9;
    animation: aliRingSpinReverse 11s linear infinite;
}

@keyframes aliRingSpin {
    to { transform: rotate(360deg); }
}

@keyframes aliRingSpinReverse {
    to { transform: rotate(-360deg); }
}

/* Two tiny orbiting sparks that revolve around the badge — pure CSS,
   attached to the emblem wrapper so they share its centre. */
.splash-emblem::before,
.splash-emblem::after {
    content: '';
    position: absolute;
    top: 50%;
    left: 50%;
    width: 6px;
    height: 6px;
    margin: -3px 0 0 -3px;
    border-radius: 50%;
    opacity: 0;
    background: var(--accent-2);
    box-shadow: 0 0 12px 3px rgba(36, 230, 196, 0.75);
}

.splash-emblem::after {
    background: var(--accent);
    box-shadow: 0 0 12px 3px rgba(212, 175, 90, 0.75);
}

.splash.is-stage-2 .splash-emblem::before,
.splash.is-stage-3 .splash-emblem::before,
.splash.is-stage-4 .splash-emblem::before {
    opacity: 1;
    animation: aliOrbit 3.4s linear infinite;
}

.splash.is-stage-2 .splash-emblem::after,
.splash.is-stage-3 .splash-emblem::after,
.splash.is-stage-4 .splash-emblem::after {
    opacity: 1;
    animation: aliOrbit 3.4s linear infinite reverse;
    animation-delay: -1.7s;
}

@keyframes aliOrbit {
    from { transform: rotate(0deg) translateX(78px) rotate(0deg); }
    to   { transform: rotate(360deg) translateX(78px) rotate(-360deg); }
}

.splash-logo {
    position: relative;
    z-index: 6;
    width: 96px;
    height: 96px;
    border-radius: 28px;
    overflow: hidden;
    background: var(--accent-gradient);
    display: grid;
    place-items: center;
    font-family: 'Plus Jakarta Sans', sans-serif;
    font-weight: 800;
    font-size: 34px;
    letter-spacing: -1px;
    color: #0b0d12;
    box-shadow: 0 20px 55px rgba(212, 175, 90, 0.35), 0 0 0 1px rgba(233,238,246,0.06);
    opacity: 0;
    transform: scale(0.3);
    filter: blur(6px);
}

.splash.is-stage-1 .splash-logo {
    animation: aliLogoGather 0.95s cubic-bezier(0.22, 0.61, 0.36, 1) forwards;
}

.splash.is-stage-2 .splash-logo,
.splash.is-stage-3 .splash-logo,
.splash.is-stage-4 .splash-logo {
    opacity: 1;
    transform: scale(1);
    filter: blur(0);
}

.splash.is-stage-2 .splash-logo {
    animation: aliLogoLiquid 0.85s cubic-bezier(0.34, 1.56, 0.64, 1) both,
               aliLogoPulse 2.6s ease-in-out 0.85s infinite;
}

/* Sheen sweep — a soft diagonal highlight that glides across the badge
   while it's "pouring" into shape, selling the liquid-metal feel
   without ever distorting the ALI wordmark itself (see aliLogoLiquid
   below: scale only, no skew — skewing sheared the letters and read
   as glitchy rather than liquid, hence the "2-chisi yaxshi emas"
   feedback). */
.splash-logo::before {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: inherit;
    background: linear-gradient(125deg, transparent 35%, rgba(255,255,255,0.65) 50%, transparent 65%);
    background-size: 220% 220%;
    opacity: 0;
    mix-blend-mode: overlay;
    pointer-events: none;
}

.splash.is-stage-2 .splash-logo::before {
    animation: aliLogoSheen 0.85s ease both;
}

@keyframes aliLogoSheen {
    0%   { opacity: 0; background-position: 130% 0%; }
    30%  { opacity: 1; }
    100% { opacity: 0; background-position: -30% 0%; }
}

.splash.is-stage-3 .splash-logo,
.splash.is-stage-4 .splash-logo {
    box-shadow: 0 0 0 2px var(--accent-2-soft), 0 0 40px rgba(36, 230, 194, 0.55), 0 20px 55px rgba(212, 175, 90, 0.35);
    animation: aliLogoPulse 2.6s ease-in-out infinite;
}

@keyframes aliLogoGather {
    0% { opacity: 0; transform: scale(0.15); filter: blur(10px); }
    70% { opacity: 1; transform: scale(1.12); filter: blur(0); }
    100% { opacity: 1; transform: scale(1); filter: blur(0); }
}

/* Liquid morph — scale-only (no skew) so the "ALI" wordmark stays
   crisp and legible the whole time; the organic feel comes entirely
   from the asymmetric border-radius easing through a soft blob shape
   and settling into the badge's rounded-square. */
@keyframes aliLogoLiquid {
    0%   { border-radius: 50%; transform: scale(0.92); }
    35%  { border-radius: 42% 58% 54% 46% / 52% 44% 56% 48%; transform: scale(1.1); }
    65%  { border-radius: 58% 42% 46% 54% / 44% 56% 44% 56%; transform: scale(0.97); }
    100% { border-radius: 28px; transform: scale(1); }
}

@keyframes aliLogoPulse {
    0%, 100% { box-shadow: 0 0 0 2px var(--accent-2-soft), 0 0 34px rgba(36, 230, 194, 0.4), 0 20px 55px rgba(212, 175, 90, 0.3); }
    50%      { box-shadow: 0 0 0 2px var(--accent-2-soft), 0 0 62px rgba(36, 230, 194, 0.8), 0 20px 65px rgba(212, 175, 90, 0.5); }
}

.splash-name {
    position: relative;
    z-index: 6;
    margin-top: 26px;
    font-family: 'Plus Jakarta Sans', sans-serif;
    font-weight: 700;
    font-size: 28px;
    perspective: 400px;
}

/* Per-letter cinematic reveal — each .char span carries a --i index
   (already present in index.php markup) used to stagger the delay and
   to sweep a teal -> gold hue across the word. */
.splash-name .char {
    display: inline-block;
    opacity: 0;
    transform: translateY(14px) rotateX(-52deg) scale(0.85);
    filter: blur(4px);
    transform-origin: 50% 100%;
    color: hsl(calc(172 - var(--i) * 9), 75%, 70%);
    text-shadow: 0 0 18px rgba(36, 230, 196, 0.35);
}

.splash.is-stage-4 .splash-name .char {
    animation: aliCharIn 0.55s cubic-bezier(0.22, 0.61, 0.36, 1) forwards;
    animation-delay: calc(var(--i) * 45ms);
}

@keyframes aliCharIn {
    to { opacity: 1; transform: translateY(0) rotateX(0deg) scale(1); filter: blur(0); }
}

/* Shine sweep that glides across the finished name once all letters
   have landed — the "premium" light-catch flourish. `screen` blend
   (instead of `overlay`) always lightens regardless of what's behind
   it, so on this dark background it reads as a clean bright streak
   rather than a muddy smear — the previous overlay blend is what made
   this stage look cheap ("4-chisi xunuk"). */
.splash-name::after {
    content: '';
    position: absolute;
    inset: -6px -14px;
    background: linear-gradient(100deg, transparent 35%, rgba(255,255,255,0.5) 50%, transparent 65%);
    background-size: 250% 100%;
    background-position: 150% 0;
    mix-blend-mode: screen;
    opacity: 0;
    pointer-events: none;
}

.splash.is-stage-4 .splash-name::after {
    animation: aliNameShine 1.1s ease 0.7s forwards;
}

@keyframes aliNameShine {
    0%   { opacity: 0; background-position: 150% 0; }
    15%  { opacity: 1; }
    60%  { opacity: 1; }
    100% { opacity: 0; background-position: -60% 0; }
}

.splash-tagline {
    position: relative;
    z-index: 6;
    margin-top: 8px;
    color: var(--text-muted);
    font-size: 15px;
    letter-spacing: 0.3px;
    opacity: 0;
}

.splash.is-stage-4 .splash-tagline {
    animation: fadeUp 0.6s 0.3s forwards;
}

/* Hamkor (ijarachi o'quv markaz) brend nomi — doiraviy ALI emblemasidan
   TASHQARIDA ko'rsatiladigan yorliq (qarang public/index.php ->
   .splash-partner, faqat .env PARTNER_BRAND_NAME to'ldirilganda
   chiqadi). Tagline'dan keyin, bir oz kechroq (0.5s) fade-up bilan
   kirib keladi — asosiy "ALI Platform" nomidan pastroq turadigan,
   ikkinchi darajali hamkorlik belgisi sifatida o'qiladi. */
.splash-partner {
    position: relative;
    z-index: 6;
    margin-top: 16px;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 7px 16px;
    border-radius: 999px;
    border: 1px solid rgba(212, 175, 90, 0.28);
    background: rgba(212, 175, 90, 0.07);
    backdrop-filter: blur(4px);
    opacity: 0;
}

.splash-partner-dot {
    width: 5px;
    height: 5px;
    border-radius: 50%;
    flex-shrink: 0;
    background: var(--accent-2);
    box-shadow: 0 0 8px 2px rgba(36, 230, 196, 0.7);
    animation: aliPartnerDotPulse 2.2s ease-in-out infinite;
}

@keyframes aliPartnerDotPulse {
    0%, 100% { opacity: 0.6; transform: scale(1); }
    50% { opacity: 1; transform: scale(1.3); }
}

.splash-partner-text {
    font-size: 12.5px;
    font-weight: 600;
    letter-spacing: 0.15px;
    color: var(--text-muted);
    white-space: nowrap;
}

.splash.is-stage-4 .splash-partner {
    animation: fadeUp 0.6s 0.5s forwards;
}

/* Loading indicator — thin track with a tri-color light sweeping
   through it, visible while stages 1-3 run, fading out once the
   final reveal (stage 4) lands. */
.splash-loader {
    position: relative;
    z-index: 6;
    margin-top: 34px;
    width: 130px;
    height: 3px;
    border-radius: 3px;
    background: rgba(233, 238, 246, 0.08);
    overflow: hidden;
    opacity: 0;
    transition: opacity 0.35s ease;
}

.splash.is-stage-1 .splash-loader,
.splash.is-stage-2 .splash-loader,
.splash.is-stage-3 .splash-loader {
    opacity: 1;
}

.splash-loader::after {
    content: '';
    position: absolute;
    inset: 0;
    width: 45%;
    border-radius: inherit;
    background: linear-gradient(90deg, transparent, var(--accent-2), var(--accent), transparent);
    animation: aliLoaderSweep 1.15s ease-in-out infinite;
}

@keyframes aliLoaderSweep {
    0%   { transform: translateX(-120%); }
    100% { transform: translateX(320%); }
}

/* The splash intentionally does NOT special-case
   prefers-reduced-motion: the phone and PC entrance must always be the
   exact same cinematic sequence — this OS-level preference is commonly
   switched on by battery-saver / "remove animations" modes on budget
   Android phones without the person ever choosing it, and having the
   phone show a different, shortened splash made it feel like a worse,
   different app entirely. */

/* Short viewports — landscape phones, small tablets in landscape, or
   any window under ~560px tall. The splash's stack (emblem + name +
   tagline + loader) is sized for portrait phones/desktop by default;
   on a short screen that stack can crowd the edges or seem cramped,
   which is part of what read as "3-chisi ekranga mos kelmayapdi". This
   scales the whole sequence down and tightens the vertical rhythm so
   it always sits comfortably centered, however short the screen is. */
@media (max-height: 560px) {
    .splash-emblem { width: 116px; height: 116px; }
    .splash-logo { width: 74px; height: 74px; font-size: 26px; border-radius: 22px; }
    .splash-name { margin-top: 14px; font-size: 22px; }
    .splash-tagline { margin-top: 6px; font-size: 13px; }
    .splash-loader { margin-top: 20px; }
}

@keyframes fadeUp {
    from { transform: translateY(16px); opacity: 0; }
    to { transform: translateY(0); opacity: 1; }
}

/* Glass — laminated ID-card surface: subtle top sheen + hairline edge */
.glass {
    position: relative;
    background: var(--surface);
    backdrop-filter: blur(var(--glass-blur));
    -webkit-backdrop-filter: blur(var(--glass-blur));
    border: 1px solid var(--glass-border);
    box-shadow:
        inset 0 1px 0 rgba(255,255,255,0.07),
        inset 0 -1px 0 rgba(0,0,0,0.25),
        0 1px 0 rgba(255,255,255,0.03);
}

.glass::before {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: inherit;
    background:
        linear-gradient(155deg, rgba(255,255,255,0.09) 0%, transparent 32%),
        radial-gradient(120% 60% at 15% -10%, rgba(255,255,255,0.06), transparent 60%);
    pointer-events: none;
}

/* Screens */
.screen {
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    /* "backwards" emas "both" ishlatilgan edi — bu animatsiya tugagach ham
       transform: translateY(0) elementda saqlanib qolishiga sabab bo'lgan.
       Hatto translateY(0) bo'lsa ham, transform qiymati element uchun YANGI
       containing block yaratadi — shuning uchun ichidagi position:fixed
       .bottom-nav butun ekranga emas, balki shu elementga (#app-screen)
       nisbatan joylashib qolgan va faqat sahifa oxirigacha pastga
       tushirilganda ko'rinar edi. "backwards" bilan boshlanish holati
       saqlanadi, lekin animatsiya tugagach transform butunlay olib
       tashlanadi (none), va bottom-nav haqiqatan ham butun ekranga
       nisbatan fixed bo'lib qoladi. */
    animation: screenIn 0.35s ease backwards;
}

.screen.hidden {
    display: none;
}

@keyframes screenIn {
    from { opacity: 0; transform: translateY(12px); }
    to { opacity: 1; transform: translateY(0); }
}

/* Auth */
#auth-screen {
    justify-content: center;
    padding: 24px;
}

.auth-card {
    width: 100%;
    padding: 28px;
    border-radius: var(--radius);
    box-shadow: var(--shadow);
}

/* Telefon ekranlarida login kartasi va uning ichidagi matn/tugma biroz
   kattaroq va bosilishi qulayroq bo'lsin — kenglik #app { max-width:480px }
   bilan cheklangani uchun bu yerda padding/shrift/tugma balandligini
   ko'tarish "kattaroq" his qildiradi (kartaning o'zi yon tomonlarga
   yoyilib ketmaydi, faqat proporsional jihatdan yiriklashadi). */
@media (max-width: 480px) {
    .auth-card {
        padding: 34px 24px;
    }
    .auth-card .brand-mark {
        width: 72px;
        height: 72px;
        font-size: 26px;
    }
    .auth-card h1,
    .auth-brand h1 {
        font-size: 26px;
    }
    .auth-brand p {
        font-size: 15px;
    }
    .auth-form .field input,
    .auth-form input[type="tel"],
    .auth-form input[type="text"] {
        padding: 16px 18px;
        font-size: 17px;
    }
    .auth-form .btn-primary {
        padding: 17px;
        font-size: 16px;
    }
}

/* Signature element: optical registration marks — four corner
   alignment brackets, evoking scanner calibration / verified
   document corners. Applied to auth-card and .card via utility class
   added purely in CSS (no HTML/JS dependency). */
.auth-card::after,
.card::after {
    content: '';
    position: absolute;
    inset: 8px;
    border-radius: calc(var(--radius) - 8px);
    pointer-events: none;
    background:
        linear-gradient(var(--accent-2-soft), var(--accent-2-soft)) top left / 10px 1.5px no-repeat,
        linear-gradient(var(--accent-2-soft), var(--accent-2-soft)) top left / 1.5px 10px no-repeat,
        linear-gradient(var(--accent-2-soft), var(--accent-2-soft)) top right / 10px 1.5px no-repeat,
        linear-gradient(var(--accent-2-soft), var(--accent-2-soft)) top right / 1.5px 10px no-repeat,
        linear-gradient(var(--accent-2-soft), var(--accent-2-soft)) bottom left / 10px 1.5px no-repeat,
        linear-gradient(var(--accent-2-soft), var(--accent-2-soft)) bottom left / 1.5px 10px no-repeat,
        linear-gradient(var(--accent-2-soft), var(--accent-2-soft)) bottom right / 10px 1.5px no-repeat,
        linear-gradient(var(--accent-2-soft), var(--accent-2-soft)) bottom right / 1.5px 10px no-repeat;
    opacity: 0.35;
    transition: opacity var(--transition);
}

.auth-card:hover::after,
.card:hover::after { opacity: 0.7; }

.auth-brand {
    text-align: center;
    margin-bottom: 28px;
}

.brand-mark {
    position: relative;
    width: 60px;
    height: 60px;
    margin: 0 auto 14px;
    border-radius: 18px;
    background: var(--accent-gradient);
    display: grid;
    place-items: center;
    font-family: 'Plus Jakarta Sans', sans-serif;
    font-weight: 800;
    font-size: 22px;
    color: #0b0d12;
}

/* Signature element: rotating calibration ring around the brand mark,
   like a camera aperture / optical scanner index. Pure CSS, continuous,
   GPU-friendly (conic-gradient border spun via @property angle). */
.brand-mark::before {
    content: '';
    position: absolute;
    inset: -6px;
    border-radius: inherit;
    padding: 1.5px;
    background: conic-gradient(from var(--ali-angle), transparent 0 78%, var(--accent-2-soft) 88%, transparent 100%);
    -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    -webkit-mask-composite: xor;
    mask-composite: exclude;
    animation: aliSpin 6s linear infinite;
}

@keyframes aliSpin {
    to { --ali-angle: 360deg; }
}

@media (prefers-reduced-motion: reduce) {
    .brand-mark::before { animation: none; }
}

.brand-mark.small {
    width: 40px;
    height: 40px;
    font-size: 14px;
    border-radius: 12px;
}

/* Header brand lockup — logo mark + wordmark + optional panel label,
   used in every app-header (student/teacher, admin, mini admin). The
   .brand-mark badge is a fixed-size square logo glyph; it was
   previously misused to hold long strings like "ALI · Kichkina admin"
   directly as its own text content, which wrapped and overlapped
   inside the tiny box and read as broken. Text now lives in its own
   flexible label next to the badge instead. */
.brand-lockup {
    display: flex;
    align-items: center;
    gap: 12px;
    min-width: 0;
}

.brand-lockup-text {
    display: flex;
    flex-direction: column;
    gap: 1px;
    min-width: 0;
}

.brand-lockup-title {
    font-family: 'Plus Jakarta Sans', sans-serif;
    font-weight: 800;
    font-size: 16px;
    letter-spacing: -0.3px;
    line-height: 1.2;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    background: var(--accent-gradient);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    color: var(--text);
}

.brand-lockup-subtitle {
    display: none;
    font-size: 11px;
    font-weight: 600;
    color: var(--text-muted);
    letter-spacing: 0.15px;
    line-height: 1.2;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* The teacher view of index.php reuses the student app shell and
   flips #app-screen to .is-teacher via app.js — the panel label is
   baked into the markup already and simply revealed here, no extra
   JS needed. Admin and mini admin each have their own dedicated page
   but share the same #admin-app-screen id, so one rule covers both;
   their subtitle text ("Asosiy admin paneli" / "Kichkina admin
   paneli") is set directly in each page's markup. */
#app-screen.is-teacher .brand-lockup-subtitle,
#admin-app-screen .brand-lockup-subtitle {
    display: block;
}

.auth-brand h1 {
    margin: 0;
    font-family: 'Plus Jakarta Sans', sans-serif;
    font-size: 25px;
    font-weight: 800;
    letter-spacing: -0.4px;
}

.auth-brand p {
    margin: 6px 0 0;
    color: var(--text-muted);
    font-size: 13px;
}

.auth-tabs {
    display: flex;
    gap: 8px;
    padding: 5px;
    background: rgba(233, 238, 246, 0.045);
    border-radius: 14px;
    margin-bottom: 22px;
}

.auth-tab {
    flex: 1;
    border: none;
    background: transparent;
    color: var(--text-muted);
    padding: 12px;
    border-radius: 10px;
    font-weight: 600;
    cursor: pointer;
    transition: var(--transition);
}

.auth-tab.active {
    background: rgba(233, 238, 246, 0.09);
    color: var(--text);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
}

.auth-form {
    display: flex;
    flex-direction: column;
    gap: 16px;
}

.field {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.field span {
    font-size: 12px;
    font-weight: 600;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.4px;
}

.field input,
.field select {
    width: 100%;
    padding: 14px 16px;
    border-radius: var(--radius-sm);
    border: 1px solid rgba(233, 238, 246, 0.1);
    background: rgba(0, 0, 0, 0.28);
    color: var(--text);
    font-size: 15px;
    outline: none;
    transition: var(--transition);
}

.field input:focus,
.field select:focus {
    border-color: var(--accent-2);
    box-shadow: 0 0 0 3px rgba(36, 230, 196, 0.18);
}

.field-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 12px;
}

/* ===================================================================
   LED LIQUID GLASS BUTTONS
   Continuous animated edge-light via conic-gradient + @property angle
   (true real-time motion, GPU-composited, no JS needed for the base
   loop). effects.js additionally tracks pointer position to move a
   soft "spotlight" bloom (--px/--py) and triggers a liquid wobble +
   light burst on press.
   =================================================================== */
.btn-primary {
    --px: 50%;
    --py: 50%;
    width: 100%;
    padding: 16px;
    border: none;
    border-radius: var(--radius-sm);
    background: var(--accent-gradient-btn);
    background-size: 180% 180%;
    color: #0b0d12;
    font-weight: 800;
    font-size: 15px;
    letter-spacing: 0.2px;
    cursor: pointer;
    position: relative;
    overflow: hidden;
    isolation: isolate;
    transition: transform 0.15s ease, box-shadow 0.25s ease, background-position 0.6s ease;
    box-shadow: 0 18px 42px rgba(212, 175, 90, 0.3), 0 4px 14px rgba(0,0,0,0.35);
}

.btn-primary:hover {
    background-position: 60% 40%;
}

/* rotating LED edge light */
.btn-primary::before,
.nav-item.active::before,
.auth-tab.active::before {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: inherit;
    padding: 1.5px;
    background: conic-gradient(from var(--ali-angle), transparent 0 60%, rgba(255,255,255,0.9) 72%, var(--accent-2-soft) 80%, transparent 92%);
    -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    -webkit-mask-composite: xor;
    mask-composite: exclude;
    animation: aliSpin var(--led-speed) linear infinite;
    pointer-events: none;
    z-index: 1;
}

/* cursor-tracking spotlight bloom (position set by effects.js) */
.btn-primary::after {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: inherit;
    background: radial-gradient(180px circle at var(--px) var(--py), rgba(255,255,255,0.35), transparent 60%);
    opacity: 0;
    transition: opacity 0.3s ease;
    pointer-events: none;
    z-index: 2;
}

.btn-primary:hover::after { opacity: 1; }

.btn-primary:hover {
    transform: translateY(-1px);
    box-shadow: 0 16px 38px rgba(212, 175, 90, 0.32), 0 0 24px rgba(36, 230, 196, 0.18);
}

.btn-primary:active {
    animation: aliLiquidPress var(--transition-liquid) both;
    box-shadow: 0 0 0 2px var(--accent-2-soft), 0 0 30px rgba(36, 230, 196, 0.5);
}

@keyframes aliLiquidPress {
    0% { border-radius: var(--radius-sm); transform: scale(1); }
    35% { border-radius: 46% 54% 60% 40% / 55% 45% 55% 45%; transform: scale(0.965); }
    65% { border-radius: 55% 45% 42% 58% / 45% 55% 45% 55%; transform: scale(1.01); }
    100% { border-radius: var(--radius-sm); transform: scale(1); }
}

.btn-primary:disabled {
    opacity: 0.7;
    cursor: not-allowed;
    transform: none;
    animation: none;
}

@media (prefers-reduced-motion: reduce) {
    .btn-primary::before, .nav-item.active::before, .auth-tab.active::before { animation: none; }
    .btn-primary:active { animation: none; }
}

.spinner {
    display: inline-block;
    width: 18px;
    height: 18px;
    border: 2px solid rgba(11, 13, 18, 0.35);
    border-top-color: #0b0d12;
    border-radius: 50%;
    animation: spin 0.8s linear infinite;
}

.spinner.hidden {
    display: none;
}

@keyframes spin {
    to { transform: rotate(360deg); }
}

.form-hint {
    text-align: center;
    color: var(--text-muted);
    font-size: 12px;
    margin: 0;
}

.code-section {
    animation: fadeUp 0.25s ease both;
}

/* App layout */
#app-screen {
    padding-bottom: 96px;
}

.app-header {
    position: sticky;
    top: 0;
    z-index: 100;
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 14px 20px;
    border-bottom: 1px solid rgba(233, 238, 246, 0.06);
}

/* thin scanning light-sweep across the header — subtle, continuous */
.app-header::after {
    content: '';
    position: absolute;
    left: 0; right: 0; bottom: -1px;
    height: 1px;
    background: linear-gradient(90deg, transparent, var(--accent-2-soft), transparent);
    opacity: 0.5;
    animation: aliHeaderSweep 5s ease-in-out infinite;
}

@keyframes aliHeaderSweep {
    0%, 100% { transform: translateX(-30%); opacity: 0; }
    50% { transform: translateX(30%); opacity: 0.6; }
}

@media (prefers-reduced-motion: reduce) {
    .app-header::after { animation: none; opacity: 0.25; }
}

.header-actions {
    display: flex;
    gap: 10px;
}

.icon-btn {
    width: 38px;
    height: 38px;
    border-radius: 12px;
    border: none;
    background: rgba(233, 238, 246, 0.06);
    color: var(--text);
    display: grid;
    place-items: center;
    cursor: pointer;
    transition: var(--transition);
}

.icon-btn:hover {
    background: rgba(233, 238, 246, 0.12);
    color: var(--accent-2);
}

/* Bildirishnoma qo'ng'irog'i (student panel, "Chiqish" tugmasi yonida) */
.notif-btn {
    position: relative;
}

.notif-badge {
    position: absolute;
    top: -4px;
    right: -4px;
    min-width: 17px;
    height: 17px;
    padding: 0 4px;
    border-radius: 999px;
    background: linear-gradient(120deg, #ff5c72, #ff8a65);
    color: #fff;
    font-size: 10px;
    font-weight: 800;
    line-height: 17px;
    text-align: center;
    box-shadow: 0 0 0 2px var(--bg, #05060b), 0 2px 8px rgba(255, 92, 114, 0.5);
    animation: notifPulse 1.8s ease-in-out infinite;
}

.notif-badge.hidden { display: none; }

@keyframes notifPulse {
    0%, 100% { transform: scale(1); }
    50% { transform: scale(1.12); }
}

@media (prefers-reduced-motion: reduce) {
    .notif-badge { animation: none; }
}

.notif-overlay { align-items: flex-start; padding-top: 12vh; }

.notif-modal {
    max-width: 420px;
    padding: 20px;
}

.notif-list {
    display: flex;
    flex-direction: column;
    gap: 10px;
    max-height: 60vh;
    overflow-y: auto;
    padding-right: 2px;
}

.notif-item {
    position: relative;
    padding: 12px 14px 12px 16px;
    border-radius: var(--radius-sm);
    background: rgba(233, 238, 246, 0.04);
    border: 1px solid rgba(233, 238, 246, 0.08);
    animation: fadeUp 0.25s ease both;
}

.notif-item::before {
    content: '';
    position: absolute;
    left: 0; top: 10px; bottom: 10px;
    width: 3px;
    border-radius: 3px;
    background: transparent;
}

.notif-item.is-unread::before {
    background: var(--accent-gradient);
    box-shadow: 0 0 10px rgba(212, 175, 90, 0.5);
}

.notif-item-text {
    font-size: 14px;
    line-height: 1.5;
    color: var(--text);
    white-space: pre-wrap;
    word-break: break-word;
}

.notif-item-date {
    margin-top: 6px;
    font-size: 11px;
    color: var(--text-muted);
}

/* Banner */
.banner {
    position: relative;
    margin: 16px;
    border-radius: var(--radius);
    overflow: hidden;
    min-height: 150px;
    background: var(--bg-3);
    animation: fadeUp 0.4s ease both;
}

.banner.hidden {
    display: none;
}

.banner img {
    width: 100%;
    height: 180px;
    object-fit: cover;
    display: block;
}

.banner-overlay {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    padding: 18px;
    background: linear-gradient(to top, rgba(0,0,0,0.78), transparent 70%);
}

.banner-logo {
    width: 36px;
    height: 36px;
    border-radius: 10px;
    background: var(--accent-gradient);
    margin-bottom: 8px;
}

.banner-text {
    font-weight: 700;
    font-size: 16px;
    text-shadow: 0 2px 10px rgba(0,0,0,0.4);
}

/* Content */
.content {
    padding: 8px 16px 24px;
    flex: 1;
}

.section {
    animation: fadeUp 0.3s ease both;
}

.section-title {
    position: relative;
    display: flex;
    align-items: center;
    gap: 10px;
    font-family: 'Plus Jakarta Sans', sans-serif;
    font-size: 24px;
    font-weight: 800;
    letter-spacing: -0.4px;
    margin: 0 0 18px;
    animation: fadeUp 0.35s ease both;
}

.section-title::before {
    content: '';
    display: inline-block;
    width: 5px;
    height: 22px;
    border-radius: 3px;
    background: var(--accent-gradient);
    box-shadow: 0 0 12px rgba(36, 230, 196, 0.35);
}

.section-subtitle {
    color: var(--text-muted);
    font-size: 13px;
    margin: -12px 0 18px;
}

/* Cards */
.card {
    position: relative;
    background: var(--surface);
    border: 1px solid rgba(233, 238, 246, 0.08);
    border-radius: var(--radius);
    padding: 18px;
    margin-bottom: 14px;
    transition: var(--transition), border-color 0.25s ease;
    animation: fadeUp 0.35s ease both;
}

.card:hover {
    transform: translateY(-2px);
    border-color: rgba(233, 238, 246, 0.16);
    box-shadow: 0 14px 34px rgba(0, 0, 0, 0.35);
}

.card:active {
    transform: scale(0.99);
}

.group-pick-card {
    cursor: pointer;
}

.card-title {
    font-weight: 700;
    margin: 0 0 6px;
}

.card-title-btn {
    display: block;
    width: 100%;
    text-align: left;
    background: none;
    border: none;
    padding: 0;
    margin: 0 0 10px;
    font-weight: 700;
    font-size: 15px;
    color: var(--text);
    cursor: pointer;
    font-family: inherit;
}

.card-title-btn:hover { color: var(--accent-2); }

.toggle-hint {
    font-weight: 400;
    font-size: 12px;
    color: var(--text-muted);
    margin-left: 6px;
}

.btn-primary-sm {
    padding: 8px 14px;
    border-radius: var(--radius-sm);
    border: none;
    background: var(--accent-gradient-btn);
    color: #0b0d12;
    font-weight: 700;
    font-size: 12px;
    cursor: pointer;
    white-space: nowrap;
}

.card-meta {
    color: var(--text-muted);
    font-size: 13px;
}

/* Profile */
.profile-header {
    display: flex;
    align-items: center;
    gap: 18px;
    margin-bottom: 22px;
}

/* Avatar wrapper: rotating conic "verified" ring around the photo,
   reusing the same @property angle spin technique as .brand-mark so
   the whole app feels like one consistent visual language. */
.profile-header {
    position: relative;
}

.profile-photo,
.profile-photo-placeholder {
    position: relative;
    z-index: 1;
    /* .profile-header — bu flex qator. Agar bu doiraga flex-shrink:0
       berilmasa, ism uzun bo'lganda yoki guruhlar ro'yxati ko'payganda
       (profile-group-list) flexbox uni faqat eniga siqib qo'yadi —
       balandligi o'zgarmay qoladi va doira ovalga aylanadi. Shuning
       uchun o'lchamini qat'iy qulflaymiz: enini ham, bo'yini ham
       hech qachon 86px'dan kichik yoki katta bo'lmasin. */
    flex-shrink: 0;
    flex-grow: 0;
    min-width: 86px;
    min-height: 86px;
    max-width: 86px;
    max-height: 86px;
}

.profile-header::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    width: 86px;
    height: 86px;
    border-radius: 50%;
    padding: 2.5px;
    background: conic-gradient(from var(--ali-angle), transparent 0 65%, var(--accent-2-soft) 82%, var(--accent) 92%, transparent 100%);
    -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    -webkit-mask-composite: xor;
    mask-composite: exclude;
    animation: aliSpin 5s linear infinite;
    pointer-events: none;
    /* Yuqoridagi flex-shrink qulfi bilan bir xil sababdan: bu halqa
       ham doimo 86x86 aylana bo'lib qolishi, ovalga ozib ketmasligi
       kerak — u fotosurat/inisiallar doirasi bilan bir xil chiziqda
       yuradi. */
    flex-shrink: 0;
}

.profile-photo {
    width: 86px;
    height: 86px;
    border-radius: 50%;
    object-fit: cover;
    border: 3px solid var(--bg-1);
    background: var(--bg-3);
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
    transition: var(--transition);
    flex-shrink: 0;
}

.profile-photo-placeholder {
    width: 86px;
    height: 86px;
    border-radius: 50%;
    background: var(--accent-gradient);
    display: grid;
    place-items: center;
    font-size: 28px;
    font-weight: 700;
    color: #0b0d12;
    border: 3px solid var(--bg-1);
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
    flex-shrink: 0;
}

.profile-photo:hover {
    transform: scale(1.04);
}

.profile-name {
    font-family: 'Plus Jakarta Sans', sans-serif;
    font-size: 21px;
    font-weight: 800;
    letter-spacing: -0.3px;
    margin: 0;
    background: linear-gradient(100deg, var(--text) 20%, #fff 45%, var(--text) 70%);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
}

.profile-group-list {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 8px;
}

.profile-group-list .profile-group {
    margin-top: 0;
}

.profile-group {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    color: var(--accent-2);
    font-weight: 600;
    font-size: 12.5px;
    margin-top: 8px;
    padding: 4px 10px 4px 8px;
    border-radius: 999px;
    background: rgba(36, 230, 196, 0.1);
    border: 1px solid rgba(36, 230, 196, 0.25);
}

.profile-group::before {
    content: '';
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--accent-2);
    box-shadow: 0 0 6px 1px rgba(36, 230, 196, 0.8);
}

.profile-grid {
    display: grid;
    gap: 10px;
}

.profile-row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 12px;
    padding: 13px 16px;
    background: rgba(233, 238, 246, 0.035);
    border: 1px solid rgba(233, 238, 246, 0.05);
    border-radius: var(--radius-sm);
    transition: var(--transition), border-color 0.25s ease;
    animation: fadeUp 0.35s ease both;
}

.profile-grid .profile-row:nth-child(1) { animation-delay: 0.03s; }
.profile-grid .profile-row:nth-child(2) { animation-delay: 0.08s; }
.profile-grid .profile-row:nth-child(3) { animation-delay: 0.13s; }
.profile-grid .profile-row:nth-child(4) { animation-delay: 0.18s; }
.profile-grid .profile-row:nth-child(5) { animation-delay: 0.23s; }

.profile-row:hover {
    background: rgba(233, 238, 246, 0.06);
    border-color: rgba(233, 238, 246, 0.12);
}

/* "{brand_name} — Bilan hamkorlikda" banner (Profilim, "Otasining
   ismi" dan tepada) — bosilganda rasmiy Telegram kanaliga olib boradi.
   Boshqa profile-row'lar bilan bir xil radius/joylashuvda, lekin brend
   gradienti va yaltiroq border bilan ajralib turadi. */
.school-official-row {
    position: relative;
    padding: 15px 16px;
    text-decoration: none;
    color: inherit;
    cursor: pointer;
    background:
        linear-gradient(rgba(10, 14, 20, 0.88), rgba(10, 14, 20, 0.88)) padding-box,
        var(--accent-gradient) border-box;
    border: 1px solid transparent;
    border-radius: var(--radius-sm);
    overflow: hidden;
    isolation: isolate;
}

.school-official-row::before {
    content: '';
    position: absolute;
    inset: 0;
    z-index: -1;
    background: linear-gradient(120deg, rgba(212, 175, 90, 0.16), rgba(36, 230, 196, 0.1) 60%, transparent 100%);
    opacity: 0.9;
    transition: opacity 0.25s ease;
}

.school-official-row:hover {
    background:
        linear-gradient(rgba(10, 14, 20, 0.78), rgba(10, 14, 20, 0.78)) padding-box,
        var(--accent-gradient) border-box;
    transform: translateY(-1px);
    box-shadow: 0 10px 26px rgba(212, 175, 90, 0.18), 0 4px 18px rgba(36, 230, 196, 0.14);
}

.school-official-row:hover::before {
    opacity: 1;
}

.school-official-row:active {
    transform: translateY(0);
}

.school-official-icon {
    background: var(--accent-gradient);
    color: #0a0e14;
}

.school-official-text {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}

.school-official-title {
    font-weight: 800;
    font-size: 14.5px;
    letter-spacing: 0.2px;
    background: var(--accent-gradient);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
}

.school-official-subtitle {
    font-size: 12px;
    color: var(--text-muted);
}

.school-official-arrow {
    flex-shrink: 0;
    width: 28px;
    height: 28px;
    background: rgba(233, 238, 246, 0.06);
    color: var(--accent-2);
    transition: transform 0.25s ease, background 0.25s ease;
}

.school-official-row:hover .school-official-arrow {
    transform: translateX(3px);
    background: rgba(36, 230, 196, 0.14);
}

.profile-row .row-left {
    display: flex;
    align-items: center;
    gap: 12px;
    min-width: 0;
}

.profile-row .row-icon {
    flex-shrink: 0;
    width: 34px;
    height: 34px;
    border-radius: 10px;
    display: grid;
    place-items: center;
    background: rgba(36, 230, 196, 0.08);
    color: var(--accent-2);
}

.profile-row .label {
    color: var(--text-muted);
    font-size: 13px;
}

.profile-row .value {
    font-weight: 600;
    text-align: right;
    white-space: nowrap;
}

.photo-upload {
    margin-top: 16px;
}

.photo-upload input {
    display: none;
}

.photo-upload label {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 12px;
    border-radius: var(--radius-sm);
    border: 1px dashed rgba(233, 238, 246, 0.22);
    color: var(--text-muted);
    font-weight: 600;
    font-size: 13.5px;
    cursor: pointer;
    transition: var(--transition), background 0.25s ease;
}

.photo-upload label:hover {
    border-color: var(--accent-2);
    color: var(--text);
    background: rgba(36, 230, 196, 0.06);
}

.photo-upload label:hover svg {
    color: var(--accent-2);
}

/* Empty state */
.empty-state {
    text-align: center;
    padding: 40px 20px;
    color: var(--text-muted);
}

.empty-state svg {
    margin-bottom: 14px;
    opacity: 0.6;
}

/* Assignment questions */
.question-card {
    margin-bottom: 16px;
    padding: 18px;
    background: var(--surface);
    border-radius: var(--radius);
    border: 1px solid rgba(233, 238, 246, 0.08);
}

.question-number {
    display: inline-block;
    padding: 4px 10px;
    border-radius: 20px;
    background: var(--accent-gradient);
    color: #0b0d12;
    font-size: 12px;
    font-weight: 700;
    margin-bottom: 10px;
}

.question-text {
    font-weight: 600;
    margin-bottom: 14px;
    line-height: 1.6;
}

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

.option {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 14px;
    border-radius: var(--radius-sm);
    background: rgba(0, 0, 0, 0.22);
    border: 1px solid rgba(233, 238, 246, 0.06);
    cursor: pointer;
    transition: var(--transition);
}

.option:hover {
    border-color: rgba(36, 230, 196, 0.4);
}

.option input {
    accent-color: var(--accent-2);
    width: 18px;
    height: 18px;
    flex-shrink: 0;
}

.option.selected {
    border-color: var(--accent-2);
    background: rgba(36, 230, 196, 0.1);
}

/* Ranking */

/* "TOP 10" yorlig'i — podium ustida, oltin gradient matn va ikki
   tomonidagi ingichka chiziqlar bilan. */
.ranking-top-label {
    display: flex;
    align-items: center;
    gap: 10px;
    margin: 4px 0 16px;
    font-size: 12px;
    font-weight: 800;
    letter-spacing: 0.09em;
    text-transform: uppercase;
}

.ranking-top-label span {
    background: var(--accent-gradient);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
    white-space: nowrap;
}

.ranking-top-label::before,
.ranking-top-label::after {
    content: '';
    flex: 1;
    height: 1px;
    background: linear-gradient(90deg, transparent, rgba(212, 175, 90, 0.45), transparent);
}

/* Podium — 1—3 o'rinlar uchun, eng ko'zga tashlanadigan taqdimot.
   Markazdagi (1-o'rin) slot kattaroq va tepasida sekin "suzuvchi" tojcha
   animatsiyasi bilan. */
.podium {
    display: flex;
    align-items: flex-end;
    justify-content: center;
    gap: 10px;
    padding: 30px 4px 22px;
    margin-bottom: 8px;
}

.podium-slot {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    flex: 1;
    min-width: 0;
    max-width: 130px;
    padding: 20px 8px 16px;
    background: var(--surface);
    border: 1px solid rgba(233, 238, 246, 0.08);
    border-radius: var(--radius);
    animation: podiumRise 0.5s cubic-bezier(0.22, 0.61, 0.36, 1) both;
}

.podium-second { order: 1; padding-bottom: 12px; }
.podium-first  { order: 2; padding-top: 30px; padding-bottom: 24px; z-index: 1;
    background: linear-gradient(160deg, rgba(212, 175, 90, 0.2), rgba(36, 230, 196, 0.06));
    border-color: rgba(212, 175, 90, 0.4);
    box-shadow: 0 16px 44px rgba(212, 175, 90, 0.18);
}
.podium-third  { order: 3; padding-bottom: 8px; }

.podium-second, .podium-third { align-self: flex-end; }

.podium-slot:nth-of-type(1) { animation-delay: 0.08s; }
.podium-slot:nth-of-type(2) { animation-delay: 0s; }
.podium-slot:nth-of-type(3) { animation-delay: 0.16s; }

@keyframes podiumRise {
    from { opacity: 0; transform: translateY(18px); }
    to { opacity: 1; transform: translateY(0); }
}

.podium-crown {
    position: absolute;
    top: -24px;
    font-size: 26px;
    filter: drop-shadow(0 4px 10px rgba(212, 175, 90, 0.55));
    animation: crownFloat 2.4s ease-in-out infinite;
}

@keyframes crownFloat {
    0%, 100% { transform: translateY(0) rotate(-4deg); }
    50% { transform: translateY(-5px) rotate(4deg); }
}

.podium-avatar-wrap {
    position: relative;
    margin-bottom: 10px;
}

.podium-avatar {
    width: 54px;
    height: 54px;
    border-radius: 50%;
    object-fit: cover;
    background: var(--bg-3);
    border: 3px solid var(--accent);
    display: block;
}

.podium-first .podium-avatar {
    width: 74px;
    height: 74px;
    border-color: var(--accent-soft);
    box-shadow: 0 0 0 4px rgba(212, 175, 90, 0.22);
}

.podium-second .podium-avatar { border-color: #d1d5db; }
.podium-third .podium-avatar { border-color: var(--accent); }

.podium-medal {
    position: absolute;
    bottom: -2px;
    right: -2px;
    width: 22px;
    height: 22px;
    border-radius: 50%;
    display: grid;
    place-items: center;
    font-size: 11px;
    font-weight: 800;
    color: var(--bg-1);
    background: var(--accent-gradient);
    border: 2px solid var(--bg-2);
}

.podium-name {
    font-weight: 700;
    font-size: 13px;
    max-width: 100%;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.podium-first .podium-name { font-size: 14.5px; }

.podium-score {
    margin-top: 3px;
    font-size: 11px;
    font-weight: 600;
    color: var(--text-muted);
}

.podium-first .podium-score { color: var(--accent-soft); }

.podium-you-badge { margin-top: 8px; }

.podium-self {
    border-color: var(--accent-2);
    box-shadow: 0 0 0 2px rgba(36, 230, 196, 0.18);
}

/* 4—10-o'rinlar — oddiy qatordan yulduzcha nishon, kuchliroq oltin
   gradient fon va yumshoq porlash (glow) bilan ajralib turadi. */
.ranking-list-top10 { margin-bottom: 12px; }

.ranking-item-top10 {
    position: relative;
    background: linear-gradient(100deg, rgba(212, 175, 90, 0.14), rgba(36, 230, 196, 0.05));
    border-color: rgba(212, 175, 90, 0.4);
    box-shadow: 0 10px 28px rgba(212, 175, 90, 0.14);
}

.ranking-item-top10::before {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: var(--radius);
    padding: 1px;
    background: linear-gradient(120deg, rgba(212, 175, 90, 0.6), rgba(36, 230, 196, 0.25) 60%, transparent 90%);
    -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    -webkit-mask-composite: xor;
    mask-composite: exclude;
    pointer-events: none;
}

/* Kartaning yuqori-o'ng burchagida osilib turgan kichik yulduzcha —
   4—10-o'rinlarni ro'yxatda birinchi qarashda ajratib beradi. */
.ranking-item-top10-star {
    position: absolute;
    top: -9px;
    right: 14px;
    font-size: 15px;
    line-height: 1;
    filter: drop-shadow(0 2px 5px rgba(212, 175, 90, 0.65));
    animation: starTwinkle 2.6s ease-in-out infinite;
    pointer-events: none;
}

@keyframes starTwinkle {
    0%, 100% { transform: scale(1) rotate(0deg); opacity: 1; }
    50% { transform: scale(1.15) rotate(-8deg); opacity: 0.85; }
}

.rank-badge-top10 {
    background: var(--accent-gradient);
    color: var(--bg-1);
    box-shadow: 0 0 0 3px rgba(212, 175, 90, 0.16);
}

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

.ranking-item {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 14px;
    background: var(--surface);
    border-radius: var(--radius);
    border: 1px solid rgba(233, 238, 246, 0.08);
    animation: listReveal 0.35s ease both;
}

.ranking-item:nth-child(1) { animation-delay: 0.05s; }
.ranking-item:nth-child(2) { animation-delay: 0.1s; }
.ranking-item:nth-child(3) { animation-delay: 0.15s; }
.ranking-item:nth-child(4) { animation-delay: 0.2s; }

@keyframes listReveal {
    from { opacity: 0; transform: translateX(-10px); }
    to { opacity: 1; transform: translateX(0); }
}

.rank-badge {
    width: 34px;
    height: 34px;
    border-radius: 50%;
    display: grid;
    place-items: center;
    font-weight: 800;
    font-size: 13px;
    background: rgba(233,238,246,0.08);
    flex-shrink: 0;
}

.rank-badge.gold { background: rgba(232, 183, 60, 0.18); color: var(--warning); }
.rank-badge.silver { background: rgba(200, 200, 200, 0.15); color: #d1d5db; }
.rank-badge.bronze { background: rgba(212, 175, 90, 0.15); color: var(--accent); }

.ranking-photo {
    width: 44px;
    height: 44px;
    border-radius: 50%;
    object-fit: cover;
    background: var(--bg-3);
    flex-shrink: 0;
}

.ranking-info {
    flex: 1;
    min-width: 0;
}

.ranking-name {
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.ranking-count {
    font-size: 12px;
    color: var(--text-muted);
}

.ranking-item.ranking-item-self {
    border-color: var(--accent);
    background: rgba(126, 116, 246, 0.08);
}

.ranking-you-badge {
    font-size: 11px;
    font-weight: 700;
    color: var(--accent);
    background: rgba(126, 116, 246, 0.15);
    padding: 3px 8px;
    border-radius: 999px;
    flex-shrink: 0;
}

/* Attendance */
.attendance-list {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.attendance-item {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 14px 16px;
    background: var(--surface);
    border-radius: var(--radius-sm);
    border: 1px solid rgba(233, 238, 246, 0.08);
}

.attendance-date {
    font-weight: 600;
}

.attendance-nav-row {
    display: flex;
    justify-content: space-between;
    gap: 8px;
    margin-top: 12px;
}

.attendance-nav-row .btn-secondary {
    flex: 1;
}

.attendance-nav-row .btn-secondary:disabled {
    opacity: 0.4;
    cursor: not-allowed;
}

.attendance-meta-row {
    margin-top: 4px;
}

.attendance-meta-row .attendance-status {
    padding: 3px 10px;
    font-size: 11px;
}

.attendance-weekday {
    font-size: 12px;
    color: var(--text-muted);
}

.attendance-status {
    padding: 6px 12px;
    border-radius: 20px;
    font-size: 12px;
    font-weight: 700;
    text-transform: uppercase;
}

.status-present { background: rgba(53, 217, 153, 0.15); color: var(--success); }
.status-absent { background: rgba(255, 92, 114, 0.15); color: var(--danger); }
.status-late { background: rgba(232, 183, 60, 0.15); color: var(--warning); }
.status-excused { background: rgba(36, 230, 196, 0.15); color: var(--accent-2); }
.status-unknown { background: rgba(233,238,246,0.08); color: var(--text-muted); }

.attendance-week-nav {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 14px;
    margin-top: 18px;
    padding-top: 14px;
    border-top: 1px solid rgba(233, 238, 246, 0.08);
}

.attendance-week-btn {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 9px 16px;
    border-radius: 999px;
    border: 1px solid rgba(233, 238, 246, 0.14);
    background: var(--surface);
    color: var(--text);
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
    transition: border-color .15s ease, background .15s ease, color .15s ease, transform .15s ease;
}

.attendance-week-btn:hover:not(:disabled) {
    border-color: var(--accent-2);
    color: var(--accent-2);
    transform: translateY(-1px);
}

.attendance-week-btn:active:not(:disabled) {
    transform: translateY(0);
}

.attendance-week-btn:disabled {
    opacity: 0.35;
    cursor: not-allowed;
}

.attendance-week-label {
    min-width: 96px;
    text-align: center;
    font-size: 12px;
    font-weight: 600;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: .03em;
}

/* ---------------------------------------------------------------------
   Shared month calendar (calendar.js) — used by Student "Davomatim" and
   Teacher "Davomot topshirish". A row of every date in the month sits at
   the top; lesson days are marked separately (gold ring + dot); once an
   attendance result is known for a lesson day it's shown right there too
   (green = bor / red = yoʻq).
--------------------------------------------------------------------- */
.cal-widget {
    background: var(--surface);
    border: 1px solid rgba(233, 238, 246, 0.08);
    border-radius: var(--radius-sm);
    padding: 16px;
}

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

.cal-title {
    font-weight: 700;
    font-size: 15px;
    font-family: 'Plus Jakarta Sans', sans-serif;
}

.cal-nav-btn {
    width: 32px;
    height: 32px;
    border-radius: 50%;
    border: 1px solid rgba(233, 238, 246, 0.12);
    background: transparent;
    color: var(--text);
    font-size: 18px;
    line-height: 1;
    cursor: pointer;
    transition: var(--transition);
}

.cal-nav-btn:hover { background: var(--surface-strong); }

.cal-weekdays {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: 4px;
    margin-bottom: 6px;
}

.cal-weekday {
    text-align: center;
    font-size: 11px;
    font-weight: 700;
    color: var(--text-muted);
    text-transform: uppercase;
}

.cal-grid {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: 4px;
}

.cal-day {
    position: relative;
    aspect-ratio: 1 / 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 2px;
    border-radius: 10px;
    border: 1px solid transparent;
    background: transparent;
    color: var(--text-muted);
    font-size: 12px;
    cursor: default;
    padding: 0;
}

.cal-day.cal-empty { visibility: hidden; }

.cal-daynum { font-weight: 600; }

.cal-day.cal-lesson {
    color: var(--text);
    border-color: rgba(212, 175, 90, 0.4);
    background: rgba(212, 175, 90, 0.08);
}

.cal-day.cal-upcoming {
    border-style: dashed;
    color: var(--text-muted);
}

.cal-day.cal-today { box-shadow: 0 0 0 2px var(--accent-2) inset; }

.cal-day.cal-selected {
    border-color: var(--accent-2);
    background: rgba(36, 230, 196, 0.16);
}

.cal-day.cal-clickable { cursor: pointer; }
.cal-day.cal-clickable:hover { background: rgba(212, 175, 90, 0.18); }

.cal-dot {
    width: 5px;
    height: 5px;
    border-radius: 50%;
    background: var(--accent);
}

.cal-day.cal-present .cal-dot { background: var(--success); }
.cal-day.cal-absent .cal-dot { background: var(--danger); }
.cal-day.cal-late .cal-dot { background: var(--warning); }
.cal-day.cal-excused .cal-dot { background: var(--accent-2); }
.cal-day.cal-present { border-color: rgba(53, 217, 153, 0.45); background: rgba(53, 217, 153, 0.1); }
.cal-day.cal-absent { border-color: rgba(255, 92, 114, 0.45); background: rgba(255, 92, 114, 0.1); }
.cal-day.cal-late { border-color: rgba(232, 183, 60, 0.45); background: rgba(232, 183, 60, 0.1); }
.cal-day.cal-excused { border-color: rgba(36, 230, 196, 0.45); background: rgba(36, 230, 196, 0.1); }

.cal-legend {
    display: flex;
    flex-wrap: wrap;
    gap: 14px;
    margin-top: 14px;
    padding-top: 12px;
    border-top: 1px solid rgba(233, 238, 246, 0.08);
}

.cal-legend-item {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 12px;
    color: var(--text-muted);
}

.cal-legend-dot {
    width: 9px;
    height: 9px;
    border-radius: 50%;
    display: inline-block;
}

.cal-legend-lesson { background: var(--accent); }
.cal-legend-present { background: var(--success); }
.cal-legend-absent { background: var(--danger); }
.cal-legend-late { background: var(--warning); }
.cal-legend-excused { background: var(--accent-2); }

/* Kichraytirilgan kalendar — faqat oʻqituvchi panelidagi "Davomot
   topshirish" boʻlimida ishlatiladi (public/assets/js/teacher.js,
   #att-calendar container). Talaba/admin tomonidagi kalendar bunga
   taalluqli emas, chunki .cal-widget bazaviy stili oʻzgartirilmagan. */
.cal-compact {
    max-width: 300px;
    margin: 0 auto;
}

.cal-compact .cal-widget { padding: 10px; }
.cal-compact .cal-header { margin-bottom: 8px; }
.cal-compact .cal-title { font-size: 13px; }
.cal-compact .cal-nav-btn { width: 24px; height: 24px; font-size: 14px; }
.cal-compact .cal-weekdays { gap: 3px; margin-bottom: 4px; }
.cal-compact .cal-weekday { font-size: 9px; }
.cal-compact .cal-grid { gap: 3px; }
.cal-compact .cal-day { font-size: 10px; border-radius: 7px; gap: 1px; }
.cal-compact .cal-dot { width: 4px; height: 4px; }
.cal-compact .cal-legend { gap: 8px; margin-top: 8px; padding-top: 8px; }
.cal-compact .cal-legend-item { font-size: 10px; }
.cal-compact .cal-legend-dot { width: 7px; height: 7px; }

/* Bottom nav — floating glass pill (Telegram-style) */
.bottom-nav {
    position: fixed;
    left: 12px;
    right: 12px;
    bottom: max(12px, env(safe-area-inset-bottom));
    z-index: 100;
    display: flex;
    justify-content: space-around;
    align-items: center;
    gap: 2px;
    padding: 8px;
    border-radius: 999px;
    background: var(--surface-strong);
    backdrop-filter: blur(var(--glass-blur));
    -webkit-backdrop-filter: blur(var(--glass-blur));
    border: 1px solid var(--glass-border);
    box-shadow: var(--shadow);
    animation: fadeUp 0.35s ease both;
}

/* Bo'limlar soni ekran eniga sig'maydigan bo'lib qolganda (masalan 7+
   bo'lim), panel torayib/harflar maydalashib ketish o'rniga — gorizontal
   suriladigan (scrollable) qatorga aylanadi. Har bir tugma o'z tabiiy
   o'lchamida qoladi (flex-shrink: 0), shu sabab hech narsa siqilmaydi
   yoki mayda bo'lib qolmaydi — shunchaki qatorni suriysiz. Faqat
   telefon kengligida kerak: >=1024px'da nav sidebar'ga aylanadi va
   vertikal yo'nalishda joy yetarli. */
@media (max-width: 1023px) {
    .bottom-nav {
        justify-content: flex-start;
        overflow-x: auto;
        overflow-y: hidden;
        -webkit-overflow-scrolling: touch;
        scroll-snap-type: x proximity;
        scrollbar-width: none;
        -ms-overflow-style: none;
        /* Chekkalarda tugmalar birdan "kesilib" qolmasdan, asta-sekin
           xiralashib ko'rinishi — bu vizual ishora: "bu yerda yana
           bo'limlar bor, suring". */
        mask-image: linear-gradient(to right, transparent 0, black 20px, black calc(100% - 20px), transparent 100%);
        -webkit-mask-image: linear-gradient(to right, transparent 0, black 20px, black calc(100% - 20px), transparent 100%);
    }

    .bottom-nav::-webkit-scrollbar {
        display: none;
    }

    .bottom-nav .nav-item {
        flex: 0 0 auto;
        min-width: 68px;
        scroll-snap-align: center;
    }
}

/* Klaviatura ochiq paytda (input/textarea fokusda) vaqtincha yashirish —
   qarang public/assets/js/app.js dagi focusin/focusout handlerlari. Faqat
   telefon kengligida kerak: katta ekranda (sidebar rejimi) klaviatura
   muammosi yoʻq, shuning uchun bu yerda ham cheklab qoʻyilgan. */
@media (max-width: 1023px) {
    .bottom-nav.kb-hidden {
        display: none;
    }
}

@media (min-width: 1024px) {
    .bottom-nav {
        position: fixed;
        left: 0;
        top: 0;
        bottom: 0;
        right: auto;
        width: 240px;
        flex-direction: column;
        justify-content: flex-start;
        padding: 24px;
        gap: 8px;
        align-items: stretch;
        border-radius: 0;
        /* Sidebar endi ham "laminated glass" ko'rinishida — mobil pastki
           menyu bilan bir xil vizual til: xira shisha fon, yumshoq soya,
           va oʻng chetda gold->teal gradient chiziq. Avval bular butunlay
           oʻchirilgan edi, shu sabab PC'da tekis va sifatsiz koʻrinar edi. */
        background: linear-gradient(180deg, var(--surface-strong), var(--surface));
        backdrop-filter: blur(var(--glass-blur));
        -webkit-backdrop-filter: blur(var(--glass-blur));
        box-shadow: 12px 0 40px rgba(0, 0, 0, 0.35);
        border: none;
        border-right: 1px solid var(--glass-border);
        /* Bo'limlar soni ko'payib (endi 7 ta), juda past bo'yli
           oynalarda barchasi tik sig'may qolishi mumkin — shu holatda
           panelning o'zi (overflow yashirin bo'lgan tashqi sidebar
           emas, faqat shu ro'yxat) vertikal suriladi, hech qanday
           tugma ekrandan tashqarida "yo'qolib" qolmaydi.
        */
        overflow-y: auto;
        scrollbar-width: none;
        -ms-overflow-style: none;
    }

    .bottom-nav::-webkit-scrollbar {
        display: none;
    }

    .bottom-nav::after {
        content: '';
        position: absolute;
        top: 0;
        right: -1px;
        bottom: 0;
        width: 1px;
        background: linear-gradient(180deg, transparent, var(--accent-2-soft) 35%, var(--accent) 70%, transparent);
        opacity: 0.55;
    }

    .nav-item {
        justify-content: flex-start;
        padding: 14px 16px;
        gap: 12px;
    }

    .nav-item span { display: inline; }

    #app-screen {
        padding-left: 240px;
        padding-bottom: 0;
    }

    .app-header {
        left: 240px;
    }

    .banner, .content {
        margin-left: 24px;
        margin-right: 24px;
    }
}

.nav-item {
    position: relative;
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
    border: none;
    background: transparent;
    color: var(--text-muted);
    font-size: 11px;
    font-weight: 600;
    padding: 6px;
    cursor: pointer;
    border-radius: 14px;
    overflow: hidden;
    transition: var(--transition);
}

.nav-item svg {
    transition: var(--transition);
}

.nav-item.active,
.nav-item:hover {
    color: var(--text);
    background: rgba(233, 238, 246, 0.06);
}

.nav-item.active svg {
    color: var(--accent-2);
    filter: drop-shadow(0 0 6px rgba(36, 230, 196, 0.55));
    transform: translateY(-1px) scale(1.08);
}

.nav-item.active {
    box-shadow: 0 0 22px rgba(36, 230, 196, 0.12);
}

.nav-item.active::after {
    content: '';
    position: absolute;
    bottom: 2px;
    left: 50%;
    width: 4px;
    height: 4px;
    border-radius: 50%;
    background: var(--accent-2);
    box-shadow: 0 0 6px 1px rgba(36, 230, 196, 0.8);
    animation: navDotIn 0.3s cubic-bezier(0.34, 1.56, 0.64, 1) both;
}

@keyframes navDotIn {
    from { opacity: 0; transform: translateX(-50%) scale(0); }
    to   { opacity: 1; transform: translateX(-50%) scale(1); }
}

.nav-item:active {
    transform: scale(0.94);
}

/* Chat tabidagi "nechta yangi xabar bor" belgisi — .notif-badge bilan
   bir xil vizual til, faqat ikonka burchagiga joylashtirilgan.
   .nav-item'ning overflow:hidden'i (active holatdagi orqa fon
   effektlari uchun) shu belgini kesib qo'ymasligi uchun
   .nav-item-chat'da overflow qaytadan visible qilinadi. */
.nav-item-chat {
    overflow: visible;
}

.nav-badge {
    position: absolute;
    top: 2px;
    left: 50%;
    margin-left: 2px;
    min-width: 16px;
    height: 16px;
    padding: 0 4px;
    border-radius: 999px;
    background: linear-gradient(120deg, #ff5c72, #ff8a65);
    color: #fff;
    font-size: 10px;
    font-weight: 800;
    line-height: 16px;
    text-align: center;
    box-shadow: 0 0 0 2px var(--bg-2, #0a0c14), 0 2px 8px rgba(255, 92, 114, 0.5);
    animation: notifPulse 1.8s ease-in-out infinite;
}

.nav-badge.hidden { display: none; }

@media (prefers-reduced-motion: reduce) {
    .nav-badge { animation: none; }
}

/* "Profilim" — endi pastki navigatsiyada emas, tepadagi sarlavha
   qatorida (bildirishnomalar qo'ng'irog'i yonida) turadi. Markup
   soddaligi uchun u ham .nav-item klassidan foydalanadi (shu bir xil
   JS navigatsiya kodi — currentSection almashtirish, .active belgisi —
   qayta yozilmasdan ishlab ketaveradi), lekin vizual ko'rinishi butunlay
   boshqacha: pastdagi ustunsimon icon+label o'rniga, .icon-btn'larga
   o'xshash ixcham gorizontal pastki (pill) tugma. */
.header-profile-btn {
    flex: 0 0 auto;
    flex-direction: row;
    width: auto;
    height: 38px;
    padding: 0 14px 0 10px;
    gap: 7px;
    border-radius: 999px;
    background: rgba(233, 238, 246, 0.06);
    color: var(--text-muted);
    font-size: 13px;
    font-weight: 700;
    overflow: visible;
}

.header-profile-btn span {
    display: inline;
}

.header-profile-btn svg {
    width: 18px;
    height: 18px;
    flex-shrink: 0;
}

.header-profile-btn:hover {
    background: rgba(233, 238, 246, 0.12);
    color: var(--text);
}

.header-profile-btn.active {
    background: var(--accent-gradient);
    color: #0b0d12;
    box-shadow: 0 4px 16px rgba(36, 230, 196, 0.3);
}

.header-profile-btn.active svg {
    color: #0b0d12;
    filter: none;
    transform: none;
}

/* Bosh sahifadagi umumiy .nav-item.active::after nuqtachasi (pastki
   navigatsiya uchun mo'ljallangan) bu yerda kerak emas. */
.header-profile-btn.active::after {
    content: none;
}

/* O'qituvchi paneli endi shu bir xil #app-screen ichida
   #app-screen.is-teacher orqali render qilinadi (u o'zining alohida
   Profil bo'limiga ega, TeacherPanel.mount() orqali) — shu sabab
   sarlavhadagi o'quvchi-ga xos "Profilim" tugmasi o'qituvchi
   rejimida ko'rinmasligi kerak. */
#app-screen.is-teacher .header-profile-btn {
    display: none;
}

@media (max-width: 380px) {
    /* Juda tor ekranlarda "Profilim" so'zi qo'ng'iroq va chiqish
       tugmalari bilan sig'may qolmasligi uchun faqat ikonka qoladi. */
    .header-profile-btn span {
        display: none;
    }
    .header-profile-btn {
        padding: 0 10px;
        gap: 0;
    }
}

/* Toast */
.toast {
    position: fixed;
    bottom: 92px;
    left: 50%;
    transform: translateX(-50%);
    z-index: 1001;
    padding: 12px 20px;
    border-radius: 30px;
    background: var(--bg-3);
    color: var(--text);
    font-weight: 600;
    box-shadow: var(--shadow);
    border: 1px solid rgba(233, 238, 246, 0.08);
    opacity: 1;
    transition: opacity 0.3s ease, transform 0.3s ease;
    max-width: 90%;
    text-align: center;
}

.toast.hidden {
    opacity: 0;
    transform: translateX(-50%) translateY(10px);
    pointer-events: none;
}

.toast.error {
    background: rgba(255, 92, 114, 0.15);
    color: var(--danger);
    border-color: rgba(255, 92, 114, 0.25);
}

.toast.success {
    background: rgba(53, 217, 153, 0.15);
    color: var(--success);
    border-color: rgba(53, 217, 153, 0.25);
}

/* Utilities */
.hidden { display: none !important; }
.text-center { text-align: center; }
.mt-2 { margin-top: 12px; }

/* Scrollbar */
::-webkit-scrollbar { width: 6px; }
::-webkit-scrollbar-thumb { background: rgba(233,238,246,0.12); border-radius: 6px; }
::-webkit-scrollbar-track { background: transparent; }

/* ===================================================================
   Teacher Panel (Part 2) — reuses the design tokens defined in :root
   =================================================================== */

.app-screen.is-teacher,
#app-screen.is-teacher {
    padding-left: 0;
}

.teacher-tabs {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
    gap: 10px;
    padding: 12px 20px;
}

.teacher-tab {
    display: flex;
    align-items: center;
    justify-content: center;
    text-align: center;
    min-height: 64px;
    padding: 12px 14px;
    border-radius: 14px;
    border: 1px solid rgba(233, 238, 246, 0.08);
    background: var(--surface);
    color: var(--text-muted);
    font-size: 13px;
    font-weight: 600;
    line-height: 1.3;
    cursor: pointer;
    transition: var(--transition);
}

.teacher-tab:hover { color: var(--text); border-color: rgba(233,238,246,0.18); transform: translateY(-2px); }

.teacher-tab.active {
    background: var(--accent-gradient);
    color: #0b0d12;
    border-color: transparent;
    box-shadow: 0 8px 24px rgba(212, 175, 90, 0.3);
}

/* "Chat" tabi ustidagi qizil belgi — nechta yangi (o'qilmagan) xabar
   bor, .notif-badge bilan bir xil vizual til. Qarang
   public/assets/js/teacher.js -> refreshChatBadge() / renderChat(). */
.teacher-tab {
    position: relative;
}
.teacher-tab-badge {
    position: absolute;
    top: -6px;
    right: -6px;
    min-width: 18px;
    height: 18px;
    padding: 0 5px;
    border-radius: 999px;
    background: linear-gradient(120deg, #ff5c72, #ff8a65);
    color: #fff;
    font-size: 10.5px;
    font-weight: 800;
    line-height: 18px;
    text-align: center;
    box-shadow: 0 0 0 2px var(--bg-1, #05060b), 0 2px 8px rgba(255, 92, 114, 0.5);
    animation: notifPulse 1.8s ease-in-out infinite;
}
.teacher-tab-badge.hidden { display: none; }

/* Guruh-tanlagich kartochkalaridagi belgi (Chat -> guruh tanlash
   ekrani) — bitta kartochka bosilishi mumkin bo'lgani uchun cursor va
   position:relative ham shu yerda beriladi. */
.chat-group-pick-card {
    cursor: pointer;
    position: relative;
}
.chat-group-pick-badge {
    position: absolute;
    top: 10px;
    right: 10px;
}

/* Oʻqituvchi yozgan xabar tepasidagi kichkina yorliq — oʻquvchi
   tomonidagi bir xil chatda kimning oʻqituvchi ekanini ajratib
   turadi. Qarang public/assets/js/teacher.js -> chatBubbleHtml() /
   public/assets/js/app.js -> chatBubbleHtml(). */
.chat-bubble-role-tag {
    display: inline-block;
    margin-left: 6px;
    padding: 1px 7px;
    border-radius: 999px;
    background: rgba(212, 175, 90, 0.18);
    color: var(--accent-2);
    font-size: 9.5px;
    font-weight: 800;
    letter-spacing: 0.02em;
    text-transform: uppercase;
    vertical-align: middle;
}

@media (min-width: 640px) {
    .teacher-tabs { grid-template-columns: repeat(auto-fill, minmax(170px, 1fr)); }
}

.teacher-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: 14px;
    padding: 0 20px 24px;
}

.teacher-group-card { padding: 18px; }

.period-toggle {
    display: flex;
    gap: 8px;
    margin-top: 14px;
    flex-wrap: wrap;
}

.period-btn {
    flex: 1;
    min-width: 140px;
    padding: 10px 14px;
    border-radius: 12px;
    border: 1px solid rgba(233, 238, 246, 0.08);
    background: var(--surface);
    color: var(--text-muted);
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
    transition: var(--transition);
}

.period-btn:hover { color: var(--text); border-color: rgba(233,238,246,0.18); }

.period-btn.active {
    background: var(--accent-gradient);
    color: #0b0d12;
    border-color: transparent;
    box-shadow: 0 8px 24px rgba(212, 175, 90, 0.3);
}

.teacher-card {
    margin: 0 20px 20px;
    padding: 20px;
}

.assignment-block {
    border: 1px solid rgba(233, 238, 246, 0.08);
    border-radius: var(--radius-sm);
    padding: 14px;
    margin-bottom: 14px;
    background: rgba(233, 238, 246, 0.02);
}

.assignment-block-title {
    font-weight: 700;
    margin-bottom: 8px;
    color: var(--accent-2);
}

.btn-secondary {
    padding: 10px 18px;
    border-radius: var(--radius-sm);
    border: 1px solid rgba(233, 238, 246, 0.12);
    background: var(--surface);
    color: var(--text);
    font-weight: 600;
    font-size: 13px;
    cursor: pointer;
    transition: var(--transition);
    text-decoration: none;
}

.btn-secondary:hover { border-color: var(--accent-2); color: var(--accent-2); }

.btn-danger-sm {
    padding: 8px 14px;
    border-radius: var(--radius-sm);
    border: 1px solid rgba(255, 92, 114, 0.35);
    background: rgba(255, 92, 114, 0.08);
    color: var(--danger);
    font-weight: 600;
    font-size: 12px;
    cursor: pointer;
    transition: var(--transition);
}

.btn-danger-sm:hover { background: rgba(255, 92, 114, 0.18); }

.btn-secondary-sm {
    padding: 8px 14px;
    border-radius: var(--radius-sm);
    border: 1px solid var(--border);
    background: transparent;
    color: var(--text-muted);
    font-weight: 600;
    font-size: 12px;
    cursor: pointer;
    transition: var(--transition);
    white-space: nowrap;
}

.btn-secondary-sm:hover { border-color: var(--accent-2); color: var(--accent-2); }

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

.found-user-row {
    align-items: flex-start;
    gap: 12px;
}

.form-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 12px;
}

.form-group {
    display: flex;
    flex-direction: column;
    gap: 6px;
    margin-bottom: 14px;
}

.form-group label {
    font-size: 12px;
    font-weight: 600;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.4px;
}

.field-hint {
    font-size: 12px;
    color: var(--text-muted);
    font-weight: 400;
    text-transform: none;
    letter-spacing: normal;
}

.form-group input,
.form-group select,
.form-group textarea {
    width: 100%;
    padding: 14px 16px;
    border-radius: var(--radius-sm);
    border: 1px solid rgba(233, 238, 246, 0.1);
    background: rgba(0, 0, 0, 0.28);
    color: var(--text);
    font-size: 15px;
    outline: none;
    transition: var(--transition);
    font-family: inherit;
}

.form-group input:focus,
.form-group select:focus,
.form-group textarea:focus {
    border-color: var(--accent-2);
    box-shadow: 0 0 0 3px rgba(36, 230, 196, 0.18);
}

.form-group input[type="file"] {
    padding: 10px;
}

.question-editor-list {
    display: flex;
    flex-direction: column;
    gap: 10px;
    max-height: 460px;
    overflow-y: auto;
    padding-right: 6px;
}

.question-editor-row {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 10px 12px;
    border-radius: var(--radius-sm);
    background: rgba(233, 238, 246, 0.03);
}

.qe-num {
    flex: 0 0 32px;
    font-weight: 700;
    color: var(--text-muted);
}

.qe-options {
    display: flex;
    gap: 8px;
}

.qe-option {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    border-radius: 10px;
    border: 1px solid rgba(233, 238, 246, 0.12);
    cursor: pointer;
    font-weight: 700;
    font-size: 12px;
}

.qe-option input { display: none; }

.qe-option.correct {
    background: var(--accent-gradient);
    border-color: transparent;
    color: #0b0d12;
}

.qe-open-answer {
    flex: 1;
    padding: 8px 12px;
    border-radius: var(--radius-sm);
    border: 1px solid rgba(233, 238, 246, 0.12);
    background: var(--bg-2);
    color: var(--text);
}

.open-answer-input {
    width: 100%;
    padding: 12px 14px;
    border-radius: var(--radius-sm);
    border: 1px solid rgba(233, 238, 246, 0.12);
    background: var(--bg-2);
    color: var(--text);
    font-size: 14px;
}

.weekday-picker {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

.weekday-chip {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 8px 12px;
    border-radius: 999px;
    border: 1px solid rgba(233, 238, 246, 0.1);
    cursor: pointer;
    font-size: 13px;
}

.weekday-chip input:checked + span { color: var(--accent-2); font-weight: 700; }

.att-toggle-btn {
    padding: 6px 16px;
    border-radius: 20px;
    font-size: 12px;
    font-weight: 700;
    text-transform: uppercase;
    border: 1px solid rgba(233, 238, 246, 0.14);
    cursor: pointer;
    transition: var(--transition);
    background: rgba(233,238,246,0.08);
    color: var(--text-muted);
}

.att-toggle-btn.status-present { background: rgba(53, 217, 153, 0.15); color: var(--success); border-color: rgba(53, 217, 153, 0.4); }
.att-toggle-btn.status-absent { background: rgba(255, 92, 114, 0.15); color: var(--danger); border-color: rgba(255, 92, 114, 0.4); }
.att-toggle-btn.status-late { background: rgba(232, 183, 60, 0.15); color: var(--warning); border-color: rgba(232, 183, 60, 0.4); }
.att-toggle-btn.status-excused { background: rgba(36, 230, 196, 0.15); color: var(--accent-2); border-color: rgba(36, 230, 196, 0.4); }

.attendance-table-wrap { overflow-x: auto; margin-top: 12px; }

.attendance-table {
    border-collapse: collapse;
    width: 100%;
    font-size: 13px;
}

.attendance-table th,
.attendance-table td {
    padding: 8px 10px;
    text-align: center;
    border-bottom: 1px solid rgba(233, 238, 246, 0.06);
    white-space: nowrap;
}

.attendance-table th:first-child,
.attendance-table td:first-child {
    text-align: left;
    position: sticky;
    left: 0;
    background: var(--bg-2);
}

.att-cell {
    width: 32px;
    height: 32px;
    border-radius: 8px;
    border: 1px solid rgba(233, 238, 246, 0.12);
    background: transparent;
    color: var(--success);
    cursor: pointer;
    font-size: 14px;
}

.att-cell.present {
    background: rgba(53, 217, 153, 0.15);
    border-color: var(--success);
}

.results-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 14px;
}

.results-table th, .results-table td {
    padding: 10px 12px;
    text-align: left;
    border-bottom: 1px solid rgba(233, 238, 246, 0.06);
}

.badge-success, .badge-muted {
    display: inline-block;
    font-size: 12px;
    font-weight: 600;
    padding: 2px 10px;
    border-radius: 999px;
    vertical-align: middle;
}

.badge-success {
    color: var(--success);
    background: rgba(53, 217, 153, 0.15);
}

.badge-muted {
    color: var(--text-muted, #9aa4b2);
    background: rgba(233, 238, 246, 0.08);
}

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

.admin-list-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 12px 14px;
    border-radius: var(--radius-sm);
    background: rgba(233, 238, 246, 0.03);
}

.admin-list-name { font-weight: 600; }
.admin-list-meta { font-size: 12px; color: var(--text-muted); }

/* ---- Natijalar: bosiladigan oʻquvchi katakchasi + batafsil modal ---- */
.res-student-cell {
    cursor: pointer;
}

.res-student-cell:hover .res-student-name {
    text-decoration: underline;
    color: var(--accent-2);
}

.res-student-id {
    display: inline-block;
    font-size: 11px;
    font-weight: 700;
    color: var(--accent);
    background: rgba(212, 175, 90, 0.12);
    border: 1px solid rgba(212, 175, 90, 0.3);
    border-radius: 999px;
    padding: 2px 8px;
    margin-right: 8px;
    letter-spacing: 0.02em;
    white-space: nowrap;
}

.res-student-name {
    font-weight: 500;
}

.res-modal-overlay {
    position: fixed;
    inset: 0;
    background: rgba(4, 6, 9, 0.72);
    backdrop-filter: blur(4px);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 1200;
    padding: 24px;
}

.res-modal {
    position: relative;
    width: 100%;
    max-width: 640px;
    max-height: 84vh;
    overflow-y: auto;
    background: var(--bg-3);
    border: 1px solid rgba(233, 238, 246, 0.08);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    padding: 24px;
}

.res-modal-close {
    position: absolute;
    top: 14px;
    right: 14px;
    width: 32px;
    height: 32px;
    border-radius: 50%;
    border: 1px solid rgba(233, 238, 246, 0.12);
    background: rgba(233, 238, 246, 0.05);
    color: var(--text);
    font-size: 18px;
    line-height: 1;
    cursor: pointer;
}

.res-modal-header {
    margin-bottom: 16px;
    padding-right: 32px;
}

.res-modal-header .card-title {
    display: flex;
    align-items: center;
    gap: 8px;
}

.res-modal-body {
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.res-q-block {
    border: 1px solid rgba(233, 238, 246, 0.08);
    border-radius: var(--radius-sm);
    padding: 12px 14px;
    background: rgba(233, 238, 246, 0.03);
}

.res-q-block.q-correct { border-color: rgba(53, 217, 153, 0.35); }
.res-q-block.q-wrong { border-color: rgba(255, 92, 114, 0.35); }

.res-q-title {
    font-weight: 600;
    font-size: 14px;
    margin-bottom: 8px;
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 8px;
}

.res-q-badge {
    font-size: 11px;
    font-weight: 700;
    white-space: nowrap;
}

.res-q-block.q-correct .res-q-badge { color: var(--success); }
.res-q-block.q-wrong .res-q-badge { color: var(--danger); }

.res-q-options {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.res-q-option {
    font-size: 13px;
    padding: 6px 10px;
    border-radius: 8px;
    background: rgba(233, 238, 246, 0.03);
    border: 1px solid transparent;
}

.res-q-option.correct {
    border-color: rgba(53, 217, 153, 0.5);
    color: var(--success);
    background: rgba(53, 217, 153, 0.1);
}

.res-q-option.wrong {
    border-color: rgba(255, 92, 114, 0.5);
    color: var(--danger);
    background: rgba(255, 92, 114, 0.1);
}

.res-q-chosen {
    font-weight: 400;
    opacity: 0.8;
}

.res-q-answer {
    font-size: 13px;
}
.res-q-answer.correct { color: var(--success); }
.res-q-answer.wrong { color: var(--danger); }

.res-q-correct {
    font-size: 13px;
    color: var(--text-muted);
    margin-top: 4px;
}
/* ------------------------------------------------------------------
   "Chat" boʻlimi (oʻquvchi paneli, pastki navigatsiya) — guruhning
   umumiy yozishmasi, Telegram guruh chatiga oʻxshab qilingan: ora-orada
   "olib qoʻyilgan" chuqurlashtirilgan panel, guruh belgisi bilan
   sarlavha, oʻzining "xabar hovuzi" foni, "✓ / ✓✓" oʻqilganlik
   belgilari va xabarni bosib "kimlar oʻqidi" roʻyxatini koʻrsatuvchi
   popup. Qarang: public/assets/js/app.js -> renderChat() / chatBubbleHtml()
   / showChatReaders().
   ------------------------------------------------------------------ */
.chat-section {
    display: flex;
    flex-direction: column;
    height: calc(100dvh - 220px);
    min-height: 360px;
    margin: -4px -4px 0;
    border-radius: var(--radius);
    border: 1px solid var(--glass-border);
    background:
        radial-gradient(ellipse 620px 340px at 12% -6%, rgba(212, 175, 90, 0.10), transparent 60%),
        radial-gradient(ellipse 560px 420px at 108% 18%, rgba(36, 230, 196, 0.09), transparent 55%),
        radial-gradient(ellipse 500px 500px at 50% 120%, rgba(212, 175, 90, 0.06), transparent 60%),
        var(--bg-2);
    box-shadow: var(--shadow);
    overflow: hidden;
}

.chat-header {
    display: flex;
    align-items: center;
    gap: 11px;
    flex: none;
    padding: 12px 14px;
    background: rgba(20, 26, 33, 0.72);
    backdrop-filter: blur(var(--glass-blur));
    border-bottom: 1px solid var(--glass-border);
    position: relative;
}
.chat-header::after {
    content: '';
    position: absolute;
    left: 0; right: 0; bottom: -1px;
    height: 1px;
    background: linear-gradient(90deg, transparent, var(--accent-2-soft), transparent);
    opacity: 0.4;
    animation: aliHeaderSweep 5s ease-in-out infinite;
}

.chat-back-btn {
    width: 32px;
    height: 32px;
    border-radius: 50%;
    border: none;
    background: transparent;
    color: var(--text);
    font-size: 22px;
    line-height: 1;
    display: grid;
    place-items: center;
    cursor: pointer;
    flex: none;
    transition: var(--transition);
}
.chat-back-btn:hover { background: var(--surface); }
.chat-back-btn:active { transform: scale(0.9); }

.chat-header-avatar {
    width: 38px;
    height: 38px;
    border-radius: 50%;
    flex: none;
    display: grid;
    place-items: center;
    background: var(--accent-gradient);
    color: #1a1200;
    font-size: 13px;
    font-weight: 800;
    letter-spacing: 0.02em;
}

.chat-header-text {
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 1px;
}

.chat-header-title {
    font-family: 'Plus Jakarta Sans', sans-serif;
    font-size: 16px;
    font-weight: 700;
    color: var(--text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.chat-header-subtitle {
    font-size: 11.5px;
    color: var(--text-muted);
    display: flex;
    align-items: center;
    gap: 5px;
}
.chat-header-subtitle::before {
    content: '';
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--success);
    box-shadow: 0 0 6px rgba(53, 217, 153, 0.7);
    flex: none;
}

.chat-messages {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: 3px;
    padding: 14px 12px 14px;
    scroll-behavior: smooth;
    -webkit-overflow-scrolling: touch;
}
.chat-messages::-webkit-scrollbar { width: 5px; }
.chat-messages::-webkit-scrollbar-thumb { background: var(--surface-strong); border-radius: 999px; }

.chat-bubble-row {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-top: 7px;
    animation: fadeUp 0.22s ease both;
}
.chat-bubble-row.is-mine {
    flex-direction: row-reverse;
}
.chat-bubble-row > .chat-avatar,
.chat-bubble-row > .chat-avatar-fallback {
    align-self: flex-end;
}

.chat-avatar {
    width: 28px;
    height: 28px;
    border-radius: 50%;
    flex: none;
    object-fit: cover;
    border: 1px solid var(--glass-border);
    margin-bottom: 1px;
}

.chat-avatar-fallback {
    width: 28px;
    height: 28px;
    border-radius: 50%;
    flex: none;
    display: grid;
    place-items: center;
    background: var(--accent-gradient);
    color: #1a1200;
    font-size: 10.5px;
    font-weight: 800;
    margin-bottom: 1px;
}

.chat-bubble {
    position: relative;
    max-width: 76%;
    padding: 8px 12px 6px;
    border-radius: 17px;
    font-size: 14.5px;
    line-height: 1.42;
    word-wrap: break-word;
    overflow-wrap: anywhere;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.28);
}

.chat-bubble-row:not(.is-mine) .chat-bubble {
    background: var(--surface-strong);
    border: 1px solid var(--glass-border);
    border-bottom-left-radius: 4px;
    color: var(--text);
}

.chat-bubble-row.is-mine .chat-bubble {
    background: var(--accent-gradient-btn);
    color: #1a1200;
    border-bottom-right-radius: 4px;
    cursor: pointer;
    transition: filter var(--transition), transform 0.12s ease;
}
.chat-bubble-row.is-mine .chat-bubble:hover { filter: brightness(1.06); }
.chat-bubble-row.is-mine .chat-bubble:active { transform: scale(0.985); }

.chat-bubble-sender {
    font-size: 11.5px;
    font-weight: 800;
    color: var(--accent-2);
    margin-bottom: 2px;
}

.chat-bubble-text {
    white-space: pre-wrap;
}

.chat-bubble-meta {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 3px;
    margin-top: 2px;
    height: 12px;
}

.chat-bubble-time {
    font-size: 10.5px;
    opacity: 0.65;
}

/* Telegram uslubidagi "✓ / ✓✓" belgisi — faqat oʻz xabarlarimizda.
   Ikkinchi (orqa) tik chiziq oʻqilmaganda yashirin, oʻqilganda paydo
   boʻladi va rang oʻzgaradi. */
.chat-ticks {
    flex: none;
    color: rgba(26, 18, 0, 0.55);
}
.chat-ticks .tick-back { opacity: 0; transition: opacity 0.2s ease; }
.chat-ticks.is-read { color: #0f6b57; }
.chat-ticks.is-read .tick-back { opacity: 1; }

.chat-input-row {
    display: flex;
    align-items: center;
    gap: 8px;
    flex: none;
    padding: 10px 12px 12px;
    background: rgba(20, 26, 33, 0.72);
    backdrop-filter: blur(var(--glass-blur));
    border-top: 1px solid var(--glass-border);
}

.chat-input-row input {
    flex: 1;
    padding: 11px 16px;
    border-radius: 999px;
    border: 1px solid var(--glass-border);
    background: var(--surface);
    color: var(--text);
    font-size: 14.5px;
    transition: var(--transition);
}
.chat-input-row input:focus {
    outline: none;
    border-color: var(--accent-2);
    background: var(--surface-strong);
}

.chat-send {
    width: 42px;
    height: 42px;
    border-radius: 50%;
    border: none;
    flex: none;
    display: grid;
    place-items: center;
    background: var(--accent-gradient-btn);
    color: #1a1200;
    cursor: pointer;
    transition: var(--transition);
}
.chat-send:hover { transform: translateY(-1px) scale(1.04); }
.chat-send:active { transform: scale(0.94); }
.chat-send:disabled { opacity: 0.4; cursor: default; transform: none; }

@media (min-width: 1024px) {
    .chat-section { height: calc(100dvh - 140px); }
}

/* -------------------- "Kimlar oʻqidi" popup -------------------- */
.chat-readers-modal {
    max-width: 380px;
    padding: 18px;
}

.chat-readers-list {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.chat-reader-item {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 6px;
    border-radius: 12px;
}
.chat-reader-item:hover { background: var(--surface); }

.chat-reader-photo {
    width: 34px;
    height: 34px;
    border-radius: 50%;
    flex: none;
    object-fit: cover;
    border: 1px solid var(--glass-border);
}

.chat-reader-fallback {
    width: 34px;
    height: 34px;
    border-radius: 50%;
    flex: none;
    display: grid;
    place-items: center;
    background: var(--accent-gradient);
    color: #1a1200;
    font-size: 12px;
    font-weight: 800;
}

.chat-reader-info {
    min-width: 0;
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: 1px;
}

.chat-reader-name {
    font-size: 14px;
    font-weight: 600;
    color: var(--text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.chat-reader-time {
    font-size: 11.5px;
    color: var(--text-muted);
}

/* -------------------- Xabar amallari (reaksiya / oʻchirish) -------------------- */
.chat-bubble-actions {
    display: flex;
    flex-direction: column;
    gap: 3px;
    flex: none;
    align-self: flex-end;
    margin-bottom: 2px;
    opacity: 0.55;
    transition: opacity var(--transition);
}
.chat-bubble-row:hover .chat-bubble-actions,
.chat-bubble-actions:has(button:focus-visible) {
    opacity: 1;
}

.chat-bubble-action-btn {
    width: 24px;
    height: 24px;
    border-radius: 50%;
    border: none;
    background: var(--surface);
    color: var(--text-muted);
    display: grid;
    place-items: center;
    cursor: pointer;
    flex: none;
    transition: var(--transition);
}
.chat-bubble-action-btn:hover { background: var(--surface-strong); color: var(--text); }
.chat-bubble-action-btn:active { transform: scale(0.9); }
.chat-bubble-delete-btn:hover { color: var(--danger); }
.chat-bubble-edit-btn:hover { color: var(--accent-2); }

/* Xabar "tahrirlangan" (edited) belgisi — Telegramdagi kabi vaqt
   yonida kichkina, xira matn. Qarang public/assets/js/app.js ->
   chatBubbleHtml() / updateChatBubbleText(). */
.chat-bubble-edited {
    font-size: 10.5px;
    opacity: 0.6;
    font-style: italic;
}

/* Pastdagi umumiy chat-input xabarni TAHRIRLASH rejimida ekanda —
   qarang startEditChatMessage() / setChatFormEditingState() /
   cancelEditChatMessage(). Faqat vizual signal, funksional oʻzgarish
   forma submit handlerida (renderChat() ichida). */
.chat-input-row.is-editing input {
    border-color: var(--accent-2);
}
.chat-edit-cancel-btn {
    width: 32px;
    height: 32px;
    border-radius: 50%;
    border: none;
    flex: none;
    display: grid;
    place-items: center;
    background: var(--surface);
    color: var(--text-muted);
    font-size: 18px;
    line-height: 1;
    cursor: pointer;
    transition: var(--transition);
}
.chat-edit-cancel-btn:hover { background: var(--surface-strong); color: var(--text); }
.chat-edit-cancel-btn:active { transform: scale(0.9); }

/* Reaksiya tanlash uchun sichqoncha ustiga chiqadigan (fixed) popover —
   qarang public/assets/js/app.js -> openReactionPicker(). */
.chat-reaction-picker {
    position: fixed;
    z-index: 1300;
    display: flex;
    gap: 3px;
    padding: 6px 8px;
    border-radius: 999px;
    background: var(--bg-3);
    border: 1px solid var(--glass-border);
    box-shadow: var(--shadow);
    animation: fadeUp 0.15s ease both;
}

.chat-reaction-picker-btn {
    width: 30px;
    height: 30px;
    border: none;
    background: transparent;
    font-size: 19px;
    line-height: 1;
    border-radius: 8px;
    cursor: pointer;
    display: grid;
    place-items: center;
    transition: transform 0.12s ease, background var(--transition);
}
.chat-reaction-picker-btn:hover { background: var(--surface); transform: scale(1.2) translateY(-2px); }

/* Xabar tagida chiqadigan reaksiya "pill"lari (soni bilan) */
.chat-bubble-reactions {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    margin-top: 4px;
}

.chat-reaction-pill {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 2px 8px;
    border-radius: 999px;
    border: 1px solid rgba(233, 238, 246, 0.14);
    background: rgba(233, 238, 246, 0.08);
    color: inherit;
    font-size: 12px;
    font-weight: 700;
    cursor: pointer;
    transition: var(--transition);
}
.chat-bubble-row.is-mine .chat-reaction-pill {
    border-color: rgba(26, 18, 0, 0.18);
    background: rgba(26, 18, 0, 0.1);
}
.chat-reaction-pill:hover { transform: translateY(-1px); }
.chat-reaction-pill.is-mine {
    border-color: var(--accent-2);
    background: rgba(36, 230, 196, 0.16);
}
.chat-bubble-row.is-mine .chat-reaction-pill.is-mine {
    border-color: rgba(26, 18, 0, 0.4);
    background: rgba(26, 18, 0, 0.16);
}

/* "Xabar oʻchirildi" tombstone — Telegramdagi kabi, joyida qoladi lekin
   matn oʻrniga shu koʻrinadi, harakatlar/tik/reaksiya yoʻqoladi. */
.chat-bubble.is-deleted {
    background: transparent !important;
    border: 1px dashed var(--glass-border) !important;
    color: var(--text-muted) !important;
    box-shadow: none;
    cursor: default !important;
}
.chat-bubble-deleted-text {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 13.5px;
    font-style: italic;
    opacity: 0.8;
}

/* -------------------- "Xabarni oʻchirish" tasdiq oynasi -------------------- */
.chat-delete-confirm-modal {
    max-width: 360px;
}
.chat-delete-confirm-text {
    font-size: 14px;
    color: var(--text-muted);
    line-height: 1.5;
    margin: 4px 0 18px;
}
.chat-delete-confirm-actions {
    display: flex;
    justify-content: flex-end;
    gap: 10px;
}

/* ===================================================================
   "Xatolik" (Bug report) — o'quvchi (bottom-nav to'liq sahifa),
   o'qituvchi/admin/kichkina admin (header ikonka + modal). Qarang:
   public/assets/js/app.js, public/assets/js/admin.js,
   App\Services\BugReportService.
   =================================================================== */

/* .field bugungacha faqat <input>/<select> uchun edi — endi xabar
   matni uchun <textarea> ham kerak, xuddi shu ko'rinishda. */
.field textarea {
    width: 100%;
    padding: 14px 16px;
    border-radius: var(--radius-sm);
    border: 1px solid rgba(233, 238, 246, 0.1);
    background: rgba(0, 0, 0, 0.28);
    color: var(--text);
    font-size: 15px;
    font-family: inherit;
    line-height: 1.5;
    outline: none;
    resize: vertical;
    min-height: 100px;
    transition: var(--transition);
}

.field textarea:focus {
    border-color: var(--warning);
    box-shadow: 0 0 0 3px rgba(232, 183, 60, 0.18);
}

/* Header ikonkasi (o'qituvchi/admin/kichkina admin) — bosilganda
   ogohlantiruvchi sariq rangga o'tadi, bildirishnoma qo'ng'irog'i
   bilan aralashib ketmasligi uchun. */
.bugreport-btn:hover {
    background: rgba(232, 183, 60, 0.14);
    color: var(--warning);
}

.bugreport-overlay { align-items: flex-start; padding-top: 10vh; }

.bugreport-modal {
    max-width: 480px;
}

.bugreport-modal-title {
    display: flex;
    align-items: center;
    gap: 8px;
}

.bugreport-modal-icon {
    display: inline-flex;
    width: 30px;
    height: 30px;
    border-radius: 9px;
    background: rgba(232, 183, 60, 0.14);
    color: var(--warning);
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

.bugreport-modal-subtitle {
    margin: 8px 0 0;
    color: var(--text-muted);
    font-size: 13px;
    line-height: 1.5;
}

.bugreport-counter {
    text-align: right;
    font-size: 11px;
    color: var(--text-muted);
    margin-top: -4px;
}

/* O'quvchi panelidagi to'liq sahifa versiyasi (bottom-nav "Xatolik") */
.bugreport-card {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.bugreport-card-icon {
    display: inline-flex;
    width: 48px;
    height: 48px;
    border-radius: 14px;
    background: rgba(232, 183, 60, 0.14);
    color: var(--warning);
    align-items: center;
    justify-content: center;
    margin-bottom: 2px;
}

/* ---------------------------------------------------------------------
   "CD tests" — bo'lim/test daraxti (o'quvchi paneli, bottom-nav).
   Bo'limlar public/CDI.php orqali qo'shiladi; qarang app.js ->
   renderCdTests() / renderCdSectionNode() / openCdTestHtmlModal().
--------------------------------------------------------------------- */
.cdtest-tree {
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.cdtest-section {
    background: linear-gradient(180deg, rgba(233, 238, 246, 0.055) 0%, rgba(233, 238, 246, 0.03) 100%);
    border: 1px solid var(--glass-border);
    border-radius: 14px;
    overflow: hidden;
    margin-left: calc(var(--cdtest-depth, 0) * 14px);
    transition: border-color var(--transition), background var(--transition);
}

.cdtest-section.open {
    border-color: rgba(36, 230, 196, 0.22);
}

.cdtest-section-head {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 14px 15px;
    cursor: pointer;
    font-weight: 600;
    font-size: 14px;
    user-select: none;
    transition: background var(--transition);
}

.cdtest-section-head:hover {
    background: rgba(233, 238, 246, 0.04);
}

.cdtest-section-head::before {
    content: '📁';
    font-size: 14px;
    flex-shrink: 0;
    filter: grayscale(0.15);
}

.cdtest-section.open > .cdtest-section-head::before {
    content: '📂';
}

.cdtest-caret {
    flex-shrink: 0;
    transition: transform var(--transition), color var(--transition);
    color: var(--text-muted);
}

.cdtest-section.open > .cdtest-section-head .cdtest-caret {
    transform: rotate(90deg);
    color: var(--accent-2);
}

.cdtest-section-name {
    flex: 1;
    letter-spacing: 0.01em;
}

.cdtest-section-body {
    display: none;
    flex-direction: column;
    gap: 8px;
    padding: 2px 12px 14px;
}

.cdtest-section.open > .cdtest-section-body {
    display: flex;
    animation: cdtestBodyIn 0.32s cubic-bezier(0.22, 0.61, 0.36, 1);
}

@keyframes cdtestBodyIn {
    from { opacity: 0; transform: translateY(-4px); }
    to { opacity: 1; transform: translateY(0); }
}

/* Test kartochkalari — Uzum Market uslubidagi grid: yuqorida rasm
   (kvadratga yaqin), pastda sarlavha; "free" testda rasm ustiga
   chap-yuqori burchakda belgi (chegirma yorlig'iga o'xshab). */
.cdtest-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
    gap: 12px;
    margin-bottom: 4px;
}

.cdtest-card {
    display: flex;
    flex-direction: column;
    background: var(--surface);
    border: 1px solid var(--glass-border);
    border-radius: var(--radius-sm);
    overflow: hidden;
    cursor: pointer;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.18);
    transition: transform var(--transition), border-color var(--transition), background var(--transition), box-shadow var(--transition);
}

.cdtest-card:active {
    transform: scale(0.96);
}

.cdtest-card:hover {
    background: rgba(233, 238, 246, 0.07);
    border-color: rgba(233, 238, 246, 0.18);
    transform: translateY(-2px);
    box-shadow: 0 10px 22px rgba(0, 0, 0, 0.28);
}

.cdtest-card-regular {
    cursor: pointer;
    opacity: 0.88;
}

.cdtest-card-cover {
    position: relative;
    width: 100%;
    height: 136px;
    background: var(--bg-3);
    overflow: hidden;
}

.cdtest-card-img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    transition: transform 0.4s cubic-bezier(0.22, 0.61, 0.36, 1);
}

.cdtest-card:hover .cdtest-card-img {
    transform: scale(1.06);
}

.cdtest-card-placeholder {
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 34px;
    background: linear-gradient(150deg, rgba(212, 175, 90, 0.16) 0%, rgba(36, 230, 196, 0.12) 100%);
}

.cdtest-card-badge {
    position: absolute;
    top: 8px;
    left: 8px;
    display: inline-flex;
    align-items: center;
    gap: 3px;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.02em;
    padding: 4px 9px;
    border-radius: 999px;
    background: rgba(36, 230, 196, 0.92);
    color: #05221c;
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.25);
    backdrop-filter: blur(2px);
}

.cdtest-card-badge-premium {
    background: linear-gradient(120deg, #f2d896 0%, #d4af5a 100%);
    color: #241a04;
}

.cdtest-card-locked {
    cursor: pointer;
}

.cdtest-card-locked .cdtest-card-cover {
    filter: saturate(0.5) brightness(0.5);
}

.cdtest-card-lock {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    color: #f2d896;
    background: rgba(7, 9, 13, 0.35);
    backdrop-filter: blur(1px);
}

.cdtest-card-lock svg {
    filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.4));
}

/* -----------------------------------------------------------------
   Premium obuna oynasi — qulflangan Premium test kartochkasi
   bosilganda ochiladi. Qarang app.js -> openPremiumModal().
--------------------------------------------------------------------- */
.premium-modal-text {
    font-size: 13.5px;
    line-height: 1.55;
    color: var(--text-muted);
    margin: 0 0 14px;
}

.premium-modal-text b {
    color: var(--text);
}

.premium-modal-hint {
    font-size: 12px;
    color: var(--text-muted);
    margin: 10px 0 16px;
}

.premium-price-box {
    display: flex;
    align-items: center;
    justify-content: space-between;
    background: rgba(212, 175, 90, 0.1);
    border: 1px solid rgba(212, 175, 90, 0.3);
    border-radius: var(--radius-sm);
    padding: 14px 16px;
    margin-bottom: 18px;
}

.premium-price-label {
    font-size: 13px;
    color: var(--text-muted);
}

.premium-price-value {
    font-size: 19px;
    font-weight: 700;
    color: var(--accent);
}

.premium-card-box {
    position: relative;
    background: linear-gradient(135deg, rgba(212, 175, 90, 0.16) 0%, rgba(36, 230, 196, 0.08) 100%);
    border: 1px solid rgba(212, 175, 90, 0.3);
    border-radius: var(--radius-sm);
    padding: 16px;
    margin-bottom: 6px;
}

.premium-card-number {
    font-size: 19px;
    font-weight: 700;
    letter-spacing: 0.04em;
    color: var(--text);
    margin-bottom: 6px;
}

.premium-card-holder {
    font-size: 13px;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.03em;
}

.premium-copy-btn {
    position: absolute;
    top: 14px;
    right: 14px;
}

.premium-upload-label {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 13px 16px;
    border-radius: var(--radius-sm);
    border: 1px dashed rgba(233, 238, 246, 0.22);
    color: var(--text);
    font-size: 13.5px;
    font-weight: 600;
    cursor: pointer;
    text-align: center;
}

.premium-upload-label:hover {
    border-color: var(--accent);
    color: var(--accent);
}

.premium-pending-block {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    padding: 12px 4px 4px;
}

.premium-pending-icon {
    font-size: 34px;
    margin-bottom: 10px;
}

.cdtest-card-title {
    padding: 10px 11px 12px;
    font-size: 13px;
    font-weight: 600;
    line-height: 1.35;
    color: var(--text);
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* Test "free" bosilganda TO'LIQ EKRANDA ochiladi — edge-to-edge,
   header/bottom-nav'dan ustida (z-index eng baland), Telegram Mini
   App'ning o'zi kabi to'liq immersiv. */
body.cdtest-fullscreen-open {
    overflow: hidden;
}

.cdtest-fullscreen-overlay {
    position: fixed;
    inset: 0;
    z-index: 2000;
    display: flex;
    flex-direction: column;
    background: #fff;
}

.cdtest-fullscreen-header {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    gap: 10px;
    padding: calc(env(safe-area-inset-top, 0px) + 12px) 14px 12px;
    background: var(--bg-3);
    border-bottom: 1px solid rgba(233, 238, 246, 0.08);
}

.cdtest-fullscreen-back {
    flex-shrink: 0;
    width: 34px;
    height: 34px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    border: 1px solid rgba(233, 238, 246, 0.12);
    background: rgba(233, 238, 246, 0.05);
    color: var(--text);
    cursor: pointer;
}

.cdtest-fullscreen-title {
    flex: 1;
    font-size: 14.5px;
    font-weight: 600;
    color: var(--text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.cdtest-fullscreen-frame-wrap {
    position: relative;
    flex: 1;
    background: #fff;
}

.cdtest-fullscreen-spinner {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}

.cdtest-fullscreen-frame {
    width: 100%;
    height: 100%;
    border: 0;
    display: block;
}
