/* ---------------------------------------------------------------------------
   Design tokens — IRO house style.

   The palette and typography follow iro-dogs.org so this results site reads as
   part of the same organisation: navy carries every structural surface and all
   headings, slate blue carries running text, sand gold is the only decorative
   accent (rules, eyebrows, highlights) and red is reserved for what is live or
   urgent. Nothing else is allowed to be a brand colour — medal metals and the
   score-grading greens are functional, not decorative.

   The original site sets its headings in Campton and its lead lines in Arvo.
   Campton is licensed, so the sans is Figtree (same geometric-humanist build,
   same double-storey a); Arvo is free and is used exactly as they use it, for
   eyebrows and stat labels.
   --------------------------------------------------------------------------- */
:root {
    /* Brand constants — identical in both themes, never overridden. */
    --iro-navy: #092552;
    --iro-navy-deep: #061a3c;
    --iro-navy-light: #1d4e8f;
    --iro-slate: #29536e;
    --iro-slate-muted: #81a0b4;
    --iro-sand: #b5a272;
    --iro-sand-light: #cbbb94;
    --iro-red: #e5343a;
    --iro-mist: #e6e9ed;

    --font-sans: 'Figtree', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    --font-accent: 'Arvo', Georgia, 'Times New Roman', serif;

    --primary-color: var(--iro-navy);
    --primary-hover: var(--iro-navy-light);
    --accent-color: var(--iro-sand);
    --secondary-color: var(--iro-slate);
    --success-color: #1f7a5c;
    --warning-color: #c08a2e;
    --error-color: var(--iro-red);

    --bg-primary: #ffffff;
    --bg-secondary: #f3f5f8;
    --bg-card: #ffffff;
    --bg-hover: var(--iro-mist);

    --text-primary: var(--iro-navy);
    --text-secondary: var(--iro-slate);
    --text-muted: var(--iro-slate-muted);

    --border-color: var(--iro-mist);
    /* Table heads are navy by day; at night the page is already navy, so they
       lift instead of deepen. */
    --table-head: var(--iro-navy);
    --table-head-hover: var(--iro-navy-light);
    --hero-from: var(--iro-navy);
    --hero-to: var(--iro-navy-deep);
    /* Shadows are navy-tinted rather than black: on a white page a neutral grey
       shadow under a navy card reads as dirt. */
    --shadow-sm: 0 1px 2px 0 rgb(9 37 82 / 0.06);
    --shadow-md: 0 4px 10px -2px rgb(9 37 82 / 0.10), 0 2px 4px -2px rgb(9 37 82 / 0.06);
    --shadow-lg: 0 14px 28px -8px rgb(9 37 82 / 0.18), 0 4px 10px -6px rgb(9 37 82 / 0.10);

    /* IRO buttons are 12px; the scale is built around that. */
    --radius-sm: 0.5rem;
    --radius-md: 0.75rem;
    --radius-lg: 1rem;
    --radius-xl: 1.25rem;
}

/* Dark Theme */
[data-theme="dark"] {
    /* Night is the same navy taken down, not a neutral grey: the brand colour
       becomes the page and gold does the work blue does by day. */
    --primary-color: #4d8bd0;
    --primary-hover: #6ba3e0;

    --bg-primary: #04122a;
    --bg-secondary: #0a2148;
    --bg-card: #0a2148;
    --bg-hover: #123063;

    --text-primary: #eef3f8;
    --text-secondary: #b3c7da;
    --text-muted: #7d9ab1;

    --border-color: #163667;
    --table-head: #0f2f5f;
    --table-head-hover: #1a4585;
    /* At night the page is already navy, so the hero has to be lighter than
       its background rather than darker, or it stops being a card. */
    --hero-from: #16386c;
    --hero-to: #0c2550;
    --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.35);
    --shadow-md: 0 4px 10px -2px rgb(0 0 0 / 0.45), 0 2px 4px -2px rgb(0 0 0 / 0.35);
    --shadow-lg: 0 14px 28px -8px rgb(0 0 0 / 0.55), 0 4px 10px -6px rgb(0 0 0 / 0.4);
}


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

