/* ============================================================================
   BASE STYLES — Typography, Elements, Validation
   Foundation styles that apply globally before component-specific CSS.
   ============================================================================ */

/* --- Box Model --- */
*,
*::before,
*::after {
    box-sizing: border-box;
}

/* --- Document --- */
html {
    font-size: 16px;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-rendering: optimizeLegibility;
    /* Bootstrap sets `:root { scroll-behavior: smooth }`. Combined with Blazor
       enhanced navigation's scroll-to-top, that smooth scroll makes every
       left-nav click visibly "scroll/fade in" the new page — a janky bounce.
       Force instant scroll so navigation feels immediate. Theme-morph
       transitions are separate (driven by `.theme-transitioning`). */
    scroll-behavior: auto;
}

body {
    font-family: var(--font-body);
    font-size: var(--text-base);
    font-weight: 400;
    line-height: 1.6;
    color: var(--text-primary);
    background-color: var(--surface-1);
}

@supports (padding-top: env(safe-area-inset-top)) {
    body {
        padding-top: env(safe-area-inset-top);
    }
}

/* --- Typography --- */
h1, h2, h3, h4, h5, h6 {
    font-family: var(--font-display);
    font-weight: 720;
    line-height: 1.2;
    color: var(--text-primary);
    letter-spacing: 0;
}

h1, .fs-1 { font-size: var(--text-4xl); }
h2, .fs-2 { font-size: var(--text-3xl); }
h3, .fs-3 { font-size: var(--text-2xl); }
h4, .fs-4 { font-size: var(--text-xl); }
h5, .fs-5 { font-size: var(--text-lg); }
h6, .fs-6 { font-size: var(--text-base); font-weight: 500; }

h1:focus { outline: none; }

/* --- Links --- */
a, .btn-link {
    color: var(--accent-primary);
    text-decoration: none;
    transition: color var(--duration-fast) var(--ease-out);
}

a:hover, .btn-link:hover {
    color: var(--accent-primary-hover);
    text-underline-offset: 4px;
}

/* --- Stats & Numbers --- */
.stat-value, .score, .points, [data-stat] {
    font-family: var(--font-mono);
    font-variant-numeric: tabular-nums;
    letter-spacing: 0;
}

/* --- Images --- */
img {
    max-width: 100%;
    height: auto;
}

/* --- Horizontal Rules --- */
hr {
    border: none;
    border-top: 1px solid var(--border-subtle);
    margin: 2rem 0;
    height: 0;
    opacity: 1;
}

/* --- Form Inputs --- */
input[type="text"],
input[type="search"],
input[type="email"],
input[type="password"],
textarea,
select {
    background: var(--surface-2);
    border: 1px solid var(--border-default);
    color: var(--text-primary);
    border-radius: var(--radius-sm);
}

input::placeholder,
textarea::placeholder {
    color: var(--text-tertiary);
}

input:focus,
textarea:focus,
select:focus {
    border-color: var(--accent-primary);
    outline: none;
    box-shadow: var(--focus-ring, 0 0 0 3px var(--accent-primary-subtle));
}

/* --- Focus Ring --- */
:focus-visible {
    outline: none;
    box-shadow: var(--focus-ring, 0 0 0 2px var(--accent-primary-subtle));
}

/* --- Validation --- */
.valid.modified:not([type=checkbox]) {
    outline: 1px solid var(--accent-success);
}

.invalid {
    outline: 1px solid var(--accent-danger);
}

.validation-message {
    color: var(--accent-danger);
}

/* --- Blazor Error Boundary --- */
.blazor-error-boundary {
    background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;
    padding: 1rem 1rem 1rem 3.7rem;
    color: white;
}

.blazor-error-boundary::after {
    content: "An error has occurred.";
}

/* --- FontAwesome SVG/JS Sizing (morph-safe) ---
   FA 5.15.3's SVG/JS build (js/all.min.js) replaces `<i class="fas fa-x">` with
   `<svg class="svg-inline--fa fa-x fa-w-N">` and injects its own sizing CSS into a
   runtime <style> block. During Blazor enhanced-navigation DOM morphing that injected
   style can be lost or applied late, so the SVG briefly renders at its intrinsic
   (huge) dimensions — the oversized-icon flash. These ALWAYS-LOADED rules reproduce
   FA's native sizing so an FA SVG can never render oversized regardless of morph
   timing, which lets us keep DOM preservation (morphing) enabled.

   Native FA 5.15.3 defaults (from svg-with-js.css):
     .svg-inline--fa { display:inline-block; font-size:inherit; height:1em;
                       vertical-align:-.125em; overflow:visible }
   Width is set per-icon via .fa-w-N (e.g. .fa-w-16 = 1em, .fa-w-20 = 1.25em), so we
   leave width:auto to preserve each glyph's aspect ratio and only cap max-width as a
   backstop for the mid-morph case where the .fa-w-N class itself hasn't applied yet.
   No !important so FA's own per-icon width classes still win. */
.svg-inline--fa {
    display: inline-block;
    height: 1em;
    width: auto;
    max-width: 1.5em;
    vertical-align: -0.125em;
    overflow: visible;
}

/* Defensive cap on the pre-replacement <i> webfont icons so a fallback (FA JS not yet
   loaded, or webfont path) can't inflate either. Matches FA's 1em baseline. */
i.fa, i.fas, i.far, i.fal, i.fab, i.fad {
    font-size: 1em;
    line-height: 1;
}

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