@import url('https://fonts.googleapis.com/css2?family=Chakra+Petch:wght@400;500;600;700&family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;700&display=swap');

:root {
    --void: #0a0b10;
    --panel: #13151c;
    --panel-raised: #1a1d2a;
    --line: rgba(148, 163, 220, 0.15);
    --indigo: #6d6af6;
    --cyan: #2dd9e8;
    --rose: #fb6f92;
    --emerald: #34e2a1;
    --amber: #f5b74d;
    --text-hi: #f8fafc;
    --text-mid: #cbd5e1;
    --text-low: #64748b;
}

* { box-sizing: border-box; }

body {
    font-family: 'Inter', sans-serif;
    background: linear-gradient(180deg, var(--void) 0%, #0d0e12 100%);
    color: var(--text-hi);
    position: relative;
    min-height: 100vh;
    overflow-x: hidden;
}

.font-display { font-family: 'Chakra Petch', sans-serif; }
.font-mono { font-family: 'JetBrains Mono', monospace; }

/* Wrapper for the four decorative background layers below (grid-field +
   three glow-orbs). They used to be position:fixed each, which caused the
   GPU-compositor black-screen bug fixed elsewhere in this file (see the
   .app-sidebar comment for the original diagnosis) - switching them to
   position:absolute fixed THAT, but introduced a different bug: glow-orb-2
   and glow-orb-3 deliberately sit partly off-screen (right:-5%/left:-10%)
   for an edge-bleed look, and as absolute (in-flow-for-sizing) elements
   that actually extends the document's real scrollable width past the
   viewport, even though body's overflow-x:hidden visually hides it at
   rest. iOS Safari (and some Chrome mobile builds) don't reliably keep
   honoring a ROOT element's overflow:hidden once a pinch-zoom gesture
   changes the visual viewport, which is exactly the "zoom out and the
   layout breaks" report this fixes - the hidden overflow becomes reachable
   again mid-zoom. A nested, non-root overflow:hidden container doesn't
   have that quirk, so this wrapper (not body) is what actually clips them,
   regardless of zoom level. height is generous enough to contain all three
   orbs' vertical extent (tallest reaches ~900px down) without clipping the
   glow effect itself. */
.bg-decor-layer {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 1000px;
    overflow: hidden;
    pointer-events: none;
    z-index: 0;
}

.grid-field {
    position: absolute;
    inset: 0;
    z-index: 0;
    pointer-events: none;
    background-image: 
        linear-gradient(rgba(45, 217, 232, 0.05) 1px, transparent 1px),
        linear-gradient(90deg, rgba(45, 217, 232, 0.05) 1px, transparent 1px),
        linear-gradient(rgba(109, 106, 246, 0.02) 1px, transparent 1px),
        linear-gradient(90deg, rgba(109, 106, 246, 0.02) 1px, transparent 1px);
    background-size: 50px 50px, 50px 50px, 100px 100px, 100px 100px;
    opacity: 0.7;
    animation: gridPulse 8s ease-in-out infinite;
}

@keyframes gridPulse {
    0%, 100% { opacity: 0.5; }
    50% { opacity: 0.8; }
}

/* AMBIENT NEON GLOW ORB BACKGROUND */
.glow-orb {
    position: absolute;
    top: -120px;
    left: 50%;
    transform: translateX(-50%);
    width: 1000px;
    height: 600px;
    background: radial-gradient(circle, rgba(109, 106, 246, 0.3) 0%, rgba(45, 217, 232, 0.15) 45%, transparent 75%);
    filter: blur(60px);
    animation: orbFloat 12s ease-in-out infinite;
    z-index: 1;
    pointer-events: none;
}

@keyframes orbFloat {
    0%, 100% { transform: translateX(-50%) translateY(0); }
    50% { transform: translateX(-50%) translateY(20px); }
}

/* ADDITIONAL GLOW ORBS FOR MORE VIBRANCY */
.glow-orb-2 {
    position: absolute;
    top: 500px;
    right: -5%;
    width: 600px;
    height: 400px;
    background: radial-gradient(circle, rgba(251, 111, 146, 0.2) 0%, rgba(109, 106, 246, 0.1) 40%, transparent 70%);
    filter: blur(50px);
    animation: orbFloat2 15s ease-in-out infinite;
    z-index: 1;
    pointer-events: none;
}

@keyframes orbFloat2 {
    0%, 100% { transform: translate(0, 0); }
    50% { transform: translate(-30px, -20px); }
}

/* THIRD GLOW ORB FOR BALANCE */
.glow-orb-3 {
    position: absolute;
    top: 160px;
    left: -10%;
    width: 500px;
    height: 500px;
    background: radial-gradient(circle, rgba(52, 226, 161, 0.12) 0%, rgba(45, 217, 232, 0.06) 50%, transparent 70%);
    filter: blur(60px);
    animation: orbFloat3 18s ease-in-out infinite;
    z-index: 1;
    pointer-events: none;
}

@keyframes orbFloat3 {
    0%, 100% { transform: translate(0, 0); }
    50% { transform: translate(25px, 15px); }
}

/* ORB AMBIENT RESPONSIVE MOTION */
@keyframes pulse-orb {
    0% {
        transform: translateX(-50%) scale(1);
        opacity: 0.8;
    }
    100% {
        transform: translateX(-48%) scale(1.1);
        opacity: 1;
    }
}

/* ADDITIONAL PARTICLE EFFECTS */
.particle-field {
    position: fixed;
    inset: 0;
    z-index: 0;
    pointer-events: none;
    background-image: 
        radial-gradient(circle at 20% 30%, rgba(45, 217, 232, 0.1) 0%, transparent 50%),
        radial-gradient(circle at 80% 70%, rgba(109, 106, 246, 0.08) 0%, transparent 50%),
        radial-gradient(circle at 40% 80%, rgba(251, 111, 146, 0.06) 0%, transparent 40%);
    animation: particleFloat 20s ease-in-out infinite;
}

@keyframes particleFloat {
    0%, 100% { transform: translate(0, 0); }
    25% { transform: translate(10px, -5px); }
    50% { transform: translate(-5px, 10px); }
    75% { transform: translate(-10px, -5px); }
}

/* SCANLINE / CRT FILTER TO ENHANCE SCIFI VIBES */
body::after {
    content: " ";
    display: block;
    position: fixed;
    top: 0; left: 0; bottom: 0; right: 0;
    background: linear-gradient(rgba(18, 16, 16, 0) 50%, rgba(0, 0, 0, 0.15) 50%), linear-gradient(90deg, rgba(255, 0, 0, 0.04), rgba(0, 255, 0, 0.01), rgba(0, 0, 255, 0.04));
    z-index: 9999;
    background-size: 100% 4px, 6px 100%;
    pointer-events: none;
    opacity: 0.08;
}

/* SCIFI PANEL CONTAINER */
.panel {
    background: linear-gradient(135deg, rgba(19, 21, 28, 0.9) 0%, rgba(10, 11, 16, 0.95) 100%);
    -webkit-backdrop-filter: blur(16px) saturate(140%);
    backdrop-filter: blur(16px) saturate(140%);
    border: 1px solid rgba(148, 163, 220, 0.15);
    transition: all 0.3s cubic-bezier(0.16, 1, 0.3, 1);
    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.05);
}