body {
    font-family: var(--font-sans);
    background-color: var(--bg-primary);
    color: var(--text-primary);
    line-height: 1.6;
    transition: background-color 0.3s ease, color 0.3s ease;
}

.app-container {
    min-height: 100vh;
    display: flex;
    flex-direction: column;
}

/* Header Styles */
.header {
    background: var(--bg-card);
    border-bottom: 1px solid var(--border-color);
    box-shadow: var(--shadow-sm);
    position: sticky;
    top: 0;
    z-index: 100;
}

.header-content {
    max-width: 1200px;
    margin: 0 auto;
    padding: 1rem 1.5rem;
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.brand {
    display: flex;
    align-items: center;
    gap: 0.75rem;
}

.brand i {
    color: var(--primary-color);
    font-size: 1.5rem;
}

.brand h1 {
    font-size: 1.5rem;
    font-weight: 700;
    color: var(--text-primary);
}

.header-controls {
    display: flex;
    gap: 0.5rem;
}

.theme-toggle,
.refresh-btn {
    background: var(--bg-secondary);
    border: 1px solid var(--border-color);
    color: var(--text-secondary);
    padding: 0.5rem;
    border-radius: var(--radius-md);
    cursor: pointer;
    transition: all 0.2s ease;
    width: 40px;
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
}

.theme-toggle:hover,
.refresh-btn:hover {
    background: var(--bg-hover);
    color: var(--text-primary);
}

/* Main Content */
.main-content {
    flex: 1;
    max-width: 1200px;
    margin: 0 auto;
    padding: 2rem 1.5rem;
    width: 100%;
}

/* Hero Section */
.hero-section {
    margin-bottom: 3rem;
}

.hero-card {
    background: var(--bg-card);
    border-radius: var(--radius-xl);
    padding: 2rem;
    box-shadow: var(--shadow-md);
    border: 1px solid var(--border-color);
}

.competition-info h2 {
    font-size: 2rem;
    font-weight: 700;
    margin-bottom: 1rem;
    color: var(--text-primary);
}

.meta-info {
    display: flex;
    align-items: center;
    gap: 1rem;
    margin-bottom: 2rem;
    flex-wrap: wrap;
}

.badge {
    background: var(--primary-color);
    color: white;
    padding: 0.25rem 0.75rem;
    border-radius: var(--radius-md);
    font-size: 0.875rem;
    font-weight: 500;
}

.update-time {
    color: var(--text-secondary);
    font-size: 0.875rem;
}

.stats-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: 1.5rem;
    margin-top: 1.5rem;
}

.stat-card {
    text-align: center;
    padding: 1rem;
    background: var(--bg-secondary);
    border-radius: var(--radius-lg);
    border: 1px solid var(--border-color);
}

.stat-number {
    font-size: 2rem;
    font-weight: 700;
    color: var(--primary-color);
    margin-bottom: 0.5rem;
}

.stat-label {
    color: var(--text-secondary);
    font-size: 0.875rem;
    font-weight: 500;
}

/* Navigation Section */
.navigation-section {
    margin-bottom: 3rem;
}

.nav-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
    gap: 1.5rem;
}

.nav-card {
    background: var(--bg-card);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-xl);
    padding: 1.5rem;
    text-decoration: none;
    color: inherit;
    display: flex;
    align-items: center;
    gap: 1rem;
    transition: all 0.2s ease;
    box-shadow: var(--shadow-sm);
}

.nav-card:hover {
    transform: translateY(-2px);
    box-shadow: var(--shadow-lg);
    border-color: var(--primary-color);
}

.nav-icon {
    width: 60px;
    height: 60px;
    border-radius: var(--radius-lg);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.5rem;
    flex-shrink: 0;
}

