/* Neon terminal design system.
   Tokens are dark-first; [data-theme="light"] swaps in a "paper terminal" variant with the
   same accents darkened for contrast. Components are prefixed nx- so they can't collide with
   Bootstrap or the MudBlazor classes still in use on pages that haven't been migrated yet. */

:root,
[data-theme="dark"] {
    --nx-bg: #05070d;
    --nx-bg-elevated: #0b1020;
    --nx-surface: rgba(14, 20, 36, 0.72);
    --nx-surface-solid: #0e1424;
    --nx-surface-hover: rgba(20, 28, 50, 0.85);
    --nx-border: rgba(120, 160, 255, 0.14);
    --nx-border-strong: rgba(120, 160, 255, 0.28);

    --nx-text: #e6edf7;
    --nx-text-dim: #9aa8bf;
    --nx-text-faint: #64718a;

    --nx-cyan: #22d3ee;
    --nx-green: #4ade80;
    --nx-lime: #a3e635;
    --nx-amber: #fbbf24;
    --nx-red: #f87171;

    --nx-accent: var(--nx-cyan);
    --nx-accent-2: var(--nx-green);
    --nx-on-accent: #031016;

    --nx-glow: 0 0 0 1px rgba(34, 211, 238, 0.45), 0 0 24px rgba(34, 211, 238, 0.25), 0 0 64px rgba(74, 222, 128, 0.12);
    --nx-glow-soft: 0 0 18px rgba(34, 211, 238, 0.18);
    --nx-shadow: 0 10px 30px rgba(0, 0, 0, 0.45);

    --nx-grid-line: rgba(34, 211, 238, 0.055);
    --nx-orb-1: rgba(34, 211, 238, 0.16);
    --nx-orb-2: rgba(74, 222, 128, 0.14);
    --nx-orb-3: rgba(59, 130, 246, 0.12);

    --nx-font-sans: 'Space Grotesk', 'Segoe UI', system-ui, sans-serif;
    --nx-font-mono: 'JetBrains Mono', 'Cascadia Code', Consolas, monospace;

    --nx-radius: 14px;
    --nx-radius-sm: 8px;
    --nx-header-h: 64px;
    --nx-ease: cubic-bezier(0.2, 0.8, 0.2, 1);

    color-scheme: dark;
}

[data-theme="light"] {
    --nx-bg: #f4f6fb;
    --nx-bg-elevated: #ffffff;
    --nx-surface: rgba(255, 255, 255, 0.78);
    --nx-surface-solid: #ffffff;
    --nx-surface-hover: rgba(255, 255, 255, 0.95);
    --nx-border: rgba(30, 50, 90, 0.12);
    --nx-border-strong: rgba(30, 50, 90, 0.24);

    --nx-text: #0d1424;
    --nx-text-dim: #4a5770;
    --nx-text-faint: #7a869c;

    --nx-cyan: #0891b2;
    --nx-green: #16a34a;
    --nx-lime: #4d7c0f;
    --nx-amber: #b45309;
    --nx-red: #dc2626;
    --nx-on-accent: #ffffff;

    --nx-glow: 0 0 0 1px rgba(8, 145, 178, 0.45), 0 8px 28px rgba(8, 145, 178, 0.18), 0 0 48px rgba(22, 163, 74, 0.08);
    --nx-glow-soft: 0 6px 18px rgba(8, 145, 178, 0.14);
    --nx-shadow: 0 10px 30px rgba(20, 30, 60, 0.10);

    --nx-grid-line: rgba(8, 145, 178, 0.07);
    --nx-orb-1: rgba(8, 145, 178, 0.10);
    --nx-orb-2: rgba(22, 163, 74, 0.08);
    --nx-orb-3: rgba(37, 99, 235, 0.07);

    color-scheme: light;
}

/* ---------- Base ---------- */

/* theme.js puts .mud-theme-dark on <html> and <body>, and MudBlazor paints that class with its
   "dark" intent color (!important) - outrank it until MudBlazor is gone. */
:root:root,
:root body {
    background-color: var(--nx-bg) !important;
}

html body {
    color: var(--nx-text);
    font-family: var(--nx-font-sans);
    -webkit-font-smoothing: antialiased;
}

::selection {
    background: color-mix(in srgb, var(--nx-accent) 35%, transparent);
    color: var(--nx-text);
}

