/* ============================================================================
   GRAY WOLF — DESIGN LAYER
   Loaded after global.css. Recalibrates the shared token set, typography,
   motion and primitives so every page in the app inherits the refresh.

   Type:   Poppins (display) · Inter (UI/body) · JetBrains Mono (data)
   Accent: #36dbe7 dark / #2a1b3d (Gray Wolf purple) light
   ========================================================================= */

/* ── 1. Tokens ───────────────────────────────────────────────────────────── */

:root {
    /* Type stacks */
    --gw-display: 'Poppins', 'Inter', system-ui, sans-serif;
    --gw-sans: 'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;
    --gw-mono: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;

    /* Radius scale — one system, no stray 2px/5px corners */
    --gw-r-xs: 6px;
    --gw-r-sm: 8px;
    --gw-r-md: 10px;
    --gw-r-lg: 14px;
    --gw-r-xl: 20px;
    --gw-r-full: 999px;

    /* Motion */
    --gw-ease-out: cubic-bezier(0.23, 1, 0.32, 1);
    --gw-ease-in-out: cubic-bezier(0.77, 0, 0.175, 1);
    --gw-ease-spring: cubic-bezier(0.34, 1.4, 0.64, 1);
    --gw-t-press: 140ms;
    --gw-t-fast: 180ms;
    --gw-t-base: 240ms;
    --gw-t-slow: 320ms;

    /* Surfaces — layered near-blacks with a cool cast, never #000 */
    --gw-canvas: #0a0c10;
    --gw-surface: #0f1319;
    --gw-surface-2: #141923;
    --gw-surface-3: #1b2130;
    --gw-line: rgba(255, 255, 255, 0.08);
    --gw-line-strong: rgba(255, 255, 255, 0.16);

    /* Ink */
    --gw-ink: #e9edf3;
    --gw-ink-2: rgba(233, 237, 243, 0.64);
    --gw-ink-3: rgba(233, 237, 243, 0.4);

    /* Semantics — unified with the existing badge ramp */
    --gw-accent: #36dbe7;
    --gw-accent-soft: rgba(54, 219, 231, 0.13);
    --gw-accent-ink: #04222a;
    --gw-risk: #ff4d6d;
    --gw-warn: #ffb347;
    --gw-safe: #3dffa0;

    --gw-shadow-1: 0 1px 2px rgba(0, 0, 0, 0.4);
    --gw-shadow-2: 0 4px 16px -4px rgba(0, 0, 0, 0.5);
    --gw-shadow-3: 0 18px 48px -16px rgba(0, 0, 0, 0.7);

    /* ── Remap the legacy token set onto the new palette ── */
    --background-color: var(--gw-canvas);
    --text-color: var(--gw-ink);
    --accent-color: var(--gw-accent);
    --accent-glow: rgba(54, 219, 231, 0.22);
    --accent-glow-strong: rgba(54, 219, 231, 0.42);
    --link-color: var(--gw-ink);
    --link-hover-color: var(--gw-accent);

    --box-1-bg: rgba(20, 25, 35, 0.62);
    --box-2-border: var(--gw-line);
    --glass-border: var(--gw-line);
    --glass-bg-dark: rgba(10, 12, 16, 0.78);
    --glass-bg-card: rgba(255, 255, 255, 0.035);
    --glass-blur: blur(20px) saturate(150%);
    --shadow-glass: var(--gw-shadow-2), inset 0 1px 0 rgba(255, 255, 255, 0.05);
    --shadow-glow: var(--gw-shadow-2);

    --input-bg-color: rgba(255, 255, 255, 0.045);
    --input-border-color: rgba(255, 255, 255, 0.12);
    --input-text-color: var(--gw-ink);
    --search-box-bg-color: rgba(255, 255, 255, 0.035);
    --search-box-border-color: var(--gw-line);

    --button-1-bg-color: rgba(255, 255, 255, 0.07);
    --button-1-border-color: rgba(255, 255, 255, 0.12);
    --button-1-hover-color: rgba(255, 255, 255, 0.12);
    --button-1-bg-color-hover: rgba(255, 255, 255, 0.12);

    --tab-button-text-color: var(--gw-ink-2);
    --tab-button-text-color-hover: var(--gw-ink);
    --tab-button-text-color-clicked: var(--gw-ink);
    --tab-button-bg-color-clicked: transparent;
    --tab-button-bg-hover: transparent;

    --navbar-bg-color: rgba(10, 12, 16, 0.72);
    --popup-bg-color: rgba(20, 25, 35, 0.94);
    --modal-bg-color: rgba(20, 25, 35, 0.96);
    --left-panel-bg-color: rgba(10, 12, 16, 0.8);
    --nested-table-bg-color: var(--gw-surface-2);
    --nested-row-bg-color-hover: rgba(255, 255, 255, 0.05);
}

[data-bs-theme="light"] {
    /* Gray Wolf purple. It carries the chrome, the primary buttons and every
       interactive accent in light mode. */
    --gw-brand: #2a1b3d;

    --gw-canvas: #f5f3f9;
    --gw-surface: #ffffff;
    --gw-surface-2: #f8f6fc;
    --gw-surface-3: #efebf5;
    --gw-line: rgba(42, 27, 61, 0.12);
    --gw-line-strong: rgba(42, 27, 61, 0.24);
    --gw-ink: #211533;
    --gw-ink-2: rgba(33, 21, 51, 0.68);
    --gw-ink-3: rgba(33, 21, 51, 0.46);
    --gw-accent: var(--gw-brand);
    --gw-accent-soft: rgba(42, 27, 61, 0.09);
    --gw-accent-ink: #ffffff;
    /* A lifted tint of the same hue, for hovers and links that need to read as
       interactive rather than as body ink. */
    --gw-accent-lift: #5b4380;
    --gw-risk: #d92546;
    --gw-warn: #b56a06;
    --gw-safe: #0f8f57;

    --gw-shadow-1: 0 1px 2px rgba(42, 27, 61, 0.07);
    --gw-shadow-2: 0 4px 16px -4px rgba(42, 27, 61, 0.14);
    --gw-shadow-3: 0 18px 48px -16px rgba(42, 27, 61, 0.2);

    --link-color: var(--gw-ink);
    --box-1-bg: rgba(255, 255, 255, 0.82);
    --glass-bg-dark: var(--gw-brand);
    --glass-bg-card: rgba(255, 255, 255, 0.7);
    --input-bg-color: rgba(255, 255, 255, 0.9);
    --input-border-color: rgba(42, 27, 61, 0.14);
    --search-box-bg-color: rgba(255, 255, 255, 0.78);
    --button-1-bg-color: rgba(42, 27, 61, 0.06);
    --button-1-border-color: rgba(42, 27, 61, 0.14);
    --button-1-hover-color: rgba(42, 27, 61, 0.1);
    --button-1-bg-color-hover: rgba(42, 27, 61, 0.1);
    /* The header and left rail keep a dark plate in light mode. Their icons,
       nav text and the logo lockup are all built for a dark ground, and the
       brand has no dark-ink logo asset. */
    --navbar-bg-color: var(--gw-brand);
    --popup-bg-color: rgba(255, 255, 255, 0.97);
    --modal-bg-color: #ffffff;
    --left-panel-bg-color: var(--gw-brand);
    --nested-table-bg-color: var(--gw-surface-2);
    --nested-row-bg-color-hover: rgba(42, 27, 61, 0.045);
    --accent-glow: rgba(42, 27, 61, 0.16);
    --accent-glow-strong: rgba(42, 27, 61, 0.3);
    --left-panel-title-color: #b9a8d6;
}