.tracking-card .nav-icon {
    background: linear-gradient(135deg, #059669, #10b981);
    color: white;
}

.field-card .nav-icon {
    background: linear-gradient(135deg, #2563eb, #3b82f6);
    color: white;
}

.track-card .nav-icon {
    background: linear-gradient(135deg, #d97706, #f59e0b);
    color: white;
}

.countries-card .nav-icon {
    background: linear-gradient(135deg, #059669, #10b981);
    color: white;
}

.external-card .nav-icon {
    background: linear-gradient(135deg, #7c3aed, #8b5cf6);
    color: white;
}

.teams-card .nav-icon {
    background: linear-gradient(135deg, #1d4ed8, #3b82f6);
    color: white;
}

.nav-content {
    flex: 1;
}

.nav-content h3 {
    font-size: 1.125rem;
    font-weight: 600;
    margin-bottom: 0.5rem;
    color: var(--text-primary);
}

.nav-content p {
    color: var(--text-secondary);
    font-size: 0.875rem;
    margin-bottom: 0.75rem;
}

.nav-stats {
    display: flex;
    gap: 1rem;
}

.participants {
    background: var(--bg-secondary);
    color: var(--text-secondary);
    padding: 0.25rem 0.5rem;
    border-radius: var(--radius-sm);
    font-size: 0.75rem;
    font-weight: 500;
}

.nav-arrow {
    color: var(--text-muted);
    transition: transform 0.2s ease;
}

.nav-card:hover .nav-arrow {
    transform: translateX(4px);
    color: var(--primary-color);
}

/* Preview Section */
/* The standings block had no rule of its own, only ones for its h3, so it was
   the one section on this page with no bottom margin — .hero-section and
   .navigation-section both carry 3rem — and the navigation cards sat flush
   against it. */
.preview-section {
    margin-bottom: 3rem;
}

.preview-section h3 {
    font-size: 1.25rem;
    font-weight: 600;
    margin-bottom: 1.5rem;
    color: var(--text-primary);
}

.preview-tabs {
    display: flex;
    gap: 0.5rem;
    margin-bottom: 1.5rem;
    border-bottom: 1px solid var(--border-color);
}

.tab-btn {
    background: none;
    border: none;
    padding: 0.75rem 1rem;
    cursor: pointer;
    color: var(--text-secondary);
    font-weight: 500;
    border-bottom: 2px solid transparent;
    transition: all 0.2s ease;
}

.tab-btn.active {
    color: var(--primary-color);
    border-bottom-color: var(--primary-color);
}

.tab-btn:hover {
    color: var(--text-primary);
}

.preview-content {
    background: var(--bg-card);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-lg);
    padding: 1.5rem;
    min-height: 200px;
}

.loading-placeholder {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 1rem;
    color: var(--text-muted);
    height: 150px;
}

/* Footer */
.footer {
    background: var(--bg-card);
    border-top: 1px solid var(--border-color);
    margin-top: auto;
}

.footer-content {
    max-width: 1200px;
    margin: 0 auto;
    padding: 1.5rem;
    display: flex;
    justify-content: space-between;
    align-items: center;
    flex-wrap: wrap;
    gap: 1rem;
}

.footer-content p {
    color: var(--text-secondary);
    font-size: 0.875rem;
}

.footer-links {
    display: flex;
    gap: 1rem;
}

.footer-links a {
    color: var(--text-secondary);
    text-decoration: none;
    font-size: 0.875rem;
    transition: color 0.2s ease;
}

.footer-links a:hover {
    color: var(--primary-color);
}

/* Loading Overlay */
.loading-overlay {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: rgba(0, 0, 0, 0.5);
    display: none;
    align-items: center;
    justify-content: center;
    z-index: 1000;
}

.loading-spinner {
    background: var(--bg-card);
    padding: 2rem;
    border-radius: var(--radius-lg);
    text-align: center;
    box-shadow: var(--shadow-lg);
}

.loading-spinner i {
    font-size: 2rem;
    color: var(--primary-color);
    margin-bottom: 1rem;
}

/* Animations */
@keyframes fadeIn {
    from { opacity: 0; transform: translateY(20px); }
    to { opacity: 1; transform: translateY(0); }
}

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

.ti-spin {
    animation: ti-spin 1s linear infinite;
    display: inline-block;
}

.hero-card,
.nav-card,
.preview-content {
    animation: fadeIn 0.6s ease-out;
}

/* Responsive Design */
@media (max-width: 768px) {
    .main-content {
        padding: 1rem;
    }

    .hero-card {
        padding: 1.5rem;
    }

    .competition-info h2 {
        font-size: 1.5rem;
    }

    .meta-info {
        flex-direction: column;
        align-items: flex-start;
        gap: 0.5rem;
    }

    .stats-grid {
        grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
        gap: 1rem;
    }

    .nav-grid {
        grid-template-columns: 1fr;
    }

    .nav-card {
        padding: 1rem;
    }

    .nav-icon {
        width: 50px;
        height: 50px;
        font-size: 1.25rem;
    }

    .footer-content {
        flex-direction: column;
        text-align: center;
        gap: 0.5rem;
    }

    .preview-tabs {
        flex-wrap: wrap;
    }
}

@media (max-width: 480px) {
    .header-content {
        padding: 0.75rem 1rem;
    }

    .brand h1 {
        font-size: 1.25rem;
    }

    .stats-grid {
        grid-template-columns: 1fr 1fr;
    }
}
/* ============================================================
   Landing page — energy pass
   ------------------------------------------------------------
   Everything here styles what the homepage already renders; no
   colour is literal, so both themes follow automatically.
   ============================================================ */

/* --- category colour, finally read -------------------------------------
   updateCategoryCards() has always set --category-color from the colour
   picked in the admin panel, and nothing consumed it, so every category
   tile rendered the same grey. The fallback keeps a category saved
   without a colour looking deliberate rather than broken. */
.category-card {
    --category-color: var(--primary-color);
    position: relative;
    overflow: hidden;
}

.category-card::before {
    content: '';
    position: absolute;
    inset: 0 0 auto 0;
    height: 4px;
    background: var(--category-color);
    opacity: 0.9;
}

.category-card .nav-icon {
    background-color: var(--category-color);
    /* A flat fill over any hue reads as a sticker; the overlay gives the
       tile depth without needing a second colour per category. */
    background-image: linear-gradient(135deg, rgb(255 255 255 / 0.3), rgb(0 0 0 / 0.15));
    color: #fff;
}

.category-card:hover {
    border-color: var(--category-color);
    transform: translateY(-4px);
}

.category-card:hover .nav-icon {
    transform: scale(1.06) rotate(-3deg);
}

.nav-icon {
    transition: transform 0.2s ease;
}

/* --- hero --------------------------------------------------------------- */
.hero-card {
    position: relative;
    overflow: hidden;
}

/* A tint of the brand colour, so the first block on the page is not the
   same flat white as everything below it. */
.hero-card::after {
    content: '';
    position: absolute;
    top: -60%;
    right: -10%;
    width: 45%;
    aspect-ratio: 1;
    border-radius: 50%;
    background: var(--primary-color);
    opacity: 0.07;
    pointer-events: none;
}

.competition-info h2 {
    font-size: clamp(2rem, 5vw, 3rem);
    line-height: 1.1;
    letter-spacing: -0.02em;
}

/* --- live badge --------------------------------------------------------- */
.live-badge {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    background: var(--error-color);
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
}

.live-dot {
    width: 0.5rem;
    height: 0.5rem;
    border-radius: 50%;
    background: currentColor;
    box-shadow: 0 0 0 0 currentColor;
    animation: live-pulse 2s ease-out infinite;
}

@keyframes live-pulse {
    0%   { box-shadow: 0 0 0 0 rgb(255 255 255 / 0.7); }
    70%  { box-shadow: 0 0 0 0.5rem rgb(255 255 255 / 0); }
    100% { box-shadow: 0 0 0 0 rgb(255 255 255 / 0); }
}

/* Flashed by app.js when a refresh actually brings new data. */
.live-badge.refreshed {
    animation: live-flash 0.6s ease;
}

@keyframes live-flash {
    0%, 100% { transform: scale(1); }
    40%      { transform: scale(1.12); }
}

/* --- stats -------------------------------------------------------------- */
.stat-card {
    position: relative;
    overflow: hidden;
    transition: transform 0.2s ease, box-shadow 0.2s ease;
}

.stat-card:hover {
    transform: translateY(-3px);
    box-shadow: var(--shadow-md);
}

.stat-number {
    font-size: clamp(2.25rem, 6vw, 3rem);
    line-height: 1;
    letter-spacing: -0.03em;
    /* Digits must not jump width while animateNumber() counts up. */
    font-variant-numeric: tabular-nums;
    min-height: 1em;
}

.stat-label {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.4rem;
}

.stat-label i {
    color: var(--primary-color);
}

/* --- standings ---------------------------------------------------------- */
.preview-section h3 {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.preview-section h3 i {
    color: var(--primary-color);
}

.podium-mount:not(:empty) {
    margin-bottom: 1.5rem;
}

/* --- motion ------------------------------------------------------------- */
/* Nothing here honoured this before, while the stylesheets animate podium
   rises, floating medals and shimmer skeletons. */
@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: 0.001ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.001ms !important;
        scroll-behavior: auto !important;
    }
}

/* Admin-authored status chip, shown only when the text exists. */
.status-badge {
    background: var(--bg-hover);
    color: var(--text-secondary);
    border: 1px solid var(--border-color);
}

/* Three stats, three columns, at every width. `auto-fit` with a 150px minimum
   drops to two columns on a phone and leaves the third card orphaned on a row
   of its own; the numbers are short enough to share the width. */
@media (max-width: 640px) {
    .stats-grid {
        grid-template-columns: repeat(3, 1fr);
        gap: 0.6rem;
    }

    .stat-card {
        padding: 0.75rem 0.4rem;
    }

    .stat-label {
        font-size: 0.7rem;
        line-height: 1.25;
    }

    /* The icon costs width the label needs when it wraps. */
    .stat-label i {
        display: none;
    }
}

/* ===========================================================================
   IRO house style

   Everything above is the generic results-site chrome; this block is what
   makes it look like IRO. It is deliberately kept together and last so the
   house style can be read — or lifted out — in one piece.

   Four moves, taken from iro-dogs.org:
     1. navy is a surface, not just a text colour (hero, table head, footer);
     2. one 120px sand rule under a heading, never more decoration than that;
     3. the slab serif appears only as an eyebrow or a stat label;
     4. red is reserved for live.
   =========================================================================== */

/* --- typography --------------------------------------------------------- */
h1, h2, h3, h4, h5 {
    font-weight: 700;
    letter-spacing: -0.015em;
}

/* The eyebrow/lead line — the one place the slab serif is allowed. Used for
   stat labels and section leads, exactly as the parent site uses Arvo. */
.eyebrow,
.hero-card .stat-label {
    font-family: var(--font-accent);
    font-weight: 400;
    letter-spacing: 0;
}

/* The sand rule. Applied through ::after so it survives inside the flex
   headings, which would otherwise lay it out as a sibling column. */
.competition-info h2,
.preview-section h3,
.results-info h2 {
    position: relative;
    padding-bottom: 0.95rem;
}

.competition-info h2::after,
.preview-section h3::after,
.results-info h2::after {
    content: '';
    position: absolute;
    left: 0;
    bottom: 0;
    width: 120px;
    max-width: 60%;
    height: 2px;
    background: var(--accent-color);
}

/* --- header ------------------------------------------------------------- */
/* A hairline of the brand across the top of every page — the cheapest way to
   say "same organisation" on a site that cannot carry the IRO logo. */
.header::before {
    content: '';
    display: block;
    height: 3px;
    background: linear-gradient(90deg, var(--iro-navy), var(--iro-sand));
}

.brand i {
    color: var(--accent-color);
}

.brand h1 {
    letter-spacing: -0.02em;
}

/* --- hero --------------------------------------------------------------- */
/* The single focal point of the landing page: a navy block, the way the
   parent site opens every page with one. */
.hero-card {
    background: linear-gradient(140deg, var(--hero-from) 0%, var(--hero-to) 75%);
    border-color: transparent;
    color: #fff;
    box-shadow: var(--shadow-lg);
}

.hero-card .competition-info h2 {
    color: #fff;
}

/* The decorative circle was a tint of the primary colour, which is now the
   card itself — sand instead, or it disappears. Kept faint: at full strength
   it muddies whatever stat card it passes behind. */
.hero-card::after {
    background: var(--iro-sand);
    opacity: 0.1;
}

.hero-card .update-time {
    color: rgb(255 255 255 / 0.72);
}

/* Everything the hero holds was styled for a white card: the teams page puts a
   subtitle, the pass-mark rule and its category chips in there. */
.hero-card .badge {
    background: rgb(255 255 255 / 0.14);
    color: #fff;
}

/* Live keeps its red — it is the one thing on the page that is not decoration. */
.hero-card .live-badge {
    background: var(--error-color);
}

.hero-card .page-subtitle,
.hero-card .rule-note {
    color: rgb(255 255 255 / 0.8);
}

.hero-card .pass-mark {
    background: rgb(255 255 255 / 0.06);
    border-color: rgb(255 255 255 / 0.16);
    color: rgb(255 255 255 / 0.8);
}

.hero-card .pass-mark-category {
    color: #fff;
}

.hero-card .stat-card {
    background: rgb(255 255 255 / 0.06);
    border-color: rgb(255 255 255 / 0.16);
}

.hero-card .stat-card:hover {
    background: rgb(255 255 255 / 0.1);
}

.hero-card .stat-number {
    color: #fff;
}

.hero-card .stat-label {
    color: var(--iro-sand-light);
}

.hero-card .stat-label i {
    color: var(--iro-sand);
}

/* --- navigation cards --------------------------------------------------- */
/* The fixed cards used one hue each out of a generic palette — purple, green,
   blue — which fought the category colours next to them. They are brand tones
   now; the category tiles keep the colour the admin chose, because there it
   carries meaning. */
.countries-card .nav-icon {
    background: linear-gradient(135deg, var(--iro-slate), #3d7699);
    color: #fff;
}

.teams-card .nav-icon {
    background: linear-gradient(135deg, var(--iro-navy), var(--iro-navy-light));
    color: #fff;
}

.external-card .nav-icon {
    background: linear-gradient(135deg, var(--iro-sand), var(--iro-sand-light));
    color: var(--iro-navy);
}

.tab-btn:hover {
    color: var(--accent-color);
}

/* --- buttons ------------------------------------------------------------ */
/* IRO draws every button as a 2px border on a 12px radius — filled for the
   primary action, outlined for the rest. --radius-md is that 12px. */
.export-btn,
.filter-btn {
    border-width: 2px;
}

.export-btn:hover,
.filter-btn:hover,
.filter-btn.active {
    border-color: var(--primary-color);
}

/* --- tables ------------------------------------------------------------- */
/* A navy header row, which is also what stops the sortable headers from
   reading as body text. */
.results-table thead th {
    background: var(--table-head);
    color: #fff;
    border-bottom: none;
}

.results-table th i {
    color: var(--iro-sand-light);
}

.results-table th:hover {
    background: var(--table-head-hover);
}

/* --- footer ------------------------------------------------------------- */
.footer {
    background: var(--iro-navy);
    border-top: none;
    color: #fff;
}

.footer-content {
    padding: 2rem 1.5rem;
}

.footer-content p {
    color: rgb(255 255 255 / 0.7);
}

.footer-links a {
    color: var(--iro-sand-light);
}

.footer-links a:hover {
    color: #fff;
}

/* --- overlays ----------------------------------------------------------- */
.loading-overlay {
    background: rgb(6 26 60 / 0.55);
}