.panel::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 1px;
    background: linear-gradient(90deg, transparent, rgba(45, 217, 232, 0.4), transparent);
    opacity: 0.6;
}

.panel:hover {
    border-color: rgba(45, 217, 232, 0.4);
    box-shadow: 0 0 30px rgba(45, 217, 232, 0.15), inset 0 1px 0 rgba(255, 255, 255, 0.1);
}

/* ADVANCED CYBERNETIC BRACKET CORNERS DESIGN */
.bracket-frame {
    position: relative;
    overflow: visible;
}

/* Several modals/dropdowns pair `bracket-frame` with a Tailwind
   `max-h-[...] overflow-y-auto` so long content scrolls inside a capped
   box (profile modal, notification dropdowns, template pickers, ticket
   replies, etc). `.bracket-frame`'s own `overflow: visible` above has the
   same specificity as Tailwind's single-class `.overflow-y-auto`, and this
   stylesheet loads after tailwind.css, so it was silently winning and
   cancelling the scroll - the box just grew past the viewport with no
   scrollbar, forcing a page zoom-out to see the rest. This compound
   selector (two classes = higher specificity) wins regardless of load
   order and restores the intended scroll, without touching the separate
   `bracket-frame` + `overflow-hidden` panels elsewhere that rely on the
   visible corners showing through. */
.bracket-frame.overflow-y-auto {
    overflow-y: auto;
}

/* Same specificity trap as above, but for `position`: `.bracket-frame`'s
   own `position: relative` (single class) has equal specificity to
   Tailwind's single-class `.absolute { position: absolute }`, and this
   stylesheet loads after tailwind.css, so it was silently winning on any
   dropdown that pairs `absolute` with `bracket-frame` for the corner
   decoration (notification bell panel, account menu, survey/analytics
   action menus, etc). With `position` cancelled back to `relative`, the
   panel stayed in normal document flow instead of floating over the page,
   inflating the whole nav bar's height to match the open panel's content
   and shoving the other header icons down to its vertical center - the
   "clunky notification tab" bug. This compound selector wins regardless
   of load order and restores the intended floating behavior. */
.bracket-frame.absolute {
    position: absolute;
}

.bracket-frame::before,
.bracket-frame::after {
    content: '';
    position: absolute;
    width: 16px;
    height: 16px;
    pointer-events: none;
    z-index: 5;
    transition: all 0.3s ease;
}

/* Top-Left & Bottom-Right Corner styling */
.bracket-frame::before {
    top: -1px;
    left: -1px;
    border-top: 2px solid #2dd9e8;
    border-left: 2px solid #2dd9e8;
    box-shadow: 0 0 8px rgba(45, 217, 232, 0.4);
}

.bracket-frame::after {
    bottom: -1px;
    right: -1px;
    border-bottom: 2px solid #6d6af6;
    border-right: 2px solid #6d6af6;
    box-shadow: 0 0 8px rgba(109, 106, 246, 0.4);
}

/* Hover-activated cybernetic corner expansion */
.bracket-frame:hover::before {
    width: 22px;
    height: 22px;
    border-top-color: #2dd9e8;
    border-left-color: #2dd9e8;
    filter: drop-shadow(0 0 6px rgba(45, 217, 232, 0.8));
}

.bracket-frame:hover::after {
    width: 22px;
    height: 22px;
    border-bottom-color: #fb6f92;
    border-right-color: #fb6f92;
    filter: drop-shadow(0 0 6px rgba(251, 111, 146, 0.8));
}

/* HIGH-TECH PULSING DOTS */
.pulse-dot {
    position: relative;
    display: inline-block;
    animation: pulseGlow 2s ease-in-out infinite;
}

@keyframes pulseGlow {
    0%, 100% { opacity: 1; transform: scale(1); }
    50% { opacity: 0.7; transform: scale(1.1); }
}

.pulse-dot::after {
    content: '';
    position: absolute;
    inset: -4px;
    border-radius: 9999px;
    border: 1px solid currentColor;
    opacity: 0.8;
    animation: pulse-ring 2s cubic-bezier(0.215, 0.610, 0.355, 1) infinite;
}

@keyframes pulse-ring {
    0% {
        transform: scale(0.6);
        opacity: 0.8;
    }
    100% {
        transform: scale(2.2);
        opacity: 0;
    }
}

/* PREMIUM SCIFI INPUTS */
.input-style {
    background: rgba(8, 9, 13, 0.8);
    border: 1px solid rgba(148, 163, 220, 0.16);
    color: #eef0f7;
    font-family: "JetBrains Mono", monospace;
    transition: all 0.25s ease;
}