/* ── 2. Typography ───────────────────────────────────────────────────────── */

html,
body {
    font-family: var(--gw-sans);
    font-feature-settings: 'cv11' 1, 'ss01' 1;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    letter-spacing: -0.006em;
}

/* The canvas colour lives on <html>; <body> stays transparent so the ambient
   wash below it can show through. A page stylesheet that sets an opaque body
   background will hide the wash, which is why providers.css no longer does. */
html {
    background-color: var(--gw-canvas);
}

body {
    background-color: transparent;
    background-image: none;
}

/* The ambient wash lives on a fixed, non-painting pseudo-element rather than
   on `background-attachment: fixed`, which forces a full-viewport repaint on
   every scroll frame. Measured: p95 scroll frame 93ms -> 57ms. */
body::before {
    content: '';
    position: fixed;
    inset: 0;
    z-index: -1;
    pointer-events: none;
    background-image:
        radial-gradient(70% 50% at 12% -5%, color-mix(in srgb, var(--gw-accent) 7%, transparent) 0%, transparent 70%),
        radial-gradient(55% 45% at 92% 8%, color-mix(in srgb, var(--gw-accent) 4%, transparent) 0%, transparent 70%);
}

h1, h2, h3, h4, h5,
.landing-page h1,
.landing-page h2,
.gw-display {
    font-family: var(--gw-display);
    font-weight: 600;
    letter-spacing: -0.028em;
    line-height: 1.12;
    text-wrap: balance;
}

h1 { font-size: clamp(1.65rem, 1.2rem + 1.5vw, 2.35rem); margin: 0 0 0.35em; }
h2 { font-size: clamp(1.2rem, 1rem + 0.7vw, 1.5rem); }
h3 { font-size: 1.1rem; letter-spacing: -0.02em; }
h4, h5 { font-size: 0.98rem; letter-spacing: -0.015em; }

.service-page h1 {
    font-size: clamp(1.6rem, 1.25rem + 1.2vw, 2.1rem);
    margin-bottom: 0.15em;
}

p, li, td, th, label, input, select, textarea, button {
    letter-spacing: -0.004em;
}

/* Numerals line up in columns everywhere data lives */
td, th, .number, .metric-chip-val, .verdict-score-num,
.ctx-kv-val, table, .dataTable {
    font-variant-numeric: tabular-nums;
    font-feature-settings: 'tnum' 1;
}

/* Addresses, hashes, tx ids — mono is functional here, not decorative */
.gw-mono,
.crypto-address-link,
code, kbd, samp {
    font-family: var(--gw-mono);
    font-size: 0.92em;
    letter-spacing: -0.01em;
}

/* Small-caps section labels keep their job but lose the shouty tracking */
.cc-tab-section-label,
.metric-chip-label {
    font-weight: 600;
    letter-spacing: 0.04em;
}

/* ── 3. Focus ────────────────────────────────────────────────────────────── */

:focus-visible {
    outline: 2px solid var(--gw-accent);
    outline-offset: 2px;
    border-radius: var(--gw-r-xs);
}

/* ── 4. Buttons ──────────────────────────────────────────────────────────── */

.button-style1,
.button-style2,
.button-style3,
.button-style4,
.button-icon,
.verdict-btn,
div.dt-buttons > .dt-button,
.btn {
    font-family: var(--gw-sans);
    font-weight: 500;
    transition:
        background-color var(--gw-t-fast) var(--gw-ease-out),
        border-color var(--gw-t-fast) var(--gw-ease-out),
        color var(--gw-t-fast) var(--gw-ease-out),
        box-shadow var(--gw-t-fast) var(--gw-ease-out),
        transform var(--gw-t-press) var(--gw-ease-out);
}

.button-style1,
div.dt-buttons > .dt-button,
.button-icon {
    border-radius: var(--gw-r-md);
    box-shadow: var(--gw-shadow-1);
}

.button-style2 {
    border-radius: var(--gw-r-md);
}

.button-style1:hover,
div.dt-buttons > .dt-button:hover,
.button-icon:hover,
.button-style2:hover,
.verdict-btn:hover {
    background: var(--button-1-bg-color-hover);
    border-color: var(--gw-line-strong);
    box-shadow: var(--gw-shadow-2);
}

/* The old red CTA fought the cyan brand accent. It is now the primary. */
.button-style4 {
    background: var(--gw-accent);
    color: var(--gw-accent-ink);
    font-family: var(--gw-display);
    font-weight: 600;
    font-size: 1rem;
    letter-spacing: -0.015em;
    padding: 0.75rem 1.6rem;
    border: none;
    border-radius: var(--gw-r-full);
    box-shadow:
        0 1px 0 rgba(255, 255, 255, 0.25) inset,
        0 6px 22px -6px color-mix(in srgb, var(--gw-accent) 60%, transparent);
}

.button-style4:hover {
    background: color-mix(in srgb, var(--gw-accent) 88%, white);
    box-shadow:
        0 1px 0 rgba(255, 255, 255, 0.3) inset,
        0 10px 30px -6px color-mix(in srgb, var(--gw-accent) 70%, transparent);
}

/* Press feedback. Nothing in this app confirmed a click before. */
.button-style1:active,
.button-style2:active,
.button-style4:active,
.button-icon:active,
.verdict-btn:active,
div.dt-buttons > .dt-button:active,
.gw-press:active {
    transform: scale(0.97);
}

.button.disabled,
.button-icon:disabled,
.button-style1:disabled {
    opacity: 0.45;
    transform: none;
    cursor: not-allowed;
}

/* ── 5. Inputs ───────────────────────────────────────────────────────────── */

input[type=text],
input[type=password],
input[type=date],
input[type=email],
input[type=number],
input[type=search],
textarea,
select,
.service-page .ms-choice {
    border-radius: var(--gw-r-md);
    padding: 0.55rem 0.85rem;
    font-size: 0.9rem;
    transition:
        border-color var(--gw-t-fast) var(--gw-ease-out),
        box-shadow var(--gw-t-fast) var(--gw-ease-out),
        background-color var(--gw-t-fast) var(--gw-ease-out);
}

input[type=text]:hover,
input[type=password]:hover,
input[type=email]:hover,
input[type=search]:hover,
select:hover {
    border-color: var(--gw-line-strong);
}

input[type=text]:focus,
input[type=password]:focus,
input[type=date]:focus,
input[type=email]:focus,
input[type=number]:focus,
input[type=search]:focus,
textarea:focus,
select:focus {
    border-color: var(--gw-accent);
    box-shadow: 0 0 0 3px var(--gw-accent-soft);
    outline: none;
}

::placeholder { color: var(--gw-ink-3); opacity: 1; }

.search-box {
    border-radius: var(--gw-r-lg);
    padding: 1.15rem 1.35rem;
    background: var(--search-box-bg-color);
    border-color: var(--gw-line);
}

/* ── 6. Surfaces ─────────────────────────────────────────────────────────── */

