/* base.css — global reset + typography baseline.
   Component-specific CSS still lives inline in each *.jsx file
   (it gets co-located there during the design-canvas phase). */

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

html {
  /* Always paint to viewport bg so request-desktop-site (which can make
     body narrower than the layout viewport) doesn't expose a default
     white strip on the right. */
  background: var(--bg);
  /* overflow-x: clip is the modern equivalent of `hidden` — same clip
     behavior, but does NOT make this element a scroll container, so
     position: sticky still works on the TopBar and nested scrollers
     (the pricing matrix) keep their own overflow:auto. */
  overflow-x: clip;
  /* Belt + braces in case `clip` isn't honored on a stray browser. */
  overflow-x: hidden;
  overflow-x: clip;
}

body {
  margin: 0;
  padding: 0;
  width: 100%;
  min-height: 100vh;
  background: var(--bg);
  color: var(--ink);
  font: 16px/1.55 var(--sans);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  transition: background .2s ease, color .2s ease;
  /* Triple guard against horizontal scroll. The mascot wrap, fixed
     consent banner, and any future absolute-positioned element could
     in theory push past 100vw; clip + hidden fallback catches them. */
  overflow-x: hidden;
  overflow-x: clip;
}

/* #app is the React mount root. Anything React renders lives inside it.
   Clipping here too means even a wild absolutely-positioned child
   can't introduce horizontal scroll. */
#app {
  width: 100%;
  overflow-x: clip;
}

h1, h2, h3, h4 {
  margin: 0;
  font-family: var(--serif);
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--ink);
}
h1 { font-size: clamp(40px, 6vw, 72px); line-height: 1.05; }
h2 { font-size: clamp(28px, 4vw, 48px); line-height: 1.15; }
h3 { font-size: 22px; line-height: 1.25; }

p { margin: 0; }

a { color: inherit; text-decoration: none; }

button { font: inherit; }

/* Shared helpers used across components */
.wrap {
  max-width: 1180px;
  margin: 0 auto;
  padding: 0 var(--gutter);
  position: relative;
}
.serif { font-family: var(--serif); }
.mono  { font-family: var(--mono); }
.center { text-align: center; }
.eyebrow {
  font: 500 11px/1 var(--mono);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.hair {
  height: 1px;
  background: var(--hair);
  width: 100%;
}
.text-mute { color: var(--ink-3); }

/* Button presets */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 44px;
  padding: 0 22px;
  border-radius: 10px;
  font: 500 14px/1 var(--sans);
  cursor: pointer;
  border: 1px solid transparent;
  transition: transform .15s ease, box-shadow .2s ease, background .15s ease, border-color .15s ease;
}
.btn-pill { border-radius: 999px; min-height: 36px; padding: 0 16px; font-size: 13px; }
.btn-primary { background: var(--accent); color: #fff; }
.btn-primary:hover { transform: translateY(-1px); box-shadow: var(--shadow); }
.btn-secondary { background: var(--card); color: var(--ink); border-color: var(--border); }
.btn-secondary:hover { border-color: var(--ink); }
.btn-ghost { background: transparent; border: 0; color: var(--ink); padding: 8px 0; cursor: pointer; }

.card {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 24px;
}

.tlink {
  font: 500 14px/1 var(--sans);
  color: var(--accent);
  text-decoration: none;
  border-bottom: 1px dashed currentColor;
  padding-bottom: 2px;
}

/* Print / no-print toggle used by the footer + TopBar */
@media print { .no-print { display: none !important; } }

/* Reduced motion respect */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
}

/* Focus visibility — never sacrifice for aesthetics. */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 4px;
}

/* ── Page-wide no-select ──────────────────────────────────────────────────
   The whole site is mostly imagery + brand copy; we want to discourage
   incidental drag/save/copy. Form fields stay selectable so people can
   actually type into the waitlist. */
html, body {
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
}
input, textarea, [contenteditable="true"], [contenteditable=""] {
  -webkit-user-select: text;
  -moz-user-select: text;
  -ms-user-select: text;
  user-select: text;
}

/* ── Mascot — base, float, and aura ─────────────────────────────────────── */
.monk-img {
  /* Mascot is rendered as a <div role="img"> with background-image so the
     browser's "Save image" context menu doesn't show. See MonkAvatar in
     shared.jsx.
     Light theme = the original (warm-skinned) mascot.
     Dark theme  = the alternate (high-contrast) variant.  */
  background-image: url('/assets/monk-mascot-light.png');
  background-repeat: no-repeat;
  background-size: contain;
  background-position: center;
  -webkit-user-select: none;
  user-select: none;
  -webkit-user-drag: none;
  -webkit-touch-callout: none;
}
:root[data-theme="dark"] .monk-img,
html[data-theme="dark"] .monk-img,
body[data-theme="dark"] .monk-img {
  /* !important wins over the inline background-image fallback that
     shared.jsx sets on every MonkAvatar (light variant). */
  background-image: url('/assets/monk-mascot-dark.png') !important;
}

/* Slow, feather-like floating — translateY range bumped so it's
   actually visible at phone sizes. ±6 px was imperceptible on a 320 px
   mascot; ±14 px reads as a clear levitation. */
.monk-float {
  animation: monk-float 6s ease-in-out infinite;
  will-change: transform;
  transform-origin: center bottom;
}
@keyframes monk-float {
  0%, 100% { transform: translateY(0)     rotate(-0.7deg); }
  50%      { transform: translateY(-14px) rotate( 0.7deg); }
}
/* Only collapse the float for users who EXPLICITLY ask for reduced
   motion — this is the OS-level "remove animations" toggle. Most users
   never touch it, so this branch should be rare. */
@media (prefers-reduced-motion: reduce) {
  .monk-float { animation: none; }
}

/* ── Aura — static sun-disc behind the mascot ───────────────────────────
   Plain soft radial halo. No spin, no pulse, no rays. Sits BEHIND the
   figure (z-index 0; the mascot is z-index 1) so it reads as a warm
   light source rather than competing with the silhouette. */
.monk-aura-wrap { display: inline-block; position: relative; }
.monk-aura {
  position: absolute;
  /* Sun-disc placement: behind the head/torso, slightly larger so the
     bright core shows past the silhouette like a proper backlight. */
  inset: -4% 6% 18% 6%;
  pointer-events: none;
  z-index: 0;
  border-radius: 50%;
  /* Strong, opaque sun core. Falloff is short so the glow doesn't bleed
     too far past the figure. */
  background: radial-gradient(
    closest-side,
    rgba(255,170,70, 0.85) 0%,
    rgba(255,140,40, 0.55) 25%,
    rgba(232,116,26, 0.22) 50%,
    rgba(232,116,26, 0.05) 75%,
    transparent 90%);
  filter: blur(6px);
}
.monk-aura-wrap .monk-img { position: relative; z-index: 1; }
/* Dark theme: a touch warmer + a touch brighter so the sun still reads
   as a sun (not a brown smudge) against near-black. */
:root[data-theme="dark"] .monk-aura,
html[data-theme="dark"] .monk-aura,
body[data-theme="dark"] .monk-aura {
  background: radial-gradient(
    closest-side,
    rgba(255,190,90, 0.90) 0%,
    rgba(255,160,60, 0.60) 25%,
    rgba(255,130,40, 0.25) 50%,
    rgba(255,120,30, 0.06) 75%,
    transparent 90%);
}
