/* base.css — foundation primitives (Phase 4.1): page canvas, atmosphere
 * layers, scrollbars, selection, focus rings, motion keyframes, and the
 * header theme toggle. This is the DL "base + atmosphere" layer, kept
 * separate from tokens.css (pure tokens) and app.css (component/shell CSS,
 * rewritten in phases 4.2–4.5). Everything references tokens — never raw hex.
 */

/* ---- base ---- */
html {
  background-color: var(--canvas);
  overflow-x: clip;          /* atmosphere layers never cause sideways scroll */
  scroll-behavior: smooth;
}
* { border-color: var(--line); }

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

:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* scrollbars tuned to the ramp */
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: var(--canvas); }
::-webkit-scrollbar-thumb {
  background: var(--scrollbar-thumb);
  border-radius: var(--r-pill);
  border: 2px solid var(--canvas);
}
::-webkit-scrollbar-thumb:hover { background: var(--scrollbar-thumb-hover); }

/* ---- atmosphere — fixed decorative layers behind everything ---- */
.bg-grid,
.bg-grain {
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
}
.bg-grid {
  background-image:
    linear-gradient(to right, var(--grid-line) 1px, transparent 1px),
    linear-gradient(to bottom, var(--grid-line) 1px, transparent 1px);
  background-size: 74px 74px;
  -webkit-mask-image: radial-gradient(ellipse 90% 60% at 50% -8%, #000 8%, transparent 82%);
  mask-image: radial-gradient(ellipse 90% 60% at 50% -8%, #000 8%, transparent 82%);
}
.bg-grain {
  opacity: var(--grain-opacity);
  mix-blend-mode: var(--grain-blend);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 220 220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.82' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.5'/%3E%3C/svg%3E");
}

/* ---- motion primitives ---- */
@keyframes fade-rise {
  from { opacity: 0; transform: translateY(24px); }
  to   { opacity: 1; transform: translateY(0); }
}
.rise { opacity: 0; animation: fade-rise var(--dur-reveal) var(--ease-out-expo) both; }

@keyframes skeleton-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.5; } }
.skeleton {
  background-color: var(--skeleton);
  border-radius: var(--r-md);
  animation: skeleton-pulse 2.6s ease-in-out infinite;
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .rise { animation: none; opacity: 1; }
  .skeleton { animation: none; }
}

/* ---- header theme toggle ---- */
.topbar__aside { display: flex; align-items: center; gap: var(--sp-3); }

.theme-toggle {
  display: grid;
  place-items: center;
  height: 36px;
  width: 36px;
  border-radius: var(--r-sm);
  border: 1px solid var(--line);
  background: transparent;
  color: var(--ink-muted);
  cursor: pointer;
  font-size: 15px;
  line-height: 1;
  transition: border-color var(--dur-fast), color var(--dur-fast);
}
.theme-toggle:hover { border-color: var(--line-strong); color: var(--ink); }
.theme-toggle:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* Icon visibility is pure CSS off data-theme — no JS, no flash, no mismatch. */
.theme-toggle .theme-icon-moon { display: none; }
[data-theme="light"] .theme-toggle .theme-icon-sun { display: none; }
[data-theme="light"] .theme-toggle .theme-icon-moon { display: inline; }