.box-style1 {
    border-radius: var(--gw-r-lg);
    border-color: var(--gw-line);
    background: var(--box-1-bg);
    box-shadow: var(--gw-shadow-2);
    transition: border-color var(--gw-t-base) var(--gw-ease-out);
}

.box-style2 { border-radius: var(--gw-r-lg); }
.box-style2-small { border-radius: var(--gw-r-md); }
.nested-table { border-radius: var(--gw-r-md); }
.table-div { border-radius: var(--gw-r-lg); }
.modal-content { border-radius: var(--gw-r-lg); border: 1px solid var(--gw-line); }
.dropdown-menu, .popup, .popover { border-radius: var(--gw-r-md); }

.ctx-panel {
    border-radius: var(--gw-r-lg);
    transition:
        border-color var(--gw-t-base) var(--gw-ease-out),
        transform var(--gw-t-base) var(--gw-ease-out),
        box-shadow var(--gw-t-base) var(--gw-ease-out);
}

.cc-tab-block { border-radius: var(--gw-r-md); }
.metric-chip { border-radius: var(--gw-r-sm); }
.risk-box { border-radius: var(--gw-r-full); padding: 2px 9px; font-size: 0.75rem; }

/* Card lift, pointer devices only — touch fires hover on tap */
@media (hover: hover) and (pointer: fine) {
    .ctx-panel:hover {
        transform: translateY(-2px);
        border-color: var(--gw-line-strong);
        box-shadow: var(--gw-shadow-2);
    }
}

/* ── 7. Segmented tabs ───────────────────────────────────────────────────── */
/* Replaces the grey 2px-radius fill blocks with one pill track and a single
   indicator that slides between items — the movement is what tells you the
   state changed. */

.tab-button-group,
.gw-segmented {
    position: relative;
    display: inline-flex;
    width: fit-content;
    max-width: 100%;
    flex-wrap: wrap;
    gap: 2px;
    padding: 4px;
    border-radius: var(--gw-r-full);
    background: var(--gw-surface-2);
    border: 1px solid var(--gw-line);
    box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.25);
    isolation: isolate;
}

[data-bs-theme="light"] .tab-button-group,
[data-bs-theme="light"] .gw-segmented {
    box-shadow: inset 0 1px 2px rgba(42, 27, 61, 0.05);
}

.tab-button-group .gw-seg-indicator {
    position: absolute;
    z-index: -1;
    pointer-events: none;
    top: 4px;
    left: 0;
    height: calc(100% - 8px);
    border-radius: var(--gw-r-full);
    background: var(--gw-surface-3);
    border: 1px solid var(--gw-line-strong);
    box-shadow: var(--gw-shadow-1);
    opacity: 0;
    transform-origin: left center;
    transition:
        transform var(--gw-t-base) var(--gw-ease-spring),
        width var(--gw-t-base) var(--gw-ease-spring),
        opacity var(--gw-t-fast) var(--gw-ease-out);
}

.tab-button-group .gw-seg-indicator.is-ready { opacity: 1; }

.tab-button,
.nav-tabs .nav-link {
    position: relative;
    border-radius: var(--gw-r-full) !important;
    border: none !important;
    background: transparent !important;
    padding: 0.42rem 1.05rem;
    font-size: 0.86rem;
    font-weight: 500;
    white-space: nowrap;
    transition:
        color var(--gw-t-fast) var(--gw-ease-out),
        transform var(--gw-t-press) var(--gw-ease-out);
}

.tab-button:hover,
.nav-tabs .nav-link:hover {
    color: var(--tab-button-text-color-hover) !important;
    background: transparent !important;
}

.tab-button.clicked,
.tab-button.clicked:hover,
.nav-tabs .nav-link.active,
.nav-tabs .nav-item.show .nav-link {
    color: var(--gw-ink) !important;
    background: transparent !important;
    font-weight: 600;
}

/* Fallback fill for groups the indicator script has not measured (bare
   Bootstrap nav-tabs, tabs rendered after load) */
.tab-button-group:not(.gw-seg-live) .tab-button.clicked,
.nav-tabs .nav-link.active {
    background: var(--gw-surface-3) !important;
    box-shadow: var(--gw-shadow-1);
}

.tab-button:active,
.nav-tabs .nav-link:active { transform: scale(0.97); }

.nav-tabs {
    border-bottom: none;
    gap: 2px;
    padding: 4px;
    border-radius: var(--gw-r-full);
    background: var(--gw-surface-2);
    border: 1px solid var(--gw-line);
    width: fit-content;
}

/* ── 8. Loading ──────────────────────────────────────────────────────────── */
/* The spinner-and-"Loading..." scrim is replaced by an indeterminate top bar
   over a light scrim: less occlusion, and a moving bar reads as faster. */

.loading-backdrop {
    background-color: rgba(8, 10, 14, 0.45) !important;
    backdrop-filter: blur(2px) !important;
    -webkit-backdrop-filter: blur(2px) !important;
    font-size: 0 !important;
    gap: 0 !important;
    align-items: flex-start !important;
    transition: opacity var(--gw-t-base) var(--gw-ease-out);
}

.loading-backdrop.d-none { display: none !important; }

.gw-progress {
    width: 100%;
    height: 2px;
    overflow: hidden;
    background: color-mix(in srgb, var(--gw-accent) 14%, transparent);
}

.gw-progress::after {
    content: '';
    display: block;
    width: 40%;
    height: 100%;
    border-radius: var(--gw-r-full);
    background: linear-gradient(90deg,
        transparent,
        var(--gw-accent) 35%,
        var(--gw-accent) 65%,
        transparent);
    animation: gw-indeterminate 1.15s var(--gw-ease-in-out) infinite;
}

@keyframes gw-indeterminate {
    0% { transform: translateX(-100%); }
    100% { transform: translateX(350%); }
}

/* Skeletons for content that arrives later */
.gw-skeleton {
    position: relative;
    overflow: hidden;
    border-radius: var(--gw-r-sm);
    background: var(--gw-surface-2);
}

.gw-skeleton::after {
    content: '';
    position: absolute;
    inset: 0;
    background: linear-gradient(90deg,
        transparent,
        rgba(255, 255, 255, 0.06),
        transparent);
    animation: gw-shimmer 1.4s var(--gw-ease-in-out) infinite;
}

@keyframes gw-shimmer {
    0% { transform: translateX(-100%); }
    100% { transform: translateX(100%); }
}

.spinner { animation: spinning 0.9s linear infinite; }

/* ── 9. Page entrance ────────────────────────────────────────────────────── */
/* One orchestrated reveal per page load, not a scattered effect on every
   section. Runs once; never blocks interaction. */

.service-page { animation: none; }

.gw-reveal {
    opacity: 0;
    transform: translateY(10px);
}

.gw-reveal.gw-in {
    opacity: 1;
    transform: none;
    transition:
        opacity var(--gw-t-slow) var(--gw-ease-out),
        transform var(--gw-t-slow) var(--gw-ease-out);
    transition-delay: var(--gw-delay, 0ms);
}

/* ── 10. Tables ──────────────────────────────────────────────────────────── */

table.dataTable thead th,
.table thead th {
    font-family: var(--gw-sans);
    font-size: 0.74rem;
    font-weight: 600;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--gw-ink-3);
    border-bottom: 1px solid var(--gw-line) !important;
    border-top: none !important;
    padding-top: 0.7rem;
    padding-bottom: 0.7rem;
}

