/* =====================================================================
   MOTION SYSTEM — The Bordewick Atelier
   Shared across all pages. CSS-native, luxury-restrained, CLS-safe.
   Reveals use opacity + clip-path + filter only — never translateY on
   scroll-triggered elements. Hover states use --transition-interactive.
   ===================================================================== */

:root {
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);
  --stagger-step: 55ms;
}

/* ---------------------------------------------------------------------
   0. Reduced motion — hard override, always wins
   --------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .reveal,
  .reveal-up,
  .reveal-clip,
  .fade-in,
  .hero__title,
  .hero__eyebrow,
  .hero__subtitle,
  .hero__actions,
  .hero__stats,
  .hero__name,
  .hero__press,
  .course-hero .hero-kicker,
  .course-hero h1,
  .course-hero .lead,
  .course-hero .course-proof,
  body > section:first-of-type > .container > .section__eyebrow:first-child,
  body > section:first-of-type > .container > h1.section__title,
  [data-parallax],
  [data-parallax-inner] {
    opacity: 1 !important;
    clip-path: none !important;
    filter: none !important;
    transform: none !important;
    animation: none !important;
    transition: none !important;
  }
}

/* ---------------------------------------------------------------------
   1. Legacy .fade-in — upgraded to CLS-safe (opacity + clip-path only)
   The site already used .fade-in with translateY(24px). We replace the
   mechanism so the element occupies its final box from first paint —
   no layout shift — while preserving the class name so no markup
   changes are required across the 7 pages.
   --------------------------------------------------------------------- */
.fade-in {
  opacity: 0;
  clip-path: inset(0 0 12% 0); /* masked from bottom, no box movement */
  transform: none;
  transition: opacity 700ms var(--ease-out), clip-path 700ms var(--ease-out), filter 700ms var(--ease-out);
  will-change: opacity, clip-path;
}
.fade-in.visible {
  opacity: 1;
  clip-path: inset(0 0 0% 0);
}
.fade-in-delay-1 { transition-delay: 90ms; }
.fade-in-delay-2 { transition-delay: 160ms; }
.fade-in-delay-3 { transition-delay: 230ms; }
.fade-in-delay-4 { transition-delay: 300ms; }

/* Native scroll-driven fallback/enhancement for browsers that support it.
   Progressive enhancement only — JS IntersectionObserver remains the
   primary mechanism for correctness across all browsers. */
@supports (animation-timeline: scroll()) {
  .reveal {
    opacity: 1;
  }
}

/* ---------------------------------------------------------------------
   2. Hero entrance choreography (page-load, not scroll-triggered)
   Staggered reveal of eyebrow -> name -> title -> subtitle -> press
   badges -> actions -> stats. Runs once on load via animation, not IO,
   since it must fire immediately without requiring scroll.
   --------------------------------------------------------------------- */
.hero__eyebrow,
.hero__name,
.hero__title,
.hero__subtitle,
.hero__press,
.hero__actions,
.hero__stats {
  opacity: 0;
  clip-path: inset(0 0 30% 0);
  animation: hero-enter 900ms var(--ease-out) both;
}
.hero__eyebrow  { animation-delay: 60ms; }
.hero__name     { animation-delay: 120ms; }
.hero__title    { animation-delay: 180ms; }
.hero__subtitle { animation-delay: 320ms; }
.hero__press    { animation-delay: 420ms; }
.hero__actions  { animation-delay: 500ms; }
.hero__stats    { animation-delay: 580ms; }

@keyframes hero-enter {
  to {
    opacity: 1;
    clip-path: inset(0 0 0% 0);
  }
}

/* Hero photo: gentle scale-in + fade, independent of the copy timing */
.hero__right img,
.about-photo-main img {
  animation: hero-photo-enter 1200ms var(--ease-out) both;
  animation-delay: 100ms;
}
@keyframes hero-photo-enter {
  from { opacity: 0; transform: scale(1.04); }
  to   { opacity: 1; transform: scale(1); }
}

