/* =========================================================
   FGB — Motion system
   Reveals, masked headlines, page-transition curtain, scroll progress. All reduced-motion gated. Paired JS: assets/js/main.js + motion.js.
   Architecture: tokens → base → motion → page. Each page loads
   exactly four stylesheets in that order.
   ========================================================= */

/* Hidden start states apply only when JS runs (html.js is set by the inline head script):
   without JS, or if a script fails, content stays visible. Audit 2026-10-02. */
.js [data-reveal] {
  opacity: 0;
  transform: translateY(22px);
  transition: opacity .7s var(--ease-out), transform .75s var(--ease-out);
  transition-delay: var(--delay, 0ms);
}

[data-reveal].is-in {
  opacity: 1; transform: translateY(0);
}

[data-reveal="fade"] { transform: none; }

.js h1[data-reveal], .js h2[data-reveal] {
  opacity: 0;
  transform: translateY(38px);
}

h1[data-reveal].is-in, h2[data-reveal].is-in {
  opacity: 1;
  transform: translateY(0);
  animation: headMask .95s var(--ease-in-out) var(--delay, 0ms) both;
}

.reveal-line-wrapper {
  overflow: hidden;
  display: inline-block;
  vertical-align: top;
}

.reveal-text {
  display: inline-block;
}

.js .reveal-text {
  transform: translateY(100%);
}

@media (prefers-reduced-motion: reduce) {
  .reveal-text {transform: translateY(0) !important }
  [data-reveal] {opacity: 1 !important; transform: none !important }
}

[data-split]:not(.hero__title) .word {
  display: inline-block;
  white-space: nowrap;
}

[data-split]:not(.hero__title) .ch {
  display: inline-block;
  opacity: 0;
  transform: translateY(0.45em);
  animation: chReveal 0.8s cubic-bezier(0.2, 0.8, 0.2, 1) forwards;
  animation-delay: calc(var(--i, 0) * 16ms + 120ms);
}

.pt-curtain {
  position: fixed;
  inset: 0;
  z-index: 10000;
  background: var(--ink);
  transform: translateY(101%);
  pointer-events: none;
  display: flex;
  align-items: center;
  justify-content: center;
}

.pt-curtain::before {
  /* bronze hairline that leads the wipe */
  content: "";
  position: absolute;
  top: -1px; left: 0; right: 0;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--bronze-600) 30%, var(--bronze-600) 70%, transparent);
}

.pt-curtain__mark {
  font-family: var(--serif);
  font-style: italic;
  font-weight: 500;
  font-size: clamp(20px, 2.4vw, 30px);
  color: var(--bronze-600);
  letter-spacing: 0.04em;
  opacity: 0;
  transform: translateY(14px);
}

.pt-curtain.is-out {
  transform: translateY(0%);
  transition: transform .4s cubic-bezier(.76, 0, .24, 1);
}

.pt-curtain.is-out .pt-curtain__mark {
  opacity: 1;
  transform: translateY(0);
  transition: opacity .3s ease .18s, transform .4s var(--ease-out) .18s;
}

.pt-curtain.is-in {
  transform: translateY(0%);
}

.pt-curtain.is-in.is-lift {
  transform: translateY(-101%);
  transition: transform .55s cubic-bezier(.76, 0, .24, 1);
}

body.pt-entering main, body.pt-entering .footer {
  animation: ptSettle 0.65s var(--ease-out) .08s backwards;
}

[data-plx-bound] { overflow: hidden; position: relative; }

[data-plx-bound] picture {
  position: absolute;
  top: -6%; bottom: -6%;
  left: 0; right: 0;
}

[data-plx-bound] picture img { width: 100%; height: 100%; object-fit: cover; }

@media (prefers-reduced-motion: reduce) {
  .pt-curtain {display: none !important }
  h1[data-reveal], h2[data-reveal] {clip-path: none !important }
  body.pt-entering main, body.pt-entering .footer {animation: none !important }
}

.scroll-progress {
  position: fixed;
  top: 0; left: 0; right: 0;
  height: var(--scroll-progress-height);
  z-index: calc(var(--z-nav) + 2);
  pointer-events: none;
}

.scroll-progress span {
  display: block; height: 100%;
  background: var(--bronze);
  transform-origin: left center;
  transform: scaleX(0);
}

@media (prefers-reduced-motion: reduce) {
  .scroll-progress {display: none !important }
}

html.pt-pending body::after {
  content: "";
  position: fixed;
  inset: 0;
  background: var(--ink);
  z-index: 9999;
}

@keyframes headMask {
  from { clip-path: inset(-5% -6% 102% -6%); transform: translateY(38px); }
  to   { clip-path: inset(-15% -8% -25% -8%); transform: translateY(0); }
}

@keyframes chReveal {
  to { opacity: 1; transform: translateY(0); }
}

@keyframes ptSettle {
  from { opacity: 0; transform: translateY(16px); }
  to   { opacity: 1; transform: translateY(0); }
}

@keyframes chReveal {
  to { opacity: 1; transform: translateY(0); }
}

/* Lenis runtime classes (added by the library, not present in markup) */
html.lenis, html.lenis body { height: auto; }
.lenis.lenis-smooth { scroll-behavior: auto !important; }
.lenis.lenis-smooth [data-lenis-prevent] { overscroll-behavior: contain; }
.lenis.lenis-stopped { overflow: hidden; }
.lenis.lenis-smooth iframe { pointer-events: none; }

/* Split-text chars are JS-created — guard them under reduced motion */
@media (prefers-reduced-motion: reduce) {
  [data-split] .ch { opacity: 1 !important; transform: none !important; animation: none !important; }
}
