/* v2 refinements — assembled by v2/assemble.py from v2/out/*.css; everything scoped to body.ssn-v2 */

/* ===================== base.css ===================== */
/* ==========================================================================
   SSN v2 — base layer: tokens, body-copy typography, section rhythm, ivory
   bands, utilities, no-JS fallback
   --------------------------------------------------------------------------
   Concatenated FIRST into assets/css/v2.css. Every rule is scoped under
   .ssn-v2 (body class on index2.html) so index.html is untouched. Section
   files may rely on the tokens below; they must NOT re-set paragraph
   font-size/weight (owned here).

   For section specialists:
   - Keep the v1 wrapper class on your <section> (.ssn-intro, .ssn-acc, …).
     If you drop it, the id-keyed fallback below still gives the section its
     rhythm, but at (0,1,0) — any .ssn-v2 .x rule of yours overrides it.
   - If you rename or replace a standard paragraph's class, put .v2-body on it
     (18px / 400 / 1.6); on a card / quote paragraph put .v2-card (17px / 400 /
     1.6). Those two utilities carry exactly the declarations of the typography
     blocks below.
   - .v2-ivory paints a region ivory and warms its hairlines. Put it on the
     full-width <section> (the element carrying px-spacex), never on
     .inner-area / .base-container, which is centred with max-width 100rem and
     would leave white gutters of --space-x on each side.
   ========================================================================== */

/* ---- Tokens --------------------------------------------------------------- */
.ssn-v2 {
  --ssn-ivory: #f7f5f0;            /* warm ivory band (Amenities, FAQ) */
  --ssn-hair: #e6e6e6;             /* hairline on white (re-pointed to the ivory tone inside bands) */
  --ssn-hair-ivory: #e3dfd6;       /* hairline on ivory */
  --v2-rhythm: clamp(4.5rem, 7vw, 7rem);   /* one section's breathing room */
  --v2-body-size: 1.125rem;        /* 18px standard paragraph — all breakpoints, per the brief */
  --v2-body-lh: 1.6;
  --v2-card-size: 1.0625rem;       /* 17px card / quote copy — all breakpoints */
  --v2-card-lh: 1.6;
}

/* ---- Body copy: 18px / 400 / 1.6 ----------------------------------------
   Beats the theme's .font-light (300) and v1's per-section sizes by
   specificity (.ssn-v2 + class). Eyebrows, labels, captions, buttons,
   headings and the accommodations carousel cards are deliberately untouched.
   .v2-body is the opt-in utility for any paragraph not listed here. */
.ssn-v2 .v2-body,
.ssn-v2 .ssn-intro__text,
.ssn-v2 .ssn-acc__text,            /* accommodations intro sentence only (not the cards) */
.ssn-v2 .ssn-extras__text,
.ssn-v2 .ssn-loc__text,
.ssn-v2 .ssn-faqs__text,
.ssn-v2 .ssn-cta__text,
.ssn-v2 .ssn-q__inner p,
.ssn-v2 .ssn-q__inner li {
  font-family: var(--primary-font);
  font-size: var(--v2-body-size);
  font-weight: 300;
  line-height: var(--v2-body-lh);
}

/* Card descriptions and review quotes: a step down (17px), same weight/rhythm.
   .v2-card is the opt-in utility for any card / quote paragraph not listed. */
.ssn-v2 .v2-card,
.ssn-v2 .ssn-exp__text,
.ssn-v2 .ssn-rev__text {
  font-family: var(--primary-font);
  font-size: var(--v2-card-size);
  font-weight: 300;
  line-height: var(--v2-card-lh);
}
/* Review pull-quote keeps its v1 size (so it still leads the 17px body) but is
   kept at the light weight 300 with a slightly roomier leading. */
.ssn-v2 .ssn-rev__lead { font-weight: 300; line-height: 1.32; }

/* ---- Section rhythm -------------------------------------------------------
   Rule: every section opens with one unit of breathing room (padding-top).
   White-on-white neighbours share that single unit (no padding-bottom), so
   the gap between any two white sections is exactly --v2-rhythm.
   Ivory bands (#amenities, #faq) get the unit top AND bottom so the tint
   reads as a band; the white section immediately BEFORE a band also closes
   with the unit so the band starts at the same distance it ends. The photo
   CTA (#book) keeps its own, larger internal padding — it is a panel, not a
   gap, and sits directly under the FAQ band.
   padding-top/bottom only (never the shorthand: .px-spacex owns the sides). */

/* id-keyed fallback at (0,1,0): :where adds no specificity, so this beats
   prototype.css's (0,1,0) section rules by source order only (v2.css loads
   after) and loses to any .ssn-v2 .x rule in a section file. It guards the
   rhythm if a specialist drops the v1 wrapper class. */
