/* ==========================================================================
   base.css — reset, screen machinery, shared primitives, global chrome.
   ========================================================================== */

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

html, body {
  margin: 0;
  padding: 0;
  height: 100%;
  overflow: hidden;              /* only #main-screen is allowed to scroll */
}

body {
  font-family: var(--font-body);
  color: var(--burgundy);
  background: var(--pastel-pink);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  -webkit-tap-highlight-color: transparent;
}

img, svg, video { display: block; max-width: 100%; }
button { font: inherit; color: inherit; }
.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }

.sr-only {
  position: absolute; width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  clip: rect(0 0 0 0); clip-path: inset(50%); overflow: hidden; white-space: nowrap;
}

/* --------------------------------------------------------------------------
   Focus. Visible, on-theme, and never suppressed. (§2.3)
   -------------------------------------------------------------------------- */
:focus { outline: none; }
:focus-visible {
  outline: 3px solid var(--wine);
  outline-offset: 3px;
  border-radius: var(--r-sm);
}
.overlay--blush :focus-visible,
.wish :focus-visible,
.hero :focus-visible { outline-color: var(--gold-light); }


/* ==========================================================================
   SCREENS
   Hidden screens are *fully* gone: no opacity, no visibility, no tab stops.
   ========================================================================== */
.screen {
  position: fixed;
  inset: 0;
  z-index: var(--z-screen);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition:
    opacity    var(--dur-slow) var(--ease-soft),
    visibility 0s linear var(--dur-slow);
}

.screen.is-active {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transition:
    opacity    var(--dur-slow) var(--ease-soft),
    visibility 0s linear 0s;
}

/* the one screen that scrolls */
#main-screen.is-active {
  overflow-y: auto;
  overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
  scroll-behavior: smooth;
}


/* ==========================================================================
   SHARED TYPE
   ========================================================================== */
.eyebrow {
  font-family: var(--font-cute);
  font-size: clamp(18px, 4.6vw, 24px);
  font-weight: 400;
  color: var(--dusty-pink);
  letter-spacing: .04em;
  margin: 0 0 var(--sp);
}
.eyebrow--gold { color: var(--gold); }

.section-title {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(30px, 8vw, 52px);
  line-height: 1.14;
  color: var(--burgundy);
  margin: 0 0 var(--sp-2);
}
.section-title--gold { color: var(--gold-light); }

.section-sub {
  font-family: var(--font-cute);
  font-size: clamp(17px, 4.2vw, 21px);
  color: var(--wine);
  opacity: .8;
  margin: 0 0 var(--sp-4);
}


/* ==========================================================================
   BUTTONS
   ========================================================================== */
.btn {
  appearance: none;
  border: 0;
  cursor: pointer;
  font-family: var(--font-body);
  font-weight: 600;
  font-size: clamp(15px, 3.8vw, 17px);
  letter-spacing: .02em;
  padding: 15px var(--sp-4);
  border-radius: var(--r-pill);
  box-shadow: var(--shadow-soft);
  transition:
    transform   var(--dur-fast) var(--ease-bounce),
    box-shadow  var(--dur-fast) var(--ease-soft),
    filter      var(--dur-fast) var(--ease-soft);
}
.btn:hover  { transform: translateY(-3px); box-shadow: var(--shadow-strong); }
.btn:active { transform: translateY(0) scale(.97); }

.btn--pink {
  background: linear-gradient(160deg, var(--blush), var(--dusty-pink));
  color: var(--burgundy);
}
.btn--gold {
  background: linear-gradient(160deg, var(--gold-light), var(--gold));
  color: var(--burgundy-deep);
  padding: 17px 44px;
  font-size: clamp(16px, 4.2vw, 19px);
}
.btn--ghost {
  background: transparent;
  color: var(--gold-light);
  border: 1.5px solid rgba(236, 216, 166, .45);
  box-shadow: none;
  font-weight: 500;
}
.btn--ghost:hover { background: rgba(236, 216, 166, .10); box-shadow: none; }

/* light-background sibling of .btn--ghost — for cream/pink sections */
.btn--outline {
  background: transparent;
  color: var(--wine);
  border: 1.5px solid var(--dusty-pink);
  box-shadow: none;
  font-weight: 500;
}
.btn--outline:hover { background: rgba(223, 160, 179, .12); box-shadow: none; }