table.dataTable tbody td,
.table tbody td {
    border-top: none !important;
    border-bottom: 1px solid color-mix(in srgb, var(--gw-line) 55%, transparent) !important;
    font-size: 0.86rem;
    padding-top: 0.6rem;
    padding-bottom: 0.6rem;
}

table.dataTable tbody tr,
.table tbody tr {
    transition: background-color var(--gw-t-fast) var(--gw-ease-out);
}

table.dataTable tbody tr:hover,
.table tbody tr:hover {
    background-color: var(--nested-row-bg-color-hover);
}

/* ── 11. Scrollbars ──────────────────────────────────────────────────────── */

::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }

::-webkit-scrollbar-thumb {
    background-color: var(--gw-line-strong);
    border-radius: var(--gw-r-full);
    border: 3px solid transparent;
    background-clip: content-box;
}

::-webkit-scrollbar-thumb:hover {
    background-color: color-mix(in srgb, var(--gw-ink) 35%, transparent);
    background-clip: content-box;
}

/* Firefox scrollbar styling. Scoped to the root and to the containers that
   actually scroll: a universal selector here forces a style recalculation on
   every node, which is measurable on the data-dense table pages. */
html,
body,
.table-div,
.box-overflow,
.datatable-div,
.dt-scroll-body,
#detailed-menu,
.modal-body,
.dropdown-menu {
    scrollbar-color: var(--gw-line-strong) transparent;
    scrollbar-width: thin;
}

/* ── 12. Semantic colours ────────────────────────────────────────────────── */
/* Pure #f00 hurts on a dark canvas. Everything moves to the badge ramp. */

.deceptive-color, .not-valid-color, .error-message { color: var(--gw-risk); }
.non-deceptive-color, .valid-color { color: var(--gw-safe); }
.potentially-deceptive-color { color: var(--gw-warn); }
.potentially-non-deceptive-color { color: #b6e05a; }
.unrelated-color, .text-lightgrey { color: var(--gw-ink-3); }

.risk-box.critical { background: color-mix(in srgb, var(--gw-risk) 20%, transparent); color: var(--gw-risk); border: 1px solid color-mix(in srgb, var(--gw-risk) 35%, transparent); }
.risk-box.high { background: color-mix(in srgb, var(--gw-warn) 18%, transparent); color: var(--gw-warn); border: 1px solid color-mix(in srgb, var(--gw-warn) 32%, transparent); }
.risk-box.medium { background: rgba(230, 210, 90, 0.16); color: #e6d25a; border: 1px solid rgba(230, 210, 90, 0.3); }
.risk-box.low { background: color-mix(in srgb, var(--gw-safe) 14%, transparent); color: var(--gw-safe); border: 1px solid color-mix(in srgb, var(--gw-safe) 28%, transparent); }

/* ── 13. Links ───────────────────────────────────────────────────────────── */

a { transition: color var(--gw-t-fast) var(--gw-ease-out); }

.crypto-address-link {
    text-decoration-color: color-mix(in srgb, var(--gw-accent) 40%, transparent);
    text-underline-offset: 2px;
}

.button-link { text-underline-offset: 2px; }

/* ── 14. Reduced motion ──────────────────────────────────────────────────── */
/* Fewer and gentler, not zero: opacity still carries the state change. */

@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }

    .gw-reveal { opacity: 1; transform: none; }

    .gw-progress::after,
    .gw-skeleton::after,
    .spinner {
        animation-duration: 1.2s !important;
        animation-iteration-count: infinite !important;
    }

    .tab-button-group .gw-seg-indicator {
        transition-duration: 0.01ms !important;
    }

    a:active, button:active, .button:active,
    .tab-button:active, .gw-press:active {
        transform: none !important;
    }
}

/* Glass surfaces need a solid fallback when transparency is turned down */
@media (prefers-reduced-transparency: reduce) {
    .box-style1,
    .dropdown-menu,
    .popup,
    .modal-content,
    #left-navbar,
    .header-panel {
        backdrop-filter: none !important;
        -webkit-backdrop-filter: none !important;
        background: var(--gw-surface) !important;
    }
}

/* ============================================================================
   PART 2 — APPLICATION CHROME
   Page headers, filter panels, DataTables furniture, icon buttons.
   These surfaces appear on nearly every service page.
   ========================================================================= */

/* ── Page header ─────────────────────────────────────────────────────────── */

.service-page { padding-top: 0.5rem; }

.service-page > h1,
.service-page > .content > h1 {
    padding-bottom: 0.85rem;
    margin-bottom: 1.1rem;
    border-bottom: 1px solid var(--gw-line);
}

/* A description immediately after the title is the page's subtitle. */
.service-page > h1 + p,
.service-page > .content > h1 + p {
    margin-top: -0.6rem;
    margin-bottom: 1.4rem;
    max-width: 78ch;
    font-size: 0.9rem;
    line-height: 1.55;
    color: var(--gw-ink-2);
}

/* ── Filter panels ───────────────────────────────────────────────────────── */
/* 2rem of padding on a two-row filter strip left a lot of dead box. */

.box-style1 { padding: 1.3rem 1.4rem; }
.box-style2 { padding: 1.3rem 1.4rem; }

.service-page .box-style1 label,
.service-page .box-style2 label {
    font-size: 0.8rem;
    font-weight: 500;
    color: var(--gw-ink-2);
}

/* ── DataTables furniture ────────────────────────────────────────────────── */

.dt-container {
    font-size: 0.86rem;
    color: var(--gw-ink-2);
}

.dt-length,
.dt-search,
.dt-info,
.dt-paging {
    padding-block: 0.45rem;
}

.dt-length select,
.dt-search input,
.dt-input {
    display: inline-block;
    width: auto;
    min-width: 74px;
    padding: 0.34rem 0.7rem;
    font-size: 0.82rem;
    border-radius: var(--gw-r-sm);
}

.dt-search input { min-width: 210px; }

.dt-length label,
.dt-search label {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    font-size: 0.8rem;
    color: var(--gw-ink-3);
}

.dt-buttons { display: flex; flex-wrap: wrap; gap: 0.4rem; }

div.dt-buttons > .dt-button {
    margin: 0;
    padding: 0.38rem 0.85rem;
    font-size: 0.8rem;
    font-weight: 500;
}

.dt-info {
    font-size: 0.78rem;
    color: var(--gw-ink-3);
    font-variant-numeric: tabular-nums;
}

/* Pagination as one pill track, matching the segmented tabs.
   Scoped through .dt-container to outrank DataTables' own block rule. */
.dt-container div.dt-paging,
.dt-paging {
    display: inline-flex;
    align-items: center;
    gap: 2px;
    padding: 4px;
    border-radius: var(--gw-r-full);
    background: var(--gw-surface-2);
    border: 1px solid var(--gw-line);
    width: fit-content;
    justify-content: flex-start;
}

.dt-container .dt-paging button.dt-paging-button,
.dt-paging-button {
    min-width: 30px;
    height: 28px;
    padding: 0 0.55rem;
    border: none;
    border-radius: var(--gw-r-full);
    background: transparent;
    color: var(--gw-ink-2);
    font-size: 0.8rem;
    font-variant-numeric: tabular-nums;
    cursor: pointer;
    transition:
        background-color var(--gw-t-fast) var(--gw-ease-out),
        color var(--gw-t-fast) var(--gw-ease-out),
        transform var(--gw-t-press) var(--gw-ease-out);
}

