.sec-hero { --h: 980px; background: rgba(18,18,18,1); overflow: hidden; clip-path: inset(0); }
/* curtain hero: full-bleed photo held still behind the section, revealed by
   two cream panels sliding apart.
   The backdrop is a position:fixed LAYER clipped by the section's clip-path,
   not background-attachment:fixed. A fixed background cannot be promoted to a
   compositor layer, so every scroll frame had to repaint this full-bleed
   photo, which is the stutter. clip-path clips descendants WITHOUT becoming
   their containing block, so the layer stays viewport-anchored and the
   parallax reads exactly the same while scrolling becomes a pure composite.
   Same reason it now works on iOS, where attachment:fixed is broken. */
.sec-hero::before { content: ""; position: fixed; inset: 0; z-index: 0;
  background: url("../images/hero-booth.jpg") center / cover no-repeat;
  filter: brightness(.62); }
.cur-curtain { position: absolute; top: 0; bottom: 0; width: 50.5%; background: var(--cream); z-index: 3; }
.cur-l { left: 0; animation: cur-open-l 1.4s cubic-bezier(.75,0,.2,1) .4s forwards; }
.cur-r { right: 0; animation: cur-open-r 1.4s cubic-bezier(.75,0,.2,1) .4s forwards; }
@keyframes cur-open-l { to { transform: translateX(-101%); } }
@keyframes cur-open-r { to { transform: translateX(101%); } }
.cur-center { inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; }
.cur-center > * { position: static; margin: 0; }
/* OPTIONAL client logo, leading the curtain reveal one beat ahead of the
   kicker (1.35s vs 1.5s), so the brand lands before the copy. Both placements
   in this kit (here and .foot-logo in style.css) sit on dark ground, so a
   dark-on-transparent wordmark is forced to white with the filter rather than
   shipping a second inverted asset: brightness(0) flattens antialiased greys
   to black, invert(1) takes the lot to white, neither touches alpha. Drop the
   filter if the client's mark is already light, and delete the <img> from the
   hero markup if they have no wordmark. `.cur-center > *` zeroes margins,
   hence the two-class selector to win the gap under the mark back. */
/* Her mark is a two-tone lockup (heart + script), REVERSED into her own two
   brand colours for this dark slot: images/logo-hero.png is the cream heart with
   her near-black script, built from her original artwork with nothing but a
   luminance swap between #121212 and #f4efea. So NO brightness(0) invert(1)
   here: the kit's filter exists to force a single-colour dark wordmark white,
   and on a two-tone lockup it flattens heart and script into one white blob.
   Sized narrower than the kit's 290px because her mark is 1.18:1, not the ~3:1
   wordmark that clamp was cut for; at 240px it stands 203px tall. */
.cur-center .cur-logo { width: clamp(160px, 18vw, 240px); height: auto;
  margin: 0 0 26px;
  opacity: 0; animation: cur-fade 1s ease 1.35s forwards; }
.cur-kicker { font-family: var(--font-mont); font-size: 12px; letter-spacing: .3em; text-transform: uppercase; opacity: 0; animation: cur-fade 1s ease 1.5s forwards; }
.cur-title { font-family: var(--font-serif); font-size: 84px; line-height: 1.05; max-width: 1000px; margin: 22px 0 26px; opacity: 0; animation: cur-fade 1.2s ease 1.7s forwards; }
.cur-sub { font-size: 19px; line-height: 1.55; max-width: 560px; opacity: 0; animation: cur-fade 1s ease 2s forwards; }
.cur-btn { margin-top: 38px; padding: 16px 30px; border-color: var(--cream-text); color: var(--cream-text); opacity: 0; animation: cur-fade 1s ease 2.2s forwards; }
.cur-btn:hover { background: var(--cream); border-color: var(--cream); color: var(--ink); }
.cur-corner { bottom: 96px; font-family: var(--font-mont); font-size: 11px; letter-spacing: .26em; text-transform: uppercase; opacity: 0; animation: cur-fade 1s ease 2.4s forwards; }
.cur-bl { left: 0; }
.cur-br { right: 0; }
@keyframes cur-fade { from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: translateY(0); } }
/* --h grown from the kit's 1010 (2026-08-06, layout gate): this client's lede
   runs 7 lines where the kit sized ~5, ending at 320 instead of ~256, so the
   kit's .xpn-cta at 280 printed its box across the last two lines. The cta and
   the panels below it both shift +64 (the exact overrun), which keeps the kit's
   24px lede-to-cta and 42px cta-to-panels gaps, and --h takes the same +64 so
   the panels keep their 100px bottom margin. */
