/* ============================================================
   single-service.html (360 booth) — zephyr language, own grid.
   Like services/location, this page breaks from the fixed 1200px
   canvas: responsive sections capped at 1200px, all classes
   spin- prefixed to stay clear of canvas rules. Its structure is
   its own: full-bleed video hero, count-up number band, a dark
   chapter player ("The Making of a spin"), a headliner marquee with
   a ticket rail for the events, one oversized pull quote,
   animated FAQ.
   Motion: load choreography (spin-rise), shared .fade-in
   observer (script.js), chapter autoplay + count-ups in
   single-service.js. All motion respects reduced motion.
   ============================================================ */

.spin-wrap { max-width: 1200px; margin: 0 auto; padding: 0 clamp(22px, 4vw, 48px); }

.spin-eyebrow {
  font-family: var(--font-sub); font-size: 12px; letter-spacing: .26em;
  text-transform: uppercase; color: var(--powder);
}
.spin-h2 {
  font-family: var(--font-display); font-weight: 200;
  font-size: clamp(34px, 4.6vw, 56px); line-height: 1.08;
  text-transform: uppercase; letter-spacing: .02em;
}
.spin-h2 em { font-style: italic; text-transform: none; letter-spacing: 0; }
.spin-btn {
  display: inline-flex; align-items: center; justify-content: center;
  padding: 17px 36px; background: var(--paleblue); text-decoration: none;
  border: 0; cursor: pointer;
  font-family: var(--font-sub); font-size: 12px; letter-spacing: .18em;
  text-transform: uppercase; color: var(--slate);
  transition: background .45s, color .45s, transform .45s;
}
.spin-btn:hover { background: var(--powder); color: var(--cream); }
.spin-btn:focus-visible { outline: 2px solid var(--powder); outline-offset: 3px; }
.spin-ghost {
  font-family: var(--font-sub); font-size: 12px; letter-spacing: .18em;
  text-transform: uppercase; color: var(--cream); text-decoration: none;
  border-bottom: 1px solid var(--paleblue); padding-bottom: 6px;
  transition: color .3s, border-color .3s;
}
.spin-ghost:hover { color: var(--paleblue); }

/* scroll reveal (rides the shared .fade-in observer in script.js) */
.spin-main .fade-in { opacity: 0; transform: translateY(22px); transition: opacity .8s ease, transform .8s ease; }
.spin-main .fade-in.is-visible { opacity: 1; transform: none; }

/* ---------- hero: full-bleed video, centered copy ---------- */
.spin-hero {
  position: relative; overflow: hidden;
  min-height: 560px; height: 100vh; height: 100svh;
  display: flex; align-items: center; justify-content: center;
  text-align: center; background: #000;
  /* the photo is PINNED, so the copy travels over a still frame. Same technique
     the kit already uses on .mq-testimonial; the darkening stays on the
     .spin-hero-scrim layer so the measured contrast values below still hold.
     `cover` here resolves against the VIEWPORT, not the section, which is why
     the source is exported at 2600px rather than pane width. */
  background-image: url("../images/hero-keepsake-station.webp");
  background-size: cover; background-position: center;
  background-repeat: no-repeat; background-attachment: fixed;
}
/* Deepened from .38/.44/.66 (2026-08-08). The kit's hero is a dark VIDEO; this
   page runs a bright, high-key keychain-station photo behind the same copy, and
   measured against the actual glyph pixels the top of the old gradient left the
   eyebrow at 3.9:1 for half its pixels and 2.1:1 at its worst, with the lede at
   3.4:1 across a tenth of its glyphs. Worst case at 390x664 (real iPhone svh),
   where the shorter hero pulls the copy over the brightest part of the frame.
   The top two stops carry the change; the bottom stop was already doing its job
   (the chip measured 4.4:1 at its worst before this). */
