/* =========================================================================
   TriggerMotion floor + demo styling  (build: tm-spa, from-scratch)
   Two tiers. Tier 0 = native CSS scroll-driven (reveal, simple parallax).
   Tier 1 = GSAP/ScrollTrigger (stack, snap, trail, magnetic, hover).
   Master switch = html.tm-active. Reduced-motion = one place. FOIC-safe.
   ========================================================================= */

/* ---------- tokens ---------- */
:root{
  --bg:#f4f1ea; --surface:#ffffff; --surface-2:#efe9df;
  --ink:#211e19; --muted:#6d675d; --line:#ddd5c7;
  --sage:#7f8c6b; --sage-deep:#5f6b4e; --stone:#b7a68c; --clay:#a9825f;
  --shadow:0 18px 50px -22px rgba(40,34,24,.45);
  --radius:14px; --maxw:1180px;
  --serif:"Cormorant Garamond","Iowan Old Style","Palatino Linotype",Georgia,serif;
  --display:"Cinzel","Cormorant Garamond",Georgia,serif;
  --sans:"Inter",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
}

*{box-sizing:border-box}
html{overflow-x:clip; -webkit-text-size-adjust:100%; scroll-behavior:smooth}
body{
  margin:0; background:var(--bg); color:var(--ink);
  font-family:var(--sans); font-size:17px; line-height:1.65;
  -webkit-font-smoothing:antialiased;
}
img{max-width:100%; display:block}
h1,h2,h3{font-family:var(--serif); font-weight:600; line-height:1.06; margin:0}
h1,h2{font-family:var(--display); text-transform:uppercase}
h1{font-size:clamp(2.6rem,6.4vw,5rem); letter-spacing:.03em; line-height:1.04}
h2{font-size:clamp(1.9rem,4.2vw,3.2rem); letter-spacing:.04em; line-height:1.1}
h3{font-size:clamp(1.3rem,2.4vw,1.7rem)}
p{margin:0 0 1em}
a{color:inherit}
.eyebrow{font-family:var(--sans); text-transform:uppercase; letter-spacing:.32em;
  font-size:.72rem; font-weight:600; color:var(--sage-deep)}
.lead{font-size:1.2rem; color:var(--muted); max-width:60ch}
.wrap{max-width:var(--maxw); margin-inline:auto; padding-inline:clamp(20px,5vw,48px)}
section{position:relative}
.section-pad{padding-block:clamp(60px,10vh,116px)}
.center{text-align:center; margin-inline:auto}
.muted{color:var(--muted)}

/* ============================ FLOOR: TIER 0 (CSS) ======================== */
/* Blur-in reveal. FOIC rule: the element is fully visible by default.
   The hidden 'from' state is applied ONLY when the browser supports
   scroll-driven animation AND the master switch html.tm-active is present.
   No JS, no library -> if either is absent, content simply shows, static. */
@supports (animation-timeline: view()){
  html.tm-active .tm-reveal{
    opacity:0;
    animation:tm-reveal-in linear both;
    animation-timeline:view();
    animation-range:entry calc(3% + (var(--tm-i,0) * 7%)) cover 40%;
  }
}
@keyframes tm-reveal-in{
  from{opacity:0; transform:translateY(32px); filter:blur(14px)}
  to  {opacity:1; transform:none;             filter:blur(0)}
}

/* Simple parallax. Frame clips; image is overscanned (taller than frame)
   so vertical travel never exposes an edge (Image Contract: overscan >= |travel|). */
.tm-parallax{position:relative; overflow:clip; border-radius:var(--radius)}
.tm-parallax__img{
  position:absolute; left:0; width:100%;
  top:-20%; height:140%;              /* +/-20% overscan (covers +/-16% travel) */
  object-fit:cover; will-change:transform;
}
@supports (animation-timeline: view()){
  html.tm-active .tm-parallax__img{
    animation:tm-parallax-move linear both;
    animation-timeline:view();
    animation-range:cover 0% cover 55%;
  }
}
@keyframes tm-parallax-move{
  from{transform:translateY(-16%)}
  to  {transform:translateY(16%)}
}

/* ===================== REDUCED-MOTION MASTER SWITCH ====================== */
/* One place. If the user prefers reduced motion, every engine collapses to
   its natural, visible, static state -- Tier 0 (here) and Tier 1 (JS never
   inits / is killed). Nothing is left parked at opacity:0 waiting on scroll. */
