/* Critical pre-React shell styles. Served from public/ so Vite does not send
 * this plain CSS through the full Tailwind content scanner during builds. */
body {
  /* The literal copy of --font-sans (src/lib/design/tokens.css § Typography),
   * and one of only two in the repo. It cannot be `var(--font-sans)`: this
   * sheet is a plain <link> in index.html that paints the pre-React skeleton,
   * and tokens.css arrives later inside the bundled CSS — so the var would be
   * undefined for exactly the frames this file exists to style, and the
   * skeleton would flash in the browser default before the app took over.
   * Keep the two in step; see that section for why the Windows names are
   * where they are. Plex is named first like the token, but cannot resolve
   * until the bundled CSS (which carries its @font-face) arrives, so the
   * skeleton paints in the system face — the same face swap shows.
   *
   * Wrapped in `var(--font-sans, …)` so the literal is only the FALLBACK. As a
   * bare value it pinned `body` to the Latin-first stack for the life of the
   * page, and `[dir="rtl"] { --font-sans: var(--font-arabic) }` never reached
   * anything below <html>: measured in Chromium, `html` resolved the Arabic
   * stack and `body` the Latin one. Once tokens.css loads the var resolves
   * and the RTL swap applies; before it, the literal paints the skeleton. */
  font-family: var(--font-sans, 'IBM Plex Sans', 'IBM Plex Sans Arabic', -apple-system, BlinkMacSystemFont, 'SF Pro Text', 'SF Pro Display', 'SF Pro', 'SF Pro Arabic', 'SF Arabic', 'Geeza Pro', 'Segoe UI', Roboto, 'Noto Sans', system-ui, Arial, 'Helvetica Neue', sans-serif);
  margin: 0;
  /* Literal copies of --background (#F4F6F7 light / #0E1A22 dark, see
   * src/lib/design/tokens.css), for the same reason as the font stack above:
   * the tokens have not loaded when this paints, and a mismatch here is the
   * flash of the wrong colour on every cold load. Keep them in step. */
  background: #f4f6f7;
}

html.dark body {
  background: #0e1a22;
}

#root {
  min-height: 100vh;
}

.app-skeleton {
  position: fixed;
  inset: 0;
  background: #f4f6f7;
  display: flex;
  flex-direction: column;
  z-index: 9999;
}

html.dark .app-skeleton {
  background: #0e1a22;
}

/* Static blocks, not a shimmer: the house bans decorative loops (CLAUDE.md
 * § Implementation Rules), and a still placeholder needs no reduced-motion
 * opt-out at all. */
.skeleton-header {
  height: 68px;
  background: #e8eef0;
}

html.dark .skeleton-header {
  background: #15242e;
}

.skeleton-hero {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 2rem;
}

.skeleton-content {
  max-width: 600px;
  width: 100%;
}

.skeleton-line {
  height: 20px;
  background: #e8eef0;
  border-radius: 4px;
  margin-bottom: 12px;
}

html.dark .skeleton-line {
  background: #15242e;
}

.skeleton-line:first-child {
  width: 80%;
  height: 32px;
}

.skeleton-line:nth-child(2) {
  width: 60%;
}

.skeleton-line:nth-child(3) {
  width: 40%;
}

#root:not(:empty) + .app-skeleton {
  display: none;
}

/* Build-time page summary for crawlers that do not run JavaScript
 * (src/config/seo/prerender.ts). It sits under the fixed skeleton while the
 * bundle loads, and is removed from view the moment the app renders. */
.prerender {
  padding: 2rem 1rem;
  max-width: 64rem;
  margin: 0 auto;
}

#root:not(:empty) ~ .prerender {
  display: none;
}