.spin-hero-scrim {
  position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(0,0,0,.54) 0%, rgba(0,0,0,.58) 55%, rgba(0,0,0,.70) 100%);
}
.spin-hero-copy { position: relative; padding: 96px 22px; max-width: 900px; }
@keyframes spin-rise { to { opacity: 1; transform: none; } }
.spin-rise { opacity: 0; transform: translateY(26px); animation: spin-rise .9s cubic-bezier(.2,.7,.2,1) forwards; }
.spin-hero .spin-eyebrow { display: block; margin-bottom: 28px; color: var(--paleblue); animation-delay: .05s; }
.spin-h1 {
  font-family: var(--font-display); font-weight: 200;
  font-size: clamp(52px, 7.4vw, 104px); line-height: .98;
  text-transform: uppercase; letter-spacing: .02em; color: var(--cream);
}
.spin-h1 .spin-line { display: block; }
.spin-h1 .spin-line:nth-child(1) { animation-delay: .14s; }
.spin-h1 .spin-line:nth-child(2) { animation-delay: .26s; }
.spin-h1 em { font-style: italic; text-transform: none; letter-spacing: 0; color: var(--paleblue); }
.spin-lede {
  max-width: 54ch; margin: 26px auto 0; font-size: 16px; line-height: 1.75;
  color: rgba(247, 248, 245, .82); animation-delay: .4s;
}
.spin-hero-actions {
  margin-top: 36px; display: flex; align-items: center; justify-content: center;
  gap: 28px; flex-wrap: wrap; animation-delay: .52s;
}

/* ---------- the spin, by the numbers (count-ups) ---------- */
.spin-numbers { background: var(--cream); padding: clamp(56px, 7vw, 92px) 0; }
.spin-numbers .spin-eyebrow { display: block; text-align: center; margin-bottom: clamp(34px, 4vw, 52px); }
.spin-nums { display: grid; grid-template-columns: repeat(4, 1fr); gap: clamp(24px, 3vw, 52px); }
.spin-num { border-left: 1px solid rgba(43, 58, 85, .25); padding-left: 18px; }
.spin-num b {
  display: block; font-family: var(--font-display); font-weight: 200;
  font-size: clamp(40px, 4.4vw, 64px); line-height: 1;
  font-variant-numeric: tabular-nums;
}
.spin-num span {
  display: block; margin-top: 10px; font-family: var(--font-sub); font-size: 10.5px;
  letter-spacing: .18em; text-transform: uppercase; color: var(--powder);
}

/* ---------- the making of a spin: dark chapter player ---------- */
.spin-film { background: var(--slate); color: var(--cream); padding: clamp(72px, 9vw, 120px) 0; scroll-margin-top: 84px; }
.spin-film .spin-eyebrow { color: var(--paleblue); }
.spin-film-head { max-width: 640px; margin-bottom: clamp(40px, 5vw, 60px); }
.spin-film-head .spin-eyebrow { display: block; margin-bottom: 18px; }
.spin-film-head p { margin-top: 18px; font-size: 15px; line-height: 1.75; color: rgba(247, 248, 245, .72); }

.spin-stage { position: relative; overflow: hidden; }
.spin-stage-media { position: relative; aspect-ratio: 16 / 7.6; }
.spin-stage-media img,
.spin-stage-media video {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
  opacity: 0; transition: opacity .8s ease;
}
.spin-stage-media img.is-live,
.spin-stage-media video.is-live { opacity: 1; }
.spin-stage-caption {
  position: absolute; left: 0; right: 0; bottom: 0;
  padding: clamp(60px, 6vw, 90px) clamp(22px, 3vw, 40px) clamp(20px, 2.4vw, 30px);
  /* Was `rgba(43,58,85,0) 0%, rgba(43,58,85,.78) 100%` (2026-08-08). These
     captions run about 2.5x the kit's length, so they wrap to two lines and the
     first line sits high in the ramp where it was still nearly transparent, over
     stage photos that are far brighter than the kit's. Measured on the glyph
     pixels, chapters 02 and 04 fell to 2.3:1 across a tenth of their strokes
     (2.03:1 at worst) against the kit's own 3.2:1/2.8:1 baseline. Same gradient,
     same colour, reshaped to reach its dark end where this copy actually starts;
     it still opens fully transparent, so the photo is never boxed. */
  background: linear-gradient(180deg, rgba(43,58,85,0) 0%, rgba(43,58,85,.72) 42%, rgba(43,58,85,.90) 100%);
  pointer-events: none;
  /* all captions share one grid cell so the crossfade never reflows */
  display: grid; align-items: end;
}
.spin-stage-caption p {
  grid-area: 1 / 1; margin: 0; max-width: 62ch;
  font-family: var(--font-display); font-style: italic; font-weight: 200;
  font-size: clamp(18px, 2vw, 26px); line-height: 1.4; color: var(--cream);
  opacity: 0; transition: opacity .8s ease;
}
.spin-stage-caption p.is-live { opacity: 1; }

