/* =============================================================================
   CTFY · Franchise (/franchise/, PRD pages/16) · page-only layout
   Builds on css/site.css (foundation) and css/modules.css (M01–M33). Only page variants live here:
   the H2 stage fit (text left from 1280px, product first on phones), the word-stat numeral, the dark M26
   studio strip, the M27 `journey` variant (framed tile above each node, line drawn node to node) and
   chapter seams/spacing. Motion is transform/opacity only and comes from the reveal engine (data-reveal,
   data-reveal-group, data-reveal-hold); the one loop (step 4 crossfade) pauses off-screen ([data-in-view])
   and stops with the G4 toggle (html[data-motion="off"]) and prefers-reduced-motion.
   ============================================================================= */

/* ---------- 1 · Hero (H2 Product Stage) ---------- */
.fr-hero .stage__product{width:min(66%,760px)}
.fr-hero .stage__chips>li:nth-child(1){--x:63%;--y:2%}
.fr-hero .stage__chips>li:nth-child(2){--x:6%;--y:84%}
@media (min-width:1280px){
  /* the product sits right of the text column, vertically centred on the field */
  .fr-hero .stage__product{width:60%;margin-right:-1%}
  .fr-hero .stage__chips>li:nth-child(1){--x:72%;--y:8%}
  .fr-hero .stage__chips>li:nth-child(2){--x:50%;--y:88%}
}
@media (max-width:767px){
  /* phones (PRD §6): product first, then crumbs · eyebrow · H1 · lead · CTAs, then the two chips */
  .fr-hero{padding-top:calc(var(--dock-top) + var(--dock-h) + 4px);text-align:left}
  .fr-hero .stage{display:contents}
  .fr-hero .stage__product{order:-1;width:min(100%,520px);margin:0 auto 4px}
  .fr-hero .stage__reflection{display:none}
  .fr-hero .stage__bloom{left:0;right:0;top:calc(var(--dock-top) + var(--dock-h));bottom:auto;height:min(300px,76vw)}
  .fr-hero .hero__content{justify-items:start}
  .fr-hero .hero__lead{margin-inline:0}
  .fr-hero .hero__ctas{justify-content:flex-start}
  .fr-hero .stage__chips{order:1;display:flex;flex-wrap:wrap;width:min(var(--container),100% - 2*var(--gutter));margin:28px auto 0}
}

/* ---------- 2 · At a glance (M03 word stats) ---------- */
.fr-glance{padding-block:clamp(32px,4vw,64px) clamp(40px,5vw,80px)}
/* "5" is a figure inside a word stat: Manrope 300 beside the Cormorant word (PRD §4.2) */
.fr-n{font:300 .9em/1 var(--font-sans);letter-spacing:-.04em;font-variant-numeric:tabular-nums}

/* ---------- 3 · Why us (M24 numbered + dark M26 strip) ---------- */
.fr-why{padding-top:var(--section-y-tight)}
.fr-kicker{display:flex;align-items:baseline;gap:14px;margin-bottom:2px}
.fr-kicker .eyebrow{color:var(--fg-3)}
/* M26 is a porcelain bento; here it is one dark row of four tiles (wide, tall, wide, tall) */
.fr-strip{margin-top:clamp(56px,7vw,104px);grid-template-columns:minmax(0,1.5fr) minmax(0,1fr) minmax(0,1.5fr) minmax(0,1fr);grid-template-rows:clamp(220px,23vw,330px)}
.fr-strip>li:nth-child(1){grid-row:auto}
.fr-strip>li:nth-child(2){grid-column:auto}
.fr-strip .m-gallery__tile{background:var(--bg-2);box-shadow:0 30px 60px -36px rgba(0,0,0,.8)}
.fr-strip .m-gallery__tile::after{content:"";position:absolute;inset:0;z-index:1;border-radius:inherit;box-shadow:inset 0 0 0 1px rgba(255,255,255,.08);pointer-events:none}
.fr-strip picture{display:contents}
.fr-strip .m-gallery__tile figcaption{z-index:2;color:var(--text-1)}
.fr-strip .m-gallery__tile:focus-visible{outline-color:var(--theta-400)}
@media (max-width:767px){
  /* phones: a horizontal snap row that bleeds to the screen edges; the next tile peeks in */
  .fr-strip{display:flex;gap:12px;margin-inline:calc(var(--gutter) * -1);padding:0 var(--gutter) 6px;overflow-x:auto;overscroll-behavior-x:contain;
    scroll-snap-type:x mandatory;scroll-padding-inline:var(--gutter);scrollbar-width:none}
  .fr-strip::-webkit-scrollbar{display:none}
  .fr-strip>li{flex:none;width:56vw;height:min(68vw,340px);scroll-snap-align:start}
  .fr-strip>li.fr-strip__wide{width:82vw}
}