/* Fixed backdrop: a faint grid plus slow-drifting color orbs. Sits behind everything. */
.nx-backdrop {
    position: fixed;
    inset: 0;
    z-index: -1;
    pointer-events: none;
    overflow: hidden;
    background:
        linear-gradient(var(--nx-grid-line) 1px, transparent 1px) 0 0 / 48px 48px,
        linear-gradient(90deg, var(--nx-grid-line) 1px, transparent 1px) 0 0 / 48px 48px,
        var(--nx-bg);
    mask-image: radial-gradient(ellipse at 50% 0%, #000 40%, transparent 100%);
}

.nx-backdrop::before,
.nx-backdrop::after,
.nx-backdrop > span {
    content: '';
    position: absolute;
    border-radius: 50%;
    filter: blur(80px);
}

.nx-backdrop::before {
    width: 620px; height: 620px;
    top: -180px; left: -120px;
    background: var(--nx-orb-1);
}

.nx-backdrop::after {
    width: 560px; height: 560px;
    top: 10%; right: -160px;
    background: var(--nx-orb-2);
}

.nx-backdrop > span {
    width: 480px; height: 480px;
    bottom: -200px; left: 35%;
    background: var(--nx-orb-3);
}

@media (prefers-reduced-motion: no-preference) {
    .nx-backdrop::before { animation: nx-drift 26s ease-in-out infinite alternate; }
    .nx-backdrop::after { animation: nx-drift 32s ease-in-out infinite alternate-reverse; }
    .nx-backdrop > span { animation: nx-drift 38s ease-in-out infinite alternate; }
}

@keyframes nx-drift {
    from { transform: translate(0, 0) scale(1); }
    to { transform: translate(80px, 60px) scale(1.15); }
}

.nx-main {
    max-width: 1320px;
    margin: 0 auto;
    padding: 24px 24px 64px;
}

.nx-main.nx-main--auto {
    min-height: 0;
}

@media (max-width: 600px) {
    .nx-main { padding: 16px 16px 48px; }
}

.nx-mono { font-family: var(--nx-font-mono); }

/* The gradient repeats (cyan..lime..cyan) so sliding it by one full image width loops seamlessly. */
.nx-gradient-text {
    background: linear-gradient(92deg, var(--nx-cyan), var(--nx-green) 25%, var(--nx-lime) 50%, var(--nx-green) 75%, var(--nx-cyan));
    background-size: 200% auto;
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
}

@media (prefers-reduced-motion: no-preference) {
    .nx-gradient-text { animation: nx-shimmer 8s linear infinite; }
}

@keyframes nx-shimmer {
    from { background-position: 0% 50%; }
    to { background-position: 200% 50%; }
}

/* Soft light that trails the mouse across the page (positions set by js/neonFx.js). */
.nx-cursor-glow {
    position: fixed;
    inset: 0;
    z-index: -1;
    pointer-events: none;
    background: radial-gradient(520px circle at var(--nx-cx, -999px) var(--nx-cy, -999px),
        color-mix(in srgb, var(--nx-accent) 9%, transparent), transparent 45%);
}

@media (pointer: coarse) {
    .nx-cursor-glow { display: none; }
}

/* Glitch: two tinted copies of the text (from data-text) slice and jitter for a moment every few
   seconds, and continuously while hovered. */
.nx-glitch {
    position: relative;
    display: inline-block;
}

.nx-glitch::before,
.nx-glitch::after {
    content: attr(data-text);
    position: absolute;
    inset: 0;
    pointer-events: none;
    opacity: 0;
}

.nx-glitch::before { color: var(--nx-cyan); }
.nx-glitch::after { color: var(--nx-green); }

@media (prefers-reduced-motion: no-preference) {
    .nx-glitch::before { animation: nx-glitch-a 5s steps(1, end) infinite; }
    .nx-glitch::after { animation: nx-glitch-b 5s steps(1, end) infinite; }
    .nx-glitch:hover::before { animation-duration: 0.6s; }
    .nx-glitch:hover::after { animation-duration: 0.6s; }
}

@keyframes nx-glitch-a {
    0%, 86%, 100% { opacity: 0; transform: none; clip-path: inset(0 0 0 0); }
    88% { opacity: 0.9; transform: translate(-4px, 1px); clip-path: inset(10% 0 60% 0); }
    90% { opacity: 0.9; transform: translate(3px, -2px); clip-path: inset(55% 0 20% 0); }
    92% { opacity: 0.9; transform: translate(-2px, 0); clip-path: inset(30% 0 45% 0); }
    94% { opacity: 0.9; transform: translate(5px, 2px); clip-path: inset(75% 0 5% 0); }
}

@keyframes nx-glitch-b {
    0%, 87%, 100% { opacity: 0; transform: none; clip-path: inset(0 0 0 0); }
    89% { opacity: 0.85; transform: translate(4px, -1px); clip-path: inset(65% 0 10% 0); }
    91% { opacity: 0.85; transform: translate(-3px, 2px); clip-path: inset(15% 0 70% 0); }
    93% { opacity: 0.85; transform: translate(2px, 0); clip-path: inset(40% 0 35% 0); }
    95% { opacity: 0.85; transform: translate(-5px, -2px); clip-path: inset(5% 0 80% 0); }
}

/* ---------- Header ---------- */

.nx-header {
    position: sticky;
    top: 0;
    z-index: 1200;
    height: var(--nx-header-h);
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 0 20px;
    background: color-mix(in srgb, var(--nx-bg) 70%, transparent);
    backdrop-filter: blur(14px) saturate(140%);
    -webkit-backdrop-filter: blur(14px) saturate(140%);
    border-bottom: 1px solid var(--nx-border);
}

.nx-header::after {
    content: '';
    position: absolute;
    left: 0; right: 0; bottom: -1px;
    height: 1px;
    background: linear-gradient(90deg, transparent, var(--nx-cyan), var(--nx-green), transparent);
    background-size: 50% 100%;
    background-repeat: no-repeat;
    opacity: 0.7;
}

/* A pulse of light that sweeps along the header's bottom edge. */
@media (prefers-reduced-motion: no-preference) {
    .nx-header::after { animation: nx-sweep 7s ease-in-out infinite; }
}

@keyframes nx-sweep {
    from { background-position: -100% 0; }
    to { background-position: 200% 0; }
}

.nx-header-nav {
    display: flex;
    align-items: center;
    gap: 2px;
    margin-left: 12px;
}

.nx-header-nav a {
    position: relative;
    padding: 8px 12px;
    border-radius: var(--nx-radius-sm);
    color: var(--nx-text-dim);
    text-decoration: none;
    font-family: var(--nx-font-mono);
    font-size: 0.85rem;
    letter-spacing: 0.02em;
    transition: color 0.2s, background 0.2s;
}

.nx-header-nav a:hover {
    color: var(--nx-text);
    background: color-mix(in srgb, var(--nx-accent) 8%, transparent);
}

.nx-header-nav a.active {
    color: var(--nx-accent);
}

.nx-header-nav a.active::after {
    content: '';
    position: absolute;
    left: 12px; right: 12px; bottom: 2px;
    height: 2px;
    border-radius: 2px;
    background: var(--nx-accent);
    box-shadow: 0 0 10px var(--nx-accent);
}

.nx-header-spacer { flex: 1; }

.nx-header-actions {
    display: flex;
    align-items: center;
    gap: 6px;
}

.nx-hello {
    font-family: var(--nx-font-mono);
    font-size: 0.8rem;
    color: var(--nx-text-faint);
    margin-right: 6px;
}

/* Between the full desktop width and the point where the nav collapses into the drawer, tighten
   the links and drop the greeting so seven sections plus "hire me" and the account buttons fit. */
@media (max-width: 1200px) {
    .nx-header-nav { margin-left: 4px; }
    .nx-header-nav a { padding: 8px 8px; }
    .nx-header-nav a.active::after { left: 8px; right: 8px; }
    .nx-hello { display: none; }

    /* Admin shortcuts; also on the profile page and in the drawer. */
    .nx-hide-md { display: none !important; }
}

@media (max-width: 960px) {
    .nx-header-nav, .nx-hello { display: none; }
}

@media (max-width: 600px) {
    .nx-header { padding: 0 12px; gap: 6px; }
    .nx-hide-xs { display: none !important; }
}

/* ---------- Drawer ---------- */

.nx-scrim {
    position: fixed;
    inset: 0;
    z-index: 1300;
    background: rgba(2, 4, 10, 0.55);
    backdrop-filter: blur(3px);
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.25s var(--nx-ease);
}

.nx-drawer {
    position: fixed;
    top: 0; bottom: 0; left: 0;
    z-index: 1301;
    width: min(320px, 88vw);
    display: flex;
    flex-direction: column;
    background: color-mix(in srgb, var(--nx-bg-elevated) 92%, transparent);
    backdrop-filter: blur(18px);
    border-right: 1px solid var(--nx-border-strong);
    box-shadow: 20px 0 60px rgba(0, 0, 0, 0.35);
    transform: translateX(-102%);
    transition: transform 0.3s var(--nx-ease);
    visibility: hidden;
}

.nx-drawer-open .nx-scrim { opacity: 1; pointer-events: auto; }
.nx-drawer-open .nx-drawer { transform: none; visibility: visible; }

.nx-drawer-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    height: var(--nx-header-h);
    padding: 0 12px 0 20px;
    border-bottom: 1px solid var(--nx-border);
    font-family: var(--nx-font-mono);
    color: var(--nx-text-faint);
    font-size: 0.8rem;
    letter-spacing: 0.12em;
    text-transform: uppercase;
}