.input-style:focus {
    outline: none;
    border-color: #2dd9e8;
    box-shadow: 0 0 12px rgba(45, 217, 232, 0.15);
    background: rgba(16, 18, 25, 0.95);
}

/* NEO-PULSING PRIMARY BUTTONS */
.btn-primary {
    position: relative;
    background: linear-gradient(135deg, #6d6af6 0%, #2dd9e8 100%);
    color: #08090d;
    font-weight: 700;
    font-family: "Chakra Petch", sans-serif;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    border: none;
    overflow: hidden;
    box-shadow: 0 4px 15px rgba(45, 217, 232, 0.25);
    cursor: pointer;
    transition: all 0.3s cubic-bezier(0.16, 1, 0.3, 1);
}

.btn-primary::before {
    content: '';
    position: absolute;
    top: 0; left: -100%;
    width: 100%; height: 100%;
    background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);
    transition: all 0.6s ease;
}

.btn-primary:hover {
    transform: translateY(-2px);
    box-shadow: 0 6px 22px rgba(45, 217, 232, 0.45);
    color: #08090d;
}

.btn-primary:hover::before {
    left: 100%;
}

.btn-primary:active {
    transform: translateY(0);
}

/* ENTRANCE ANIMATIONS */
@keyframes fadeInUp {
    from {
        opacity: 0;
        transform: translateY(30px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

@keyframes fadeInScale {
    from {
        opacity: 0;
        transform: scale(0.9);
    }
    to {
        opacity: 1;
        transform: scale(1);
    }
}

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

@keyframes slideInRight {
    from {
        opacity: 0;
        transform: translateX(30px);
    }
    to {
        opacity: 1;
        transform: translateX(0);
    }
}

.animate-fade-in-up {
    animation: fadeInUp 0.6s cubic-bezier(0.16, 1, 0.3, 1) forwards;
    opacity: 0;
}

.animate-fade-in-scale {
    animation: fadeInScale 0.5s cubic-bezier(0.16, 1, 0.3, 1) forwards;
    opacity: 0;
}

.animate-slide-in-left {
    animation: slideInLeft 0.6s cubic-bezier(0.16, 1, 0.3, 1) forwards;
    opacity: 0;
}

.animate-slide-in-right {
    animation: slideInRight 0.6s cubic-bezier(0.16, 1, 0.3, 1) forwards;
    opacity: 0;
}

/* Staggered animation delays */
.delay-100 { animation-delay: 0.1s; }
.delay-200 { animation-delay: 0.2s; }
.delay-300 { animation-delay: 0.3s; }
.delay-400 { animation-delay: 0.4s; }
.delay-500 { animation-delay: 0.5s; }
.delay-600 { animation-delay: 0.6s; }

/* GLITCH EFFECT */
@keyframes glitch {
    0% {
        transform: translate(0);
    }
    20% {
        transform: translate(-2px, 2px);
    }
    40% {
        transform: translate(-2px, -2px);
    }
    60% {
        transform: translate(2px, 2px);
    }
    80% {
        transform: translate(2px, -2px);
    }
    100% {
        transform: translate(0);
    }
}

@keyframes glitch-skew {
    0% {
        transform: skew(0deg);
    }
    20% {
        transform: skew(2deg);
    }
    40% {
        transform: skew(-2deg);
    }
    60% {
        transform: skew(1deg);
    }
    80% {
        transform: skew(-1deg);
    }
    100% {
        transform: skew(0deg);
    }
}

.glitch-effect {
    position: relative;
    display: inline-block;
}

.glitch-effect:hover {
    animation: glitch 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94) both infinite;
}

.glitch-effect::before,
.glitch-effect::after {
    content: attr(data-text);
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    opacity: 0;
    pointer-events: none;
}

.glitch-effect:hover::before {
    opacity: 0.8;
    color: #2dd9e8;
    animation: glitch-skew 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94) both infinite;
    clip-path: polygon(0 0, 100% 0, 100% 45%, 0 45%);
    transform: translate(-2px);
}

.glitch-effect:hover::after {
    opacity: 0.8;
    color: #fb6f92;
    animation: glitch-skew 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94) reverse both infinite;
    clip-path: polygon(0 55%, 100% 55%, 100% 100%, 0 100%);
    transform: translate(2px);
}

/* PREMIUM UPGRADE BUTTON WITH SHINE EFFECT */
.btn-upgrade {
    position: relative;
    background: linear-gradient(135deg, #6d6af6 0%, #fb6f92 100%);
    color: white;
    font-weight: 700;
    font-family: "Chakra Petch", sans-serif;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    border: 1px solid rgba(255, 255, 255, 0.2);
    overflow: hidden;
    box-shadow: 0 0 15px rgba(109, 106, 246, 0.35);
    cursor: pointer;
    transition: all 0.3s cubic-bezier(0.16, 1, 0.3, 1);
}

.btn-upgrade::before {
    content: '';
    position: absolute;
    top: 0; left: -100%;
    width: 100%; height: 100%;
    background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.1), transparent);
    transition: transform 1s ease-out;
}

.btn-upgrade:hover {
    filter: brightness(1.1);
    box-shadow: 0 0 22px rgba(251, 111, 146, 0.5);
    transform: translateY(-1px);
}

.btn-upgrade:hover::before {
    transform: translateX(100%);
}

.btn-upgrade:active {
    transform: scale(0.95);
}

/* STATUS INDICATOR WITH PULSE */
.status-indicator {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.5rem 1rem;
    background: rgba(14, 16, 23, 0.85);
    -webkit-backdrop-filter: blur(12px);
    backdrop-filter: blur(12px);
    border: 1px solid rgba(45, 217, 232, 0.3);
    border-radius: 9999px;
    box-shadow: 0 0 15px rgba(45, 217, 232, 0.06);
    transition: all 0.3s ease;
}

.status-indicator:hover {
    border-color: rgba(45, 217, 232, 0.5);
    box-shadow: 0 0 20px rgba(45, 217, 232, 0.15);
}