.spin-chapters { margin-top: clamp(24px, 3vw, 36px); display: grid; grid-template-columns: repeat(4, 1fr); gap: clamp(16px, 2vw, 30px); }
.spin-chap {
  background: none; border: 0; padding: 0; cursor: pointer; text-align: left;
  color: rgba(247, 248, 245, .62); transition: color .35s;
}
.spin-chap:hover { color: var(--cream); }
.spin-chap:focus-visible { outline: 2px solid var(--paleblue); outline-offset: 4px; }
.spin-chap.is-live { color: var(--cream); }
.spin-chap-track { display: block; height: 2px; background: rgba(247, 248, 245, .22); overflow: hidden; }
.spin-chap-fill { display: block; height: 100%; width: 0; background: var(--paleblue); }
.spin-chap.is-live .spin-chap-fill.is-run { width: 100%; transition: width var(--spin-dur, 5s) linear; }
.spin-chap-num {
  display: block; margin-top: 16px;
  font-family: var(--font-display); font-style: italic; font-weight: 200;
  font-size: 22px; color: var(--paleblue);
}
.spin-chap-name {
  display: block; margin-top: 8px; font-family: var(--font-sub);
  font-size: 12px; letter-spacing: .2em; text-transform: uppercase;
}
.spin-chap-sub { display: block; margin-top: 8px; font-family: var(--font-body); font-size: 13px; line-height: 1.5; color: rgba(247, 248, 245, .55); }
.spin-chap.is-live .spin-chap-sub { color: rgba(247, 248, 245, .75); }

/* ---------- where it plays: headliner marquee + ticket rail ---------- */
.spin-events { background: var(--paleblue); padding: clamp(72px, 9vw, 120px) 0; }
.spin-marquee-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.35fr); gap: clamp(32px, 5vw, 84px); align-items: start; }
.spin-evt-head .spin-eyebrow { display: block; margin-bottom: 18px; }
.spin-evt-head p { margin-top: 18px; font-size: 15px; line-height: 1.75; max-width: 46ch; color: color-mix(in srgb, var(--slate) 80%, var(--paleblue)); }
/* buttons sit on paleblue here, so the shared paleblue .spin-btn inverts */
.spin-events .spin-btn { background: var(--slate); color: var(--cream); padding: 14px 26px; }
.spin-events .spin-btn:hover { background: var(--powder); }

/* left column: the live event's copy crossfades in place */
.spin-live { margin-top: clamp(28px, 3vw, 44px); border-top: 1px solid rgba(43,58,85,.25); padding-top: clamp(22px, 2.4vw, 32px); display: grid; }
.spin-live-slide { grid-area: 1 / 1; opacity: 0; transform: translateY(14px); transition: opacity .55s ease, transform .55s ease; pointer-events: none; visibility: hidden; }
.spin-live-slide.is-live { opacity: 1; transform: none; pointer-events: auto; visibility: visible; transition-delay: .18s; }
.spin-live-name {
  font-family: var(--font-display); font-weight: 200;
  font-size: clamp(30px, 3.2vw, 44px); line-height: 1.05;
  text-transform: uppercase; letter-spacing: .02em;
}
.spin-live-name em { font-style: italic; text-transform: none; letter-spacing: 0; color: var(--powder); }
.spin-live-slide p { margin-top: 14px; font-size: 15px; line-height: 1.75; max-width: 44ch; color: color-mix(in srgb, var(--slate) 84%, var(--paleblue)); }
.spin-live-cta { margin-top: 22px; display: flex; align-items: center; gap: 22px; flex-wrap: wrap; }