.nx-drawer-body {
    flex: 1;
    overflow-y: auto;
    padding: 12px 10px 24px;
}

.nx-nav-link,
.nx-nav-group > summary {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 9px 12px;
    border-radius: var(--nx-radius-sm);
    color: var(--nx-text-dim);
    text-decoration: none;
    font-size: 0.93rem;
    cursor: pointer;
    transition: background 0.15s, color 0.15s;
    user-select: none;
}

.nx-nav-link:hover,
.nx-nav-group > summary:hover {
    color: var(--nx-text);
    background: color-mix(in srgb, var(--nx-accent) 8%, transparent);
}

.nx-nav-link--hire { color: var(--nx-lime); }
.nx-nav-link--hire .bi { text-shadow: 0 0 10px var(--nx-lime); }

.nx-nav-link.active {
    color: var(--nx-accent);
    background: color-mix(in srgb, var(--nx-accent) 12%, transparent);
    box-shadow: inset 2px 0 0 var(--nx-accent);
}

.nx-nav-link .bi,
.nx-nav-group > summary .bi {
    font-size: 1.05rem;
    width: 20px;
    text-align: center;
}

.nx-nav-group > summary { list-style: none; }
.nx-nav-group > summary::-webkit-details-marker { display: none; }

.nx-nav-group > summary::after {
    content: '\F282'; /* bootstrap-icons chevron-down */
    font-family: 'bootstrap-icons';
    margin-left: auto;
    font-size: 0.75rem;
    transition: transform 0.2s;
}