/* 2b. Course page hero — different markup (.course-hero), same choreography */
.course-hero .hero-kicker,
.course-hero h1,
.course-hero .lead,
.course-hero .course-proof {
  opacity: 0;
  clip-path: inset(0 0 30% 0);
  animation: hero-enter 900ms var(--ease-out) both;
}
.course-hero .hero-kicker  { animation-delay: 60ms; }
.course-hero h1            { animation-delay: 160ms; }
.course-hero .lead         { animation-delay: 280ms; }
.course-hero .course-proof { animation-delay: 400ms; }

/* 2c. Simple page headers (legal pages, journal index) — light entrance
   for the eyebrow + H1 pair even without the .fade-in class, so every
   page feels considered on load, not just the homepage. */
body > section:first-of-type > .container > .section__eyebrow:first-child,
body > section:first-of-type > .container > h1.section__title {
  opacity: 0;
  clip-path: inset(0 0 30% 0);
  animation: hero-enter 800ms var(--ease-out) both;
}
body > section:first-of-type > .container > .section__eyebrow:first-child { animation-delay: 60ms; }
body > section:first-of-type > .container > h1.section__title { animation-delay: 150ms; }

/* ---------------------------------------------------------------------
   3. Nav — shrinks + gains shadow/blur on scroll (JS toggles .nav--scrolled)
   --------------------------------------------------------------------- */
.nav {
  transition: background 300ms var(--ease-in-out), box-shadow 300ms var(--ease-in-out),
              padding-block 300ms var(--ease-in-out), backdrop-filter 300ms var(--ease-in-out);
}
.nav--scrolled {
  padding-block: var(--space-3, 0.75rem);
  background: color-mix(in oklab, var(--color-bg), transparent 4%);
  box-shadow: 0 4px 24px rgba(0, 0, 0, 0.08);
  backdrop-filter: blur(24px);
  -webkit-backdrop-filter: blur(24px);
}
[data-theme='dark'] .nav--scrolled {
  box-shadow: 0 4px 24px rgba(0, 0, 0, 0.35);
}

/* ---------------------------------------------------------------------
   4. Nav link underline animation
   --------------------------------------------------------------------- */
.nav__links a {
  position: relative;
  background-image: linear-gradient(var(--color-primary), var(--color-primary));
  background-repeat: no-repeat;
  background-position: left bottom;
  background-size: 0% 1px;
  transition: background-size var(--transition-interactive, 180ms cubic-bezier(0.16,1,0.3,1)), color var(--transition-interactive, 180ms cubic-bezier(0.16,1,0.3,1));
  padding-bottom: 2px;
}
.nav__links a:hover {
  background-size: 100% 1px;
}

/* Generic underline-on-hover utility for inline text links inside copy */
.footer__links a,
.media-logo {
  transition: color var(--transition-interactive, 180ms cubic-bezier(0.16,1,0.3,1));
}

/* ---------------------------------------------------------------------
   5. Card lift + shadow on hover (cards not already covered in style.css)
   --------------------------------------------------------------------- */
.step-card,
.credential-row,
.press-card,
.office-pill,
.kenneth-quote-card,
.hero__press-badge {
  transition: transform var(--transition-interactive, 180ms cubic-bezier(0.16,1,0.3,1)),
              box-shadow var(--transition-interactive, 180ms cubic-bezier(0.16,1,0.3,1)),
              border-color var(--transition-interactive, 180ms cubic-bezier(0.16,1,0.3,1));
}
.step-card:hover {
  transform: translateY(-4px);
  box-shadow: var(--shadow-md);
  border-color: var(--color-primary);
}
.press-card:hover {
  transform: translateY(-3px);
  box-shadow: var(--shadow-md);
}
.office-pill:hover {
  transform: translateY(-2px);
  border-color: var(--color-primary);
}

/* ---------------------------------------------------------------------
   6. Buttons — refine press/scale feedback beyond base style.css
   --------------------------------------------------------------------- */
.btn {
  transition:
    background var(--transition-interactive, 180ms cubic-bezier(0.16,1,0.3,1)),
    color var(--transition-interactive, 180ms cubic-bezier(0.16,1,0.3,1)),
    border-color var(--transition-interactive, 180ms cubic-bezier(0.16,1,0.3,1)),
    box-shadow var(--transition-interactive, 180ms cubic-bezier(0.16,1,0.3,1)),
    transform 150ms var(--ease-out);
}
.btn:active {
  transform: translateY(0) scale(0.98);
}

