/* ============================================================
   Jessin Chua — "izanami" cinematic concept (ivory / light)
   Language: izanami-official.com teardown (IZANAMI-TEARDOWN.md)
   Ivory palette · Playfair Display + Cinzel + Inter · Lenis + GSAP
   ============================================================ */

:root{
  --paper:#F4EFE6;
  --paper-hi:#FBF8F1;
  --paper-2:#ECE4D6;
  --mist:#EFE9DD;
  --ink:#1B1712;
  --ink-80:#3A332B;
  --ink-60:#6B6256;
  --ink-40:#9A8F7F;
  /* Darkened from #8A6A4B 2026-09-01 (audit finding H1). The old value sat at
     4.32:1 on paper, just under the 4.5:1 readable minimum, and it carries the
     small numerals, kickers and captions that the oldest readers squint at
     hardest. #7E5F42 is 5.09:1, and it also lifts white-on-umber from 4.67 to
     5.5:1 where umber is a button ground. Visually a half-step deeper. */
  --umber:#7E5F42;
  --umber-soft:#B79A78;
  --line:color-mix(in srgb, var(--ink) 16%, transparent);
  --line-soft:color-mix(in srgb, var(--ink) 9%, transparent);
  --serif:"Playfair Display", Georgia, serif;
  --caps:"Cinzel", Georgia, serif;
  --sans:"Inter", "Helvetica Neue", Arial, sans-serif;
  --gut:clamp(20px, 5vw, 90px);
  --maxw:1320px;
}

*{margin:0;padding:0;box-sizing:border-box}
html{ -webkit-text-size-adjust:100%; }
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}
@media (prefers-reduced-motion: reduce){ html{scroll-behavior:auto} }

body{
  font-family:var(--sans); font-weight:400; font-size:16px; line-height:1.7;
  color:var(--ink); background:var(--paper);
  -webkit-font-smoothing:antialiased; overflow-x:hidden;
}
img,video{display:block;max-width:100%}
a{color:inherit;text-decoration:none}
em,i{font-style:italic}
::selection{background:var(--umber-soft);color:var(--ink)}

.wrap{width:min(100% - 2*var(--gut), var(--maxw));margin-inline:auto}

/* ---------- grain + global mist ---------- */
.grain{position:fixed;inset:0;z-index:120;pointer-events:none;opacity:.05;mix-blend-mode:multiply;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E")}

/* ---------- nav ---------- */
.nav{position:fixed;inset:0 0 auto 0;z-index:100;display:flex;align-items:center;justify-content:space-between;
  padding:clamp(18px,2.4vw,30px) var(--gut);
  transition:background .5s ease, padding .5s ease;
  mix-blend-mode:normal;}
.nav.solid{background:rgba(244,239,230,.92);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);box-shadow:0 1px 0 0 var(--line-soft)}
.nav .brand{display:flex;align-items:center;gap:10px;font-family:var(--caps);font-size:15px;letter-spacing:.18em;text-transform:uppercase}
.nav .brand img{height:30px;width:auto;mix-blend-mode:multiply}
.nav .navlinks{display:flex;gap:clamp(20px,2.4vw,40px);align-items:center;font-family:var(--caps);font-size:12px;letter-spacing:.2em;text-transform:uppercase}
.nav .navlinks a{position:relative;padding:4px 0;color:var(--ink-80)}
.nav .navlinks a::after{content:"";position:absolute;left:0;bottom:0;width:0;height:1px;background:var(--ink);transition:width .4s cubic-bezier(.22,1,.36,1)}
.nav .navlinks a:hover::after,.nav .navlinks a[aria-current=page]::after{width:100%}
.menu-btn{display:none}
.mobile-menu{display:none}
@media (max-width:1120px){ /* W4 NAV FIT: was 920px · 6th link (Pricing) crammed the desktop nav 921-1119px (brand-links gap <20px); links show from 1121px where the gap is 22px+ */
  .nav .navlinks{display:none}
  .menu-btn{display:inline-flex;font-family:var(--caps);font-size:12px;letter-spacing:.2em;text-transform:uppercase;background:none;border:0;color:var(--ink);cursor:pointer}
  .mobile-menu{position:fixed;inset:0;z-index:95;background:var(--paper);display:none;flex-direction:column;justify-content:center;gap:6px;padding:var(--gut)}
  .mobile-menu.open{display:flex}
  .mobile-menu a{font-family:var(--serif);font-size:clamp(34px,9vw,56px);padding:10px 0;border-bottom:1px solid var(--line-soft)}
}

/* ---------- hero ---------- */
.hero{position:relative;height:100svh;min-height:620px;overflow:hidden;display:flex;align-items:flex-end}
.hero-media{position:absolute;inset:-8% 0 -8% 0;z-index:0;will-change:transform}
.hero-media img,.hero-media video{width:100%;height:100%;object-fit:cover}
.hero-scrim{position:absolute;inset:0;z-index:1;pointer-events:none;
  background:linear-gradient(to bottom, rgba(244,239,230,.42) 0%, rgba(244,239,230,.05) 26%, rgba(244,239,230,.12) 64%, rgba(244,239,230,.72) 100%)}
.hero-mist{position:absolute;inset:0;z-index:1;pointer-events:none;opacity:.5;
  background:radial-gradient(120% 70% at 50% 30%, transparent 40%, rgba(239,233,221,.5) 100%);
  mix-blend-mode:screen}
.hero-mist.drift{background:linear-gradient(100deg, transparent 0%, rgba(247,243,235,.5) 30%, transparent 60%, rgba(247,243,235,.35) 90%);background-size:240% 100%;animation:drift 26s linear infinite}
@keyframes drift{from{background-position:0 0}to{background-position:240% 0}}
@media (prefers-reduced-motion: reduce){.hero-mist.drift{animation:none}}
.hero-inner{position:relative;z-index:2;width:100%;padding:0 var(--gut) clamp(40px,7vw,96px)}
.hero-eyebrow{font-family:var(--caps);font-size:12px;letter-spacing:.34em;text-transform:uppercase;color:var(--ink-80)}
.hero-title{font-family:var(--serif);font-weight:400;font-size:clamp(40px,7vw,104px);line-height:1.02;letter-spacing:-.01em;margin-top:clamp(14px,1.8vw,26px);max-width:16ch}
.hero-title em{font-style:italic}
.hero-sub{margin-top:clamp(16px,2vw,26px);max-width:46ch;font-size:15.5px;line-height:1.7;color:var(--ink-80)}
.hero-meta{position:absolute;left:var(--gut);right:var(--gut);bottom:16px;z-index:2;display:flex;justify-content:space-between;gap:18px;
  font-family:var(--caps);font-size:10.5px;letter-spacing:.22em;text-transform:uppercase;color:var(--ink-60)}
.scrollcue{position:absolute;left:50%;bottom:18px;transform:translateX(-50%);z-index:2;width:1px;height:46px;background:linear-gradient(var(--ink-40),transparent);overflow:hidden}
.scrollcue::after{content:"";position:absolute;top:-46px;left:0;width:1px;height:46px;background:var(--ink);animation:cue 2.4s cubic-bezier(.7,0,.3,1) infinite}
@keyframes cue{to{transform:translateY(92px)}}

/* ---------- generic display type ---------- */
.eyebrow{font-family:var(--caps);font-size:12px;letter-spacing:.3em;text-transform:uppercase;color:var(--ink-60)}
.display{font-family:var(--serif);font-weight:400;line-height:1.04;letter-spacing:-.01em;font-size:clamp(34px,5.4vw,84px)}
.display em{font-style:italic}
.statement{font-family:var(--serif);font-weight:400;font-size:clamp(24px,3.1vw,46px);line-height:1.16;letter-spacing:-.005em;text-wrap:balance}
.lede{font-size:clamp(16px,1.4vw,19px);line-height:1.7;color:var(--ink-80);max-width:52ch}
.body{font-size:15.5px;line-height:1.75;color:var(--ink-60);max-width:60ch}
.vlabel{position:absolute;left:clamp(8px,1.2vw,18px);top:0;writing-mode:vertical-rl;font-family:var(--caps);font-size:11px;letter-spacing:.3em;text-transform:uppercase;color:var(--ink-40)}

/* ---------- "— View" link ---------- */
.viewlink{display:inline-flex;align-items:center;gap:16px;font-family:var(--caps);font-size:12px;letter-spacing:.22em;text-transform:uppercase;color:var(--ink-80)}
.viewlink .ln{width:46px;height:1px;background:var(--ink);transition:width .5s cubic-bezier(.22,1,.36,1)}
.viewlink:hover .ln{width:84px}

/* ---------- sections / rhythm ---------- */
.sec{position:relative;padding-block:clamp(72px,12vw,180px)}
.sec-tight{padding-block:clamp(44px,7vw,96px)}

/* numbered chapter (homepage) */
.chapter{position:relative;display:grid;grid-template-columns:1fr 1fr;gap:clamp(28px,5vw,90px);align-items:center;
  padding-block:clamp(64px,10vw,150px)}
.chapter:nth-child(even) .chapter-media{order:-1}
.chapter-no{font-family:var(--serif);font-size:clamp(40px,5vw,70px);line-height:1;color:var(--umber);opacity:.55}
.chapter-body{position:relative}
.chapter-body .display{margin-top:clamp(10px,1.4vw,18px)}
.chapter-body .statement{margin-top:clamp(12px,1.4vw,18px)}
.chapter-body .body{margin-top:clamp(16px,1.8vw,24px)}
.chapter-body .viewlink{margin-top:clamp(22px,2.6vw,34px)}
.chapter-media{position:relative;overflow:hidden;border-radius:2px;aspect-ratio:4/3}
.chapter-media img{position:absolute;inset:-10% 0;width:100%;height:120%;object-fit:cover;will-change:transform}
@media (max-width:820px){
  .chapter{grid-template-columns:1fr;gap:24px}
  .chapter:nth-child(even) .chapter-media{order:0}
  .chapter-media{aspect-ratio:4/3}
}

/* full-bleed parallax band */
.bleed{position:relative;height:clamp(360px,80vh,820px);overflow:hidden}
.bleed-media{position:absolute;inset:-12% 0;will-change:transform}
.bleed-media img,.bleed-media video{width:100%;height:100%;object-fit:cover}
.bleed-cap{position:absolute;inset:auto 0 0 0;z-index:2;padding:0 var(--gut) clamp(30px,5vw,60px);
  background:linear-gradient(transparent, rgba(20,17,13,.42));}
