/* Global Styles - Dark Theme (Default)
   Indigo is the primary action color (active tabs, links, primary CTAs).
   ============================================================================
   DESIGN TOKENS (theme-agnostic — same scale on dark + light)

   Use these tokens instead of magic numbers in component styles. They define
   a small, professional vocabulary for type, spacing, radius, and shadow.
   ============================================================================ */
:root {
    /* Typography scale (modular, ~1.125 ratio) */
    --text-xs:  0.72rem;   /* 11.5px — micro labels, badges, helper text */
    --text-sm:  0.82rem;   /* 13px   — body small, table cells, sub-text */
    --text-md:  0.92rem;   /* 14.7px — body default, button labels */
    --text-base:1rem;      /* 16px   — sections of long text */
    --text-lg:  1.12rem;   /* 18px   — H3 / card titles */
    --text-xl:  1.32rem;   /* 21px   — H2 / section titles */
    --text-2xl: 1.65rem;   /* 26px   — H1 / page titles */
    --text-3xl: 2.05rem;   /* 33px   — Hero numbers (tile values) */

    /* Font weights — restraint: only 4 stops */
    --fw-regular: 400;
    --fw-medium: 500;
    --fw-semibold: 600;
    --fw-bold: 700;

    /* Spacing scale (4px base) */
    --space-1: 4px;
    --space-2: 8px;
    --space-3: 12px;
    --space-4: 16px;
    --space-5: 20px;
    --space-6: 24px;
    --space-8: 32px;

    /* Border radius scale (canonical — single source of truth) */
    --radius-sm: 4px;
    --radius-md: 8px;   /* effective value: the theme block previously overrode 6px -> 8px */
    --radius-lg: 12px;  /* effective value: the theme block previously overrode 10px -> 12px */
    --radius-xl: 14px;
    --radius-pill: 999px;

    /* Elevation scale (canonical). Inline box-shadows that match migrate here. */
    --shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.4);
    --shadow-md: 0 4px 12px rgba(0, 0, 0, 0.35);
    --shadow-lg: 0 8px 30px rgba(0, 0, 0, 0.35);
}

/* ============================================================================
   Global "what's broken right now" pill — sits in the top-right of the
   global header (next to the keyboard-help / theme toggle). Three states:
     green  → no failures, pill is hidden via inline style="display:none"
              (keeps the header clean when everything's fine)
     yellow → 1-2 failures, amber outline + count
     red    → 3+ failures, danger outline + animated pulse to draw attention
   Polled every 60s by frontend/app.js (`_pollGlobalStatus`).
   ============================================================================ */