/* ---------------------------------------------------------------------
   7. Parallax wrapper — transform applied to an inner element only, so
   sibling layout never shifts. JS updates --parallax-y per element.
   --------------------------------------------------------------------- */
[data-parallax] {
  overflow: hidden;
}
[data-parallax-inner] {
  transform: translateY(var(--parallax-y, 0px)) scale(var(--parallax-scale, 1));
  transition: transform 60ms linear;
  will-change: transform;
  /* Fill the parallax wrapper exactly so nested media keeps its
     original sizing/positioning — the parallax effect is purely
     visual and never changes the box any sibling lays out against. */
  width: 100%;
  height: 100%;
}
.hero__right [data-parallax-inner] img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center top;
}

/* ---------------------------------------------------------------------
   8. Ambient motion — restrained, continuous, decorative only
   Slow breathing glow behind the hero eyebrow mark + quote mark.
   --------------------------------------------------------------------- */
@keyframes ambient-breathe {
  0%, 100% { opacity: 0.7; transform: scale(1); }
  50%      { opacity: 1;   transform: scale(1.06); }
}
.hero__eyebrow::before {
  animation: ambient-glow 4.5s var(--ease-in-out) infinite;
}
@keyframes ambient-glow {
  0%, 100% { opacity: 0.55; }
  50%      { opacity: 1; }
}
.quote-mark {
  animation: ambient-breathe 6s var(--ease-in-out) infinite;
  transform-origin: center;
  display: inline-block;
}

/* Slow ambient gradient drift on the hero right-panel overlay, if present */
.hero__right::before {
  background-size: 200% 200%;
  animation: ambient-gradient-shift 14s ease-in-out infinite;
}
@keyframes ambient-gradient-shift {
  0%, 100% { background-position: 0% 50%; }
  50%      { background-position: 100% 50%; }
}

/* ---------------------------------------------------------------------
   9. Media logo + affiliate hover polish (color shift already present;
   add subtle lift here for consistency)
   --------------------------------------------------------------------- */
.media-logo:hover {
  transform: translateY(-1px);
}

/* ---------------------------------------------------------------------
   10. Stat counters — ensure no CLS while counting (fixed min-width via
   tabular numerals) and a soft entrance for the whole stat block.
   --------------------------------------------------------------------- */
[data-count] {
  font-variant-numeric: tabular-nums;
}

/* ---------------------------------------------------------------------
   11. Section dividers — subtle draw-in when scrolled into view
   --------------------------------------------------------------------- */
.divider {
  transform-origin: center;
}

/* ---------------------------------------------------------------------
   12. Smooth scroll handled by html { scroll-behavior: smooth } already
   present in style.css — keep as the single source of truth.
   --------------------------------------------------------------------- */

/* ---------------------------------------------------------------------
   13. No-JS safety net. Every page sets `document.documentElement.
   classList.add('js')` in a tiny inline script at the top of <head>
   (executes synchronously, before CSS paints meaningfully). If JS is
   disabled/blocked, <html> never gets the .js class, and this rule
   forces every scroll/entrance-animated element to full visibility so
   content is never permanently hidden. .fade-in relies on JS
   (IntersectionObserver) to add .visible — this is the fallback for
   when that JS never runs.
   --------------------------------------------------------------------- */
html:not(.js) .fade-in,
html:not(.js) .hero__eyebrow,
html:not(.js) .hero__name,
html:not(.js) .hero__title,
html:not(.js) .hero__subtitle,
html:not(.js) .hero__press,
html:not(.js) .hero__actions,
html:not(.js) .hero__stats,
html:not(.js) .hero__right img,
html:not(.js) .about-photo-main img,
html:not(.js) .course-hero .hero-kicker,
html:not(.js) .course-hero h1,
html:not(.js) .course-hero .lead,
html:not(.js) .course-hero .course-proof,
html:not(.js) body > section:first-of-type > .container > .section__eyebrow:first-child,
html:not(.js) body > section:first-of-type > .container > h1.section__title {
  opacity: 1 !important;
  clip-path: none !important;
  animation: none !important;
  transform: none !important;
}