.status-dot {
    position: relative;
    display: inline-flex;
}

.status-dot::before {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: 9999px;
    background: currentColor;
    animation: ping 1.5s cubic-bezier(0, 0, 0.2, 1) infinite;
}

@keyframes ping {
    75%, 100% {
        transform: scale(2);
        opacity: 0;
    }
}

/* WELCOME HERO CARD */
.welcome-card {
    position: relative;
    overflow: hidden;
    border-radius: 1rem;
    padding: 1.5rem 2rem;
    border: 1px solid rgba(148, 163, 220, 0.1);
    background: linear-gradient(135deg, #161925 0%, #12141e 50%, #0a0b10 100%);
    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
}

.welcome-card::before {
    content: '';
    position: absolute;
    top: 0;
    right: 0;
    width: 20rem;
    height: 20rem;
    background: rgba(109, 106, 246, 0.05);
    border-radius: 50%;
    filter: blur(3rem);
    pointer-events: none;
}

.system-badge {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    font-family: "JetBrains Mono", monospace;
    font-size: 0.5625rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.2em;
    color: #2dd9e8;
    background: rgba(45, 217, 232, 0.15);
    padding: 0.25rem 0.75rem;
    border-radius: 9999px;
    border: 1px solid rgba(45, 217, 232, 0.25);
    margin-bottom: 0.25rem;
}

.system-badge .dot {
    width: 0.375rem;
    height: 0.375rem;
    border-radius: 9999px;
    background: #2dd9e8;
    box-shadow: 0 0 8px #2dd9e8;
    animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}

@keyframes pulse {
    0%, 100% {
        opacity: 1;
    }
    50% {
        opacity: 0.5;
    }
}

/* METRIC CARDS WITH HOVER EFFECTS */
.metric-card {
    padding: 1.25rem;
    border-radius: 0.75rem;
    border: 1px solid rgba(148, 163, 220, 0.08);
    background: #11131c;
    transition: all 0.3s ease;
}

.metric-card:hover {
    border-color: rgba(45, 217, 232, 0.3);
}

.metric-card.hover-cyan:hover {
    border-color: rgba(45, 217, 232, 0.3);
}

.metric-card.hover-emerald:hover {
    border-color: rgba(52, 226, 161, 0.3);
}

.metric-card.hover-indigo:hover {
    border-color: rgba(109, 106, 246, 0.3);
}

.metric-card.hover-rose:hover {
    border-color: rgba(251, 111, 146, 0.3);
}

/* LIVE TELEMETRY FEED */
.telemetry-feed {
    padding: 1.25rem;
    border-radius: 0.75rem;
    background: #0d0f15;
    border: 1px solid rgba(148, 163, 220, 0.08);
    border-left: 4px solid #6d6af6;
}

.telemetry-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding-bottom: 0.625rem;
    border-bottom: 1px solid rgba(148, 163, 220, 0.05);
}

.telemetry-indicator {
    width: 0.5rem;
    height: 0.5rem;
    border-radius: 9999px;
    background: #fb6f92;
    animation: ping 1.5s cubic-bezier(0, 0, 0.2, 1) infinite;
}

/* GRADIENT BUTTONS */
.btn-gradient-cyan {
    background: linear-gradient(135deg, #2dd9e8 0%, #6d6af6 100%);
    color: black;
    font-weight: 700;
    font-family: "Chakra Petch", sans-serif;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    border: none;
    border-radius: 0.75rem;
    padding: 0.5rem 1rem;
    cursor: pointer;
    transition: all 0.3s ease;
}

.btn-gradient-cyan:hover {
    transform: scale(1.02);
}

.btn-glass {
    background: rgba(255, 255, 255, 0.05);
    color: white;
    border: 1px solid rgba(255, 255, 255, 0.15);
    font-weight: 700;
    font-family: "Chakra Petch", sans-serif;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    border-radius: 0.75rem;
    padding: 0.5rem 1rem;
    cursor: pointer;
    transition: all 0.3s ease;
}

.btn-glass:hover {
    background: rgba(255, 255, 255, 0.1);
}

/* SERVER CARDS WITH ACTIVE/OFFLINE STATES */
.server-card {
    padding: 1.5rem;
    border-radius: 1rem;
    border: 1px solid rgba(148, 163, 220, 0.1);
    transition: all 0.3s ease;
}

.server-card.active {
    background: #11131c;
    border-color: rgba(148, 163, 220, 0.1);
}

.server-card.active:hover {
    border-color: rgba(109, 106, 246, 0.4);
    box-shadow: 0 4px 25px rgba(109, 106, 246, 0.08);
}

.server-card.inactive {
    background: #0d0e14;
    border-color: rgba(148, 163, 220, 0.05);
    opacity: 0.8;
}

.server-icon {
    width: 3rem;
    height: 3rem;
    border-radius: 0.75rem;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 1px solid rgba(148, 163, 220, 0.1);
    background: #181a26;
    font-size: 1.5rem;
    box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.3);
}

.server-status-light {
    width: 0.5rem;
    height: 0.5rem;
    border-radius: 9999px;
}

.server-status-light.online {
    background: #2dd9e8;
    animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
    box-shadow: 0 0 8px #2dd9e8;
}

.server-status-light.offline {
    background: #475569;
}

/* SERVER STATS PANEL */
.server-stats {
    padding: 1rem;
    border-radius: 0.75rem;
    background: rgba(23, 26, 38, 0.8);
    border: 1px solid rgba(148, 163, 220, 0.06);
}

/* PROGRESS BARS */
.progress-bar {
    width: 100%;
    height: 0.375rem;
    background: rgba(0, 0, 0, 0.4);
    border-radius: 9999px;
    overflow: hidden;
}

.progress-fill {
    height: 100%;
    border-radius: 9999px;
    transition: all 0.5s ease;
}

.progress-fill.success {
    background: #34e2a1;
}

.progress-fill.warning {
    background: #fb6f92;
}