.dt-paging-button:hover:not(.disabled):not(.current) {
    background: rgba(255, 255, 255, 0.07);
    color: var(--gw-ink);
}

[data-bs-theme="light"] .dt-paging-button:hover:not(.disabled):not(.current) {
    background: rgba(42, 27, 61, 0.06);
}

.dt-paging-button.current {
    background: var(--gw-surface-3);
    border: 1px solid var(--gw-line-strong);
    color: var(--gw-ink);
    font-weight: 600;
}

.dt-paging-button:active:not(.disabled) { transform: scale(0.94); }

.dt-paging-button.disabled {
    opacity: 0.3;
    cursor: default;
}

/* ── Row action icons ────────────────────────────────────────────────────── */
/* Table rows carry up to eight bare icons with no hit target or feedback. */

td .button-icon,
td a.button-icon,
td button.button-icon {
    height: 26px;
    width: 26px;
    font-size: 0.72rem;
    border-radius: var(--gw-r-sm);
    background: transparent;
    border-color: transparent;
    color: var(--gw-ink-3);
    box-shadow: none;
}

td .button-icon:hover {
    background: rgba(255, 255, 255, 0.08);
    border-color: var(--gw-line);
    color: var(--gw-accent);
}

[data-bs-theme="light"] td .button-icon:hover {
    background: rgba(42, 27, 61, 0.06);
}

td .button-icon:active { transform: scale(0.9); }

/* ── Floating help button ────────────────────────────────────────────────── */

#help-button,
.help-button,
button.button-style1[onclick*="help" i] {
    border-radius: var(--gw-r-full);
    padding: 0.5rem 1.1rem;
    box-shadow: var(--gw-shadow-3);
}

/* ── Badges and chips ────────────────────────────────────────────────────── */

.ssc-badge {
    padding: 2px 9px;
    font-size: 0.68rem;
    font-weight: 600;
    letter-spacing: 0.01em;
}

/* ── Empty states ────────────────────────────────────────────────────────── */
/* "No results found." as a bare table row reads like a rendering failure. */

table.dataTable td.dt-empty,
table.dataTable td.dataTables_empty {
    padding: 2.6rem 1rem !important;
    text-align: center;
    color: var(--gw-ink-3);
    font-size: 0.88rem;
    border-bottom: none !important;
}

.gw-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.55rem;
    padding: 3rem 1.5rem;
    text-align: center;
    color: var(--gw-ink-3);
}

.gw-empty-icon {
    display: grid;
    place-items: center;
    width: 44px;
    height: 44px;
    border-radius: var(--gw-r-md);
    background: var(--gw-surface-2);
    border: 1px solid var(--gw-line);
    color: var(--gw-ink-3);
    font-size: 1.05rem;
}

.gw-empty-title {
    font-family: var(--gw-display);
    font-size: 0.98rem;
    font-weight: 600;
    color: var(--gw-ink-2);
}

.gw-empty-body { font-size: 0.85rem; max-width: 40ch; }

/* ============================================================================
   PART 3 — LIGHT MODE CORRECTIONS

   The light theme was built around a solid purple navbar and sidebar, so its
   chrome text, icons and hover fills were all hardcoded white. Part 1 moved
   those surfaces to neutral light, which left white-on-white. This section
   repoints every one of them at the ink tokens.
   ========================================================================= */

[data-bs-theme="light"] {
    --button-1-text-color: var(--gw-ink);
    --tab-button-text-color-clicked: var(--gw-ink);
    --navbar-text: rgba(255, 255, 255, 0.92);
    --left-panel-text-color: #ffffff;
    --left-panel-link: rgba(255, 255, 255, 0.88);
    --left-panel-link-bg-color: rgba(255, 255, 255, 0.14);
    --main-text-color: var(--gw-ink);
    --card-text: var(--gw-ink);
    --card-text-hover: var(--gw-ink);
    --service-card-bg: var(--glass-bg-card);
    --service-cart-border: var(--gw-line);
    --content-box-border: var(--gw-line);
    --map-color: rgba(22, 20, 44, 0.3);
    --tab-button-bg-color-clicked: transparent;
    --popup-link-text-color: var(--gw-ink);
    --popup-link-bg-color: var(--gw-accent-soft);
    --disable-input-bg-color: rgba(42, 27, 61, 0.06);
}

/* ── Footer ──────────────────────────────────────────────────────────────── */

[data-bs-theme="light"] .main-footer,
[data-bs-theme="light"] .footer-panel,
[data-bs-theme="light"] .main-footer a {
    color: var(--gw-ink);
}

[data-bs-theme="light"] .main-footer a:hover { color: var(--gw-accent); }

/* ── Surfaces that assumed a dark canvas ─────────────────────────────────── */

[data-bs-theme="light"] .ctx-panel,
[data-bs-theme="light"] .cc-tab-block,
[data-bs-theme="light"] .service-card,
[data-bs-theme="light"] .content-box {
    background: var(--gw-surface);
    border-color: var(--gw-line);
    box-shadow: var(--gw-shadow-1);
}

[data-bs-theme="light"] .gw-skeleton::after {
    background: linear-gradient(90deg, transparent, rgba(42, 27, 61, 0.06), transparent);
}

[data-bs-theme="light"] .loading-backdrop {
    background-color: rgba(244, 246, 251, 0.5) !important;
}

[data-bs-theme="light"] .nav-logo,
[data-bs-theme="light"] .header-logo-image {
    filter: none;
}

/* The dot mark and graph are tuned for a dark ground. */
[data-bs-theme="light"] .pm { fill: var(--gw-accent); }
[data-bs-theme="light"] .gw-netgraph { opacity: 0.35; }

/* Landing hero on light. */
[data-bs-theme="light"] .landing-page,
[data-bs-theme="light"] .intro-headline,
[data-bs-theme="light"] .service-card .card-content .card-text .title {
    color: var(--gw-ink);
}

[data-bs-theme="light"] .intro-sub,
[data-bs-theme="light"] .intro-kicker,
[data-bs-theme="light"] .service-card .card-content .card-text .content {
    color: var(--gw-ink-2);
}

[data-bs-theme="light"] .network-logo { filter: saturate(0.25); opacity: 0.65; }

/* The lockup keeps its own colours in both themes. It is a near-white asset,
   so in light mode the bar behind it carries the contrast instead: the header
   and footer sit on a deep plate rather than the page ground. */
[data-bs-theme="light"] .header-logo-image,
[data-bs-theme="light"] .nav-logo,
[data-bs-theme="light"] .footer-logo img,
[data-bs-theme="light"] .main-footer img[alt*="ogo"] {
    filter: none;
}

/* ============================================================================
   PART 4 — LOADING, SEARCH FIELDS, MOTION FINISHES
   ========================================================================= */

/* ── Spinners ────────────────────────────────────────────────────────────── */
/* Font Awesome's spinner glyph and Bootstrap's border spinner appear all over
   the app. Both are recoloured and sped up: a faster spinner makes the same
   wait feel shorter. */

i.fa-spinner,
.spinner {
    color: var(--gw-accent);
    font-size: 0.85em;
    animation: spinning 0.75s linear infinite;
}

