/* ============================================================
   xPulse Chat – base.css
   Custom Properties · Reset · Typography · Noise · Animations
   ============================================================ */

/* ── Custom Properties ── */
:root {
    --bg:            #0d0d0d;
    --surface:       #141414;
    --border:        #222;
    --muted:         #444;
    --text:          #c8c8c8;
    --text-dim:      #555;
    --accent:        #8703b0;
    --accent2:       #7eb8a4;
    --danger:        #c0606a;
    --mono:          'JetBrains Mono', ui-monospace, 'Cascadia Code', 'Fira Code', Consolas, monospace;
    --serif:         'Fraunces', Georgia, ui-serif, serif;
    --sidebar-width: 230px;
    --topbar-height: 46px;
}

/* ── Reset ── */
*, *::before, *::after {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}

/* ── Base ── */
html, body {
    height: 100%;
    min-height: -webkit-fill-available;
    background: var(--bg);
    color: var(--text);
    font-family: var(--mono);
    font-size: 13px;
    line-height: 1.6;
    overflow: hidden;
}

/* ── Noise Overlay ── */
body::before {
    content: '';
    position: fixed;
    inset: 0;
    background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.03'/%3E%3C/svg%3E");
    pointer-events: none;
    z-index: 9999;
    opacity: 0.4;
}

/* ── Animations ── */
@keyframes fadeIn     { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } }
@keyframes msgIn      { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: translateY(0); } }
@keyframes pulse-dim  { 0%, 100% { opacity: 0.4; } 50% { opacity: 1; } }
@keyframes dots       { 0% { content: ''; } 33% { content: '.'; } 66% { content: '..'; } 100% { content: '...'; } }
@keyframes shake      { 0%, 100% { transform: translateX(0); } 25% { transform: translateX(-6px); } 75% { transform: translateX(6px); } }
@keyframes spin       { to { transform: rotate(360deg); } }
@keyframes typingBounce { 0%, 60%, 100% { transform: translateY(0); opacity: 0.4; } 30% { transform: translateY(-4px); opacity: 1; } }

/* ── Update Banner ── */
.update-banner {
    position: fixed;
    bottom: 1.2rem;
    left: 50%;
    transform: translateX(-50%);
    display: flex;
    align-items: center;
    gap: 0.75rem;
    background: var(--surface);
    border: 1px solid var(--accent);
    border-radius: 2px;
    padding: 0.65rem 1rem;
    z-index: 9998;
    box-shadow: 0 4px 24px rgba(0,0,0,0.5);
    animation: fadeIn 0.3s ease both;
    white-space: nowrap;
}

.update-banner.hidden { display: none; }

.update-banner-text {
    font-size: 12px;
    color: var(--text);
    letter-spacing: 0.04em;
}

.update-banner-btn {
    background: var(--accent);
    border: none;
    color: #fff;
    font-family: var(--mono);
    font-size: 11px;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    padding: 0.35rem 0.75rem;
    border-radius: 2px;
    cursor: pointer;
    transition: opacity 0.15s;
    flex-shrink: 0;
}
.update-banner-btn:hover { opacity: 0.85; }

.update-banner-dismiss {
    background: none;
    border: none;
    color: var(--text-dim);
    font-size: 14px;
    cursor: pointer;
    padding: 0.1rem;
    line-height: 1;
    flex-shrink: 0;
    transition: color 0.15s;
}
.update-banner-dismiss:hover { color: var(--text); }

@media (max-width: 480px) {
    .update-banner {
        left: 1rem;
        right: 1rem;
        bottom: calc(1rem + env(safe-area-inset-bottom));
        transform: none;
        white-space: normal;
    }
}
