/* ============================================================
   Base: reset, background, typography, a11y primitives
   ============================================================ */

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

/* The `hidden` attribute must always win. Several components set
   `display: flex`, which otherwise beats the user-agent rule and leaves a
   supposedly hidden element occupying space — that is how the app bar was
   still showing inside a lesson. */
[hidden] { display: none !important; }

/* Browsers give <figure> a 40px left and right margin. Every illustration
   in this course is a figure, so unreset that margin pushed the artwork out
   of its column on narrow screens. */
figure, figcaption { margin: 0; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  min-height: 100dvh;
  font-family: var(--font-text);
  font-size: var(--t-md);
  line-height: 1.62;
  color: var(--ink-800);
  background: var(--paper);
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  transition: --accent var(--d-slow) linear;
}

/* ---- Aurora field -------------------------------------------------
   Three soft colour fields sit behind the glass. They are painted on a
   single fixed layer (not per-component) so we never stack blur filters.
   Animated with transform only. Cheap on a phone.                    */
.aurora {
  position: fixed; inset: -20vmax; z-index: -2;
  pointer-events: none;
  background: var(--paper);
}
.aurora::before, .aurora::after,
.aurora > i {
  content: ""; position: absolute; display: block;
  border-radius: 50%;
  filter: blur(70px);
  opacity: .55;
  will-change: transform;
}
.aurora::before {
  width: 52vmax; height: 52vmax; left: -14vmax; top: -12vmax;
  background: radial-gradient(circle at 45% 45%, var(--accent) 0%, transparent 66%);
  animation: drift-a 34s var(--e-out) infinite alternate;
  opacity: .40;
}
.aurora::after {
  width: 46vmax; height: 46vmax; right: -16vmax; top: 6vmax;
  background: radial-gradient(circle at 50% 50%, var(--accent-2) 0%, transparent 66%);
  animation: drift-b 41s var(--e-out) infinite alternate;
  opacity: .34;
}
.aurora > i {
  width: 44vmax; height: 44vmax; left: 14vmax; bottom: -22vmax;
  background: radial-gradient(circle at 50% 50%, var(--c-sun) 0%, transparent 64%);
  opacity: .22;
  animation: drift-c 47s var(--e-out) infinite alternate;
}

/* The colour belongs at the edges. A soft vertical veil keeps the middle
   of the screen — where all the reading happens — close to paper white,
   so contrast never depends on where a gradient happens to be sitting. */
.aurora::before, .aurora::after, .aurora > i { z-index: 0; }
.aurora-veil {
  position: fixed; inset: 0; z-index: -1; pointer-events: none;
  /* Two layers: a wash that carries a few percent of the unit's colour
     everywhere, so a violet unit *feels* violet, and a vertical veil that
     lifts the middle of the screen back toward paper where the reading is. */
  background:
    linear-gradient(90deg,
      transparent 0%,
      color-mix(in srgb, var(--paper) 58%, transparent) 24%,
      color-mix(in srgb, var(--paper) 72%, transparent) 50%,
      color-mix(in srgb, var(--paper) 58%, transparent) 76%,
      transparent 100%),
    linear-gradient(160deg,
      color-mix(in srgb, var(--accent) 7%, transparent) 0%,
      transparent 45%,
      color-mix(in srgb, var(--accent-2) 6%, transparent) 100%);
}
@media (max-width: 720px) {
  /* On a phone the reading column IS the screen, so veil the whole thing. */
  .aurora-veil {
    background:
      color-mix(in srgb, var(--paper) 66%, transparent),
      linear-gradient(160deg,
        color-mix(in srgb, var(--accent) 8%, transparent) 0%,
        transparent 55%,
        color-mix(in srgb, var(--accent-2) 7%, transparent) 100%);
  }
}
@keyframes drift-a { to { transform: translate3d(9vmax, 7vmax, 0) scale(1.14); } }
@keyframes drift-b { to { transform: translate3d(-11vmax, 9vmax, 0) scale(1.09); } }
@keyframes drift-c { to { transform: translate3d(7vmax, -10vmax, 0) scale(1.16); } }

/* A faint grain keeps large gradients from banding on cheap panels. */
.aurora-grain {
  position: fixed; inset: 0; z-index: -1; pointer-events: none;
  opacity: .30; mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='140' height='140'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/><feColorMatrix type='saturate' values='0'/></filter><rect width='140' height='140' filter='url(%23n)' opacity='.30'/></svg>");
}

/* ---- Typography ---- */
h1, h2, h3, h4, .display {
  font-family: var(--font-display);
  font-weight: 800;
  line-height: 1.14;
  letter-spacing: -0.018em;
  color: var(--ink-900);
  margin: 0 0 var(--s3);
  text-wrap: balance;
}
h1 { font-size: var(--t-3xl); }
h2 { font-size: var(--t-2xl); }
h3 { font-size: var(--t-xl); }
h4 { font-size: var(--t-lg); }
p  { margin: 0 0 var(--s4); text-wrap: pretty; }
p:last-child { margin-bottom: 0; }
a { color: var(--accent-deep); text-underline-offset: 3px; }
strong, b { font-weight: 800; color: var(--ink-900); }
small { font-size: var(--t-sm); }

.eyebrow {
  font-family: var(--font-display);
  font-weight: 800; font-size: var(--t-xs);
  letter-spacing: .13em; text-transform: uppercase;
  color: var(--accent-deep);
  margin: 0 0 var(--s2);
}
.lede { font-size: var(--t-lg); color: var(--ink-700); }
.muted { color: var(--ink-600); }
.tiny { font-size: var(--t-xs); color: var(--ink-600); }

/* Spanish text gets its own voice so learners can spot it instantly. */
.es {
  font-family: var(--font-display);
  font-weight: 800;
  color: var(--accent-ink);
  font-feature-settings: "kern" 1;
}
.es-lg { font-size: var(--t-xl); }
.en { color: var(--ink-600); font-style: normal; }

/* ---- Layout helpers ---- */
.wrap { width: min(100% - 2rem, var(--read-wide)); margin-inline: auto; }
.read { width: min(100%, var(--read)); margin-inline: auto; }
.stack > * + * { margin-top: var(--s4); }
.row { display: flex; gap: var(--s3); align-items: center; flex-wrap: wrap; }
.row-tight { display: flex; gap: var(--s2); align-items: center; flex-wrap: wrap; }
.spacer { flex: 1 1 auto; }
.center { text-align: center; }

/* ---- Accessibility primitives ---- */
.sr-only {
  position: absolute !important; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0;
}
:focus { outline: none; }
:focus-visible {
  outline: 3px solid var(--accent-deep);
  outline-offset: 3px;
  border-radius: var(--r-xs);
}
.skip-link {
  position: fixed; top: -100px; left: 12px; z-index: 999;
  background: var(--white); color: var(--ink-900);
  padding: var(--s3) var(--s4); border-radius: var(--r-sm);
  box-shadow: var(--sh-3); font-weight: 800;
  transition: top var(--d-fast) var(--e-out);
}
.skip-link:focus-visible { top: 12px; }

::selection { background: var(--accent); color: #fff; }

/* Touch targets never below 44px in the learning flow. */
button, .btn, .tile, .opt { touch-action: manipulation; }

/* ---- Reduced motion: kill drift + transitions, keep state changes ---- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
  .aurora::before, .aurora::after, .aurora > i { animation: none !important; }
}

/* ---- Coarse pointers: blur is expensive on low-end phones ---- */
@media (max-width: 540px) {
  :root { --glass-blur: 14px; }
}