.bleed-cap .display,.bleed-cap .statement,.bleed-cap .eyebrow{color:var(--paper-hi)}
.bleed-cap .lede{color:color-mix(in srgb, #FBF8F1 80%, transparent)}

/* centred motif moment (izanami "Who we are") */
.motif{position:relative;text-align:center;padding-block:clamp(90px,16vw,220px);overflow:hidden}
.motif-media{position:absolute;inset:-12% 0;z-index:0;will-change:transform}
.motif-media img{width:100%;height:124%;object-fit:cover}
.motif::after{content:"";position:absolute;inset:0;z-index:1;background:rgba(244,239,230,.6)}
.motif .inner{position:relative;z-index:2;width:min(100% - 2*var(--gut), 720px);margin-inline:auto}
.motif .mark{width:56px;margin:0 auto clamp(20px,2.4vw,30px);mix-blend-mode:multiply}

/* ---------- reveals & parallax ---------- */
.rv{opacity:0;transform:translateY(30px);transition:opacity 1.1s cubic-bezier(.16,1,.3,1),transform 1.1s cubic-bezier(.16,1,.3,1)}
.rv.in{opacity:1;transform:none}
.rv-2{transition-delay:.08s}.rv-3{transition-delay:.16s}.rv-4{transition-delay:.24s}
.linemask{display:block;overflow:hidden}
.linemask>span{display:block;transform:translateY(110%);transition:transform 1.1s cubic-bezier(.16,1,.3,1)}
.linemask.in>span{transform:none}
html.no-js .rv,html.shot .rv{opacity:1!important;transform:none!important}
html.no-js .linemask>span,html.shot .linemask>span{transform:none!important}
@media (prefers-reduced-motion: reduce){.rv{opacity:1;transform:none}.linemask>span{transform:none}}

/* ---------- footer ---------- */
.foot{position:relative;background:var(--paper-hi);border-top:1px solid var(--line);padding:clamp(56px,8vw,110px) var(--gut) 0}
.foot-grid{display:grid;grid-template-columns:1.5fr 1fr 1fr;gap:clamp(28px,4vw,60px);align-items:start}
.foot-nav{display:flex;flex-direction:column;gap:10px;font-family:var(--caps);font-size:clamp(20px,2.4vw,30px);letter-spacing:.04em;text-transform:uppercase}
.foot-nav a{color:var(--ink);transition:color .3s,padding-left .4s cubic-bezier(.22,1,.36,1)}
.foot-nav a:hover{color:var(--umber);padding-left:10px}
.foot h4,.foot .foot-h{font-family:var(--caps);font-size:11px;font-weight:700;letter-spacing:.24em;text-transform:uppercase;color:var(--ink-60);margin-bottom:14px}
.foot .addr{font-size:14px;line-height:1.8;color:var(--ink-80)}
.foot .addr a{text-decoration:underline;text-underline-offset:3px}
.foot-social{display:flex;flex-direction:column;gap:9px;font-family:var(--caps);font-size:12px;letter-spacing:.16em;text-transform:uppercase;margin-top:18px}
.foot-meta{display:flex;flex-wrap:wrap;justify-content:space-between;gap:14px;margin-top:clamp(40px,6vw,80px);padding:18px 0;border-top:1px solid var(--line-soft);
  font-family:var(--caps);font-size:10.5px;letter-spacing:.2em;text-transform:uppercase;color:var(--ink-60)}
.foot-word{overflow:hidden;line-height:.8}
.foot-word .display{font-size:clamp(44px,13vw,200px);transform:translateY(.1em);color:var(--ink);opacity:.9}
@media (max-width:820px){.foot-grid{grid-template-columns:1fr;gap:30px}}

/* ---------- buttons / forms (contact in footer) ---------- */
.pill{display:inline-flex;align-items:center;gap:10px;font-family:var(--caps);font-size:12px;letter-spacing:.18em;text-transform:uppercase;
  background:var(--ink);color:var(--paper-hi);border:0;border-radius:999px;padding:13px 26px;cursor:pointer;transition:background .3s}
.pill:hover{background:var(--umber)}

/* utility */
.tc{text-align:center}.mt0{margin-top:0!important}
.page-top{padding-top:clamp(90px,11vw,150px)}

/* ============ motion v2 ============ */
/* page-transition curtain (Swup-style wipe) */
.pt{position:fixed;inset:0;z-index:200;background:var(--paper);transform:scaleY(0);transform-origin:top;pointer-events:none;will-change:transform}
html.no-js .pt,html.shot .pt{display:none}

/* per-line masked rise (auto-split headings) */
.split .ln-mask,.hero-title .ln-mask{display:block;overflow:hidden}
.split .ln-in,.hero-title .ln-in{display:block;will-change:transform}

/* image unveil */
.reveal{overflow:hidden;position:relative}
.reveal img{display:block;width:100%;height:auto;will-change:transform,clip-path}

/* sticky chapters (the izanami "held" feel) */
@media (min-width:821px){
  .chapter{align-items:start}
  .chapter-body{position:sticky;top:24vh}
  .chapter-media{aspect-ratio:4/3.2}
  .chapter-media.tall{aspect-ratio:4/4.6}
}
.linemask{display:block;overflow:hidden}.linemask>span{display:block}

/* ============ mobile stacking for inline grids (enrichment sections) ============ */
@media (max-width:760px){
  [style*="repeat(4,1fr)"],[style*="repeat(4, 1fr)"],[style*="repeat(3,1fr)"],[style*="repeat(3, 1fr)"]{grid-template-columns:1fr 1fr!important}
  [style*="repeat(2,1fr)"],[style*="repeat(2, 1fr)"]{grid-template-columns:1fr!important}
  [style*="grid-template-columns:1fr 1fr"]{grid-template-columns:1fr!important}
  [style*="grid-template-columns:1fr 1.1fr"],[style*="grid-template-columns:1fr 1.05fr"],[style*="grid-template-columns:1.1fr 1fr"]{grid-template-columns:1fr!important}
}
@media (max-width:460px){
  [style*="repeat(4,1fr)"],[style*="repeat(4, 1fr)"]{grid-template-columns:1fr!important}
}
/* A3: portrait/story split grids collapse with the .chapter breakpoint (820px),
   not 760 — no cream shaft around the portrait in the 761-820 band */
@media (max-width:820px){
  [style*="grid-template-columns:1fr 1.1fr"],[style*="grid-template-columns:1.1fr 1fr"]{grid-template-columns:1fr!important}
}

/* QA fixes: clip footer outro, give the giant sign-off tidy bounds */
.foot{overflow:hidden}
.foot-word{margin-bottom:clamp(-10px,-1vw,-4px)}
[data-stars]{color:var(--umber);letter-spacing:3px}

/* WebGL fog hero canvas */
.hero-canvas{position:absolute;inset:0;width:100%;height:100%;display:block;z-index:1;opacity:0;transition:opacity .9s ease}
.hero-media img{transition:opacity .9s ease}
html.webgl-hero .hero-scrim{z-index:2}

/* real portrait in the motif moment */
.motif-portrait{width:clamp(96px,9vw,132px);height:clamp(96px,9vw,132px);border-radius:50%;object-fit:cover;object-position:50% 40%;margin:0 auto clamp(22px,2.6vw,34px);box-shadow:0 18px 50px rgba(27,23,18,.18)}

/* warm section + warm full-bleed accents (warmth pass) */
.sec--warm{background:linear-gradient(180deg, var(--paper) 0%, #F0E7D7 100%)}
.warm-band{position:relative;height:clamp(340px,62vh,640px);overflow:hidden;border-radius:2px}
.warm-band .bm{position:absolute;inset:-10% 0;will-change:transform}
.warm-band .bm img{width:100%;height:100%;object-fit:cover}
.warm-band .cap{position:absolute;left:0;right:0;bottom:0;z-index:2;padding:0 var(--gut) clamp(26px,4vw,52px);background:linear-gradient(transparent, rgba(40,30,18,.34))}
.warm-band .cap .statement,.warm-band .cap .eyebrow{color:#FBF6EC}

/* featured brand film */
.film-feat{width:100%;border-radius:3px;overflow:hidden;background:var(--ink);box-shadow:0 30px 80px rgba(27,23,18,.16)}
.film-feat video{width:100%;display:block}

/* ===== critique fixes ===== */
/* caption contrast + descender clearance on warm bands & bleeds */
.warm-band .cap{padding-bottom:clamp(34px,4.5vw,60px);background:linear-gradient(transparent, rgba(38,28,16,.18) 30%, rgba(38,28,16,.62))}
.warm-band .cap .statement{max-width:30ch;line-height:1.18;padding-bottom:.12em}
.bleed-cap{padding-bottom:clamp(34px,4.5vw,60px);background:linear-gradient(transparent, rgba(20,17,13,.20) 26%, rgba(20,17,13,.6))}
.bleed-cap .statement{line-height:1.16;padding-bottom:.12em}
/* hero micro-labels readable over misty image */
.hero-eyebrow{color:var(--ink);text-shadow:0 1px 14px rgba(247,243,235,.6)}
.hero-meta{color:var(--ink-80);text-shadow:0 1px 12px rgba(247,243,235,.6)}
/* footer giant wordmark: breathing room, no harsh clip */
.foot{padding-bottom:clamp(20px,3vw,40px)}
.foot-word{margin-bottom:0}
.foot-word .display{font-size:clamp(40px,11.5vw,176px)}
/* explicit difference section */
.diff{border-top:1px solid var(--line-soft)}
.diff-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:clamp(20px,3vw,54px) clamp(28px,5vw,80px);margin-top:clamp(34px,4vw,60px)}
.diff-item{display:grid;grid-template-columns:auto 1fr;gap:clamp(16px,2vw,28px);align-items:start;padding-top:22px;border-top:1px solid var(--line-soft)}
.diff-item .n{font-family:var(--serif);font-size:clamp(22px,2vw,30px);color:var(--umber);line-height:1}
.diff-item h3{font-family:var(--serif);font-weight:400;font-size:clamp(20px,1.8vw,26px);line-height:1.15;margin-bottom:8px}
.diff-item p{font-size:14.5px;line-height:1.65;color:var(--ink-60);max-width:42ch}
@media (max-width:760px){.diff-grid{grid-template-columns:1fr}}

/* ===================== reviews showcase (client reviews, presented well) ===================== */
.reviews{border-top:1px solid var(--line-soft)}
.rev-head{display:flex;flex-wrap:wrap;align-items:flex-end;justify-content:space-between;gap:18px}
.rev-agg{display:flex;align-items:baseline;gap:14px}
.rev-score{font-family:var(--serif);font-size:clamp(40px,5vw,66px);line-height:.9;color:var(--ink)}
.rev-agg .rev-stars{font-size:clamp(16px,1.5vw,20px)}
.rev-stars{color:var(--umber);letter-spacing:3px;line-height:1}
.rev-stars.sm{font-size:13px}
.rev-meta{font-family:var(--caps);font-size:11px;letter-spacing:.18em;text-transform:uppercase;color:var(--ink-60)}
.rev-feature{margin:clamp(34px,4.5vw,64px) 0 clamp(28px,3.5vw,48px);max-width:760px}
.rev-feature .rev-stars{font-size:18px;display:block;margin-bottom:18px}
.rev-feature blockquote{font-family:var(--serif);font-weight:400;font-size:clamp(24px,2.8vw,40px);line-height:1.18;letter-spacing:-.005em;color:var(--ink);text-wrap:balance}
.rev-feature figcaption,.rev-by{display:flex;flex-wrap:wrap;align-items:center;gap:10px 14px;margin-top:clamp(16px,2vw,24px)}
.rev-name{font-family:var(--serif);font-style:italic;font-size:17px;color:var(--ink-80)}
.rev-when{font-family:var(--caps);font-size:10.5px;letter-spacing:.16em;text-transform:uppercase;color:var(--ink-40)}
.vpill{font-family:var(--caps);font-size:9.5px;letter-spacing:.16em;text-transform:uppercase;color:var(--umber);border:1px solid color-mix(in srgb,var(--umber) 38%,transparent);border-radius:999px;padding:4px 10px;white-space:nowrap}
.rev-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(16px,1.8vw,26px);margin-top:clamp(8px,1vw,14px)}
.rev-card{display:flex;flex-direction:column;gap:14px;padding:clamp(22px,2.2vw,32px);background:var(--paper-hi);border:1px solid var(--line-soft);border-radius:14px}
.rev-card .rev-stars{margin-bottom:2px}
.rev-card p{font-size:15px;line-height:1.6;color:var(--ink-80);flex:1}
.rev-card .rev-by{margin-top:6px;border-top:1px solid var(--line-soft);padding-top:14px}
/* single inline review for the subpages */
.rev-inline{max-width:40ch}
.rev-inline .rev-stars{display:block;margin-bottom:12px}
.rev-inline blockquote{font-family:var(--serif);font-size:clamp(19px,1.9vw,26px);line-height:1.28;color:var(--ink)}
@media (max-width:820px){.rev-grid{grid-template-columns:1fr}}

/* hero text legibility (stronger, localized) */
.hero-scrim{background:linear-gradient(to bottom, rgba(244,239,230,.34) 0%, rgba(244,239,230,.03) 24%, rgba(40,30,18,.10) 60%, rgba(40,30,18,.42) 100%)}
.hero-title{text-shadow:0 2px 30px rgba(35,26,15,.28)}
.hero-sub{color:var(--paper-hi);text-shadow:0 1px 18px rgba(35,26,15,.5)}
html.webgl-hero .hero-eyebrow{color:var(--paper-hi)}
/* footer wordmark: tighten the void above it */
.foot-word{margin-top:clamp(-8px,-1.5vw,-4px)}
.foot{padding-top:clamp(40px,6vw,90px)}

/* her-scene bands: taller + face-biased crop so her face is always shown */
.warm-band.person{height:clamp(480px,80vh,800px)}
.warm-band.person .bm img{object-position:50% 22%}

/* ===== CTAs (clear next step) ===== */
.nav-cta{font-family:var(--caps);font-size:11px;letter-spacing:.16em;text-transform:uppercase;border:1px solid color-mix(in srgb,var(--ink) 50%,transparent);border-radius:999px;padding:9px 17px;color:var(--ink);transition:background .4s ease,color .4s ease,border-color .4s ease}
.nav-cta:hover{background:var(--ink);color:var(--paper);border-color:var(--ink)}
.nav-cta::after{display:none}
.hero-cta{display:inline-flex;align-items:center;gap:12px;margin-top:clamp(20px,2.4vw,30px);font-family:var(--caps);font-size:12px;letter-spacing:.2em;text-transform:uppercase;color:var(--ink);background:color-mix(in srgb,var(--paper-hi) 84%,transparent);-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);border:1px solid color-mix(in srgb,var(--ink) 22%,transparent);border-radius:999px;padding:14px 28px;transition:background .4s ease,color .4s ease}
.hero-cta:hover{background:var(--ink);color:var(--paper-hi)}

/* hero CTA subtext */
.hero-cta-note{margin-top:12px;max-width:38ch;font-size:13px;line-height:1.5;color:var(--ink-80);text-shadow:0 1px 14px rgba(247,243,235,.55)}
html.webgl-hero .hero-cta-note{color:var(--paper-hi);text-shadow:0 1px 16px rgba(35,26,15,.5)}

/* inline CTA button (cream sections) */
.cta-btn{display:inline-flex;align-items:center;gap:12px;font-family:var(--caps);font-size:12px;letter-spacing:.2em;text-transform:uppercase;color:var(--paper);background:var(--ink);border:1px solid var(--ink);border-radius:999px;padding:14px 30px;transition:background .4s ease,color .4s ease}
.cta-btn:hover{background:transparent;color:var(--ink)}
.cta-line{font-size:15px;line-height:1.6;color:var(--ink-80);max-width:46ch;margin-bottom:clamp(16px,2vw,22px)}

/* ===== floating WhatsApp contact button ===== */
.wa-fab{position:fixed;right:clamp(16px,2.4vw,34px);bottom:clamp(16px,2.4vw,34px);z-index:140;width:clamp(54px,5vw,62px);height:clamp(54px,5vw,62px);display:flex;align-items:center;justify-content:center;border-radius:50%;background:#25D366;color:#fff;box-shadow:0 12px 32px rgba(20,17,13,.30);transition:transform .35s cubic-bezier(.22,1,.36,1),box-shadow .35s ease;animation:wa-in .55s .8s both}
.wa-fab svg{width:58%;height:58%;display:block}
.wa-fab:hover{transform:translateY(-3px) scale(1.05);box-shadow:0 18px 44px rgba(20,17,13,.36)}
@keyframes wa-in{from{opacity:0;transform:scale(.5)}to{opacity:1;transform:scale(1)}}
@media (prefers-reduced-motion:reduce){.wa-fab{animation:none}}
html.shot .wa-fab{animation:none;opacity:1}

/* ===== legacy "what planning covers" sticky parallax media ===== */
.pc-grid{display:grid;grid-template-columns:1.02fr .98fr;gap:clamp(32px,5vw,90px);align-items:stretch}
.pc-media{position:relative;height:100%}
.pc-stack{position:sticky;top:15vh;margin:0;aspect-ratio:4/5;border-radius:2px;overflow:hidden;background:var(--paper-2);box-shadow:0 24px 60px rgba(27,23,18,.12)}
.pc-stack img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;opacity:0;transform:scale(1.06);transition:opacity 1s cubic-bezier(.22,1,.36,1),transform 1.6s cubic-bezier(.22,1,.36,1);will-change:opacity,transform}
.pc-stack img.on{opacity:1;transform:scale(1)}
@media (max-width:820px){
  .pc-grid{grid-template-columns:1fr;gap:clamp(22px,5vw,38px)}
  .pc-media{order:-1}
  .pc-stack{position:relative;top:0;aspect-ratio:16/10}
}

/* ===== hero legibility: gold title + outlined eyebrow ===== */
:root{--gold:#A6803C}
.hero-title{color:var(--gold);text-shadow:0 1px 0 rgba(60,44,20,.20),0 2px 22px rgba(28,20,8,.45),0 6px 44px rgba(28,20,8,.28)}
.hero-title em{color:var(--gold)}
.hero-eyebrow,html.webgl-hero .hero-eyebrow,.hero-meta,html.webgl-hero .hero-meta{
  color:#FBF7EF;
  text-shadow:0 0 1px rgba(44,36,26,.95), 0 0 3px rgba(44,36,26,.6), 0 1px 3px rgba(30,24,16,.6);
}

/* ===== hero typography v2: clean type on a cinematic scrim (no muddy shadows) ===== */
.hero-scrim{background:linear-gradient(to bottom, rgba(26,19,12,0) 0%, rgba(26,19,12,0) 30%, rgba(26,19,12,.22) 50%, rgba(18,13,8,.66) 100%)}
.hero-title{color:var(--gold);text-shadow:0 1px 3px rgba(14,10,5,.42)}
.hero-title em{color:var(--gold)}
.hero-eyebrow,html.webgl-hero .hero-eyebrow{color:#FBF7EF;-webkit-text-stroke:0;text-shadow:0 1px 3px rgba(12,9,5,.55)}
.hero-sub{color:#F1EADC;text-shadow:0 1px 4px rgba(12,9,5,.5)}
.hero-meta,html.webgl-hero .hero-meta{color:#EBE3D4;text-shadow:0 1px 3px rgba(12,9,5,.5)}

/* ===== hero typography v3: white title on a deeper cinematic base ===== */
.hero-scrim{background:linear-gradient(to bottom, rgba(22,16,10,0) 0%, rgba(22,16,10,0) 32%, rgba(22,16,10,.18) 52%, rgba(16,11,7,.56) 74%, rgba(11,8,4,.80) 100%)}
.hero-title,.hero-title em{color:#FCF9F3;text-shadow:0 1px 3px rgba(10,7,4,.5), 0 2px 18px rgba(10,7,4,.32)}
.hero-eyebrow,html.webgl-hero .hero-eyebrow{color:#FBF7EF;text-shadow:0 1px 3px rgba(10,7,4,.6)}
.hero-sub{color:#F3ECDF;text-shadow:0 1px 4px rgba(10,7,4,.55)}
.hero-meta,html.webgl-hero .hero-meta{color:#ECE4D5;text-shadow:0 1px 3px rgba(10,7,4,.55)}


/* ================================================================
   ============  V2 REBUILD BLOCK (2026-07 · blueprint §11)  ======
   Appended last on purpose: later rules win over the legacy
   override blocks above. Page agents consume the classes below.
   ================================================================ */

/* ---------- type & contrast bumps ---------- */
.body{font-size:16px}
.diff-item p{font-size:15px}
.rev-meta{font-size:12px;color:var(--ink-60)}
.rev-when{color:var(--ink-60)}
.vlabel{color:var(--ink-60)}
/* small umber text darkened for contrast (blueprint: #7A5C3F) */
.vpill{color:#7A5C3F;border-color:color-mix(in srgb,#7A5C3F 44%,transparent)}
.umber-small{color:#7A5C3F} /* utility for page agents ("In one line:" etc.) */

/* ---------- chapter-page deck spacing (H1 -> lede) ---------- */
.page-top h1 + .lede,
.page-top .display + .lede{margin-top:clamp(20px,3vw,36px)}

/* ---------- focus visibility ---------- */
:focus-visible{outline:2px solid var(--umber);outline-offset:3px}
form[data-wa] input:focus-visible{
  outline:none;
  border-bottom-color:var(--umber)!important;
  box-shadow:0 1px 0 0 var(--umber);
}
/* form status line must stay readable (beats the inline 12.5px) */
form[data-wa] [data-status]{font-size:14px!important;line-height:1.5}

/* ---------- menu button: >=44px touch target ---------- */
@media (max-width:1120px){ /* W4 NAV FIT: was 920px · 6th link (Pricing) crammed the desktop nav 921-1119px (brand-links gap <20px); links show from 1121px where the gap is 22px+ */
  .menu-btn{padding:14px;margin:-14px;min-width:44px;min-height:44px;justify-content:center;align-items:center}
}

/* ---------- vlabel: gone on tablet/mobile ---------- */
@media (max-width:900px){ .vlabel{display:none} }

/* ---------- mobile grid fix: 3-col inline grids -> 1 col <=600px ---------- */
@media (max-width:600px){
  [style*="repeat(3,1fr)"],[style*="repeat(3, 1fr)"],[style*="repeat(3,"],[style*="repeat(3, "]{grid-template-columns:1fr!important}
}

/* ---------- scrim system fix: washed-out eyebrow bands ---------- */
.bleed-cap{
  padding-top:clamp(60px,8vw,120px);
  background:linear-gradient(to bottom, transparent 0%, rgba(38,28,16,.30) 45%, rgba(38,28,16,.68) 100%);
}
.warm-band .cap{
  padding-top:clamp(60px,8vw,120px);
  background:linear-gradient(to bottom, transparent 0%, rgba(38,28,16,.30) 45%, rgba(38,28,16,.68) 100%);
}
.bleed-cap .eyebrow,.warm-band .cap .eyebrow{
  color:#FBF6EC;
  text-shadow:0 1px 3px rgba(12,9,5,.6),0 1px 14px rgba(12,9,5,.35);
}
.bleed-cap .statement,.warm-band .cap .statement{text-shadow:0 1px 4px rgba(12,9,5,.4)}

/* ---------- .proof-strip : hero proof line ---------- */
.proof-strip{
  margin-top:clamp(16px,2vw,24px);
  font-family:var(--caps);
  font-size:12.5px;letter-spacing:.18em;text-transform:uppercase;
  color:var(--paper-hi);
  text-shadow:0 1px 3px rgba(10,7,4,.6),0 1px 14px rgba(10,7,4,.35);
  max-width:64ch;line-height:1.9;
}
.proof-strip .rev-stars{color:#E9C989;text-shadow:0 1px 3px rgba(10,7,4,.6)}
@media (max-width:480px){
  .proof-strip{font-size:11px;letter-spacing:.14em;max-width:30ch} /* wraps to 2 lines */
}

/* ---------- .cta-secondary : quiet underlined secondary ask ---------- */
.cta-secondary{
  display:inline-block;
  font-size:14.5px;line-height:1.6;color:var(--ink-80);
  text-decoration:underline;text-decoration-color:color-mix(in srgb,var(--umber) 55%,transparent);
  text-underline-offset:4px;text-decoration-thickness:1px;
  transition:color .3s ease,text-decoration-color .3s ease;
}
.cta-secondary:hover{color:var(--ink);text-decoration-color:var(--umber)}
/* on the hero (dark scrim) it reads light */
.hero .cta-secondary{
  color:var(--paper-hi);
  text-decoration-color:color-mix(in srgb,#FBF8F1 55%,transparent);
  text-shadow:0 1px 3px rgba(10,7,4,.55);
}
.hero .cta-secondary:hover{color:#fff;text-decoration-color:#FBF8F1}

/* ---------- .nav-cta activation (pill sits right of navlinks) ---------- */
.nav .nav-cta{white-space:nowrap;margin-left:clamp(10px,1.4vw,18px)}
@media (max-width:1120px){ /* W4 NAV FIT: was 920px · 6th link (Pricing) crammed the desktop nav 921-1119px (brand-links gap <20px); links show from 1121px where the gap is 22px+ */
  /* keep the pill visible next to the menu button on mobile */
  .nav .nav-cta{display:inline-flex;margin-left:0;margin-right:16px;padding:8px 14px;font-size:10.5px}
}
@media (max-width:480px){ .nav .nav-cta{display:none} } /* FAB covers contact at this size */

/* ---------- .chapters-index : hairline-ruled 4-row index ----------
   markup: <div class="chapters-index">
             <a class="ci-row" href="...">
               <span class="ci-no">01</span>
               <span class="ci-label">Selling</span>
               <span class="ci-line">One plain line about it.</span>
               <span class="viewlink"><span class="ln"></span>View</span>
             </a> ... </div> */
.chapters-index{border-bottom:1px solid var(--line-soft);margin-top:clamp(28px,4vw,56px)}
.ci-row{
  display:grid;
  grid-template-columns:clamp(40px,5vw,72px) minmax(150px,.75fr) 1.5fr auto;
  gap:clamp(14px,2.4vw,40px);
  align-items:baseline;
  padding:clamp(20px,2.6vw,34px) 0;
  border-top:1px solid var(--line-soft);
  transition:padding-left .5s cubic-bezier(.22,1,.36,1),background .5s ease;
}
.ci-row:hover{padding-left:clamp(10px,1.4vw,22px)}
.ci-no{font-family:var(--serif);font-size:clamp(18px,1.8vw,26px);color:var(--umber);line-height:1}
.ci-label{font-family:var(--serif);font-weight:400;font-size:clamp(24px,3vw,42px);line-height:1.08;letter-spacing:-.005em;color:var(--ink)}
.ci-line{font-size:15px;line-height:1.6;color:var(--ink-60);max-width:46ch}
.ci-row .viewlink{justify-self:end}
.ci-row:hover .viewlink .ln{width:84px}
@media (max-width:900px){
  .ci-row{grid-template-columns:clamp(36px,6vw,56px) 1fr auto;grid-template-areas:"no label view" "no line line"}
  .ci-no{grid-area:no}.ci-label{grid-area:label}.ci-line{grid-area:line;margin-top:6px}.ci-row .viewlink{grid-area:view}
}
@media (max-width:600px){
  .ci-row{grid-template-columns:auto 1fr;grid-template-areas:"no label" "line line" "view view";gap:10px 14px;padding:20px 0}
  .ci-row:hover{padding-left:0}
  .ci-row .viewlink{justify-self:start;margin-top:2px}
}

/* ---------- .bench-row : legacy bench hairline rows ----------
   markup: <div class="bench-row">
             <span class="bn">01</span><span class="brole">Estate planning</span>
             <span class="bpartner">Summit Planners</span>
             <span class="bline">What they do for you, in one line.</span>
           </div>  (last row followed by .bench-rows container border) */
.bench-rows{border-bottom:1px solid var(--line-soft)}
.bench-row{
  display:grid;
  grid-template-columns:clamp(36px,4vw,60px) minmax(140px,.7fr) minmax(140px,.7fr) 1.4fr;
  gap:clamp(12px,2vw,36px);
  align-items:baseline;
  padding:clamp(18px,2.2vw,28px) 0;
  border-top:1px solid var(--line-soft);
}
.bench-row .bn{font-family:var(--serif);font-size:clamp(17px,1.6vw,24px);color:var(--umber);line-height:1}
.bench-row .brole{font-family:var(--caps);font-size:11.5px;letter-spacing:.18em;text-transform:uppercase;color:var(--ink-80)}
.bench-row .bpartner{font-family:var(--serif);font-size:clamp(17px,1.7vw,23px);line-height:1.2;color:var(--ink)}
.bench-row .bline{font-size:14.5px;line-height:1.6;color:var(--ink-60);max-width:44ch}
@media (max-width:700px){
  .bench-row{grid-template-columns:auto 1fr;grid-template-areas:"bn brole" "bn bpartner" "bline bline";gap:6px 14px}
  .bench-row .bn{grid-area:bn}.bench-row .brole{grid-area:brole}
  .bench-row .bpartner{grid-area:bpartner}.bench-row .bline{grid-area:bline;margin-top:6px}
}

/* ---------- .stat-display : About stats at display scale ----------
   markup: <div class="stat-display">
             <div class="stat"><span class="stat-n">5.0</span><span class="stat-l">PropertyGuru rating</span></div> ... */
.stat-display{
  display:grid;grid-template-columns:repeat(3,1fr);
  gap:clamp(20px,3vw,48px);
  margin-top:clamp(30px,4vw,56px);
}
.stat-display .stat{
  border-top:1px solid var(--line);
  padding-top:clamp(16px,2vw,26px);
  display:flex;flex-direction:column;gap:10px;
}
.stat-display .stat-n{
  font-family:var(--serif);font-weight:400;
  font-size:clamp(56px,8vw,120px);line-height:.95;letter-spacing:-.02em;color:var(--ink);
}
.stat-display~.stat-caption{
  margin-top:clamp(14px,1.8vw,22px);
  font-family:var(--caps);font-size:10.5px;letter-spacing:.22em;text-transform:uppercase;
  color:var(--ink-60);line-height:1.8;
}
.stat-display .stat-l{
  font-family:var(--caps);font-size:11.5px;letter-spacing:.2em;text-transform:uppercase;color:var(--ink-60);
  margin-top:auto; /* A2: labels sit on a shared baseline across cells */
}
@media (max-width:600px){ .stat-display{grid-template-columns:1fr;gap:22px} }

/* ---------- .faq-rows : plain answers, hairline rows ----------
   markup: <div class="faq-rows">
             <div class="faq-row"><h3>What it costs</h3><p>...</p></div> ... */
.faq-rows{border-bottom:1px solid var(--line-soft);margin-top:clamp(26px,3.4vw,48px)}
.faq-row{
  display:grid;grid-template-columns:minmax(200px,.55fr) 1fr;
  gap:clamp(14px,2.4vw,44px);
  padding:clamp(20px,2.6vw,34px) 0;
  border-top:1px solid var(--line-soft);
}
.faq-row h3{font-family:var(--serif);font-weight:400;font-size:clamp(19px,1.9vw,27px);line-height:1.2;color:var(--ink)}
.faq-row p{font-size:15px;line-height:1.7;color:var(--ink-80);max-width:64ch}
@media (max-width:600px){ .faq-row{grid-template-columns:1fr;gap:10px;padding:20px 0} }

/* ---------- film: click-to-play ring ---------- */
.film-feat,[data-film]{position:relative}
.play-ring{
  position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);
  z-index:3;
  width:clamp(104px,12vw,140px);height:clamp(104px,12vw,140px);
  display:flex;align-items:center;justify-content:center;text-align:center;
  border:1px solid color-mix(in srgb,#FBF8F1 75%,transparent);
  border-radius:50%;
  background:color-mix(in srgb,rgba(20,16,10,.35) 100%,transparent);
  -webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);
  color:var(--paper-hi);
  font-family:var(--caps);font-size:11px;letter-spacing:.22em;text-transform:uppercase;
  line-height:1.6;cursor:pointer;padding:12px;
  transition:transform .5s cubic-bezier(.22,1,.36,1),background .4s ease,border-color .4s ease;
}
.play-ring:hover{transform:translate(-50%,-50%) scale(1.06);background:rgba(20,16,10,.5);border-color:#FBF8F1}
.play-ring[hidden]{display:none}
.film-cap{margin-top:clamp(14px,1.8vw,20px);font-size:14px;color:var(--ink-60);text-align:center}

/* ---------- .wa-fab v2 : ivory pill (desktop) / ivory circle (mobile) ---------- */
.wa-fab{
  width:auto;height:auto;
  gap:10px;
  padding:14px 22px;
  border-radius:999px;
  background:var(--paper-hi);
  color:var(--ink);
  border:1px solid var(--line);
  box-shadow:0 10px 30px rgba(20,17,13,.18);
}
.wa-fab svg{width:20px;height:20px;flex:none}
.wa-fab::after{
  content:"WhatsApp";
  font-family:var(--caps);font-size:11.5px;letter-spacing:.2em;text-transform:uppercase;
  color:inherit;line-height:1;
}
.wa-fab:hover,.wa-fab:focus-visible{
  transform:translateY(-3px);
  color:#1FAD53; /* WhatsApp green accent, hover/focus only */
  border-color:#25D366;
  box-shadow:0 16px 40px rgba(20,17,13,.24);
}
@media (max-width:820px){ /* A4: was 760px — wide pill overlapped .bio-col text 761-830px */
  .wa-fab{width:56px;height:56px;padding:0;justify-content:center}
  .wa-fab::after{content:none}
  .wa-fab svg{width:26px;height:26px}
}
/* never let the FAB collide with hero micro-meta on small phones */
@media (max-width:480px){
  .hero-meta,.scrollcue{display:none}
}

/* ---------- QA fix pass (2026-07-02) ---------- */
/* FAB safe zone: band captions and the About bio column never run under the
   bottom-right WhatsApp pill */
@media (min-width:760px){
  .bleed-cap,.warm-band .cap{padding-right:clamp(190px,15vw,240px)}
  .bio-col{padding-right:clamp(70px,9vw,160px)}
}
/* tap targets: >=24px hit height on hairline links, no visual shift */
.viewlink,.foot-social a{padding-block:8px;margin-block:-8px}
/* chapter-page deck: air between the lede and the bleed below it */
.page-top{padding-bottom:24px}

/* ---------- end v2 rebuild block ---------- */


/* ================================================================
   ============  WAVE 2 BLOCK (2026-07-02 · wave2-plan §A)  =======
   Shared components + device-fix pass. Appended after the V2 block
   on purpose: later rules win. Builders consume the classes below;
   markup contracts are in the comments. Register: ivory / hairline /
   Cinzel — no radii on cards, no colored fills, no icons.
   ================================================================ */

/* ---------- A1 · .log-card : the viewing-log facsimile ----------
   markup: <aside class="log-card">
             <div class="lc-row"><span class="lc-k">Viewing 04</span>
               <span class="lc-v">Saturday 3.20pm</span></div> …
             <p class="lc-note">A sample entry, illustrative. …</p>
           </aside>
   partial redaction: wrap the hidden words in <span class="redact">…</span> */
.log-card{
  background:var(--paper-hi);
  border:1px solid var(--line);
  box-shadow:0 20px 54px rgba(27,23,18,.10);
  padding:clamp(22px,2.8vw,38px) clamp(20px,2.4vw,34px);
  max-width:520px;
}
.log-card .lc-row{
  display:grid;
  grid-template-columns:minmax(112px,.44fr) 1fr;
  gap:4px clamp(14px,1.8vw,26px);
  align-items:baseline;
  padding:11px 0;
  border-top:1px solid var(--line-soft);
}
.log-card .lc-row:first-child{border-top:0;padding-top:0}
.log-card .lc-k{font-family:var(--caps);font-size:10px;letter-spacing:.24em;text-transform:uppercase;color:var(--ink-60);line-height:1.8}
.log-card .lc-v{font-family:var(--sans);font-size:14px;line-height:1.6;color:var(--ink-80)}
.log-card .redact{
  background:color-mix(in srgb, var(--ink) 70%, transparent);
  color:transparent;
  padding:0 .3em;
  -webkit-user-select:none;user-select:none;
}
.log-card .redact::selection{background:transparent;color:transparent}
.log-card .lc-note{
  margin-top:clamp(12px,1.6vw,18px);
  padding-top:12px;
  border-top:1px solid var(--line-soft);
  font-size:11px;line-height:1.65;color:var(--ink-60);
}
@media (max-width:400px){
  .log-card .lc-row{grid-template-columns:1fr;gap:2px}
}

/* ---------- A2 · .case-timeline : horizontal 4-node hairline timeline ----------
   markup: <ol class="case-timeline">
             <li><b>Two years</b><span>unsold elsewhere</span></li> ×4
           </ol> */
.case-timeline{
  list-style:none;margin:0;padding:0;
  display:grid;grid-template-columns:repeat(4,1fr);
  gap:clamp(18px,2.6vw,40px);
}
.case-timeline li{
  position:relative;
  border-top:1px solid var(--line);
  padding-top:clamp(16px,2vw,26px);
}
.case-timeline li::before{
  content:"";position:absolute;left:0;top:-3.5px;
  width:6px;height:6px;border-radius:50%;background:var(--umber);
}
.case-timeline b{
  display:block;font-family:var(--serif);font-weight:400;
  font-size:clamp(26px,2.8vw,42px);line-height:1.08;letter-spacing:-.01em;color:var(--ink);
}
.case-timeline span{
  display:block;margin-top:9px;
  font-family:var(--caps);font-size:10.5px;letter-spacing:.2em;text-transform:uppercase;
  color:var(--ink-60);line-height:1.7;
}
@media (max-width:760px){ .case-timeline{grid-template-columns:repeat(2,1fr);gap:24px clamp(18px,4vw,32px)} }
@media (max-width:460px){ .case-timeline{grid-template-columns:1fr;gap:20px} }

/* ---------- A3 · .pull-stats : slim numeric stat band ----------
   markup: <div class="pull-stats">
             <div class="ps"><b data-count="79">79</b><span>homes in three years</span></div> …
           </div>
   JS counts [data-count] up on enter (~1.2s, once); reduced-motion renders final. */
.pull-stats{
  display:grid;
  grid-template-columns:repeat(auto-fit,minmax(170px,1fr));
  gap:clamp(20px,3vw,48px);
  padding:clamp(26px,3.4vw,50px) 0;
  border-top:1px solid var(--line);
  border-bottom:1px solid var(--line);
}
.pull-stats .ps b{
  display:block;font-family:var(--serif);font-weight:400;
  font-size:clamp(40px,5vw,72px);line-height:1;letter-spacing:-.015em;color:var(--ink);
  font-variant-numeric:tabular-nums;
}
.pull-stats .ps span{
  display:block;margin-top:10px;
  font-family:var(--caps);font-size:10.5px;letter-spacing:.2em;text-transform:uppercase;
  color:var(--ink-60);line-height:1.7;
}
@media (max-width:460px){ .pull-stats{grid-template-columns:1fr;gap:24px} }

/* ---------- A4 · .ground-strip : stylised ink-on-cream ground band ----------
   markup: <div class="ground-strip">
             <span class="gs-node"><i></i>Serangoon Gardens</span> ×5
           </div>
   One hairline, node ticks, names alternating above/below. JS adds .in on
   enter (draw-in); reduced-motion / no-js / ?shot render it drawn. */
.ground-strip{
  position:relative;
  display:flex;justify-content:space-between;align-items:flex-start;
  height:128px;
  margin-block:clamp(30px,4vw,56px);
}
.ground-strip::before{
  content:"";position:absolute;left:0;right:0;top:50%;height:1px;background:var(--line);
  transform:scaleX(0);transform-origin:left center;
  transition:transform 1.5s cubic-bezier(.22,1,.36,1);
}
.ground-strip.in::before{transform:scale(1)}
.ground-strip .gs-node{
  position:relative;height:50%;
  display:flex;align-items:flex-end;padding-bottom:16px;
  font-family:var(--caps);font-size:10.5px;letter-spacing:.18em;text-transform:uppercase;
  color:var(--ink-80);line-height:1.5;text-align:center;
  opacity:0;transition:opacity .9s ease;
}
.ground-strip.in .gs-node{opacity:1}
.ground-strip .gs-node:nth-child(1){transition-delay:.25s}
.ground-strip .gs-node:nth-child(2){transition-delay:.4s}
.ground-strip .gs-node:nth-child(3){transition-delay:.55s}
.ground-strip .gs-node:nth-child(4){transition-delay:.7s}
.ground-strip .gs-node:nth-child(5){transition-delay:.85s}
.ground-strip .gs-node:nth-child(even){
  align-self:flex-end;align-items:flex-start;
  padding-bottom:0;padding-top:16px;
}
.ground-strip .gs-node i{
  position:absolute;left:50%;bottom:0;
  width:1px;height:9px;background:var(--ink-60);
}
.ground-strip .gs-node i::after{ /* node dot sitting on the line */
  content:"";position:absolute;left:50%;bottom:-2.5px;transform:translateX(-50%);
  width:5px;height:5px;border-radius:50%;background:var(--umber);
}
.ground-strip .gs-node:nth-child(even) i{bottom:auto;top:0}
.ground-strip .gs-node:nth-child(even) i::after{bottom:auto;top:-2.5px}
html.no-js .ground-strip::before,html.shot .ground-strip::before{transform:scale(1);transition:none}
html.no-js .ground-strip .gs-node,html.shot .ground-strip .gs-node{opacity:1;transition:none}
@media (prefers-reduced-motion: reduce){
  .ground-strip::before{transform:scale(1);transition:none}
  .ground-strip .gs-node{opacity:1;transition:none}
}
@media (max-width:600px){ /* vertical fallback: hairline down the left */
  .ground-strip{display:block;height:auto;padding-left:24px}
  .ground-strip::before{left:2px;right:auto;top:3px;bottom:3px;width:1px;height:auto;
    transform:scaleY(0);transform-origin:center top}
  .ground-strip .gs-node,
  .ground-strip .gs-node:nth-child(even){
    display:block;height:auto;padding:9px 0;text-align:left;align-self:auto;
  }
  .ground-strip .gs-node i,
  .ground-strip .gs-node:nth-child(even) i{
    left:-22px;right:auto;top:calc(50% - .5px);bottom:auto;width:12px;height:1px;
  }
  .ground-strip .gs-node i::after,
  .ground-strip .gs-node:nth-child(even) i::after{
    left:-2px;top:-2px;bottom:auto;transform:none;
  }
}

/* ---------- A5 · .arc-3 / .arc-3-wrap : three-node holding arc ----------
   markup: <ol class="arc-3">
             <li><b>The way in</b><p>two quiet lines…</p></li> ×3
           </ol>
   wrap:   <div class="arc-3-wrap">
             <div>…heading + intro + .arc-3…</div>
             <figure class="arc-rail"><img …><img …></figure>
           </div>  (rail is sticky ≥900px) */
.arc-3{
  list-style:none;margin:0;padding:0;
  display:grid;grid-template-columns:repeat(3,1fr);
  gap:clamp(20px,3vw,44px);
}
.arc-3 li{position:relative;border-top:1px solid var(--line);padding-top:clamp(16px,2vw,26px)}
.arc-3 li::before{
  content:"";position:absolute;left:0;top:-3.5px;
  width:6px;height:6px;border-radius:50%;background:var(--umber);
}
.arc-3 b,.arc-3 h3{
  display:block;font-family:var(--serif);font-weight:400;
  font-size:clamp(20px,2vw,28px);line-height:1.15;letter-spacing:-.005em;color:var(--ink);
}
.arc-3 p,.arc-3 li>span{display:block;margin-top:10px;font-size:14.5px;line-height:1.65;color:var(--ink-60);max-width:34ch}
@media (max-width:760px){ .arc-3{grid-template-columns:1fr;gap:24px} }
.arc-3-wrap{display:grid;grid-template-columns:1fr;gap:clamp(28px,4vw,56px);align-items:start}
.arc-3-wrap .arc-rail{display:flex;flex-direction:column;gap:clamp(14px,1.8vw,24px);margin:0}
.arc-3-wrap .arc-rail img{width:100%;height:auto}
@media (min-width:900px){
  .arc-3-wrap{grid-template-columns:1.15fr .85fr;gap:clamp(36px,5vw,84px)}
  .arc-3-wrap .arc-rail{position:sticky;top:12vh}
  /* P1 fix: when the text column carries .arc-copy, IT pins and the taller
     rail scrolls past (sticky on the taller child never engages). Scoped so
     plain .arc-rail keeps its sticky if the class is reused elsewhere. */
  .arc-3-wrap .arc-copy{position:sticky;top:12vh;align-self:start}
  .arc-3-wrap .arc-copy~.arc-rail{position:static}
}
/* P1 fix (mobile): rail figures fill the column; no orphan inset thirds */
@media (max-width:899px){
  .arc-3-wrap .arc-rail figure{margin:0!important;width:100%!important}
}

/* ---------- A6 · .line-family : legacy lineage device ----------
   markup: <div class="line-family">
             <div class="lf-row"><b>The home</b><span>one quiet line</span></div> ×3
           </div> */
.line-family{
  position:relative;
  display:flex;flex-direction:column;gap:clamp(24px,3vw,38px);
  padding-left:clamp(24px,3vw,36px);
  max-width:46ch;
}
.line-family::before{content:"";position:absolute;left:2px;top:8px;bottom:8px;width:1px;background:var(--line)}
.line-family .lf-row{position:relative}
.line-family .lf-row::before{
  content:"";position:absolute;top:.5em;left:calc(-1*clamp(24px,3vw,36px));
  width:5px;height:5px;border-radius:50%;background:var(--umber);
}
.line-family b,.line-family h3{
  display:block;font-family:var(--serif);font-weight:400;
  font-size:clamp(20px,2.2vw,30px);line-height:1.15;color:var(--ink);
}
.line-family .lf-row span,.line-family .lf-row p{
  display:block;margin-top:6px;font-size:14.5px;line-height:1.6;color:var(--ink-60);
}

/* ---------- A7 · .colophon : per-page one-line disclaimer above the footer ---------- */
.colophon{
  text-align:center;
  font-family:var(--caps);font-size:10.5px;letter-spacing:.22em;text-transform:uppercase;
  color:var(--ink-60);
  padding:clamp(28px,4vw,48px) var(--gut);
  line-height:1.9;
}

/* ---------- A8 · ambient hero loops (motion-plan.md, authoritative) ----------
   Layered video above the untouched still; crossfades in only once actually
   playing (JS adds .is-playing/.playing). Hidden <760px and under
   reduced-motion so the webp still shows and zero video bytes are fetched. */
.amb-loop{position:relative;overflow:hidden}
.bleed-media .loop-video,.amb-loop video{
  position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  opacity:0;transition:opacity .9s ease;
}
.bleed-media .loop-video.is-playing,.bleed-media .loop-video.playing,
.amb-loop video.is-playing,.amb-loop video.playing{opacity:1}
@media (max-width:759.98px), (prefers-reduced-motion: reduce){
  .bleed-media .loop-video,.amb-loop video{display:none}
}
html.shot .bleed-media .loop-video,html.shot .amb-loop video{display:none}

/* ---------- A9 · pc-stack: first frame never lost without JS/motion ---------- */
html.no-js .pc-stack img:first-child,html.shot .pc-stack img:first-child{opacity:1;transform:none}
@media (prefers-reduced-motion: reduce){
  .pc-stack img:first-child{opacity:1;transform:none}
}

/* ---------- A10 · form v3: textarea matches the input underline style ---------- */
form[data-wa] textarea{
  display:block;width:100%;
  background:none;border:0;border-bottom:1px solid var(--line);border-radius:0;
  padding:10px 0;margin-bottom:6px;
  font:inherit;line-height:1.5;color:var(--ink);
  resize:vertical;min-height:2.4em;
}
form[data-wa] textarea:focus-visible{
  outline:none;
  border-bottom-color:var(--umber);
  box-shadow:0 1px 0 0 var(--umber);
}

/* ---------- device-fix pass (12-viewport compatibility test, 2026-07-02) ---------- */
/* D3: index hero-meta clock clears the WhatsApp pill (768-1200px) */
@media (min-width:481px){ .hero-meta{padding-right:clamp(150px,13vw,210px)} }
/* D4: phones — band-caption tails clear the FAB circle */
@media (max-width:759px){ .bleed-cap,.warm-band .cap{padding-right:76px} }
/* D5: tap targets on hairline links (hit area only, no visual shift) */
.addr a,.cta-secondary{padding-block:8px;margin-block:-8px}
/* D6: selling four-fact caps row (builder A applies the class) */
.fact-row{display:grid;grid-template-columns:repeat(2,1fr);gap:clamp(16px,2.4vw,36px)}
@media (min-width:900px){ .fact-row{grid-template-columns:repeat(4,1fr)} }
@media (max-width:460px){ .fact-row{grid-template-columns:1fr} }
/* D7: proof strip trims its tail on small phones (builder A adds the span) */
@media (max-width:480px){ .proof-strip .extra{display:none} }

/* ---------- end wave 2 block ---------- */

/* ---- FINAL QA POLISH (post wave-2) ---- */
.case-timeline{margin-top:clamp(28px,3vw,44px)}
.rev-card .rev-by{margin-top:auto;padding-top:14px}

/* ============================================================================
   WAVE 3 BLOCK · .photo-close — closing-CTA pattern (cta-photo-plan.md §1)
   ============================================================================
   FINAL CLASS NAMES (collision-checked against the legacy .pc-grid/.pc-stack
   pillar component and all izanami.js hooks — NO rename needed, use as planned):
     .photo-close          the 2-col wrapper (add .flip to mirror: image RIGHT)
     .pc-fig               the figure — MUST also carry class "reveal"
     .pc-body              the existing close content, moved in unchanged

   EXPECTED MARKUP (builders):
   <div class="photo-close">                    <!-- or class="photo-close flip" -->
     <figure class="pc-fig reveal">
       <img src="images/gen3-cta-tea.webp" width="…" height="…" loading="lazy"
            alt="…" style="object-position:50% 30%">  <!-- tune crop per image -->
       <figcaption>Optional one line in her voice.</figcaption>
     </figure>
     <div class="pc-body">
       …existing close content verbatim: .eyebrow, .statement, .cta-line,
       .cta-btn, .cta-secondary, tel line, viewlinks row (all keep their
       inline margins — nothing needs restyling)…
     </div>
   </div>

   NOTES:
   - The 4/5 (desktop) / 4/3 (≤899px) aspect lives on the IMG, not the figure,
     so the optional figcaption flows below the photo without distorting the
     ratio box (same as every existing .reveal figure on the site). Builders:
     do NOT add inline aspect-ratio — only object-position if needed.
   - The unveil animation is inherited automatically: izanami.js wires every
     ".reveal" (clip reveal + slow scale + 4% img parallax) and the still/no-js
     path adds .in — no JS change was required, works as a grid item.
   - ≤899px the component stacks image-FIRST in source order (figure is first
     in the markup); .flip has no effect below 900px by design.
   ========================================================================== */
.photo-close{display:block}
@media (min-width:900px){
  .photo-close{display:grid;grid-template-columns:minmax(300px,.9fr) 1.4fr;
    gap:clamp(32px,5vw,80px);align-items:center}
  .photo-close.flip>.pc-fig{order:2}
  .photo-close.flip>.pc-body{order:1}
}
.pc-fig{margin:0;position:relative;overflow:hidden;border-radius:2px}
.pc-fig img{display:block;width:100%;height:auto;aspect-ratio:4/5;object-fit:cover}
.pc-fig figcaption{margin-top:12px;font-family:var(--serif);font-style:italic;
  font-size:15px;line-height:1.55;color:var(--ink-60)}
@media (max-width:899.98px){
  .pc-fig{margin:0 0 clamp(26px,7vw,38px)}
  .pc-fig img{aspect-ratio:4/3}
}
/* nested close content: kill any stray top gap so align-items:center is true */
.pc-body>:first-child{margin-top:0}
/* ---------- end wave 3 block ---------- */

/* flip variant: mirror column WIDTHS too (order alone put the image in the wide track) */
@media (min-width:900px){
  .photo-close.flip{grid-template-columns:1.4fr minmax(300px,.9fr)}
}

/* ================================================================
   ============  WAVE 4 BLOCK (2026-07-03 · pricing-plan.md)  =====
   Pricing page components. Appended last on purpose: later rules
   win. Register: ivory / hairline / Playfair numerals / Cinzel caps
   — no border-radius, no colored fills, no icon fonts. The only
   glyphs are the small ◆ tick and the faint "·" for excluded rows.
   ================================================================ */

/* ---------- W4.1 · .price-tiers : two hairline-framed rate columns ----------
   markup: <div class="price-tiers">
             <article class="price-tier">
               <span class="tier-no">i.</span>
               <p class="tier-label">Option one</p>
               <h2 class="tier-name">Well sold</h2>
               <div class="tier-rate"><span class="rate">2.0<em>%</em></span>
                 <span class="rate-of">of sale price</span></div>
               <p class="tier-line">…</p>
               <p class="tier-note">…</p>
             </article> ×2 </div>
   Side by side ≥760px, stacked below. The note is pinned to the card
   foot (margin-top:auto) so both cards close on the same line. */
.price-tiers{
  display:grid;grid-template-columns:1fr 1fr;
  gap:clamp(18px,2.4vw,40px);
  margin-top:clamp(30px,4vw,56px);
}
.price-tier{
  position:relative;
  border:1px solid var(--line);
  padding:clamp(26px,3.4vw,52px) clamp(22px,3vw,46px);
  display:flex;flex-direction:column;
}
.price-tier .tier-no{font-family:var(--serif);font-size:clamp(20px,2vw,28px);color:var(--umber);line-height:1}
.price-tier .tier-label{
  font-family:var(--caps);font-size:11px;letter-spacing:.24em;text-transform:uppercase;
  color:var(--ink-60);margin-top:clamp(12px,1.4vw,18px);
}
.price-tier .tier-name{
  font-family:var(--serif);font-weight:400;
  font-size:clamp(28px,3vw,44px);line-height:1.08;letter-spacing:-.005em;
  color:var(--ink);margin-top:8px;
}
.price-tier .tier-rate{
  margin-top:clamp(18px,2.4vw,30px);
  padding-top:clamp(16px,2vw,26px);
  border-top:1px solid var(--line-soft);
}
.price-tier .rate{
  display:block;font-family:var(--serif);font-weight:400;
  font-size:clamp(56px,6.4vw,104px);line-height:.95;letter-spacing:-.02em;
  color:var(--ink);font-variant-numeric:tabular-nums;
}
.price-tier .rate em{font-style:normal;font-size:.46em}
.price-tier .rate-of{
  display:block;margin-top:10px;
  font-family:var(--caps);font-size:11px;letter-spacing:.22em;text-transform:uppercase;
  color:var(--ink-60);
}
.price-tier .tier-line{
  margin-top:clamp(16px,2vw,24px);margin-bottom:clamp(18px,2.4vw,30px);
  font-size:15px;line-height:1.7;color:var(--ink-80);max-width:44ch;
}
.price-tier .tier-note{
  margin-top:auto;
  padding-top:clamp(16px,2vw,24px);
  border-top:1px solid var(--line-soft);
  font-family:var(--caps);font-size:10.5px;letter-spacing:.2em;text-transform:uppercase;
  color:var(--ink-60);line-height:1.8;
}
@media (max-width:760px){
  .price-tiers{grid-template-columns:1fr;gap:16px}
}

/* ---------- W4.2 · .price-table : grouped hairline comparison rows ----------
   markup: <div class="price-table">
             <div class="pt-head">
               <span class="pt-h-blank" aria-hidden="true"></span>
               <span class="pt-h">Well sold · 2.0%</span>
               <span class="pt-h">Seen first · 2.5%</span>
             </div>
             <div class="pt-group"><span class="g-no">i.</span>
               <span class="g-name">What gets made about your home</span></div>
             <div class="pt-row">
               <span class="pt-feat"><b>Row name</b>
                 <span class="pt-sub">one-line sub</span></span>
               <span class="pt-cell"><span class="tick" role="img"
                 aria-label="Included in Well sold">◆</span></span>
               <span class="pt-cell"><span class="no-tick"
                 aria-label="Not included in Well sold">·</span></span>
               <span class="pt-tags">Well sold · Seen first</span>
             </div> … </div>
   Ticks are text glyphs, never icon fonts. ≤600px the tick columns and
   header vanish and each row shows .pt-tags (Cinzel micro-labels naming
   the options that include it) — stacked, no horizontal scroll. */
.price-table{margin-top:clamp(30px,4vw,56px);border-bottom:1px solid var(--line)}
.pt-head,.pt-row{
  display:grid;
  grid-template-columns:1fr clamp(112px,13vw,170px) clamp(112px,13vw,170px);
  gap:clamp(10px,1.8vw,30px);
  align-items:center;
}
.pt-head{padding-bottom:14px;border-bottom:1px solid var(--line);align-items:end}
.pt-h{
  font-family:var(--caps);font-size:11px;letter-spacing:.16em;text-transform:uppercase;
  color:var(--ink-80);text-align:center;line-height:1.7;
}
.pt-group{
  display:flex;align-items:baseline;gap:clamp(10px,1.4vw,16px);
  padding:clamp(26px,3.4vw,44px) 0 12px;
}
.pt-group .g-no{font-family:var(--serif);font-size:clamp(18px,1.8vw,26px);color:var(--umber);line-height:1}
.pt-group .g-name{
  font-family:var(--caps);font-size:11.5px;letter-spacing:.22em;text-transform:uppercase;
  color:var(--ink-80);line-height:1.7;
}
.pt-row{padding:clamp(13px,1.7vw,19px) 0;border-top:1px solid var(--line-soft)}
.pt-feat b{
  display:block;font-family:var(--serif);font-weight:400;
  font-size:clamp(17px,1.7vw,22px);line-height:1.3;color:var(--ink);
}
.pt-feat .pt-sub{display:block;margin-top:3px;font-size:13.5px;line-height:1.55;color:var(--ink-60);max-width:52ch}
.pt-cell{text-align:center}
.pt-cell .tick{color:var(--umber);font-size:11px;line-height:1}
.pt-cell .no-tick{display:inline-block;width:12px;height:1px;background:var(--ink-40);vertical-align:middle;overflow:hidden;color:transparent;font-size:0;line-height:0}
.pt-tags{display:none}
@media (max-width:600px){
  .pt-head{display:none}
  .pt-cell{display:none}
  .pt-row{grid-template-columns:1fr;gap:0;padding:15px 0}
  .pt-tags{
    display:block;margin-top:8px;
    font-family:var(--caps);font-size:10px;letter-spacing:.2em;text-transform:uppercase;
    color:var(--ink-60);line-height:1.7;
  }
  .pt-tags::before{content:"◆  ";color:var(--umber);font-size:8.5px}
  .pt-group{padding:26px 0 4px}
}

/* ---------- W4.3 · .arc-3 numbered variant (Seen first unlocks) ----------
   markup: <li><span class="u-no">01</span><b>Styled renovation previews</b>
             <p>one line</p></li> */
.arc-3 .u-no{
  display:block;font-family:var(--serif);font-size:clamp(18px,1.8vw,24px);
  color:var(--umber);line-height:1;margin-bottom:10px;
}

/* ---------- W4.4 · tier v2 : 21:9 image header + overlapping rate ----------
   markup (inside .price-tier, before everything else):
   <figure class="tier-media"><img … loading="lazy"></figure>
   <div class="tier-rate over"><span class="rate">2.0<em>%</em></span>
     <span class="rate-of">of sale price</span></div>
   <span class="tier-no">i.</span> …
   The figure bleeds to the card border (negative margins cancel the card
   padding). The rate block notches up over the image's bottom edge on a
   paper panel flush with the card's left border. Collapses cleanly at any
   width because every offset is derived from the same card-padding clamps. */
.price-tier .tier-media{
  margin:calc(-1*clamp(26px,3.4vw,52px)) calc(-1*clamp(22px,3vw,46px)) 0;
  overflow:hidden;
}
.price-tier .tier-media img{display:block;width:100%;height:auto;aspect-ratio:21/9;object-fit:cover}
.price-tier .tier-rate.over{
  position:relative;z-index:2;
  align-self:flex-start;
  margin-top:calc(-1*clamp(30px,3.8vw,58px));
  margin-left:calc(-1*clamp(22px,3vw,46px));
  padding:clamp(12px,1.6vw,20px) clamp(20px,2.6vw,36px) 0 clamp(22px,3vw,46px);
  background:var(--paper);
  border-top:0;
}
.price-tier .tier-media~.tier-no{margin-top:clamp(16px,2vw,26px)}
.price-tier .tier-kicker{
  font-family:var(--caps);font-size:10.5px;letter-spacing:.22em;text-transform:uppercase;
  color:var(--umber);margin-top:10px;line-height:1.7;
}

/* ---------- W4.5 · .pt-proof : the viewing-log artifact under group iii ----------
   markup: <div class="pt-proof">
             <div class="pp-copy">…eyebrow + body…</div>
             <aside class="log-card">…</aside>
           </div>
   Copy left, log-card right ≥900px; stacked below. */
.pt-proof{
  display:grid;grid-template-columns:1fr;
  gap:clamp(24px,3.4vw,44px);
  margin-top:clamp(30px,4vw,54px);
}
@media (min-width:900px){
  .pt-proof{grid-template-columns:1fr minmax(360px,480px);align-items:center;gap:clamp(36px,5vw,84px)}
  .pt-proof .log-card{justify-self:end;width:100%}
}

/* ---------- W4.6 · .work-wrap : v-items left, sticky two-figure rail right ----------
   markup: <div class="work-wrap">
             <div class="work-copy">…single-column .diff-grid…</div>
             <div class="work-rail"><figure class="reveal">…</figure> ×2</div>
           </div>
   Rail is shorter than the copy, so sticky goes on the RAIL (arc-3-wrap's
   .arc-copy inversion is not needed here). */
.work-wrap{
  display:grid;grid-template-columns:1fr;
  gap:clamp(28px,4vw,56px);align-items:start;
}
.work-wrap .diff-grid{grid-template-columns:1fr;margin-top:clamp(26px,3vw,44px)}
.work-wrap .work-rail{display:flex;flex-direction:column;gap:clamp(18px,2.4vw,30px)}
.work-wrap .work-rail figure{margin:0}
.work-wrap .work-rail img{display:block;width:100%;height:auto;aspect-ratio:3/2;object-fit:cover}
.work-wrap .work-rail figcaption{
  margin-top:12px;font-family:var(--serif);font-style:italic;
  font-size:15px;line-height:1.55;color:var(--ink-60);
}
@media (min-width:900px){
  .work-wrap{grid-template-columns:1.1fr .9fr;gap:clamp(36px,5vw,84px)}
  .work-wrap .work-rail{position:sticky;top:10vh}
}

/* ---------- W4.7 · .unlock-3 : visual three-up (Seen first unlocks) ----------
   markup: <ol class="unlock-3">
             <li><figure><img …></figure>
               <span class="u-no">01</span><b>…</b><p>…</p></li>
             <li>…<div class="ledger" role="img" aria-label="…">
               <span class="lg-row lg-top">Your home<i></i>First in the results</span>
               <span class="lg-row" aria-hidden="true"><i></i></span> ×2
             </div>…</li>
           </ol>
   Cell 03 carries the typographic ledger device instead of a photo:
   three hairline rows, the top one in umber. Abstract, never a portal UI. */
.unlock-3{
  list-style:none;margin:clamp(30px,4vw,52px) 0 0;padding:0;
  display:grid;grid-template-columns:repeat(3,1fr);
  gap:clamp(20px,3vw,44px);
}
.unlock-3 li{position:relative;border-top:1px solid var(--line);padding-top:clamp(16px,2vw,26px)}
.unlock-3 li::before{
  content:"";position:absolute;left:0;top:-3.5px;
  width:6px;height:6px;border-radius:50%;background:var(--umber);
}
.unlock-3 figure{margin:0 0 clamp(14px,1.8vw,22px);overflow:hidden}
.unlock-3 figure img{display:block;width:100%;height:auto;aspect-ratio:16/9;object-fit:cover}
.unlock-3 .u-no{
  display:block;font-family:var(--serif);font-size:clamp(18px,1.8vw,24px);
  color:var(--umber);line-height:1;margin-bottom:10px;
}
.unlock-3 b{
  display:block;font-family:var(--serif);font-weight:400;
  font-size:clamp(20px,2vw,28px);line-height:1.15;color:var(--ink);
}
.unlock-3 p{margin-top:10px;font-size:14.5px;line-height:1.65;color:var(--ink-60);max-width:34ch}
.unlock-3 .ledger{
  aspect-ratio:16/9;
  border:1px solid var(--line);
  background:var(--paper-hi);
  box-shadow:0 20px 54px rgba(27,23,18,.08);
  margin:0 0 clamp(14px,1.8vw,22px);
  padding:clamp(14px,1.8vw,24px) clamp(16px,2vw,26px) clamp(10px,1.4vw,18px);
  display:flex;flex-direction:column;
}
.unlock-3 .ledger .lg-head{
  font-family:var(--caps);font-size:9.5px;letter-spacing:.26em;text-transform:uppercase;
  /* --ink-40 is a hairline value (2.99:1). These two are the only places it
     carried words a reader has to make out, so they take --ink-60 (5.2:1).
     Audit 2026-09-01, finding H1. */
  color:var(--ink-60);line-height:1.6;
  padding-bottom:clamp(8px,1vw,12px);
}
.unlock-3 .ledger .lg-row{
  flex:1;min-height:0;
  display:flex;align-items:center;gap:14px;
  border-top:1px solid var(--line-soft);
  font-family:var(--caps);font-size:11px;letter-spacing:.2em;text-transform:uppercase;
  line-height:1.5;
}
.unlock-3 .ledger .lg-top{
  flex:1.3;
  color:#7A5C3F;
  border-top:1px solid color-mix(in srgb, var(--umber) 45%, transparent);
}
.unlock-3 .ledger .lg-dia{font-style:normal;font-size:10px;line-height:1;color:var(--umber)}
.unlock-3 .ledger .lg-name{font-weight:500;white-space:nowrap}
.unlock-3 .ledger .lg-tag{
  margin-left:auto;font-size:9px;letter-spacing:.16em;
  color:var(--ink-60);white-space:nowrap;
}
.unlock-3 .ledger .lg-bar{height:6px;background:color-mix(in srgb, var(--ink) 9%, transparent)}
.unlock-3 .ledger .lg-bar+.lg-bar{margin-left:auto}
@media (max-width:820px){
  .unlock-3{grid-template-columns:1fr;gap:30px}
  .unlock-3 p{max-width:52ch}
}

/* ---------- end wave 4 block ---------- */

/* ---- A11Y GATE FIXES (pre-launch) ---- */
@media (prefers-reduced-motion:reduce){.scrollcue::after{animation:none}}
.warm-band .cap{background:linear-gradient(to top, rgba(38,28,16,.78), rgba(38,28,16,.30) 55%, transparent)}
.hero-eyebrow,html.webgl-hero .hero-eyebrow{text-shadow:0 1px 3px rgba(10,7,4,.75), 0 2px 14px rgba(10,7,4,.4)}
.stat-display .stat-n{margin-top:auto}
.log-card .redact{white-space:nowrap}
form[data-wa] textarea{resize:none;min-height:64px}

/* ---- TECH FOUNDATIONS (landmarks + skip link) ---- */
main{display:block}
.skip-link{position:fixed;top:18px;left:18px;z-index:300;width:1px;height:1px;overflow:hidden;white-space:nowrap;clip-path:inset(50%);padding:0;background:var(--paper-hi);color:var(--ink);border:1px solid var(--line);border-radius:999px;font-family:var(--caps);font-size:11px;letter-spacing:.22em;text-transform:uppercase;box-shadow:0 12px 32px rgba(27,23,18,.16)}
.skip-link:focus-visible{width:auto;height:auto;overflow:visible;clip-path:none;padding:12px 22px;outline:2px solid var(--umber);outline-offset:3px}

/* ===================== WAVE 5 BLOCK =====================
   1) First-paint note: the load curtain + hero intro were retimed in
      izanami.js (0.45s power3.out uncover starting immediately; hero image
      no longer opacity-faded; split headings render unsplit until fonts
      settle instead of being hidden). No CSS change was needed for that —
      .pt keeps its default transform:scaleY(0) so pre-JS / no-JS / ?shot
      paints are never covered.
   2) Clickability affordances (meeting decision 4): sub-page links must
      read unmistakably clickable, on touch as well as pointer. Everything
      stays in the ivory/hairline register — ink hairlines, paper tints,
      existing radii only. */

/* (a) .viewlink — persistent affordance: a hairline underline (offset, on
   the label text) plus a small trailing arrow that nudges right on hover.
   Both are visible at rest so touch devices get the affordance too. */
.viewlink{text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:6px;
  text-decoration-color:color-mix(in srgb, var(--ink) 34%, transparent);
  transition:text-decoration-color .4s ease}
.viewlink:hover{text-decoration-color:var(--ink)}
.viewlink::after{content:"\2192";font-family:var(--sans);font-size:14px;line-height:1;
  transform:translateX(0);transition:transform .5s cubic-bezier(.22,1,.36,1)}
.viewlink:hover::after{transform:translateX(6px)}

/* (b) .chapters-index rows — the whole row is the link. Default state keeps
   the nested .viewlink arrow visible (reads as a link before hover); hover
   adds a paper-hi tint behind the row (the existing padding-left slide and
   .ln growth remain) and slides the arrow. .ci-row already transitions
   `background`, so the tint eases in/out. */
.chapters-index .ci-row:hover{background:var(--paper-hi)}
.chapters-index .ci-row:hover .viewlink::after{transform:translateX(6px)}
.chapters-index .ci-row:hover .viewlink{text-decoration-color:var(--ink)}

/* (c) .btn-quiet — quiet bordered button for INTERNAL links.
   Contract: same shape/padding as .cta-btn (999px pill, 14px 30px, Cinzel
   caps 12px/.2em) but inverted register — 1px ink hairline on paper, ink
   text; hover swaps to ink fill / ivory text. Use for secondary journeys,
   e.g. <a class="btn-quiet" href="/selling">See how I sell a home</a>.
   Sits beside .cta-btn (solid ink = primary) without competing. */
.btn-quiet{display:inline-flex;align-items:center;gap:12px;font-family:var(--caps);font-size:12px;
  letter-spacing:.2em;text-transform:uppercase;color:var(--ink);background:var(--paper);
  border:1px solid var(--ink);border-radius:999px;padding:14px 30px;
  transition:background .4s ease,color .4s ease}
.btn-quiet:hover{background:var(--ink);color:var(--paper-hi)}

/* (d) touch devices: hover styling is inert there, but nothing above is
   hover-gated — underline + arrows render at rest, so the affordance holds. */
/* ---------- end wave 5 block ---------- */

/* ---------- discretion register: delayed FAB (audit move 8) ----------
   Pages whose <body> carries .fab-delay (prime, legacy) keep the WhatsApp
   FAB hidden at load; izanami.js adds .fab-on once the reader has scrolled
   past ~one viewport, and it fades/rises in. Still modes (?shot, reduced
   motion, no-JS) show it immediately. Pages without the class are
   untouched — base .wa-fab rules apply as before. */
body.fab-delay .wa-fab{
  opacity:0;transform:translateY(14px);pointer-events:none;
  animation:none; /* cancel the base wa-in entrance */
  transition:opacity .7s cubic-bezier(.22,1,.36,1),transform .7s cubic-bezier(.22,1,.36,1),
    box-shadow .35s ease,color .4s ease,border-color .4s ease;
}
body.fab-delay .wa-fab.fab-on{opacity:1;transform:translateY(0);pointer-events:auto}
body.fab-delay .wa-fab.fab-on:hover,
body.fab-delay .wa-fab.fab-on:focus-visible{transform:translateY(-3px)}
/* still modes: visible from first paint */
html.shot body.fab-delay .wa-fab,
html.no-js body.fab-delay .wa-fab{opacity:1;transform:none;pointer-events:auto}
@media (prefers-reduced-motion:reduce){
  body.fab-delay .wa-fab{opacity:1;transform:none;pointer-events:auto}
}

/* ============================================================
   TAP TARGETS · tel links (audit 2026-09-01, finding M2)
   The number rendered 104x17 on a phone. 44px is the minimum a
   finger can reliably hit, and this is the single action the
   oldest visitors are most likely to want.
   ============================================================ */
a[href^="tel:"]{display:inline-block;min-height:44px;padding:12px 0;line-height:20px}
.foot-social a,.addr a[href^="tel:"]{vertical-align:top}

/* ============================================================
   PRINT (audit 2026-09-01, finding C2)
   Body copy is opacity:0 until a ScrollTrigger adds .in. Print
   never scrolls, so before this block every page printed blank:
   the pricing page produced 14 empty A4 sheets. The site already
   had the mechanism (STILL mode, ?shot) but it was never wired
   to the printer.
   ============================================================ */
@media print{
  /* 1 · everything the motion layer hides, made visible */
  .rv,.reveal,.split,.hero-title,.linemask,.ground-strip,
  .rv-2,.rv-3,.rv-4,.pc-fig,.log-card,figure,section,article{
    opacity:1!important;transform:none!important;clip-path:none!important;
    filter:none!important;visibility:visible!important;
  }
  .ln-in,.linemask>span,.w{transform:none!important;opacity:1!important}

  /* 2 · ink and paper. Cream backgrounds waste toner and grey text
        on white is harder to read than it looks on screen. */
  :root{--paper:#fff;--paper-hi:#fff;--paper-2:#fff;--mist:#fff;
        --ink:#000;--ink-80:#1a1a1a;--ink-60:#333;--ink-40:#555;
        --umber:#5a4630;--line:#bbb;--line-soft:#ddd}
  html,body{background:#fff!important;color:#000!important;font-size:11pt;line-height:1.5}
  *{-webkit-print-color-adjust:exact;print-color-adjust:exact;
    box-shadow:none!important;text-shadow:none!important}

  /* 3 · screen furniture that means nothing on paper */
  .nav,.nav-wrap,.mobile-menu,.menu-btn,.wa-fab,.scrollcue,.skip-link,
  .film-feat,[data-film],video,.play-ring,.hero-mist,.hero-fog,
  .foot-word,.foot-social,.ambient,.loop,canvas{display:none!important}

  /* 4 · the hero is a full-screen image on screen; on paper it is a title */
  .hero{min-height:0!important;height:auto!important;padding:0 0 18pt!important;
        background:none!important;color:#000!important}
  .hero-media,.hero .bg{display:none!important}
  .hero-title{color:#000!important;font-size:24pt!important;line-height:1.1!important}

  /* 5 · keep related things on one sheet */
  h1,h2,h3,h4{break-after:avoid;page-break-after:avoid}
  figure,.log-card,.tier,.pt-row,.fq,.bench-row,.promise-row,li{
    break-inside:avoid;page-break-inside:avoid}
  img{max-width:100%!important;height:auto!important}

  /* 6 · a reader holding the paper still needs to reach her */
  a[href^="tel:"],a[href*="wa.me"]{min-height:0;padding:0}
  main::after{
    content:"jessinchua.sg · +65 8959 3313 · Jessin Chua · PropNex Realty · CEA R066020B";
    display:block;margin-top:16pt;padding-top:8pt;border-top:1pt solid #bbb;
    font-family:var(--sans);font-size:8.5pt;color:#333}
}

/* ---- print-only fee sheet (pricing.html) ---- */
.fee-sheet{display:none}
@media print{
  /* the screen page is replaced by the sheet, not appended to */
  .has-fee-sheet main > section:not(.fee-sheet),
  .has-fee-sheet > header.page-top,
  .has-fee-sheet > footer{display:none!important}
  .has-fee-sheet main::after{content:none}
  .fee-sheet{display:block!important;font-family:var(--sans);color:#000}
  .fs-brand{font-family:var(--caps);font-size:8.5pt;letter-spacing:.18em;
    text-transform:uppercase;color:#5a4630;margin:0 0 14pt}
  .fs-title{font-family:var(--serif);font-weight:400;font-size:26pt;line-height:1.08;
    margin:0 0 8pt;color:#000}
  .fs-sub{font-size:10pt;line-height:1.5;margin:0 0 16pt;max-width:34em;color:#222}
  .fs-tiers{display:flex;gap:14pt;margin-bottom:16pt}
  .fs-tier{flex:1;border:0.6pt solid #999;padding:10pt 11pt}
  .fs-pc{font-family:var(--serif);font-size:22pt;line-height:1;margin:0}
  .fs-nm{font-family:var(--caps);font-size:8pt;letter-spacing:.13em;text-transform:uppercase;
    color:#5a4630;margin:4pt 0 6pt}
  .fs-ds{font-size:9pt;line-height:1.45;margin:0;color:#222}
  .fs-tbl{width:100%;border-collapse:collapse;font-size:9.5pt;margin-bottom:16pt}
  .fs-tbl th{text-align:left;font-family:var(--caps);font-size:7.5pt;letter-spacing:.12em;
    text-transform:uppercase;color:#444;border-bottom:0.8pt solid #000;padding:0 6pt 5pt 0;font-weight:400}
  .fs-tbl th:nth-child(2),.fs-tbl th:nth-child(3),
  .fs-tbl td:nth-child(2),.fs-tbl td:nth-child(3){text-align:center;width:16%}
  .fs-tbl td{padding:5pt 6pt 5pt 0;border-bottom:0.4pt solid #ccc;color:#111}
  .fs-tbl td:nth-child(2),.fs-tbl td:nth-child(3){color:#5a4630}
  .fs-qh{font-family:var(--serif);font-weight:400;font-size:13pt;margin:0 0 8pt;color:#000}
  .fs-qa{margin:0 0 16pt;max-width:40em}
  .fs-qa dt{font-size:9.5pt;font-weight:600;margin-top:8pt;color:#000}
  .fs-qa dd{font-size:9.5pt;line-height:1.45;margin:2pt 0 0;color:#222}
  .fs-foot{border-top:0.6pt solid #999;padding-top:7pt;font-size:8.5pt;color:#444;margin:0}
  .fee-sheet,.fs-tiers,.fs-tbl,.fs-qa{break-inside:avoid;page-break-inside:avoid}
  /* the sheet is meant to be one sheet: kill inherited page padding so the
     content box matches the printable area and nothing spills to a second leaf */
  body.has-fee-sheet,body.has-fee-sheet main,body.has-fee-sheet .fee-sheet{
    padding:0!important;margin:0!important;min-height:0!important}
  body.has-fee-sheet .fee-sheet > *:last-child{margin-bottom:0!important}
}

/* The floating WhatsApp button sat outside every landmark, so a screen-reader
   user moving by landmark never reached the one control that is always on
   screen. The wrapper is a labelled complementary region; it is not a
   containing block, so the button's position:fixed is untouched.
   Audit 2026-09-01, finding L3. */
.wa-fab-wrap{position:static;margin:0;padding:0;border:0;line-height:0}

/* ---- the three answers, beside the price (finding H3) ---- */
.fee-qa{margin-top:clamp(34px,4.5vw,60px);padding-top:clamp(24px,3vw,36px);
  border-top:1px solid var(--line)}
.fee-qa .eyebrow{margin-bottom:clamp(16px,2vw,24px)}
.fee-qa-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(20px,3vw,44px)}
.fee-qa-grid h3{font-family:var(--serif);font-weight:400;font-size:clamp(17px,1.5vw,20px);
  line-height:1.25;color:var(--ink);margin-bottom:8px}
.fee-qa-grid p{font-size:15px;line-height:1.7;color:var(--ink-60);margin:0}
.fee-qa-more{margin-top:clamp(18px,2.2vw,26px);font-family:var(--caps);font-size:11px;
  letter-spacing:.18em;text-transform:uppercase}
.fee-qa-more a{color:var(--umber);text-decoration:none;border-bottom:1px solid var(--line)}
.fee-qa-more a:hover{border-bottom-color:var(--umber)}
@media (max-width:820px){
  .fee-qa-grid{grid-template-columns:1fr;gap:clamp(18px,4vw,26px)}
}

/* ============================================================
   CONTACT BAR (audit 2026-09-01, finding H3)
   The only way to reply sat at the very bottom of pages running 13 to 15
   phone-screens. This follows the reader instead. It appears once she is
   past the hero and hides again over the footer, where the real CTA lives,
   so the two never argue.

   Selling, Landed and Pricing only. /prime and /legacy keep the
   by-appointment register, where a bar that follows you down the page is
   the wrong manner. That was a written stance, not an oversight.
   ============================================================ */
.contact-bar{
  position:fixed;left:0;right:0;bottom:0;z-index:40;
  background:color-mix(in srgb, var(--paper-hi) 94%, transparent);
  backdrop-filter:saturate(120%) blur(10px);
  border-top:1px solid var(--line);
  transform:translateY(100%);transition:transform .5s cubic-bezier(.16,1,.3,1);
  padding-bottom:env(safe-area-inset-bottom);
}
.contact-bar.cb-on{transform:none}
.cb-in{width:min(100% - 2*var(--gut), var(--maxw));margin-inline:auto;
  display:flex;align-items:center;gap:clamp(12px,2vw,22px);
  padding:11px 0;min-height:60px}
.cb-line{font-size:15px;line-height:1.4;color:var(--ink-80);flex:1;min-width:0}
.cb-go,.cb-tel{
  display:inline-flex;align-items:center;justify-content:center;
  font-family:var(--caps);font-size:11px;letter-spacing:.16em;text-transform:uppercase;
  text-decoration:none;white-space:nowrap;min-height:44px;padding:0 20px;border-radius:999px;
}
.cb-go{background:var(--ink);color:var(--paper-hi);transition:background .3s}
.cb-go:hover{background:var(--umber)}
.cb-tel{color:var(--ink);border:1px solid var(--line);padding:0 16px}
.cb-tel:hover{border-color:var(--umber);color:var(--umber)}
/* The floating button and the bar must never stack on top of each other.
   !important is load-bearing here: .wa-fab carries `animation:wa-in .55s .8s both`,
   and a filled animation outranks a normal declaration in the cascade. Only an
   important declaration wins, so this is deliberate rather than lazy. */
body.cb-visible .wa-fab{opacity:0!important;pointer-events:none;transition:opacity .3s}
@media (max-width:560px){
  .cb-line{font-size:14px}
  .cb-in{gap:10px;padding:9px 0}
  .cb-go{padding:0 14px;font-size:10.5px}
  .cb-tel{padding:0 13px;font-size:10.5px}
}
@media (prefers-reduced-motion:reduce){.contact-bar{transition:none}}
@media print{.contact-bar{display:none!important}}