/* LOG ENTRY STYLING */
.log-entry {
    display: flex;
    align-items: flex-start;
    gap: 0.625rem;
    color: #cbd5e1;
}

.log-timestamp {
    color: #6d6af6;
    font-weight: 500;
    flex-shrink: 0;
}

.log-badge {
    padding: 0.125rem 0.375rem;
    border-radius: 0.25rem;
    font-size: 0.5rem;
    font-weight: 700;
    text-transform: uppercase;
    flex-shrink: 0;
}

.log-badge.success {
    background: rgba(52, 226, 161, 0.1);
    color: #34e2a1;
}

.log-badge.ticket {
    background: rgba(45, 217, 232, 0.1);
    color: #2dd9e8;
}

.log-badge.security {
    background: rgba(251, 111, 146, 0.1);
    color: #fb6f92;
}

/* CUSTOM SCROLLBAR FOR LOGS */
.custom-scrollbar::-webkit-scrollbar {
    width: 6px;
}

.custom-scrollbar::-webkit-scrollbar-track {
    background: rgba(0, 0, 0, 0.2);
    border-radius: 3px;
}

.custom-scrollbar::-webkit-scrollbar-thumb {
    background: rgba(148, 163, 220, 0.2);
    border-radius: 3px;
}

.custom-scrollbar::-webkit-scrollbar-thumb:hover {
    background: rgba(148, 163, 220, 0.4);
}

/* OFFLINE SERVER STATE */
.server-offline-state {
    padding: 1.5rem;
    text-align: center;
    border: 1px dashed rgba(148, 163, 220, 0.08);
    border-radius: 0.75rem;
    background: rgba(0, 0, 0, 0.2);
}

/* SECTION DIVIDER */
.section-divider {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.section-divider::after {
    content: '';
    flex: 1;
    height: 1px;
    background: linear-gradient(to right, rgba(148, 163, 220, 0.1), transparent);
}

/* SECONDRY BUTTONS WITH GLASS OVERLAY */
.btn-secondary {
    background: rgba(22, 25, 37, 0.6);
    border: 1px solid rgba(148, 163, 220, 0.2);
    color: #9ba0b8;
    font-family: "Chakra Petch", sans-serif;
    letter-spacing: 0.05em;
    transition: all 0.25s ease;
    cursor: pointer;
}

.btn-secondary:hover {
    background: rgba(109, 106, 246, 0.1);
    color: #eef0f7;
    border-color: rgba(109, 106, 246, 0.4);
}

/* CUSTOM HIGH TECH SCROLLBARS */
::-webkit-scrollbar {
    width: 6px;
    height: 6px;
}

::-webkit-scrollbar-track {
    background: #08090d;
}

::-webkit-scrollbar-thumb {
    background: #161925;
    border: 1px solid rgba(148, 163, 220, 0.08);
    border-radius: 3px;
}

::-webkit-scrollbar-thumb:hover {
    background: #6d6af6;
    border-color: #2dd9e8;
}

/* CHROME/GLOW TRANSITIONS FOR EMBEDS */
.glow-border {
    animation: glow-pulse 4s infinite alternate;
}

@keyframes glow-pulse {
    0% {
        box-shadow: 0 0 10px rgba(109, 106, 246, 0.1);
    }
    100% {
        box-shadow: 0 0 20px rgba(45, 217, 232, 0.2);
    }
}

/* LOGO SWIRL SPINNING AND PULSING ANIMATIONS */
@keyframes spin-slow {
    from {
        transform: rotate(0deg);
    }
    to {
        transform: rotate(360deg);
    }
}

@keyframes spin-reverse-slower {
    from {
        transform: rotate(360deg);
    }
    to {
        transform: rotate(0deg);
    }
}

.animate-spin-slow {
    animation: spin-slow 20s linear infinite;
    transform-origin: center;
}

.animate-spin-reverse-slower {
    animation: spin-reverse-slower 30s linear infinite;
    transform-origin: center;
}

/* Hide scrollbars but keep functionality */
.no-scrollbar::-webkit-scrollbar { display: none; }
.no-scrollbar { -ms-overflow-style: none; scrollbar-width: none; }

::selection { background: rgba(109,106,246,0.35); }

html { scroll-behavior: smooth; }

/* ============================================================
   TOAST NOTIFICATIONS
   Replaces native alert()/confirm() popups, which block the whole
   tab and look nothing like the rest of the UI, with an in-theme
   stack that appears/dismisses without interrupting the user.
   ============================================================ */
#toast-stack {
    position: fixed;
    top: 1.5rem;
    right: 1.5rem;
    z-index: 9998;
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    width: min(360px, calc(100vw - 3rem));
    pointer-events: none;
}

.toast {
    pointer-events: auto;
    display: flex;
    align-items: flex-start;
    gap: 0.75rem;
    padding: 0.875rem 1rem;
    border-radius: 0.875rem;
    background: linear-gradient(135deg, rgba(19, 21, 28, 0.97) 0%, rgba(10, 11, 16, 0.98) 100%);
    -webkit-backdrop-filter: blur(16px) saturate(140%);
    backdrop-filter: blur(16px) saturate(140%);
    border: 1px solid rgba(148, 163, 220, 0.15);
    box-shadow: 0 8px 30px rgba(0, 0, 0, 0.5);
    font-size: 0.8125rem;
    color: var(--text-mid);
    transform: translateX(calc(100% + 1.5rem));
    opacity: 0;
    transition: transform 0.35s cubic-bezier(0.16, 1, 0.3, 1), opacity 0.35s ease;
}

.toast.toast-visible {
    transform: translateX(0);
    opacity: 1;
}

.toast-icon {
    flex-shrink: 0;
    width: 1.5rem;
    height: 1.5rem;
    border-radius: 9999px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0.75rem;
}