.nx-nav-group[open] > summary::after { transform: rotate(180deg); }

.nx-nav-group > .nx-nav-children {
    margin: 2px 0 6px 21px;
    padding-left: 10px;
    border-left: 1px solid var(--nx-border);
}

.nx-nav-children .nx-nav-link { font-size: 0.88rem; padding: 7px 10px; }

.nx-nav-divider {
    height: 1px;
    margin: 10px 8px;
    background: var(--nx-border);
}

.nx-nav-label {
    margin: 14px 12px 6px;
    font-family: var(--nx-font-mono);
    font-size: 0.7rem;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--nx-text-faint);
}

/* ---------- Buttons ---------- */

.nx-btn {
    --_bg: transparent;
    --_fg: var(--nx-text);
    --_bd: var(--nx-border-strong);
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    min-height: 40px;
    padding: 0 18px;
    border-radius: 999px;
    border: 1px solid var(--_bd);
    background: var(--_bg);
    color: var(--_fg);
    font-family: var(--nx-font-mono);
    font-size: 0.85rem;
    font-weight: 600;
    letter-spacing: 0.02em;
    text-decoration: none;
    cursor: pointer;
    white-space: nowrap;
    transition: transform 0.15s var(--nx-ease), box-shadow 0.25s, background 0.2s, border-color 0.2s, color 0.2s;
}

.nx-btn:hover { color: var(--_fg); border-color: var(--nx-accent); box-shadow: var(--nx-glow-soft); transform: translateY(-1px); }
.nx-btn:active { transform: translateY(0) scale(0.98); }
.nx-btn:focus-visible { outline: 2px solid var(--nx-accent); outline-offset: 2px; }
.nx-btn[disabled] { opacity: 0.45; pointer-events: none; }

.nx-btn--primary {
    --_bg: linear-gradient(92deg, var(--nx-cyan), var(--nx-green) 70%, var(--nx-lime));
    --_fg: var(--nx-on-accent);
    --_bd: transparent;
    background-size: 160% 100%;
    background-position: 0 0;
}

.nx-btn--primary:hover { background-position: 100% 0; box-shadow: var(--nx-glow); border-color: transparent; }

.nx-btn--ghost { --_bd: transparent; --_fg: var(--nx-text-dim); }
.nx-btn--ghost:hover { --_fg: var(--nx-text); background: color-mix(in srgb, var(--nx-accent) 8%, transparent); box-shadow: none; border-color: transparent; }