.spinner-border {
    width: 1.05rem;
    height: 1.05rem;
    border-width: 2px;
    border-color: var(--gw-accent);
    border-right-color: transparent;
    animation-duration: 0.7s;
}

.spinner-border-sm { width: 0.85rem; height: 0.85rem; border-width: 2px; }

/* Loading copy sits back so the content that replaces it is the event. */
.suggestion-loading,
.ctx-panel-loading .ctx-empty {
    color: var(--gw-ink-3);
    font-size: 0.84rem;
}

/* ── Search fields ───────────────────────────────────────────────────────── */

.dt-container .dt-search input,
.dt-container input[type="search"],
.length-filter input[type="search"],
.length-filter input[type="text"] {
    min-width: 200px;
    width: auto;
    padding: 0.38rem 0.75rem;
    border-radius: var(--gw-r-full);
    border: 1px solid var(--input-border-color);
    background: var(--input-bg-color);
    color: var(--input-text-color);
    font-size: 0.82rem;
}

.length-filter {
    align-items: center;
    gap: 0.75rem;
}

.length-filter label {
    font-size: 0.8rem;
    color: var(--gw-ink-3);
}

/* ── Accordion and disclosure ────────────────────────────────────────────── */

summary { cursor: pointer; }
summary::marker { color: var(--gw-ink-3); }

details > summary {
    transition: color var(--gw-t-fast) var(--gw-ease-out);
}

details > summary:hover { color: var(--gw-accent); }

/* ── Modals ──────────────────────────────────────────────────────────────── */
/* Modals stay centred; only the scale and fade carry the entrance. */

.modal.show .modal-dialog,
.modal-container {
    animation: gw-modal-in var(--gw-t-base) var(--gw-ease-out);
}