.ssn-v2 :where(#intro, #accommodations, #amenities, #experiences, #reviews, #location, #gallery, #faq) {
  padding-top: var(--v2-rhythm);
  padding-bottom: 0;
}
.ssn-v2 :where(#accommodations, #amenities, #gallery, #faq) { padding-bottom: var(--v2-rhythm); }

/* class-keyed rhythm at (0,2,0): the primary rules */
.ssn-v2 .ssn-intro,                /* #intro          white  (v1: 7.5rem top / 3.125rem bottom) */
.ssn-v2 .ssn-acc,                  /* #accommodations white  — section wrapper only */
.ssn-v2 .ssn-amen,                 /* #amenities      ivory */
.ssn-v2 .ssn-exp,                  /* #experiences    white */
.ssn-v2 .ssn-rev,                  /* #reviews        white */
.ssn-v2 .ssn-loc,                  /* #location       white */
.ssn-v2 .ssn-gal,                  /* #gallery        white */
.ssn-v2 .ssn-faqs {                /* #faq            ivory (v1: 8.5rem bottom) */
  padding-top: var(--v2-rhythm);
  padding-bottom: 0;
}
/* ivory bands: equal top and bottom */
.ssn-v2 .ssn-amen,
.ssn-v2 .ssn-faqs { padding-bottom: var(--v2-rhythm); }
/* white sections that precede an ivory band close with the unit */
.ssn-v2 .ssn-acc,
.ssn-v2 .ssn-gal { padding-bottom: var(--v2-rhythm); }

/* ---- Ivory bands ----------------------------------------------------------
   Owned here so the band and the rhythm around it stay coherent by default
   (prototype.css paints .ssn-amen and .ssn-faqs white at (0,1,0); these win
   at (0,2,0), the :wher fallback by source order). --ssn-hair is
   re-pointed inside the band so anything drawn with var(--ssn-hair) takes the
   warmer tone automatically. Section files may still override. */
.ssn-v2 .v2-ivory,
.ssn-v2 .ssn-amen,
.ssn-v2 .ssn-faqs,
.ssn-v2 :where(#amenities, #faq) {
  background: var(--ssn-ivory);
  --ssn-hair: var(--ssn-hair-ivory);
}
/* v1 hairlines inside the bands are hard-coded #e6e6e6 in prototype.css;
   re-tint them through the inherited token (ivory tone inside a band, the
   plain #e6e6e6 anywhere else). Section files at (0,2,0) load later and win. */
.ssn-v2 .ssn-amen__item,
.ssn-v2 .ssn-extras,
.ssn-v2 .ssn-acc-list,
.ssn-v2 .ssn-q { border-color: var(--ssn-hair); }

/* ---- Shared utilities ------------------------------------------------------
   .v2-hair  — 1px hairline rule; #e6e6e6 on white, #e3dfd6 inside an ivory
               band (it reads the inherited --ssn-hair token).
   .v2-ivory — see the band block above and the header note on placement. */
.ssn-v2 .v2-hair { height: 1px; background: var(--ssn-hair); border: 0; margin: 0; }

/* ---- No-JS fallback -------------------------------------------------------
   prototype.css hides every [data-reveal] (opacity 0, translateY) with no
   html.js gate, and the `js` class is only added by an inline script, so
   without JavaScript the whole page below the hero stays invisible. These
   rules are (0,3,1): they beat [data-reveal] (0,1,0), .ssn-cta__bg[data-reveal]
   (0,2,0) and any section rule of the form .ssn-v2 .x[data-reveal] (0,3,0).
   With JS enabled html.js is present and nothing here applies. */
html:not(.js) .ssn-v2 [data-reveal] { opacity: 1; transform: none; transition: none; }
html:not(.js) .ssn-v2 .ssn-word > span { transform: none; transition: none; }   /* belt and braces: .ssn-word is JS-made */

/* FAQ panels are collapsed by CSS alone (grid-template-rows: 0fr) and only
   #faq-1 ships open in the markup; without prototype.js the toggles are inert,
   so expand every answer. (0,3,0) beats .ssn-q__panel (0,1,0). */
/* html:not(.js) .ssn-v2 .ssn-q__panel { grid-template-rows: 1fr; } */

/* ===================== amenities.css ===================== */
/* ==========================================================================
   v2 — Section 4: Amenities (What Makes Your Stay Special)
   Warm ivory band · ringed navy icons · ivory hairlines (#e3dfd6) · delicate
   column dividers · staggered reveals · "A Little Extra Magic" signature band.
   All rules scoped under .ssn-v2; new classes prefixed .v2-.
   ========================================================================== */

/* --- Section: ivory band with equal top/bottom padding ---------------------
   Side padding comes from the theme's .px-spacex on the section (never the
   `padding` shorthand here). Tokens (--ssn-ivory, --v2-rhythm, --ssn-hair-ivory)
   come from base.css; the literal fallbacks only guard against load order.
   Top/bottom defer to the shared --v2-rhythm so the band matches #faq. */
.ssn-v2 .ssn-amen.v2-ivory {
  background: var(--ssn-ivory, #f7f5f0);
  padding-top: var(--v2-rhythm, clamp(4.5rem, 7vw, 7rem));
  padding-bottom: var(--v2-rhythm, clamp(4.5rem, 7vw, 7rem));
}
.ssn-v2 .v2-amen__head { margin-bottom: 2.75rem; }

/* --- Grid: 3 × 2, airy but compact (≈190px tall at 1440) ------------------ */
.ssn-v2 .v2-amen__grid {
  --v2-amen-gap: clamp(2rem, 4vw, 4rem);
  position: relative;
  column-gap: var(--v2-amen-gap);
  row-gap: 2.5rem;
}
/* Two full-height vertical hairlines, centred in the column gaps. Absolutely
   positioned pseudo-elements sit outside the grid flow, so they take no cell. */
.ssn-v2 .v2-amen__grid::before,
.ssn-v2 .v2-amen__grid::after {
  content: ""; position: absolute; top: 0; bottom: 0; width: 1px;
  background: var(--ssn-hair-ivory, #e3dfd6); pointer-events: none;
}
.ssn-v2 .v2-amen__grid::before { left: calc((100% - 2 * var(--v2-amen-gap)) / 3 + var(--v2-amen-gap) / 2); }
.ssn-v2 .v2-amen__grid::after  { left: calc((100% - 2 * var(--v2-amen-gap)) * 2 / 3 + var(--v2-amen-gap) * 1.5); }

.ssn-v2 .v2-amen__item {
  gap: 1.125rem;
  padding-top: 1.625rem;
  border-top: 1px solid var(--ssn-hair-ivory, #e3dfd6);
}

/* Icon in a 3rem thin ring: 1px navy at 35%, navy stroke, optically centred */
.ssn-v2 .v2-amen__icon {
  display: inline-flex; align-items: center; justify-content: center;
  box-sizing: border-box;
  width: 3rem; height: 3rem; border-radius: 50%;
  border: 1px solid rgba(34, 38, 64, .35);
  color: #222640; background: transparent;
}
.ssn-v2 .v2-amen__icon svg { width: 1.375rem; height: 1.375rem; display: block; }

/* Labels step up slightly; weight 400 comes from .font-normal in the markup */
.ssn-v2 .v2-amen__label { font-size: 1.1875rem; line-height: 1.3; letter-spacing: 0; margin: 0; text-wrap: balance; }

/* --- Complimentary extras: hairline-framed signature band ------------------ */
.ssn-v2 .v2-extras {
  margin-top: 3.5rem;
  padding: 2rem 0;                       /* no px-spacex on this element */
  border-top: 1px solid var(--ssn-hair-ivory, #e3dfd6);
  border-bottom: 1px solid var(--ssn-hair-ivory, #e3dfd6);
  gap: 2rem 3rem;
}
.ssn-v2 .v2-extras__lead { gap: 1.125rem; }
/* Sparkle sits in a 3rem box so the title block aligns with the grid labels */
.ssn-v2 .v2-extras__icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 3rem; height: 3rem; color: #e0ab2e;
  transform-origin: 50% 50%;
}
.ssn-v2 .v2-extras__icon svg { width: 2rem; height: 2rem; display: block; }
/* Eyebrow: unchanged v1 size/tracking, re-asserted at .ssn-v2 specificity so a
   generic v2 paragraph rule cannot inflate it; #4f4f4f for ≥4.5:1 on ivory */
.ssn-v2 .v2-extras__eyebrow {
  margin: 0 0 .5rem; color: #4f4f4f;
  font-family: var(--primary-font); font-weight: 700; font-size: .6875rem; line-height: 1;
  letter-spacing: .2em; text-transform: uppercase;
}
.ssn-v2 .v2-extras__title { font-size: 1.75rem; line-height: 1.15; letter-spacing: -.005em; margin: 0; }
.ssn-v2 .v2-extras__text { max-width: 36rem; margin: 0; }   /* size/weight/leading owned by base.css */

/* Sparkle bloom: unfolds one beat after the band fades in. Gated on html.js
   (visible without JS) and forced to its final state by .is-settled. */
.js .ssn-v2 .v2-extras .v2-extras__icon {
  opacity: 0; transform: scale(.55) rotate(-25deg);
  transition: opacity 1.2s cubic-bezier(.22,.61,.36,1), transform 1.4s cubic-bezier(.22,.61,.36,1);
  transition-delay: calc(var(--reveal-delay, 0s) + .25s);
}
.js .ssn-v2 .v2-extras.is-inview .v2-extras__icon { opacity: 1; transform: none; }
.ssn-v2 .v2-extras.is-settled .v2-extras__icon { transition: none; opacity: 1; transform: none; }

/* No-JS safety net for this section: reveals are visible without the observer */
html:not(.js) .ssn-v2 .ssn-amen [data-reveal] { opacity: 1; transform: none; }

/* --- Tablet (≤1024): still 3 columns, tighter gap ------------------------- */
@media (max-width: 1024px) {
  .ssn-v2 .v2-amen__grid { --v2-amen-gap: 2rem; row-gap: 2.25rem; }
  .ssn-v2 .v2-amen__item { gap: 1rem; padding-top: 1.5rem; }
  .ssn-v2 .v2-amen__label { font-size: 1.125rem; }
  .ssn-v2 .v2-extras { margin-top: 3rem; gap: 1.5rem 3rem; }
}

/* --- Phones (≤768): 2 × 3, icon above label, no column dividers ----------- */
@media (max-width: 768px) {
  .ssn-v2 .v2-amen__head { margin-bottom: 2.25rem; }
  .ssn-v2 .v2-amen__grid { --v2-amen-gap: 1.5rem; row-gap: 1.75rem; }
  .ssn-v2 .v2-amen__grid::before,
  .ssn-v2 .v2-amen__grid::after { display: none; }
  .ssn-v2 .v2-amen__item { gap: .875rem; padding-top: 1.25rem; }
  .ssn-v2 .v2-amen__icon { width: 2.75rem; height: 2.75rem; }
  .ssn-v2 .v2-amen__icon svg { width: 1.25rem; height: 1.25rem; }
  .ssn-v2 .v2-amen__label { font-size: 1.0625rem; }
  .ssn-v2 .v2-extras { margin-top: 2.5rem; padding: 1.75rem 0; gap: 1.125rem; }
  .ssn-v2 .v2-extras__lead { gap: 1rem; }
  .ssn-v2 .v2-extras__icon { width: 2.75rem; height: 2.75rem; }
  .ssn-v2 .v2-extras__icon svg { width: 1.75rem; height: 1.75rem; }
  .ssn-v2 .v2-extras__title { font-size: 1.5rem; }
}

/* --- Reduced motion: no transforms/animations; everything visible --------- */
@media (prefers-reduced-motion: reduce) {
  .ssn-v2 .v2-extras .v2-extras__icon,
  .js .ssn-v2 .v2-extras .v2-extras__icon { opacity: 1; transform: none; transition: none; }
}

/* ===================== experiences.css ===================== */
/* ==========================================================================
   v2 — Experiences (#experiences): editorial composition
   --------------------------------------------------------------------------
   A refinement layer over the v1 rules in prototype.css. The markup keeps
   every v1 hook (.ssn-exp__grid / __item / __card / __media / __body /
   __progress / __progress-bar), so the phone-size swipe row and its progress
   line (prototype.js) keep working; the only class additions are
   .v2-exp--01…04 on the four <li>s.

   ≥1200     one staggered band on a 24-column grid:
             01 portrait 4:5 (6 cols) · 02 landscape 3:2 (8 cols) ·
             03 5:6 (5 cols) · 04 5:7 (5 cols).
             The feet of 01, 02 and 04 share one baseline while 03 is lifted
             to the top line. The offsets are plain rem values (exact at
             1440); where container units exist (@supports margin-top: 1cqw)
             they are recomputed from the real track widths so the baseline
             is exact at any viewport. Images 275–380px tall at 1440; the
             section is ~850px tall.
   769–1199  two rows on 12 columns, 5+7 then 7+5: in each row the wide
             landscape card drops by exactly the height difference, so the
             two feet align and the drop alternates sides (a zigzag). Same
             rem-then-@supports pattern (rem exact at 834).
   ≤768      the v1 swipe row is untouched (same classes, same JS). The row
             reveals as a unit: prototype.js observes each <li>, but inside
             the clipped track only card 01 ever crosses the .15 threshold
             on load, so once 01 is in view its siblings are shown by CSS;
             the per-card stagger is zeroed, the fade shortened, and the
             travel kept inside the track's bottom padding so the hairline
             rule is never clipped mid-settle.
   Scoped under .ssn-v2; paragraph size/weight belongs to base.css.
   ========================================================================== */
.ssn-v2 .ssn-exp {
  --v2-exp-gap: clamp(1.25rem, 2vw, 1.75rem);   /* v1's gutter, reused for every width */
  --v2-exp-settle: 2.75rem;                      /* reveal travel (the "settle") */
}

/* ---- Card refinements, every width ---------------------------------------
   Slower zoom, numeral and arrow ease to the right together, the rule draws
   over a longer beat. v1's gradient foot and focus outline are kept. */
.ssn-v2 .ssn-exp__media img { transition: transform 1.4s cubic-bezier(.22,.61,.36,1); }
.ssn-v2 .ssn-exp__card:hover .ssn-exp__media img,
.ssn-v2 .ssn-exp__card:focus-visible .ssn-exp__media img { transform: scale(1.045); }
.ssn-v2 .ssn-exp__media::after { transition: opacity .8s ease; }
.ssn-v2 .ssn-exp__index { transition: transform .8s cubic-bezier(.22,.61,.36,1); }
.ssn-v2 .ssn-exp__card:hover .ssn-exp__index,
.ssn-v2 .ssn-exp__card:focus-visible .ssn-exp__index { transform: translateX(4px); }
.ssn-v2 .ssn-exp__name { text-wrap: balance; }          /* "Explore the / Local Area", never an orphan */
.ssn-v2 .ssn-exp__arrow { transition: transform .6s cubic-bezier(.22,.61,.36,1); }
.ssn-v2 .ssn-exp__card:hover .ssn-exp__arrow,
.ssn-v2 .ssn-exp__card:focus-visible .ssn-exp__arrow { transform: translateX(8px); }
.ssn-v2 .ssn-exp__rule::after { transition: transform .8s cubic-bezier(.22,.61,.36,1); }
.ssn-v2 .ssn-exp__text { max-width: 24rem; }

/* ---- Reveal: each card fades up over a longer, slightly deeper settle; the
   stagger is the inline --reveal-delay (0 / .12 / .24 / .36s). Gated on
   html.js like the hero; .is-settled is prototype.js's timed fallback. */
.js .ssn-v2 .ssn-exp__item[data-reveal] {
  transform: translateY(var(--v2-exp-settle));
  transition-duration: 1.3s;
}
.js .ssn-v2 .ssn-exp__item[data-reveal].is-inview,
.js .ssn-v2 .ssn-exp__item[data-reveal].is-settled { transform: none; }

/* ==========================================================================
   ≥1200 — one staggered band, 24 columns
   ========================================================================== */
@media (min-width: 1200px) {
  .ssn-v2 .ssn-exp__grid {
    grid-template-columns: repeat(24, minmax(0, 1fr));
    gap: var(--v2-exp-gap);
    align-items: start;
    --v2-exp-drop: 2.5rem;                      /* how far 01 sits under the top line */
  }
  .ssn-v2 .ssn-exp__item { margin: 0; }

  /* 01 — portrait 4:5, six columns, a step below the top line */
  .ssn-v2 .v2-exp--01 { grid-column: span 6; margin-top: var(--v2-exp-drop); }
  .ssn-v2 .v2-exp--01 .ssn-exp__media { aspect-ratio: 4 / 5; }

  /* 02 — landscape 3:2, eight columns; its foot on 01's baseline
     (9rem = drop + 01's height − 02's height at 1440; exact value below) */
  .ssn-v2 .v2-exp--02 { grid-column: span 8; margin-top: 9rem; }
  .ssn-v2 .v2-exp--02 .ssn-exp__media { aspect-ratio: 3 / 2; }

  /* 03 — 5:6, five columns, lifted to the top line */
  .ssn-v2 .v2-exp--03 { grid-column: span 5; margin-top: 0; }
  .ssn-v2 .v2-exp--03 .ssn-exp__media { aspect-ratio: 5 / 6; }

  /* 04 — tall 5:7, five columns; its foot on the same baseline (4.5rem at 1440) */
  .ssn-v2 .v2-exp--04 { grid-column: span 5; margin-top: 4.5rem; }
  .ssn-v2 .v2-exp--04 .ssn-exp__media { aspect-ratio: 5 / 7; }

  /* Exact baseline at any viewport: the real track widths (one column, then
     the 5 / 6 / 8-column spans) from container units, used by the cards'
     margin-top. Feature-gated so a browser without cqw keeps the rem values
     above — a calc that is invalid at computed-value time zeroes the
     property rather than falling back to an earlier declaration. */
  @supports (margin-top: 1cqw) {
    .ssn-v2 .ssn-exp__grid {
      container-type: inline-size;
      --v2-exp-col: calc((100cqw - 23 * var(--v2-exp-gap)) / 24);
      --v2-exp-w5: calc(5 * var(--v2-exp-col) + 4 * var(--v2-exp-gap));
      --v2-exp-w6: calc(6 * var(--v2-exp-col) + 5 * var(--v2-exp-gap));
      --v2-exp-w8: calc(8 * var(--v2-exp-col) + 7 * var(--v2-exp-gap));
    }
    .ssn-v2 .v2-exp--02 { margin-top: calc(var(--v2-exp-drop) + var(--v2-exp-w6) * 1.25 - var(--v2-exp-w8) * 2 / 3); }
    .ssn-v2 .v2-exp--04 { margin-top: calc(var(--v2-exp-drop) + var(--v2-exp-w6) * 1.25 - var(--v2-exp-w5) * 1.4); }
  }
}

/* ==========================================================================
   769–1199 — two rows, 12 columns, the drop alternates sides
   ========================================================================== */
@media (min-width: 769px) and (max-width: 1199px) {
  .ssn-v2 .ssn-exp__grid {
    grid-template-columns: repeat(12, minmax(0, 1fr));
    gap: clamp(2.5rem, 5vw, 3.5rem) var(--v2-exp-gap);
    align-items: start;
  }
  .ssn-v2 .ssn-exp__item { margin: 0; }

  /* row 1 — portrait left, landscape right (dropped to share the foot;
     3.5rem = 01's height − 02's height at 834; exact value below) */
  .ssn-v2 .v2-exp--01 { grid-column: span 5; }
  .ssn-v2 .v2-exp--01 .ssn-exp__media { aspect-ratio: 4 / 5; }
  .ssn-v2 .v2-exp--02 { grid-column: span 7; margin-top: 3.5rem; }
  .ssn-v2 .v2-exp--02 .ssn-exp__media { aspect-ratio: 4 / 3; }

  /* row 2 — landscape left (dropped), portrait right */
  .ssn-v2 .v2-exp--03 { grid-column: span 7; margin-top: 3.5rem; }
  .ssn-v2 .v2-exp--03 .ssn-exp__media { aspect-ratio: 4 / 3; }
  .ssn-v2 .v2-exp--04 { grid-column: span 5; }
  .ssn-v2 .v2-exp--04 .ssn-exp__media { aspect-ratio: 4 / 5; }

  /* exact drop at any viewport (see the ≥1200 note on the gate) */
  @supports (margin-top: 1cqw) {
    .ssn-v2 .ssn-exp__grid {
      container-type: inline-size;
      --v2-exp-col: calc((100cqw - 11 * var(--v2-exp-gap)) / 12);
      --v2-exp-w5: calc(5 * var(--v2-exp-col) + 4 * var(--v2-exp-gap));
      --v2-exp-w7: calc(7 * var(--v2-exp-col) + 6 * var(--v2-exp-gap));
    }
    .ssn-v2 .v2-exp--02,
    .ssn-v2 .v2-exp--03 { margin-top: calc(var(--v2-exp-w5) * 1.25 - var(--v2-exp-w7) * .75); }
  }
}

/* ==========================================================================
   ≤768 — v1 swipe row; the row reveals as one unit inside the clipped track
   ========================================================================== */
@media (max-width: 768px) {
  /* travel ≤ the track's .5rem bottom padding (overflow-y: hidden), so the
     hairline rule is never clipped while a card settles */
  .ssn-v2 .ssn-exp { --v2-exp-settle: .5rem; }

  /* no per-card stagger against a user swipe: one short fade for every card.
     (0,4,0) beats [data-reveal]'s transition-delay: var(--reveal-delay)
     (0,1,0) and the 1.3s duration above (same specificity, earlier). */
  .js .ssn-v2 .ssn-exp__item[data-reveal] { transition-delay: 0s; transition-duration: .9s; }

  /* Cards 02–04 sit clipped by the track's overflow-x; 02 peeks ~14% at 375
     (below prototype.js's .15 threshold), so on load only 01 gets .is-inview
     and the peeking edge would stay blank. Once 01 is in view, show its
     siblings too. (0,6,0) beats the hidden state: opacity from [data-reveal]
     (0,1,0), transform from the .js rule above (0,4,0). prototype.js still
     adds .is-inview / .is-settled to each card as it is swiped in — by then
     it is already visible, so nothing re-animates. */
  .js .ssn-v2 .ssn-exp__item.is-inview ~ .ssn-exp__item[data-reveal] { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  .js .ssn-v2 .ssn-exp__item[data-reveal] { transform: none; transition: none; }
  .ssn-v2 .ssn-exp__media img, .ssn-v2 .ssn-exp__media::after, .ssn-v2 .ssn-exp__index,
  .ssn-v2 .ssn-exp__arrow, .ssn-v2 .ssn-exp__rule::after { transition: none; }
  /* no hover / focus transforms at all: (0,4,1) / (0,4,0) beat the v1 hover
     rules in prototype.css (0,3,1) / (0,3,0) and the v2 ones above (same
     specificity, earlier in source). The rule's scaleX(1) stays — it
     appears rather than moves, a state indicator. */
  .ssn-v2 .ssn-exp__card:hover .ssn-exp__media img,
  .ssn-v2 .ssn-exp__card:focus-visible .ssn-exp__media img,
  .ssn-v2 .ssn-exp__card:hover .ssn-exp__index,
  .ssn-v2 .ssn-exp__card:focus-visible .ssn-exp__index,
  .ssn-v2 .ssn-exp__card:hover .ssn-exp__arrow,
  .ssn-v2 .ssn-exp__card:focus-visible .ssn-exp__arrow { transform: none; }
}

/* ===================== location.css ===================== */
/* ==========================================================================
   v2 — Section 7: Location (illustrated Texas map + driving-time legend)
   --------------------------------------------------------------------------
   Desktop ≥1025: copy | map | driving-time list (the list doubles as the map
   controls; address + directions is its final hairline row).
   769–1024: copy full width, then map | list.   ≤768: copy → map → list → address.
   Hover / focus / tap a city (list row or map dot) → an illustrative bézier
   draws from that city to Star Studded Nights; leaving fades it.
   SVG text and strokes are in viewBox units (600 wide), so label sizes are
   re-set per breakpoint to land at ~11–13 rendered px for that band's map width.
   ========================================================================== */
.ssn-v2 .ssn-loc {
  --v2-navy: #222640;
  --v2-gold: #e0ab2e;
  --v2-hair: #e6e6e6;
  --v2-ease: cubic-bezier(.22,.61,.36,1);
  --v2-map-w: clamp(19rem, 31.5vw, 28.5rem);
  --v2-list-w: clamp(15rem, 19vw, 17.25rem);
}

/* ---- grid ---------------------------------------------------------------- */
.ssn-v2 .v2-loc__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, var(--v2-map-w)) minmax(0, var(--v2-list-w));
  grid-template-areas: "copy map list";
  column-gap: clamp(2.25rem, 4.2vw, 4.5rem);
  align-items: start;
}
.ssn-v2 .v2-loc__copy { grid-area: copy; }
.ssn-v2 .v2-map       { grid-area: map; }
.ssn-v2 .v2-loc__list { grid-area: list; }

/* copy: keep the H2 / paragraph sizes from base.css; only constrain measure */
.ssn-v2 .ssn-loc__title { max-width: 14ch; margin-bottom: 1.5rem; }
.ssn-v2 .ssn-loc__text  { max-width: 26rem; }

/* ---- map ------------------------------------------------------------------ */
.ssn-v2 .v2-map { position: relative; }
.ssn-v2 .v2-map__svg {
  display: block; width: 100%; height: auto; overflow: visible;
  font-family: var(--primary-font);
}
.ssn-v2 .v2-map__outline {
  fill: var(--v2-navy); fill-opacity: .025;
  stroke: var(--v2-navy); stroke-width: 1.25; stroke-linejoin: round; stroke-linecap: round;
  vector-effect: non-scaling-stroke;
}

/* connectors: a faint dashed guide appears first, the solid line draws over it.
   Widths are in user units on purpose: with pathLength="1" the dash must scale
   with the path, and non-scaling-stroke would lay the dash in screen space. */
.ssn-v2 .v2-map__route { pointer-events: none; }
.ssn-v2 .v2-map__ghost,
.ssn-v2 .v2-map__line { fill: none; stroke: var(--v2-navy); stroke-linecap: round; }
.ssn-v2 .v2-map__ghost {
  stroke-width: 1.3; stroke-dasharray: 2.5 4.5; opacity: 0;
  transition: opacity .45s ease;
}
.ssn-v2 .v2-map__line {
  stroke-width: 1.65; stroke-dasharray: 1; stroke-dashoffset: 1; opacity: 0;
  transition: opacity .45s ease, stroke-dashoffset 0s linear .45s;   /* reset only after the fade-out */
}
.ssn-v2 .v2-map__route.is-active .v2-map__ghost { opacity: .5; transition-duration: .3s; }
.ssn-v2 .v2-map__route.is-active .v2-map__line {
  stroke-dashoffset: 0; opacity: 1;
  transition: opacity .2s ease, stroke-dashoffset .9s var(--v2-ease);
}

/* city markers */
.ssn-v2 .v2-map__city { cursor: pointer; }
.ssn-v2 .v2-map__hit { fill: transparent; stroke: none; }
.ssn-v2 .v2-map__dot {
  fill: var(--v2-navy);
  transform-box: fill-box; transform-origin: center;
  transition: transform .5s var(--v2-ease), opacity .5s ease;
}
.ssn-v2 .v2-map__halo {
  fill: var(--v2-navy); fill-opacity: .12; opacity: 0;
  transform-box: fill-box; transform-origin: center; transform: scale(.4);
  transition: opacity .45s ease, transform .6s var(--v2-ease);
}
.ssn-v2 .v2-map__city.is-active .v2-map__dot  { transform: scale(1.4); }
.ssn-v2 .v2-map__city.is-active .v2-map__halo { opacity: 1; transform: scale(1); }
.ssn-v2 .v2-map__label {
  font-size: 16px; font-weight: 400; letter-spacing: .09em; text-transform: uppercase;
  fill: #4f4f4f; paint-order: stroke; stroke: #fff; stroke-width: 4px; stroke-linejoin: round;
  transition: fill .35s ease;
}
.ssn-v2 .v2-map__label--end { text-anchor: end; }
.ssn-v2 .v2-map__label--mid { text-anchor: middle; }
.ssn-v2 .v2-map__city.is-active .v2-map__label { fill: var(--v2-navy); font-weight: 600; }
/* while a city is lit the others recede: dots fade, labels step to a grey that
   still clears 4.5:1 on white (#6b6b6b ≈ 5.3:1) — never below legibility */
.ssn-v2 .v2-map.has-active .v2-map__city:not(.is-active) .v2-map__dot   { opacity: .45; }
.ssn-v2 .v2-map.has-active .v2-map__city:not(.is-active) .v2-map__label { fill: #6b6b6b; }

/* focal marker: gold dot + soft pulsing ring. The whole group ignores the
   pointer (the pulse used to steal Waco's hover every cycle); only the small
   shield takes it, so hovering the gold marker itself selects nothing. */
.ssn-v2 .v2-map__home { pointer-events: none; }
.ssn-v2 .v2-map__home-shield { fill: transparent; stroke: none; pointer-events: visiblePainted; }
.ssn-v2 .v2-map__home-dot  { fill: var(--v2-gold); stroke: #fff; stroke-width: 1.5; vector-effect: non-scaling-stroke; }
.ssn-v2 .v2-map__home-ring { fill: none; stroke: var(--v2-gold); stroke-width: 1; stroke-opacity: .7; vector-effect: non-scaling-stroke; }
.ssn-v2 .v2-map__pulse {
  fill: var(--v2-gold); fill-opacity: .18; stroke: var(--v2-gold); stroke-width: 1; stroke-opacity: .5;
  vector-effect: non-scaling-stroke;
  transform-box: fill-box; transform-origin: center;
  animation: v2-loc-pulse 3.2s var(--v2-ease) infinite;
}
/* the pulse repaints the whole inline SVG every frame, so it only runs while the
   map is on screen: paused until the reveal has fired and whenever location.js
   marks the map off-screen (both hooks are JS-gated; without JS it just runs) */
html.js .ssn-v2 .v2-map[data-reveal]:not(.is-inview) .v2-map__pulse,
html.js .ssn-v2 .v2-map.is-offscreen .v2-map__pulse { animation-play-state: paused; }
@keyframes v2-loc-pulse {
  0%   { transform: scale(.3); opacity: .9; }
  70%  { opacity: 0; }
  100% { transform: scale(1.25); opacity: 0; }
}
/* property label: sentence case, lighter and set off from the city labels by a short
   gold leader, so the cluster around Waco / Fort Worth reads as one calm group */
.ssn-v2 .v2-map__home-label {
  font-size: 15.5px; font-weight: 600; letter-spacing: .02em; text-transform: none;
  fill: var(--v2-navy); text-anchor: end;
  paint-order: stroke; stroke: #fff; stroke-width: 4px; stroke-linejoin: round;
}
.ssn-v2 .v2-map__home-leader { stroke: var(--v2-gold); stroke-width: 1; stroke-opacity: .9; vector-effect: non-scaling-stroke; }

/* readout (bottom-left, over empty space) + caption (bottom-right, over the Gulf) */
.ssn-v2 .v2-map__readout {
  position: absolute; left: 0; bottom: 3.25rem; margin: 0;
  display: flex; flex-direction: column; gap: .375rem;
  font-family: var(--primary-font); color: var(--v2-navy); pointer-events: none;
  opacity: 0; transform: translateY(6px);
  transition: opacity .45s ease, transform .6s var(--v2-ease);
}
.ssn-v2 .v2-map__readout.is-on { opacity: 1; transform: none; }
.ssn-v2 .v2-map__readout-city { font-weight: 700; font-size: .6875rem; line-height: 1; letter-spacing: .2em; text-transform: uppercase; }
.ssn-v2 .v2-map__readout-time { font-weight: 400; font-size: 1.75rem; line-height: 1; letter-spacing: -.01em; color: #000; }
.ssn-v2 .v2-map__caption {
  margin: .25rem 0 0; text-align: center;
  font-family: var(--primary-font); font-weight: 400; font-size: .6875rem; line-height: 1.5;
  letter-spacing: .06em; color: #4f4f4f;
}

/* ---- driving-time list (the controls) -------------------------------------- */
.ssn-v2 .v2-loc__list-head {
  display: flex; flex-direction: column; align-items: flex-start; gap: .5rem;
  padding-bottom: .875rem; border-bottom: 1px solid var(--v2-hair);
}
.ssn-v2 .v2-loc__list-label {
  margin: 0; font-family: var(--primary-font); font-weight: 700; font-size: .6875rem; line-height: 1;
  letter-spacing: .2em; text-transform: uppercase; color: var(--v2-navy); white-space: nowrap;
}
.ssn-v2 .v2-loc__list-hint {
  margin: 0; font-family: var(--primary-font); font-weight: 400; font-size: .6875rem; line-height: 1;
  letter-spacing: .08em; color: #4f4f4f; white-space: nowrap;
}
.ssn-v2 .v2-loc__rows { list-style: none; margin: 0; padding: 0; }
.ssn-v2 .v2-loc__row {
  position: relative; width: 100%; min-height: 2.75rem;
  display: flex; align-items: baseline; justify-content: space-between; gap: 1rem;
  padding: .6875rem 0 .75rem; margin: 0; border: 0; border-bottom: 1px solid var(--v2-hair);
  background: none; color: #000; text-align: left; cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.ssn-v2 .v2-loc__row::after {                /* hairline turns navy from the left on hover/active */
  content: ""; position: absolute; left: 0; right: 0; bottom: -1px; height: 1px;
  background: var(--v2-navy); transform: scaleX(0); transform-origin: left;
  transition: transform .6s var(--v2-ease);
}
.ssn-v2 .v2-loc__row.is-active::after { transform: scaleX(1); }
.ssn-v2 .v2-loc__row:focus-visible { outline: 2px solid #222640; outline-offset: 3px; }
.ssn-v2 .v2-loc__row-city {
  display: inline-flex; align-items: center; gap: .625rem;
  font-family: var(--primary-font); font-weight: 600; font-size: .75rem; line-height: 1;
  letter-spacing: .16em; text-transform: uppercase; color: #4f4f4f;
  transition: color .35s ease;
}
.ssn-v2 .v2-loc__row-city::before {          /* small marker that fills in when the row is active */
  content: ""; width: 6px; height: 6px; border-radius: 50%; flex: 0 0 auto;
  border: 1px solid rgba(34,38,64,.45); background: transparent;
  transition: background-color .35s ease, border-color .35s ease, transform .5s var(--v2-ease);
}
.ssn-v2 .v2-loc__row.is-active .v2-loc__row-city { color: var(--v2-navy); }
.ssn-v2 .v2-loc__row.is-active .v2-loc__row-city::before { background: var(--v2-navy); border-color: var(--v2-navy); transform: scale(1.25); }
.ssn-v2 .v2-loc__row-time {
  font-size: 1.1875rem; line-height: 1; letter-spacing: -.01em; white-space: nowrap;
  transition: color .35s ease, transform .5s var(--v2-ease);
}
.ssn-v2 .v2-loc__row.is-active .v2-loc__row-time { color: var(--v2-navy); transform: translateX(-2px); }
.ssn-v2 .v2-loc__unit { font-size: .875rem; font-weight: 300; letter-spacing: 0; }
.ssn-v2 .v2-loc__pre  { font-size: .6875rem; font-weight: 700; letter-spacing: .16em; text-transform: uppercase; vertical-align: .2em; margin-right: .125rem; }
.ssn-v2 .v2-loc__row[aria-pressed="true"] .v2-loc__row-city::before { box-shadow: 0 0 0 3px rgba(34,38,64,.12); }

/* address + directions (final row of the list) */
.ssn-v2 .v2-loc__addr {
  display: flex; align-items: center; flex-wrap: wrap; gap: .875rem 1rem;
  padding-top: 1.125rem;
}
.ssn-v2 .v2-loc__pin { width: 1.25rem; height: 1.25rem; color: var(--v2-navy); flex: 0 0 auto; }
.ssn-v2 .v2-loc__pin svg { width: 100%; height: 100%; display: block; }
.ssn-v2 .v2-loc__addr-text { font-style: normal; font-size: .9375rem; line-height: 1.5; margin: 0; flex: 1 1 10rem; }
.ssn-v2 .v2-loc__directions { flex: 1 1 100%; margin-left: 2.25rem; margin-top: .125rem; }   /* lines up with the address text, clear of the pin */
/* the 18px-tall text link keeps its look but gains a ~40px tap area and the house focus ring
   (.ssn-textlink is position: relative; its ::after is the underline) */
.ssn-v2 .v2-loc__directions::before { content: ""; position: absolute; left: 0; right: 0; top: -.75rem; bottom: -.625rem; }
.ssn-v2 .v2-loc__directions:focus-visible { outline: 2px solid #222640; outline-offset: 3px; }

/* ---- responsive ------------------------------------------------------------- */
@media (max-width: 1320px) {
  .ssn-v2 .v2-map__label { font-size: 17px; }
  .ssn-v2 .v2-map__home-label { font-size: 16.5px; }
}
@media (max-width: 1180px) {
  .ssn-v2 .ssn-loc { --v2-map-w: clamp(17rem, 32vw, 24rem); --v2-list-w: clamp(15rem, 18vw, 15.5rem); }
  .ssn-v2 .v2-map__label { font-size: 20px; }
  .ssn-v2 .v2-map__home-label { font-size: 19px; }
  .ssn-v2 .v2-map__ghost { stroke-width: 1.6; }
  .ssn-v2 .v2-map__line  { stroke-width: 2; }
  .ssn-v2 .v2-map__readout-time { font-size: 1.5rem; }
}
@media (max-width: 1024px) {
  .ssn-v2 .v2-loc__grid {
    grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
    grid-template-areas: "copy copy" "map list";
    column-gap: clamp(2rem, 5vw, 3.5rem); row-gap: 2.5rem;
  }
  .ssn-v2 .ssn-loc__title { max-width: 18ch; }
  .ssn-v2 .ssn-loc__text  { max-width: 38rem; }
  .ssn-v2 .v2-map { align-self: center; max-width: 26.5rem; }
  .ssn-v2 .v2-map__label { font-size: 19px; }
  .ssn-v2 .v2-map__home-label { font-size: 18px; }
  .ssn-v2 .v2-map__ghost { stroke-width: 1.3; }
  .ssn-v2 .v2-map__line  { stroke-width: 1.65; }
}
@media (max-width: 768px) {
  .ssn-v2 .v2-loc__grid {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas: "copy" "map" "list";
    row-gap: 2.25rem;
  }
  .ssn-v2 .ssn-loc__title { max-width: none; margin-bottom: 1.125rem; }
  .ssn-v2 .v2-map { align-self: start; max-width: 28rem; }
  .ssn-v2 .v2-map__svg { overflow: visible; }
  .ssn-v2 .v2-map__label { font-size: 16px; letter-spacing: .1em; }
  .ssn-v2 .v2-map__home-label { font-size: 15.5px; }
  .ssn-v2 .v2-map__dot { r: 4; }
  .ssn-v2 .v2-map__ghost { stroke-width: 1.75; }
  .ssn-v2 .v2-map__line  { stroke-width: 2.2; }
  .ssn-v2 .v2-map__readout { bottom: 3.5rem; }
  .ssn-v2 .v2-map__readout-time { font-size: 1.375rem; }
  .ssn-v2 .v2-map__caption { text-align: center; }
  .ssn-v2 .v2-loc__list-hint { display: none; }
  .ssn-v2 .v2-loc__row { min-height: 3rem; padding: .8125rem 0 .875rem; }
  .ssn-v2 .v2-loc__row-time { font-size: 1.125rem; }
  .ssn-v2 .v2-loc__addr { padding-top: 1.25rem; }
}
@media (max-width: 430px) {
  /* phones: the map is 290–400px wide (scale .48–.67), so labels step up again */
  .ssn-v2 .v2-map__label { font-size: 19px; }
  .ssn-v2 .v2-map__home-label { font-size: 18px; }
}
@media (max-width: 340px) {
  .ssn-v2 .v2-map__label { font-size: 21px; }
  .ssn-v2 .v2-map__home-label { font-size: 20px; }
}

/* touch: map cities are tappable too (the list rows remain the primary controls);
   each city's hit circle and its label both count as the target */
.ssn-v2 .v2-map__city { -webkit-tap-highlight-color: transparent; touch-action: manipulation; }

/* ---- no JS: nothing responds, so drop the hint and the empty readout ---------- */
html:not(.js) .ssn-v2 .v2-loc__list-hint,
html:not(.js) .ssn-v2 .v2-map__readout { display: none; }

/* ---- reduced motion: connectors and states appear without drawing; no pulse ---- */
@media (prefers-reduced-motion: reduce) {
  .ssn-v2 .v2-map__pulse { animation: none; opacity: .35; transform: none; }
  .ssn-v2 .v2-map__ghost, .ssn-v2 .v2-map__line,
  .ssn-v2 .v2-map__route.is-active .v2-map__ghost, .ssn-v2 .v2-map__route.is-active .v2-map__line,
  .ssn-v2 .v2-map__city, .ssn-v2 .v2-map__dot, .ssn-v2 .v2-map__halo, .ssn-v2 .v2-map__label,
  .ssn-v2 .v2-map__readout, .ssn-v2 .v2-loc__row::after, .ssn-v2 .v2-loc__row-city, .ssn-v2 .v2-loc__row-city::before,
  .ssn-v2 .v2-loc__row-time { transition: none; }
  .ssn-v2 .v2-map__readout { transform: none; }
  .ssn-v2 .v2-loc__row.is-active .v2-loc__row-time { transform: none; }
}

/* ===================== polish.css ===================== */
/* ==========================================================================
   v2 — Polish pass: Gallery (#gallery) · Guest Reviews (#reviews) ·
   FAQ (#faq) · Final CTA (#book)
   --------------------------------------------------------------------------
   A refinement layer over the v1 rules in prototype.css. Every JS hook
   (.ssn-gal__*, .ssn-rev__*, .ssn-q__*, .ssn-cta__*) keeps its class and
   place — this file only restyles. All rules are scoped under .ssn-v2; new
   classes are prefixed .v2-. Paragraph size/weight belongs to base.css.
   Tokens from base.css: --ssn-ivory, --ssn-hair, --ssn-hair-ivory.
   polish.js ticks .v2-gal__count-cur and sets --v2-lb-pos on the lightbox;
   without it the counter reads "01 — 12" and the viewer line sits at zero.
   ========================================================================== */

/* ==========================================================================
   GALLERY — editorial rail: every even photo steps down 1.5rem, small-caps
   captions, hairline "01 — 12" index beside the arrows, deeper hover,
   refined full-screen viewer
   ========================================================================== */
.ssn-v2 .ssn-gal { --v2-gal-step: 1.5rem; }                  /* vertical offset of even photos */
.ssn-v2 .ssn-gal__head { margin-bottom: 2.75rem; }
.ssn-v2 .ssn-gal__hint { margin-top: 1rem; letter-spacing: .14em; }

/* index counter: "01 — 12", the dash drawn as a hairline */
.ssn-v2 .ssn-gal__nav { align-items: center; gap: .75rem; }
.ssn-v2 .v2-gal__count {
  display: inline-flex; align-items: center; gap: .75rem; margin-right: 1rem;
  font-family: var(--primary-font); font-weight: 600; font-size: .6875rem; line-height: 1;
  letter-spacing: .22em; color: #000; font-variant-numeric: tabular-nums;
}
.ssn-v2 .v2-gal__count-rule { width: 1.75rem; height: 1px; background: #000; opacity: .3; }
.ssn-v2 .v2-gal__count-total { color: #5a5a5a; }

/* rail rhythm: the track grows at the foot so the lower captions are not
   clipped (prototype.css keeps overflow-y hidden on the track) */
.ssn-v2 .ssn-gal__track { padding-bottom: calc(.5rem + var(--v2-gal-step)); }
.ssn-v2 .ssn-gal__item:nth-child(even) { margin-top: var(--v2-gal-step); }
.ssn-v2 .ssn-gal__progress { margin-top: 1rem; }

/* photo hover: slower zoom, a whisper of navy, the expand disc rises in */
.ssn-v2 .ssn-gal__open::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: rgba(34,38,64,0); transition: background-color .7s ease;
}
.ssn-v2 .ssn-gal__open:hover::after,
.ssn-v2 .ssn-gal__open:focus-visible::after { background: rgba(34,38,64,.14); }
.ssn-v2 .ssn-gal__open img { transition-duration: 1.3s; }
.ssn-v2 .ssn-gal__open:hover img,
.ssn-v2 .ssn-gal__open:focus-visible img { transform: scale(1.05); }
/* shadow kept inside the 1rem inset: .ssn-gal__open clips (overflow hidden) */
.ssn-v2 .ssn-gal__expand {
  z-index: 1; width: 2.5rem; height: 2.5rem; right: 1rem; bottom: 1rem;
  background: rgba(255,255,255,.94); box-shadow: 0 3px 10px rgba(0,0,0,.18);
  transform: translateY(8px) scale(.9);
  transition: opacity .55s ease, transform .7s cubic-bezier(.22,.61,.36,1);
}
.ssn-v2 .ssn-gal__open:hover .ssn-gal__expand,
.ssn-v2 .ssn-gal__open:focus-visible .ssn-gal__expand { opacity: 1; transform: none; }

/* captions: small caps (a hair darker on hover) */
.ssn-v2 .ssn-gal__cap {
  margin-top: .875rem; text-transform: none; font-variant-caps: small-caps;
  font-size: .9375rem; letter-spacing: .1em; color: #4f4f4f; transition: color .5s ease;
}
.ssn-v2 .ssn-gal__item:hover .ssn-gal__cap { color: #000; }

/* full-screen viewer: slower image settle, small-caps caption, a thin line
   above the caption that fills to the current position (--v2-lb-pos, 0–1).
   The backdrop fade is asymmetric: .5s in (.is-open), .3s out — prototype.js
   flips `hidden` 300ms after close, so the out-fade must finish by then. */
.ssn-v2 .ssn-lightbox { transition-duration: .3s; }
.ssn-v2 .ssn-lightbox.is-open { transition-duration: .5s; }
.ssn-v2 .ssn-lightbox__img {
  transform: scale(.965) translateY(10px);
  transition: opacity .75s ease, transform 1.2s cubic-bezier(.22,.61,.36,1);
}
.ssn-v2 .ssn-lightbox__img.is-ready { transform: none; }
.ssn-v2 .ssn-lightbox__figure { gap: 1.25rem; }
.ssn-v2 .ssn-lightbox__cap { position: relative; padding-top: 1.125rem; align-items: center; text-transform: none; }
.ssn-v2 .ssn-lightbox__cap::before,
.ssn-v2 .ssn-lightbox__cap::after { content: ""; position: absolute; left: 0; top: 0; width: 100%; height: 1px; }
.ssn-v2 .ssn-lightbox__cap::before { background: rgba(255,255,255,.18); }
.ssn-v2 .ssn-lightbox__cap::after {
  background: #fff; transform-origin: left; transform: scaleX(var(--v2-lb-pos, 0));
  transition: transform .8s cubic-bezier(.22,.61,.36,1);
}
.ssn-v2 .ssn-lightbox__text { font-variant-caps: small-caps; font-size: 1rem; letter-spacing: .08em; color: rgba(255,255,255,.92); }
.ssn-v2 .ssn-lightbox__count { font-size: .6875rem; letter-spacing: .24em; color: rgba(255,255,255,.55); font-variant-numeric: tabular-nums; }

/* ==========================================================================
   GUEST REVIEWS — sculptural 5.0 (light numeral over gold stars, hairline,
   count), an oversized quote mark behind each lead, more air in the rail
   ========================================================================== */
/* wider rail gap on desktop only — below 1025px prototype.css's own
   breakpoint values (2rem / 1.25rem) must keep winning */
@media (min-width: 1025px) { .ssn-v2 .ssn-rev { --rev-gap: clamp(2.25rem, 4vw, 4rem); } }
.ssn-v2 .ssn-rev__head { margin-bottom: 3.25rem; }

/* summary block */
.ssn-v2 .ssn-rev__summary { padding-bottom: .375rem; }
.ssn-v2 .ssn-rev__score { flex-direction: column; align-items: flex-end; gap: .875rem; margin-bottom: 1.125rem; }
.ssn-v2 .ssn-rev__num {
  font-size: clamp(3.5rem, 4.6vw, 4.5rem); font-weight: 300; line-height: .9;
  letter-spacing: -.02em; font-variant-numeric: tabular-nums;
}
.ssn-v2 .ssn-rev__stars svg { width: 1.125rem; height: 1.125rem; fill: #e0ab2e; }
.ssn-v2 .ssn-rev__count {
  padding-top: .875rem; margin-bottom: 1.125rem;
  border-top: 1px solid var(--ssn-hair, #e6e6e6); letter-spacing: .14em; color: #4f4f4f;
}

/* rail cards: hairline-topped, a touch more air; quote ornament behind the lead */
.ssn-v2 .ssn-rev__card { position: relative; padding-top: 2rem; }
.ssn-v2 .ssn-rev__lead { position: relative; z-index: 0; margin: 1.375rem 0 1rem; }
.ssn-v2 .ssn-rev__lead::before {
  content: "\201C"; content: "\201C" / "";             /* alt-text form keeps it out of the a11y tree */
  position: absolute; z-index: -1; left: -.06em; top: -.3em;
  font-family: var(--primary-font); font-weight: 400; font-size: 6.5rem; line-height: 1;
  color: #222640; opacity: .13; pointer-events: none;
}
.ssn-v2 .ssn-rev__text { margin-bottom: 1.625rem; }
.ssn-v2 .ssn-rev__meta { gap: .375rem .875rem; }
.ssn-v2 .ssn-rev__date { color: #4f4f4f; }
.ssn-v2 .ssn-rev__foot { margin-top: 2.5rem; }

/* ==========================================================================
   FAQ — ivory band, #e3dfd6 hairlines, lighter circle icon, navy open state
   with the answer copy indented behind a short navy hairline
   ========================================================================== */
.ssn-v2 .ssn-faqs.v2-ivory { background: var(--ssn-ivory, #f7f5f0); }
.ssn-v2 .ssn-faqs .ssn-acc-list { border-bottom-color: #e3dfd6; }
.ssn-v2 .ssn-faqs .ssn-q { border-top-color: #e3dfd6; }
.ssn-v2 .ssn-faqs__intro { top: 6rem; }                      /* still sticky on desktop (prototype.css) */
.ssn-v2 .ssn-faqs__all { margin-top: 2.25rem; }

/* question row */
.ssn-v2 .ssn-q__btn { padding: 1.5rem 0; gap: 1.75rem; }
.ssn-v2 .ssn-q__label { transition: color .45s ease; }
.ssn-v2 .ssn-q.is-open .ssn-q__label,
.ssn-v2 .ssn-q__btn:hover .ssn-q__label { color: #222640; }

/* circle icon: lighter ring, longer strokes, fills navy when open */
.ssn-v2 .ssn-q__icon { width: 2.5rem; height: 2.5rem; border-color: rgba(34,38,64,.28); }
.ssn-v2 .ssn-q__icon i { width: .875rem; }
.ssn-v2 .ssn-q__btn:hover .ssn-q__icon { border-color: #222640; }
.ssn-v2 .ssn-q.is-open .ssn-q__icon { background: #222640; border-color: #222640; }

/* open panel: copy indents behind a navy hairline that draws down */
.ssn-v2 .ssn-q__inner { position: relative; padding-left: 1.5rem; }
.ssn-v2 .ssn-q__inner::before {
  content: ""; position: absolute; left: 0; top: .5rem; bottom: 1.875rem; width: 1px;
  background: #222640; opacity: .45; transform: scaleY(0); transform-origin: top;
  transition: transform .7s cubic-bezier(.22,.61,.36,1) .1s;
}
.ssn-v2 .ssn-q.is-open .ssn-q__inner::before { transform: scaleY(1); }
.ssn-v2 .ssn-q__inner > :last-child { margin-bottom: 1.875rem; }
.ssn-v2 .ssn-q__kv dt { color: #4f4f4f; }                    /* 4.5:1 on ivory */

/* ==========================================================================
   FINAL CTA — gold hairline above the heading, zoom-settle on the photograph
   brought inside the 1.4s motion band, button lifts on hover; scrim untouched
   ========================================================================== */
.ssn-v2 .ssn-cta__inner { max-width: 48rem; }
.ssn-v2 .v2-cta__rule { display: block; width: 3rem; height: 1px; margin: 0 auto 2.25rem; background: #e0ab2e; }
/* draws in from the centre with the reveal; visible as-is when scripts never run (no html.js) */
.ssn-v2 .v2-cta__rule[data-reveal] { opacity: 1; transform: none; transition: transform 1.4s cubic-bezier(.22,.61,.36,1) .1s; }
.js .ssn-v2 .v2-cta__rule[data-reveal] { transform: scaleX(0); }
.js .ssn-v2 .v2-cta__rule[data-reveal].is-inview,
.js .ssn-v2 .v2-cta__rule[data-reveal].is-settled { transform: scaleX(1); }
.ssn-v2 .ssn-cta__title { margin-bottom: 1.625rem; }
.ssn-v2 .ssn-cta__text { margin-bottom: 2.75rem; }

/* photograph: settles from a slight zoom at the top of the motion band (v1: 1.08 / 2.2s) */
.ssn-v2 .ssn-cta__bg[data-reveal] { transform: scale(1.06); transition: transform 1.4s cubic-bezier(.22,.61,.36,1); }
.ssn-v2 .ssn-cta__bg[data-reveal].is-inview,
.ssn-v2 .ssn-cta__bg[data-reveal].is-settled { transform: none; }

/* button: navy fill plus a soft lift */
.ssn-v2 .ssn-cta__btn {
  padding: 1.3125rem 2.875rem; letter-spacing: .22em; box-shadow: 0 0 0 rgba(8,10,20,0);
  transition: background-color .45s ease, color .45s ease,
              transform .6s cubic-bezier(.22,.61,.36,1), box-shadow .6s ease;
}
.ssn-v2 .ssn-cta__btn:hover { transform: translateY(-2px); box-shadow: 0 16px 36px rgba(8,10,20,.3); }
.ssn-v2 .ssn-cta__btn:active { transform: none; transition-duration: .15s; }
.ssn-v2 .ssn-cta__btn-arrow { transition: transform .6s cubic-bezier(.22,.61,.36,1); }
.ssn-v2 .ssn-cta__btn:hover .ssn-cta__btn-arrow { transform: translateX(6px); }

/* ==========================================================================
   Keyboard safety net — a focusable control inside a [data-reveal] wrapper
   (FAQ question buttons, the gallery arrows, the CTA button) can receive focus
   before the wrapper has crossed the reveal threshold (nearest-edge focus
   scrolling, magnifiers, programmatic focus). Show the wrapper at once while
   it holds focus. (0,4,0) beats [data-reveal] and [data-reveal].is-inview.
   ========================================================================== */
.ssn-v2 :is(.ssn-gal, .ssn-rev, .ssn-faqs, .ssn-cta) [data-reveal]:focus-within {
  opacity: 1; transform: none; transition: none;
}

/* ==========================================================================
   Responsive
   ========================================================================== */
@media (max-width: 768px) {
  /* gallery */
  .ssn-v2 .ssn-gal { --v2-gal-step: 1rem; }
  .ssn-v2 .ssn-gal__head { margin-bottom: 2rem; }
  .ssn-v2 .ssn-gal__nav { width: 100%; }
  .ssn-v2 .v2-gal__count { margin-right: auto; }              /* index left, arrows flush right */
  .ssn-v2 .ssn-gal__expand { opacity: 1; transform: none; width: 2.125rem; height: 2.125rem; box-shadow: none; }
  .ssn-v2 .ssn-gal__cap { font-size: .875rem; }
  .ssn-v2 .ssn-gal__progress { margin-top: .5rem; }
  .ssn-v2 .ssn-lightbox__cap { padding-top: .875rem; }
  .ssn-v2 .ssn-lightbox__text { font-size: .9375rem; }
  /* reviews */
  .ssn-v2 .ssn-rev__score { align-items: flex-start; gap: .75rem; }
  .ssn-v2 .ssn-rev__num { font-size: 3.25rem; }
  .ssn-v2 .ssn-rev__card { padding-top: 1.75rem; }
  .ssn-v2 .ssn-rev__lead::before { font-size: 4.5rem; }
  /* faq */
  .ssn-v2 .ssn-q__btn { padding: 1.25rem 0; gap: 1.125rem; }
  .ssn-v2 .ssn-q__icon { width: 2.25rem; height: 2.25rem; }
  .ssn-v2 .ssn-q__inner { padding-left: 1.125rem; }
  /* cta */
  .ssn-v2 .v2-cta__rule { margin-bottom: 1.75rem; }
  .ssn-v2 .ssn-cta__btn { padding: 1.1875rem 2.25rem; }
}

@media (prefers-reduced-motion: reduce) {
  .ssn-v2 .ssn-gal__open img, .ssn-v2 .ssn-gal__open::after, .ssn-v2 .ssn-gal__expand, .ssn-v2 .ssn-gal__cap,
  .ssn-v2 .ssn-lightbox, .ssn-v2 .ssn-lightbox.is-open, .ssn-v2 .ssn-lightbox__img, .ssn-v2 .ssn-lightbox__cap::after,
  .ssn-v2 .ssn-q__label, .ssn-v2 .ssn-q__inner::before,
  .ssn-v2 .ssn-cta__btn, .ssn-v2 .ssn-cta__btn-arrow { transition: none; }
  .ssn-v2 .ssn-lightbox__img, .ssn-v2 .ssn-q__inner::before, .ssn-v2 .ssn-cta__btn:hover { transform: none; }
  /* hover zoom: no transform either (same (0,3,1) specificity, later in source) */
  .ssn-v2 .ssn-gal__open:hover img, .ssn-v2 .ssn-gal__open:focus-visible img { transform: none; }
  .ssn-v2 .v2-cta__rule[data-reveal], .js .ssn-v2 .v2-cta__rule[data-reveal],
  .ssn-v2 .ssn-cta__bg[data-reveal] { transform: none; transition: none; }
}