/* right column: 16:10 marquee, then the waiting ticket strips */
.spin-marquee { position: relative; aspect-ratio: 16 / 10; overflow: hidden; }
.spin-marquee img,
.spin-marquee video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; clip-path: inset(0 0 100% 0); transition: clip-path .8s cubic-bezier(.2,.7,.2,1); }
.spin-marquee img.is-live,
.spin-marquee video.is-live { clip-path: inset(0 0 0 0); z-index: 1; }
.spin-marquee-tag {
  position: absolute; z-index: 2; left: 0; bottom: 0;
  background: var(--cream); color: var(--slate);
  font-family: var(--font-sub); font-size: 10.5px; letter-spacing: .26em;
  text-transform: uppercase; padding: 12px 18px;
}
.spin-tickets { margin-top: clamp(14px, 1.6vw, 20px); display: grid; gap: clamp(10px, 1.2vw, 14px); }
.spin-ticket {
  display: grid; grid-template-columns: 76px 1fr auto; align-items: center;
  gap: clamp(14px, 2vw, 24px); background: none;
  border: 1px solid rgba(43,58,85,.3); padding: 10px; cursor: pointer;
  text-align: left; font: inherit; color: inherit;
  transition: background .4s ease, transform .5s cubic-bezier(.2,.7,.2,1);
}
.spin-ticket:hover { background: color-mix(in srgb, var(--cream) 65%, var(--paleblue)); transform: translateX(6px); }
.spin-ticket:focus-visible { outline: 2px solid var(--powder); outline-offset: 3px; }
.spin-ticket.is-live { display: none; }
.spin-ticket-thumb { width: 76px; height: 76px; overflow: hidden; }
.spin-ticket-thumb img,
.spin-ticket-thumb video { width: 100%; height: 100%; object-fit: cover; display: block; }
.spin-ticket-name {
  font-family: var(--font-display); font-weight: 200;
  font-size: clamp(19px, 1.8vw, 24px); text-transform: uppercase;
  letter-spacing: .02em; line-height: 1.1;
}
.spin-ticket-name em { font-style: italic; text-transform: none; letter-spacing: 0; color: var(--powder); }
.spin-ticket-go {
  font-family: var(--font-sub); font-size: 10.5px; letter-spacing: .24em;
  text-transform: uppercase; color: var(--powder); padding-right: 8px; white-space: nowrap;
}

/* ---------- one oversized pull quote ---------- */

/* ---------- faq: centered single column ---------- */
.spin-faq { background: var(--linen); padding: clamp(64px, 8vw, 110px) 0; }
.spin-faq-head { text-align: center; max-width: 560px; margin: 0 auto clamp(36px, 4vw, 52px); }
.spin-faq-head .spin-eyebrow { display: block; margin-bottom: 18px; }
.spin-faq-head p { margin-top: 18px; font-size: 15px; line-height: 1.75; color: color-mix(in srgb, var(--slate) 78%, var(--linen)); }
.spin-faqs { max-width: 760px; margin: 0 auto; }
.spin-faqs .faq-q { font-size: 15px; }
/* animated open: grid-rows collapse, overriding the global display toggle */
.spin-faqs .faq-a {
  display: grid; grid-template-rows: 0fr; overflow: hidden;
  transition: grid-template-rows .45s cubic-bezier(.2,.7,.2,1);
}
.spin-faqs .faq-item.open .faq-a { grid-template-rows: 1fr; }
.spin-faqs .faq-a p {
  min-height: 0; padding: 0; font-size: 14.5px; line-height: 1.75;
  color: color-mix(in srgb, var(--slate) 80%, var(--linen));
}
.spin-faqs .faq-item.open .faq-a p { padding-bottom: 18px; }