.global-status-pill {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 10px;
    margin-right: 8px;
    background: transparent;
    border: 1px solid var(--gray-300, rgba(255,255,255,0.18));
    border-radius: var(--radius-pill, 999px);
    color: var(--text-primary);
    font-size: var(--text-xs, 0.72rem);
    font-weight: var(--fw-semibold, 600);
    cursor: pointer;
    transition: background 0.15s, border-color 0.15s, transform 0.12s;
    white-space: nowrap;
    line-height: 1.2;
}
.global-status-pill:hover {
    background: var(--bg-elevated);
    transform: translateY(-1px);
}
.global-status-dot {
    display: inline-block;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--gray-400);
}
.global-status-pill.is-yellow {
    border-color: rgba(245, 158, 11, 0.55);
    background: var(--warning-light);
    color: #f59e0b;
}
.global-status-pill.is-yellow .global-status-dot { background: var(--warning, #f59e0b); }
.global-status-pill.is-red {
    border-color: rgba(239, 68, 68, 0.55);
    background: var(--danger-light);
    color: var(--danger);
}
.global-status-pill.is-red .global-status-dot {
    background: var(--danger);
    /* Subtle pulse so the red state is visually unmissable without being
       obnoxious. 2.4s cycle = noticeable but not seizure-inducing. */
    animation: global-status-pulse 2.4s ease-in-out infinite;
}
.global-status-pill.is-loading .global-status-dot { background: var(--gray-400); }
@keyframes global-status-pulse {
    0%, 100% { box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.55); }
    50%      { box-shadow: 0 0 0 6px rgba(239, 68, 68, 0); }
}
[data-theme="light"] .global-status-pill {
    border-color: #e2e8f0;
    color: #475569;
}
[data-theme="light"] .global-status-pill.is-yellow {
    background: rgba(245, 158, 11, 0.10);
    color: #d97706;
}
[data-theme="light"] .global-status-pill.is-red {
    background: rgba(239, 68, 68, 0.08);
    color: #b91c1c;
}

:root, [data-theme="dark"] {
    /* Primary Brand Colors — Indigo */
    --primary: #6366f1;
    --primary-dark: #4f46e5;
    --primary-light: #818cf8;
    --primary-bg: rgba(99, 102, 241, 0.12);
    /* Accent kept as alias of primary so any var(--accent*) usages still work */
    --accent: #6366f1;
    --accent-light: #818cf8;
    --accent-bg: rgba(99, 102, 241, 0.12);

    /* Status Colors */
    --success: #22c55e;
    --success-light: rgba(34, 197, 94, 0.15);
    --success-dark: #16a34a;
    --danger: #ef4444;
    --danger-light: rgba(239, 68, 68, 0.15);
    --danger-dark: #dc2626;
    --warning: #f59e0b;
    --warning-light: rgba(245, 158, 11, 0.15);
    --running: #3b82f6;
    --running-light: rgba(59, 130, 246, 0.15);

    /* Semantic status tokens — single source for pass/fail/running/warn.
       Reference the base palette so light-theme overrides flow through. */
    --status-pass: var(--success);
    --status-fail: var(--danger);
    --status-running: var(--running);
    --status-warn: var(--warning);
    --status-pass-bg: var(--success-light);
    --status-fail-bg: var(--danger-light);
    --status-running-bg: var(--running-light);
    --status-warn-bg: var(--warning-light);

    /* Neutral Colors - Dark Scale */
    --gray-50: #18181b;
    --gray-100: #1f1f23;
    --gray-200: #27272a;
    --gray-300: #3f3f46;
    --gray-400: #71717a;
    --gray-500: #a1a1aa;
    --gray-600: #d4d4d8;
    --gray-700: #e4e4e7;
    --gray-800: #f4f4f5;
    --gray-900: #fafafa;

    /* Background Layers */
    --bg-base: #09090b;
    --bg-surface: #18181b;
    --bg-elevated: #1f1f23;
    --bg-overlay: #27272a;

    /* Table Header */
    --table-header-bg: #1f1f23;
    --table-header-text: #e4e4e7;
    --table-header-hover: #27272a;

    /* Card & Surface */
    --card-bg: #18181b;
    --card-border: #27272a;
    --card-shadow: 0 1px 3px rgba(0, 0, 0, 0.4);

    /* Text */
    --text-primary: #e4e4e7;
    --text-secondary: #a1a1aa;
    --text-muted: #71717a;

    /* Gradients */
    --primary-gradient: linear-gradient(135deg, #6366f1 0%, #818cf8 100%);
    --accent-gradient:  linear-gradient(135deg, #6366f1 0%, #818cf8 100%);
    --success-gradient: linear-gradient(135deg, #22c55e 0%, #4ade80 100%);
    --danger-gradient: linear-gradient(135deg, #ef4444 0%, #f87171 100%);
    --warning-gradient: linear-gradient(135deg, #f59e0b 0%, #fbbf24 100%);
    --info-gradient: linear-gradient(135deg, #3b82f6 0%, #60a5fa 100%);
    --dark-gradient: linear-gradient(135deg, #18181b 0%, #1f1f23 100%);

    /* Spacing — legacy aliases of the canonical --space-* scale (TEMP: remove in cleanup) */
    --spacing-xs: var(--space-1);
    --spacing-sm: var(--space-2);
    --spacing-md: var(--space-3);
    --spacing-lg: var(--space-4);
    --spacing-xl: var(--space-6);

    /* Radius is now defined once in the top :root block (canonical). */

    /* Font Sizes — LEGACY scale (values differ from --text-*; do NOT remap in
       Phase 1, it would change rendered sizes. Unify in the look-refresh phase.) */
    --font-xs: 0.7rem;
    --font-sm: 0.75rem;
    --font-base: 0.85rem;
    --font-md: 0.9rem;
    --font-lg: 1rem;
}

/* Light Theme */
[data-theme="light"] {
    /* Primary Brand Colors — Indigo (kept consistent with dark theme) */
    --primary: #4f46e5;
    --primary-dark: #4338ca;
    --primary-light: #6366f1;
    --primary-bg: rgba(79, 70, 229, 0.08);
    --accent: #4f46e5;
    --accent-light: #6366f1;
    --accent-bg: rgba(79, 70, 229, 0.08);

    /* Status Colors - Slightly adjusted for light bg */
    --success: #16a34a;
    --success-light: rgba(22, 163, 74, 0.12);
    --success-dark: #15803d;
    --danger: #dc2626;
    --danger-light: rgba(220, 38, 38, 0.1);
    --danger-dark: #b91c1c;
    --warning: #d97706;
    --warning-light: rgba(217, 119, 6, 0.12);
    --running: #2563eb;
    --running-light: rgba(37, 99, 235, 0.1);

    /* Neutral Colors - Light Scale with better contrast */
    --gray-50: #f8fafc;
    --gray-100: #f1f5f9;
    --gray-200: #e2e8f0;
    --gray-300: #cbd5e1;
    --gray-400: #94a3b8;
    --gray-500: #64748b;
    --gray-600: #475569;
    --gray-700: #334155;
    --gray-800: #1e293b;
    --gray-900: #0f172a;

    /* Background Layers - With subtle shades */
    --bg-base: #f1f5f9;
    --bg-surface: #f8fafc;
    --bg-elevated: #ffffff;
    --bg-overlay: #e2e8f0;

    /* Card backgrounds for light mode */
    --card-bg: #ffffff;
    --card-border: #e2e8f0;

    /* Table Header */
    --table-header-bg: #e2e8f0;
    --table-header-text: #1e293b;
    --table-header-hover: #cbd5e1;

    /* Card & Surface */
    --card-bg: #ffffff;
    --card-border: #cbd5e1;
    --card-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);

    /* Text - Dark text on light bg */
    --text-primary: #0f172a;
    --text-secondary: #334155;
    --text-muted: #475569;

    /* Gradients */
    --primary-gradient: linear-gradient(135deg, #4f46e5 0%, #6366f1 100%);
    --dark-gradient: linear-gradient(135deg, #f8fafc 0%, #ffffff 100%);
}

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

body {
    font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    background: var(--bg-base);
    min-height: 100vh;
    color: var(--text-primary);
    padding: 0;
    padding-top: 0;
    position: relative;
    overflow-x: auto;
    max-width: 100vw;
    transition: background-color 0.3s ease, color 0.3s ease;
}

/* Global Header with AMD ROCm Logo */
.global-header {
    background: var(--bg-surface);
    border-bottom: 1px solid var(--card-border);
    padding: 10px 30px;
    position: sticky;
    top: 0;
    transition: background-color 0.3s ease, border-color 0.3s ease;
    z-index: 1000;
    box-shadow: 0 2px 4px rgba(0, 21, 41, 0.08);
}

.global-header-content {
    max-width: none;
    margin: 0 auto;
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 0 10px;
}

.logo-section {
    display: flex;
    align-items: center;
    gap: 16px;
}

.amd-logo {
    height: 40px;
    width: auto;
    object-fit: contain;
    border-radius: 8px;
}

.logo-divider {
    width: 1px;
    height: 28px;
    background: rgba(255, 255, 255, 0.2);
}

.dashboard-title {
    font-size: 1.2rem;
    font-weight: 600;
    color: #ffffff;
    letter-spacing: 0.5px;
}

.header-links {
    display: flex;
    gap: 20px;
}

/* Theme Toggle Button */
.theme-toggle {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    background: rgba(255, 255, 255, 0.05);
    border: 1px solid rgba(255, 255, 255, 0.15);
    border-radius: 8px;
    cursor: pointer;
    transition: all 0.2s ease;
    font-size: 1.2rem;
    position: relative;
    /* Explicit color so SVG icons (theme toggle moon/sun, header `?`) inherit
       a visible foreground in dark mode. Without this, currentColor resolves
       to the body default which can be near-transparent on dark backgrounds. */
    color: rgba(255, 255, 255, 0.85);
}

.theme-toggle:hover {
    background: rgba(255, 255, 255, 0.1);
    transform: scale(1.05);
}

.theme-icon-dark,
.theme-icon-light {
    position: absolute;
    transition: opacity 0.2s ease, transform 0.3s ease;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
/* Explicit Lucide icon size + color inside the theme toggle so the moon/sun
   render visibly on both themes. */
.theme-icon-dark [data-lucide], .theme-icon-dark svg.lucide,
.theme-icon-light [data-lucide], .theme-icon-light svg.lucide {
    width: 18px;
    height: 18px;
    color: currentColor;
    stroke: currentColor;
}

/* Dark theme: show moon, hide sun */
:root .theme-icon-dark,
[data-theme="dark"] .theme-icon-dark {
    opacity: 1;
    transform: rotate(0deg);
}

:root .theme-icon-light,
[data-theme="dark"] .theme-icon-light {
    opacity: 0;
    transform: rotate(-90deg);
}

/* Light theme: show sun, hide moon */
[data-theme="light"] .theme-icon-dark {
    opacity: 0;
    transform: rotate(90deg);
}

[data-theme="light"] .theme-icon-light {
    opacity: 1;
    transform: rotate(0deg);
}

[data-theme="light"] .theme-toggle {
    background: #ffffff;
    border-color: #cbd5e1;
    /* Explicit dark slate color so the `?`, moon/sun, and any other
       icons inside the button render visibly on light backgrounds.
       Without this they inherit the dark-mode default (white-ish) and
       disappear into the white background. */
    color: #475569;
}

[data-theme="light"] .theme-toggle:hover {
    background: #f8fafc;
    border-color: #6366f1;
    color: #4f46e5;
}

/* Force the SVG icons inside light-mode header buttons to use the dark
   slate color too. Some browsers don't propagate `color` to inline SVG
   strokes consistently — be explicit. */
[data-theme="light"] .theme-toggle [data-lucide],
[data-theme="light"] .theme-toggle svg.lucide,
[data-theme="light"] .theme-toggle .theme-icon-dark [data-lucide],
[data-theme="light"] .theme-toggle .theme-icon-light [data-lucide],
[data-theme="light"] .theme-toggle .theme-icon-dark svg.lucide,
[data-theme="light"] .theme-toggle .theme-icon-light svg.lucide {
    color: #475569;
    stroke: #475569;
}
[data-theme="light"] .theme-toggle:hover [data-lucide],
[data-theme="light"] .theme-toggle:hover svg.lucide,
[data-theme="light"] .theme-toggle:hover .theme-icon-dark [data-lucide],
[data-theme="light"] .theme-toggle:hover .theme-icon-light [data-lucide],
[data-theme="light"] .theme-toggle:hover .theme-icon-dark svg.lucide,
[data-theme="light"] .theme-toggle:hover .theme-icon-light svg.lucide {
    color: #4f46e5;
    stroke: #4f46e5;
}

/* Same defensive override for the GitHub/Docs link icons in light mode —
   `.header-link` already sets a dark color, but some Lucide upgrades
   leave the SVG stroke default. Make it explicit. */
[data-theme="light"] .header-link [data-lucide],
[data-theme="light"] .header-link svg.lucide {
    color: #475569;
    stroke: #475569;
}
[data-theme="light"] .header-link:hover [data-lucide],
[data-theme="light"] .header-link:hover svg.lucide {
    color: #4f46e5;
    stroke: #4f46e5;
}

.header-link {
    display: flex;
    align-items: center;
    gap: 6px;
    color: rgba(255, 255, 255, 0.85);
    text-decoration: none;
    font-size: 0.9rem;
    font-weight: 500;
    padding: 8px 14px;
    border-radius: 6px;
    transition: all 0.2s ease;
    background: rgba(255, 255, 255, 0.05);
    border: 1px solid rgba(255, 255, 255, 0.15);
}
/* Lucide icons inside header links — explicit size + inherit color so they
   render visibly on the dark header bar. */
.header-link [data-lucide], .header-link svg.lucide {
    width: 16px;
    height: 16px;
    color: currentColor;
    stroke: currentColor;
    flex-shrink: 0;
}

.header-link:hover {
    color: #ffffff;
    background: rgba(255, 255, 255, 0.1);
    border-color: rgba(255, 255, 255, 0.2);
    transform: translateY(-1px);
}

/* Light theme header adjustments */
[data-theme="light"] .global-header {
    background: #e2e8f0;
    border-bottom: 1px solid #cbd5e1;
}

[data-theme="light"] .header-link {
    color: #475569;
    background: rgba(0, 0, 0, 0.03);
    border-color: #e2e8f0;
}

[data-theme="light"] .header-link:hover {
    color: #1e293b;
    background: rgba(0, 0, 0, 0.06);
    border-color: #cbd5e1;
}

[data-theme="light"] .dashboard-title {
    color: #1e293b;
}

[data-theme="light"] .logo-divider {
    background: #e2e8f0;
}

.github-icon, .docs-icon {
    font-size: 1rem;
}

/* Container adjustment for header */
.container {
    padding: 20px;
}

/* Clean background - no animation */

.container {
    max-width: none;
    margin: 0 auto;
    background: transparent;
    padding: 20px 30px;
    overflow-x: visible;
    width: 100%;
    box-sizing: border-box;
}

/* Header */
/* Tab page header — single rule used by every .tab-content > header. Token
   spacing + lighter divider line make the rhythm consistent across tabs.
   Sticky below the tab-nav bar so the page title, dropdowns, and refresh
   button stay visible while scrolling through long tables. */
header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--space-4);
    margin-bottom: var(--space-5);
    padding: var(--space-3) 0 var(--space-4) 0;
    border-bottom: 2px solid var(--card-border, rgba(255,255,255,0.10));
    /* Sticky: global-header ~60px + 8px gap + tab-nav ~48px + 24px mask
       = ~140px. Responsive overrides adjust the `top` value. */
    position: sticky;
    top: 140px;
    z-index: 40;
    background: var(--bg-base);
}
/* Mask below the sticky page-title header — hides content scrolling up
   into the gap between the page title and the first content section.
   Starts BELOW the border-bottom so the divider line stays visible. */
.tab-content > header::after {
    content: '';
    position: absolute;
    top: calc(100% + 2px);
    left: -30px;
    right: -30px;
    height: 16px;
    background: var(--bg-base);
    pointer-events: none;
    z-index: 1;
}
/* Right-side actions group: dropdowns + last-updated + buttons line up
   horizontally and don't push the h1 around. */
header .header-info {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--space-3);
}

/* Single source of truth for heading typography. Component overrides MUST
   inherit from these to keep the visual hierarchy consistent across tabs. */
h1 {
    font-size: var(--text-2xl);
    line-height: 1.2;
    color: var(--text-primary);
    font-weight: var(--fw-semibold);
    display: flex;
    align-items: center;
    gap: var(--space-2);
    letter-spacing: -0.01em;
}
h2 {
    font-size: var(--text-xl);
    line-height: 1.3;
    color: var(--text-primary);
    font-weight: var(--fw-semibold);
    display: flex;
    align-items: center;
    gap: var(--space-2);
    letter-spacing: -0.005em;
}
h3 {
    font-size: var(--text-lg);
    line-height: 1.35;
    color: var(--text-primary);
    font-weight: var(--fw-semibold);
    display: flex;
    align-items: center;
    gap: var(--space-2);
}

/* Icon color in headings — covers BOTH the source <i data-lucide="…">
   markup AND the <svg class="lucide"> that Lucide swaps in at runtime.
   Without the SVG selectors, icons would lose their color the moment Lucide
   upgrades them, which was the source of the "some headings have colored
   icons, others don't" inconsistency. */
h1 i, h2 i, h3 i,
h1 > svg.lucide, h2 > svg.lucide, h3 > svg.lucide,
h1 [data-lucide], h2 [data-lucide], h3 [data-lucide],
.dashboard-section h2 svg.lucide,
.dashboard-section h2 [data-lucide],
.summary-section h2 svg.lucide,
.summary-section h2 [data-lucide] {
    color: var(--primary);
    stroke: currentColor;
}

@media (max-width: 768px) {
    h1 { font-size: var(--text-xl); }
    h2 { font-size: var(--text-lg); }
}

.header-info {
    display: flex;
    align-items: center;
    gap: 30px;
    font-size: 0.9rem;
}

.branch-info, .last-updated {
    display: flex;
    align-items: center;
    gap: 8px;
    color: #666;
}

.last-fetched {
    opacity: 0.85;
    font-size: 0.9em;
}

.branch-info strong {
    color: #333;
}

.refresh-btn {
    background: var(--primary);
    color: white;
    border: none;
    padding: 8px 16px;
    border-radius: 6px;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 0.875rem;
    font-weight: 500;
    transition: all 0.2s ease;
    min-height: 40px;
    box-sizing: border-box;
}

.refresh-btn:hover {
    transform: translateY(-2px);
    box-shadow: 0 5px 15px rgba(102, 126, 234, 0.4);
}

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

.refresh-btn i {
    transition: transform 0.3s;
}

.refresh-btn:hover i {
    transform: rotate(180deg);
}

/* Multi-Arch view switch (segmented two-button control replaces the
   two-option <select> dropdown in the Multi-Arch tab header). */
.ma-view-switch {
    display: inline-flex;
    align-items: stretch;
    gap: 0;
    padding: 3px;
    background: var(--bg-elevated, rgba(255, 255, 255, 0.04));
    border: 1px solid var(--card-border, rgba(255, 255, 255, 0.08));
    border-radius: 8px;
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.02);
}

.ma-view-btn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 6px 12px;
    border: none;
    background: transparent;
    color: var(--text-secondary, rgba(255, 255, 255, 0.7));
    font-size: 0.85rem;
    font-weight: 600;
    border-radius: 6px;
    cursor: pointer;
    transition: background 0.15s ease, color 0.15s ease, transform 0.05s ease;
    line-height: 1;
    white-space: nowrap;
}

.ma-view-btn i {
    width: 14px;
    height: 14px;
}

.ma-view-btn:hover {
    color: var(--text-primary, #fff);
    background: rgba(255, 255, 255, 0.04);
}

.ma-view-btn.is-active {
    background: var(--primary, #6366f1);
    color: #fff;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.15);
}

.ma-view-btn.is-active i {
    color: #fff;
}

.ma-view-btn:active {
    transform: translateY(1px);
}

@media (max-width: 600px) {
    .ma-view-btn span {
        display: none;
    }
    .ma-view-btn {
        padding: 6px 10px;
    }
}

/* Dashboard Grid */
.dashboard-grid {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    gap: 30px;
    margin-bottom: 30px;
    max-width: 100%;
}

.dashboard-section {
    background: var(--card-bg);
    border-radius: 12px;
    padding: 25px;
    border: 1px solid var(--card-border);
    max-width: 100%;
    overflow: hidden;
    transition: background-color 0.3s ease, border-color 0.3s ease;
}
/* Subtle "tag" inside an h2 section title — used for things like
   "develop branch" qualifier without adding visual weight. */
.section-meta {
    margin-left: 8px;
    padding: 2px 9px;
    border-radius: 999px;
    background: rgba(129, 140, 248, 0.12);
    color: var(--text-secondary, #888);
    font-size: 0.65rem;
    font-weight: 600;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    vertical-align: middle;
}

.dashboard-section:hover {
    box-shadow: 0 8px 30px rgba(0, 0, 0, 0.12);
}

.dashboard-section.full-width {
    grid-column: 1 / -1;
}

.dashboard-section h2 {
    font-size: 1.5rem;
    margin-bottom: 20px;
    color: var(--text-primary);
    display: flex;
    align-items: center;
    gap: 10px;
}

.dashboard-section h2 i {
    color: var(--primary);
}

/* Tables */
.table-container {
    overflow-x: auto;
    border-radius: 10px;
    border: 1px solid var(--card-border, #e2e8f0);
    max-width: 100%;
    -webkit-overflow-scrolling: touch;
    background: var(--bg-elevated, transparent);
}

.table-container.horizontal-scroll {
    max-width: 100%;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    border-radius: 0;
}

table {
    width: 100%;
    border-collapse: collapse;
    background: var(--card-bg);
    transition: background-color 0.3s ease;
}

th {
    background: var(--table-header-bg);
    padding: var(--spacing-md) var(--spacing-sm);
    text-align: left;
    font-weight: 600;
    color: var(--table-header-text);
    font-size: var(--font-sm);
    text-transform: uppercase;
    letter-spacing: 0.5px;
    border: none;
    border-bottom: 2px solid var(--card-border, rgba(255,255,255,0.10));
}

td {
    padding: 10px 8px;
    border-bottom: 1px solid var(--card-border);
    font-size: 0.9rem;
    color: var(--text-primary);
    transition: background-color 0.3s ease;
}

tr:hover {
    background: var(--bg-elevated);
}

.loading {
    text-align: center;
    padding: 40px;
    color: var(--text-muted);
    font-style: italic;
}

/* ---------- Status Badges (redesigned) ----------
   Goals:
    - Single, readable hue per status (no clashing gradients).
    - Status-colored LEFT BORDER for emphasis (matches AI insight cards).
    - Cleaner typography: status icon on top, duration on a single muted
      line below — no nested mini-circle for queue time (that lives in
      the tooltip now).
    - For failure badges that open the AI investigate modal on click,
      reveal a "Investigate ›" hint on hover (status-badge-hint). Makes
      the badge feel clickable instead of just a status pill. */
.status-badge {
    position: relative;
    display: inline-flex;
    padding: 5px 8px;
    border-radius: 6px;
    font-size: 0.72rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.3px;
    text-align: center;
    min-width: 70px;
    min-height: 36px;
    align-items: center;
    justify-content: center;
    flex-direction: column;
    transition: transform 0.1s ease, filter 0.1s ease, box-shadow 0.15s ease;
    box-sizing: border-box;
    overflow: hidden;
    /* Subtle depth: a 1px white inset on the top edge (suggests light from
       above) + a small dark drop shadow (suggests the pill is slightly
       raised). Tuned to read as "polished button" not "neon glow". */
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.12),
        0 1px 2px rgba(0, 0, 0, 0.30);
}

/* Light mode: same shape, lighter ink. Pure-black drop shadow is too
   heavy on white surfaces; soften it and bump the highlight slightly so
   the pill still feels lifted on bright backgrounds. */
[data-theme="light"] .status-badge {
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.30),
        0 1px 2px rgba(15, 23, 42, 0.10);
}

/* Hover: gentle lift — uses the same translateY already applied by
   `a.status-link:hover .status-badge`, but adds a slightly softer
   shadow so the elevation feels intentional. */
a.status-link:hover .status-badge {
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.18),
        0 2px 4px rgba(0, 0, 0, 0.35);
}
[data-theme="light"] a.status-link:hover .status-badge {
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.45),
        0 2px 4px rgba(15, 23, 42, 0.15);
}

/* Investigate affordance — failure badges that open the AI modal show
   a tiny sparkle icon (✦) in the top-right corner. Very subtle at rest,
   brightens on hover + the rainbow glow border appears. Signals "AI
   investigation available" without covering the status content. */
.status-badge-hint { display: none; }

.status-badge-actionable {
    cursor: pointer;
}

/* Sparkle icon — purple/indigo tint, always visible; brightens on hover */
.status-badge-actionable::before {
    content: '✦';
    position: absolute;
    top: 2px;
    right: 3px;
    font-size: 0.5rem;
    line-height: 1;
    color: rgba(167, 139, 250, 0.5);
    pointer-events: none;
    transition: color 0.2s ease, transform 0.2s ease, text-shadow 0.2s ease;
    z-index: 2;
}
.status-badge-actionable:hover::before,
a.status-link:hover .status-badge-actionable::before {
    color: #c4b5fd;
    transform: scale(1.4);
    text-shadow: 0 0 6px rgba(167, 139, 250, 0.6);
}

/* Rainbow glow border on hover */
.status-badge-actionable::after {
    content: '';
    position: absolute;
    inset: -2px;
    border-radius: inherit;
    border: 2px solid transparent;
    opacity: 0;
    transition: opacity 0.2s ease;
    pointer-events: none;
    background: linear-gradient(135deg, #fbbf24, #f87171, #a78bfa, #22d3ee) border-box;
    -webkit-mask: linear-gradient(#fff 0 0) padding-box, linear-gradient(#fff 0 0);
            mask: linear-gradient(#fff 0 0) padding-box, linear-gradient(#fff 0 0);
    -webkit-mask-composite: xor;
            mask-composite: exclude;
}
.status-badge-actionable:hover::after,
a.status-link:hover .status-badge-actionable::after {
    opacity: 1;
    animation: glow-rotate 2s linear infinite;
}

@keyframes glow-rotate {
    0%   { filter: hue-rotate(0deg); }
    100% { filter: hue-rotate(360deg); }
}

/* Dark mode: rich mid-tone fills — same visual pattern as the light-mode
   pastels but shifted into the dark palette. Saturated enough to pop on
   dark backgrounds, not so bright they sear your eyes at 1 AM. White
   text for maximum readability. Subtle colored left border for type cue. */
/* ---- Dark-mode badge palette ----
   Vibrant saturated fills matching the download-button aesthetic (the
   green/pink/amber pills the user liked). White text for readability.
   Left-border accent in a lighter shade of the same hue. */
.status-badge.pass {
    /* Use the canonical --success token so this badge matches every
       other "success" affordance in the dashboard. Was #34d399 (emerald
       400) which read as a slightly different green than text/tile
       greens that already use --success (#22c55e green-500). */
    background: var(--success);
    color: #ffffff;
}

a.status-link {
    text-decoration: none;
    display: inline-block;
}
a.status-link:hover .status-badge {
    transform: translateY(-1px);
    filter: brightness(1.1);
}

.status-badge.fail {
    background: var(--status-fail);
    color: #ffffff;
}

.status-badge.skipped {
    background: #8b6e47;
    color: #ffffff;
}

.status-badge.running {
    background: linear-gradient(135deg, #d97706 0%, #f59e0b 100%);
    color: #fefce8;

}

.status-badge.in-progress {
    background: linear-gradient(135deg, #4f46e5 0%, #818cf8 100%);
    color: #e0e7ff;

    animation: pulse 2s infinite;
}

.status-badge.cancelled {
    background: #f97316;
    color: #ffffff;
}

.status-badge.no-data {
    background: #374151;
    color: #9ca3af;

}

[data-theme="light"] .status-badge.no-data {
    background: #f3f4f6;
    color: #6b7280;

}

.status-badge.pending {
    background: linear-gradient(135deg, #4f46e5 0%, #818cf8 100%);
    color: #e0e7ff;

    animation: pulse 2s infinite;
}

.status-badge.unknown {
    background: #4b5563;
    color: #e5e7eb;

}

/* Light mode: same hues as dark for instant recognizability — the
   green/red/brown palette comes from the canonical state design and
   should not change between themes. Only running/in-progress/pending
   keep their softer light-mode tints since they animate. */
[data-theme="light"] .status-badge.pass     { background: var(--status-pass); color: #ffffff; }
[data-theme="light"] .status-badge.fail     { background: var(--status-fail); color: #ffffff; }
[data-theme="light"] .status-badge.skipped  { background: #8b6e47; color: #ffffff; }
[data-theme="light"] .status-badge.running  { background: linear-gradient(135deg, #fcd34d 0%, #fde68a 100%); color: #713f12; }
[data-theme="light"] .status-badge.in-progress { background: linear-gradient(135deg, #a5b4fc 0%, #c7d2fe 100%); color: #3730a3; }
[data-theme="light"] .status-badge.cancelled { background: #f97316; color: #ffffff; }
[data-theme="light"] .status-badge.pending  { background: linear-gradient(135deg, #a5b4fc 0%, #c7d2fe 100%); color: #3730a3; }
[data-theme="light"] .status-badge.unknown  { background: #e5e7eb; color: #374151; }

/* ============================================================================
   DESIGN POLISH — class aliases so the four parallel vocabularies render
   identically. Pure CSS aliases mean we don't need to rename any class in
   200+ JS template strings.
   ============================================================================ */

/* GitHub-style status names → match our existing badges */
.status-badge.success      { background: var(--status-pass); color: #ffffff; font-weight: 600; }
.status-badge.failure,
.status-badge.timed_out,
.status-badge.startup_failure { background: var(--status-fail); color: #ffffff; font-weight: 600; }
.status-badge.queued       { background: linear-gradient(135deg, #4f46e5 0%, #818cf8 100%); color: #e0e7ff; animation: pulse 2s infinite; }
.status-badge.completed    { background: var(--status-pass); color: #ffffff; }
.status-badge.draft        { background: #4b5563; color: var(--text-secondary); }

/* Light theme aliases — keep the same green/red so the palette is
   identical to the screenshot's reference design across both themes. */
[data-theme="light"] .status-badge.success      { background: var(--status-pass); color: #ffffff; }
[data-theme="light"] .status-badge.failure,
[data-theme="light"] .status-badge.timed_out,
[data-theme="light"] .status-badge.startup_failure { background: var(--status-fail); color: #ffffff; }
[data-theme="light"] .status-badge.queued       { background: linear-gradient(135deg, #a5b4fc 0%, #c7d2fe 100%); color: #3730a3; }
[data-theme="light"] .status-badge.completed    { background: var(--status-pass); color: #ffffff; }
[data-theme="light"] .status-badge.draft        { background: #e5e7eb; color: #374151; }

/* Three parallel "state" vocabularies (health-*, cat-*, pri-tile-*) all share
   the same green/yellow/red semantics. Map them to a single canonical look so
   rows in different tabs look identical. */
.health-good, .cat-pass,
.pri-tile-good   { color: var(--status-pass); }
.health-warn, .cat-run,
.pri-tile-warn   { color: var(--status-warn); }
.health-bad,  .cat-fail,
.pri-tile-bad    { color: var(--status-fail); }
.cat-na          { color: var(--text-muted, #6b7280); }
/* Existing detail rules (border-left, background tints, etc.) live in the
   per-component sections — these aliases just guarantee the *foreground*
   color is one of three canonical tones across every tab. */

/* ============================================================================
   PROFESSIONAL POLISH — alignment, numerals, focus, hover
   These rules give the dashboard the small details that separate a polished
   product from a prototype.
   ============================================================================ */

/* Tabular numerals — a single CSS rule that makes every number in tables and
   stat cards line up at the decimal point. Modern browsers support this on
   almost every system font. */
.status-table, .pytorch-table, .ci-hud-table,
.pri-tile-value, .pri-tile-sub,
.report-card .card-value,
.summary-trend-summary,
.component-health-pct,
.component-health-meta,
.health-cell,
.cat-badge,
.gpu-health-table,
table.status-table td,
table.pytorch-table td,
.gpu-health-table td,
.pri-recent-meta {
    font-variant-numeric: tabular-nums;
    font-feature-settings: 'tnum' 1, 'cv11' 1;
}

/* Right-align numeric columns by default in our standard tables. The
   `[data-numeric]` attribute (set by JS or by future markup) opts a single
   cell into right-alignment without us having to add classes everywhere.
   Existing centered status columns are unaffected. */
td[data-numeric], th[data-numeric],
.col-numeric, .col-num, .num-cell {
    text-align: right !important;
    font-variant-numeric: tabular-nums;
    font-feature-settings: 'tnum' 1;
}
/* Common columns that ARE numeric in our tables — coerce them */
.status-table td.col-failures, .status-table td.col-passed,
.status-table td.col-total, .status-table td.col-percent,
.status-table td.col-duration, .status-table td.col-time {
    text-align: right;
    font-variant-numeric: tabular-nums;
}

/* Focus-visible: real accessibility for keyboard users. Most modern browsers
   only show focus rings when navigating by keyboard, hiding them on mouse
   click — exactly the right behavior. We add a clean ring that doesn't fight
   the existing visual language. */
:focus { outline: none; }
button:focus-visible,
a:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
[tabindex]:focus-visible,
.tab-button:focus-visible,
.tab-group-button:focus-visible,
.tab-sub-button:focus-visible,
.refresh-btn:focus-visible,
.cat-toggle-link:focus-visible {
    outline: 2px solid var(--primary, #6366f1);
    outline-offset: 2px;
    border-radius: var(--radius-md, 6px);
}

/* Keyboard-only focus for tile cover-link pattern (entire-card-clickable) —
   put the ring on the parent so it wraps the whole card visually. */
.pri-tile:has(.pri-tile-cover:focus-visible) {
    outline: 2px solid var(--primary, #6366f1);
    outline-offset: 2px;
}

/* Hover lift for clearly-clickable rows: give a 1px translateY + subtle bg
   so users know it's interactive. Non-clickable rows don't move. */
.bump-row:hover, .pri-recent-row:hover, .summary-list-item:hover,
tr.repo-ci-row:hover, .triage-cluster-row:hover {
    background: rgba(99, 102, 241, 0.04);
}
