/* ===========================================================================
   Home page geometry — one block per section.
   Every co-ordinate was measured off the original's rendered DOM at an
   asserted 1200px viewport width. `left` values are canvas-relative
   (0 = left edge of the 1200px canvas); `top` values are section-relative.
   Each section's height is its --h; change that one number to resize it.
   Note: url() here resolves against css/, so images are ../img/...
   =========================================================================== */

/* ---- 1. header ----------------------------------------------------------
   The measured SCE nav (six absolutely placed links at fixed x offsets) is
   gone: this build has its own five in-page anchors plus the booking
   button, so the row is laid out with flex inside .hdr__in. NOT .cv --
   `.cv > * { position: absolute }` would drop every item on top of the
   logo. The logo is an <img> at img/cherry-on-top-logo.png; until that
   file is dropped in, the browser falls back to its alt text.          */
.sec-1 { --h: 117.4px; background: var(--ink); }
.hdr__in {
  width: var(--canvas); height: 100%; margin-inline: auto;
  padding: 0 30px; display: flex; align-items: center;
}
.hdr__logo { flex: none; display: block; color: #fff; }
/* the wordmark is 336x178, so drive it off HEIGHT and let the width follow:
   a fixed width plus max-height just letterboxes it inside its own box. */
.hdr__logo img { height: 76px; width: auto; }
.hdr__logo--sm img { height: 52px; }
.hdr__nav { display: flex; align-items: center; gap: 26px; margin-left: auto; }
.hdr__nav a { white-space: nowrap; }
.hdr__nav a:hover { color: var(--pink-lt); }
.hdr__cta {
  width: 168px; height: 40px; margin-left: 8px;
  font-size: 13px; line-height: 16px; letter-spacing: normal;
}

.hdr-sticky { height: var(--hdr-sticky-h); }

/* ---- 2. hero -----------------------------------------------------------
   Was a 494px band: black scrim over the photo, rotating "THE MOST …"
   headline. Design-variants round 5 "no panel", chosen 2026-08-01: the
   colour is a drifting magenta light mesh with the photograph sunk into
   it as texture, the headline sits straight on that mesh with a bar of
   light under it, and the ONLY glass is the shelf across the foot of the
   fold carrying the three numbers and the button.

   Like .sec-3 this section opts out of the fixed-canvas model: it fills
   the viewport below the static header, and its content is wrapped in
   .hx-in rather than .cv, because `.cv > * { position: absolute }` would
   drop the centred flow layout on the floor. Everything is prefixed
   .hx- so it cannot collide with the measured sections around it.    */
.sec-2 {
  --h: calc(100vh - var(--hdr-h));
  min-height: 700px;
  overflow: hidden;      /* the blurred light must not spill into sec-1 / sec-3 */
  background: #06060a;
  display: flex;
  align-items: center;
}

/* the light: three soft blobs on slow opposing drifts */
.hx-blob { position: absolute; border-radius: 50%; filter: blur(96px); }
.hx-b1 {
  width: 900px; height: 760px; left: -12%; top: -22%;
  background: rgba(143,42,82,.62);
  animation: hx-d1 26s ease-in-out infinite alternate;
}
.hx-b2 {
  width: 700px; height: 640px; right: -6%; top: 2%;
  background: rgba(74,16,52,.62);
  animation: hx-d2 33s ease-in-out infinite alternate;
}
.hx-b3 {
  width: 620px; height: 540px; left: 38%; bottom: -26%;
  background: rgba(210,110,155,.34);
  animation: hx-d3 21s ease-in-out infinite alternate;
}
@keyframes hx-d1 { to { transform: translate(120px,90px)  scale(1.12); } }
@keyframes hx-d2 { to { transform: translate(-130px,60px) scale(1.08); } }
@keyframes hx-d3 { to { transform: translate(90px,-110px) scale(1.16); } }

/* The photograph, sunk into the mesh as luminance only. PINNED: the
   background is fixed to the viewport, so the type, the shelf and the
   drifting light all scroll over a stationary photo. Same technique the
   original statement bands used (.sec--parallax in style.css). It only
   works while no ANCESTOR has a transform/filter/will-change, which would
   turn the fixed background back into a scrolling one, so keep .sec-2
   free of those. iOS ignores it and falls back to scroll, which is fine
   for a desktop-first canvas. */
.hx-tex {
  position: absolute; inset: 0;
  background: url('../img/cot-hero.jpg') 50% 40%/cover no-repeat fixed;
  opacity: .18; mix-blend-mode: luminosity;
}
/* film grain over the whole field, as an inline SVG so nothing is fetched */
.hx-grain {
  position: absolute; inset: 0; opacity: .3; pointer-events: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='140' height='140'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2'/></filter><rect width='140' height='140' filter='url(%23n)' opacity='.5'/></svg>");
}
.hx-vig {
  position: absolute; inset: 0;
  background: radial-gradient(120% 100% at 50% 42%, rgba(0,0,0,0) 24%, rgba(0,0,0,.8) 100%);
}

.hx-in {
  position: relative; z-index: 3;
  width: var(--canvas); margin: 0 auto;
  /* the shelf is 104px tall and full-bleed, so the stack clears it */
  padding: 0 30px 120px;
  display: flex; flex-direction: column; align-items: center; text-align: center;
}

.hx-chip {
  display: inline-flex; align-items: center; gap: 12px;
  padding: 9px 18px; margin-bottom: 30px; border-radius: 99px;
  background: rgba(255,255,255,.1); border: 1px solid rgba(255,255,255,.24);
  -webkit-backdrop-filter: blur(14px); backdrop-filter: blur(14px);
  font-size: 11px; font-weight: 700; letter-spacing: .16em;
  text-transform: uppercase; color: #fff;
  animation: hx-fade .8s ease .1s both;
}
.hx-chip b { color: var(--pink-lt); letter-spacing: .2em; }

.hx-ttl {
  font-family: 'Anton', Arial, sans-serif; font-weight: 400;
  text-transform: uppercase; color: #fff;
  font-size: 104px; line-height: .9; letter-spacing: .5px;
  text-shadow: 0 14px 60px rgba(0,0,0,.6);
}
/* each line is masked by its own overflow box so it can slide up into place */
.hx-ttl b { display: block; overflow: hidden; font-weight: 400; }
.hx-ttl b i { display: block; font-style: normal; animation: hx-rise 1s cubic-bezier(.2,.7,.2,1) both; }
.hx-ttl b:nth-child(1) i { animation-delay: .08s; }
.hx-ttl b:nth-child(2) i { animation-delay: .2s; color: var(--pink-lt); }
@keyframes hx-rise { from { transform: translateY(108%); } to { transform: translateY(0); } }

/* a bar of light under the headline instead of a rule */
.hx-glow {
  width: 520px; height: 3px; margin-top: 26px; border-radius: 99px;
  background: linear-gradient(90deg, rgba(143,42,82,0), var(--pink), rgba(143,42,82,0));
  box-shadow: 0 0 40px rgba(143,42,82,.85);
  animation: hx-fade .9s ease .5s both;
}
.hx-txt {
  margin-top: 26px; max-width: 620px;
  font-size: 16px; line-height: 28px; letter-spacing: .24px; color: #e2e4e8;
  animation: hx-fade .9s ease .56s both;
}

/* the shelf: the only glass on the page */
.hx-shelf {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 4; height: 104px;
  display: flex; align-items: center; justify-content: center; gap: 40px;
  background: rgba(10,6,14,.42); border-top: 1px solid rgba(255,255,255,.22);
  -webkit-backdrop-filter: blur(26px) saturate(150%);
  backdrop-filter: blur(26px) saturate(150%);
  animation: hx-up 1s cubic-bezier(.2,.7,.2,1) .6s both;
}
.hx-stat { text-align: center; }
.hx-stat b {
  display: block; font-family: 'Anton', Arial, sans-serif; font-weight: 400;
  font-size: 30px; line-height: 1; color: #fff;
}
.hx-stat em {
  display: block; margin-top: 5px; font-style: normal;
  font-size: 10px; font-weight: 700; letter-spacing: .2em;
  text-transform: uppercase; color: rgba(255,255,255,.7);
}
.hx-stat:first-child b { color: var(--pink-lt); }
.hx-sep { width: 1px; height: 46px; background: rgba(255,255,255,.2); }
.hx-btn {
  display: flex; align-items: center; justify-content: center;
  width: 214px; height: 56px; background: var(--pink); color: #fff;
  font-size: 14px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase;
}
.hx-btn:hover { background: #fff; color: var(--pink); }

@keyframes hx-up   { from { opacity: 0; transform: translateY(26px); } to { opacity: 1; transform: none; } }
@keyframes hx-fade { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }

/* ---- 3. about Cherry On Top Services ------------------------------------
   Was the SCE pull quote + intro (a 388.3px white band). Design-variants
   round 2 "stage" put the copy over a full-bleed photograph; round 3 dropped
   the photograph for a WHITE ground and combined two of its ten details
   (chosen 2026-08-01): magenta crop marks framing the band, and the business
   name set enormous in outline only behind the headline.

   This is the one section that opts OUT of the fixed-height canvas model.
   Its height comes from its copy, so it overrides .sec's `height: var(--h)`
   with auto and wraps its content in .abt-cv rather than .cv — `.cv > * {
   position: absolute }` would drop the whole flow layout on the floor.
   Everything is prefixed .abt- so it cannot collide with the measured
   sections either side of it.                                          */
.sec-3 {
  height: auto;        /* beats .sec { height: var(--h) }: later stylesheet */
  overflow: hidden;    /* the wordmark bleeds past both edges on purpose */
  background: #fff;
  /* 96px of head room, not the standalone's 78: the fixed .hdr-sticky bar is
     83.8px tall, and at 78 it clipped the eyebrow for anyone who stopped
     scrolling exactly at this section's top edge. */
  padding: 96px 0 76px;
}

/* the wordmark: outline only, no fill, bled off both edges and sitting far
   enough back that the headline reads straight over it */
.abt-ghost {
  position: absolute; z-index: 0;
  left: 50%; top: 150px; transform: translateX(-50%);
  font-family: 'Anton', Arial, sans-serif;
  font-size: 230px; line-height: 1; letter-spacing: 4px;
  white-space: nowrap;
  color: transparent; -webkit-text-stroke: 1px #ebeae7;
  user-select: none;
}
/* crop marks: one corner each, pushed right out to the four corners of the
   section itself — full viewport width, not the 1200px canvas — with only a
   16px breath so they read as marks rather than a clipped border. */
.abt-frame { position: absolute; z-index: 0; inset: 16px; }
.abt-frame i { position: absolute; width: 44px; height: 44px; }
.abt-frame i:nth-child(1) { top: 0; left: 0;
  border-top: 2px solid var(--pink); border-left: 2px solid var(--pink); }
.abt-frame i:nth-child(2) { top: 0; right: 0;
  border-top: 2px solid var(--pink); border-right: 2px solid var(--pink); }
.abt-frame i:nth-child(3) { bottom: 0; left: 0;
  border-bottom: 2px solid var(--pink); border-left: 2px solid var(--pink); }
.abt-frame i:nth-child(4) { bottom: 0; right: 0;
  border-bottom: 2px solid var(--pink); border-right: 2px solid var(--pink); }
.abt-rule { position: absolute; z-index: 3; inset: 0 0 auto 0; height: 5px; background: var(--pink); }
.abt-cv   { position: relative; z-index: 2; width: var(--canvas); margin-inline: auto; }

.abt-eyebrow { font-size: 12px; font-weight: 700; letter-spacing: 4.4px;
               text-transform: uppercase; color: var(--pink); }
.abt-head    { margin-top: 18px; width: 840px;
               font-size: 64px; line-height: 68px; letter-spacing: .4px;
               text-transform: uppercase; color: var(--head); }
.abt-head em { font-style: normal; color: var(--pink); }
/* 840px, not 640: the same measure as .abt-head, so the lead ends on the
   headline's right edge instead of stopping short. Widened 2026-08-03 when
   the copy grew — at 640 it ran to 13 lines and pushed the section to
   1031px; at 840 it is 10 lines and 938px. */
/* Justified on the client's note (2026-08-17): both edges of the lead now land
   on the same measure as the headline above it. */
.abt-lead    { margin-top: 24px; width: 840px;
               font-size: 20px; line-height: 31px; font-weight: 600; color: var(--head);
               text-align: justify; }
/* The lead runs long enough to need two paragraphs. The second is a
   continuation of the same thought, so it takes a tighter gap than the 24px
   .abt-lead uses to separate itself from the headline above. */
.abt-lead--cont { margin-top: 18px; }

.abt-cols { margin-top: 44px; padding-top: 34px;
            border-top: 1px solid var(--band);
            display: grid; grid-template-columns: repeat(2, 1fr); column-gap: 64px; }
.abt-cols p { font-size: 15.5px; line-height: 28px; color: var(--body); }
.abt-cols p + p { margin-top: 16px; }
.abt-cols b { font-weight: 600; color: var(--head); }

.abt-foot { margin-top: 44px; display: flex; align-items: center; justify-content: space-between; }
.abt-btn  { height: 62px; padding: 0 40px; letter-spacing: .4px; transition: transform .3s ease; }
.abt-btn:hover { transform: translateY(-2px); }
.abt-social   { display: flex; align-items: center; gap: 18px; }
.abt-social a { display: flex; align-items: center; justify-content: center;
                width: 44px; height: 44px; border: 1px solid var(--band);
                transition: border-color .3s ease, background .3s ease; }
.abt-social a:hover { border-color: var(--pink); background: var(--pink); }
.abt-social svg { width: 20px; height: 20px; fill: #9aa0aa; transition: fill .3s ease; }
.abt-social a:hover svg { fill: #fff; }

/* Entrance, on the same terms as the triptych's: the band is fully legible
   without it, and script.js only adds .is-in once the section is reached. */
.sec-3.is-in .abt-eyebrow,
.sec-3.is-in .abt-lead,
.sec-3.is-in .abt-cols,
.sec-3.is-in .abt-foot { animation: abt-fade .85s ease both; }
.sec-3.is-in .abt-head { animation: abt-rise .85s cubic-bezier(.2,.7,.25,1) both; }
.sec-3.is-in .abt-eyebrow { animation-delay: .06s; }
.sec-3.is-in .abt-head    { animation-delay: .14s; }
.sec-3.is-in .abt-lead    { animation-delay: .30s; }
.sec-3.is-in .abt-cols    { animation-delay: .44s; }
.sec-3.is-in .abt-foot    { animation-delay: .58s; }
@keyframes abt-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes abt-rise { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: none; } }
/* (abt-push and its reduced-motion opt-out went with the photograph) */

/* ---- 4/5/6. the three statements, as one triptych ---------------------
   The original ran three separate 100vh parallax bands, one centred Anton
   line each with a magenta halo. This is the design-variants 02 "triptych"
   (chosen 2026-08-01): the three bands turned sideways into three
   full-height columns inside ONE viewport, statements anchored low, the
   same three photos. Hovering a column widens it, restores its colour and
   opens the proof copy; the columns wipe up in sequence the first time the
   section is reached (script.js block 4). Nothing here needs the 1200px
   canvas, so this section has no .cv: the columns bleed edge to edge.
   NB: `.sec--parallax`, `.statement` and `.t-h3` in style.css are what
   drove the old bands and are now unused by this page.                 */
.sec-stmt { --h: 100vh; min-height: 640px; display: flex; background: var(--ink); }
/* the 5px pink rule the three bands each carried, kept once for the run */
.sec-stmt::before {
  content: ''; position: absolute; inset: 0 0 auto 0;
  height: 5px; background: var(--pink); z-index: 9;
}

.stmt {
  position: relative; flex: 1 1 0; overflow: hidden; cursor: pointer;
  border-right: 1px solid rgba(255,255,255,.16);
  transition: flex-grow .6s cubic-bezier(.2,.7,.2,1);
}
.stmt:last-child { border-right: 0; }

/* the photo sits in its own layer so the hover can zoom and recolour it
   without touching the gradient that keeps the type readable */
.stmt__img {
  position: absolute; inset: 0;
  background-position: 50% 50%; background-size: cover; background-repeat: no-repeat;
  filter: grayscale(1) contrast(1.08) brightness(.62);
  transform: scale(1.04);
  transition: filter .6s ease, transform .8s cubic-bezier(.2,.7,.2,1);
}
/* Right-sized copies: the 2500x1667 originals were 4.2MP each (~17MB decoded)
   for a column that is never wider than ~55% of the viewport. The originals
   are still used full-bleed by .cba-bg and by the archived variant rounds,
   so these are separate files rather than a resize in place. */
.stmt-1 .stmt__img { background-image: url('../img/cot-stmt-1.jpg'); }
.stmt-2 .stmt__img { background-image: url('../img/cot-stmt-2.jpg'); }
.stmt-3 .stmt__img { background-image: url('../img/cot-stmt-3.jpg'); }
.stmt::after {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(180deg,
    rgba(0,0,0,.45) 0%, rgba(0,0,0,0) 34%, rgba(0,0,0,.78) 100%);
}

.stmt__in { position: absolute; inset: auto 0 0 0; z-index: 3; padding: 0 40px 52px; }
.stmt__num {
  margin-bottom: 16px;
  font-size: 11px; font-weight: 700; letter-spacing: .28em;
  text-transform: uppercase; color: var(--pink);
}
.stmt__ttl {
  font-family: 'Anton', Arial, sans-serif; font-weight: 400;
  font-size: 46px; line-height: 1.02; letter-spacing: .5px;
  text-transform: uppercase; color: #fff;
}
/* the proof copy is collapsed until the column opens */
.stmt__more {
  max-height: 0; opacity: 0; overflow: hidden;
  transition: max-height .6s cubic-bezier(.2,.7,.2,1), opacity .4s ease;
}
.stmt__more p {
  margin-top: 18px; max-width: 420px;
  font-size: 15px; line-height: 27px; letter-spacing: .24px; color: #d7dade;
}
.stmt__link {
  display: inline-block; margin-top: 18px; padding-bottom: 5px;
  border-bottom: 1px solid var(--pink);
  font-size: 12px; font-weight: 700; letter-spacing: .2em;
  text-transform: uppercase; color: #fff;
}
.stmt__link:hover { color: var(--pink); }
/* the pink underline that grows across the column foot */
.stmt__rule {
  position: absolute; left: 40px; bottom: 0; z-index: 4;
  height: 3px; width: 0; background: var(--pink);
  transition: width .6s cubic-bezier(.2,.7,.2,1);
}

/* Both of these must carry the same specificity or the narrowing rule wins
   over the widening one and every column stays a third of the screen: hence
   `.sec-stmt .stmt:hover` rather than the shorter `.stmt:hover`.
   (Adding .is-pointing to both keeps them equal at (0,3,0).)

   .is-pointing gates ONLY the resize, and script.js sets it on a real
   mousemove and clears it on scroll. Without that gate, scrolling with the
   pointer anywhere over the section reflowed the columns from 400/400/400 to
   270/270/658 — and because the content moves under a stationary cursor, the
   hovered column kept changing and the columns re-animated the whole way
   down. That was the "glitchy on scroll" report of 2026-08-03. The colour
   and copy reveals below are NOT gated: they change nothing's geometry. */
.sec-stmt.is-pointing:hover .stmt { flex-grow: .78; }
.sec-stmt.is-pointing .stmt:hover { flex-grow: 1.9; }
.stmt:hover .stmt__img { filter: grayscale(0) contrast(1) brightness(.78); transform: scale(1); }
.stmt:hover .stmt__more { max-height: 230px; opacity: 1; }
.stmt:hover .stmt__rule { width: calc(100% - 80px); }

/* Entrance. The columns are fully legible without it: script.js adds
   .is-in when the section first scrolls into view and only then does the
   wipe run, so nothing here depends on the observer firing.            */
.sec-stmt.is-in .stmt { animation: stmt-col .9s cubic-bezier(.2,.7,.2,1) both; }
.sec-stmt.is-in .stmt-1 { animation-delay: .05s; }
.sec-stmt.is-in .stmt-2 { animation-delay: .17s; }
.sec-stmt.is-in .stmt-3 { animation-delay: .29s; }
@keyframes stmt-col {
  from { clip-path: inset(100% 0 0 0); }
  to   { clip-path: inset(0 0 0 0); }
}

/* ---- 7. (an empty 0-height row in the original; nothing to render) ----- */

/* ---- 8. packages -------------------------------------------------------
   Two priced cards side by side. Like sec-3 this section is flow, not
   canvas: its height comes from the copy (the two descriptions are long
   and must never be clipped), so it overrides .sec's fixed height and
   wraps its content in .pkg-cv rather than .cv.                       */
.sec-pkg { height: auto; background: var(--cream); padding: 92px 0 96px; }
.pkg-cv { width: var(--canvas); margin-inline: auto; padding: 0 30px; }
.pkg-eyebrow {
  font-size: 11px; font-weight: 700; letter-spacing: .32em;
  text-transform: uppercase; color: var(--pink);
}
.pkg-head { margin-top: 14px; text-transform: uppercase; }
.pkg-grid {
  margin-top: 44px; display: grid; grid-template-columns: 1fr 1fr; gap: 26px;
  align-items: start;
}
.pkg {
  display: flex; flex-direction: column; height: 100%;
  background: #fff; border: 1px solid #e4e2dd; padding: 34px 34px 32px;
}
.pkg__top {
  display: flex; align-items: flex-start; justify-content: space-between; gap: 20px;
  padding-bottom: 20px; border-bottom: 1px solid #e4e2dd;
}
.pkg__name {
  font-family: 'Anton', Arial, sans-serif; font-weight: 400;
  font-size: 26px; line-height: 1.1; color: var(--head); text-transform: uppercase;
}
.pkg__price {
  flex: none; font-family: 'Anton', Arial, sans-serif; font-weight: 400;
  font-size: 34px; line-height: 1; color: var(--pink);
}
.pkg__desc { margin-top: 20px; }
.pkg__list { margin-top: 20px; padding-top: 18px; border-top: 1px solid #e4e2dd; }
.pkg__list li {
  position: relative; padding-left: 22px; margin-top: 11px;
  font-size: 15px; line-height: 24px; color: var(--head);
}
.pkg__list li::before {
  content: ''; position: absolute; left: 0; top: 9px;
  width: 8px; height: 8px; border-radius: 50%; background: var(--pink);
}
.pkg__cta {
  margin-top: 26px; align-self: flex-start; width: 190px; height: 48px;
}

/* ---- 9. the photo strip ------------------------------------------------
   A continuously sliding band of six portrait tiles, doubled, running
   full bleed. This is the one section that clips: .sec is overflow:visible
   everywhere else, but the track is deliberately wider than the viewport.
   The travel distance is ONE set width, 6 x 260px = 1560px; change the tile
   width or the tile count and this number changes with it or the loop
   visibly jumps. Was 8 x 260 = 2080px until the client's 2026-08-17 note
   pulled two tiles. Speed held at roughly 55px a second, so the duration
   came down with the distance: 1560px / 28.5s.                          */
.sec-9 { --h: 380px; background: var(--ink); overflow: hidden; }
.sec-9 .strip__track {
  display: flex; height: 100%; width: max-content;
  animation: strip-slide 28.5s linear infinite;
  will-change: transform;
}
.sec-9 .strip__track img { flex: none; width: 260px; height: 380px; object-fit: cover; }
@keyframes strip-slide {
  from { transform: translateX(0); }
  to   { transform: translateX(-1560px); }
}

/* ---- 10. add-ons -------------------------------------------------------
   One enhancement on screen at a time. The five slides are stacked in a
   single grid cell (grid-area: 1/1), which is what keeps the stage the
   height of the LONGEST add-on: an inactive slide is hidden with
   visibility, not display, so it still contributes its height and the
   section never jumps as you page through. Flow height, like the packages,
   because the client's descriptions must never be clipped.            */
.sec-add { height: auto; background: #fff; padding: 92px 0 96px; }
.add-cv { width: var(--canvas); margin-inline: auto; padding: 0 30px; }

.add-top {
  display: flex; align-items: flex-end; justify-content: space-between; gap: 40px;
  padding-bottom: 26px; border-bottom: 1px solid #e4e2dd;
}
.add-eyebrow {
  font-size: 11px; font-weight: 700; letter-spacing: .32em;
  text-transform: uppercase; color: var(--pink);
}
.add-head { margin-top: 14px; text-transform: uppercase; }

.add-nav { display: flex; align-items: center; gap: 14px; }
.add-count {
  margin-right: 6px; font-size: 12px; font-weight: 700; letter-spacing: .18em;
  text-transform: uppercase; color: #9aa0ab;
}
.add-count b { font-weight: 700; color: var(--head); }
.add-arrow {
  display: flex; align-items: center; justify-content: center;
  width: 52px; height: 52px; border: 1px solid #d8d5cf; color: var(--head);
  transition: background .25s ease, border-color .25s ease, color .25s ease;
}
.add-arrow svg { width: 20px; height: 20px; display: block; }
.add-arrow--next svg { transform: rotate(180deg); }
.add-arrow:hover { background: var(--pink); border-color: var(--pink); color: #fff; }

/* the stage: every slide in the same cell.
   overflow:hidden so the incoming slide's travel is clipped to the stage and
   can never widen the page (it used to, by 4px, on a 390px screen). */
.add-stage { display: grid; margin-top: 38px; overflow: hidden; }
.ad {
  grid-area: 1 / 1;
  display: grid; grid-template-columns: 360px 1fr; gap: 40px;
  opacity: 0; visibility: hidden;
  /* NO transition on the way out — see below */
}
/* Only the INCOMING slide animates; the outgoing one is hidden on the same
   frame. This replaced a crossfade (2026-08-04): transitioning `visibility`
   over .4s kept the outgoing slide visible for the whole fade, so for ~320ms
   two different blocks of copy were both painted at partial opacity in the
   same grid cell and you could read one through the other. Now exactly one
   slide is ever on screen. */
.ad.is-on {
  opacity: 1; visibility: visible;
  animation: ad-in .3s cubic-bezier(.2,.7,.2,1) both;
}
@keyframes ad-in {
  from { opacity: 0; transform: translateX(20px); }
  to   { opacity: 1; transform: none; }
}
/* stepping backwards comes in from the other side */
.add-stage.is-back .ad.is-on { animation-name: ad-in-back; }
@keyframes ad-in-back {
  from { opacity: 0; transform: translateX(-20px); }
  to   { opacity: 1; transform: none; }
}

.ad__top { align-self: start; }
/* One photo per enhancement, on the client's 2026-08-17 note that couples
   need to SEE what the enhancement is. It sits under the name and price in
   the 360px column.
   ONE shared 360x300 box, not each photo's own aspect ratio: the four they
   sent run from 16:9 to portrait, and letting the portrait one stand at its
   full height made the stage 460px taller than the longest description, so
   every other slide opened with a band of empty white under it. 300px is
   what fits beside the longest body (name + price + gap + photo = 406px,
   against a 415px description) without growing the section at all. */
.ad__img {
  display: block; width: 100%; height: 300px; margin-top: 26px;
  object-fit: cover; background: #f1efea;
}
.ad__name {
  font-family: 'Anton', Arial, sans-serif; font-weight: 400;
  font-size: 34px; line-height: 1.06; color: var(--head); text-transform: uppercase;
}
.ad__price {
  margin-top: 12px; font-family: 'Anton', Arial, sans-serif; font-weight: 400;
  font-size: 34px; line-height: 1; color: var(--pink);
}
.ad__body p { font-size: 15px; line-height: 26px; letter-spacing: .24px; color: var(--body); }
.ad__body p + p, .ad__body ul + p { margin-top: 14px; }
.ad__lead { font-size: 16px !important; color: var(--head) !important; font-weight: 600; }
.ad__q { margin-top: 18px !important; font-weight: 700; color: var(--head) !important; }
.ad__body ul { margin-top: 10px; }
.ad__body li {
  position: relative; padding-left: 22px; margin-top: 9px;
  font-size: 15px; line-height: 25px; color: var(--body);
}
.ad__body li::before {
  content: ''; position: absolute; left: 0; top: 9px;
  width: 8px; height: 8px; border-radius: 50%; background: var(--pink);
}
.ad__body li b, .ad__inc b { color: var(--head); }
.ad__inc {
  margin-top: 22px !important; padding-top: 16px; border-top: 1px solid #e4e2dd;
  font-size: 14px !important; letter-spacing: .1em;
}
.ad__inc b {
  display: inline-block; margin-right: 12px;
  font-size: 11px; font-weight: 700; letter-spacing: .2em; text-transform: uppercase;
  color: var(--pink);
}

/* the name tabs double as the position indicator */
.add-tabs {
  display: flex; flex-wrap: wrap; gap: 8px;
  margin-top: 40px; padding-top: 26px; border-top: 1px solid #e4e2dd;
}
.add-tab {
  /* tuned so all five names sit on ONE row inside the 1140px canvas */
  padding: 10px 13px; border: 1px solid #d8d5cf;
  font-size: 11px; font-weight: 700; letter-spacing: .1em;
  text-transform: uppercase; color: #7c828c;
  transition: background .25s ease, border-color .25s ease, color .25s ease;
}
.add-tab:hover { color: var(--head); border-color: var(--head); }
.add-tab.is-on { background: var(--pink); border-color: var(--pink); color: #fff; }

@media (prefers-reduced-motion: reduce) {
  /* straight swap, no travel and no fade */
  .ad.is-on { animation: none; }
}

/* ---- 10b. parties & events ---------------------------------------------
   The deck, restored from the archived variants round. Three matted prints
   fanned on the centre line that spread apart and show their captions on
   hover, one per event type in the onboarding form. Canvas model, like the
   rest of the measured sections: every child of .cv is absolutely placed. */
.sec-pev { --h: 900px; background: var(--cream); overflow: hidden; }

.sec-pev .pev-kick {
  left: 0; top: 92px; width: 1200px; text-align: center;
  font-size: 11px; font-weight: 700; letter-spacing: .34em;
  text-transform: uppercase; color: var(--pink);
}
.sec-pev .pev-t {
  left: 0; top: 138px; width: 1200px; text-align: center;
  font-family: 'Anton', Arial, sans-serif; font-weight: 400;
  font-size: 62px; line-height: 1.04; letter-spacing: .4px;
  text-transform: uppercase; color: var(--head);
}
/* the connecting word drops to its own line and carries the accent, the way
   the original's ampersand did */
.sec-pev .pev-t em { font-style: normal; color: var(--pink); }

.sec-pev .pev-deck { left: 0; top: 330px; width: 1200px; height: 340px; }
.pev-pr {
  position: absolute; left: 50%; top: 0; width: 250px; height: 300px;
  margin-left: -125px; background: #fff; padding: 10px;
  box-shadow: 0 22px 50px rgba(33,41,52,.26);
  transform: translateX(var(--x)) rotate(var(--r));
  transition: transform .55s cubic-bezier(.2,.7,.25,1), box-shadow .55s ease;
}
.pev-pr img { width: 100%; height: 100%; object-fit: cover; display: block; }
.pev-cap {
  position: absolute; left: 10px; right: 10px; bottom: 10px;
  padding: 9px 0; background: rgba(0,0,0,.62); color: #fff; text-align: center;
  font-size: 10.5px; font-weight: 700; letter-spacing: 2.2px; text-transform: uppercase;
  opacity: 0; transition: opacity .4s ease;
}
.pev-deck:hover .pev-cap { opacity: 1; }
/* three prints, so the fan is symmetrical about the middle one */
.pev-p1 { --x: -215px; --r: -9deg; z-index: 1; }
.pev-p2 { --x: 0px;    --r: 0deg;  z-index: 3; }
.pev-p3 { --x: 215px;  --r: 9deg;  z-index: 2; }
.pev-deck:hover .pev-p1 { --x: -320px; --r: -4deg; }
.pev-deck:hover .pev-p2 { --x: 0px;    --r: 0deg; }
.pev-deck:hover .pev-p3 { --x: 320px;  --r: 4deg; }
.pev-pr:hover { box-shadow: 0 34px 74px rgba(33,41,52,.36); }

.sec-pev .pev-cta {
  left: 450px; top: 730px; width: 300px; height: 60px;
  display: flex; align-items: center; justify-content: center; gap: 14px;
  background: var(--pink); color: #fff;
  font-size: 14px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase;
}
.sec-pev .pev-cta svg { width: 16px; height: 10px; fill: none; stroke: currentColor; stroke-width: 1.6; }
.sec-pev .pev-cta:hover { background: var(--head); }

/* ---- 10c. call to action band ------------------------------------------
   Full-bleed photo interstitial between the deck and the service area. Its
   foot fades to near black so it runs into the black band below rather than
   butting against it.                                                 */
.sec-cba { --h: 520px; overflow: hidden; }
.cba-bg {
  position: absolute; inset: 0;
  background: url('../img/cot-cta.jpg') 50% 46%/cover no-repeat;
  filter: grayscale(1) contrast(1.08) brightness(.62);
}
.cba-wash {
  position: absolute; inset: 0;
  background:
    linear-gradient(180deg, rgba(6,6,10,.7) 0%, rgba(6,6,10,.45) 40%, rgba(0,0,0,.96) 100%),
    radial-gradient(70% 90% at 50% 55%, rgba(143,42,82,.5), rgba(143,42,82,0) 72%);
}
.cba-cv {
  position: relative; z-index: 2;
  width: var(--canvas); height: 100%; margin-inline: auto; padding: 0 30px;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  text-align: center;
}
.cba-eyebrow {
  font-size: 11px; font-weight: 700; letter-spacing: .34em;
  text-transform: uppercase; color: var(--pink-lt);
}
.cba-head {
  margin-top: 20px; font-family: 'Anton', Arial, sans-serif; font-weight: 400;
  font-size: 64px; line-height: 1.02; letter-spacing: .4px;
  text-transform: uppercase; color: #fff; text-shadow: 0 10px 50px rgba(0,0,0,.6);
}
.cba-sub {
  margin-top: 20px; max-width: 620px;
  font-size: 16px; line-height: 28px; letter-spacing: .24px; color: #dfe1e6;
}
.cba-acts { display: flex; align-items: center; gap: 30px; margin-top: 34px; }
.cba-btn {
  display: flex; align-items: center; justify-content: center;
  width: 226px; height: 58px; background: var(--pink); color: #fff;
  font-size: 14px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase;
}
.cba-btn:hover { background: #fff; color: var(--pink); }
.cba-mail {
  font-size: 14px; letter-spacing: .04em; color: #e2e4e8;
  border-bottom: 1px solid rgba(255,255,255,.4); padding-bottom: 4px;
}
.cba-mail:hover { color: var(--pink-lt); border-color: var(--pink-lt); }

/* ---- 11. service area --------------------------------------------------
   Replaces the testimonials headliner, which was removed with the SCE
   reviews in it. Nothing here is invented: primary city, surrounding
   cities and travel distance, exactly as the onboarding form gives them. */
.sec-area { --h: 420px; background: var(--ink); }
.area-cv {
  width: var(--canvas); height: 100%; margin-inline: auto; padding: 0 30px;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  text-align: center;
}
.area-eyebrow {
  font-size: 11px; font-weight: 700; letter-spacing: .34em;
  text-transform: uppercase; color: var(--pink-lt);
}
.area-head {
  margin-top: 18px; font-family: 'Anton', Arial, sans-serif; font-weight: 400;
  font-size: 96px; line-height: .94; letter-spacing: .5px;
  text-transform: uppercase; color: #fff;
}
.area-cities {
  margin-top: 20px; font-size: 15px; font-weight: 600; letter-spacing: .14em;
  text-transform: uppercase; color: #c9ccd3;
}
.area-travel {
  display: flex; align-items: baseline; gap: 14px; margin-top: 34px;
  padding-top: 22px; border-top: 1px solid rgba(255,255,255,.24);
}
.area-travel b { font-family: 'Anton', Arial, sans-serif; font-weight: 400; font-size: 34px; color: #fff; }
.area-travel em {
  font-style: normal; font-size: 11px; font-weight: 700; letter-spacing: .2em;
  text-transform: uppercase; color: #8b919c;
}

/* ---- 12b. FAQ ----------------------------------------------------------
   Native <details> accordion. The answer is display:none until the item is
   [open], so nothing is merely visually hidden. The marker is drawn as two
   bars that become a minus when open, and the arrow is suppressed because
   Safari and Chrome draw different default triangles.                 */
.sec-faq { height: auto; background: var(--cream); padding: 92px 0 96px; }
.faq-cv { width: var(--canvas); margin-inline: auto; padding: 0 30px; }
.faq-eyebrow {
  font-size: 11px; font-weight: 700; letter-spacing: .32em;
  text-transform: uppercase; color: var(--pink);
}
.faq-head { margin-top: 14px; text-transform: uppercase; }

.faq-list { margin-top: 40px; border-top: 1px solid #ddd9d2; }
.faq-i { border-bottom: 1px solid #ddd9d2; }
.faq-q {
  display: flex; align-items: flex-start; gap: 20px;
  padding: 24px 4px; cursor: pointer; list-style: none;
  transition: color .25s ease;
}
/* both engines draw their own marker; suppress both */
.faq-q::-webkit-details-marker { display: none; }
.faq-q::marker { content: ''; }
.faq-n {
  flex: none; width: 30px; padding-top: 4px;
  font-size: 12px; font-weight: 700; letter-spacing: .1em; color: var(--pink);
}
.faq-qt {
  flex: 1; font-family: 'Anton', Arial, sans-serif; font-weight: 400;
  font-size: 22px; line-height: 1.24; color: var(--head); text-transform: none;
}
.faq-i:hover .faq-qt, .faq-i[open] .faq-qt { color: var(--pink); }

/* the plus / minus */
.faq-mark {
  position: relative; flex: none; width: 22px; height: 22px; margin-top: 3px;
}
.faq-mark::before, .faq-mark::after {
  content: ''; position: absolute; left: 50%; top: 50%; background: var(--head);
  transform: translate(-50%,-50%); transition: transform .3s ease, background .25s ease;
}
.faq-mark::before { width: 15px; height: 2px; }
.faq-mark::after  { width: 2px; height: 15px; }
.faq-i[open] .faq-mark::after { transform: translate(-50%,-50%) scaleY(0); }
.faq-i[open] .faq-mark::before, .faq-i:hover .faq-mark::before,
.faq-i:hover .faq-mark::after { background: var(--pink); }

.faq-a { padding: 0 60px 26px 50px; }
.faq-a p {
  font-size: 15.5px; line-height: 27px; letter-spacing: .24px; color: var(--body);
  max-width: 880px;
}
/* the open animation is on the answer, not on height: animating height on
   <details> needs JS to measure, and this reads just as well */
.faq-i[open] .faq-a { animation: faq-in .35s ease both; }
@keyframes faq-in { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: none; } }

/* ---- 13. footer --------------------------------------------------------
   Four columns of flow, not the measured absolute grid: the SCE footer
   had an address, hours, a phone number and a client login, none of which
   the onboarding form provides.                                       */
.sec-13 { height: auto; background: var(--ink); padding: 66px 0 58px; }
.ft-cv {
  width: var(--canvas); margin-inline: auto; padding: 0 30px;
  display: grid; grid-template-columns: 1.2fr 1fr 1fr .8fr; gap: 40px; align-items: start;
}
.ft-logo { display: block; color: #fff; }
.ft-logo img { height: 84px; width: auto; }
.ft-domain { margin-top: 16px; font-size: 13px; letter-spacing: .1em; color: #8b919c; }
.ft-lab {
  font-size: 11px; font-weight: 700; letter-spacing: .24em;
  text-transform: uppercase; color: var(--pink-lt); margin-bottom: 14px;
}
.ft-txt { font-size: 14px; line-height: 24px; color: #d7dade; }
.ft-txt + .ft-txt { margin-top: 10px; }
.ft-txt a { text-decoration: none; }
.ft-txt a:hover { color: var(--pink-lt); }
.ft-social a {
  display: flex; align-items: center; gap: 10px; margin-top: 12px;
  font-size: 13px; color: #d7dade;
}
.ft-social svg { width: 18px; height: 18px; fill: #fff; flex: none; }
.ft-social a:hover { color: var(--pink-lt); }
.ft-social a:hover svg { fill: var(--pink-lt); }

/* ---- 14. footer, lower ------------------------------------------------ */
.sec-14 { --h: 92px; background: var(--ink); border-top: 1px solid rgba(255,255,255,.12); }
.sec-14 .foot__legal  { left: 30px; top: 36px; width: 1140.1px; text-align: center; color: #8b919c; }

/* ===========================================================================
   MOBILE LAYER — per-section re-layout  (added 2026-08-03)
   ---------------------------------------------------------------------------
   Purely ADDITIVE: one @media block, nothing above this line touched, so
   desktop is byte-for-byte identical (proven by per-segment pixel diff at
   1440 and 1200).

   Why the section overrides live HERE and not in style.css: this file loads
   LAST. The blanket in style.css (`.sec .cv > *`) is (0,2,0), but so are the
   canvas rules above (`.sec-pev .pev-t { width: 1200px }`), and at equal
   specificity the later file wins — so those have to be re-stated in this
   block or the deck stays 1200px wide inside a 390px screen.
   =========================================================================== */
@media (max-width: 900px) {

  /* Build marker. ?debug=1 prints this; if it comes back empty the phone is
     running a CACHED stylesheet, not this one. Bump it when debugging cache. */
  :root { --build: "20260804b"; }

  /* ---- 1. header: logo left, hamburger right, nav as a dropdown -------- */
  .sec-1 { height: var(--hdr-h); z-index: 60; }
  .hdr__in { width: auto; padding: 0 18px; }
  /* 68px, up from 40. The wordmark is 336x178, so height drives it and the
     width follows (~128px), which still leaves the hamburger its 44px tap
     target with room to spare on a 390px screen. */
  .hdr__logo img { height: 68px; }

  .hdr__nav {
    display: none;                 /* .hdr.is-open flips this to flex */
    position: absolute; left: 0; right: 0; top: 100%; z-index: 60;
    flex-direction: column; align-items: stretch; gap: 0;
    margin-left: 0; padding: 6px 18px 20px;
    background: var(--ink);
    border-top: 1px solid rgba(255,255,255,.14);
    box-shadow: 0 22px 40px rgba(0,0,0,.45);
  }
  .hdr.is-open .hdr__nav { display: flex; }
  .hdr__nav a { padding: 14px 2px; border-bottom: 1px solid rgba(255,255,255,.1); }
  .hdr__cta {
    width: 100%; height: 54px; margin: 16px 0 0;
    font-size: 14px; border-bottom: 0;
  }

  /* ---- 2. hero --------------------------------------------------------- */
  /* Fills the screen: the header is 68px and sits above in flow, so the hero
     takes the rest of the window and the two together are exactly one fold.
     min-height rather than height, so a short phone that genuinely cannot fit
     the headline + shelf scrolls instead of clipping them.
     dvh first, vh as the fallback for browsers without it: on iOS Safari
     100vh is TALLER than the visible area (it assumes the address bar is
     hidden), which would push the shelf off the bottom of the fold. */
  .sec-2 {
    height: auto;
    /* three tiers, each overriding the last where supported. --app-vh is the
       only one iOS Safari gets right (script.js measures innerHeight); the
       other two are fallbacks for JS-off / older engines. */
    min-height: calc(100vh - var(--hdr-h));
    min-height: calc(100dvh - var(--hdr-h));
    min-height: calc(var(--app-vh, 100dvh) - var(--hdr-h));
    display: flex; flex-direction: column;
    padding: 26px 0 0;
  }
  /* .hx-in absorbs the slack so the copy stays optically centred in whatever
     height is left, and the shelf stays pinned to the foot of the fold. */
  .hx-in { width: auto; padding: 0 20px 20px; flex: 1 1 auto; justify-content: center; }
  /* Everything below is trimmed to a budget, not to taste. iOS Safari's
     VISIBLE height on a 390x844 phone is ~660px with the toolbars showing,
     so the hero has ~592px to work with. At the original spacing the stack
     measured 603px and pushed the button just under the fold. */
  .hx-ttl { font-size: clamp(34px, 11.5vw, 56px); line-height: .94; }
  .hx-chip { margin-bottom: 14px; font-size: 10px; padding: 7px 13px; gap: 8px; }
  .hx-glow { width: min(300px, 74%); margin-top: 14px; }
  .hx-txt { margin-top: 14px; font-size: 14.5px; line-height: 24px; }
  /* the blobs are 900px wide with a 96px blur — far too much surface for a
     phone GPU; shrink them and the blur with them */
  .hx-b1 { width: 420px; height: 380px; filter: blur(64px); }
  .hx-b2 { width: 360px; height: 320px; filter: blur(64px); }
  .hx-b3 { width: 320px; height: 280px; filter: blur(64px); }
  /* Pinned photo texture (requested 2026-08-04).
     NOT background-attachment: fixed — iOS Safari ignores that outright and
     renders it as scroll. Instead the LAYER ITSELF is position: fixed, which
     WebKit does honour, with its own background merely scrolling inside it.

     Why this is safe even though .sec-2 is overflow:hidden (which does not
     clip fixed descendants): the header above carries z-index 60 so it paints
     over the layer, and every section below the hero has an opaque background
     and comes LATER in the document, so they paint over it as they scroll up.
     The texture therefore reads as pinned behind the hero and is covered the
     moment the next section arrives. Keep .sec-2 free of transform / filter /
     will-change, any of which would make it the containing block and turn
     this back into a scrolling layer. */
  .hx-tex {
    position: fixed; top: 0; left: 0; width: 100%;
    height: var(--app-vh, 100dvh);
    background-attachment: scroll;
  }
  /* the shelf stops being a pinned bar and becomes the foot of the fold */
  .hx-shelf {
    position: static; flex: none; height: auto;
    flex-wrap: wrap; gap: 14px 22px; padding: 14px 18px 16px;
  }
  .hx-sep { display: none; }
  .hx-stat { min-width: 84px; }
  .hx-stat b { font-size: 22px; }
  .hx-stat em { margin-top: 3px; }
  .hx-btn { width: 100%; max-width: 320px; height: 50px; }

  /* ---- 3. about -------------------------------------------------------- */
  .sec-3 { padding: 54px 0 52px; }
  .abt-cv { width: auto; padding: 0 20px; }
  .abt-ghost { font-size: 78px; top: 84px; letter-spacing: 1px; }
  .abt-frame { inset: 10px; }
  .abt-frame i { width: 26px; height: 26px; }
  .abt-head { width: auto; margin-top: 14px; font-size: 38px; line-height: 41px; }
  /* Justified only on the wide measure. At ~330px the lines carry six or
     seven words, and justifying them tore white rivers through the middle of
     the paragraph, which is the opposite of the "looks aligned" the note
     asked for. */
  .abt-lead { width: auto; margin-top: 20px; font-size: 17px; line-height: 28px;
              text-align: left; }
  .abt-lead--cont { margin-top: 16px; }
  .abt-cols { margin-top: 32px; padding-top: 26px; grid-template-columns: 1fr; row-gap: 16px; }
  .abt-foot { margin-top: 32px; flex-direction: column; align-items: stretch; gap: 20px; }
  .abt-btn { width: 100%; height: 56px; padding: 0; }
  .abt-social { justify-content: center; }

  /* ---- 4/5/6. the triptych: three stacked bands ------------------------ */
  .sec-stmt { height: auto; min-height: 0; flex-direction: column; }
  .stmt {
    flex: none; height: 320px;
    border-right: 0; border-bottom: 1px solid rgba(255,255,255,.16);
  }
  /* no hover on a phone, so the photo shows in colour and the proof copy is
     simply always open */
  .stmt__img { filter: grayscale(0) contrast(1) brightness(.5); transform: none; }
  /* Column 1 is a standing PORTRAIT of Andres in a 440x320 landscape panel, so
     `cover` shows only the middle ~48% of the frame and the default 50% 50%
     started the crop at his hairline. 20% lifts the window to 10%..59% of the
     image: head fully clear, torso still in shot, and the caption overlay
     lands on his suit rather than his face. Desktop is untouched — there the
     column is 480x900, so the full image height is already visible and only
     the sides crop. */
  .stmt-1 .stmt__img { background-position: 50% 20%; }
  /* Same problem, the other direction, for the two photos the client swapped
     in on 2026-08-17. Both are tall frames dropped into a 390x320 landscape
     band, so `cover` keeps only the middle ~55% of the image height and the
     default 50% 50% window lands ABOVE the subject in each.
     02: at 50% the frame was mostly ceiling and wall; 62% brings his face
     clear of the headline and puts the decks back in shot.
     03: at 50% the window sat on bare panelling with the DJ table sliced off
     behind the copy, which is the one thing this block exists to show; 70%
     lifts the whole white table, laptop and sub into the open area above the
     headline. Desktop is untouched: there the column is 480x900 and the full
     height is already visible. */
  .stmt-2 .stmt__img { background-position: 50% 62%; }
  .stmt-3 .stmt__img { background-position: 50% 70%; }
  .stmt__more { max-height: none; opacity: 1; overflow: visible; }
  .stmt__in { padding: 0 22px 26px; }
  .stmt__ttl { font-size: 33px; }
  .stmt__more p { margin-top: 12px; font-size: 14px; line-height: 24px; }
  .stmt__rule { left: 22px; width: calc(100% - 44px); }
  /* the wipe animates clip-path across a filtered full-bleed photo — three
     of them at once is more than a phone should be asked to composite */
  .sec-stmt.is-in .stmt { animation: none; }

  /* ---- 8. packages ----------------------------------------------------- */
  .sec-pkg { padding: 54px 0 58px; }
  .pkg-cv { width: auto; padding: 0 20px; }
  /* The section mark was a tiny eyebrow over a single stranded word
     ("WEDDING") hard against the left edge with the rest of the line empty,
     which read like a mistake. Centred, tracked out, and closed with a short
     rule it reads as a deliberate divider instead. */
  .pkg-eyebrow { text-align: center; letter-spacing: .38em; font-size: 10.5px; }
  .pkg-head {
    margin-top: 10px; text-align: center;
    font-size: 34px; line-height: 36px; letter-spacing: 1.2px;
  }
  .pkg-rule {
    display: block; width: 46px; height: 3px;
    margin: 16px auto 0; background: var(--pink);
  }
  /* Swipeable instead of stacked (requested 2026-08-04). CSS scroll-snap, no
     JS: the row scrolls horizontally and each card snaps into place, which is
     native touch behaviour and keeps momentum/rubber-banding correct.
     The negative margins cancel .pkg-cv's 20px padding so the row can run to
     both screen edges, and the matching scroll-padding keeps the FIRST card
     inset by 20px rather than flush against the bezel. */
  .pkg-grid {
    margin-top: 30px;
    display: flex;                    /* was a 2-col grid */
    align-items: stretch;             /* both cards the same height */
    /* 40px, not 14: with a full-width card the row is 20 + 400 + gap, so any
       gap under 20px leaves the next card poking into the 20px right margin.
       40px parks it fully off-screen, and it also makes card 2's centred snap
       position land exactly on the maximum scroll offset. */
    gap: 40px;
    margin-left: -20px; margin-right: -20px;
    padding: 4px 20px 6px;            /* 4/6px so the card edges are not clipped */
    overflow-x: auto;
    overscroll-behavior-x: contain;   /* swiping the row must not page-scroll */
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;            /* Firefox */
  }
  .pkg-grid::-webkit-scrollbar { display: none; }
  .pkg {
    /* One card, full width. The earlier version let the next card peek 50px
       as a swipe affordance; that job now belongs to the counter + arrows
       below, so each card gets the whole screen and reads as one clean panel.
       Full width also buys ~50px of measure, which takes lines out of the
       description and is part of why the card is shorter. */
    flex: 0 0 100%;
    scroll-snap-align: center;
    padding: 22px 20px 24px;
    /* must be auto, not the desktop rule's height:100%. A flex item only
       stretches to the row height when its cross size is auto, so with
       height:100% the two cards kept their own content heights and the
       carousel had one tall card and one short one. */
    height: auto;
  }
  .pkg__top { flex-direction: column; gap: 4px; padding-bottom: 16px; }
  .pkg__name { font-size: 21px; }
  .pkg__price { font-size: 28px; }
  /* The description was 605px of a 1193px card (22 lines at 16/27.52).
     15px/24px over the wider full-bleed measure takes it to about 13 lines.
     This is the single biggest reason the card is no longer so long. */
  .pkg__desc { margin-top: 16px; font-size: 15px; line-height: 24px; }
  .pkg__list { margin-top: 16px; padding-top: 14px; margin-bottom: 22px; }
  .pkg__list li { margin-top: 9px; font-size: 14.5px; line-height: 22px; padding-left: 20px; }
  .pkg__list li::before { top: 7px; width: 7px; height: 7px; }
  /* equal-height cards would otherwise leave the shorter card's button
     floating mid-card: push it to the foot and keep a gap above it */
  .pkg__cta { width: 100%; align-self: stretch; margin-top: auto; height: 46px; }

  /* the carousel nav: counter between two arrows, centred under the cards.
     Deliberately the same shape as the Enhancements nav so the two
     carousels on this page do not look like different components. */
  .pkg-nav {
    display: flex; align-items: center; justify-content: center; gap: 16px;
    margin-top: 22px;
  }
  .pkg-arrow {
    display: flex; align-items: center; justify-content: center;
    width: 46px; height: 46px; border: 1px solid #d8d5cf; color: var(--head);
    background: #fff;
  }
  .pkg-arrow svg { width: 19px; height: 19px; display: block; }
  .pkg-arrow--next svg { transform: rotate(180deg); }
  .pkg-arrow[disabled] { opacity: .34; }
  .pkg-count {
    min-width: 58px; text-align: center;
    font-size: 12px; font-weight: 700; letter-spacing: .18em;
    text-transform: uppercase; color: #9aa0ab;
  }
  .pkg-count b { font-weight: 700; color: var(--head); }

  /* ---- 9. photo strip -------------------------------------------------- */
  /* shorter band, but the TILE WIDTH stays 260px: the keyframe travels
     exactly 8 x 260 = 2080px, so changing the width makes the loop jump. */
  .sec-9 { --h: 220px; height: 220px; }
  .sec-9 .strip__track img { width: 260px; height: 220px; }

  /* ---- 10. add-ons ----------------------------------------------------- */
  .sec-add { padding: 54px 0 58px; }
  .add-cv { width: auto; padding: 0 20px; }
  .add-top { flex-direction: column; align-items: flex-start; gap: 18px; padding-bottom: 20px; }
  .add-head { font-size: 30px; line-height: 34px; }
  .add-nav { width: 100%; justify-content: flex-start; }
  .add-arrow { width: 46px; height: 46px; }
  .add-stage { margin-top: 28px; }
  /* align-content: the stage is as tall as the LONGEST add-on (inactive
     slides are visibility:hidden, so they still contribute height). Stacked
     into one column that spare height was being shared out BETWEEN the two
     rows, leaving a dead gap under the price on every short slide; park the
     rows at the top and let the slack fall to the bottom instead. */
  .ad { grid-template-columns: 1fr; gap: 22px; align-content: start; }
  /* (the old `transform: none` override here is gone: inactive slides no
     longer carry a translate at all, and .add-stage is overflow:hidden, so
     the 4px page overflow it was fixing cannot come back.) */
  .ad__name { font-size: 27px; }
  .ad__price { font-size: 28px; margin-top: 8px; }
  .add-tabs { margin-top: 28px; padding-top: 20px; gap: 6px; }
  .add-tab { padding: 9px 10px; font-size: 10px; letter-spacing: .06em; }

  /* ---- 10b. parties & events: the fan becomes a stack ------------------ */
  /* every one of these is (0,2,0) in the block above and this file loads
     after style.css, so the blanket alone cannot unpin them */
  .sec-pev { height: auto; padding: 54px 0 58px; }
  .sec-pev .pev-kick { width: auto; }
  .sec-pev .pev-t { width: auto; font-size: 34px; line-height: 1.06; }
  .sec-pev .pev-deck {
    width: auto; height: auto; margin-top: 28px;
    display: flex; flex-direction: column; align-items: center; gap: 16px;
  }
  /* Prints: no fan, no rotation, captions always legible.
     position stays RELATIVE, not static: .pev-cap is absolute with
     `bottom: 10px`, so a static print hands it up to .sec-pev and all three
     captions pile up at the foot of the section on top of the CTA.
     And because it stays relative, the base rule's `left: 50%` becomes a
     relative OFFSET (it is merely ignored while static), which would shove
     every print half the deck's width off the right edge, so zero it. */
  .pev-pr {
    position: relative; left: auto; top: auto;
    margin-left: 0; transform: none;
    width: min(260px, 84%); height: auto; aspect-ratio: 250 / 300;
  }
  .pev-cap { opacity: 1; }
  .sec-pev .pev-cta { width: 100%; max-width: 320px; margin: 28px auto 0; }

  /* ---- 10c. call to action band ---------------------------------------- */
  .sec-cba { height: auto; padding: 60px 0 64px; }
  .cba-cv { width: auto; height: auto; padding: 0 20px; }
  .cba-head { margin-top: 16px; font-size: 38px; line-height: 41px; }
  .cba-sub { margin-top: 16px; font-size: 15px; line-height: 26px; }
  .cba-acts { flex-direction: column; gap: 18px; margin-top: 28px; width: 100%; }
  .cba-btn { width: 100%; max-width: 320px; }

  /* ---- 11. service area ------------------------------------------------ */
  .sec-area { height: auto; padding: 54px 0 58px; }
  .area-cv { width: auto; height: auto; padding: 0 20px; }
  .area-head { margin-top: 14px; font-size: 52px; line-height: .96; }
  .area-cities { margin-top: 16px; font-size: 12.5px; letter-spacing: .1em; }
  .area-travel { margin-top: 26px; padding-top: 18px; }
  .area-travel b { font-size: 28px; }

  /* ---- 12b. FAQ -------------------------------------------------------- */
  .sec-faq { padding: 54px 0 58px; }
  .faq-cv { width: auto; padding: 0 20px; }
  .faq-head { font-size: 30px; line-height: 34px; }
  .faq-list { margin-top: 28px; }
  .faq-q { gap: 12px; padding: 18px 2px; }
  .faq-n { width: 22px; font-size: 11px; }
  .faq-qt { font-size: 17px; line-height: 1.3; }
  .faq-mark { width: 18px; height: 18px; }
  .faq-a { padding: 0 6px 22px 34px; }
  .faq-a p { font-size: 15px; line-height: 25px; }

  /* ---- 13/14. footer --------------------------------------------------- */
  .sec-13 { padding: 46px 0 40px; }
  .ft-cv { width: auto; padding: 0 20px; grid-template-columns: 1fr; gap: 26px; }
  .ft-logo img { height: 62px; }
  .sec-14 { height: auto; padding: 20px 0 22px; }
  .sec-14 .foot__legal { width: auto; padding: 0 20px; }
}

/* ---------------------------------------------------------------------------
   Short-viewport trim. The 92px header + 68px wordmark (2026-08-04) is right
   for a modern phone, but on a 553px visible height (iPhone SE) it pushed the
   hero's button 11px under the fold. Step both down there so the fold still
   closes. Still gated on max-width:900px, so desktop can never match it.
   --------------------------------------------------------------------------- */
@media (max-width: 900px) and (max-height: 620px) {
  :root { --hdr-h: 74px; }
  .hdr__logo img { height: 54px; }
}

/* The enhancements band disappears if the client ever clears every add-on.
   The <template> lives in its own DocumentFragment so :has() cannot see it,
   which is what makes this test "are there real cards" rather than "is there
   markup". Kit contract: templates/README.md "The add-ons slot always ships". */
#addons:not(:has([data-bc-pkg])) { display: none; }