.toast-success .toast-icon { background: rgba(52, 226, 161, 0.15); color: var(--emerald); }
.toast-error .toast-icon { background: rgba(251, 111, 146, 0.15); color: var(--rose); }
.toast-warning .toast-icon { background: rgba(245, 183, 77, 0.15); color: var(--amber); }
.toast-info .toast-icon { background: rgba(45, 217, 232, 0.15); color: var(--cyan); }

.toast-success { border-color: rgba(52, 226, 161, 0.25); }
.toast-error { border-color: rgba(251, 111, 146, 0.25); }
.toast-warning { border-color: rgba(245, 183, 77, 0.25); }
.toast-info { border-color: rgba(45, 217, 232, 0.25); }

.toast-message { flex: 1; line-height: 1.4; padding-top: 0.1rem; }

.toast-close {
    flex-shrink: 0;
    background: none;
    border: none;
    color: var(--text-low);
    cursor: pointer;
    padding: 0;
    font-size: 0.75rem;
    line-height: 1;
    transition: color 0.2s ease;
}

.toast-close:hover { color: var(--text-hi); }

/* ============================================================
   MODAL TRANSITIONS
   The old approach toggled `hidden`/`flex` directly, so modals
   just snapped into existence. This fades the backdrop in and
   scales the panel up, and reverses it on the way out so JS can
   wait for the transition before actually hiding the element.
   ============================================================ */
.modal-overlay {
    transition: opacity 0.25s ease;
    opacity: 0;
}

.modal-overlay.modal-open {
    opacity: 1;
}

.modal-overlay .modal-panel {
    transition: transform 0.3s cubic-bezier(0.16, 1, 0.3, 1), opacity 0.3s ease;
    transform: scale(0.94) translateY(8px);
    opacity: 0;
}

.modal-overlay.modal-open .modal-panel {
    transform: scale(1) translateY(0);
    opacity: 1;
}

/* ============================================================
   SKELETON LOADING STATES
   A plain "Loading..." string causes a layout-shifting text swap
   the instant data arrives. A shimmer bar sized like the eventual
   content reads as "this is loading" at a glance and swaps out
   without the jump.
   ============================================================ */
.skeleton-bar {
    display: inline-block;
    height: 1.5rem;
    width: 4.5rem;
    border-radius: 0.375rem;
    background: linear-gradient(90deg, rgba(148, 163, 220, 0.08) 25%, rgba(148, 163, 220, 0.18) 37%, rgba(148, 163, 220, 0.08) 63%);
    background-size: 400% 100%;
    animation: skeletonShimmer 1.6s ease-in-out infinite;
    vertical-align: middle;
}

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

/* ============================================================
   ACCESSIBLE KEYBOARD FOCUS
   Buttons/links only had hover treatment - a keyboard user tabbing
   through the dashboard had no way to see where focus was. This
   restores a visible ring on keyboard focus only (not on mouse
   click) so pointer users see no visual change.
   ============================================================ */
a:focus-visible,
button:focus-visible,
input:focus-visible,
textarea:focus-visible,
select:focus-visible,
.btn-primary:focus-visible,
.btn-secondary:focus-visible,
.btn-glass:focus-visible,
.btn-gradient-cyan:focus-visible,
.btn-upgrade:focus-visible,
.nav-link:focus-visible,
.util-icon-btn:focus-visible,
.avatar-btn:focus-visible,
.app-nav-link:focus-visible,
.app-sidebar-toggle:focus-visible {
    outline: 2px solid var(--cyan);
    outline-offset: 2px;
    border-radius: 0.375rem;
}

/* ============================================================
   REDUCED MOTION
   Respect the OS-level "reduce motion" preference: keep the
   overall dark theme intact but stop the ambient grid pulse, orb
   drift, and glitch/scanline effects, which are exactly the kind
   of continuous motion that setting exists to opt out of.
   ============================================================ */
/* ============================================================
   PRIMARY NAVIGATION
   Bigger, clearer wayfinding for the top nav bar. Previously every
   link looked identical whether or not it was the current page, so
   there was no way to tell where you were in the app - .nav-link
   now gets an explicit .active state (filled gradient + glow) so
   the current section is unmistakable at a glance.
   ============================================================ */
.nav-bar {
    padding: 0.5rem;
    border-radius: 1rem;
    position: relative;
}

.nav-bar::after {
    content: '';
    position: absolute;
    left: 1rem;
    right: 1rem;
    bottom: -1px;
    height: 1px;
    background: linear-gradient(90deg, transparent, rgba(45, 217, 232, 0.35), rgba(109, 106, 246, 0.35), transparent);
}

.nav-link {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.7rem 1.125rem;
    border-radius: 0.75rem;
    font-family: "JetBrains Mono", monospace;
    font-size: 0.75rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--text-mid);
    border: 1px solid transparent;
    transition: all 0.25s ease;
    white-space: nowrap;
}

.nav-link:hover {
    color: var(--text-hi);
    background: rgba(255, 255, 255, 0.05);
    border-color: rgba(148, 163, 220, 0.15);
}

.nav-link .nav-link-icon {
    width: 1.125rem;
    height: 1.125rem;
    flex-shrink: 0;
    transition: filter 0.25s ease;
}

.nav-link.active {
    color: #08090d;
    background: linear-gradient(135deg, var(--indigo) 0%, var(--cyan) 100%);
    border-color: transparent;
    box-shadow: 0 0 18px rgba(45, 217, 232, 0.35), 0 2px 8px rgba(0, 0, 0, 0.3);
}

.nav-link.active .nav-link-icon {
    filter: brightness(0) saturate(100%);
    opacity: 0.85;
}

/* ============================================================
   UTILITY CLUSTER (status / language / notifications / avatar)
   Bumped to a consistent 40px control height so this row reads
   as one deliberate row of controls instead of a cluster of
   mismatched pill sizes.
   ============================================================ */
