.sec-hero { --h: 980px; background: rgba(19,19,19,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;
  /* brightness .62 -> .44 (owner, 2026-10-17: "darken the hero so I can read the words"). Measured behind the
     text: the brightest pixels (the white dress and backdrop) gave 2.4:1 against the cream text at .62;
     .44 lifts the worst pixel to about 4.5:1 for the 11 to 14px lines and well past 3:1 for the headline. */
  filter: brightness(.44); }
.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 #111111 and #f1f3f6. 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; }
/* opacity is .001, NOT 0, and the single character is load-bearing. Chrome
   discards any paint made at opacity:0 and records each element's paint ONCE;
   these fade in on a compositor-driven animation and never repaint on the main
   thread, so at zero every LCP candidate in the first viewport is transparent
   at the one paint Chrome looks at. PageSpeed then returns NO_LCP and NO
   performance score at all. Measured on three live client sites built from this
   kit. .cur-logo is deliberately left at 0: its filter forces a compositing
   layer over the full-viewport .cur-center and at .001 that shifts the whole
   viewport by 1/255, and it is never the LCP element.
   .001 is below one 8-bit alpha step, so it is pixel-identical. */
.cur-kicker { font-family: var(--font-mont); font-size: 12px; letter-spacing: .3em; text-transform: uppercase; opacity: .001; 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: .001; animation: cur-fade 1.2s ease 1.7s forwards; }
.cur-sub { font-size: 19px; line-height: 1.55; max-width: 560px; opacity: .001; 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: .001; 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: .001; 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.
   Owner's editor pass, 2026-10-07: the lede beside the title was dropped and
   the cta and panels moved up 150 into its room; --h stayed 1074, so the
   panels now sit 250px clear of the section's foot. */
.sec-intro { --h: 1074px; background: #000000; 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; }
/* right of the title, its bottom edge level with the two-line title's (128 + 114) */
.xpn-cta { left: 820px; top: 194px; }
.xpn-panels { left: 0; top: 284px; 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(19,19,19,.10) 0%, rgba(19,19,19,0) 30%, rgba(19,19,19,0) 52%, rgba(19,19,19,.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-cta-2 { --h: 100vh; background: rgba(19,19,19,1); overflow: hidden; }
/* horizon CTA 2, was the 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(19,19,19,1); }
.hzn-bg::after { content: ""; position: absolute; inset: 0; background: linear-gradient(to top, rgba(19,19,19,.94) 8%, rgba(19,19,19,.55) 38%, rgba(19,19,19,.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(241,243,246,.45); margin: 22px 0 40px; transform-origin: left; transform: scaleX(0); }
.hzn-row { display: flex; align-items: flex-start; justify-content: space-between; gap: 60px; }
.hzn-title { font-family: var(--font-serif); font-size: 104px; line-height: .98; max-width: 720px; margin: 0; opacity: 0; transform: translateY(28px); }
/* margin: 0 and a top-aligned row (2026-09-30, owner: "the gap between the line and the text is pretty big"). The h2 kept
   the browser's 1em heading margin, 104px above and below, because .hzn-base > * { margin: 0 } only reaches the base's
   own children; and the row aligned to the bottom, so a title shorter than the copy column sat ~130px under the rule.
   Now the title and the copy both start 40px under the rule (the rule's own margin). */
.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-cta-2.is-in .hzn-kicker { animation: hzn-fade 1s ease .1s forwards; }
.sec-cta-2.is-in .hzn-rule { animation: hzn-draw 1.4s cubic-bezier(.6,0,.2,1) .25s forwards; }
.sec-cta-2.is-in .hzn-title { animation: hzn-rise 1.1s cubic-bezier(.2,.7,.2,1) .45s forwards; }
.sec-cta-2.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(245,246,248,0)); }
.vgal-belt::after { right: 0; background: linear-gradient(270deg, var(--cream), rgba(245,246,248,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: #111214; overflow: hidden; }
.tt-topline {
  left: 0; right: 0; top: 74px;
  display: flex; justify-content: space-between; align-items: baseline;
  border-bottom: 1px solid rgba(241,243,246,.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;
}
/* text-wrap: balance (owner, 2026-10-17): each .tt-line is one row on desktop; on a phone a long line wraps,
   and plain wrapping left one word alone on the second row ("print!", "and the gallery"). Balanced wrapping
   splits a wrapped line evenly between its rows, so no row is ever a single word, at any width. */
.tt-line > span { display: block; transform: translateY(125%); text-wrap: balance; }
.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(241,243,246,.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.
   2026-10-07 (owner saw the sub printed over the story): the kit's own story
   runs 10 lines at 400px and ended at 672, past the sub at 640. Sub and cta
   move down 56 together (the 24px story-to-sub gap and 30px sub-to-cta gap
   kept) and --h grows the same 56, so the bottom margin is unchanged.
   Desktop only; at 900px and under these stack in flow.
   Corre Memories, 2026-10-15 (layout gate): her story runs 11 lines at 400px
   and ends at 700, past the sub at 696, and the sub runs 7 lines to 892, past
   the cta at 838, so "Say hello" printed across its last two lines. Sub moves
   to 724 (story bottom + the 24px gap), cta to 950 (sub bottom 920 + the 30px
   gap), and --h grows the same 112 so the 110px bottom margin is unchanged.
   2026-10-17 (owner: "make it one text box, then the spacing is always right"):
   after the copy was cut to the kit's footprint the story ran 6 lines and the
   sub sat 160px below it. The sub is GONE as an element: its sentences live in
   .abx-para after a blank line (<br><br>), so the gap is one line-height and
   can never drift. The para now ends at 756; cta moves to 786 (the 30px gap)
   and --h shrinks the same 164 to 946, bottom margin unchanged. */
.sec-about { --h: 946px; background: #e9ecf0; 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-cta { left: 120px; top: 786px; 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(17,17,17,.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(17,17,17, .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-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-event-types { --h: auto; height: 100vh; min-height: 840px; padding: 0; background: #2a2b2e; 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(241,243,246,.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(19,19,19,.55); }
.fcs-meta { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; margin-top: 20px; border-top: 1px solid rgba(241,243,246,.22); padding-top: 16px; }
/* one line each (owner, 2026-10-06): the name, the tag and the line never wrap; overlong copy is clipped with an ellipsis, never wrapped */
.fcs-name { font-family: var(--font-serif); font-size: 27px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.fcs-metric { font-family: var(--font-italic); font-size: 27px; color: rgba(241,243,246,.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; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; color: rgba(241,243,246,.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(241,243,246,.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(241,243,246,.18); position: relative; }
.fcs-bar { position: absolute; left: 0; top: -1px; height: 3px; width: 12%; background: var(--accent-lift); transition: width .45s ease; }
/* event types: hover-expanding accordion (variant 03, 2026-07-15) */
.sec-event-types { --h: 880px; background: #000000; }
.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(241,243,246,.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(19,19,19,.85), rgba(19,19,19,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(19,19,19,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(241,243,246,.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: #131313; 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: #131313; 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; }
  /* The head term ("<city> photo booth") must hold ONE line on a phone, with the accent word on the second
     (owner, 2026-10-17: three lines with "booth" alone is wrong). 9.6vw wrapped a 21-character head term
     at 390 (400px of text in 346px); 8vw with a 28px floor fits it at 360, 390 and 430. A build whose city
     is longer measures the first line unwrapped at 360 and lowers the vw until it fits. */
  .cur-title { font-size: clamp(28px, 8vw, 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; }
  /* The photo has to FILL the card. It is absolutely positioned with inset:0,
     but an absolutely positioned replaced element with height:auto keeps its
     intrinsic ratio and ignores `bottom`, so two photos of different shapes
     rendered at different heights inside the 4:3 cards (220px and 158px in a
     260px card, measured live on Desert Glow 2026-09-28) and the dark band
     under the caption was whatever was left, a different size on every card.
     Desktop never shows it because the canvas rules give the image its height. */
  .sec-intro .xpn-panel img,
  .sec-intro .xpn-panel video { width: 100%; height: 100%; object-fit: cover; }
  .sec-intro .xpn-desc { opacity: 1; transform: none; bottom: 56px; font-size: 13px;
                         max-width: none; right: 24px; }
  /* Phone reveal (owner, 2026-10-17: the panel text should not just sit there). Each .xpn-panel gets
     is-in from the reveal observer in script.js as it scrolls into view; number, name, then the line
     rise in, staggered. Desktop is untouched (hover reveals the line). Reduced motion: shown at once. */
  .sec-intro .xpn-panel .xpn-num, .sec-intro .xpn-panel .xpn-name, .sec-intro .xpn-panel .xpn-desc { opacity: 0; transform: translateY(14px); }
  .sec-intro .xpn-panel.is-in .xpn-num { animation: xpn-rise .9s cubic-bezier(.2,.7,.2,1) .1s forwards; }
  .sec-intro .xpn-panel.is-in .xpn-name { animation: xpn-rise 1s cubic-bezier(.2,.7,.2,1) .3s forwards; }
  .sec-intro .xpn-panel.is-in .xpn-desc { animation: xpn-rise 1s cubic-bezier(.2,.7,.2,1) .55s forwards; }
  /* The desktop scrim stays fully clear until 52% of the panel, which is safe
     there because .xpn-desc is hidden until hover. The rule above makes it
     permanently visible on mobile, where it runs three to five lines and its
     first lines land ABOVE that point, sitting on bare photo: measured 1.03:1
     against white 13px copy on a high-key branded shot at 360 wide (Desert
     Glow). Start the darkening where the desc actually begins. */
  .sec-intro .xpn-panel::after {
    background: linear-gradient(180deg, rgba(19,19,19,.12) 0%, rgba(19,19,19,.10) 20%,
                                        rgba(19,19,19,.64) 42%, rgba(19,19,19,.82) 100%); }
  .sec-intro .xpn-name { font-size: 24px; }

  /* CTA 2 */
  .sec-cta-2 .cv { min-height: 88svh; display: flex; padding: 96px 22px 56px; }
  /* pin the photo to the viewport on mobile (see .sec-hero note) */
  .sec-cta-2 { clip-path: inset(0); }
  .hzn-bg { position: fixed; background-attachment: scroll; }
  .sec-cta-2 .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-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-event-types { height: auto; min-height: 0; padding: 64px 0 56px; }
  /* margin: 0 is load-bearing: the head is a flex item of the section's
     column, and the desktop `margin: 0 auto` on a flex item cancels stretch,
     so the head shrank to its content and centred 43px in from the cards'
     22px edge (owner, 2026-09-28: eyebrow, title and arrows sit left, on the
     same edge as the cards). */
  .fcs-head { width: auto; margin: 0; 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: 18px; }   /* was 20: name + tag must share one row on a 360px card */
  .fcs-what { font-size: 10px; letter-spacing: .12em; }   /* one line on a 360px card at ~34 characters */
  .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; }

  /* 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; }
}

/* ---- the accent 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 / #000000 intro / #111214 testimonial /
   #2a2b2e stats / #000000 event types / near-black CTA are DARK -> --accent-lift;
   the cream body behind the gallery belt and #e9ecf0 about are LIGHT ->
   --accent. (The FAQ is the shared #111214 band since 2026-10-07: DARK.) */
/* .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); }

/* ---- FAQ (2026-10-07) ---------------------------------------------------------
   The FAQ is ONE shared block, identical on every page; the occasion page's copy
   is the master. Interior pages style it from css/patterns.css + css/services.css,
   which the home page cannot load (they restyle .sec-hero, .sec-faq,
   .sec-call-to-action and .sec-contact-form, all of which the home page uses).
   So these are the exact rules it needs, copied VERBATIM from those two files.
   Change one copy, change both. Wiring (accordion + reveal) is in script.js. */
.fl { position: relative; overflow: hidden; --line: rgba(17,17,17,.25); }
.fl-wrap { max-width: 1200px; margin: 0 auto; padding: 96px 60px 104px; }
.fl-dark2 { background: #111214; color: var(--cream-text); --line: rgba(241,243,246,.28); }
.fl-kicker { margin: 0 0 16px; font-family: var(--font-pop); font-weight: 300;
  font-size: 13px; letter-spacing: .24em; text-transform: uppercase; opacity: .8; }
.fl-title { margin: 0; font-family: var(--font-serif); font-weight: 400;
  font-size: 58px; line-height: 1.08; }
.fl-title em { font-family: var(--font-italic); font-style: normal; }
.fl-num { font-family: var(--font-italic); font-size: 22px; white-space: nowrap; }
.fade-in { opacity: 0; transform: translateY(24px);
  transition: opacity .8s ease, transform .8s ease; }
.fade-in.is-in { opacity: 1; transform: none; }
.qa-list { margin-top: 52px; }
.qa-item { display: grid; grid-template-columns: 96px 1fr; gap: 0 44px;
  padding: 30px 0; border-top: 1px solid var(--line); }
.qa-item:last-child { border-bottom: 1px solid var(--line); }
.qa-q { margin: 0; font-family: var(--font-serif); font-weight: 400;
  font-size: 27px; line-height: 1.2; }
.qa-a { grid-column: 2; margin: 12px 0 0; font-family: var(--font-pop);
  font-weight: 300; font-size: 15.5px; line-height: 1.6; max-width: 660px; }
.qa-acc .qa-q button { display: flex; width: 100%; align-items: baseline;
  justify-content: space-between; gap: 20px; background: none; border: 0;
  padding: 0; margin: 0; color: inherit; font: inherit; text-align: left;
  cursor: pointer; }
.qa-tog { flex: none; font-family: var(--font-italic); font-size: 17px;
  opacity: .65; white-space: nowrap; transition: opacity .3s ease; }
.qa-tog::before { content: "( Open )"; }
.qa-item.is-open .qa-tog::before { content: "( Close )"; }
.qa-acc .qa-q button:hover .qa-tog { opacity: 1; }
.qa-acc .qa-body { grid-column: 2; }
.qa-acc.js .qa-body { display: grid; grid-template-rows: 0fr;
  transition: grid-template-rows .55s ease; }
.qa-acc.js .qa-item.is-open .qa-body { grid-template-rows: 1fr; }
.qa-acc.js .qa-clip { min-height: 0; overflow: hidden; }
@keyframes xpn-rise { to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) {
  .sec-intro .xpn-panel .xpn-num, .sec-intro .xpn-panel .xpn-name, .sec-intro .xpn-panel .xpn-desc { opacity: 1; transform: none; animation: none; }
  .fade-in { opacity: 1; transform: none; transition: none; }
  .qa-acc.js .qa-body { transition: none; }
}
@media (max-width: 900px) {
  .fl-wrap { padding: 60px 22px 68px; }
  .fl-title { font-size: clamp(34px, 9.5vw, 44px); }
  .qa-item { grid-template-columns: 1fr; gap: 0; padding: 24px 0; }
  .qa-item .fl-num { margin-bottom: 8px; }
  .qa-q { font-size: 22px; }
  .qa-a { grid-column: 1; }
  .qa-acc .qa-body { grid-column: 1; }
}