/* ---------- hero price chip ---------- */
.spin-hero-chip {
  margin-top: 22px; font-family: var(--font-sub); font-size: 10.5px;
  letter-spacing: .2em; text-transform: uppercase; color: rgba(247, 248, 245, .85);
  animation-delay: .64s;
}
.spin-hero-chip a { color: var(--paleblue); }

/* ---------- what's included ---------- */
/* ---------- what's included: full-bleed photo | itemised list ----------
   Owner-directed layout (2026-08-09), assembled from vocabulary the kit already
   uses: the two-column photo/copy split of .svc-inc-top, the hairline row rules
   of .faq-item, the inset outline of .ig-frame, the letterspaced --powder
   eyebrow, and the display-caps h2 with its italic <em> accent. The photo bleeds
   to the viewport edge, so this section does NOT use .spin-wrap. */
.spin-included { background: var(--linen); padding: 0; }
.spin-inc-grid {
  display: grid; grid-template-columns: minmax(0, 0.92fr) minmax(0, 1.08fr);
  align-items: stretch;
}
.spin-inc-media { position: relative; margin: 0; min-height: 640px; overflow: hidden; }
.spin-inc-media img { position: absolute; inset: 0; width: 100%; height: 100%;
                      object-fit: cover; display: block; }
/* inset hairline, the same accent .ig-frame draws over its photos */
.spin-inc-media::after {
  content: ""; position: absolute; left: 30px; top: 30px; right: 30px; bottom: 30px;
  border: 1px solid rgba(250, 246, 240, .45); pointer-events: none;
}
.spin-inc-copy {
  display: flex; flex-direction: column; justify-content: center;
  padding: clamp(56px, 6vw, 104px) clamp(24px, 5vw, 92px);
  max-width: 780px;
}
.spin-inc-copy .spin-eyebrow { display: block; margin-bottom: 18px; }
.spin-inc-lede {
  margin-top: 20px; max-width: 46ch; font-size: 15px; line-height: 1.8;
  color: color-mix(in srgb, var(--slate) 78%, var(--linen));
}
.spin-inc-lede a { color: var(--slate); }

.spin-inc-list {
  list-style: none; margin: clamp(28px, 3.2vw, 42px) 0 0;
  border-top: 1px solid rgba(74, 65, 57, .18);
}
.spin-inc-list li {
  display: grid; grid-template-columns: 16px 1fr auto; gap: 0 14px; align-items: baseline;
  padding: 13px 2px; border-bottom: 1px solid rgba(74, 65, 57, .18);
  font-family: var(--font-display); font-weight: 200;
  font-size: clamp(15px, 1.32vw, 19px); line-height: 1.3;
  text-transform: uppercase; letter-spacing: .02em;
}
.spin-inc-list li::before { content: "\2022"; color: var(--powder); line-height: 1; }
.spin-inc-plus {
  font-family: var(--font-sub); font-style: normal; font-size: 11px;
  letter-spacing: .16em; color: var(--powder); white-space: nowrap;
}

.spin-inc-foot {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 18px 28px; flex-wrap: wrap; margin-top: clamp(26px, 3vw, 40px);
}
.spin-inc-price { display: flex; align-items: baseline; gap: 14px; }
.spin-inc-price span {
  font-family: var(--font-sub); font-size: 11px; letter-spacing: .22em;
  text-transform: uppercase; color: color-mix(in srgb, var(--slate) 68%, var(--linen));
}
.spin-inc-price b {
  font-family: var(--font-display); font-weight: 200;
  font-size: clamp(28px, 3vw, 38px); line-height: 1;
}
.spin-inc-cta {
  font-family: var(--font-sub); font-size: 12px; letter-spacing: .18em;
  text-transform: uppercase; color: var(--slate); text-decoration: none;
  border-bottom: 1px solid var(--slate); padding-bottom: 6px;
  transition: color .35s, border-color .35s;
}
.spin-inc-cta:hover { color: var(--powder); border-color: var(--powder); }