.util-pill {
    height: 2.5rem;
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0 1rem;
    border-radius: 9999px;
    background: rgba(14, 16, 23, 0.85);
    -webkit-backdrop-filter: blur(12px);
    backdrop-filter: blur(12px);
    border: 1px solid rgba(148, 163, 220, 0.15);
    font-family: "JetBrains Mono", monospace;
    font-size: 0.6875rem;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--text-mid);
    transition: all 0.25s ease;
}

.util-icon-btn {
    height: 2.5rem;
    width: 2.5rem;
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 9999px;
    background: rgba(14, 16, 23, 0.85);
    -webkit-backdrop-filter: blur(12px);
    backdrop-filter: blur(12px);
    border: 1px solid rgba(148, 163, 220, 0.15);
    color: var(--text-mid);
    cursor: pointer;
    transition: all 0.25s ease;
    position: relative;
}

.util-icon-btn:hover {
    color: var(--text-hi);
    border-color: rgba(45, 217, 232, 0.4);
    box-shadow: 0 0 15px rgba(45, 217, 232, 0.15);
}

.util-icon-btn .util-badge {
    position: absolute;
    top: 0.35rem;
    right: 0.35rem;
    width: 0.5rem;
    height: 0.5rem;
    border-radius: 9999px;
    background: var(--rose);
    box-shadow: 0 0 6px var(--rose);
}

/* Avatar / profile menu trigger - replaces the plain text "MORE"
   hamburger with something that reads as "this is you", the way
   Discord/Linear/Vercel all put account-level nav behind an
   avatar rather than a loose text link. */
.avatar-btn {
    height: 2.5rem;
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.25rem 0.75rem 0.25rem 0.25rem;
    border-radius: 9999px;
    background: rgba(14, 16, 23, 0.85);
    -webkit-backdrop-filter: blur(12px);
    backdrop-filter: blur(12px);
    border: 1px solid rgba(148, 163, 220, 0.15);
    cursor: pointer;
    transition: all 0.25s ease;
}

.avatar-btn:hover {
    border-color: rgba(109, 106, 246, 0.5);
    box-shadow: 0 0 15px rgba(109, 106, 246, 0.2);
}

.avatar-btn img,
.avatar-btn .avatar-fallback {
    width: 2rem;
    height: 2rem;
    border-radius: 9999px;
    object-fit: cover;
    flex-shrink: 0;
}

.avatar-btn .avatar-fallback {
    display: flex;
    align-items: center;
    justify-content: center;
    background: linear-gradient(135deg, var(--indigo) 0%, var(--cyan) 100%);
    color: #08090d;
    font-family: "Chakra Petch", sans-serif;
    font-weight: 700;
    font-size: 0.75rem;
}

.avatar-btn .avatar-name {
    font-family: "JetBrains Mono", monospace;
    font-size: 0.6875rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--text-mid);
    max-width: 6rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.avatar-btn:hover .avatar-name {
    color: var(--text-hi);
}

/* ============================================================
   APP SHELL
   Persistent left sidebar + slim topbar, replacing the old
   per-page top nav row that had to cram brand, primary nav, and
   the whole utility cluster into one horizontal strip. Rendered
   once in base.html instead of copy-pasted (with drifting markup)
   into six separate page templates.
   ============================================================ */
.app-shell {
    display: flex;
    min-height: 100vh;
    position: relative;
    z-index: 1;
}

.app-sidebar {
    width: 17rem;
    flex-shrink: 0;
    display: flex;
    flex-direction: column;
    background: linear-gradient(180deg, rgba(13, 15, 23, 0.97) 0%, rgba(8, 9, 13, 0.98) 100%);
    border-right: 1px solid rgba(148, 163, 220, 0.1);
    /* Was position:fixed - a full-height, always-mounted, high-z-index
       layer with continuously-animating children (spinning logo, pulse-dot,
       status ping) inside it. That combination is a known GPU compositor
       trigger: the browser keeps it on its own layer permanently and would
       periodically re-promote/mis-scale it, blowing up whichever icon it
       was rendering at that moment to fill the viewport for a frame or two.
       Removing backdrop-filter alone (see git history) didn't stop it, so
       this removes position:fixed itself on desktop, where the sidebar is
       visible essentially 100% of the time. sticky keeps the exact same
       pinned-while-scrolling look, but the element is a normal flex child
       instead of a floating always-on compositor layer - .app-main no
       longer needs its old margin-left:17rem offset hack because of this.
       Mobile keeps position:fixed (see the max-width:1023px block below)
       since there it's a short-lived, user-toggled overlay drawer rather
       than something permanently mounted, so it isn't the same risk. */
    position: sticky;
    top: 0;
    height: 100vh;
    z-index: 50;
    transition: transform 0.3s cubic-bezier(0.16, 1, 0.3, 1);
}

.app-sidebar-brand {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 1.75rem 1.5rem 1.5rem;
    border-bottom: 1px solid rgba(148, 163, 220, 0.08);
}

.app-sidebar-nav {
    flex: 1;
    overflow-y: auto;
    padding: 1.25rem 1rem;
    display: flex;
    flex-direction: column;
    gap: 0.375rem;
}

.app-nav-link {
    display: flex;
    align-items: center;
    gap: 0.875rem;
    padding: 0.8rem 1rem;
    border-radius: 0.75rem;
    font-family: "Chakra Petch", sans-serif;
    font-size: 0.875rem;
    font-weight: 600;
    letter-spacing: 0.02em;
    color: var(--text-mid);
    border-left: 2px solid transparent;
    transition: all 0.2s ease;
    position: relative;
}

.app-nav-link .app-nav-icon {
    width: 1.25rem;
    height: 1.25rem;
    flex-shrink: 0;
}

.app-nav-link:hover {
    color: var(--text-hi);
    background: rgba(255, 255, 255, 0.04);
}

.app-nav-link.active {
    color: var(--text-hi);
    background: linear-gradient(90deg, rgba(45, 217, 232, 0.14) 0%, rgba(109, 106, 246, 0.05) 100%);
    border-left-color: var(--cyan);
    box-shadow: inset 0 0 20px rgba(45, 217, 232, 0.06);
}

