    /* ═══════════════════════════════════════
   IPERFECT.NET — FINAL UI THEME
   Matching preview.html design system
═══════════════════════════════════════ */
    :root {
        --white: #ffffff;
        --gray-50: #f9fafb;
        --gray-100: #f3f4f6;
        --gray-200: #e5e7eb;
        --gray-300: #d1d5db;
        --gray-400: #9ca3af;
        --gray-500: #6b7280;
        --gray-600: #4b5563;
        --gray-700: #374151;
        --gray-800: #1f2937;
        --gray-900: #111827;
        --blue-50: #eff6ff;
        --blue-100: #dbeafe;
        --blue-400: #60a5fa;
        --blue-500: #3b82f6;
        --blue-600: #2563eb;
        --blue-700: #1d4ed8;
        --indigo-500: #6366f1;
        --emerald-500: #10b981;
        --amber-500: #f59e0b;
        --red-500: #ef4444;
        --bg: var(--gray-50);
        --surface: var(--white);
        --sidebar: var(--gray-900);
        --accent: var(--blue-600);
        --accent-h: var(--blue-700);
        --border: var(--gray-200);
        --text: var(--gray-900);
        --sub: var(--gray-500);
        --mono: 'DM Mono', 'Courier New', monospace;
        --sans: 'DM Sans', system-ui, sans-serif;
        --r: 10px;
        --r-sm: 6px;
        --sh: 0 1px 2px rgba(0, 0, 0, .06), 0 1px 3px rgba(0, 0, 0, .08);
        --sh-md: 0 4px 6px -1px rgba(0, 0, 0, .07), 0 2px 4px -1px rgba(0, 0, 0, .05);
        --sh-lg: 0 10px 25px -5px rgba(0, 0, 0, .1), 0 8px 10px -6px rgba(0, 0, 0, .05);
        --cosmic-bg: #06080f;
        --sidebar-bg: rgba(12, 16, 25, 0.82);
        --sidebar-glass-border: rgba(255, 255, 255, 0.1);
        --sidebar-muted: #8b95b0;
        --sidebar-text: #eef2ff;
        --sidebar-accent: #00d4ff;
        --r-lg: 24px;
        --ease: cubic-bezier(0.22, 1, 0.36, 1);
        --sh-lg-cosmic: 0 24px 64px rgba(0, 0, 0, 0.45), 0 0 40px rgba(0, 212, 255, 0.08);
    }

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

    html {
        scroll-behavior: smooth
    }

    html,
    body {
        font-family: var(--sans) !important;
        font-size: 14px;
        line-height: 1.6;
        background: #ffffff !important;
        color: var(--text) !important;
        -webkit-font-smoothing: antialiased;
        position: relative;
        min-height: 100vh;
        overflow-x: hidden;
    }

    html[data-theme="dark"],
    html[data-theme="dark"] body {
        background: var(--cosmic-bg) !important;
    }

    /* ── testgrok ambient ── */
    /* noise + orbs stay dark-mode only; the network dot animation shows in both themes */
    .noise,
    .orb {
        display: none;
    }
    #network-canvas {
        display: block;
    }
    .noise {
        position: fixed;
        inset: 0;
        pointer-events: none;
        z-index: 9999;
        opacity: 0.035;
        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.85' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
    }
    .orb, .ip-orb {
        position: fixed;
        border-radius: 50%;
        filter: blur(80px);
        pointer-events: none;
        z-index: 0;
    }
    .orb-1, .ip-orb-1 { width: 520px; height: 520px; background: rgba(0, 212, 255, 0.12); top: -120px; right: -80px; }
    .orb-2, .ip-orb-2 { width: 400px; height: 400px; background: rgba(124, 58, 237, 0.14); bottom: 20%; left: -100px; }
    .orb-3, .ip-orb-3 { width: 300px; height: 300px; background: rgba(34, 211, 168, 0.1); top: 45%; right: 10%; }
    #network-canvas {
        position: fixed;
        inset: 0;
        width: 100%;
        height: 100%;
        /* opacity handled in the draw loop per-theme for star vs soft-network look */
        opacity: 1;
        pointer-events: none;
        z-index: 0;
    }
    html[data-theme="dark"] .noise,
    html[data-theme="dark"] .orb {
        display: block;
    }
    .ip-topbar, .ip-content, .ip-celebration, .ip-bottom-nav { position: relative; z-index: 1; }

    /* ── TOPBAR ── */
    .ip-topbar {
        position: sticky;
        top: 0;
        z-index: 200;
        background: rgba(255, 255, 255, .88);
        backdrop-filter: blur(14px);
        -webkit-backdrop-filter: blur(14px);
        border-bottom: 1px solid var(--border);
        box-shadow: var(--sh);
    }

    .ip-topbar-inner {
        display: flex;
        align-items: center;
        justify-content: space-between;
        max-width: 1180px;
        margin: 0 auto;
        width: min(1180px, calc(100% - 48px));
        padding: 0 24px;
        height: 62px;
        gap: 16px;
    }

    .ip-logo {
        display: flex;
        align-items: center;
        gap: 10px;
        text-decoration: none !important
    }

    .ip-logo-icon {
        width: 34px;
        height: 34px;
        background: linear-gradient(135deg, var(--blue-600), var(--indigo-500));
        border-radius: 8px;
        display: flex;
        align-items: center;
        justify-content: center;
        color: #fff;
        font-weight: 700;
        font-size: 13px;
        letter-spacing: -.5px;
        box-shadow: 0 2px 8px rgba(37, 99, 235, .35);
        flex-shrink: 0;
    }

    .ip-logo-text {
        font-size: 15px;
        font-weight: 700;
        color: var(--gray-900);
        line-height: 1.2
    }

    .ip-logo-dot {
        color: var(--blue-600)
    }

    .ip-logo-slogan {
        font-size: 10px;
        color: var(--gray-400);
        font-style: italic;
        line-height: 1.2
    }

    .ip-pill {
        display: flex;
        align-items: center;
        gap: 5px;
        background: #ecfdf5;
        border: 1px solid #a7f3d0;
        color: #065f46;
        font-size: 11px;
        font-weight: 600;
        padding: 4px 10px;
        border-radius: 100px;
        cursor: pointer;
        user-select: none;
        transition: background .15s;
    }
    .ip-pill:hover { background: #d1fae5; }
    /* The half of the pill that explains the number. It is the first thing
       to go when the topbar runs out of room: the count is the fact, the
       sentence is the help, and the title carries the whole of it anyway. */
    .ip-pill-more { font-weight: 500; opacity: .85; }
    @media (max-width: 640px) { .ip-pill-more { display: none !important; } }
    @keyframes ip-flash-green {
        0%, 100% { background: #ecfdf5; border-color: #a7f3d0; }
        50%      { background: #bbf7d0; border-color: #4ade80; }
    }
    @keyframes ip-flash-red {
        0%, 100% { background: #ecfdf5; border-color: #a7f3d0; }
        50%      { background: #fecaca; border-color: #f87171; }
    }
    .ip-pill.flash-up   { animation: ip-flash-green 1s ease-in-out 5; }
    .ip-pill.flash-down { animation: ip-flash-red   1s ease-in-out 5; }



    /* ── Missed calls: topbar pill + its popup ──
       The same shape as the online pill next to it, in red rather than
       green, and hidden outright when there is nothing missed — a badge
       that is always on screen stops being a badge. `unseen` is the only
       thing that separates a call the user has not looked at yet from the
       history below it. */
    .ip-miss-pill {
        background: #fef2f2;
        border-color: #fecaca;
        color: #991b1b;
        display: none;            /* paint() shows it once there is one */
    }
    .ip-miss-pill:hover { background: #fee2e2; }
    .ip-miss-pill.unseen { animation: ip-miss-throb 1.6s ease-in-out infinite; }
    .ip-miss-pill .ip-miss-ico { font-size: 12px; line-height: 1; }
    @keyframes ip-miss-throb {
        0%, 100% { background: #fef2f2; border-color: #fecaca; }
        50%      { background: #fecaca; border-color: #f87171; }
    }
    @media (prefers-reduced-motion: reduce) {
        .ip-miss-pill.unseen { animation: none; background: #fecaca; border-color: #f87171; }
    }

    #ip-missed-popup {
        display: none;
        position: fixed;
        top: 52px;
        right: 16px;
        z-index: 9999;
        background: #ffffff;
        border: 1px solid var(--border, #e5e7eb);
        border-radius: 12px;
        box-shadow: 0 8px 32px rgba(0,0,0,.15);
        min-width: 280px;
        max-width: 380px;
        font-size: 13px;
        overflow: hidden;
    }
    #ip-missed-popup.open { display: block; }
    #ip-missed-body, #voip-missed-body { max-height: 340px; overflow-y: auto; }
    .ip-miss-clear {
        background: none;
        border: 0;
        padding: 0 8px 0 0;
        font-size: 11.5px;
        font-weight: 600;
        color: var(--red-600, #dc2626);
        cursor: pointer;
    }
    .ip-miss-clear:hover { text-decoration: underline; }
    .ip-miss-row {
        display: flex;
        align-items: flex-start;
        gap: 10px;
        padding: 10px 16px;
        border-bottom: 1px solid var(--border, #f3f4f6);
    }
    .ip-miss-row:last-child { border-bottom: none; }
    /* A call not yet looked at, marked down the edge rather than by colouring
       the row: the rows below it are still perfectly readable history. */
    .ip-miss-row.fresh { border-left: 3px solid var(--red-600, #dc2626); padding-left: 13px; }
    .ip-miss-flag { font-size: 20px; line-height: 1.2; }
    .ip-miss-info { flex: 1; min-width: 0; }
    .ip-miss-name {
        font-weight: 600;
        color: var(--text, #111);
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }
    .ip-miss-sub, .ip-miss-when {
        font-size: 11.5px;
        color: var(--muted, #6b7280);
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }
    .ip-miss-acts { display: flex; align-items: center; gap: 6px; flex: 0 0 auto; }
    .ip-miss-back {
        display: inline-flex !important;
        align-items: center !important;
        gap: 4px !important;
        padding: 6px 9px !important;
        font-size: 11.5px !important;
        font-weight: 600 !important;
        line-height: 1.2 !important;
        color: #fff !important;
        background: var(--blue-600, #2563eb) !important;
        border: 1px solid var(--blue-600, #2563eb) !important;
        border-radius: 8px !important;
        box-shadow: none !important;
        cursor: pointer !important;
    }
    .ip-miss-back:hover {
        background: var(--blue-700, #1d4ed8) !important;
        border-color: var(--blue-700, #1d4ed8) !important;
        color: #fff !important;
    }
    .ip-miss-del {
        background: none;
        border: 0;
        padding: 2px 4px;
        font-size: 13px;
        line-height: 1;
        color: #9ca3af;
        cursor: pointer;
    }
    .ip-miss-del:hover { color: var(--red-600, #dc2626); }
    .ip-miss-empty { padding: 16px; color: var(--muted, #6b7280); font-size: 12.5px; }


    html[data-theme="dark"] .ip-miss-pill { background: #450a0a; border-color: #7f1d1d; color: #fca5a5; }
    html[data-theme="dark"] .ip-miss-pill:hover { background: #7f1d1d; }
    html[data-theme="dark"] .ip-miss-pill.unseen { animation: ip-miss-throb-dark 1.6s ease-in-out infinite; }
    @keyframes ip-miss-throb-dark {
        0%, 100% { background: #450a0a; border-color: #7f1d1d; }
        50%      { background: #7f1d1d; border-color: #b91c1c; }
    }
    @media (prefers-reduced-motion: reduce) {
        html[data-theme="dark"] .ip-miss-pill.unseen { animation: none; background: #7f1d1d; border-color: #b91c1c; }
    }
    html[data-theme="dark"] #ip-missed-popup { background: #1e293b; border-color: #334155; box-shadow: 0 8px 32px rgba(0,0,0,.5); }
    html[data-theme="dark"] .ip-miss-row { border-bottom-color: #334155; }
    html[data-theme="dark"] .ip-miss-name { color: #e2e8f0; }
    html[data-theme="dark"] .ip-miss-sub, html[data-theme="dark"] .ip-miss-when { color: #94a3b8; }

    /* Online users popup */
    #ip-online-popup {
        display: none;
        position: fixed;
        top: 52px;
        right: 16px;
        z-index: 9999;
        background: #ffffff;
        border: 1px solid var(--border, #e5e7eb);
        border-radius: 12px;
        box-shadow: 0 8px 32px rgba(0,0,0,.15);
        min-width: 280px;
        max-width: 360px;
        font-size: 13px;
        overflow: hidden;
    }
    #ip-online-popup.open { display: block; }
    .ip-popup-hdr {
        display: flex;
        align-items: center;
        justify-content: space-between;
        padding: 12px 16px 8px;
        border-bottom: 1px solid var(--border, #e5e7eb);
        font-weight: 700;
        font-size: 13px;
        color: var(--text, #111);
    }
    .ip-popup-close {
        cursor: pointer;
        font-size: 16px;
        line-height: 1;
        color: #888;
        background: none;
        border: none;
        padding: 0 2px;
    }
    .ip-popup-close:hover { color: #333; }

    /* ── Dial an app user by username, inside the popup ──
       The list below only reaches people who happen to be here right now;
       an app user is reachable by name even with the app closed. Same
       resolve-then-dial path as the VoIP tab's card, shrunk to fit here.
       The buttons repeat the global `button` rule's !important properties
       because that rule is declared later and would otherwise paint them
       as plain white boxes. */
    .ip-popup-dial {
        padding: 10px 16px;
        border-bottom: 1px solid var(--border, #e5e7eb);
        background: var(--gray-50, #f9fafb);
    }
    .ip-popup-dial-lbl {
        margin-bottom: 6px;
        font-size: 11px;
        font-weight: 600;
        letter-spacing: .02em;
        color: #6b7280;
    }
    .ip-popup-dial-row { display: flex; gap: 6px; align-items: center; }
    .ip-popup-dial-at {
        display: inline-flex;
        align-items: center;
        flex: 1 1 auto;
        min-width: 0;
        background: #fff;
        border: 1px solid var(--border, #d1d5db);
        border-radius: 8px;
        transition: border-color .15s, box-shadow .15s;
    }
    .ip-popup-dial-at:focus-within {
        border-color: var(--blue-600, #2563eb);
        box-shadow: 0 0 0 3px rgba(37, 99, 235, .15);
    }
    .ip-popup-dial-at span { padding: 0 1px 0 9px; font-size: 12.5px; color: #6b7280; }
    .ip-popup-dial-input {
        flex: 1 1 auto;
        min-width: 0;
        width: 100%;
        padding: 7px 8px 7px 2px;
        font-size: 12.5px;
        color: var(--text, #111);
        background: transparent;
        border: 0;
        outline: none;
    }
    .ip-popup-dial-btn {
        flex: 0 0 auto;
        display: inline-flex !important;
        align-items: center !important;
        justify-content: center !important;
        gap: 4px !important;
        padding: 7px 10px !important;
        font-size: 12px !important;
        font-weight: 600 !important;
        line-height: 1.2 !important;
        color: #fff !important;
        border: 1px solid transparent !important;
        border-radius: 8px !important;
        box-shadow: none !important;
        cursor: pointer !important;
    }
    .ip-popup-dial-btn.call {
        background: var(--blue-600, #2563eb) !important;
        border-color: var(--blue-600, #2563eb) !important;
    }
    .ip-popup-dial-btn.call:hover {
        background: var(--blue-700, #1d4ed8) !important;
        border-color: var(--blue-700, #1d4ed8) !important;
        color: #fff !important;
    }
    .ip-popup-dial-btn.msg {
        background: var(--emerald-600, #059669) !important;
        border-color: var(--emerald-600, #059669) !important;
    }
    .ip-popup-dial-btn.msg:hover {
        background: var(--emerald-700, #047857) !important;
        border-color: var(--emerald-700, #047857) !important;
        color: #fff !important;
    }
    .ip-popup-dial-btn:disabled { opacity: .55 !important; cursor: default !important; }
    .ip-popup-dial .voip-dial-note {
        margin-top: 6px;
        font-size: 11.5px;
        line-height: 1.4;
        min-height: 0;
        white-space: normal;
    }
    .ip-popup-dial .voip-dial-note:empty { display: none; }
    html[data-theme="dark"] .ip-popup-dial { background: #16233a; border-color: #334155; }
    html[data-theme="dark"] .ip-popup-dial-at { background: #1e293b; border-color: #334155; }
    html[data-theme="dark"] .ip-popup-dial-input { color: #e2e8f0; }
    .ip-user-row {
        display: flex;
        align-items: flex-start;
        gap: 10px;
        padding: 10px 16px;
        border-bottom: 1px solid var(--border, #f3f4f6);
    }
    .ip-user-row:last-child { border-bottom: none; }
    .ip-user-flag { font-size: 22px; line-height: 1; }
    .ip-user-info { flex: 1; min-width: 0; }
    /* On-screen marker before the ISP name: filled green while one of the
       user's tabs has iperfect.net in front of them, hollow while it only
       runs in the background (minimised, or another tab selected). */
    .ip-user-vis {
        display: inline-block;
        width: 9px; height: 9px;
        margin-right: 6px;
        vertical-align: 1px;
        border-radius: 50%;
        box-sizing: border-box;
        border: 1.5px solid #9ca3af;
        background: transparent;
    }
    .ip-user-vis.on { background: #22c55e; border-color: #16a34a; }
    html[data-theme="dark"] .ip-user-vis { border-color: #64748b; }
    .ip-user-isp {
        font-weight: 600;
        color: var(--text, #111);
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }
    .ip-user-loc {
        font-size: 11px;
        color: #6b7280;
        margin-top: 2px;
    }
    .ip-user-ip {
        font-size: 11px;
        font-family: var(--mono, monospace);
        color: #6b7280;
        margin-top: 2px;
    }
    .ip-user-dev {
        font-size: 11px;
        color: #6b7280;
        margin-top: 2px;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }
    .ip-user-ago {
        font-size: 10px;
        color: #9ca3af;
        white-space: nowrap;
        margin-top: 2px;
    }
    .ip-user-scroll {
        overscroll-behavior: contain;   /* don't chain the scroll to the page */
        scrollbar-width: thin;
        scrollbar-color: #cbd5e1 transparent;
    }
    .ip-user-scroll::-webkit-scrollbar { width: 8px; }
    .ip-user-scroll::-webkit-scrollbar-track { background: transparent; }
    .ip-user-scroll::-webkit-scrollbar-thumb {
        background: #cbd5e1;
        border-radius: 4px;
        border: 2px solid transparent;
        background-clip: content-box;
    }
    .ip-user-scroll::-webkit-scrollbar-thumb:hover { background: #94a3b8; background-clip: content-box; }
    .ip-popup-self {
        padding: 8px 16px;
        background: var(--gray-50);
        border-top: 1px solid var(--border, #e5e7eb);
        font-size: 11px;
        color: #6b7280;
    }
    .ip-popup-loading {
        padding: 18px 16px;
        text-align: center;
        color: #9ca3af;
        font-size: 12px;
    }

    /* ── Voice call button in each online-user row ── */
    .ip-call-btn {
        flex: 0 0 auto;
        display: inline-flex;
        align-items: center;
        gap: 5px;
        margin-top: 2px;
        padding: 5px 10px;
        font-size: 11px;
        font-weight: 600;
        color: #fff;
        background: var(--blue-600, #2563eb);
        border: none;
        border-radius: 999px;
        cursor: pointer;
        white-space: nowrap;
        transition: background .15s, opacity .15s;
    }
    .ip-call-btn:hover { background: var(--blue-700, #1d4ed8); }
    .ip-call-btn:disabled { opacity: .5; cursor: default; }

    /* ── Call + Message buttons stack in each online-user row ── */
    .ip-user-acts { flex: 0 0 auto; display: flex; flex-direction: column; gap: 5px; }
    .ip-msg-btn {
        flex: 0 0 auto;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        gap: 5px;
        padding: 5px 10px;
        font-size: 11px;
        font-weight: 600;
        color: #fff;
        background: var(--emerald-600, #059669);
        border: none;
        border-radius: 999px;
        cursor: pointer;
        white-space: nowrap;
        transition: background .15s, opacity .15s;
    }
    .ip-msg-btn:hover { background: var(--emerald-700, #047857); }
    .ip-msg-btn:disabled { opacity: .5; cursor: default; }

    /* ── VoIP Communication tab: a handset-style dialer on the left,
       missed calls and the online list beside it like a phone's
       recents/contacts. Stacks into one column on narrow screens. ── */
    .voip-phone {
        display: grid;
        grid-template-columns: minmax(280px, 360px) 1fr;
        gap: 18px;
        align-items: start;
        margin: 14px 0 4px;
    }
    @media (max-width: 860px) {
        .voip-phone { grid-template-columns: 1fr; }
    }

    .voip-dialer {
        display: flex;
        flex-direction: column;
        align-items: center;
        padding: 28px 22px 20px;
        border-radius: 28px;
        color: #f8fafc;
        background: linear-gradient(165deg, #1e3a8a 0%, #0f172a 62%, #020617 100%);
        box-shadow: 0 18px 40px rgba(15, 23, 42, .28), inset 0 1px 0 rgba(255,255,255,.08);
        text-align: center;
    }
    .voip-dialer-avatar {
        display: flex; align-items: center; justify-content: center;
        width: 84px; height: 84px;
        font-size: 38px; font-weight: 700;
        color: #fff;
        background: linear-gradient(135deg, #3b82f6, #6366f1);
        border-radius: 50%;
        box-shadow: 0 0 0 6px rgba(59,130,246,.18), 0 0 0 12px rgba(59,130,246,.08);
    }
    .voip-dialer-label {
        margin: 16px 0 12px;
        font-size: 12px; font-weight: 600;
        letter-spacing: .08em; text-transform: uppercase;
        color: #94a3b8;
    }
    .voip-dialer .voip-dial-at {
        display: flex; align-items: center; justify-content: center;
        width: 100%;
        border-bottom: 2px solid rgba(148,163,184,.35);
        transition: border-color .15s;
    }
    .voip-dialer .voip-dial-at:focus-within { border-bottom-color: #60a5fa; }
    .voip-dialer .voip-dial-at span { font-size: 26px; font-weight: 300; color: #94a3b8; }
    .voip-dialer .voip-dial-input {
        flex: 1 1 auto; min-width: 0;
        padding: 6px 4px 8px;
        font-size: 26px; font-weight: 300;
        letter-spacing: .02em;
        text-align: center;
        color: #fff;
        background: transparent;
        border: 0; outline: none;
    }
    .voip-dialer .voip-dial-input::placeholder { color: #475569; }
    .voip-dialer .voip-dial-note { margin-top: 10px; min-height: 18px; font-size: 13px; color: #cbd5e1; }
    .voip-dialer .voip-dial-note.err  { color: #fca5a5; }
    .voip-dialer .voip-dial-note.ok   { color: #86efac; }
    .voip-dialer .voip-dial-note.wait { color: #cbd5e1; }

    .voip-dialer-actions {
        display: flex; justify-content: center; align-items: flex-end;
        gap: 40px;
        margin: 18px 0 6px;
    }
    .voip-dialer-act {
        display: flex; flex-direction: column; align-items: center; gap: 8px;
        font-size: 12px; color: #cbd5e1;
    }
    /* #tabvoip + !important: the site-wide `button` rule (and dark.css's
       button:not(.btn-primary)) force a white, square, padded button with
       !important of their own, so only a heavier selector wins here. */
    #tabvoip .voip-dialer .voip-dial-btn {
        display: flex !important; align-items: center !important; justify-content: center !important;
        width: 68px !important; height: 68px !important;
        padding: 0 !important;
        color: #fff !important;
        border: 0 !important; border-radius: 50% !important;
        cursor: pointer !important;
        transition: transform .12s, background .15s, box-shadow .15s !important;
    }
    #tabvoip .voip-dialer .voip-dial-btn:active { transform: scale(.94) !important; }
    #tabvoip .voip-dialer .voip-dial-btn.call {
        background: #22c55e !important;
        box-shadow: 0 8px 22px rgba(34,197,94,.45) !important;
    }
    #tabvoip .voip-dialer .voip-dial-btn.call:hover { background: #16a34a !important; }
    #tabvoip .voip-dialer .voip-dial-btn.msg {
        background: #3b82f6 !important;
        box-shadow: 0 8px 22px rgba(59,130,246,.4) !important;
    }
    #tabvoip .voip-dialer .voip-dial-btn.msg:hover { background: #2563eb !important; }
    #tabvoip .voip-dialer .voip-dial-btn:disabled { opacity: .5 !important; cursor: default !important; transform: none !important; }

    /* Shared with the online-users popup's dial box. */
    .voip-dial-note.err  { color: var(--red-600, #dc2626); }
    .voip-dial-note.ok   { color: var(--emerald-600, #059669); }
    .voip-dial-note.wait { color: var(--muted, #6b7280); }

    /* "Get the app", folded into the foot of the dialer. */
    .voip-app-cta {
        width: 100%;
        margin-top: 18px;
        padding-top: 16px;
        border-top: 1px solid rgba(148,163,184,.2);
    }
    .voip-app-cta-title { margin: 0 0 10px; font-size: 13px; font-weight: 600; color: #e2e8f0; }
    /* #fff !important because the page-wide `a` rule paints every link with
       --accent and carries !important of its own; a class outranks it. */
    .voip-app-cta-btn {
        display: inline-flex; align-items: center; gap: 8px;
        padding: 10px 18px;
        font-size: 13px; font-weight: 600;
        color: #fff !important;
        background: var(--blue-600, #2563eb);
        border-radius: 999px;
        text-decoration: none;
    }
    .voip-app-cta-btn:hover { background: var(--blue-700, #1d4ed8); color: #fff !important; }
    .voip-app-cta-fine { margin: 10px 0 0; font-size: 11px; line-height: 1.5; color: #94a3b8; }

    /* Recents / contacts panels beside the dialer. */
    .voip-side { display: flex; flex-direction: column; gap: 18px; min-width: 0; }
    .voip-panel {
        border: 1px solid var(--border, #e5e7eb);
        border-radius: 18px;
        background: var(--card, #fff);
        overflow: hidden;
    }
    .voip-panel-head {
        display: flex; align-items: center; gap: 8px;
        padding: 14px 16px 10px;
    }
    .voip-panel-title { font-size: 15px; font-weight: 700; color: var(--text, #111); }
    .voip-panel-count {
        font-size: 12px; font-weight: 600;
        color: var(--red-600, #dc2626);
    }
    .voip-missed-head .ip-miss-clear { margin-left: auto; padding-right: 0; }
    .voip-missed-card .ip-miss-row { padding-left: 16px; padding-right: 16px; }
    .voip-missed-card .ip-miss-row.fresh { padding-left: 13px; }
    .voip-missed-card .ip-miss-empty { padding: 4px 16px 16px; }

    .voip-search-wrap { display: flex; gap: 8px; padding: 0 16px 12px; }
    .voip-search-input {
        flex: 1 1 auto; min-width: 0;
        padding: 9px 16px;
        font-size: 14px;
        color: var(--text, #111);
        background: var(--gray-100, #f3f4f6);
        border: 1px solid transparent;
        border-radius: 999px;
        outline: none;
        transition: border-color .15s, box-shadow .15s, background .15s;
    }
    .voip-search-input:focus {
        background: var(--card, #fff);
        border-color: var(--blue-600, #2563eb);
        box-shadow: 0 0 0 3px rgba(37, 99, 235, .15);
    }
    #tabvoip .voip-refresh-btn {
        flex: 0 0 auto;
        width: 38px !important; height: 38px !important;
        display: inline-flex !important; align-items: center !important; justify-content: center !important;
        padding: 0 !important;
        font-size: 17px !important; font-weight: 600 !important;
        color: var(--text, #111) !important;
        background: var(--gray-100, #f3f4f6) !important;
        border: 0 !important;
        border-radius: 50% !important;
        box-shadow: none !important;
    }
    #tabvoip .voip-refresh-btn:hover { background: var(--gray-200, #e5e7eb) !important; }
    #voip-user-list { width: 100%; border-top: 1px solid var(--border, #e5e7eb); }

    html[data-theme="dark"] .voip-panel { background: #111c30; border-color: #334155; }
    html[data-theme="dark"] .voip-panel-title { color: #e2e8f0; }
    html[data-theme="dark"] .voip-panel-count { color: #fca5a5; }
    html[data-theme="dark"] .voip-search-input { background: #1e293b; color: #e2e8f0; }
    html[data-theme="dark"] .voip-search-input:focus { background: #1e293b; }
    html[data-theme="dark"] #tabvoip .voip-refresh-btn { background: #1e293b !important; color: #e2e8f0 !important; }
    html[data-theme="dark"] #tabvoip .voip-refresh-btn:hover { background: #263449 !important; }
    html[data-theme="dark"] #voip-user-list { border-color: #334155; }
    html[data-theme="dark"] .voip-dialer { box-shadow: 0 18px 40px rgba(0,0,0,.5), inset 0 1px 0 rgba(255,255,255,.06); }

    /* ── Shareable link row: label, the URL itself, copy and open ── */
    .ip-share {
        display: flex;
        align-items: center;
        gap: 10px;
        flex-wrap: wrap;
        max-width: 720px;
        margin: 16px auto;
        padding: 10px 12px;
        border: 1px solid var(--border, #e5e7eb);
        border-radius: 12px;
        background: var(--surface, #fff);
        box-shadow: var(--sh);
    }
    .ip-share-lbl {
        font-size: 11px; font-weight: 700; letter-spacing: .05em;
        text-transform: uppercase;
        color: var(--sub, #6b7280);
        flex: 0 0 auto;
    }
    .ip-share-url {
        flex: 1 1 260px;
        min-width: 0;
        overflow-x: auto;
        white-space: nowrap;
        padding: 7px 10px;
        border-radius: 8px;
        background: var(--gray-100, #f3f4f6);
        border: 1px solid var(--border, #e5e7eb);
        font-family: var(--mono);
        font-size: 12.5px;
        color: var(--text, #111827);
        -webkit-user-select: all;
        user-select: all;
    }
    /* Everything here is !important twice over: the page-wide `a` rule
       repaints every link, and the `button` rule repaints every button —
       both with !important of their own, so a plain class loses to them. */
    .ip-share-btn {
        flex: 0 0 auto;
        display: inline-flex !important;
        align-items: center !important;
        gap: 6px !important;
        padding: 8px 14px !important;
        border-radius: 8px !important;
        border: 1px solid var(--accent) !important;
        font-size: 12.5px !important;
        font-weight: 600 !important;
        font-family: var(--sans) !important;
        line-height: 1.4 !important;
        box-shadow: none !important;
        text-decoration: none !important;
        white-space: nowrap !important;
        cursor: pointer !important;
        background: var(--accent) !important;
        color: #fff !important;
    }
    .ip-share-btn:hover { background: var(--accent-h) !important; border-color: var(--accent-h) !important; }
    .ip-share-btn.copied { background: var(--emerald-500) !important; border-color: var(--emerald-500) !important; }
    html[data-theme="dark"] .ip-share-url { background: #16233b; border-color: #334155; }
    /* The same row sitting in a tool's heading bar, pushed to the right. */
    .ip-share.ip-share-head {
        margin: 0 0 0 auto;
        max-width: 460px;
        padding: 5px 6px 5px 10px;
        gap: 8px;
        flex-wrap: nowrap;
        box-shadow: none;
    }
    .ip-share-head .ip-share-url { flex: 1 1 auto; padding: 5px 8px; font-size: 12px; }
    .ip-share-head .ip-share-btn { padding: 6px 12px !important; }
    @media (max-width: 900px) {
        .ip-share.ip-share-head { margin: 0; max-width: 100%; width: 100%; }
    }

    /* Section heading inside the user list ("App users" / "Web browsers") */
    .ip-user-group {
        padding: 8px 14px;
        font-size: 11.5px; font-weight: 700; letter-spacing: .04em;
        text-transform: uppercase;
        color: var(--muted, #6b7280);
        background: var(--gray-50, #f9fafb);
        border-bottom: 1px solid var(--border, #e5e7eb);
    }
    .ip-user-handle { font-weight: 700; color: var(--blue-600, #2563eb); }
    .ip-user-asleep {
        display: inline-block; margin-left: 6px; padding: 1px 6px;
        font-size: 10.5px; font-weight: 600; border-radius: 99px;
        color: var(--muted, #6b7280); background: var(--gray-100, #f3f4f6);
    }
    html[data-theme="dark"] .ip-user-group { background: #16233a; border-color: #334155; color: #94a3b8; }
    html[data-theme="dark"] .ip-user-asleep { background: #1e293b; color: #94a3b8; }

    /* ── Call panel (incoming / calling / in-call) ── */
    #ip-call-panel {
        display: none;
        position: fixed;
        top: 52px;
        right: 16px;
        z-index: 10001;
        width: 300px;
        max-width: calc(100vw - 32px);
        background: #ffffff;
        border: 1px solid var(--border, #e5e7eb);
        border-radius: 14px;
        box-shadow: 0 12px 40px rgba(0,0,0,.22);
        overflow: hidden;
        font-size: 13px;
    }
    #ip-call-panel.open { display: block; }
    .ip-call-body { padding: 18px 18px 16px; text-align: center; }
    .ip-call-avatar {
        width: 56px; height: 56px; line-height: 56px;
        margin: 0 auto 10px;
        font-size: 30px; text-align: center;
        background: var(--gray-50, #f3f4f6);
        border-radius: 50%;
    }
    .ip-call-title { font-weight: 700; color: var(--text, #111); font-size: 15px; }
    .ip-call-sub { color: #6b7280; font-size: 12px; margin-top: 3px; }
    .ip-call-status { color: var(--emerald-600, #059669); font-size: 12px; margin-top: 8px; min-height: 15px; }
    .ip-call-actions { display: flex; gap: 10px; justify-content: center; margin-top: 16px; }
    .ip-call-act {
        flex: 1;
        display: inline-flex; align-items: center; justify-content: center; gap: 6px;
        padding: 9px 12px;
        font-size: 13px; font-weight: 600;
        border: none; border-radius: 10px;
        cursor: pointer;
        transition: filter .15s, background .15s;
    }
    .ip-call-act:hover { filter: brightness(.94); }
    .ip-call-act.accept { background: var(--emerald-500, #10b981); color: #fff; }
    .ip-call-act.reject { background: #ef4444; color: #fff; }
    .ip-call-act.neutral { background: var(--gray-50, #f3f4f6); color: var(--text, #111); }
    .ip-call-act.active { background: #6366f1; color: #fff; }
    .ip-call-hint { font-size: 10px; color: #9ca3af; margin-top: 12px; }

    /* ── Text-message panel (WebRTC data channel) ──
       Sits bottom-right so it can stay open alongside the call panel. */
    #ip-chat-panel {
        display: none;
        position: fixed;
        right: 16px;
        bottom: 16px;
        z-index: 10002;
        width: 320px;
        max-width: calc(100vw - 32px);
        background: #ffffff;
        border: 1px solid var(--border, #e5e7eb);
        border-radius: 14px;
        box-shadow: 0 12px 40px rgba(0,0,0,.22);
        overflow: hidden;
        font-size: 13px;
    }
    #ip-chat-panel.open { display: flex; flex-direction: column; }
    .ip-chat-hdr {
        display: flex;
        align-items: center;
        gap: 9px;
        padding: 10px 12px;
        border-bottom: 1px solid var(--border, #f3f4f6);
        background: var(--gray-50, #f9fafb);
    }
    .ip-chat-avatar { font-size: 20px; line-height: 1; }
    .ip-chat-who { flex: 1; min-width: 0; }
    .ip-chat-title {
        font-weight: 700;
        color: var(--text, #111);
        font-size: 13px;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }
    .ip-chat-status { color: #6b7280; font-size: 11px; margin-top: 1px; }

    /* "Call" button in the chat header — starts a voice call with whoever
       the open conversation is with, so the user does not have to go back
       to the Who's Online list to dial them. */
    /* Blue pill, same look as the "Call" buttons in the Who's Online list.
       Every property the global button rule sets with !important has to be
       overridden the same way, or this comes out as a white rounded box. */
    .ip-chat-call {
        flex: 0 0 auto;
        display: none !important;
        align-items: center !important;
        justify-content: center !important;
        padding: 5px 10px !important;
        font-size: 12px !important;
        font-weight: 600 !important;
        line-height: 1.2 !important;
        color: #fff !important;
        background: var(--blue-600, #2563eb) !important;
        border: 1px solid var(--blue-600, #2563eb) !important;
        border-radius: 999px !important;
        box-shadow: none !important;
        cursor: pointer !important;
    }
    .ip-chat-call.show { display: inline-flex !important; }
    .ip-chat-call:hover {
        background: var(--blue-700, #1d4ed8) !important;
        border-color: var(--blue-700, #1d4ed8) !important;
        color: #fff !important;
    }
    .ip-chat-call:disabled { opacity: .5 !important; cursor: default !important; }

    /* Peer detail strip under the chat header. */
    .ip-chat-peer {
        display: none;
        padding: 7px 12px;
        border-bottom: 1px solid var(--border, #f3f4f6);
        background: var(--gray-50, #f9fafb);
    }
    .ip-chat-peer.show { display: block; }
    .ip-chat-peer div {
        font-size: 11px;
        line-height: 1.4;
        color: #6b7280;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }
    .ip-chat-peer .ip-chat-peer-ip { font-family: var(--mono, monospace); }

    /* Minimized: collapse to the header bar and leave it as the handle that
       brings the panel back. Two ids beat the single-id rules these hide. */
    #ip-chat-panel.min .ip-chat-hdr { cursor: pointer; }
    #ip-chat-panel.min .ip-chat-call { display: none !important; }
    #ip-chat-panel.min .ip-chat-peer { display: none; }
    #ip-chat-panel.min #ip-chat-tabs,
    #ip-chat-panel.min #ip-chat-logs,
    #ip-chat-panel.min .ip-chat-composer,
    #ip-chat-panel.min .ip-chat-hint { display: none; }
    .ip-chat-min-badge {
        display: none;
        flex: 0 0 auto;
        min-width: 17px;
        padding: 0 5px;
        font-size: 10.5px;
        font-weight: 700;
        line-height: 17px;
        text-align: center;
        color: #fff;
        background: var(--blue-600, #2563eb);
        border-radius: 999px;
    }
    .ip-chat-min-badge.show { display: inline-block; }

    /* Conversation tabs — hidden until a second chat is open. */
    #ip-chat-tabs {
        display: none;
        gap: 4px;
        padding: 6px 8px;
        overflow-x: auto;
        scrollbar-width: thin;
        border-bottom: 1px solid var(--border, #f3f4f6);
        background: var(--gray-50, #f9fafb);
    }
    #ip-chat-tabs.show { display: flex; }
    .ip-chat-tab {
        display: inline-flex;
        align-items: center;
        gap: 5px;
        flex: 0 0 auto;
        max-width: 150px;
        padding: 4px 6px 4px 8px;
        font-size: 11.5px;
        color: var(--text, #111);
        background: var(--card, #fff);
        border: 1px solid var(--border, #e5e7eb);
        border-radius: 999px;
        cursor: pointer;
        user-select: none;
    }
    .ip-chat-tab.active {
        border-color: var(--blue-600, #2563eb);
        box-shadow: inset 0 0 0 1px var(--blue-600, #2563eb);
        font-weight: 600;
    }
    .ip-chat-tab.ended { opacity: .55; }
    .ip-chat-tab-flag { flex: 0 0 auto; }
    .ip-chat-tab-name {
        min-width: 0;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }
    /* Unread count for a conversation the user is not currently looking at. */
    .ip-chat-tab-badge {
        flex: 0 0 auto;
        min-width: 15px;
        padding: 0 4px;
        font-size: 10px;
        font-weight: 700;
        line-height: 15px;
        text-align: center;
        color: #fff;
        background: var(--blue-600, #2563eb);
        border-radius: 999px;
    }
    .ip-chat-tab-typing { flex: 0 0 auto; font-size: 11px; color: var(--blue-600, #2563eb); }
    .ip-chat-tab-x {
        flex: 0 0 auto;
        width: 15px;
        line-height: 15px;
        text-align: center;
        font-size: 13px;
        color: #9ca3af;
        border-radius: 999px;
    }
    .ip-chat-tab-x:hover { color: #ef4444; background: rgba(239, 68, 68, .12); }

    #ip-chat-logs {
        flex: 1 1 auto;
        display: flex;
        height: 240px;
        min-height: 0;
    }
    .ip-chat-log {
        display: none;
        flex: 1 1 auto;
        min-width: 0;
        overflow-y: auto;
        padding: 10px 12px;
        background: var(--card, #fff);
    }
    .ip-chat-log.active { display: block; }
    .ip-chat-msg { display: flex; align-items: flex-end; gap: 6px; margin-bottom: 8px; }
    .ip-chat-msg.me { flex-direction: row-reverse; }
    .ip-chat-msg.sys { justify-content: center; }
    .ip-chat-bubble {
        max-width: 78%;
        padding: 7px 10px;
        border-radius: 12px;
        word-break: break-word;
        white-space: pre-wrap;
        background: var(--gray-50, #f3f4f6);
        color: var(--text, #111);
    }
    .ip-chat-msg.me .ip-chat-bubble { background: var(--blue-600, #2563eb); color: #fff; }
    /* Timestamp + delivery ticks travel together so they read as "12:30 ✓✓"
       even in the .me row, which is laid out row-reverse. */
    .ip-chat-meta { display: flex; align-items: center; gap: 3px; flex: 0 0 auto; }
    .ip-chat-time { font-size: 10px; color: #9ca3af; flex: 0 0 auto; }
    .ip-chat-ticks {
        display: inline-flex;
        align-items: center;
        color: #9ca3af;          /* sent + delivered */
        line-height: 0;
    }
    .ip-chat-ticks.read   { color: var(--blue-600, #2563eb); }   /* seen */
    .ip-chat-ticks.failed { color: #ef4444; }
    .ip-chat-sys { font-size: 11px; color: #9ca3af; font-style: italic; }

    /* "typing…" bubble — three bouncing dots on the peer's side of the log */
    .ip-chat-typing .ip-chat-bubble { padding: 9px 12px; }
    .ip-chat-dots { display: inline-flex; align-items: center; gap: 4px; }
    .ip-chat-dots i {
        display: block;
        width: 6px;
        height: 6px;
        border-radius: 50%;
        background: #9ca3af;
        animation: ip-typing-bounce 1.2s infinite ease-in-out;
    }
    .ip-chat-dots i:nth-child(2) { animation-delay: .18s; }
    .ip-chat-dots i:nth-child(3) { animation-delay: .36s; }
    @keyframes ip-typing-bounce {
        0%, 60%, 100% { opacity: .35; transform: translateY(0); }
        30%           { opacity: 1;   transform: translateY(-3px); }
    }
    @media (prefers-reduced-motion: reduce) {
        .ip-chat-dots i { animation: ip-typing-fade 1.2s infinite ease-in-out; }
        @keyframes ip-typing-fade { 0%, 60%, 100% { opacity: .35; } 30% { opacity: 1; } }
    }
    .ip-chat-composer {
        display: flex;
        gap: 8px;
        padding: 10px 12px;
        border-top: 1px solid var(--border, #f3f4f6);
    }
    #ip-chat-input {
        flex: 1 1 auto;
        min-width: 0;
        padding: 8px 10px;
        font-size: 13px;
        color: var(--text, #111);
        background: var(--card, #fff);
        border: 1px solid var(--border, #d1d5db);
        border-radius: 9px;
        outline: none;
    }
    #ip-chat-input:focus { border-color: var(--blue-600, #2563eb); }
    #ip-chat-send {
        flex: 0 0 auto;
        padding: 8px 14px;
        font-size: 13px;
        font-weight: 600;
        color: #fff;
        background: var(--blue-600, #2563eb);
        border: none;
        border-radius: 9px;
        cursor: pointer;
    }
    #ip-chat-send:disabled { opacity: .5; cursor: default; }
    .ip-chat-hint { font-size: 10px; color: #9ca3af; text-align: center; padding: 0 12px 10px; }

    .ip-dot {
        width: 7px;
        height: 7px;
        background: var(--emerald-500);
        border-radius: 50%;
        animation: ip-pulse 2s infinite
    }

    @keyframes ip-pulse {

        0%,
        100% {
            opacity: 1
        }

        50% {
            opacity: .4
        }
    }

    .ip-clock {
        font-family: var(--mono);
        font-size: 12px;
        color: var(--sub);
        background: var(--gray-100);
        padding: 4px 10px;
        border-radius: 100px;
        letter-spacing: .04em;
    }

    .ip-hamburger {
        display: none;
        flex-direction: column;
        gap: 4px;
        background: none;
        border: none !important;
        cursor: pointer;
        padding: 6px;
        border-radius: 6px;
        box-shadow: none !important;
    }

    .ip-hamburger:hover {
        background: var(--gray-100) !important
    }

    .ip-hamburger span {
        display: block;
        width: 20px;
        height: 2px;
        background: var(--gray-600);
        border-radius: 2px;
        transition: all .25s
    }

    .ip-hamburger.open span:nth-child(1) {
        transform: translateY(6px) rotate(45deg)
    }

    .ip-hamburger.open span:nth-child(2) {
        opacity: 0
    }

    .ip-hamburger.open span:nth-child(3) {
        transform: translateY(-6px) rotate(-45deg)
    }

    /* ── LAYOUT ── */
    .container,
    .container-fluid {
        max-width: 100% !important;
        width: 100% !important;
        padding: 0 !important;
        margin: 0 !important
    }

    /* ── SIDEBAR (glass panel — index1 style) ── */
    .ip-sidebar {
        width: 228px;
        flex-shrink: 0;
        background: var(--sidebar-bg);
        backdrop-filter: blur(16px) saturate(1.2);
        -webkit-backdrop-filter: blur(16px) saturate(1.2);
        border-radius: var(--r-lg);
        padding: 18px 0 22px;
        box-shadow: var(--sh-lg-cosmic);
        border: 1px solid var(--sidebar-glass-border);
        position: sticky;
        top: 86px;
        height: fit-content;
        transition: transform .3s var(--ease);
        overflow: hidden;
    }
    .ip-sidebar::before {
        content: '';
        position: absolute;
        top: 0;
        left: 16px;
        right: 16px;
        height: 1px;
        background: linear-gradient(
            90deg,
            transparent 0%,
            rgba(0, 212, 255, 0.15) 15%,
            rgba(0, 212, 255, 0.55) 50%,
            rgba(124, 58, 237, 0.45) 85%,
            transparent 100%
        );
        border-radius: 1px;
        pointer-events: none;
    }
    .ip-sidebar::after {
        content: '';
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        height: 56px;
        background: linear-gradient(180deg, rgba(0, 212, 255, 0.04) 0%, transparent 100%);
        pointer-events: none;
    }

    .ip-sidebar-label {
        font-size: 10px;
        font-weight: 600;
        letter-spacing: .1em;
        text-transform: uppercase;
        color: var(--sidebar-muted);
        padding: 10px 18px 5px;
    }

    /* Sidebar nav links — Bootstrap wizard override */
    #rootwizard>ul.nav {
        background: transparent !important;
        border: none !important;
        padding: 0 !important;
        list-style: none !important;
        border-radius: 0 !important;
        flex-direction: column !important;
        display: flex !important;
    }

    #rootwizard>ul.nav>li,
    .ip-sidebar ul>li {
        float: none !important;
        margin: 0 !important;
        display: block !important
    }

    /* Group labels and dividers must never go inline */
    li.nav-group-label,
    li.nav-divider {
        float: none !important;
        display: block !important;
        clear: both !important;
    }

    #rootwizard>ul.nav>li>a,
    #rootwizard>ul.nav>li>a:focus {
        display: flex !important;
        align-items: center !important;
        gap: 10px !important;
        padding: 10px 18px !important;
        color: var(--sidebar-muted) !important;
        font-size: 13px !important;
        font-weight: 500 !important;
        font-family: var(--sans) !important;
        border-left: 3px solid transparent !important;
        border-top: none !important;
        border-right: none !important;
        border-bottom: none !important;
        border-radius: 0 !important;
        background: transparent !important;
        transition: all .15s !important;
        text-decoration: none !important;
        margin: 0 !important;
    }

    #rootwizard>ul.nav>li>a:hover {
        color: #fff !important;
        background: rgba(255, 255, 255, .05) !important;
        border-left-color: #6b7280 !important;
    }

    #rootwizard>ul.nav>li.active>a,
    #rootwizard>ul.nav>li.active>a:focus {
        color: var(--sidebar-text) !important;
        background: rgba(0, 212, 255, 0.1) !important;
        border-left: 3px solid var(--sidebar-accent) !important;
        font-weight: 600 !important;
    }

    .ip-sidebar ul {
        list-style: none !important;
        padding: 0 !important;
        margin: 0 !important;
        display: flex !important;
        flex-direction: column !important;
        width: 100% !important;
    }

    .ip-sidebar ul>li {
        display: block !important;
        width: 100% !important;
        float: none !important;
        clear: both !important;
    }

    .ip-sidebar ul li a {
        display: flex !important;
        align-items: center !important;
        gap: 10px !important;
        padding: 10px 18px !important;
        color: var(--sidebar-muted) !important;
        font-size: 13px !important;
        font-weight: 500 !important;
        font-family: var(--sans) !important;
        border-left: 3px solid transparent !important;
        border-top: none !important;
        border-right: none !important;
        border-bottom: none !important;
        border-radius: 0 !important;
        background: transparent !important;
        transition: all .15s !important;
        text-decoration: none !important;
        margin: 0 !important;
        box-shadow: none !important;
    }

    .ip-sidebar ul li a:hover {
        color: #fff !important;
        background: rgba(255, 255, 255, .05) !important;
        border-left-color: #6b7280 !important;
    }

    .ip-sidebar ul li.active>a {
        color: var(--sidebar-text) !important;
        background: rgba(0, 212, 255, 0.1) !important;
        border-left: 3px solid var(--sidebar-accent) !important;
        font-weight: 600 !important;
    }

    .nav-icon {
        width: 16px;
        height: 16px;
        flex-shrink: 0;
        opacity: .7
    }

    .ip-sidebar ul li.active>a .nav-icon,
    #rootwizard>ul.nav>li.active>a .nav-icon {
        opacity: 1;
        color: var(--sidebar-accent) !important
    }

    /* Valid li-based dividers & group labels */
    li.nav-divider {
        list-style: none !important;
        height: 1px !important;
        background: rgba(255, 255, 255, .07) !important;
        margin: 6px 0 !important;
        padding: 0 !important;
        border: none !important;
    }

    li.nav-group-label {
        display: block !important;
        list-style: none !important;
        font-size: 10px !important;
        font-weight: 600 !important;
        letter-spacing: .12em !important;
        text-transform: uppercase !important;
        color: var(--sidebar-accent) !important;
        font-family: var(--mono) !important;
        padding: 10px 18px 5px !important;
        width: 100% !important;
    }

    /* ── CONTENT AREA ── */
    .ip-content {
        flex: 1;
        min-width: 0;
        background: var(--surface);
        border-radius: var(--r);
        border: 1px solid var(--border);
        box-shadow: var(--sh-md);
        overflow: hidden;
    }

    .tab-content {
        background: var(--surface) !important;
        border: none !important;
        padding: 28px 32px !important;
    }

    .tab-pane {
        animation: ip-fadein .2s ease
    }

    @keyframes ip-fadein {
        from {
            opacity: 0;
            transform: translateY(8px)
        }

        to {
            opacity: 1;
            transform: translateY(0)
        }
    }

    /* ── SECTION HEADERS ── */
    .ip-section-head {
        display: flex;
        align-items: center;
        margin-bottom: 24px;
        padding-bottom: 16px;
        border-bottom: 1px solid var(--border);
        gap: 10px;
    }

    /* Shareable direct link shown under a tool's heading (see IP_TAB_LINKS). */
    .ip-permalink {
        margin: -14px 0 16px;
        font-size: 11.5px;
        color: var(--gray-500);
    }

    .ip-permalink a {
        color: var(--blue-600);
        text-decoration: none;
        font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    }

    .ip-permalink a:hover { text-decoration: underline; }

    .ip-section-icon {
        width: 36px;
        height: 36px;
        background: var(--blue-50);
        border-radius: 8px;
        display: flex;
        align-items: center;
        justify-content: center;
        color: var(--blue-600);
        flex-shrink: 0;
    }

    .ip-section-title {
        font-size: 18px !important;
        font-weight: 700 !important;
        color: var(--gray-900) !important;
        border: none !important;
        padding: 0 !important;
        margin: 0 !important;
        font-family: var(--sans) !important;
        letter-spacing: -.2px;
    }

    /* ── WEB SEARCH ── */
    .ws-panel { margin-top: 4px; }
    .ws-hero {
        text-align: center;
        padding: 36px 20px 28px;
        border-radius: var(--r);
        background: linear-gradient(180deg, var(--blue-50) 0%, transparent 70%);
        border: 1px solid var(--border);
        transition: padding .25s ease, background .25s ease, border-color .25s ease;
    }
    .ws-panel.ws-searched .ws-hero {
        padding: 0;
        background: transparent;
        border: none;
        text-align: left;
    }
    .ws-hero-icon {
        width: 56px;
        height: 56px;
        margin: 0 auto 14px;
        display: flex;
        align-items: center;
        justify-content: center;
        background: var(--blue-50);
        border-radius: 16px;
        color: var(--blue-600);
    }
    .ws-hero-sub {
        font-size: 14px !important;
        color: var(--sub) !important;
        margin: 0 auto 22px !important;
        max-width: 440px;
        line-height: 1.55 !important;
    }
    .ws-panel.ws-searched .ws-empty,
    .ws-panel.ws-searched .ws-suggestions { display: none; }
    .ws-search-wrap {
        max-width: 620px;
        margin: 0 auto;
    }
    .ws-panel.ws-searched .ws-search-wrap {
        max-width: none;
        margin: 0 0 18px;
    }
    .ws-search-wrap .gsc-control-cse,
    .ws-search-wrap table.gsc-search-box {
        padding: 0 !important;
        margin: 0 !important;
        background: transparent !important;
        border: none !important;
    }
    .ws-search-wrap .gsc-input-box {
        min-height: 46px;
        border-radius: 12px !important;
    }
    .ws-search-wrap input.gsc-input {
        font-size: 15px !important;
        height: 44px !important;
    }
    .ws-suggestions {
        display: flex;
        flex-wrap: wrap;
        align-items: center;
        justify-content: center;
        gap: 8px;
        margin-top: 22px;
    }
    .ws-suggestions-label {
        font-size: 12px;
        color: var(--sub);
        font-weight: 500;
        margin-right: 2px;
    }
    button.ws-chip {
        display: inline-flex !important;
        align-items: center !important;
        padding: 7px 14px !important;
        font-size: 12px !important;
        font-weight: 500 !important;
        font-family: var(--sans) !important;
        color: var(--gray-700) !important;
        background: var(--white) !important;
        border: 1px solid var(--border) !important;
        border-radius: 100px !important;
        cursor: pointer !important;
        transition: background .15s, border-color .15s, color .15s, box-shadow .15s !important;
        box-shadow: var(--sh) !important;
        line-height: 1.3 !important;
        white-space: nowrap !important;
        transform: none !important;
    }
    button.ws-chip:hover {
        background: var(--blue-50) !important;
        border-color: var(--blue-400) !important;
        color: var(--blue-700) !important;
        box-shadow: var(--sh-md) !important;
    }
    .ws-results-wrap {
        padding-top: 4px;
    }
    .ws-panel:not(.ws-searched) .ws-results-wrap { display: none !important; }

    /* ── TYPOGRAPHY ── */
    h1,
    h2,
    h3,
    h4,
    h5 {
        font-family: var(--sans) !important;
        color: var(--text) !important
    }

    h2:not(.ip-section-title) {
        font-size: 17px !important;
        font-weight: 700 !important;
        border-bottom: 1px solid var(--border) !important;
        padding-bottom: 10px !important;
        margin: 4px 0 18px !important;
    }

    h2.ip-section-title {
        border-bottom: none !important;
        padding: 0 !important;
        margin: 0 !important;
    }

    h3 {
        font-size: 14px !important;
        font-weight: 600 !important
    }

    p {
        color: var(--sub) !important
    }

    b,
    strong {
        color: var(--text) !important
    }

    small {
        color: var(--sub) !important;
        font-size: 12px
    }

    a {
        color: var(--accent) !important;
        text-decoration: none
    }

    a:hover {
        color: var(--accent-h) !important
    }

    label {
        color: var(--sub) !important;
        font-size: 12px;
        font-weight: 500
    }

    /* ── INPUTS ── */
    input[type=text],
    input[type=number],
    textarea,
    select {
        background: #fff !important;
        border: 1px solid var(--gray-200) !important;
        border-radius: var(--r-sm) !important;
        color: var(--text) !important;
        font-family: var(--mono) !important;
        font-size: 12.5px !important;
        padding: 8px 11px !important;
        outline: none !important;
        transition: border-color .15s, box-shadow .15s !important;
        box-shadow: var(--sh) !important;
    }

    input[type=text]:focus,
    input[type=number]:focus,
    textarea:focus,
    select:focus {
        border-color: var(--blue-500) !important;
        box-shadow: 0 0 0 3px rgba(59, 130, 246, .12) !important;
    }

    select option {
        background: #fff;
        color: var(--text)
    }

    input[type=checkbox] {
        accent-color: var(--accent)
    }

    input[type=range] {
        accent-color: var(--accent)
    }

    textarea {
        resize: vertical;
        min-height: 70px
    }

    /* ── BUTTONS ── */
    input[type=button],
    button,
    .btn {
        display: inline-flex !important;
        align-items: center !important;
        gap: 6px !important;
        background: var(--white) !important;
        border: 1px solid var(--gray-200) !important;
        border-radius: var(--r-sm) !important;
        color: var(--gray-700) !important;
        font-family: var(--sans) !important;
        font-size: 13px !important;
        font-weight: 500 !important;
        padding: 8px 16px !important;
        cursor: pointer !important;
        transition: background .15s, border-color .15s, box-shadow .15s, color .15s !important;
        box-shadow: var(--sh) !important;
        text-decoration: none !important;
        white-space: nowrap !important;
        vertical-align: middle !important;
        line-height: 1.4 !important;
        outline: none !important;
    }

    input[type=button]:hover,
    button:hover,
    .btn:hover {
        background: var(--gray-50) !important;
        border-color: var(--gray-300) !important;
        color: var(--gray-900) !important;
        box-shadow: 0 1px 4px rgba(0, 0, 0, .1) !important;
    }

    input[type=button]:active,
    button:active,
    .btn:active {
        background: var(--gray-100) !important;
        box-shadow: none !important;
        transform: translateY(1px) !important;
    }

    /* Primary — blue solid */
    .btn-primary,
    input[type=button][name=btn1],
    input[type=button][value="Check Speed"],
    input[type=button][value="click here"] {
        background: var(--blue-600) !important;
        border-color: var(--blue-600) !important;
        color: #fff !important;
        box-shadow: 0 2px 8px rgba(37, 99, 235, .3) !important;
        font-weight: 600 !important;
    }

    .btn-primary:hover,
    input[type=button][name=btn1]:hover,
    input[type=button][value="Check Speed"]:hover,
    input[type=button][value="click here"]:hover {
        background: var(--blue-700) !important;
        border-color: var(--blue-700) !important;
        color: #fff !important;
        box-shadow: 0 4px 12px rgba(37, 99, 235, .4) !important;
    }

    /* Danger */
    .btn-danger {
        border-color: #fecaca !important;
        color: var(--red-500) !important;
        background: var(--white) !important
    }

    .btn-danger:hover {
        background: #fef2f2 !important;
        border-color: var(--red-500) !important;
        color: var(--red-500) !important
    }

    /* Sizes */
    .btn-sm,
    input[type=button].btn-sm {
        padding: 6px 12px !important;
        font-size: 12px !important
    }

    .btn-xs,
    input[type=button].btn-xs {
        padding: 4px 9px !important;
        font-size: 11px !important
    }

    .btn-block {
        width: 100% !important;
        justify-content: center !important
    }

    /* Specific action buttons — give them primary style */
    input[type=button][value="Check Port"],
    input[type=button][name="portcheck_btn"],
    input[type=button][value="Lookup"],
    input[type=button][value="Sort"],
    input[type=button][value="Start Job"],
    input[type=button][value="Stop Job"],
    input[type=button][value="Get Time"],
    input[type=button][value="Get Date Time"],
    input[type=button][value="Get MiliSeconds"],
    input[type=button][value="Calculate Backup"],
    input[type=button][value="Check"],
    input[type=button][value="Create"],
    input[type=button][value="Format"],
    input[type=button][name="btnSendFCM"],
    input[type=button][name="btnURLUpload"],
    input[type=button][value="+ Add load"],
    input[type=button][value="Calculate Battery Capacity"],
    input[type=button][id="bc_pdf_btn"],
    button[id="xml"],
    button[id="css"],
    button[id="sql"],
    button[id="json"] {
        background: var(--blue-600) !important;
        border-color: var(--blue-600) !important;
        color: #fff !important;
        box-shadow: 0 2px 8px rgba(37, 99, 235, .25) !important;
        font-weight: 600 !important;
    }

    input[type=button][value="Check Port"]:hover,
    input[type=button][name="portcheck_btn"]:hover,
    input[type=button][value="Lookup"]:hover,
    input[type=button][value="Sort"]:hover,
    input[type=button][value="Start Job"]:hover,
    input[type=button][value="Get Time"]:hover,
    input[type=button][value="Get Date Time"]:hover,
    input[type=button][value="Get MiliSeconds"]:hover,
    input[type=button][value="Calculate Backup"]:hover,
    input[type=button][value="Check"]:hover,
    input[type=button][value="Create"]:hover,
    input[type=button][name="btnSendFCM"]:hover,
    input[type=button][name="btnURLUpload"]:hover,
    input[type=button][value="+ Add load"]:hover,
    input[type=button][value="Calculate Battery Capacity"]:hover,
    input[type=button][id="bc_pdf_btn"]:hover,
    button[id="xml"]:hover,
    button[id="css"]:hover,
    button[id="sql"]:hover,
    button[id="json"]:hover {
        background: var(--blue-700) !important;
        border-color: var(--blue-700) !important;
        color: #fff !important;
    }

    /* Minimize / Load Sample — subtle secondary */
    button[id="xmlmin"],
    button[id="cssmin"],
    button[id="sqlmin"],
    button[id="jsonmin"],
    button[id="xml_load"],
    button[id="css_load"],
    button[id="sql_load"],
    button[id="json_load"],
    input[type=button][value="Upper Case"],
    input[type=button][value="Lower Case"],
    input[type=button][value="Stop Job"] {
        background: var(--gray-50) !important;
        border-color: var(--gray-300) !important;
        color: var(--gray-700) !important;
    }

    /* Reset button */
    button[id="Reset"],
    input[type=reset],
    .btn-danger-outline {
        background: var(--white) !important;
        border-color: #fecaca !important;
        color: var(--red-500) !important;
    }

    button[id="Reset"]:hover {
        background: #fef2f2 !important;
        border-color: var(--red-500) !important
    }

    /* ── PRE / CODE ── */
    pre {
        background: var(--gray-900) !important;
        color: #e2e8f0 !important;
        border-radius: var(--r-sm) !important;
        font-family: var(--mono) !important;
        font-size: 12px !important;
        padding: 14px 18px !important;
        overflow-x: auto;
        margin: 6px 0 14px !important;
        line-height: 1.7;
        border: none !important;
        position: relative;
    }

    code {
        font-family: var(--mono) !important;
        color: var(--blue-600);
        font-size: 12px
    }

    /* ── COPYABLE COMMAND BLOCK ── */
    .cmd-box {
        position: relative;
    }

    .cmd-box>pre {
        padding-right: 44px !important;
    }

    /* NOTE: the global `button` rule above sets padding/background/color
       with !important, so every conflicting property here needs it too —
       without it the padding crushes the icon to zero width. */
    button.cmd-copy {
        position: absolute;
        top: 7px;
        right: 7px;
        display: inline-flex !important;
        align-items: center !important;
        justify-content: center !important;
        box-sizing: border-box !important;
        width: 28px !important;
        height: 28px !important;
        min-width: 0 !important;
        padding: 0 !important;
        gap: 0 !important;
        background: rgba(255, 255, 255, .10) !important;
        color: #cbd5e1 !important;
        border: 1px solid rgba(255, 255, 255, .18) !important;
        border-radius: 5px !important;
        box-shadow: none !important;
        cursor: pointer !important;
        opacity: .7;
        transition: opacity .15s, background .15s, color .15s !important;
    }

    .cmd-box:hover .cmd-copy {
        opacity: 1;
    }

    button.cmd-copy:hover {
        background: rgba(255, 255, 255, .22) !important;
        border-color: rgba(255, 255, 255, .35) !important;
        color: #fff !important;
        box-shadow: none !important;
        opacity: 1;
    }

    button.cmd-copy:focus-visible {
        opacity: 1;
        outline: 2px solid #60a5fa !important;
        outline-offset: 1px;
    }

    button.cmd-copy.copied,
    button.cmd-copy.copied:hover {
        opacity: 1;
        background: #059669 !important;
        border-color: #059669 !important;
        color: #fff !important;
    }

    button.cmd-copy svg {
        display: block;
        flex: 0 0 auto;
        width: 14px;
        height: 14px;
    }

    /* ── CARDS ── */
    .card {
        background: var(--surface) !important;
        border: 1px solid var(--border) !important;
        border-radius: var(--r) !important;
        box-shadow: var(--sh) !important;
    }

    .card-header {
        background: var(--gray-50) !important;
        border-bottom: 1px solid var(--border) !important;
        color: var(--sub) !important;
        font-size: 12.5px !important;
        font-family: var(--sans) !important;
        font-weight: 600 !important;
        padding: 12px 16px !important;
    }

    /* ── PROGRESS ── */
    .progress {
        background: var(--gray-100) !important;
        border-radius: 100px !important;
        height: 5px !important;
        overflow: hidden
    }

    .progress-bar {
        background: linear-gradient(90deg, var(--blue-500), var(--indigo-500)) !important
    }

    /* Uploaded file name */
    .file-item-name {
        font-size: 1.15rem;
        font-weight: 700;
        letter-spacing: 0.01em;
        color: var(--gray-900, #111);
        font-family: 'Segoe UI', system-ui, -apple-system, sans-serif;
    }
    .file-item-name a {
        color: inherit;
        text-decoration: none;
    }
    .file-item-name a:hover {
        text-decoration: underline;
    }
    .file-download-count {
        display: inline-flex;
        align-items: center;
        gap: 4px;
        margin-left: 8px;
        padding: 2px 8px;
        border-radius: 12px;
        background: #eef2ff;
        color: #1d4ed8;
        font-size: 12px;
        font-weight: 600;
        line-height: 1.2;
        white-space: nowrap;
        vertical-align: middle;
        cursor: pointer;
    }
    .file-download-count:hover { background: #e0e7ff; }
    .file-download-count:focus-visible { outline: 2px solid #2563eb; outline-offset: 1px; }

    /* "Downloaded from" popup, opened from the count (js/home/main.js). */
    .ft-dl-pop {
        position: fixed;
        z-index: 2000;
        max-height: min(60vh, 420px);
        display: flex;
        flex-direction: column;
        background: #fff;
        color: #1f2937;
        border: 1px solid #e5e7eb;
        border-radius: 10px;
        box-shadow: 0 10px 30px rgba(15, 23, 42, .18);
        font-size: 12px;
    }
    .ft-dl-pop-head {
        display: flex;
        align-items: center;
        justify-content: space-between;
        padding: 8px 10px 8px 12px;
        border-bottom: 1px solid #e5e7eb;
        font-weight: 600;
        font-size: 13px;
    }
    .ft-dl-pop-close {
        border: 0;
        background: none;
        color: inherit;
        font-size: 18px;
        line-height: 1;
        padding: 0 4px;
        cursor: pointer;
        opacity: .6;
    }
    .ft-dl-pop-close:hover { opacity: 1; }
    .ft-dl-pop-body { padding: 8px 12px; overflow-y: auto; color: #6b7280; }
    .ft-dl-pop-list { list-style: none; margin: 0; padding: 0; }
    .ft-dl-pop-list li { padding: 6px 0; border-bottom: 1px solid #f1f5f9; }
    .ft-dl-pop-list li:last-child { border-bottom: 0; }
    .ft-dl-where { color: #1f2937; line-height: 1.35; overflow-wrap: anywhere; }
    .ft-dl-when { color: #9ca3af; font-size: 11px; margin-top: 2px; }
    .ft-dl-note { margin-top: 6px; font-size: 11px; color: #9ca3af; }

    /* Copy Link menu: the same popup shell, one row per format. */
    .ft-copy-menu { padding: 4px; }
    .ft-copy-item {
        display: block;
        width: 100%;
        text-align: left;
        border: 0;
        background: none;
        color: inherit;
        padding: 7px 8px;
        border-radius: 7px;
        cursor: pointer;
    }
    .ft-copy-item:hover,
    .ft-copy-item:focus-visible { background: #f1f5f9; outline: none; }
    .ft-copy-label { display: block; font-weight: 600; font-size: 12px; }
    .ft-copy-value {
        display: block;
        margin-top: 2px;
        font-size: 11px;
        color: #6b7280;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
        background: none;
        padding: 0;
    }

    html[data-theme="dark"] .ft-dl-pop { background: #0f172a; color: #e2e8f0; border-color: #1e293b; box-shadow: 0 10px 30px rgba(0, 0, 0, .5); }
    html[data-theme="dark"] .ft-dl-pop-head { border-bottom-color: #1e293b; }
    html[data-theme="dark"] .ft-dl-pop-body { color: #94a3b8; }
    html[data-theme="dark"] .ft-dl-pop-list li { border-bottom-color: #1e293b; }
    html[data-theme="dark"] .ft-dl-where { color: #e2e8f0; }
    html[data-theme="dark"] .ft-copy-item:hover,
    html[data-theme="dark"] .ft-copy-item:focus-visible { background: #1e293b; }
    html[data-theme="dark"] .ft-copy-value { color: #94a3b8; }
    html[data-theme="dark"] .ft-dl-when,
    html[data-theme="dark"] .ft-dl-note { color: #64748b; }
    .file-download-icon,
    .file-size-icon {
        width: 14px;
        height: 14px;
        flex-shrink: 0;
    }
    .file-size-badge {
        display: inline-flex;
        align-items: center;
        gap: 4px;
        margin-left: 8px;
        padding: 2px 8px;
        border-radius: 12px;
        background: #f1f5f9;
        color: #475569;
        font-size: 12px;
        font-weight: 600;
        line-height: 1.2;
        white-space: nowrap;
        vertical-align: middle;
    }

    /* Upload progress bars need enough height to show percentage text */
    #files .progress,
    #files1 .progress {
        height: 20px !important;
        border-radius: 4px !important;
    }

    #files .progress-bar,
    #files1 .progress-bar {
        line-height: 20px !important;
        font-size: 12px !important;
    }

    /* ── DRAG & DROP ── */
    #drag-and-drop-zone,
    /* URL upload row inside the drag & drop zone */
    .ft-url-upload { max-width: 460px; margin: 0 auto 16px; text-align: left; }
    .ft-url-or {
        display: flex; align-items: center; gap: 10px;
        margin-bottom: 10px;
        font-size: 12px; color: var(--sub, #6b7280);
    }
    .ft-url-or::before, .ft-url-or::after {
        content: ""; flex: 1; height: 1px; background: var(--border, #e5e7eb);
    }
    .ft-url-row { display: flex; gap: 8px; }
    .ft-url-row .form-control { flex: 1 1 auto; min-width: 0; }
    .ft-url-row .btn { flex: 0 0 auto; }
    /* File List search box — a full-width row in the sticky card header */
    .ft-search {
        position: relative;
        display: flex;
        align-items: center;
        gap: 8px;
        width: 100%;
        margin: 8px 0 0;
    }
    .ft-search-icon {
        position: absolute;
        left: 9px;
        width: 15px;
        height: 15px;
        color: var(--sub, #6b7280);
        pointer-events: none;
    }
    .ft-search .form-control { flex: 1 1 auto; min-width: 0; padding-left: 30px; }
    .ft-search-count { flex: 0 0 auto; font-size: 12px; white-space: nowrap; }
    #files1 li.ft-search-none { padding: 18px 8px; }

    #URLUploadDiv { margin-top: 6px; font-size: 12.5px; color: var(--sub, #6b7280); word-break: break-all; }

    .dm-uploader {
        background: var(--gray-50) !important;
        border: 2px dashed var(--gray-300) !important;
        border-radius: var(--r) !important;
        transition: all .2s !important;
    }

    #drag-and-drop-zone:hover,
    .dm-uploader:hover {
        border-color: var(--blue-400) !important;
        background: var(--blue-50) !important;
    }

    .dm-uploader h3,
    .dm-uploader h1 {
        color: var(--sub) !important
    }

    /* ── STATUS ── */
    .responded {
        color: var(--emerald-500) !important;
        font-family: var(--mono);
        font-size: 12px;
        font-weight: 500
    }

    .checking,
    .unchecked {
        color: var(--amber-500) !important;
        font-family: var(--mono);
        font-size: 12px
    }

    .timeout {
        color: var(--red-500) !important;
        font-family: var(--mono);
        font-size: 12px
    }

    /* ── MISC ── */
    hr {
        border: none !important;
        border-top: 1px solid var(--border) !important;
        margin: 16px 0 !important
    }

    td,
    th {
        border-color: var(--border) !important;
        color: var(--sub) !important;
        padding: 10px 12px !important
    }

    #divinternetspeed {
        font-family: var(--mono) !important;
        font-size: 12.5px !important;
        color: var(--accent) !important;
        background: var(--blue-50);
        border: 1px solid var(--blue-100);
        border-radius: var(--r-sm);
        padding: 8px 12px;
        display: inline-block;
        margin-bottom: 8px;
    }

    /* ── NOTEPAD real-time status pills ── */
    .nt-status {
        display: inline-flex;
        align-items: center;
        gap: 6px;
        font-size: 12px;
        font-weight: 500;
        font-family: var(--sans, sans-serif);
        padding: 4px 12px;
        border-radius: 100px;
        transition: all .3s;
    }

    .nt-status::before {
        content: '';
        width: 7px;
        height: 7px;
        border-radius: 50%;
        flex-shrink: 0;
    }

    .nt-typing {
        background: #fef3c7;
        color: #92400e;
    }

    .nt-typing::before {
        background: #f59e0b;
        animation: ip-pulse 1s infinite;
    }

    .nt-saving {
        background: #eff6ff;
        color: #1d4ed8;
    }

    .nt-saving::before {
        background: #3b82f6;
        animation: ip-pulse .8s infinite;
    }

    .nt-saved {
        background: #d1fae5;
        color: #065f46;
    }

    .nt-saved::before {
        background: #10b981;
    }

    .nt-updated {
        background: #ede9fe;
        color: #5b21b6;
    }

    .nt-updated::before {
        background: #7c3aed;
    }

    .nt-updated-at {
        margin-left: auto;
        font-size: 12px;
        color: #9ca3af;
        white-space: nowrap;
        text-align: right;
    }

    .nt-updated-at.flash {
        color: #7c3aed;
    }

    .nt-updated-by {
        display: block;
        font-size: 11px;
        color: #9ca3af;
        margin-top: 2px;
        /* Wraps rather than truncating: ISP names alone can run past the
           old 320px cap, which cut the location off mid-word. */
        white-space: normal;
        overflow-wrap: anywhere;
        max-width: 520px;
    }

    .nt-updated-by:empty {
        display: none;
    }

    .nt-error {
        background: #fee2e2;
        color: #991b1b;
    }

    .nt-error::before {
        background: #ef4444;
    }

    .nt-live {
        background: #d1fae5;
        color: #065f46;
    }

    .nt-live::before {
        background: #10b981;
        animation: ip-pulse 1.5s infinite;
    }

    .nt-idle {
        display: none;
    }

    /* ── NOTEPAD with line numbers ── */
    .notepad-wrap {
        display: flex;
        border: 1px solid var(--gray-200);
        border-radius: var(--r-sm);
        overflow: hidden;
        box-shadow: var(--sh);
        min-height: 400px;
    }

    #lines {
        width: 46px !important;
        flex-shrink: 0;
        background: var(--gray-100) !important;
        color: var(--gray-400) !important;
        border: none !important;
        border-right: 1px solid var(--gray-200) !important;
        font-family: var(--mono) !important;
        font-size: 13px !important;
        line-height: 1.8 !important;
        padding: 10px 8px 10px 0 !important;
        text-align: right;
        resize: none !important;
        overflow: hidden !important;
        box-shadow: none !important;
        outline: none !important;
    }

    /* Wrapper that stacks the link-highlight mirror under the textarea */
    .np-hl-wrap {
        flex: 1;
        min-width: 0;
        position: relative;
        background: #fff;
    }

    .np-hl {
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        overflow: hidden;
        pointer-events: none;
        color: transparent;
        white-space: pre-wrap;
        overflow-wrap: break-word;
        /* font metrics are copied from #note at runtime by ntSyncHlStyle() */
    }

    .np-link {
        text-decoration: underline;
        text-decoration-color: #2563eb;
        text-underline-offset: 2px;
        background: rgba(37, 99, 235, .10);
        border-radius: 3px;
    }

    #note {
        position: relative;
        z-index: 1;
        display: block;
        /* kills the inline-block baseline gap under the textarea */
        width: 100%;
        background: transparent !important;
        border: none !important;
        color: var(--text) !important;
        font-family: var(--mono) !important;
        font-size: 13px !important;
        line-height: 1.8 !important;
        padding: 10px 12px !important;
        resize: none !important;
        box-shadow: none !important;
        outline: none !important;
    }

    /* ── MAP ── */
    #map {
        border: 1px solid var(--border) !important;
        border-radius: var(--r) !important;
        overflow: hidden;
        min-height: 280px
    }

    #myCanvas {
        border: 1px solid var(--border) !important;
        border-radius: var(--r-sm) !important;
        background: var(--gray-50) !important;
        display: block
    }

    /* ── MISC ELEMENTS ── */
    .media-body p {
        color: var(--sub) !important;
        font-size: 12.5px !important
    }

    .media-body strong a {
        font-family: var(--mono) !important;
        font-size: 12px !important
    }

    center p {
        color: var(--sub) !important;
        font-size: 12px !important;
        font-family: var(--sans) !important
    }

    /* ── SCROLLBAR ── */
    ::-webkit-scrollbar {
        width: 6px;
        height: 6px
    }

    ::-webkit-scrollbar-track {
        background: var(--gray-50)
    }

    ::-webkit-scrollbar-thumb {
        background: #cbd5e1;
        border-radius: 3px
    }

    /* ── jQuery UI TABS ── */
    #tabs {
        border: 1px solid var(--border) !important;
        border-radius: var(--r) !important;
        overflow: hidden;
        background: #fff !important
    }

    #tabs .ui-tabs-nav {
        background: var(--gray-50) !important;
        border-bottom: 1px solid var(--border) !important;
        padding: 6px 8px 0 !important
    }

    #tabs .ui-tabs-nav li {
        border: 1px solid transparent !important;
        background: transparent !important
    }

    #tabs .ui-tabs-nav li.ui-state-active {
        background: #fff !important;
        border-color: var(--border) !important
    }

    #tabs .ui-tabs-nav li a {
        color: var(--sub) !important;
        font-family: var(--sans) !important;
        font-size: 12.5px !important
    }

    #tabs .ui-tabs-nav li.ui-state-active a {
        color: var(--accent) !important;
        font-weight: 600
    }

    #tabs [role=tabpanel] {
        background: #fff !important;
        padding: 14px !important
    }

    #tabs textarea {
        width: 100% !important
    }

    /* ── FOOTER ── */
    .ip-page-footer {
        text-align: center;
        padding: 20px 24px;
        border-top: 1px solid var(--border);
        color: var(--sub);
        font-size: 12px;
        background: var(--gray-50);
    }

    /* ── MOBILE OVERLAY ── */
    .ip-overlay {
        display: none;
        position: fixed;
        inset: 0;
        background: rgba(0, 0, 0, .4);
        z-index: 149
    }

    .ip-overlay.open {
        display: block
    }

    /* ── TYPING INDICATOR BAR ── */
    .nt-typing-bar {
        display: inline-flex;
        align-items: center;
        gap: 8px;
        background: #eff6ff;
        border: 1px solid #bfdbfe;
        border-radius: 20px;
        font-size: 12px;
        font-weight: 500;
        color: #3b82f6;
        font-family: var(--sans, 'DM Sans', sans-serif);
        opacity: 0;
        max-height: 0;
        padding: 0 12px;
        margin-bottom: 0;
        overflow: hidden;
        border-width: 0;
        transform: translateY(-4px);
        transition: opacity .25s, transform .25s, max-height .3s, padding .3s, margin-bottom .3s, border-width .25s;
    }

    .nt-typing-bar.visible {
        opacity: 1;
        transform: translateY(0);
        max-height: 40px;
        padding: 7px 14px;
        margin-bottom: 10px;
        border-width: 1px;
    }

    .nt-typing-dots {
        display: flex;
        gap: 5px;
        align-items: center;
        flex-shrink: 0;
    }

    .nt-typing-dots span {
        display: block;
        width: 8px;
        height: 8px;
        background: #3b82f6;
        border-radius: 50%;
        animation: nt-bounce 1.4s ease-in-out infinite;
    }

    .nt-typing-dots span:nth-child(1) {
        animation-delay: 0s;
    }

    .nt-typing-dots span:nth-child(2) {
        animation-delay: .2s;
    }

    .nt-typing-dots span:nth-child(3) {
        animation-delay: .4s;
    }

    @keyframes nt-bounce {

        0%,
        60%,
        100% {
            transform: translateY(0);
            opacity: .3;
        }

        30% {
            transform: translateY(-7px);
            opacity: 1;
        }
    }

    /* ── RESPONSIVE ── */
    /* ═══════════════════════════════════════════
       RESPONSIVE — MOBILE FIRST
    ═══════════════════════════════════════════ */

    /* Desktop: hide hamburger */
    @media (min-width: 901px) {
        .ip-hamburger {
            display: none !important;
        }
    }

    /* ── TABLET & MOBILE (≤ 768px) ── */
    @media (max-width: 900px) {

        /* Hamburger visible */
        .ip-hamburger {
            display: flex !important;
        }

        /* Sidebar hidden by default — slides in as drawer */
        .ip-sidebar {
            position: fixed !important;
            top: 0 !important;
            left: 0 !important;
            bottom: 0 !important;
            z-index: 160 !important;
            transform: translateX(-110%) !important;
            border-radius: 0 !important;
            width: 240px !important;
            padding-top: 68px !important;
            overflow-y: auto !important;
            -webkit-overflow-scrolling: touch;
            box-shadow: 4px 0 24px rgba(0, 0, 0, .18) !important;
            transition: transform .28s cubic-bezier(.4, 0, .2, 1) !important;
            pointer-events: auto !important;
        }

        .ip-sidebar.open {
            transform: translateX(0) !important;
        }

        .ip-sidebar ul,
        .ip-sidebar ul li a {
            position: relative;
            z-index: 1;
            touch-action: manipulation;
        }

        /* Layout: stack vertically */
        .ip-body-wrap {
            flex-direction: column !important;
            padding: 12px 12px 32px !important;
            gap: 0 !important;
        }

        /* Content area always full width */
        .ip-content {
            border-radius: 10px !important;
            width: 100% !important;
            min-width: 0 !important;
        }

        /* Tab content padding */
        .tab-content {
            padding: 16px 14px !important;
        }

        /* Typography scale down */
        h2 {
            font-size: 15px !important;
        }

        h3 {
            font-size: 13px !important;
        }

        /* Hide clock in topbar */
        .ip-clock {
            display: none !important;
        }

        /* Topbar tighter */
        .ip-topbar-inner {
            padding: 0 14px !important;
        }

        /* Inputs full-width on small screens */
        input[type=text],
        input[type=number],
        select {
            width: 100% !important;
            max-width: 100% !important;
        }

        /* Buttons wrap naturally */
        input[type=button],
        button,
        .btn {
            white-space: normal !important;
        }

        /* pre / code blocks scroll horizontally */
        pre {
            font-size: 11px !important;
            padding: 10px 12px !important;
        }

        /* Bootstrap rows become single column */
        .row {
            margin: 0 !important;
        }

        .col-md-6,
        .col-sm-6,
        .col-lg-6,
        .col-md-4,
        .col-sm-4,
        .col-lg-4,
        .col-md-8,
        .col-sm-8,
        .col-lg-8,
        .col-md-12 {
            width: 100% !important;
            padding: 4px 0 !important;
            float: none !important;
        }

        /* Notepad wrap */
        .notepad-wrap {
            flex-direction: column !important;
        }

        #lines {
            display: none !important;
            /* hide line numbers on mobile */
        }

        #note {
            width: 100% !important;
            min-height: 260px !important;
            font-size: 14px !important;
        }

        /* File list items stack */
        .media {
            flex-direction: column !important;
        }

        .media-body {
            width: 100% !important;
        }

        /* Map full width */
        #map {
            height: 240px !important;
        }

        /* Canvas max width */
        #myCanvas {
            max-width: 100% !important;
            height: auto !important;
        }

        /* Section head stacks */
        .ip-section-head {
            flex-direction: column !important;
            align-items: flex-start !important;
            gap: 6px !important;
        }

        /* Tables scroll horizontally */
        table {
            display: block;
            overflow-x: auto;
            -webkit-overflow-scrolling: touch;
        }

        /* Typing indicator — mobile size tweak only (base styles are global, outside media query) */
        .nt-typing-bar {
            font-size: 12px !important;
        }

        /* IFrame tools */
        iframe {
            width: 100% !important;
            min-height: 320px;
        }

        /* Uploader zone */
        #drag-and-drop-zone,
        .dm-uploader {
            padding: 20px 12px !important;
        }

        /* Keep "Updated" stamp visible on narrow screens */
        .card-header .files-updated-at {
            width: 100%;
            text-align: right;
            margin-top: 4px;
        }

        /* Pin file-list header so "Updated" stays visible while scrolling */
        .ft-filelist-card > .card-header {
            position: sticky;
            top: 0;
            z-index: 2;
            background: var(--gray-50, #f9fafb) !important;
        }
    }

    /* ── TABLET / SMALL DESKTOP (901px – 1199px) ──
       The file-list column is too narrow here for the buttons and the
       "Updated" stamp to share one line, which pushed Refresh onto its own
       row. Drop the stamp below so all three buttons stay inline. */
    @media (min-width: 901px) and (max-width: 1199px) {
        .ft-filelist-card > .card-header .files-updated-at {
            width: 100%;
            text-align: right;
            margin-top: 4px;
        }
    }

    /* ── SMALL PHONES (≤ 480px) ── */
    @media (max-width: 480px) {

        .ip-topbar-inner {
            padding: 0 10px !important;
        }

        .tab-content {
            padding: 12px 10px !important;
        }

        /* Logo text hide on very small */
        .ip-logo-text {
            font-size: 13px !important;
        }

        /* Form elements */
        input[type=button],
        button,
        .btn {
            padding: 7px 10px !important;
            font-size: 12px !important;
        }

        /* Stat/info boxes */
        div[id^="div"] {
            font-size: 12px !important;
        }

        /* Progress bar label */
        .progress-bar {
            font-size: 10px !important;
        }

        /* Note textarea */
        #note {
            min-height: 200px !important;
            font-size: 13px !important;
        }

        /* File item actions wrap */
        .file-item-actions {
            flex-wrap: wrap !important;
            gap: 4px !important;
        }

        /* Section title smaller */
        .ip-section-title {
            font-size: 14px !important;
        }
    }

    /* ── RELATIVE TIME PILLS ── */
    .file-reltime {
        display: inline-block;
        font-family: var(--mono, monospace);
        font-size: 11.5px;
        font-weight: 500;
        color: #6b7280;
        background: #f3f4f6;
        border: 1px solid #e5e7eb;
        border-radius: 100px;
        padding: 1px 8px;
        cursor: default;
        transition: background .15s;
    }

    .file-reltime:hover {
        background: #e5e7eb;
        color: #374151;
    }

    .file-reltime.rt-fresh {
        background: #d1fae5;
        border-color: #a7f3d0;
        color: #065f46;
    }

    .file-reltime.rt-recent {
        background: #dbeafe;
        border-color: #bfdbfe;
        color: #1d4ed8;
    }

    .file-reltime.rt-today {
        background: #f3f4f6;
        border-color: #e5e7eb;
        color: #374151;
    }

    /* ── Per-file type icon ──
       The tint is drawn from currentColor at low opacity by ::before, so a
       family needs one `color` line and nothing else: the same rule then
       reads correctly on the light page and the dark one, and a new family
       cannot be half-themed. ft_file_icon_html() in
       backend/download_counts.php picks the glyph and the data-ft. */
    .file-ico {
        position: relative;
        flex: 0 0 auto;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        width: 34px;
        height: 34px;
        margin-right: 10px;
        border-radius: 9px;
        color: #6b7280;
    }
    .file-ico::before {
        content: "";
        position: absolute;
        inset: 0;
        border-radius: inherit;
        background: currentColor;
        opacity: .13;
    }
    .file-ico svg { position: relative; width: 18px; height: 18px; }

    /* File list row: icon and name share the first line; the buttons,
       badges and uploader line run the full width underneath, starting
       under the icon rather than leaving a blank column below it.
       .media-body steps out of the box (display: contents) so its
       children sit straight on the grid. Applies to every renderer of
       #files1 — the page load, the JSON refresh and getLastFiles.php. */
    #files1 > li.media {
        display: grid;
        grid-template-columns: auto minmax(0, 1fr);
        align-items: center;
        column-gap: 10px;
    }
    #files1 > li.media > .file-ico { margin-right: 0; }
    #files1 > li.media > .media-body { display: contents; }
    #files1 > li.media > .media-body > .file-item-name {
        grid-column: 2;
        margin: 0 !important;
        min-width: 0;
        word-break: break-word;
    }
    #files1 > li.media > .media-body > :not(.file-item-name) { grid-column: 1 / -1; }
    #files1 > li.media > .media-body > .file-item-name + * { margin-top: 8px; }

    .file-ico[data-ft="image"]   { color: #7c3aed; }
    .file-ico[data-ft="video"]   { color: #4f46e5; }
    .file-ico[data-ft="audio"]   { color: #db2777; }
    .file-ico[data-ft="pdf"]     { color: #e8482b; }   /* Adobe red */
    .file-ico[data-ft="doc"]     { color: #2563eb; }
    .file-ico[data-ft="sheet"]   { color: #0f9d58; }
    .file-ico[data-ft="slides"]  { color: #ea580c; }
    .file-ico[data-ft="archive"] { color: #d97706; }
    .file-ico[data-ft="code"]    { color: #0891b2; }
    .file-ico[data-ft="text"]    { color: #64748b; }
    .file-ico[data-ft="apk"]     { color: #2ca25f; }
    .file-ico[data-ft="font"]    { color: #7e22ce; }
    .file-ico[data-ft="unknown"] { color: #6b7280; }

    html[data-theme="dark"] .file-ico[data-ft="text"]    { color: #94a3b8; }
    html[data-theme="dark"] .file-ico[data-ft="unknown"] { color: #94a3b8; }

    /* Per-file "uploaded from" location line.

       It WRAPS. It used to be nowrap + ellipsis, which on any real upload
       cut the line off inside the location — "🇸🇬 DataCamp Limited •
       Singapore, North West, Singapore • 95.173.218.111 • 📱 iPh…" — so
       the one question the line exists to answer, where the file came
       from, was the part that got thrown away. ISP, place, IP and device
       are joined with " • ", so ordinary wrapping breaks between fields;
       break-word is the backstop for one long unbroken field (an ISP name,
       an IPv6 address) on a narrow phone. */
    .file-uploader {
        font-size: 11px;
        line-height: 1.35;
        color: #9ca3af;
        margin-top: 2px;
        overflow-wrap: break-word;
        max-width: 100%;
    }

    html[data-theme="dark"] .file-uploader { color: #64748b !important; }

    /* ── FILE COUNT BADGE ── */
    .nav-file-badge {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        margin-left: auto;
        min-width: 20px;
        height: 20px;
        padding: 0 6px;
        background: #2563eb;
        color: #fff;
        font-size: 11px;
        font-weight: 700;
        font-family: var(--sans, 'DM Sans', sans-serif);
        border-radius: 100px;
        line-height: 1;
        transition: transform .2s, background .2s;
        flex-shrink: 0;
    }

    #rootwizard>ul.nav>li.active>a .nav-file-badge {
        background: #60a5fa;
    }

    #rootwizard>ul.nav>li>a:hover .nav-file-badge {
        transform: scale(1.15);
    }

    .nav-file-badge.zero {
        background: #6b7280;
        opacity: .6;
    }

    /* Someone is uploading to Global File Transfer — pulsing up-arrow */
    .nav-upload-spin {
        display: none;
        align-items: center;
        justify-content: center;
        margin-left: auto;
        width: 18px;
        height: 18px;
        color: #22c55e;
        flex-shrink: 0;
        animation: navUploadPulse 1s ease-in-out infinite;
    }

    .nav-upload-spin.active {
        display: inline-flex;
    }

    /* The "Drop files here" overlay, raised the moment a dragged file
       crosses the page. Built from the theme's own variables, so it needs
       no dark-mode rules of its own: --surface, --border, --text and --sub
       are all remapped under html[data-theme="dark"]. */
    #ip-drop-veil {
        position: fixed;
        inset: 0;
        z-index: 100000;          /* over the topbar, the sidebar and the online popup */
        display: none;
        align-items: center;
        justify-content: center;
        padding: 24px;
        background: rgba(15, 23, 42, .55);
        backdrop-filter: blur(3px);
        -webkit-backdrop-filter: blur(3px);
    }

    #ip-drop-veil.visible { display: flex; }

    .ip-drop-card {
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        gap: 10px;
        width: min(560px, 100%);
        padding: 48px 32px;
        text-align: center;
        color: var(--text);
        background: var(--surface);
        border: 2px dashed var(--accent);
        border-radius: 18px;
        box-shadow: 0 24px 60px rgba(0, 0, 0, .28);
        /* The card is scenery: every drag event has to reach the veil
           underneath it, or moving over the card would read as leaving. */
        pointer-events: none;
        animation: ipDropIn .16s ease-out;
    }

    @keyframes ipDropIn {
        from { opacity: 0; transform: scale(.97); }
        to   { opacity: 1; transform: scale(1); }
    }

    @media (prefers-reduced-motion: reduce) {
        .ip-drop-card { animation: none; }
    }

    .ip-drop-icon { width: 44px; height: 44px; color: var(--accent); }
    .ip-drop-title { font-size: 21px; font-weight: 700; letter-spacing: -.01em; }
    .ip-drop-sub { font-size: 13px; color: var(--sub); max-width: 40ch; line-height: 1.5; }

    @media (max-width: 480px) {
        .ip-drop-card { padding: 32px 20px; }
        .ip-drop-title { font-size: 18px; }
    }

    /* Dragging files over the "File Transfer" menu item. Same accent the
       active section uses, so it reads as "this is where it will go",
       with a dashed edge to say it is a target and not the current tab. */
    #rootwizard>ul.nav>li.nav-drop-target>a,
    #rootwizard>ul.nav>li.nav-drop-target>a:focus,
    #rootwizard>ul.nav>li.nav-drop-target>a:hover {
        color: var(--sidebar-text) !important;
        background: rgba(0, 212, 255, .16) !important;
        border-left: 3px dashed var(--sidebar-accent) !important;
    }
    #rootwizard>ul.nav>li.nav-drop-target>a .nav-icon {
        color: var(--sidebar-accent) !important;
    }

    /* When the arrow is visible, the count badge sits right after it */
    .nav-upload-spin.active+.nav-file-badge {
        margin-left: 6px;
    }

    @keyframes navUploadPulse {
        0%, 100% { transform: translateY(0); opacity: 1; }
        50% { transform: translateY(-3px); opacity: .5; }
    }

    /* Bottom-nav files badge pulses while someone is uploading */
    .ip-bn-badge.uploading {
        background: #22c55e;
        opacity: 1;
        animation: navUploadPulse 1s ease-in-out infinite;
    }

    /* ── NOTEPAD status symbol in sidebar ── */
    .nav-note-badge {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        margin-left: auto;
        width: 20px;
        height: 20px;
        font-size: 13px;
        line-height: 1;
        border-radius: 100px;
        flex-shrink: 0;
        transition: color .2s, transform .2s;
    }

    /* Empty notepad — muted hollow circle */
    .nav-note-badge.empty {
        color: #6b7280;
        opacity: .6;
    }

    /* Notepad has content — solid accent dot */
    .nav-note-badge.filled {
        color: #2563eb;
        opacity: 1;
    }

    #rootwizard>ul.nav>li.active>a .nav-note-badge.filled {
        color: #60a5fa;
    }

    #rootwizard>ul.nav>li>a:hover .nav-note-badge {
        transform: scale(1.15);
    }

    /* Someone is typing — pulsing pencil */
    .nav-note-badge.typing {
        color: #22c55e;
        opacity: 1;
        animation: navNotePulse 1s ease-in-out infinite;
    }

    @keyframes navNotePulse {
        0%, 100% { transform: scale(1); opacity: 1; }
        50% { transform: scale(1.25); opacity: .55; }
    }

    /* ip-body-wrap layout */
    .ip-body-wrap {
        max-width: 1180px;
        margin: 0 auto;
        display: flex;
        gap: 20px;
        padding: 24px 24px 40px;
        align-items: flex-start;
    }

    @media (max-width: 768px) {
        .ip-body-wrap {
            flex-direction: column !important;
            padding: 12px 12px 32px !important;
            gap: 0 !important;
        }
    }

    /* ═══════════════════════════════════════════
       BOTTOM NAV BAR (mobile only)
    ═══════════════════════════════════════════ */
    .ip-bottom-nav {
        display: none;
        /* hidden on desktop */
    }

    @media (max-width: 900px) {

        /* Push content up so it's not hidden behind the nav bar */
        body {
            padding-bottom: 62px;
        }

        .ip-bottom-nav {
            display: flex;
            position: fixed;
            bottom: 0;
            left: 0;
            right: 0;
            z-index: 120;
            background: rgba(255, 255, 255, 0.96);
            backdrop-filter: blur(12px);
            -webkit-backdrop-filter: blur(12px);
            border-top: 1px solid var(--gray-200, #e5e7eb);
            box-shadow: 0 -2px 16px rgba(0, 0, 0, .07);
            padding: 6px 4px calc(6px + env(safe-area-inset-bottom));
            gap: 0;
        }

        .ip-bn-item {
            flex: 1;
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            gap: 3px;
            padding: 4px 2px;
            cursor: pointer;
            border-radius: 10px;
            transition: background .15s;
            position: relative;
            -webkit-tap-highlight-color: transparent;
            text-decoration: none !important;
        }

        .ip-bn-item:active {
            background: var(--gray-100, #f3f4f6);
        }

        .ip-bn-item svg {
            width: 22px;
            height: 22px;
            color: var(--gray-400, #9ca3af);
            transition: color .15s, transform .15s;
        }

        .ip-bn-item span {
            font-size: 10px;
            font-weight: 500;
            color: var(--gray-400, #9ca3af);
            font-family: var(--sans, 'DM Sans', sans-serif);
            transition: color .15s;
            white-space: nowrap;
        }

        .ip-bn-item.active svg {
            color: var(--blue-600, #2563eb);
            transform: translateY(-1px);
        }

        .ip-bn-item.active span {
            color: var(--blue-600, #2563eb);
            font-weight: 600;
        }

        .ip-bn-item.active::after {
            content: '';
            position: absolute;
            bottom: -2px;
            left: 50%;
            transform: translateX(-50%);
            width: 20px;
            height: 3px;
            background: var(--blue-600, #2563eb);
            border-radius: 3px 3px 0 0;
        }

        /* File count badge on Files tab */
        .ip-bn-badge {
            position: absolute;
            top: 2px;
            right: calc(50% - 18px);
            min-width: 16px;
            height: 16px;
            background: #2563eb;
            color: #fff;
            font-size: 9px;
            font-weight: 700;
            border-radius: 100px;
            display: flex;
            align-items: center;
            justify-content: center;
            padding: 0 4px;
            border: 2px solid #fff;
            transition: background .2s;
        }

        .ip-bn-badge.zero {
            background: #9ca3af;
        }
    }
