/* BirthdayPartyPal design system: tokens (DESIGN_SYSTEM.md).
   Tokens, base, motion and moments live in cascade layers, so any existing unlayered page CSS
   always wins: loading the design system never restyles a page by surprise. Components are
   unlayered .ds-* classes (they only style markup that asks for them).
   Colors per theme: ds/themes.css (generated). */
@layer ds.tokens, ds.base, ds.components, ds.motion, ds.moments;

@property --ds-progress { syntax: "<number>"; inherits: true; initial-value: 0; }
/* Metric-matched local fallbacks (measured against Arial): no layout jump when the web fonts swap in. */
@font-face { font-family: "BPP Display Fallback"; src: local("Arial"), local("ArialMT"), local("Helvetica"); size-adjust: 93.4%; ascent-override: 103.8%; descent-override: 25.7%; line-gap-override: 0%; }
@font-face { font-family: "BPP Body Fallback"; src: local("Arial"), local("ArialMT"), local("Helvetica"); size-adjust: 98.9%; ascent-override: 102.2%; descent-override: 35.4%; line-gap-override: 0%; }
@property --ds-shine { syntax: "<percentage>"; inherits: false; initial-value: -60%; }

@layer ds.tokens {
  :root {
    /* ---- fluid type: 1.2 ratio at 320px growing to 1.25 at 1440px ---- */
    --ds-font-display: var(--font-display, "Fredoka"), "BPP Display Fallback", ui-rounded, system-ui, sans-serif;
    --ds-font-body: var(--font-body, "Nunito"), "BPP Body Fallback", system-ui, -apple-system, "Segoe UI", sans-serif;
    --ds-step--1: clamp(0.83rem, 0.81rem + 0.11vw, 0.9rem);
    --ds-step-0: clamp(1rem, 0.97rem + 0.18vw, 1.125rem);
    --ds-step-1: clamp(1.2rem, 1.14rem + 0.3vw, 1.41rem);
    --ds-step-2: clamp(1.44rem, 1.34rem + 0.49vw, 1.76rem);
    --ds-step-3: clamp(1.73rem, 1.57rem + 0.78vw, 2.2rem);
    --ds-step-4: clamp(2.07rem, 1.83rem + 1.2vw, 2.75rem);
    --ds-step-5: clamp(2.49rem, 2.12rem + 1.83vw, 3.43rem);
    --ds-step-6: clamp(2.99rem, 2.45rem + 2.7vw, 4.29rem);
    --ds-leading-tight: 1.12; --ds-leading: 1.5; --ds-measure: 66ch; --ds-measure-narrow: 46ch;

    /* ---- space: a 4px grid, plus fluid steps for page rhythm ---- */
    --ds-space-1: 4px; --ds-space-2: 8px; --ds-space-3: 12px; --ds-space-4: 16px; --ds-space-5: 20px;
    --ds-space-6: 24px; --ds-space-8: 32px; --ds-space-10: 40px; --ds-space-12: 48px; --ds-space-16: 64px;
    --ds-space-s: clamp(12px, 0.6rem + 0.6vw, 16px);
    --ds-space-m: clamp(16px, 0.8rem + 1.1vw, 28px);
    --ds-space-l: clamp(24px, 1rem + 2.4vw, 48px);
    --ds-space-xl: clamp(40px, 1.5rem + 4.8vw, 96px);
    --ds-gutter: max(16px, env(safe-area-inset-left, 0px), env(safe-area-inset-right, 0px));
    --ds-page-max: 1180px;

    /* ---- shape ---- */
    --ds-radius-xs: 6px; --ds-radius-sm: 10px; --ds-radius-md: 14px; --ds-radius-lg: 22px; --ds-radius-xl: 32px; --ds-radius-pill: 999px;

    /* ---- elevation: layered, tinted shadows (ambient + key light) ---- */
    --ds-shadow-color: 265 60% 18%;
    --ds-shadow-1: 0 1px 2px hsl(var(--ds-shadow-color) / .10), 0 2px 6px hsl(var(--ds-shadow-color) / .08);
    --ds-shadow-2: 0 2px 4px hsl(var(--ds-shadow-color) / .08), 0 8px 20px hsl(var(--ds-shadow-color) / .12);
    --ds-shadow-3: 0 4px 8px hsl(var(--ds-shadow-color) / .08), 0 16px 36px hsl(var(--ds-shadow-color) / .16);
    --ds-shadow-4: 0 8px 16px hsl(var(--ds-shadow-color) / .10), 0 28px 64px hsl(var(--ds-shadow-color) / .24);
    --ds-shadow-press: 0 3px 0 hsl(var(--ds-shadow-color) / .22);
    --ds-ring: 0 0 0 3px var(--ds-focus);

    /* ---- motion: durations and easings (springs via linear(), cubic-bezier fallback) ---- */
    --ds-dur-instant: 90ms; --ds-dur-fast: 160ms; --ds-dur-base: 240ms; --ds-dur-slow: 400ms; --ds-dur-slower: 640ms;
    --ds-dur-spring: 820ms; --ds-dur-bounce: 1150ms; --ds-dur-celebrate: 1400ms;
    --ds-stagger: 55ms;
    --ds-ease-out: cubic-bezier(.2, .8, .2, 1);
    --ds-ease-in: cubic-bezier(.4, 0, 1, .6);
    --ds-ease-in-out: cubic-bezier(.65, 0, .35, 1);
    --ds-ease-emph: cubic-bezier(.05, .7, .1, 1);
    --ds-spring: cubic-bezier(.34, 1.4, .64, 1);
    --ds-spring-bouncy: cubic-bezier(.34, 1.7, .5, 1);
    --ds-spring-snappy: cubic-bezier(.3, 1.3, .6, 1);

    /* ---- layers and sizes ---- */
    --ds-z-sticky: 20; --ds-z-tabbar: 40; --ds-z-sheet: 80; --ds-z-particles: 95; --ds-z-toast: 110; --ds-z-moment: 210;
    --ds-tap: 44px;
    --ds-vh: 100vh;
    --ds-safe-top: env(safe-area-inset-top, 0px); --ds-safe-bottom: env(safe-area-inset-bottom, 0px);
    --ds-safe-left: env(safe-area-inset-left, 0px); --ds-safe-right: env(safe-area-inset-right, 0px);
    --ds-tabbar-h: calc(64px + var(--ds-safe-bottom));
  }
  @supports (height: 100dvh) { :root { --ds-vh: 100dvh; } }
  /* Real springs where linear() exists (sampled from mass 1; see DESIGN_SYSTEM.md "Easing"). */
  @supports (transition-timing-function: linear(0, 1)) {
    :root {
      /* stiffness 120, damping 17: settles in ~810ms, 2% overshoot. UI default. */
      --ds-spring: linear(0, 0.057, 0.186, 0.343, 0.499, 0.639, 0.755, 0.845, 0.912, 0.959, 0.989, 1.008, 1.017, 1.021, 1.021, 1.018, 1.015, 1.012, 1.009, 1.006, 1.004, 1.002, 1.001, 1);
      /* stiffness 170, damping 12: ~1150ms, 19% overshoot. Kid moments only. */
      --ds-spring-bouncy: linear(0, 0.062, 0.217, 0.418, 0.629, 0.822, 0.98, 1.094, 1.164, 1.194, 1.192, 1.168, 1.132, 1.09, 1.05, 1.016, 0.99, 0.973, 0.964, 0.962, 0.965, 0.971, 0.979, 0.987, 0.994, 1, 1.004, 1.007, 1.008, 1.007, 1.005, 1.003, 1.001, 1);
      /* stiffness 380, damping 26: ~530ms, 6% overshoot. Presses, toggles, chips. */
      --ds-spring-snappy: linear(0, 0.089, 0.284, 0.504, 0.701, 0.855, 0.96, 1.023, 1.053, 1.06, 1.054, 1.042, 1.029, 1.017, 1.008, 1.002, 0.998, 0.997, 0.996, 0.997, 0.998, 1);
    }
  }
  /* Reduced motion: durations collapse, distances go to zero; opacity fades stay (they don't move). */
  @media (prefers-reduced-motion: reduce) {
    :root { --ds-dur-spring: var(--ds-dur-fast); --ds-dur-bounce: var(--ds-dur-fast); --ds-dur-celebrate: var(--ds-dur-fast); --ds-dur-slow: var(--ds-dur-fast); --ds-dur-slower: var(--ds-dur-fast); --ds-stagger: 0ms;
      --ds-spring: ease-out; --ds-spring-bouncy: ease-out; --ds-spring-snappy: ease-out; }
  }
}