.app-nav-link.active::after {
    content: '';
    position: absolute;
    right: 1rem;
    top: 50%;
    transform: translateY(-50%);
    width: 0.375rem;
    height: 0.375rem;
    border-radius: 9999px;
    background: var(--cyan);
    box-shadow: 0 0 8px var(--cyan);
}

.app-sidebar-footer {
    padding: 1rem 1.5rem 1.5rem;
    border-top: 1px solid rgba(148, 163, 220, 0.08);
}

.app-sidebar-collapse-btn {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    width: 100%;
    padding: 0.7rem 1rem;
    border-radius: 0.75rem;
    background: transparent;
    border: 1px solid rgba(148, 163, 220, 0.12);
    color: var(--text-mid);
    font-family: "Chakra Petch", sans-serif;
    font-size: 0.8rem;
    font-weight: 600;
    letter-spacing: 0.02em;
    cursor: pointer;
    transition: all 0.2s ease;
}

.app-sidebar-collapse-btn:hover {
    color: var(--text-hi);
    border-color: var(--cyan);
    background: rgba(255, 255, 255, 0.03);
}

.app-sidebar-collapse-icon {
    width: 1.1rem;
    height: 1.1rem;
    flex-shrink: 0;
    transition: transform 0.3s ease;
}

/* Collapsed state - desktop only (see the max-width:1023px block below,
   which never adds this class; the mobile drawer already has its own
   fully-hidden/fully-shown behavior and doesn't need an icon-only middle
   state). Shrinks the sidebar to just enough room for the icons, hides
   every text label via .app-nav-label/.app-sidebar-brand-text, and
   flips the collapse icon to point the other way. */
@media (min-width: 1024px) {
    .app-sidebar.collapsed {
        width: 5.25rem;
    }

    .app-sidebar.collapsed .app-sidebar-brand-text,
    .app-sidebar.collapsed .app-nav-label {
        display: none;
    }

    .app-sidebar.collapsed .app-sidebar-brand {
        justify-content: center;
        padding-left: 0.75rem;
        padding-right: 0.75rem;
    }

    .app-sidebar.collapsed .app-nav-link {
        justify-content: center;
        padding-left: 0;
        padding-right: 0;
    }

    .app-sidebar.collapsed .app-nav-link.active::after {
        display: none;
    }

    .app-sidebar.collapsed .app-sidebar-footer {
        padding-left: 0.75rem;
        padding-right: 0.75rem;
    }

    .app-sidebar.collapsed .app-sidebar-collapse-btn {
        justify-content: center;
        padding-left: 0;
        padding-right: 0;
    }

    .app-sidebar.collapsed .app-sidebar-collapse-icon {
        transform: rotate(180deg);
    }
}

.app-sidebar-backdrop {
    display: none;
    position: fixed;
    inset: 0;
    background: rgba(3, 3, 5, 0.7);
    -webkit-backdrop-filter: blur(2px);
    backdrop-filter: blur(2px);
    z-index: 40;
}

.app-sidebar-backdrop.open {
    display: block;
}

.app-main {
    flex: 1;
    display: flex;
    flex-direction: column;
    min-width: 0;
    /* No margin-left offset needed anymore - the sidebar is a real flex
       child now (position:sticky, not fixed), so it already takes up its
       own 17rem in the row instead of being pulled out of flow. */
}

.app-topbar {
    position: sticky;
    top: 0;
    z-index: 30;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 1rem 1.5rem;
    background: rgba(10, 11, 16, 0.85);
    -webkit-backdrop-filter: blur(16px) saturate(140%);
    backdrop-filter: blur(16px) saturate(140%);
    border-bottom: 1px solid rgba(148, 163, 220, 0.08);
}

.app-sidebar-toggle {
    display: none;
    height: 2.5rem;
    width: 2.5rem;
    align-items: center;
    justify-content: center;
    border-radius: 0.75rem;
    background: rgba(255, 255, 255, 0.04);
    border: 1px solid rgba(148, 163, 220, 0.15);
    color: var(--text-hi);
    flex-shrink: 0;
    cursor: pointer;
}

.app-content {
    flex: 1;
    padding: 1.75rem 1.5rem 3rem;
}

@media (max-width: 1023px) {
    .app-sidebar {
        /* Back to position:fixed here specifically - on mobile this is a
           short-lived, user-toggled overlay drawer (closed most of the
           time), not something permanently mounted, so it needs to be
           pulled out of flow entirely rather than reserving 17rem of a
           row nobody sees, and needs fixed's full-viewport top/bottom
           to slide in as an overlay instead of pushing content. */
        position: fixed;
        top: 0;
        bottom: 0;
        left: 0;
        height: auto;
        transform: translateX(-100%);
    }

    .app-sidebar.open {
        transform: translateX(0);
        box-shadow: 0 0 40px rgba(0, 0, 0, 0.6);
    }

    .app-sidebar-toggle {
        display: inline-flex;
    }
}

@media (min-width: 1024px) {
    .app-sidebar-backdrop {
        display: none !important;
    }
}

@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }

    .grid-field,
    .glow-orb,
    .glow-orb-2,
    .glow-orb-3,
    .particle-field,
    .pulse-dot::after,
    .status-dot::before,
    .system-badge .dot,
    .server-status-light.online,
    .animate-spin-slow,
    .animate-spin-reverse-slower,
    .skeleton-bar {
        animation: none !important;
    }

    .animate-fade-in-up,
    .animate-fade-in-scale,
    .animate-slide-in-left,
    .animate-slide-in-right {
        animation-duration: 0.01ms !important;
        opacity: 1 !important;
    }

    .toast,
    .modal-overlay,
    .modal-overlay .modal-panel,
    .btn-primary,
    .btn-upgrade,
    .panel,
    .bracket-frame::before,
    .bracket-frame::after,
    .nav-link,
    .util-icon-btn,
    .avatar-btn,
    .app-sidebar,
    .app-nav-link {
        transition: none !important;
    }
}
