/* ============================================================================
   BASE — self-hosted fonts, reset, and the viewport-as-paper lock.
   Reads only from tokens.css. No component styling here.
   ============================================================================ */

/* ── Self-hosted fonts (provenance: fonts/VERSIONS.md). swap = render with the
   fallback immediately, upgrade when the woff2 arrives. ── */
@font-face {
  font-family: "Fraunces"; font-style: normal; font-weight: 600; font-display: swap;
  src: url("../fonts/fraunces-600.woff2") format("woff2");
}
@font-face {
  font-family: "Fraunces"; font-style: normal; font-weight: 700; font-display: swap;
  src: url("../fonts/fraunces-700.woff2") format("woff2");
}
@font-face {
  font-family: "Alegreya"; font-style: normal; font-weight: 400; font-display: swap;
  src: url("../fonts/alegreya-400.woff2") format("woff2");
}
@font-face {
  font-family: "Alegreya"; font-style: italic; font-weight: 400; font-display: swap;
  src: url("../fonts/alegreya-400-italic.woff2") format("woff2");
}
@font-face {
  font-family: "Alegreya"; font-style: normal; font-weight: 700; font-display: swap;
  src: url("../fonts/alegreya-700.woff2") format("woff2");
}
@font-face {
  font-family: "Courier Prime"; font-style: normal; font-weight: 400; font-display: swap;
  src: url("../fonts/courier-prime-400.woff2") format("woff2");
}

*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }

:root {
  --viewport-safe-top: env(safe-area-inset-top, 0px);
  --viewport-safe-bottom: env(safe-area-inset-bottom, 0px);
  --mobile-browser-bottom: 0px;
}

/* The root font-size gives the viewport-locked app a single scale. Mobile gets a
   higher fixed floor because narrow cover displays otherwise make every rem tiny. */
html {
  height: 100%;
  overflow: hidden;
  font-size: clamp(9.5px, calc(7.5px + 0.62vmin), 15px);
}

@media (max-width: 620px), (max-height: 520px) {
  :root {
    --mobile-browser-bottom: clamp(1.25rem, 6dvh, 3.75rem);
  }

  html {
    font-size: 15px;
  }
}

@media (max-width: 390px) {
  html {
    font-size: 16px;
  }
}

body {
  position: fixed; inset: 0; overflow: hidden;
  overscroll-behavior: none;
  background: var(--rd-paper); color: var(--rd-ink);
  font-family: var(--rd-font-body); font-size: 1rem; line-height: 1.5;
  -webkit-text-size-adjust: 100%;
  -webkit-tap-highlight-color: transparent;
  /* The frame is locked (no page scroll), so text must WRAP, never run off the edge. `anywhere` also
     lowers min-content width so flex/grid children can shrink to fit instead of overflowing. Long
     unbreakable strings (UUIDs, keys, credentials) get a fully-visible home in the Readout (core/readout). */
  overflow-wrap: anywhere;
  word-break: break-word;
}

/* Paper grain — a faint fractal-noise wash over everything (decorative, inert). */
body::before {
  content: ""; position: fixed; inset: 0; z-index: 9999; pointer-events: none; opacity: .04;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size: 180px 180px;
}

#app { position: relative; z-index: 1; height: 100dvh; width: 100vw; display: flex; flex-direction: column; overflow: hidden; }

img[data-protected-visual="true"] {
  -webkit-touch-callout: none;
  -webkit-user-drag: none;
  -webkit-user-select: none;
  user-select: none;
  pointer-events: none;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition: none !important; animation: none !important; }
}