/* ---------- 4 · Path to launch (hero moment): M27 `journey` ----------
   Each step is its own reveal target (data-reveal-group="480" on the list): on desktop the four steps enter
   together and run 480 ms apart, so the dot pops, its tile irises open and the segment then draws to the
   next dot just as that dot lights. On tablets and phones (vertical route) each step reveals as it scrolls in.
   Default (no JS, reduced, motion off) = the finished route: every segment drawn, every tile showing. */
.fr-how .sec__head{margin-bottom:clamp(40px,5vw,72px)}
/* BG-C sits on the route, not on the chapter's top edge (no hard grid line where the chapter starts) */
.fr-how .blueprint{-webkit-mask-image:radial-gradient(ellipse 72% 52% at 50% 62%,#000 20%,transparent 78%);mask-image:radial-gradient(ellipse 72% 52% at 50% 62%,#000 20%,transparent 78%)}
.fr-route{container-type:inline-size}
.fr-journey{--gap:clamp(20px,2.4vw,40px)}
.fr-journey::before{display:none}                          /* one segment per step replaces the single row line */
.fr-journey .m-route__step::after{content:"";position:absolute;pointer-events:none}
.fr-journey .m-route__step:last-child::after{display:none}
.fr-journey .m-route__media{margin:0;border-radius:var(--r-l)}
.fr-journey .m-route__media img{transform-origin:50% 50%}
.fr-journey .m-route__step>p:last-child{max-width:36ch}
@media (min-width:1024px){
  /* tile height from the column width (4:5), so the node row sits a fixed distance under every tile */
  .fr-journey{--mh:calc((100cqi - (var(--n) - 1) * var(--gap)) / var(--n) * 1.25);--ny:calc(var(--mh) + 28px)}
  .fr-journey .m-route__step{padding-top:0}
  .fr-journey .m-route__media{aspect-ratio:4/5;margin-bottom:46px}
  .fr-journey .m-route__step::before{top:var(--ny)}
  .fr-journey .m-route__step::after{left:19px;top:calc(var(--ny) + 6px);width:calc(100% + var(--gap) - 25px);height:1px;
    background:linear-gradient(90deg,var(--m-accent),rgba(107,125,255,.4));transform-origin:left}
}
@media (max-width:1023px){
  .fr-journey{gap:48px;padding-left:36px}
  .fr-journey .m-route__step::before{left:-36px;top:6px}
  .fr-journey .m-route__step::after{left:-30px;top:25px;width:1px;height:calc(100% + 48px - 25px);
    background:linear-gradient(180deg,var(--m-accent),rgba(107,125,255,.4));transform-origin:top}
  .fr-journey .m-route__media{aspect-ratio:16/10;max-width:640px;margin-bottom:14px}
}
/* reveal choreography (only while JS + motion run: .is-pending / .is-in come from core.js) */
.js .fr-journey>.m-route__step.is-pending{opacity:1;transform:none}
.js .fr-journey>.m-route__step.is-pending::before{opacity:.25;transform:scale(.5)}
.js .fr-journey>.m-route__step.is-pending::after{transform:scaleX(0)}
.js .fr-journey>.m-route__step.is-pending>.m-route__media{opacity:0;transform:scale(.9)}
.js .fr-journey>.m-route__step.is-pending>.m-route__media img{transform:scale(1.18)}
.js .fr-journey>.m-route__step.is-pending>:not(.m-route__media){opacity:0;transform:translateY(12px)}
@media (max-width:1023px){.js .fr-journey>.m-route__step.is-pending::after{transform:scaleY(0)}}
.fr-journey>.m-route__step.is-in::before{transition:opacity 260ms var(--ease-out) var(--delay,0ms),transform 420ms var(--ease-pop) var(--delay,0ms)}
.fr-journey>.m-route__step.is-in::after{transition:transform var(--seg-t,340ms) linear calc(var(--delay,0ms) + 140ms)}
.fr-journey>.m-route__step.is-in>.m-route__media{transition:opacity 420ms var(--ease-out) calc(var(--delay,0ms) + 40ms),transform 900ms var(--ease-out) calc(var(--delay,0ms) + 40ms)}
.fr-journey>.m-route__step.is-in>.m-route__media img{transition:transform 900ms var(--ease-out) calc(var(--delay,0ms) + 40ms)}
.fr-journey>.m-route__step.is-in>:not(.m-route__media){transition:opacity var(--dur-reveal) var(--ease-out) calc(var(--delay,0ms) + 160ms),transform var(--dur-reveal) var(--ease-out) calc(var(--delay,0ms) + 160ms)}
@media (max-width:1023px){.fr-journey{--seg-t:560ms}}
/* step 4 · Launch: the styled room crossfades to the chamber in its room (slow loop, only while on screen) */
.fr-fade>picture{position:absolute;inset:0;display:block}
.fr-fade__b{opacity:0;animation:fr-fade 14s var(--ease-in-out) 1.6s infinite;animation-play-state:paused}
.fr-fade[data-in-view="true"] .fr-fade__b{animation-play-state:running}
@keyframes fr-fade{0%,40%{opacity:0}50%,90%{opacity:1}100%{opacity:0}}

/* ---------- 5 · Economics bridge (M30 wide) ---------- */
.fr-bridge .m-bridge__product picture{display:block}
/* the still's near-black set (#0A0B10) is darker than the bg-2 band, so a lighten blend dissolves its rectangle;
   the figure joins the band's stacking context so the blend sees the band and bloom (as on the Home product split) */
.fr-bridge .m-bridge__product{isolation:auto}
.fr-bridge .m-bridge__product img{mix-blend-mode:lighten}
.fr-bridge .m-bridge__line{text-wrap:balance}

/* ---------- 6 · Is it you? (porcelain) ---------- */
.ch--paper.fr-partner{--seam-from:var(--bg-2);padding-bottom:var(--section-y-tight)}   /* follows the bridge band */
.fr-feel{margin-top:14px}
.fr-feel .m-feel__list li{font-size:calc(var(--t-title) * 1.2 * var(--k-display))}
.fr-feel .m-feel__list .icon{width:18px;height:18px}

/* ---------- 7 · Franchise FAQ (porcelain) ---------- */
.ch--paper.fr-faq{--seam-to:var(--bg-0);padding-top:var(--section-y-tight)}   /* the finale field is bg-0 */
.fr-note{margin-top:34px}

/* ---------- Calm states: reduced motion, motion toggle off ---------- */
[data-motion="off"] .fr-journey>.m-route__step::after,[data-motion="off"] .fr-journey .m-route__media img{transform:none!important}
[data-motion="off"] .fr-fade__b{animation:none;opacity:0}
@media (prefers-reduced-motion:reduce){
  .fr-fade__b{animation:none;opacity:0}
}