@media (prefers-reduced-motion: reduce){
  html .tm-reveal{opacity:1 !important; animation:none !important;
    transform:none !important; filter:none !important}
  html .tm-parallax__img{animation:none !important; transform:none !important;
    top:0; height:100%}
  html .tm-trail__img{display:none !important}
  .tm-magnetic{transform:none !important}
}

/* ============================ ENGINE: STACK ============================== */
/* Pinned scale-stack. Container is tall (scroll room, G4); an inner viewport
   is pinned by ScrollTrigger; cards are absolutely stacked and centered. */
.tm-stack{position:relative}
.tm-stack__viewport{height:100vh; display:grid; place-items:center; overflow:hidden; position:relative}
.tm-stack__card{
  grid-area:1 / 1; align-self:center; justify-self:center;
  width:min(760px,86vw); background:var(--surface);
  border-radius:var(--radius); box-shadow:var(--shadow); overflow:hidden;
  will-change:transform,opacity;
}
.tm-stack__card img{width:100%; aspect-ratio:16/9; object-fit:cover}
.tm-stack__body{padding:18px 24px 20px}
.tm-stack__body .eyebrow{margin-bottom:6px}
.tm-stack__body p:last-child{margin-bottom:0}
.tm-stack__body h3{margin-bottom:.25em}
/* FOIC: with no JS the cards fan out into a readable static column */
.tm-stack--static .tm-stack__viewport{height:auto; display:block}
.tm-stack--static .tm-stack__card{grid-area:auto; margin:0 auto 26px}

