/* ==========================================================================
   Self-hosted fonts — replaces the fonts.googleapis.com / fonts.gstatic.com
   CDN calls that used to sit in every template's <head>.

   Why: the Google Fonts CDN needs its own DNS lookup + TLS handshake to two
   separate origins (fonts.googleapis.com, then fonts.gstatic.com), and the
   browser can't start fetching the actual font files until the CSS from the
   first origin comes back — two network round trips before real text can
   render, on top of whatever it costs to reach this app's own server. On a
   slow or high-latency connection that's the single biggest thing standing
   between a blank page and readable text.

   Serving the same 10 weight files from this app's own /static/ folder
   collapses that to one origin, no extra handshake, and lets these files
   live in the same browser cache/CDN as the rest of the site.

   Only the weights actually used in this codebase are included (checked
   against every font-weight: declaration in static/*.css) — latin subset
   only, woff2 only (98%+ of traffic; no woff/ttf fallback needed in 2026).
   font-display: swap means visible text renders immediately in a fallback
   font and swaps in once these load, instead of staying invisible.
   ========================================================================== */

@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/static/fonts/inter-latin-400-normal.woff2') format('woff2');
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('/static/fonts/inter-latin-500-normal.woff2') format('woff2');
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('/static/fonts/inter-latin-600-normal.woff2') format('woff2');
}

@font-face {
  font-family: 'Oswald';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('/static/fonts/oswald-latin-500-normal.woff2') format('woff2');
}
@font-face {
  font-family: 'Oswald';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('/static/fonts/oswald-latin-600-normal.woff2') format('woff2');
}
@font-face {
  font-family: 'Oswald';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('/static/fonts/oswald-latin-700-normal.woff2') format('woff2');
}

@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/static/fonts/jetbrains-mono-latin-400-normal.woff2') format('woff2');
}
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('/static/fonts/jetbrains-mono-latin-500-normal.woff2') format('woff2');
}
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('/static/fonts/jetbrains-mono-latin-600-normal.woff2') format('woff2');
}
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('/static/fonts/jetbrains-mono-latin-700-normal.woff2') format('woff2');
}

/* ==========================================================================
   The ONE loading screen (the working chibi) lives in static/nav-loading.js,
   which injects its own CSS so it works before any stylesheet has arrived.
   Only this functional rule stays here: it blocks a second click landing on
   the same element while a navigation is already underway.
   ========================================================================== */
.is-nav-loading {
  cursor: progress !important;
  pointer-events: none;
}

/* ==========================================================================
   Global UX baseline (every page)
   - keyboard focus is always visible, even where a component removed its own
     outline;
   - taps respond at once (no double-tap-zoom delay) and don't flash grey;
   - inputs are 16px on touch screens so iOS doesn't zoom in on focus;
   - people who ask for reduced motion get it everywhere.
   ========================================================================== */
:is(a, button, input, select, textarea, summary, [role="button"], [tabindex]):focus-visible {
  outline: 2px solid var(--accent, #1a4fa0) !important;
  outline-offset: 2px;
}
a, button, summary, label, select, [role="button"] {
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
}
@media (pointer: coarse) and (max-width: 820px) {
  input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="file"]),
  select, textarea { font-size: max(16px, 1em); }
}
@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;
  }
}