@keyframes gw-modal-in {
    from { opacity: 0; transform: scale(0.97); }
    to { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
    .modal.show .modal-dialog,
    .modal-container { animation: none; }
}

/* ── Dropdowns and popovers ──────────────────────────────────────────────── */
/* These are anchored to a trigger, so they grow from it rather than from the
   middle of themselves. */

.dropdown-menu.show,
.popup.show {
    animation: gw-pop-in var(--gw-t-fast) var(--gw-ease-out);
    transform-origin: top left;
}

@keyframes gw-pop-in {
    from { opacity: 0; transform: scale(0.97) translateY(-4px); }
    to { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
    .dropdown-menu.show,
    .popup.show { animation: none; }
}

/* ============================================================================
   PART 5 — ADDRESS CELLS

   Tables used to clip addresses to a 7em ellipsis, which is shorter than the
   part of an address anyone can identify. The full value is shown in mono and
   a copy control sits at the right edge of the cell.
   ========================================================================= */

.gw-address {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    justify-content: space-between;
    min-width: 0;
}

.gw-address-value .gw-link-text {
    font-family: var(--gw-mono);
    font-size: 0.8rem;
    letter-spacing: -0.02em;
}

/* ── Linked values ───────────────────────────────────────────────────────── */
/* The underline wipes in from the left and the external-link glyph arrives
   with it, so before clicking you can see both that the value is a link and
   that it opens somewhere new. Transform and opacity only. */

.gw-link {
    position: relative;
    display: inline-flex;
    align-items: baseline;
    gap: 0.4rem;
    min-width: 0;
    color: var(--gw-ink);
    text-decoration: none;
    white-space: nowrap;
    transition: color var(--gw-t-fast) var(--gw-ease-out);
}

.gw-link-text {
    position: relative;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
}

.gw-link-text::after {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    bottom: -2px;
    height: 1px;
    background: currentColor;
    transform: scaleX(0);
    transform-origin: left center;
    transition: transform var(--gw-t-base) var(--gw-ease-out);
}

.gw-link-icon {
    flex-shrink: 0;
    font-size: 0.66em;
    opacity: 0;
    transform: translateX(-3px);
    transition:
        opacity var(--gw-t-fast) var(--gw-ease-out),
        transform var(--gw-t-base) var(--gw-ease-out);
}

@media (hover: hover) and (pointer: fine) {
    .gw-link:hover,
    tr:hover .gw-link:hover {
        color: var(--gw-accent);
    }

    .gw-link:hover .gw-link-text::after { transform: scaleX(1); }

    .gw-link:hover .gw-link-icon {
        opacity: 1;
        transform: translateX(0);
    }
}

/* Keyboard users get the same affordance. */
.gw-link:focus-visible { color: var(--gw-accent); outline-offset: 3px; }
.gw-link:focus-visible .gw-link-text::after { transform: scaleX(1); }
.gw-link:focus-visible .gw-link-icon { opacity: 1; transform: translateX(0); }

/* Touch has no hover, so the glyph is the only cue and has to be present. */
@media (hover: none) {
    .gw-link-icon { opacity: 0.55; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
    .gw-link-text::after,
    .gw-link-icon { transition-duration: 0.01ms !important; }
}

.gw-sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
}

/* The column is sized to hold a full bech32 address so every copy control
   lands on the same right edge instead of trailing each address at its own
   length. The URL column absorbs whatever is left. */
td.gw-address-col,
th.gw-address-col {
    width: 34%;
    min-width: 26rem;
    white-space: nowrap;
    padding-right: 1.25rem;
}

td.gw-address-col .gw-address { width: 100%; }

@media screen and (max-width: 1100px) {
    td.gw-address-col,
    th.gw-address-col { min-width: 0; width: auto; }
}

.gw-copy {
    flex-shrink: 0;
    display: grid;
    place-items: center;
    width: 24px;
    height: 24px;
    padding: 0;
    border: 1px solid transparent;
    border-radius: var(--gw-r-sm);
    background: transparent;
    color: var(--gw-ink-3);
    font-size: 0.72rem;
    cursor: pointer;
    opacity: 0.4;
    transition:
        opacity var(--gw-t-fast) var(--gw-ease-out),
        background-color var(--gw-t-fast) var(--gw-ease-out),
        border-color var(--gw-t-fast) var(--gw-ease-out),
        color var(--gw-t-fast) var(--gw-ease-out),
        transform var(--gw-t-press) var(--gw-ease-out);
}

/* Present at rest so the control is discoverable, and it comes forward on the
   row the pointer is actually on. */
tr:hover .gw-copy,
.gw-copy:hover,
.gw-copy:focus-visible,
.gw-copy.is-copied {
    opacity: 1;
}

.gw-copy:hover {
    background: rgba(255, 255, 255, 0.08);
    border-color: var(--gw-line);
    color: var(--gw-accent);
}

[data-bs-theme="light"] .gw-copy:hover { background: rgba(42, 27, 61, 0.06); }

.gw-copy:active { transform: scale(0.9); }

/* Confirmation swaps the glyph for a check rather than firing a toast. */
.gw-copy.is-copied {
    background: color-mix(in srgb, var(--gw-safe) 16%, transparent);
    border-color: color-mix(in srgb, var(--gw-safe) 32%, transparent);
    color: var(--gw-safe);
}

.gw-copy.is-copied i::before { content: "\f00c"; font-weight: 900; }

@media (prefers-reduced-motion: reduce) {
    .gw-copy:active { transform: none; }
}

/* Standalone addresses outside tables keep the ellipsis, but a wider one. */
.crypto-address-link { width: auto; max-width: 22em; }

/* ── Header lockup ───────────────────────────────────────────────────────── */
/* One asset, its own colours, in both themes. The bar behind it is dark in
   both themes so nothing has to be tinted. */

.header-logo-light { display: none; }

.header-logo-image,
.nav-logo,
[data-bs-theme="light"] .header-logo-image,
[data-bs-theme="light"] .nav-logo {
    filter: none;
}

/* The chrome is opaque in light mode, so the glass sheen and blur that make
   sense over a dark canvas would only wash it out. */
[data-bs-theme="light"] #left-navbar,
[data-bs-theme="light"] .header-panel {
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    box-shadow: var(--gw-shadow-2);
}

[data-bs-theme="light"] #left-navbar::before,
[data-bs-theme="light"] .header-panel::before {
    background: none;
}

/* Chrome borders read against the light page, not against the dark plate. */
[data-bs-theme="light"] #left-navbar { border-right-color: rgba(0, 0, 0, 0.14); }
[data-bs-theme="light"] .header-panel { border-bottom-color: rgba(0, 0, 0, 0.14); }

/* ============================================================================
   PART 6 — BACKDROP-FILTER

   An earlier pass removed backdrop blur from content panels after measuring a
   page at under 1fps. That measurement was taken while the page was still
   fetching, and was wrong: re-measured with sustained one-second samples, the
   same page holds 63fps either way. The glass is back on the panels.

   What is kept is the part that is free: overlays that sit off-canvas while
   closed do not need to rasterise a blur every frame, so theirs is gated on
   the open state (see the rules below and help_modal.html).
   ========================================================================= */

/* Overlays blur only once they are actually on screen. */
#help-modal,
#detailed-menu,
.ssc-select__menu,
.modal:not(.show) .modal-content {
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
}

#help-modal.open,
#help-modal.show,
#detailed-menu.open,
#detailed-menu.show,
.ssc-select__menu.open,
.ssc-select__menu.show,
.modal.show .modal-content {
    backdrop-filter: var(--glass-blur);
    -webkit-backdrop-filter: var(--glass-blur);
}

@media (prefers-reduced-transparency: reduce) {
    .box-style1,
    #left-navbar,
    .header-panel,
    .dropdown-menu,
    .popup,
    .modal-content,
    #detailed-menu {
        backdrop-filter: none;
        -webkit-backdrop-filter: none;
    }
}

/* ============================================================================
   PART 7 — LIGHT MODE PURPLE

   Gray Wolf purple (#2a1b3d) carries the chrome and every primary action in
   light mode, the way cyan does in dark mode. Interactive text uses the lifted
   tint so it reads as a control rather than as body ink.
   ========================================================================= */

[data-bs-theme="light"] a:hover,
[data-bs-theme="light"] a:focus,
[data-bs-theme="light"] .button-link,
[data-bs-theme="light"] .ctx-kv-val.link,
[data-bs-theme="light"] .cc-expand-btn,
[data-bs-theme="light"] .ctx-panel-action {
    color: var(--gw-accent-lift);
}

/* Primary action: solid brand purple. */
[data-bs-theme="light"] .button-style4,
[data-bs-theme="light"] input[type="submit"].button-style1,
[data-bs-theme="light"] .login-container button,
[data-bs-theme="light"] .login-box button,
[data-bs-theme="light"] form button[type="submit"] {
    background: var(--gw-brand);
    color: #ffffff;
    border-color: var(--gw-brand);
}

[data-bs-theme="light"] .button-style4:hover,
[data-bs-theme="light"] input[type="submit"].button-style1:hover,
[data-bs-theme="light"] .login-container button:hover,
[data-bs-theme="light"] .login-box button:hover,
[data-bs-theme="light"] form button[type="submit"]:hover {
    background: var(--gw-accent-lift);
    border-color: var(--gw-accent-lift);
    box-shadow: 0 6px 20px -6px rgba(42, 27, 61, 0.45);
}

/* Chrome sits on the brand plate, so its own controls tint against it. */
[data-bs-theme="light"] .menu-btn:hover,
[data-bs-theme="light"] .header-nav a:hover {
    background: rgba(255, 255, 255, 0.12);
    color: #ffffff;
}

[data-bs-theme="light"] .menu-btn.clicked {
    background: rgba(255, 255, 255, 0.18);
    border-color: rgba(255, 255, 255, 0.32);
    color: #ffffff;
}

/* Selected states across the app pick up a purple wash rather than plain grey. */
[data-bs-theme="light"] .tab-button-group .gw-seg-indicator,
[data-bs-theme="light"] #cc-tab-row .gw-seg-indicator,
[data-bs-theme="light"] .dt-paging-button.current,
[data-bs-theme="light"] .nav-tabs .nav-link.active,
[data-bs-theme="light"] .tab-button-group:not(.gw-seg-live) .tab-button.clicked {
    background: var(--gw-accent-soft);
    border-color: rgba(42, 27, 61, 0.2);
    color: var(--gw-brand);
}

[data-bs-theme="light"] .tab-button.clicked,
[data-bs-theme="light"] .cc-tab.active {
    color: var(--gw-brand) !important;
}

/* The body wash follows the brand hue instead of the cyan one. */
[data-bs-theme="light"] body::before {
    background-image:
        radial-gradient(70% 50% at 12% -5%, rgba(42, 27, 61, 0.07) 0%, transparent 70%),
        radial-gradient(55% 45% at 92% 8%, rgba(42, 27, 61, 0.05) 0%, transparent 70%);
}

/* A closed overlay still rasterises its blur every frame while it sits
   off-canvas. Blur is applied only once the overlay is actually on screen. */
#help-modal,
#detailed-menu,
.ssc-select__menu,
.modal:not(.show) .modal-content {
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
}

#help-modal.open,
#help-modal.show,
#detailed-menu.open,
#detailed-menu.show,
.ssc-select__menu.open,
.ssc-select__menu.show,
.modal.show .modal-content {
    backdrop-filter: var(--glass-blur);
    -webkit-backdrop-filter: var(--glass-blur);
}

/* ============================================================================
   PART 8 — TAB PANE ENTRY AND CLOUDBURST OSINT
   ========================================================================= */

/* ── Tab pane entry ──────────────────────────────────────────────────────── */
/* The segmented indicator already slides between tabs; the panes themselves
   still swapped instantly. A pane enters with a short rise so the eye follows
   the indicator to the new content. The outgoing pane is not animated: waiting
   out a crossfade is what makes tabbed UI feel slow.
   `display` is not interpolable on its own, so the transition is opted in via
   allow-discrete. Browsers without it keep today's instant swap. */

@media (prefers-reduced-motion: no-preference) {
    .tab-item:not(.hidden):not(.tab-item-hidden),
    .cc-tab-pane.active {
        transition:
            opacity var(--gw-t-fast) var(--gw-ease-out),
            transform var(--gw-t-fast) var(--gw-ease-out),
            display var(--gw-t-fast) allow-discrete;
    }

    @starting-style {
        .tab-item:not(.hidden):not(.tab-item-hidden),
        .cc-tab-pane.active {
            opacity: 0;
            transform: translateY(4px);
        }
    }
}

/* ── Hiding a tab actually hides it ──────────────────────────────────────── */
/* `.hidden { display: none }` is declared at global.css:783, before
   `.tab-button { display: flex }`. Equal specificity, so the later rule wins
   and adding `hidden` to a tab button does nothing at all. Any tab that is
   conditionally present (the CloudBurst OSINT tab is the first) depends on
   this, so it is stated once here rather than worked around per surface. */

.tab-button.hidden,
.nav-tabs .nav-link.hidden,
.cc-tab.hidden {
    display: none !important;
}

/* ── OSINT panel ─────────────────────────────────────────────────────────── */

.cb-panel {
    display: flex;
    flex-direction: column;
    gap: 0.9rem;
}

.cb-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 0.75rem;
    padding-bottom: 0.75rem;
    border-bottom: 1px solid var(--gw-line);
}