/* ============================ ENGINE: SNAP =============================== */
.tm-snap{position:relative}
.tm-snap__viewport{height:100vh; position:relative; overflow:hidden; border-radius:0}
.tm-snap__frame{position:absolute; inset:0; opacity:0; will-change:opacity}
.tm-snap__frame:first-child{opacity:1}
.tm-snap__frame img{width:100%; height:100%; object-fit:cover}
.tm-snap__cap{position:absolute; left:0; right:0; bottom:0; padding:40px clamp(20px,6vw,70px);
  background:linear-gradient(transparent,rgba(20,16,10,.72)); color:#fff}
.tm-snap__cap h3{color:#fff}
.tm-snap__dots{position:absolute; top:50%; right:22px; transform:translateY(-50%);
  display:flex; flex-direction:column; gap:10px; z-index:3}
.tm-snap__dots i{width:9px; height:9px; border-radius:50%; background:rgba(255,255,255,.45); transition:.3s}
.tm-snap__dots i.on{background:#fff; transform:scale(1.35)}
/* FOIC static: frames stack readable */
.tm-snap--static .tm-snap__viewport{height:auto}
.tm-snap--static .tm-snap__frame{position:relative; opacity:1; height:56vh}
.tm-snap--static .tm-snap__dots{display:none}

/* ============================ ENGINE: TRAIL ============================= */
.tm-trail{position:relative; height:82vh; min-height:520px; display:grid; place-items:center;
  overflow:hidden; background:#1b1712; color:#fff; cursor:crosshair}
.tm-trail__bg{position:absolute; inset:0; opacity:.34}
.tm-trail__bg img{width:100%; height:100%; object-fit:cover}
.tm-trail__hd{position:relative; z-index:4; text-align:center; padding:20px; pointer-events:none}
.tm-trail__hd h1{color:#fff}
.tm-trail__img{position:absolute; top:0; left:0; width:150px; height:150px;
  object-fit:cover; border-radius:10px; opacity:0; pointer-events:none;
  box-shadow:0 12px 30px rgba(0,0,0,.4); will-change:transform,opacity}
/* touch fallback -> static grid of the trail images */
.tm-trail--static{cursor:default}
.tm-trail--static .tm-trail__img{position:relative; opacity:1; width:100%; height:auto;
  aspect-ratio:1; display:block}
.tm-trail--static .tm-trail__grid{position:relative; z-index:4;
  display:grid; grid-template-columns:repeat(5,1fr); gap:10px; padding:24px; width:min(900px,92vw)}
.tm-trail__grid{display:contents}

/* ========================= ENGINE: HOVER-REVEAL ========================= */
.tm-hover-grid{display:grid; grid-template-columns:repeat(auto-fit,minmax(240px,1fr)); gap:20px}
.tm-hover{position:relative; border-radius:var(--radius); overflow:hidden; aspect-ratio:3/4;
  box-shadow:var(--shadow)}
.tm-hover img{width:100%; height:100%; object-fit:cover}
.tm-hover__cover{position:absolute; inset:0; background:var(--sage-deep); color:#fff;
  display:flex; flex-direction:column; justify-content:flex-end; padding:22px;
  clip-path:inset(0 0 0 0); transition:clip-path .55s cubic-bezier(.7,0,.2,1)}
.tm-hover__cover h3{color:#fff}
html.tm-active .tm-hover:hover .tm-hover__cover,
html.tm-active .tm-hover.is-open .tm-hover__cover{clip-path:inset(0 0 100% 0)}
.tm-hover__peek{position:absolute; left:22px; bottom:22px; color:#fff; z-index:2;
  font-family:var(--serif); font-size:1.4rem; opacity:0; transition:.4s}
html.tm-active .tm-hover:hover .tm-hover__peek,
html.tm-active .tm-hover.is-open .tm-hover__peek{opacity:1}

/* ============================ ENGINE: MAGNETIC ========================== */
.btn{display:inline-flex; align-items:center; gap:.5em; border:0; cursor:pointer;
  font-family:var(--sans); font-weight:600; font-size:1rem; letter-spacing:.01em;
  padding:15px 30px; border-radius:100px; background:var(--ink); color:#fff;
  text-decoration:none; transition:background .3s}
.btn--ghost{background:transparent; color:var(--ink); box-shadow:inset 0 0 0 1.5px var(--line)}
.btn--sage{background:var(--sage-deep)}
.tm-magnetic{will-change:transform}

/* ============================ demo chrome =============================== */
.hero-sub{max-width:52ch; color:rgba(255,255,255,.85); margin-top:14px}
.grid-3{display:grid; grid-template-columns:repeat(auto-fit,minmax(230px,1fr)); gap:22px}
.card{background:var(--surface); border-radius:var(--radius); overflow:hidden; box-shadow:var(--shadow)}
.card img{width:100%; aspect-ratio:3/2; object-fit:cover}
.card__b{padding:18px 20px 22px}
.split{display:grid; grid-template-columns:1fr 1fr; gap:clamp(24px,5vw,64px); align-items:center}
@media(max-width:820px){.split{grid-template-columns:1fr}}
.para-frame{aspect-ratio:16/10}
.filterbar{display:flex; gap:10px; flex-wrap:wrap; justify-content:center; margin-bottom:26px}
.chip{border:1.5px solid var(--line); background:transparent; border-radius:100px;
  padding:8px 18px; font-family:var(--sans); font-weight:600; font-size:.85rem; cursor:pointer;
  color:var(--muted); transition:.25s}
.chip.on{background:var(--ink); color:#fff; border-color:var(--ink)}
footer{background:var(--ink); color:#d8d2c6; padding-block:60px}
footer a{color:#fff}

/* ===================== control panel + gate probe ====================== */
.tm-panel{position:fixed; right:16px; bottom:16px; z-index:9999;
  background:rgba(24,20,16,.94); color:#fff; border-radius:12px; padding:12px 14px;
  font-family:var(--sans); font-size:12.5px; width:250px; box-shadow:0 14px 40px rgba(0,0,0,.4)}
.tm-panel h4{margin:0 0 8px; font-family:var(--sans); font-size:12.5px; letter-spacing:.14em;
  text-transform:uppercase; color:#c9c2b4}
.tm-panel button{width:100%; margin:4px 0; padding:8px; border:0; border-radius:8px; cursor:pointer;
  font-weight:600; background:#3a332a; color:#fff}
.tm-panel button.primary{background:var(--sage)}
.tm-panel .row{display:flex; gap:8px}
.tm-panel .row button{margin:4px 0}
.tm-panel pre{margin:8px 0 0; padding:8px; background:#0f0c09; border-radius:8px;
  font-size:11px; line-height:1.5; white-space:pre-wrap; max-height:190px; overflow:auto}
.tm-panel .k{color:#9fd0a0}
.tm-panel .b{color:#e8c07d}/* ====================== ENGINE 7: HORIZONTAL PINNED TRACK ================ */
.tm-htrack{height:100vh; overflow:hidden; position:relative; background:#1b1712}
.tm-htrack__inner{display:flex; height:100%; align-items:center; gap:26px;
  padding:0 clamp(20px,6vw,80px); will-change:transform}
.tm-htrack__panel{position:relative; flex:0 0 auto; width:min(560px,80vw); height:74vh;
  border-radius:var(--radius); overflow:hidden; box-shadow:var(--shadow); background:#000}
.tm-htrack__panel img{width:100%; height:100%; object-fit:cover}
.tm-htrack__cap{position:absolute; left:0; right:0; bottom:0; padding:26px;
  background:linear-gradient(transparent,rgba(20,16,10,.74)); color:#fff}
.tm-htrack__cap h3{color:#fff}
.tm-htrack__intro{flex:0 0 auto; width:min(420px,80vw); color:#efe9df; padding-right:10px}
.tm-htrack__intro h2{color:#fff}
/* FOIC / no-JS / touch: a normal horizontal scroll-snap rail */
.tm-htrack--static{height:auto; overflow:hidden}
.tm-htrack--static .tm-htrack__inner{overflow-x:auto; scroll-snap-type:x mandatory;
  padding-block:40px}
.tm-htrack--static .tm-htrack__panel{scroll-snap-align:center; height:60vh}

/* ====================== ENGINE 8: SPLIT-TEXT EDITORIAL ================== */
/* The real sentence stays in the DOM (aria-label on the host, generated markup
   aria-hidden). Each visual line is clipped; its inner slides up on scroll.
   Not bound under reduced-motion -> renders as ordinary, fully-visible text. */
.tm-splittext{display:block}
.tm-st-line{display:block; overflow:hidden}
.tm-st-lineinner{display:block; will-change:transform}
.tm-st-word{display:inline-block}
@media (prefers-reduced-motion: reduce){
  html .tm-st-lineinner{transform:none !important}
}/* ====================== ENGINE 9: MARQUEE =============================== */
.tm-marquee{overflow:hidden; white-space:nowrap; padding-block:22px; border-block:1px solid var(--line)}
.tm-marquee__inner{display:inline-flex; gap:44px; will-change:transform}
.tm-marquee__inner span{font-family:var(--serif); font-size:clamp(1.6rem,3.4vw,2.6rem); color:var(--muted)}
.tm-marquee__inner span b{color:var(--sage-deep); font-weight:600}

/* ====================== ENGINE 10: COUNT-UP ============================= */
.tm-stat{display:flex; flex-direction:column; gap:4px}
.tm-stat b{font-family:var(--display); font-size:clamp(2.6rem,5.6vw,4.2rem); line-height:1; color:var(--sage-deep); font-weight:600}
.tm-stat span{font-size:.9rem; letter-spacing:.04em; color:var(--muted)}

/* ====================== ENGINE 11: SPOTLIGHT ============================ */
.tm-spotlight{position:relative; overflow:hidden}
.tm-spotlight__base{position:absolute; inset:0; display:grid; place-items:center}
.tm-spotlight__lit{position:absolute; inset:0; display:grid; place-items:center; opacity:0; pointer-events:none;
  -webkit-mask-image:radial-gradient(260px circle at var(--tm-mx,-999px) var(--tm-my,-999px), #000 0%, transparent 70%);
          mask-image:radial-gradient(260px circle at var(--tm-mx,-999px) var(--tm-my,-999px), #000 0%, transparent 70%)}
html.tm-active .tm-spotlight__lit{opacity:1}

/* ====================== ENGINE 12: SKEW-ON-SCROLL ====================== */
.tm-skew{will-change:transform}

/* ====================== ENGINE 13: WIPE ================================ */
.tm-wipe{position:relative}
.tm-wipe [data-tm-wipe-top]{position:absolute; inset:0; clip-path:inset(0 0 0 0)} /* FOIC: revealed by default */
.tm-wipe img{width:100%; height:100%; object-fit:cover}

/* ====================== ENGINE 14: KINETIC (per-char) ================== */
.tm-kline{display:inline-block; overflow:hidden}
.tm-kchar{display:inline-block; will-change:transform}
@media (prefers-reduced-motion: reduce){ html .tm-kchar{transform:none !important; opacity:1 !important; filter:none !important} }

/* ====================== ENGINE 15: PINNED FADING TITLE ================= */
.tm-fadetitle{min-height:100vh; display:grid; place-items:center; text-align:center; overflow:hidden}
.tm-fadetitle__el{will-change:transform,opacity; max-width:18ch; margin-inline:auto}

/* ====================== ENGINE 16: FLIP GRID-MORPH ==================== */
.tm-flipgrid{min-height:100vh; display:grid; place-items:center; overflow:hidden; background:var(--surface-2)}
.tm-flipgrid__grid{display:grid; gap:14px; width:min(1040px,92vw);
  grid-template-columns:repeat(6,1fr)}            /* layout A: single row */
.tm-flipgrid.is-morphed .tm-flipgrid__grid{grid-template-columns:repeat(3,1fr)}  /* layout B: 3x2 */
.tm-flip-item{border-radius:12px; overflow:hidden; box-shadow:var(--shadow); aspect-ratio:1; will-change:transform}
.tm-flip-item img{width:100%; height:100%; object-fit:cover}

/* ====================== ENGINE 17: BEFORE / AFTER COMPARE ============= */
.tm-compare{position:relative; overflow:hidden; border-radius:var(--radius); box-shadow:var(--shadow);
  aspect-ratio:16/10; cursor:ew-resize; user-select:none; touch-action:pan-y}
.tm-compare img{position:absolute; inset:0; width:100%; height:100%; object-fit:cover}
.tm-compare [data-tm-compare-after]{clip-path:inset(0 0 0 50%)}  /* FOIC static split */
.tm-compare__handle{position:absolute; top:0; bottom:0; left:50%; width:2px; background:#fff;
  transform:translateX(-50%); box-shadow:0 0 0 1px rgba(0,0,0,.15); pointer-events:none}
.tm-compare__handle::after{content:''; position:absolute; top:50%; left:50%; width:42px; height:42px;
  transform:translate(-50%,-50%); border-radius:50%; background:#fff; box-shadow:0 4px 14px rgba(0,0,0,.3)}
.tm-compare__lab{position:absolute; bottom:14px; z-index:2; font-size:.72rem; letter-spacing:.14em;
  text-transform:uppercase; color:#fff; background:rgba(20,16,10,.55); padding:5px 12px; border-radius:100px; pointer-events:none}
.tm-compare__lab--b{left:14px}
.tm-compare__lab--a{right:14px}

/* ====================== ENGINE 20: BACKDROP (fixed full-bleed image, cards scroll over) ===== */
.tm-backdrop{position:relative}
.tm-backdrop__bg{position:sticky; top:0; height:100vh; overflow:clip; z-index:0}
.tm-backdrop__bg img{width:100%; height:100%; object-fit:cover}
.tm-backdrop__bg::after{content:""; position:absolute; inset:0;
  background:linear-gradient(rgba(20,16,10,.30), rgba(20,16,10,.55))}
.tm-backdrop__content{position:relative; z-index:1; margin-top:-100vh;
  display:flex; justify-content:center; padding:115vh 20px 115vh}
.tm-backdrop__panel{width:min(1040px,94vw); text-align:center}
.tm-backdrop__cards{display:grid; grid-template-columns:repeat(3,1fr); gap:18px;
  margin-top:34px; text-align:left}
@media(max-width:820px){.tm-backdrop__cards{grid-template-columns:1fr}}
.tm-backdrop__card{background:rgba(255,255,255,.95);
  -webkit-backdrop-filter:blur(6px); backdrop-filter:blur(6px);
  border-radius:var(--radius); padding:24px 24px 26px; box-shadow:var(--shadow)}
.tm-backdrop__card h3{margin:.15em 0 .3em; font-size:1.35rem}
.tm-backdrop__card p{margin:0}
.tm-backdrop__lead{color:#fff; max-width:20ch; margin:0 auto}

/* ====================== dev reference labels (movement names) =========== */
.tm-label{position:absolute; top:14px; left:16px; z-index:6; font-family:var(--sans);
  font-size:11px; font-weight:700; letter-spacing:.16em; text-transform:uppercase;
  color:var(--sage-deep); background:rgba(246,243,238,.82); padding:5px 11px; border-radius:100px;
  -webkit-backdrop-filter:blur(4px); backdrop-filter:blur(4px); pointer-events:none;
  box-shadow:0 2px 10px rgba(0,0,0,.08)}
.tm-label--light{color:#f4efe3; background:rgba(20,16,10,.55)}
.tm-flipgrid, .tm-fadetitle{position:relative}

/* spotlight photo reveal (Scott: text alone wasn't enough) */
.tm-spotlight__photo{position:absolute; inset:0; width:100%; height:100%; object-fit:cover}
.tm-spotlight__lit .tm-spotlight__cap{position:relative; z-index:1; color:#fff; max-width:22ch;
  margin:0 auto; padding:0 26px; text-shadow:0 2px 26px rgba(0,0,0,.9), 0 1px 4px rgba(0,0,0,.95)}