.sec-intro { --h: 1074px; background: #1B1B1B; color: var(--cream-text); }
/* expanding-panels intro (variant 03, 2026-07-15) */
.xpn-kicker { left: 0; top: 88px; font-family: var(--font-mont); font-size: 12px; font-weight: 500; letter-spacing: .32em; text-transform: uppercase; }
.xpn-title { left: 0; top: 128px; width: 680px; font-size: 52px; }
.xpn-lede { left: 820px; top: 152px; width: 380px; font-size: 15px; }
/* sits under the lede, left edge aligned to it; clears .xpn-panels at 434 */
.xpn-cta { left: 820px; top: 344px; }
.xpn-panels { left: 0; top: 434px; width: 1200px; height: 540px; display: flex; gap: 12px; counter-reset: xpn; }
.xpn-panel { position: relative; flex: 1; overflow: hidden; display: block; text-decoration: none; transition: flex .75s cubic-bezier(.5,0,.2,1); }
.xpn-panel img,
.xpn-panel video { position: absolute; inset: 0; transition: transform .75s ease; }
.xpn-panel::after { content: ""; position: absolute; inset: 0; background: linear-gradient(180deg, rgba(18,18,18,.10) 0%, rgba(18,18,18,0) 30%, rgba(18,18,18,0) 52%, rgba(18,18,18,.62) 100%); }
/* Ordinal comes from a CSS counter, not typed markup: these panels carry
   data-bc-pkg, so the price sync can REMOVE one, and a typed "( 02 )" would
   either gap the sequence or survive on the wrong panel. */
.xpn-panel { counter-increment: xpn; }
.xpn-num { position: absolute; z-index: 2; top: 22px; left: 24px; color: var(--cream-text); font-family: var(--font-mont); font-size: 12px; letter-spacing: .22em; }
.xpn-num::before { content: "( 0" counter(xpn) " )"; }
.xpn-name { position: absolute; z-index: 2; left: 24px; right: 24px; bottom: 24px; color: var(--cream-text); font-family: var(--font-serif); font-size: 29px; line-height: 1.15; margin: 0; font-weight: 400; }
.xpn-desc { position: absolute; z-index: 2; left: 24px; bottom: 104px; max-width: 330px; color: var(--cream-text); font-size: 14px; line-height: 1.6; margin: 0; opacity: 0; transform: translateY(12px); transition: opacity .5s ease .18s, transform .5s ease .18s; }
.xpn-panel:hover { flex: 2.4; }
.xpn-panels:hover .xpn-panel:not(:hover) { flex: .78; }
.xpn-panel:hover img,
.xpn-panel:hover video { transform: scale(1.05); }
.xpn-panel:hover .xpn-desc { opacity: 1; transform: none; }
.sec-signature-offer { --h: 100vh; background: rgba(18,18,18,1); overflow: hidden; }
/* horizon signature offer (variant 04, 2026-07-15): window-height, fixed-attachment photo, baseline-anchored type, reveal on scroll */
.hzn-bg { position: absolute; inset: 0; z-index: 0;
  background: url("../images/signature-studio.jpg") 50% 40% / cover no-repeat fixed rgba(18,18,18,1); }
.hzn-bg::after { content: ""; position: absolute; inset: 0; background: linear-gradient(to top, rgba(18,18,18,.94) 8%, rgba(18,18,18,.55) 38%, rgba(18,18,18,.18) 70%); }
.hzn-base { left: 0; right: 0; bottom: 84px; }
.hzn-base > * { position: static; margin: 0; }
.hzn-kicker { font-family: var(--font-mont); font-size: 11px; letter-spacing: .34em; text-transform: uppercase; opacity: 0; }
.hzn-rule { height: 1px; background: rgba(244,239,234,.45); margin: 22px 0 40px; transform-origin: left; transform: scaleX(0); }
.hzn-row { display: flex; align-items: flex-end; justify-content: space-between; gap: 60px; }
.hzn-title { font-family: var(--font-serif); font-size: 104px; line-height: .98; max-width: 720px; opacity: 0; transform: translateY(28px); }
.hzn-side { width: 330px; flex: none; padding-bottom: 10px; opacity: 0; transform: translateY(24px); }
.hzn-copy { font-size: 16px; line-height: 1.75; opacity: .88; }
.hzn-btn { margin-top: 28px; padding: 16px 28px; }
.sec-signature-offer.is-in .hzn-kicker { animation: hzn-fade 1s ease .1s forwards; }
.sec-signature-offer.is-in .hzn-rule { animation: hzn-draw 1.4s cubic-bezier(.6,0,.2,1) .25s forwards; }
.sec-signature-offer.is-in .hzn-title { animation: hzn-rise 1.1s cubic-bezier(.2,.7,.2,1) .45s forwards; }
.sec-signature-offer.is-in .hzn-side { animation: hzn-rise 1.1s cubic-bezier(.2,.7,.2,1) .65s forwards; }
@keyframes hzn-fade { to { opacity: .7; } }
@keyframes hzn-draw { to { transform: scaleX(1); } }
@keyframes hzn-rise { to { opacity: 1; transform: none; } }
/* statement + moving gallery: veiled drift (slow continuous belt, photos surface
   from a cream veil at one edge and dissolve into the other; the photo passing
   center leads at full color; arrows skip the belt one photo; JS in script.js) */
.vgal { background: var(--cream); padding: 13vh 0 15vh; }
.vgal-head { text-align: center; padding: 0 10vw 9vh; }
.vgal-kicker { font-family: var(--font-mont); font-size: 12px; letter-spacing: .35em; text-transform: uppercase; margin: 0 0 26px; }
.vgal-title { font-family: var(--font-serif); font-size: clamp(36px, 3.2vw, 48px); line-height: 1.12; text-transform: uppercase; margin: 0 auto; max-width: 820px; }
.vgal-belt { position: relative; overflow: hidden; }
.vgal-belt::before, .vgal-belt::after {
  content: ""; position: absolute; top: 0; bottom: 0; width: 16vw; z-index: 2; pointer-events: none;
}
.vgal-belt::before { left: 0; background: linear-gradient(90deg, var(--cream), rgba(244,239,234,0)); }
.vgal-belt::after { right: 0; background: linear-gradient(270deg, var(--cream), rgba(244,239,234,0)); }
.vgal-track { display: flex; align-items: center; gap: 4.5vw; width: max-content; padding-right: 4.5vw; will-change: transform; }
.vgal-track img,
.vgal-track video {
  display: block; width: auto; object-fit: cover;
  transition: filter 1.4s ease, transform 1.4s ease;
  filter: brightness(.94) saturate(.88); transform: scale(.985);
}
.vgal-track :is(img, video):nth-child(odd) { height: 54vh; }
.vgal-track :is(img, video):nth-child(even) { height: 44vh; }
.vgal-track img.lead,
.vgal-track video.lead { filter: brightness(1) saturate(1); transform: scale(1); }
/* testimonial: type takeover (one giant serif quote at a time, lines lift in, arrows + timing bar) */
/* --h grown from the kit's 900 (2026-08-06, layout gate): this client's first
   quote is a line longer than the kit's demo, so the deck below needs 620px
   where the kit needed 460, and the bottom-anchored byline/arrows/progress
   have to move down with it or the last line paints over the attribution.
   Every gap is the kit's: the byline is bottom:120px + 64px tall, so its top
   is --h - 184, and 1020 puts that 56px under the deck's 780 -- the same
   56px the kit had at 900 with a 460 deck. Re-measure --h if the quote changes. */
.sec-testimonial { --h: 1020px; background: #242424; overflow: hidden; }
.tt-topline {
  left: 0; right: 0; top: 74px;
  display: flex; justify-content: space-between; align-items: baseline;
  border-bottom: 1px solid rgba(244,239,234,.25); padding-bottom: 22px;
}
.tt-kicker { margin: 0; font-family: var(--font-mont); font-size: 12px; letter-spacing: .28em; text-transform: uppercase; opacity: .7; }
.tt-counter { margin: 0; font-family: var(--font-serif); font-size: 22px; }
.tt-counter .tt-total { opacity: .45; }
/* The deck STACKS the slides in one grid cell instead of absolutely
   positioning them, so its height is the TALLEST slide's rather than a fixed
   number the copy can outgrow. min-height keeps the kit's 460 floor; a longer
   quote grows the box instead of running out the bottom of it. This is what
   makes the section width-proof: the same rule fits 360, 390, 430 and 440
   without a per-width magic height. */
.tt-slides { left: 0; right: 0; top: 200px; min-height: 460px; display: grid; }
.tt-slide { grid-area: 1 / 1; visibility: hidden; }
.tt-slide.is-on { visibility: visible; }
/* The reveal mask must clip wider than the line box: line-height 1.12 is
   TIGHTER than the font's own metrics (half-leading is negative), so
   descenders in y/g/q/p sit ~3px below the line box and overflow:hidden
   was shearing them off. Pad the clip box down and pull the same amount
   back with a negative margin, so line rhythm is byte-identical and only
   the clip region grows. Kept in em so the mobile clamp() size inherits
   the fix. The slide-in start must clear the taller box: 110% of the span
   no longer covers it, hence 125%. */
.tt-line {
  display: block; overflow: hidden;
  font-family: var(--font-serif); font-size: 74px; line-height: 1.12;
  padding-bottom: .1em; margin-bottom: -.1em;
}
.tt-line > span { display: block; transform: translateY(125%); }
.tt-slide.is-on .tt-line > span { animation: tt-line-in .9s cubic-bezier(.2,.7,.2,1) forwards; }
.tt-slide.is-out .tt-line > span { animation: tt-line-out .5s ease forwards; }
@keyframes tt-line-in { from { transform: translateY(125%); } to { transform: translateY(0); } }
@keyframes tt-line-out { from { transform: translateY(0); } to { transform: translateY(-110%); } }
.tt-byline { left: 0; bottom: 120px; display: flex; align-items: center; gap: 20px; }
.tt-by-photo { width: 64px; height: 64px; border-radius: 50%; object-fit: cover; }
.tt-by-name { font-family: var(--font-italic); font-size: 24px; margin: 0; }
/* Five stars, static: all three reviews carry the same rating, so this sits
   outside the slide swap rather than being driven per slide. --accent-lift is
   her powder blue, the hue this dark section already uses for accent marks
   (her red measures 1.83:1 on this ground and would fail outright). */
.tt-stars { font-size: 13px; letter-spacing: .18em; color: var(--accent-lift); margin: 5px 0 0; line-height: 1; }
.tt-by-tag { font-family: var(--font-mont); font-size: 11px; letter-spacing: .22em; text-transform: uppercase; opacity: .55; margin: 4px 0 0; }
.tt-by-block { transition: opacity .4s ease; }
.tt-arrows { right: 0; bottom: 158px; display: flex; gap: 54px; }
.tt-arrow { background: none; border: 0; padding: 8px 0; cursor: pointer; color: var(--cream-text); display: block; }
.tt-arrow svg { display: block; width: 88px; height: 10px; overflow: visible; }
.tt-arrow svg line, .tt-arrow svg polyline {
  stroke: currentColor; stroke-width: 1.2; fill: none;
  transition: transform .4s ease;
}
.tt-arrow:hover svg line, .tt-arrow:hover svg polyline { transform: translateX(6px); }
.tt-prev:hover svg line, .tt-prev:hover svg polyline { transform: translateX(-6px); }
.tt-progress { left: 0; right: 0; bottom: 74px; height: 1px; background: rgba(244,239,234,.2); }
.tt-progress i { position: absolute; left: 0; top: 0; bottom: 0; width: 0; background: var(--cream-text); }
.tt-progress i.run { animation: tt-fill 6.5s linear forwards; }
@keyframes tt-fill { from { width: 0; } to { width: 100%; } }
/* about: margin axis (variant 05, 2026-07-15) — hard left text axis, rotated
   spine label, numbered marginalia, full-height photo bleeding off the right
   edge with a spinning badge; entrances gated by .is-in from the shared
   reveal observer in script.js */
/* --h grown from the kit's 900 (2026-08-06, layout gate): this client's origin
   story runs 8 lines where the kit sized ~7, so .abx-para ended at 644 and the
   kit's .abx-sub at 626 printed straight over its last line. Sub and cta move
   down 42px together, keeping the kit's own 22px sub-to-cta gap, and --h grows
   the same 42 so the section keeps its 82px bottom margin. */
.sec-about { --h: 942px; background: #EAE5E0; overflow: hidden; }
.abx-spine { left: -8px; top: 120px; writing-mode: vertical-rl; transform: rotate(180deg); font-family: var(--font-mont); font-size: 11px; letter-spacing: .4em; text-transform: uppercase; color: var(--accent); opacity: 0; }
.abx-title { left: 120px; top: 110px; font-family: var(--font-serif); font-weight: 400; font-size: 104px; line-height: 1.04; opacity: 0; transform: translateY(24px); }
/* Both paragraphs sit 28px higher than the kit put them (owner, 2026-08-11:
   "scooch the description up"). The sub runs 4 lines at this width, ending at
   780 against the button at 782; moving the pair up restores a 30px gap above
   the button and keeps their own 24px gap intact. */
.abx-para { left: 120px; top: 392px; width: 400px; font-size: 16px; line-height: 1.75; letter-spacing: .02em; opacity: 0; transform: translateY(24px); }
.abx-sub { left: 120px; top: 640px; width: 420px; font-size: 16px; line-height: 1.75; letter-spacing: .02em; opacity: 0; transform: translateY(24px); }
.abx-cta { left: 120px; top: 782px; opacity: 0; transform: translateY(24px); }
.abx-cta .btn { padding: 15px 26px; }
.abx-notes { left: 600px; top: 432px; width: 200px; opacity: 0; transform: translateY(24px); }
.abx-note { border-top: 1px solid rgba(18,18,18,.22); padding: 16px 0 24px; cursor: default; transition: border-color .4s ease; }
.abx-note:hover { border-color: var(--accent); }
.abx-note:hover .w { font-family: var(--font-italic); }
.abx-note .n { display: block; font-family: var(--font-mont); font-size: 10px; letter-spacing: .3em; color: var(--accent); margin-bottom: 6px; }
.abx-note .w { display: block; font-family: var(--font-serif); font-size: 21px; line-height: 1.25; }
/* height follows --h rather than repeating it, so the full-bleed photo cannot
   fall short of the section when --h is re-measured for longer copy. */
.abx-tall { left: 860px; top: 0; width: calc(340px + var(--gutter)); height: 100%; overflow: hidden; opacity: 0; transform: translateX(90px); }
.abx-tall img,
.abx-tall video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; opacity: 0; transition: opacity .8s ease; animation: abx-drift 26s ease-in-out infinite alternate; }
.abx-tall img.is-on,
.abx-tall video.is-on { opacity: 1; }
.abx-tall :is(img, video):nth-child(3) { object-position: 0 50%; }
/* owner portrait: an inset slot straddling the tall photo's left edge */
.abx-owner { left: 715px; top: 292px; width: 300px; height: 384px; z-index: 2;
             overflow: hidden; opacity: 0; transform: translateY(24px);
             box-shadow: 0 18px 46px rgba(18,18,18, .3); }
.abx-owner img { width: 100%; height: 100%; object-fit: cover; display: block; }
.abx-owner figcaption { position: absolute; left: 0; right: 0; bottom: 0;
             font-family: var(--font-mont); font-size: 9px; font-weight: 500;
             letter-spacing: .26em; text-transform: uppercase; text-align: center;
             padding: 9px 8px; background: rgba(11,11,11, .74); color: #fff; }
.sec-about.is-in .abx-spine { animation: abx-fade 1s ease .2s forwards; }
.sec-about.is-in .abx-title { animation: abx-rise 1s ease .3s forwards; }
.sec-about.is-in .abx-para { animation: abx-rise 1s ease .5s forwards; }
.sec-about.is-in .abx-sub { animation: abx-rise 1s ease .62s forwards; }
.sec-about.is-in .abx-notes { animation: abx-rise 1s ease .68s forwards; }
.sec-about.is-in .abx-cta { animation: abx-rise 1s ease .75s forwards; }
.sec-about.is-in .abx-tall { animation: abx-glide 1.3s cubic-bezier(.5,0,.2,1) both; }
.sec-about.is-in .abx-owner { animation: abx-rise 1s ease .9s forwards; }
@keyframes abx-rise { to { opacity: 1; transform: none; } }
@keyframes abx-fade { to { opacity: 1; } }
@keyframes abx-glide { to { opacity: 1; transform: none; } }
@keyframes abx-drift { from { transform: scale(1); } to { transform: scale(1.09); } }
/* case studies: filmstrip (chosen variant 03, 2026-07-15) — window-height
   panel, strip steps only via the arrows (no user scroll/drag) */
.sec-stats-or-features { --h: auto; height: 100vh; min-height: 840px; padding: 0; background: #2F2F2F; display: flex; flex-direction: column; justify-content: center; }
.fcs-head { width: 1200px; margin: 0 auto; display: flex; align-items: flex-end; justify-content: space-between; }
.fcs-eyebrow { font-family: var(--font-mont); font-size: 13px; letter-spacing: .24em; text-transform: uppercase; color: rgba(244,239,234,.55); margin: 0; }
.fcs-title { font-family: var(--font-serif); font-size: 64px; line-height: 1.05; margin: 12px 0 0; }
.fcs-arrows { display: flex; gap: 54px; padding-bottom: 12px; }
.fcs-arrow { background: none; border: 0; padding: 8px 0; cursor: pointer; color: var(--cream-text); display: block; }
.fcs-arrow svg { display: block; width: 110px; height: 12px; overflow: visible; }
.fcs-arrow svg line, .fcs-arrow svg polyline {
  stroke: currentColor; stroke-width: 1.2; fill: none;
  transition: transform .4s ease;
}
.fcs-next:hover svg line, .fcs-next:hover svg polyline { transform: translateX(6px); }
.fcs-prev:hover svg line, .fcs-prev:hover svg polyline { transform: translateX(-6px); }
.fcs-arrow:disabled { opacity: .3; cursor: default; }
.fcs-arrow:disabled svg line, .fcs-arrow:disabled svg polyline { transform: none; }
.fcs-strip { margin-top: 36px; overflow-x: hidden; }
.fcs-track { display: flex; gap: 44px; width: max-content; padding: 34px var(--gutter) 0; }
.fcs-card { position: relative; width: 440px; flex: 0 0 auto; text-decoration: none; color: inherit; display: block; }
.fcs-frame { position: relative; display: block; width: 100%; height: 430px; overflow: hidden; }
.fcs-frame img,
.fcs-frame video { width: 100%; height: 100%; object-fit: cover; transition: transform .8s; }
.fcs-card:hover .fcs-frame img,
.fcs-card:hover .fcs-frame video { transform: scale(1.05); }
.fcs-num { position: absolute; top: -34px; left: -14px; z-index: 2; font-family: var(--font-italic); font-size: 120px; line-height: 1; color: var(--cream-text); pointer-events: none; text-shadow: 0 2px 30px rgba(18,18,18,.55); }
.fcs-meta { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; margin-top: 20px; border-top: 1px solid rgba(244,239,234,.22); padding-top: 16px; }
.fcs-name { font-family: var(--font-serif); font-size: 27px; }
.fcs-metric { font-family: var(--font-italic); font-size: 27px; color: rgba(244,239,234,.9); white-space: nowrap; }
.fcs-what { display: block; margin-top: 6px; font-family: var(--font-mont); font-size: 11px; letter-spacing: .2em; text-transform: uppercase; color: rgba(244,239,234,.5); }
.fcs-cap { display: flex; flex-direction: column; justify-content: center; align-items: flex-start; width: 400px; height: 430px; margin-top: 34px; border: 1px solid rgba(244,239,234,.25); padding: 44px; flex: 0 0 auto; }
.fcs-cap p { font-family: var(--font-serif); font-size: 34px; line-height: 1.2; margin: 0; }
.fcs-cap .btn { margin-top: 28px; }
.fcs-progress { width: 1200px; margin: 36px auto 0; height: 1px; background: rgba(244,239,234,.18); position: relative; }
.fcs-bar { position: absolute; left: 0; top: -1px; height: 3px; width: 12%; background: var(--accent-lift); transition: width .45s ease; }
/* blog journal drawers (variant 04, 2026-07-15): one-open hover accordion,
   height is constant because exactly one drawer is open at all times */
/* --h grown from the kit's 950 (2026-08-06, layout gate): .dw-flow is inset:0
   on a canvas that does NOT clip, and this client ships SIX drawers where the
   kit shipped four. Two extra 88px rows pushed the "Ask us anything else"
   button to 1031, i.e. 81px past the section, where it printed on top of
   #event-types' heading. 1126 = that 1031 plus the kit's own 95px bottom
   margin. Raise it by 88 for every drawer added. */
/* PBLA's exact neutral, not her cream (owner, 2026-08-11: the FAQ matches
   PBLA's pixel for pixel; dark sections on both sides, so no seam). */
.sec-faq { --h: 1126px; background: #F7F7F7; }
.dw-flow { inset: 0; padding: 74px 60px 0; }
.dw-head { text-align: center; margin-bottom: 44px; }
.dw-kicker { font-family: var(--font-italic); font-size: 30px; margin: 0 0 6px; color: var(--accent); }
.dw-title { font-family: var(--font-serif); font-size: 62px; line-height: 1.02; margin: 0; text-transform: uppercase; letter-spacing: .02em; }
.dw-item {
  display: block; text-decoration: none; color: inherit; cursor: pointer;
  border-top: 1px solid rgba(18,18,18,.35); overflow: hidden;
  height: 88px; transition: height .6s cubic-bezier(.4,0,.2,1);
}
.dw-item:last-of-type { border-bottom: 1px solid rgba(18,18,18,.35); }
.dw-item.is-open { height: 268px; }
.dw-bar {
  display: grid; grid-template-columns: 92px 1fr 210px 40px; align-items: center;
  height: 88px; padding: 0 8px;
}
.dw-no { font-family: var(--font-mont); font-size: 12px; letter-spacing: .18em; }
.dw-name { font-family: var(--font-serif); font-size: 31px; line-height: 1.1; transition: color .45s ease; }
.dw-item.is-open .dw-name { font-family: var(--font-italic); color: var(--accent); }
.dw-cat { font-family: var(--font-mont); font-size: 11px; letter-spacing: .22em; text-transform: uppercase; text-align: right; opacity: .75; }
.dw-plus { position: relative; width: 16px; height: 16px; justify-self: end; transition: transform .6s cubic-bezier(.4,0,.2,1); }
.dw-plus::before, .dw-plus::after { content: ''; position: absolute; background: var(--ink); }
.dw-plus::before { left: 0; right: 0; top: 7px; height: 1px; }
.dw-plus::after { top: 0; bottom: 0; left: 7px; width: 1px; }
.dw-item.is-open .dw-plus { transform: rotate(45deg); }
.dw-body {
  display: grid; grid-template-columns: 330px 1fr auto; column-gap: 44px; align-items: center;
  padding: 0 8px 32px; opacity: 0; transform: translateY(12px);
  transition: opacity .55s ease .12s, transform .55s ease .12s;
}
.dw-item.is-open .dw-body { opacity: 1; transform: none; }
.dw-body img,
.dw-body video { width: 330px; height: 148px; object-fit: cover; display: block; }
.dw-x { display: block; font-size: 15px; line-height: 1.7; margin: 0; max-width: 480px; }
.dw-read { font-family: var(--font-mont); font-size: 12px; letter-spacing: .2em; text-transform: uppercase; border-bottom: 1px solid var(--ink); padding-bottom: 4px; white-space: nowrap; }
.dw-foot { display: flex; justify-content: center; padding-top: 46px; }
/* used by the mobile FAQ accordion, where the body toggles display and so
   cannot transition (see the max-width:900px block) */
@keyframes dw-open { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: none; } }
/* event types: hover-expanding accordion (variant 03, 2026-07-15) */
.sec-event-types { --h: 880px; background: #1B1B1B; }
.pda-head { left: 0; top: 62px; width: 1200px; display: flex; align-items: baseline; justify-content: space-between; gap: 40px; }
.pda-title { font-family: var(--font-serif); font-size: 52px; line-height: 1.05; margin: 0; }
.pda-plats { display: flex; gap: 24px; font-size: 15px; align-items: baseline; }
.pda-plats span { opacity: .55; }
.pda-plats a { color: inherit; text-decoration: none; border-bottom: 1px solid rgba(244,239,234,.4); padding-bottom: 3px; transition: border-color .3s; }
.pda-plats a:hover { border-color: var(--cream-text); }
.pda-panels { left: 0; top: 168px; width: 1200px; height: 540px; display: flex; gap: 14px; }
.pda-panel {
  position: relative; flex: 1; overflow: hidden; text-decoration: none; color: var(--cream-text);
  transition: flex .65s cubic-bezier(.6,0,.25,1); cursor: pointer;
}
.pda-panel img,
.pda-panel video {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
  filter: grayscale(.85) brightness(.62); transition: filter .65s ease, transform .65s ease;
}
.pda-panel:hover { flex: 2.4; }
.pda-panel:hover img,
.pda-panel:hover video { filter: grayscale(0) brightness(.85); transform: scale(1.03); }
.pda-panel::after { content: ""; position: absolute; inset: 0; background: linear-gradient(to top, rgba(18,18,18,.85), rgba(18,18,18,0) 55%); }
.pda-no { position: absolute; top: 22px; left: 24px; z-index: 2; font-family: var(--font-italic); font-size: 22px; opacity: .9; }
.pda-spine {
  position: absolute; bottom: 26px; left: 24px; z-index: 2;
  writing-mode: vertical-rl; transform: rotate(180deg);
  font-family: var(--font-serif); font-size: 26px; line-height: 1.15; white-space: nowrap;
  transition: opacity .4s ease;
}
.pda-card {
  position: absolute; left: 24px; right: 24px; bottom: 24px; z-index: 2;
  opacity: 0; transform: translateY(14px); transition: opacity .5s ease .15s, transform .5s ease .15s;
}
.pda-panel:hover .pda-spine { opacity: 0; }
.pda-panel:hover .pda-card { opacity: 1; transform: none; }
.pda-name { display: block; font-family: var(--font-serif); font-size: 30px; line-height: 1.15; margin: 0 0 8px; }
.pda-meta { display: block; font-family: var(--font-mont); font-size: 11px; letter-spacing: .2em; text-transform: uppercase; opacity: .75; margin: 0 0 14px; }
.pda-listen {
  display: inline-block; border-bottom: 1px solid var(--cream-text); padding-bottom: 3px;
  font-family: var(--font-mont); font-size: 12px; letter-spacing: .18em; text-transform: uppercase;
}
.pda-under { left: 0; top: 744px; width: 1200px; display: flex; align-items: center; justify-content: space-between; gap: 40px; }
.pda-blurb { max-width: 560px; font-size: 15px; line-height: 1.65; opacity: .75; margin: 0; }
/* call to action: ruled plaque (statement round winner 2026-07-15) */
.sec-call-to-action { --h: 900px; background: rgba(18,18,18,1); }
.sec-call-to-action::before { content: ""; position: absolute; inset: 0; background: url("../images/cta-band.jpg") center / cover no-repeat fixed; opacity: 0.28; }
.plq-frame {
  position: absolute; text-align: center; padding: 88px 70px 76px;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
}
.plq-rule { position: absolute; background: rgba(244,239,234,.5); }
.plq-r-top    { left: 0; right: 0; top: 0; height: 1px; transform: scaleX(0); transition: transform 1.1s cubic-bezier(.65,0,.25,1) .2s; }
.plq-r-bottom { left: 0; right: 0; bottom: 0; height: 1px; transform: scaleX(0); transition: transform 1.1s cubic-bezier(.65,0,.25,1) .35s; }
.plq-r-left   { top: 0; bottom: 0; left: 0; width: 1px; transform: scaleY(0); transition: transform 1.1s cubic-bezier(.65,0,.25,1) .5s; }
.plq-r-right  { top: 0; bottom: 0; right: 0; width: 1px; transform: scaleY(0); transition: transform 1.1s cubic-bezier(.65,0,.25,1) .65s; }
.sec-call-to-action.is-in .plq-r-top, .sec-call-to-action.is-in .plq-r-bottom { transform: scaleX(1); }
.sec-call-to-action.is-in .plq-r-left, .sec-call-to-action.is-in .plq-r-right { transform: scaleY(1); }
.plq-tick { position: absolute; width: 14px; height: 14px; opacity: 0; transition: opacity .6s ease 1.5s; }
.plq-tick::before, .plq-tick::after { content: ""; position: absolute; background: var(--cream-text); }
.plq-tick::before { width: 14px; height: 1px; top: 7px; }
.plq-tick::after { width: 1px; height: 14px; left: 7px; }
.plq-tl { left: -7px; top: -7px; } .plq-tr { right: -7px; top: -7px; }
.plq-bl { left: -7px; bottom: -7px; } .plq-br { right: -7px; bottom: -7px; }
.sec-call-to-action.is-in .plq-tick { opacity: 1; }
.plq-kicker {
  position: absolute; left: 50%; top: 0; transform: translate(-50%, -50%);
  background: #121212; padding: 6px 26px; margin: 0; white-space: nowrap;
  font-family: var(--font-mont); font-size: 11px; letter-spacing: .34em; text-transform: uppercase;
  opacity: 0; transition: opacity .8s ease 1.2s;
}
.sec-call-to-action.is-in .plq-kicker { opacity: .7; }
.plq-big {
  font-size: 92px; line-height: 1.04; margin: 0; letter-spacing: .015em;
  text-transform: uppercase; color: var(--cream-text);
  opacity: 0; transform: translateY(20px); transition: opacity 1s cubic-bezier(.2,.7,.2,1) .9s, transform 1s cubic-bezier(.2,.7,.2,1) .9s;
}
.plq-big em { text-transform: none; }
.sec-call-to-action.is-in .plq-big { opacity: 1; transform: none; }
.plq-sub {
  font-size: 20px; line-height: 1.5; max-width: 560px; margin: 30px 0 0; color: var(--cream-text);
  opacity: 0; transform: translateY(16px); transition: opacity 1s cubic-bezier(.2,.7,.2,1) 1.2s, transform 1s cubic-bezier(.2,.7,.2,1) 1.2s;
}
.sec-call-to-action.is-in .plq-sub { opacity: .88; transform: none; }
.plq-btn {
  position: absolute; left: 50%; bottom: 0; transform: translate(-50%, 50%);
  background: #121212; padding: 15px 38px; white-space: nowrap;
  opacity: 0; transition: opacity .8s ease 1.6s, background-color .5s, border-color .5s, color .5s;
}
.sec-call-to-action.is-in .plq-btn { opacity: 1; }
.plq-btn:hover { background: var(--cream); }

/* MOBILE (additive layer; see style.css) */
@media (max-width: 900px) {
  /* curtain hero */
  .sec-hero { height: 100svh; min-height: 600px; clip-path: inset(0); }
  .sec-hero .cv { height: 100%; }
  /* mobile can't honor background-attachment:fixed; pin the ::before to the
     viewport instead (clip-path on .sec-hero clips it to the hero box) so the
     photo stays fixed on phones exactly like desktop */
  .sec-hero::before { position: fixed; background-attachment: scroll; }
  .sec-hero .cur-center { position: absolute; left: 22px; right: 22px; top: 0; bottom: 0; }
  .cur-center .cur-logo { width: clamp(132px, 36vw, 190px); margin-bottom: 18px; }
  .cur-title { font-size: clamp(34px, 9.6vw, 46px); margin: 18px 0 20px; }
  .cur-sub { font-size: 16px; max-width: 330px; }
  .cur-corner { display: none; }

  /* expanding panels intro → stacked cards, descriptions always on */
  .sec-intro .cv { display: flex; flex-direction: column; padding: 64px 22px; }
  .sec-intro .xpn-title { font-size: 32px; margin: 16px 0 18px; }
  .sec-intro .xpn-lede { margin-bottom: 36px; }
  /* the cta is a flex child here with no margin of its own, so without this
     the button's border sits flush on the first booth card (owner, 2026-08-11) */
  .sec-intro .xpn-cta { margin-bottom: 28px; }
  .sec-intro .xpn-panels { position: static; width: auto; height: auto;
                           flex-direction: column; gap: 14px; }
  .sec-intro .xpn-panels .xpn-panel { flex: none; aspect-ratio: 4 / 3; }
  .sec-intro .xpn-desc { opacity: 1; transform: none; bottom: 56px; font-size: 13px;
                         max-width: none; right: 24px; }
  .sec-intro .xpn-name { font-size: 24px; }

  /* signature offer */
  .sec-signature-offer .cv { min-height: 88svh; display: flex; padding: 96px 22px 56px; }
  /* pin the photo to the viewport on mobile (see .sec-hero note) */
  .sec-signature-offer { clip-path: inset(0); }
  .hzn-bg { position: fixed; background-attachment: scroll; }
  .sec-signature-offer .hzn-base { align-self: flex-end; width: 100%; }
  .hzn-row { flex-direction: column; align-items: flex-start; gap: 26px; }
  .hzn-title { font-size: clamp(44px, 13vw, 58px); }
  .hzn-side { width: auto; padding-bottom: 0; }

  /* statement + belt */
  .vgal { padding: 10vh 0 12vh; }
  .vgal-head { padding: 0 22px 7vh; }
  .vgal-title { font-size: 26px; }
  .vgal-track :is(img, video):nth-child(odd) { height: 42vh; }
  .vgal-track :is(img, video):nth-child(even) { height: 34vh; }

  /* testimonial type takeover */
  .sec-testimonial .cv { display: flex; flex-direction: column; padding: 56px 22px 48px; }
  /* height -> min-height so the stacked deck (see the base rule) grows to its
     tallest slide. The kit's fixed 250 was 35px short of this client's first
     quote at 390 and 49px short at 440, and the overrun landed on the byline. */
  .sec-testimonial .tt-slides { position: relative; width: 100%; min-height: 250px; margin-top: 30px; }
  /* size lives on .tt-line, not the span: its em drives the descender pad */
  .tt-line { font-size: clamp(24px, 7.8vw, 32px); }
  .sec-testimonial .tt-byline { margin-top: 8px; }
  .tt-by-photo { width: 52px; height: 52px; }
  .sec-testimonial .tt-arrows { margin-top: 26px; }
  .sec-testimonial .tt-progress { position: relative; width: 100%; height: 1px; margin-top: 26px; }

  /* about: margin axis → single column */
  .sec-about .cv { display: flex; flex-direction: column; padding: 64px 22px; }
  .sec-about .abx-spine { writing-mode: horizontal-tb; transform: none; order: 1; }
  .sec-about .abx-title { order: 2; font-size: clamp(44px, 13vw, 58px); margin: 12px 0 22px; }
  .sec-about .abx-para { order: 3; }
  .sec-about .abx-sub { order: 4; margin-top: 18px; }
  .sec-about .abx-notes { order: 5; margin-top: 26px; }
  .sec-about .abx-owner { order: 5; position: relative; width: 100%; height: auto;
                          aspect-ratio: 4 / 5; margin-top: 26px; }
  .sec-about .abx-tall { order: 6; position: relative; width: 100%; height: auto;
                         aspect-ratio: 3 / 4; margin: 28px 0 6px; }
  .sec-about .abx-cta { order: 7; }

  /* case studies filmstrip */
  .sec-stats-or-features { height: auto; min-height: 0; padding: 64px 0 56px; }
  .fcs-head { width: auto; flex-direction: column; align-items: flex-start;
              gap: 18px; padding: 0 22px; }
  .fcs-title { font-size: 36px; }
  .fcs-arrows { gap: 40px; padding-bottom: 0; }
  .fcs-strip { overflow-x: auto; }
  .fcs-track { gap: 26px; padding: 30px 22px 0; }
  .fcs-card { width: min(74vw, 300px); }
  .fcs-frame { height: 300px; }
  .fcs-num { font-size: 72px; top: -24px; left: -6px; }
  .fcs-name, .fcs-metric { font-size: 20px; }
  .fcs-cap { width: min(74vw, 300px); height: 300px; margin-top: 30px; padding: 30px; }
  .fcs-cap p { font-size: 24px; }
  .fcs-progress { width: auto; margin: 30px 22px 0; }

  /* journal drawers, matched to PBLA's FAQ (owner, 2026-08-11): closed by
     default everywhere; here a tap opens one at a time (script.js toggles
     .is-open under 900px).
     Height stays auto and the BODY is what collapses, because the answers are
     different lengths and a fixed open height either clips the long ones or
     leaves a gap under the short ones. display none/grid cannot be
     transitioned, so the fade is an animation on open, which can never clip
     whatever the answer's height turns out to be. */
  .sec-faq .cv { padding: 0; }
  .dw-flow { padding: 60px 22px 64px; }
  .dw-kicker { font-size: 24px; }
  .dw-title { font-size: 38px; }
  .sec-faq .dw-item, .sec-faq .dw-item.is-open { height: auto; }
  .dw-bar { grid-template-columns: 44px 1fr auto; height: auto; padding: 16px 0 10px; }
  .dw-cat { display: none; }
  .dw-plus { display: block; }   /* the affordance that says the row opens */
  .dw-name { font-size: 21px; }
  .sec-faq .dw-body { display: none; grid-template-columns: 1fr; row-gap: 14px;
                       opacity: 1; transform: none; padding: 0 0 24px; }
  .sec-faq .dw-item.is-open .dw-body { display: grid; animation: dw-open .32s ease both; }
  /* Photos are DESKTOP ONLY (owner, 2026-08-11). On a phone the 170px image sat
     between the question and its answer, so a tapped row pushed its own answer
     toward the fold and the accordion read as if it had done nothing. */
  .dw-body img,
  .dw-body video { display: none; }
  .dw-foot { padding-top: 40px; }

  /* event-type panels → stacked, cards always on */
  .sec-event-types .cv { display: flex; flex-direction: column; padding: 56px 22px 60px; }
  .pda-head { width: auto; flex-direction: column; align-items: flex-start; gap: 14px; }
  .pda-title { font-size: 32px; }
  .pda-panels { width: auto; height: auto; flex-direction: column; gap: 12px; margin-top: 32px; }
  .sec-event-types .pda-panels .pda-panel { flex: none; height: 210px; }
  .pda-panel img,
  .pda-panel video { filter: grayscale(.2) brightness(.75); }
  .pda-spine { display: none; }
  .pda-card { opacity: 1; transform: none; }
  .pda-name { font-size: 22px; }
  .pda-under { width: auto; flex-direction: column; align-items: flex-start;
               gap: 20px; margin-top: 32px; }

  /* ruled plaque (inline geometry on the frame → !important) */
  .sec-call-to-action { clip-path: inset(0); }
  .sec-call-to-action::before { position: fixed; background-attachment: scroll; }
  .sec-call-to-action .cv { display: flex; padding: 90px 22px 100px; }
  .sec-call-to-action .plq-frame { position: relative; left: auto !important; top: auto !important;
      width: 100% !important; height: auto !important; padding: 72px 18px 64px; }
  .plq-big { font-size: clamp(32px, 9.5vw, 42px); }
  .plq-sub { font-size: 16px; margin-top: 22px; }
  .plq-kicker { width: 250px; white-space: normal; line-height: 1.7; }
  .sec-call-to-action .plq-btn { position: absolute; width: auto; }
}

/* ---- her red and blue on the home canvas (see style.css for the rule) ------
   Home's sections are the fixed canvas, not .fl-* bands, so each one is named
   with its own ground: hero photo / #1B1B1B intro / #242424 testimonial /
   #2F2F2F stats / #1B1B1B event types / near-black CTA are DARK -> powder blue;
   the cream body behind the gallery belt, #EAE5E0 about and #FAF7F4 faq are
   LIGHT -> deep red. */
/* .cur-kicker deliberately stays cream: the hero ground is a PHOTO with bright
   sky in it, not a flat dark fill, so a light powder-blue label goes thin over
   the top third. The reversed logo above it carries her colour here instead. */
.xpn-kicker { color: var(--accent-lift); }
.xpn-num { color: var(--accent-lift); }
.tt-kicker { color: var(--accent-lift); opacity: 1; }
.fcs-eyebrow { color: var(--accent-lift); }
.plq-kicker { color: var(--accent-lift); }
.sec-call-to-action.is-in .plq-kicker { opacity: 1; }
.pda-plats span { color: var(--accent-lift); opacity: 1; }
.vgal-kicker { color: var(--accent); }
/* The FAQ is the one light section that stays OUT of her red (owner,
   2026-08-11: it must match PBLA's FAQ exactly, and PBLA's reads all in
   neutral ink). Values are PBLA's measured renders: #3D3D3D for the kicker
   and the opened question, kit-default ink at .75 for the category labels. */
.sec-faq .dw-kicker { color: #3D3D3D; }
.sec-faq .dw-item.is-open .dw-name { color: #3D3D3D; }
.sec-faq .dw-cat { color: var(--ink); opacity: .75; }