/* ---------- occasion cross-link (sits on the paleblue events bg) ---------- */
.spin-panel-link {
  display: inline-block; font-family: var(--font-sub);
  font-size: 10.5px; letter-spacing: .2em; text-transform: uppercase;
  color: var(--slate); text-decoration: none;
  border-bottom: 1px solid var(--powder); padding-bottom: 4px;
}
.spin-panel-link:hover { color: var(--powder); }

/* ---------- reviews ---------- */
.spin-reviews { background: var(--butter); padding: clamp(64px, 8vw, 104px) 0; }
.spin-rev-head { text-align: center; max-width: 620px; margin: 0 auto clamp(36px, 4vw, 54px); }
.spin-rev-head .spin-eyebrow { display: block; margin-bottom: 18px; }
.spin-rev-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(20px, 2.4vw, 34px); }
.spin-review {
  margin: 0; background: var(--cream); border: 1px solid rgba(43, 58, 85, .12);
  padding: clamp(26px, 2.6vw, 36px); display: flex; flex-direction: column;
}
.spin-stars { color: var(--powder); font-size: 12px; letter-spacing: .34em; }
.spin-review blockquote {
  margin: 18px 0 24px; font-family: var(--font-display); font-style: italic;
  font-weight: 200; font-size: clamp(19px, 1.7vw, 23px); line-height: 1.45;
}
.spin-review figcaption {
  margin-top: auto; font-family: var(--font-sub); font-size: 11px;
  letter-spacing: .2em; text-transform: uppercase;
}
.spin-review figcaption span { display: block; margin-top: 6px; color: var(--powder); }

/* ---------- mobile + motion safety ---------- */
@media (max-width: 900px) {
  /* iOS does not honour background-attachment: fixed; pin the photo to the
     viewport on a fixed ::before instead and clip it to the section (clip-path
     contains fixed descendants, overflow does not), lifting the scrim and copy
     above it. Mirrors the kit's own .mq-testimonial mobile treatment. */
  .spin-hero { background-image: none; clip-path: inset(0); }
  .spin-hero::before {
    content: ""; position: fixed; inset: 0; z-index: 0;
    background: url("../images/hero-keepsake-station.webp") center / cover no-repeat;
  }
  .spin-hero-scrim { z-index: 1; }
  .spin-hero-copy { z-index: 2; }

  .spin-rev-grid { grid-template-columns: 1fr; }
  .spin-inc-grid { grid-template-columns: 1fr; }
  .spin-inc-media { min-height: 320px; }
  .spin-inc-media::after { left: 18px; top: 18px; right: 18px; bottom: 18px; }
  .spin-inc-copy { padding: 44px 22px 56px; max-width: none; }
  .spin-inc-list li { grid-template-columns: 14px 1fr auto; }
  .spin-hero { height: auto; min-height: 100svh; }
  .spin-nums { grid-template-columns: repeat(2, 1fr); gap: 30px; }
  .spin-stage-media { aspect-ratio: 4 / 3.4; }
  .spin-chapters { grid-template-columns: repeat(2, 1fr); gap: 22px; }
  .spin-marquee-grid { grid-template-columns: 1fr; gap: 34px; }
  .spin-ticket-go { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  .spin-rise { animation: none; opacity: 1; transform: none; }
  .spin-main .fade-in { transition: none; opacity: 1; transform: none; }
  .spin-stage-media img,
  .spin-stage-caption p,
  .spin-live-slide,
  .spin-marquee img,
  .spin-ticket,
  .spin-chap-fill,
  .spin-stage-media video,
  .spin-marquee video { transition: none; }
  .spin-chap.is-live .spin-chap-fill.is-run { width: 100%; transition: none; }
}