.cb-head h3 {
    margin: 0;
    font-size: 0.98rem;
    font-weight: 600;
}

.cb-head p {
    margin: 0.15rem 0 0;
    font-size: 0.8rem;
    color: var(--gw-ink-3);
}

/* Attribution. The logo is the vendor's, so it keeps its own colour and sits
   on a neutral chip rather than being tinted to our palette. */
.cb-brand {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.3rem 0.7rem 0.3rem 0.45rem;
    border-radius: var(--gw-r-full);
    border: 1px solid var(--gw-line);
    background: var(--gw-surface-2);
    color: var(--gw-ink-2);
    font-size: 0.76rem;
    font-weight: 500;
    white-space: nowrap;
    text-decoration: none;
    transition:
        color var(--gw-t-fast) var(--gw-ease-out),
        border-color var(--gw-t-fast) var(--gw-ease-out),
        transform var(--gw-t-press) var(--gw-ease-out);
}

.cb-brand:hover {
    color: var(--gw-ink);
    border-color: var(--gw-line-strong);
    text-decoration: none;
}

.cb-brand:active { transform: scale(0.97); }

.cb-brand img {
    width: 18px;
    height: 18px;
    object-fit: contain;
    flex: none;
}

/* ── Rows ────────────────────────────────────────────────────────────────── */

.cb-list {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

/* ink-2, not ink-3: these carry content rather than decoration, so they have
   to clear AA at their small size in both themes. */
.cb-section-title {
    margin: 0.25rem 0 0;
    font-size: 0.74rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--gw-ink-2);
}

.cb-row {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
    padding: 0.7rem 0.85rem;
    border-radius: var(--gw-r-md);
    border: 1px solid var(--gw-line);
    background: var(--gw-surface-2);
}

.cb-row-top {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.4rem;
}

.cb-snippet {
    margin: 0;
    font-size: 0.84rem;
    line-height: 1.5;
    color: var(--gw-ink-2);
    /* Snippets are scraped chat messages: unbounded length, arbitrary scripts,
       and no line breaks of their own. */
    overflow-wrap: anywhere;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.cb-mono {
    font-family: var(--gw-mono);
    font-size: 0.78rem;
    overflow-wrap: anywhere;
}

/* ── Chips ───────────────────────────────────────────────────────────────── */

.cb-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    padding: 0.15rem 0.55rem;
    border-radius: var(--gw-r-full);
    border: 1px solid var(--gw-line);
    background: var(--gw-surface-3);
    color: var(--gw-ink-2);
    font-size: 0.72rem;
    font-weight: 500;
    white-space: nowrap;
}

.cb-chip-source {
    color: var(--gw-ink);
    border-color: var(--gw-line-strong);
}

/* Mixed from the semantic tokens rather than hardcoded rgba, so the fills
   follow --gw-risk/warn/safe into light mode instead of staying at their
   dark-mode neon values. Same approach as the badge ramp above. */

.cb-chip-risk-high,
.cb-chip-risk-severe {
    color: var(--gw-risk);
    border-color: color-mix(in srgb, var(--gw-risk) 34%, transparent);
    background: color-mix(in srgb, var(--gw-risk) 12%, transparent);
}

.cb-chip-risk-medium {
    color: var(--gw-warn);
    border-color: color-mix(in srgb, var(--gw-warn) 34%, transparent);
    background: color-mix(in srgb, var(--gw-warn) 12%, transparent);
}

.cb-chip-risk-low {
    color: var(--gw-safe);
    border-color: color-mix(in srgb, var(--gw-safe) 32%, transparent);
    background: color-mix(in srgb, var(--gw-safe) 11%, transparent);
}

.cb-meta {
    font-size: 0.74rem;
    color: var(--gw-ink-2);
}

[data-bs-theme="light"] .cb-chip-risk-high,
[data-bs-theme="light"] .cb-chip-risk-severe {
    color: color-mix(in srgb, var(--gw-risk) 74%, #000);
}

[data-bs-theme="light"] .cb-chip-risk-medium {
    color: color-mix(in srgb, var(--gw-warn) 80%, #000);
}

[data-bs-theme="light"] .cb-chip-risk-low {
    color: color-mix(in srgb, var(--gw-safe) 72%, #000);
}

/* Count on the tab button itself. */
.cb-count {
    margin-left: 0.4rem;
    padding: 0.05rem 0.42rem;
    border-radius: var(--gw-r-full);
    background: var(--gw-accent-soft);
    color: var(--gw-accent);
    font-size: 0.72rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

/* ── Arrival ─────────────────────────────────────────────────────────────── */
/* The OSINT tab is only known to exist after its fetch resolves, so it lands
   in a bar the user is already looking at. It grows in rather than appearing
   at full width and shoving its neighbours sideways. */

@media (prefers-reduced-motion: no-preference) {
    .cb-tab-arrive {
        animation: cb-tab-in var(--gw-t-base) var(--gw-ease-out);
    }
}

@keyframes cb-tab-in {
    from { opacity: 0; transform: scale(0.92); }
    to { opacity: 1; transform: none; }
}

/* ── Skeleton ────────────────────────────────────────────────────────────── */
/* Shaped like the rows it stands in for, so nothing reflows when data lands. */

.cb-skeleton {
    border-radius: var(--gw-r-sm);
    background: var(--gw-surface-3);
    position: relative;
    overflow: hidden;
}

.cb-skeleton-row { height: 62px; border-radius: var(--gw-r-md); }
.cb-skeleton-line { height: 11px; }
.cb-skeleton-line + .cb-skeleton-line { margin-top: 0.5rem; }
.cb-skeleton-line.is-short { width: 42%; }

@media (prefers-reduced-motion: no-preference) {
    .cb-skeleton::after {
        content: "";
        position: absolute;
        inset: 0;
        transform: translateX(-100%);
        background: linear-gradient(
            90deg,
            transparent,
            rgba(255, 255, 255, 0.06),
            transparent
        );
        animation: cb-shimmer 1.15s var(--gw-ease-in-out) infinite;
    }
}

@keyframes cb-shimmer {
    to { transform: translateX(100%); }
}

/* ── Light mode ──────────────────────────────────────────────────────────── */

[data-bs-theme="light"] .cb-skeleton::after {
    background: linear-gradient(
        90deg,
        transparent,
        rgba(42, 27, 61, 0.07),
        transparent
    );
}

/* ── Narrow screens ──────────────────────────────────────────────────────── */

@media (max-width: 560px) {
    .cb-head { align-items: flex-start; }
    .cb-brand { order: -1; }
}