.nx-btn--danger:hover { border-color: var(--nx-red); color: var(--nx-red); box-shadow: 0 0 16px color-mix(in srgb, var(--nx-red) 30%, transparent); }

.nx-btn--sm { min-height: 32px; padding: 0 12px; font-size: 0.78rem; }
.nx-btn--block { width: 100%; }

.nx-icon-btn {
    display: inline-grid;
    place-items: center;
    width: 40px;
    height: 40px;
    border-radius: 50%;
    border: 1px solid transparent;
    background: transparent;
    color: var(--nx-text-dim);
    font-size: 1.2rem;
    cursor: pointer;
    text-decoration: none;
    transition: color 0.2s, background 0.2s, border-color 0.2s, box-shadow 0.2s, transform 0.15s;
}

.nx-icon-btn:hover {
    color: var(--nx-accent);
    border-color: var(--nx-border-strong);
    background: color-mix(in srgb, var(--nx-accent) 8%, transparent);
    box-shadow: var(--nx-glow-soft);
}

.nx-icon-btn:active { transform: scale(0.94); }
.nx-icon-btn:focus-visible { outline: 2px solid var(--nx-accent); outline-offset: 2px; }

/* ---------- Surfaces ---------- */

.nx-card {
    position: relative;
    background: var(--nx-surface);
    border: 1px solid var(--nx-border);
    border-radius: var(--nx-radius);
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    box-shadow: var(--nx-shadow);
}

/* Spotlight that follows the cursor across a card (--mx/--my set by js/neonFx.js). */
.nx-card::after {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: inherit;
    pointer-events: none;
    background: radial-gradient(380px circle at var(--mx, 50%) var(--my, 50%),
        color-mix(in srgb, var(--nx-accent) 11%, transparent), transparent 50%);
    opacity: 0;
    transition: opacity 0.35s;
}

.nx-card:hover::after { opacity: 1; }

.nx-card--pad { padding: 20px; }

.nx-card-title {
    display: flex;
    align-items: center;
    gap: 10px;
    margin: 0 0 14px;
    font-family: var(--nx-font-mono);
    font-size: 0.8rem;
    font-weight: 600;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--nx-text-dim);
}

.nx-card-title .bi { color: var(--nx-accent); font-size: 1rem; }

/* Animated gradient border that lights up on hover, plus a 3D tilt toward the cursor on elements
   that opt in with data-tilt (--rx/--ry set by js/neonFx.js). */
.nx-glow-hover {
    transition: transform 0.25s var(--nx-ease), box-shadow 0.35s, border-color 0.35s;
}

.nx-glow-hover::before {
    content: '';
    position: absolute;
    inset: -1px;
    border-radius: inherit;
    padding: 1px;
    background: linear-gradient(135deg, var(--nx-cyan), var(--nx-green), var(--nx-lime));
    -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    -webkit-mask-composite: xor;
    mask-composite: exclude;
    opacity: 0;
    transition: opacity 0.35s;
    pointer-events: none;
}

.nx-glow-hover:hover {
    transform: perspective(1000px) rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg)) translateY(-4px);
    border-color: transparent;
    box-shadow: var(--nx-shadow), 0 0 40px color-mix(in srgb, var(--nx-accent) 18%, transparent);
}

.nx-glow-hover:hover::before { opacity: 1; }

/* ---------- Chips / badges ---------- */

.nx-chip {
    --_c: var(--nx-accent);
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 3px 10px;
    border-radius: 999px;
    border: 1px solid color-mix(in srgb, var(--_c) 45%, transparent);
    background: color-mix(in srgb, var(--_c) 12%, transparent);
    color: var(--_c);
    font-family: var(--nx-font-mono);
    font-size: 0.7rem;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    text-decoration: none;
    white-space: nowrap;
}

a.nx-chip:hover { color: var(--_c); box-shadow: 0 0 14px color-mix(in srgb, var(--_c) 35%, transparent); }