/* ==========================================================================
   MASCOT OVERRIDE — exactly one detection point (§2.2)
   js/main.js probes CONFIG.assets.mascotOverride once and sets .has-mascot
   on <body>. Every instance in the document then flips together.
   ========================================================================== */
.mascot-img { display: none; width: 100%; height: 100%; object-fit: contain; }
body.has-mascot .mascot-img { display: block; }
body.has-mascot .mascot-svg,
body.has-mascot .pw-popup__art > svg,
body.has-mascot .mascot-mini > svg { display: none; }


/* ==========================================================================
   MISSING-ASSET PLACEHOLDERS (§2.2)
   A 404 should read as a deliberate empty state, never a broken-image icon.
   ========================================================================== */
.is-missing {
  position: relative;
  background:
    repeating-linear-gradient(135deg,
      rgba(223, 160, 179, .16) 0 10px,
      rgba(223, 160, 179, .06) 10px 20px),
    var(--cream-dark);
}
.is-missing img { opacity: 0; }
.is-missing::after {
  content: '🩷';
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  font-size: 26px;
  opacity: .5;
}


/* ==========================================================================
   GLOBAL CHROME — veil, canvas, sound toggle
   ========================================================================== */
.veil {
  position: fixed;
  inset: 0;
  z-index: var(--z-veil);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  background: var(--cream);
  transition:
    opacity    var(--dur-cinematic) var(--ease-soft),
    visibility 0s linear var(--dur-cinematic);
}
.veil.is-on {
  opacity: 1;
  visibility: visible;
  transition:
    opacity    700ms var(--ease-premium),
    visibility 0s linear 0s;
}
.veil__glow {
  position: absolute;
  inset: 0;
  background: radial-gradient(circle at 50% 50%,
    #FFFFFF 0%,
    var(--pastel-pink) 42%,
    var(--blush) 74%,
    var(--dusty-pink) 100%);
}
/* wine-tinted variant for the mascot hand-off (§4.4) */
.veil--wine .veil__glow {
  background: radial-gradient(circle at 50% 50%,
    var(--blush) 0%,
    var(--wine) 48%,
    var(--burgundy) 78%,
    var(--burgundy-deep) 100%);
}

#fx-canvas {
  position: fixed;
  inset: 0;
  z-index: var(--z-canvas);
  pointer-events: none;
}

.sound-btn {
  position: fixed;
  top: max(14px, env(safe-area-inset-top));
  right: 14px;
  z-index: var(--z-sound);
  width: 42px;
  height: 42px;
  display: none;
  place-items: center;
  border: 0;
  cursor: pointer;
  border-radius: var(--r-pill);
  background: rgba(255, 248, 239, .78);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  color: var(--wine);
  box-shadow: var(--shadow-soft);
  transition: transform var(--dur-fast) var(--ease-bounce);
}
body:not(.is-locked) .sound-btn { display: grid; }
.sound-btn:hover { transform: scale(1.08); }
.sound-btn .ic-off { display: none; }
.sound-btn[aria-pressed="true"] .ic-on  { display: none; }
.sound-btn[aria-pressed="true"] .ic-off { display: block; }


/* ==========================================================================
   CUSTOM CURSOR — desktop, main experience only. cursor.js calls
   enable()/disable() at the same moments body.is-locked toggles, so this
   never engages on the password screen.

   The !important below is deliberate and narrow: many elements across the
   other stylesheets set their own `cursor: pointer` for affordance, and an
   inherited `cursor: none` on body can't win against those. This is the
   same class of intentional global-mode override as the reduced-motion
   block in tokens.css.
   ========================================================================== */
body.cursor-ready * { cursor: none !important; }

.cursor-dot,
.cursor-trail {
  position: fixed;
  top: 0;
  left: 0;
  z-index: var(--z-cursor);
  pointer-events: none;
  opacity: 0;
  transition: opacity 200ms var(--ease-soft);
  will-change: transform;
}
body.cursor-ready .cursor-dot,
body.cursor-ready .cursor-trail { opacity: 1; }

.cursor-dot svg   { display: block; margin: -10px 0 0 -10px; filter: drop-shadow(0 2px 4px rgba(74, 22, 38, .3)); }
.cursor-trail svg { display: block; margin: -6px 0 0 -6px; opacity: .55; }