@layer ds.base {
  /* Pages that opt in with class="ds" on <html> or <body> get the full base; the rest only get
     the harmless global fixes below. */
  :where(html) { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
  /* iOS Safari zooms into any input under 16px: never let one be smaller. */
  :where(input, select, textarea) { font-size: max(16px, 1em); }
  :where(.ds) { font-family: var(--ds-font-body); line-height: var(--ds-leading); color: var(--ds-ink); background: var(--ds-bg); -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility; }
  :where(.ds) :where(h1, h2, h3, h4) { font-family: var(--ds-font-display); line-height: var(--ds-leading-tight); text-wrap: balance; margin: 0 0 .4em; }
  :where(.ds) :where(h1) { font-size: var(--ds-step-5); }
  :where(.ds) :where(h2) { font-size: var(--ds-step-3); }
  :where(.ds) :where(h3) { font-size: var(--ds-step-1); }
  :where(.ds) :where(p, li) { text-wrap: pretty; }
  :where(.ds) :where(:focus-visible) { outline: 3px solid var(--ds-focus); outline-offset: 2px; }
  :where(.ds) :where(img, svg, video, canvas) { max-width: 100%; height: auto; }
  :where(.ds) :where(button, input, select, textarea) { font: inherit; color: inherit; }
  :where(.ds) :where(input, select, textarea) { font-size: max(16px, 1em); }
  .ds-tnum { font-variant-numeric: tabular-nums; }
  .ds-prose { max-inline-size: var(--ds-measure); }
  .ds-prose > * + * { margin-block-start: 1em; }
  .ds-container { inline-size: min(100% - 2 * var(--ds-gutter), var(--ds-page-max)); margin-inline: auto; }
  .ds-stack { display: flex; flex-direction: column; gap: var(--ds-gap, var(--ds-space-4)); }
  .ds-cluster { display: flex; flex-wrap: wrap; align-items: center; gap: var(--ds-gap, var(--ds-space-2)); }
  .ds-grid { display: grid; gap: var(--ds-gap, var(--ds-space-4)); grid-template-columns: repeat(auto-fill, minmax(min(100%, var(--ds-min, 240px)), 1fr)); }
  .ds-sr-only { position: absolute; inline-size: 1px; block-size: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
  /* Long pages: skip rendering offscreen sections (sized so the scrollbar doesn't jump). */
  .ds-cv { content-visibility: auto; contain-intrinsic-size: auto var(--ds-cv-size, 600px); }
}