[data-theme="light"] .nx-chip { color: color-mix(in srgb, var(--_c) 75%, #000); }

.nx-tag {
    font-family: var(--nx-font-mono);
    font-size: 0.72rem;
    color: var(--nx-text-faint);
}

.nx-count {
    min-width: 26px;
    padding: 1px 8px;
    border-radius: 999px;
    background: color-mix(in srgb, var(--nx-accent) 14%, transparent);
    color: var(--nx-accent);
    font-family: var(--nx-font-mono);
    font-size: 0.72rem;
    text-align: center;
}

/* ---------- Inputs ---------- */

.nx-input {
    display: flex;
    align-items: center;
    gap: 8px;
    height: 42px;
    padding: 0 6px 0 14px;
    border-radius: 999px;
    border: 1px solid var(--nx-border-strong);
    background: color-mix(in srgb, var(--nx-bg) 60%, transparent);
    transition: border-color 0.2s, box-shadow 0.2s;
}

.nx-input:focus-within { border-color: var(--nx-accent); box-shadow: var(--nx-glow-soft); }

.nx-input input {
    flex: 1;
    min-width: 0;
    border: 0;
    outline: 0;
    background: transparent;
    color: var(--nx-text);
    font-family: var(--nx-font-mono);
    font-size: 0.88rem;
}

.nx-input input::placeholder { color: var(--nx-text-faint); }
.nx-input .bi { color: var(--nx-text-faint); }

/* ---------- Spinner ---------- */

.nx-spinner {
    width: 28px;
    height: 28px;
    border-radius: 50%;
    border: 2px solid var(--nx-border-strong);
    border-top-color: var(--nx-cyan);
    border-right-color: var(--nx-green);
    animation: nx-spin 0.8s linear infinite;
}

.nx-spinner--sm { width: 18px; height: 18px; }

@keyframes nx-spin { to { transform: rotate(360deg); } }

/* ---------- Pagination ---------- */

.nx-pager {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 6px;
    margin-top: 32px;
}

.nx-pager button {
    min-width: 38px;
    height: 38px;
    padding: 0 10px;
    border-radius: 10px;
    border: 1px solid var(--nx-border);
    background: var(--nx-surface);
    color: var(--nx-text-dim);
    font-family: var(--nx-font-mono);
    font-size: 0.85rem;
    cursor: pointer;
    transition: all 0.2s;
}

.nx-pager button:hover:not([disabled]) { color: var(--nx-text); border-color: var(--nx-accent); }
.nx-pager button[aria-current="page"] {
    color: var(--nx-on-accent);
    background: var(--nx-accent);
    border-color: var(--nx-accent);
    box-shadow: var(--nx-glow-soft);
}
.nx-pager button[disabled] { opacity: 0.35; cursor: default; }

/* ---------- Entrance and scroll reveal ---------- */

/* These animate the individual `translate`/`scale` properties rather than `transform`, so a
   filled animation never pins `transform` and hover lift/tilt keep working afterwards. */

/* Time-based, for content in view on load (staggered by --i). */
@media (prefers-reduced-motion: no-preference) {
    .nx-reveal {
        animation: nx-rise 0.7s var(--nx-ease) both;
        animation-delay: calc(var(--i, 0) * 70ms);
    }
}

@keyframes nx-rise {
    from { opacity: 0; translate: 0 18px; }
    to { opacity: 1; translate: none; }
}

/* Scroll-driven, for content further down: rises in as it enters the viewport. Being tied to
   scroll position rather than time, it doesn't replay when Blazor re-renders the page. Browsers
   without scroll timelines simply show the content. */
@supports (animation-timeline: view()) {
    @media (prefers-reduced-motion: no-preference) {
        .nx-scroll-reveal {
            animation: nx-scroll-rise linear both;
            animation-timeline: view();
            animation-range: entry 0% entry 70%;
        }
    }
}

@keyframes nx-scroll-rise {
    from { opacity: 0; translate: 0 48px; scale: 0.96; }
    to { opacity: 1; translate: none; scale: none; }
}

/* ---------- Count-up numbers ---------- */

/* Registered so it interpolates; unregistered (older browsers) it just jumps to the target. */
@property --nx-n {
    syntax: '<integer>';
    initial-value: 0;
    inherits: false;
}

.nx-count-up {
    counter-reset: nx-n var(--nx-n);
}

.nx-count-up::after {
    content: counter(nx-n);
}

.nx-count-up > span {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
}

@media (prefers-reduced-motion: no-preference) {
    .nx-count-up { animation: nx-count 1.8s cubic-bezier(0.16, 1, 0.3, 1) 0.3s both; }
}

@media (prefers-reduced-motion: reduce) {
    .nx-count-up { --nx-n: var(--to); }
}

@keyframes nx-count {
    from { --nx-n: 0; }
    to { --nx-n: var(--to); }
}

/* ---------- Scrollbar ---------- */

* { scrollbar-width: thin; scrollbar-color: var(--nx-border-strong) transparent; }
