/* ============================================================
   DECORB — Homepage v3 "The Room Sequence"
   ------------------------------------------------------------
   Loaded AFTER styles.css. styles.css still supplies the shared
   primitives this page reuses — .navbar, .mobile-menu, .btn,
   #launch-overlay, the cookie banner, .pricing-card, .faq-item,
   .footer — plus the base reset and the :root token block.

   Everything specific to this page is namespaced `dcb-` so it
   can never collide with the old `.hp-*` homepage rules that
   are still in styles.css for the other pages.

   The body carries `home-v3`, NOT `home-v2`, deliberately: the
   old homepage's global rules in styles.css are all scoped
   under `.home-v2`, so the new page opts out of every one of
   them while keeping the unscoped shared primitives.

   MOTION CONTRACT
   home.js adds `motion-ready` to <html> once the Motion module
   has actually loaded. Every hidden-until-animated state is
   gated behind `.motion-ready` so that a blocked CDN, an old
   browser, or a thrown error can never leave the page blank —
   it just renders static. Same reason `--dcb-hp` (hero
   progress) defaults to 0 here rather than being set by JS.
   ============================================================ */

.home-v3 {
  /* Surfaces */
  --dcb-ink: #0a0a0b;
  --dcb-ink-2: #101012;
  --dcb-ink-3: #161619;
  --dcb-ink-4: #1d1d21;

  /* Accent — the existing Decorb gold, kept exactly */
  --dcb-gold: #c9a962;
  --dcb-gold-lt: #e3cd96;
  --dcb-gold-dim: rgba(201, 169, 98, 0.16);

  /* Ink on dark */
  --dcb-cream: #f6f2ea;
  --dcb-t1: #f6f2ea;
  --dcb-t2: rgba(246, 242, 234, 0.68);
  --dcb-t3: rgba(246, 242, 234, 0.44);
  --dcb-t4: rgba(246, 242, 234, 0.26);
  --dcb-line: rgba(246, 242, 234, 0.1);
  --dcb-line-2: rgba(246, 242, 234, 0.18);

  /* Rhythm */
  --dcb-gutter: clamp(20px, 5vw, 72px);
  --dcb-max: 1340px;
  --dcb-sec: clamp(96px, 13vh, 180px);

  /* Easing — one soft "settle" curve used everywhere */
  --dcb-ease: cubic-bezier(0.16, 1, 0.3, 1);

  /* Hero scrub progress, 0 → 1. Written by home.js. */
  --dcb-hp: 0;

  background: var(--dcb-ink);
  color: var(--dcb-t1);
}

.home-v3 main {
  /* The hero pin and the reel both rely on position:sticky.
     Any ancestor with overflow other than visible silently
     kills sticky, so main must not clip. */
  overflow: visible;
}

/* ------------------------------------------------------------
   Shared type
   ------------------------------------------------------------ */

.dcb-h2 {
  font-family: var(--font-display);
  font-weight: 300;
  font-size: clamp(2.4rem, 5.2vw, 4.6rem);
  line-height: 1.02;
  letter-spacing: -0.02em;
  max-width: 18ch;
}

.dcb-h2 em {
  font-style: italic;
  font-weight: 400;
  color: var(--dcb-gold-lt);
}

.dcb-h3 {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(1.6rem, 2.6vw, 2.3rem);
  line-height: 1.12;
  letter-spacing: -0.015em;
  color: var(--dcb-t1);
}

.dcb-lede {
  font-size: clamp(1.02rem, 1.25vw, 1.2rem);
  line-height: 1.62;
  color: var(--dcb-t2);
  max-width: 56ch;
  font-weight: 300;
}

.dcb-copy {
  font-size: 1.02rem;
  line-height: 1.68;
  color: var(--dcb-t2);
  font-weight: 300;
  max-width: 54ch;
}

.dcb-eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 0.6em;
  font-size: 0.68rem;
  font-weight: 500;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--dcb-t3);
}

.dcb-eyebrow::before {
  content: "";
  width: 28px;
  height: 1px;
  background: var(--dcb-gold);
  opacity: 0.7;
}

.dcb-eyebrow-gold {
  color: var(--dcb-gold-lt);
}

.dcb-wrap {
  width: 100%;
  max-width: var(--dcb-max);
  margin-inline: auto;
  padding-inline: var(--dcb-gutter);
}

/* ------------------------------------------------------------
   Reveal — the resting state for every scroll-in element.
   Gated on .motion-ready so content is visible without JS.
   ------------------------------------------------------------ */

.motion-ready .home-v3 [data-dcb-reveal] {
  opacity: 0;
  transform: translate3d(0, 22px, 0);
  will-change: opacity, transform;
}

.home-v3 [data-dcb-reveal].is-in {
  opacity: 1;
  transform: none;
  will-change: auto;
}

/* ============================================================
   1. HERO — the scroll-scrubbed open
   ------------------------------------------------------------
   .dcb-hero is a tall rail (the scroll runway). .dcb-hero-pin
   is sticky inside it and holds every moving part, so the whole
   sequence plays while the page scrolls past the rail.

   The rail's height IS the duration of the sequence. Shortening
   it makes the whole timeline faster.
   ============================================================ */

.dcb-hero {
  position: relative;
  height: 340vh;
  background: var(--dcb-ink);
}

.dcb-hero-pin {
  position: sticky;
  top: 0;
  /* vh first as the fallback: an engine that does not understand
     svh would otherwise fall through to height:auto, and a sticky
     element with auto height does not pin at all. */
  height: 100vh;
  height: 100svh;
  min-height: 560px;
  overflow: hidden;
  display: grid;
  place-items: center;
  isolation: isolate;
}

/* Warm floor-glow behind everything, fades out as the sequence
   hands over to the full-bleed room. */
.dcb-hero-glow {
  position: absolute;
  inset: -20% -10% auto -10%;
  height: 120%;
  background:
    radial-gradient(60% 50% at 50% 42%, rgba(201, 169, 98, 0.14), transparent 70%),
    radial-gradient(40% 40% at 18% 78%, rgba(201, 169, 98, 0.07), transparent 70%);
  pointer-events: none;
  z-index: 0;
  opacity: calc(1 - var(--dcb-hp) * 2.4);
}

/* --- Ambient floating rooms -------------------------------
   Six rooms adrift behind the headline. Three things make them
   read as fluid rather than as stickers:

   1. They never sit still. Each one bobs, sways and breathes on
      three unrelated periods, so the motion never visibly loops.
      Those run on the individual translate / rotate / scale
      properties, which leaves `transform` free for the scroll
      flight-out and the mouse parallax.
   2. Depth. Far cards are smaller, softer (--blur) and dimmer
      (--o), and move less under the pointer (--d).
   3. Soft shapes - arches, discs and a pill instead of six
      identical rectangles - and a mask that dissolves them
      toward the middle, so they never compete with the copy.
   ---------------------------------------------------------- */

.dcb-amb {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  /* Mouse parallax, written by home.js. */
  --dcb-mx: 0;
  --dcb-my: 0;
  /* Size multiplier, stepped down on small screens. */
  --k: 1;
  -webkit-mask-image: radial-gradient(ellipse 62% 54% at 50% 48%, transparent 34%, #000 82%);
  mask-image: radial-gradient(ellipse 62% 54% at 50% 48%, transparent 34%, #000 82%);
}

/* Each card declares --x/--y (position), --w/--ar/--rad (size
   and shape), --d (parallax depth), --r (rest rotation),
   --fx/--fy (flight-out vector), and its float: --t (period),
   --dl (phase), --ax/--ay (drift, px), --sw (sway, deg). */
.dcb-amb-card {
  position: absolute;
  left: var(--x);
  top: var(--y);
  width: calc(var(--w, 130px) * var(--k));
  aspect-ratio: var(--ar, 3 / 4);
  border-radius: var(--rad, 18px);
  overflow: hidden;
  box-shadow: 0 30px 70px -24px rgba(0, 0, 0, 0.9);
  filter: blur(var(--blur, 0px));
  opacity: calc((1 - var(--dcb-hp) * 3.4) * var(--o, 1));
  transform:
    translate3d(
      calc(var(--dcb-mx) * var(--d) * 1px + var(--fx) * var(--dcb-hp) * 1px),
      calc(var(--dcb-my) * var(--d) * 1px + var(--fy) * var(--dcb-hp) * 1px),
      0
    )
    rotate(calc(var(--r) * 1deg))
    scale(calc(1 - var(--dcb-hp) * 0.18));
  transition: transform 1.4s var(--dcb-ease);
  animation:
    dcb-amb-drift var(--t, 14s) ease-in-out var(--dl, 0s) infinite alternate,
    dcb-amb-sway calc(var(--t, 14s) * 1.37) ease-in-out var(--dl, 0s) infinite alternate,
    dcb-amb-breathe calc(var(--t, 14s) * 0.83) ease-in-out var(--dl, 0s) infinite alternate;
  will-change: transform, translate;
}

/* Hairline that catches the light along the card's edge. */
.dcb-amb-card::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  box-shadow: inset 0 0 0 1px rgba(246, 242, 234, 0.1);
  background: linear-gradient(160deg, rgba(246, 242, 234, 0.1), transparent 38%);
}

.dcb-amb-card img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  filter: saturate(0.85) brightness(0.8);
}

@keyframes dcb-amb-drift {
  from { translate: calc(var(--ax, 8) * -1px) calc(var(--ay, 14) * 1px); }
  to   { translate: calc(var(--ax, 8) * 1px) calc(var(--ay, 14) * -1px); }
}

@keyframes dcb-amb-sway {
  from { rotate: calc(var(--sw, 2) * -1deg); }
  to   { rotate: calc(var(--sw, 2) * 1deg); }
}

@keyframes dcb-amb-breathe {
  from { scale: 0.975; }
  to   { scale: 1.035; }
}

/* Soft out-of-focus discs for depth, same drift system. */
.dcb-amb-orb {
  position: absolute;
  left: var(--x);
  top: var(--y);
  width: calc(var(--w) * var(--k));
  aspect-ratio: 1;
  border-radius: 50%;
  background: radial-gradient(circle at 32% 28%, rgba(201, 169, 98, 0.2), rgba(201, 169, 98, 0.02) 62%, transparent 72%);
  filter: blur(var(--b, 6px));
  opacity: calc((1 - var(--dcb-hp) * 3) * var(--o, 1));
  transform: translate3d(
    calc(var(--dcb-mx) * var(--d) * 1px + var(--fx) * var(--dcb-hp) * 1px),
    calc(var(--dcb-my) * var(--d) * 1px + var(--fy) * var(--dcb-hp) * 1px),
    0
  );
  transition: transform 1.8s var(--dcb-ease);
  animation: dcb-amb-drift var(--t, 22s) ease-in-out var(--dl, 0s) infinite alternate;
}

/* Phones: the copy fills the width, so the two mid-height cards
   would sit straight behind it. Drop them, shrink the rest and
   keep them to the top and bottom bands. */
@media (max-width: 680px) {
  .dcb-amb {
    --k: 0.6;
    -webkit-mask-image: linear-gradient(#000 0 14%, transparent 34% 68%, #000 88%);
    mask-image: linear-gradient(#000 0 14%, transparent 34% 68%, #000 88%);
  }

  .dcb-amb-mid {
    display: none;
  }
}

/* --- The headline stack ----------------------------------- */

.dcb-hero-stack {
  position: relative;
  z-index: 3;
  width: 100%;
  max-width: var(--dcb-max);
  padding-inline: var(--dcb-gutter);
  display: grid;
  justify-items: center;
  text-align: center;
  gap: clamp(18px, 2.4vh, 30px);
}

/* Everything except headline line B leaves early and together. */
.dcb-hero-fade {
  opacity: calc(1 - var(--dcb-hp) * 5);
  transform: translate3d(0, calc(var(--dcb-hp) * 40px), 0);
}

.dcb-hero-title {
  font-family: var(--font-display);
  font-weight: 300;
  /* Sized so line A ("Forty-seven rooms you love.") stays on ONE
     line at every desktop width — it is the longest string on the
     page and the composition depends on it not wrapping. Note the
     root font-size is 14px, not 16px, so 6.6rem is ~92px. Measure
     before raising this. */
  font-size: clamp(2.9rem, 7vw, 6.6rem);
  line-height: 0.95;
  letter-spacing: -0.028em;
  display: grid;
  gap: 0.04em;
  margin: 0;
}

/* Line A — "Forty-seven rooms you love." Leaves first, drifting
   up and desaturating so line B is left alone on screen. */
.dcb-hl-a {
  display: block;
  color: var(--dcb-t1);
  opacity: calc(1 - var(--dcb-hp) * 4.2);
  transform: translate3d(0, calc(var(--dcb-hp) * -60px), 0) scale(calc(1 - var(--dcb-hp) * 0.08));
}

/* Line B — "None of them [ROOM] yours." The two halves travel
   apart on transform only; nothing here reflows. */
.dcb-hl-b {
  display: flex;
  align-items: center;
  justify-content: center;
  white-space: nowrap;
  gap: 0.26em;
}

.dcb-w {
  display: inline-block;
  will-change: transform;
}

.dcb-w em {
  font-style: italic;
  font-weight: 400;
  color: var(--dcb-gold-lt);
}

/* --dcb-split is the px each half has travelled outward;
   --dcb-wfade is its own opacity. Both written by home.js. */
.dcb-w-l {
  transform: translate3d(calc(var(--dcb-split, 0) * -1px), 0, 0);
  opacity: var(--dcb-wfade, 1);
}

.dcb-w-r {
  transform: translate3d(calc(var(--dcb-split, 0) * 1px), 0, 0);
  opacity: var(--dcb-wfade, 1);
}

.dcb-hero-sub {
  font-size: clamp(1rem, 1.3vw, 1.18rem);
  line-height: 1.6;
  font-weight: 300;
  color: var(--dcb-t2);
  max-width: 54ch;
}

.dcb-hero-cta {
  display: grid;
  justify-items: center;
  gap: 12px;
}

.dcb-hero-note {
  font-size: 0.78rem;
  letter-spacing: 0.04em;
  color: var(--dcb-t3);
}

/* --- The media that grows out of the gap ------------------ */

/* Absolutely centred and driven purely by transform + size
   vars, so it never participates in the headline's layout.
   It starts at zero scale behind the words, grows into the gap
   they open, then takes the whole viewport. */
.dcb-reveal-media {
  position: absolute;
  top: 50%;
  left: 50%;
  z-index: 2;
  width: var(--dcb-rw, 0px);
  height: var(--dcb-rh, 0px);
  margin: calc(var(--dcb-rh, 0px) / -2) 0 0 calc(var(--dcb-rw, 0px) / -2);
  border-radius: var(--dcb-rr, 10px);
  overflow: hidden;
  opacity: var(--dcb-ro, 0);
  pointer-events: none;
  box-shadow: 0 40px 120px -30px rgba(0, 0, 0, 0.9);
}

/* Lifted above the headline once it is bigger than the words,
   so the text reads as sliding behind the room, not over it. */
.dcb-reveal-media.is-over {
  z-index: 4;
}

.dcb-reveal-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* Before/after wipe inside the hero reveal.
   --dcb-wipe is the split position as a percentage, written by
   initHero(). It stays at 0 while the room is growing (so only the
   BEFORE is on screen), then sweeps left to right once the room is
   full bleed until the AFTER owns the whole frame — the beat that
   explains the product. */
.dcb-rev-layer {
  position: absolute;
  inset: 0;
}

.dcb-rev-before {
  clip-path: inset(0 0 0 var(--dcb-wipe, 0%));
}

.dcb-rev-split {
  position: absolute;
  top: 0;
  bottom: 0;
  left: var(--dcb-wipe, 0%);
  width: 1px;
  background: var(--dcb-gold-lt);
  opacity: var(--dcb-rl, 0);
  box-shadow: 0 0 20px rgba(201, 169, 98, 0.6);
}

.dcb-rev-tag {
  position: absolute;
  top: clamp(16px, 4vh, 40px);
  padding: 7px 13px;
  border-radius: 999px;
  background: rgba(10, 10, 11, 0.74);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border: 1px solid var(--dcb-line-2);
  font-size: 0.64rem;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--dcb-cream);
  white-space: nowrap;
  opacity: var(--dcb-rs, 0);
}

/* Each tag lives inside the layer it labels, so the wipe itself
   uncovers the AFTER tag first and clips the BEFORE tag last. */
.dcb-rev-tag-l {
  left: clamp(16px, 3vw, 36px);
  border-color: var(--dcb-gold-dim);
  color: var(--dcb-gold-lt);
}

.dcb-rev-tag-r {
  right: clamp(16px, 3vw, 36px);
}

/* Vignette + caption that only materialise at full bleed. */
.dcb-reveal-scrim {
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, rgba(10, 10, 11, 0.86) 0%, rgba(10, 10, 11, 0) 46%);
  opacity: var(--dcb-rs, 0);
}

.dcb-reveal-cap {
  position: absolute;
  left: clamp(20px, 5vw, 64px);
  bottom: clamp(24px, 5vh, 56px);
  right: clamp(20px, 5vw, 64px);
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 8px 18px;
  opacity: var(--dcb-rs, 0);
  transform: translate3d(0, calc((1 - var(--dcb-rs, 0)) * 16px), 0);
}

.dcb-reveal-cap strong {
  font-family: var(--font-display);
  font-size: clamp(1.4rem, 3vw, 2.4rem);
  font-weight: 400;
  font-style: italic;
  color: var(--dcb-cream);
}

.dcb-reveal-cap span {
  font-size: 0.74rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--dcb-t3);
}

/* --- Scroll cue ------------------------------------------- */

.dcb-scroll-cue {
  position: absolute;
  left: 50%;
  bottom: clamp(18px, 4vh, 40px);
  transform: translateX(-50%);
  z-index: 5;
  display: grid;
  justify-items: center;
  gap: 8px;
  font-size: 0.66rem;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  color: var(--dcb-t3);
  opacity: calc(1 - var(--dcb-hp) * 8);
  pointer-events: none;
}

.dcb-scroll-cue i {
  display: block;
  width: 1px;
  height: 34px;
  background: linear-gradient(to bottom, var(--dcb-gold), transparent);
  animation: dcb-cue 2.2s var(--dcb-ease) infinite;
}

@keyframes dcb-cue {
  0% { transform: scaleY(0); transform-origin: top; opacity: 0; }
  40% { transform: scaleY(1); transform-origin: top; opacity: 1; }
  60% { transform: scaleY(1); transform-origin: bottom; opacity: 1; }
  100% { transform: scaleY(0); transform-origin: bottom; opacity: 0; }
}

/* ============================================================
   2. WHAT IT DOES — draggable before/after
   ------------------------------------------------------------
   --dcb-ba-x is the wipe position in percent, written by
   initBeforeAfter(). It defaults to 50 here so the component is
   correct and self-explanatory with no JS at all.
   ============================================================ */

.dcb-ba-section {
  position: relative;
  padding-block: clamp(56px, 9vh, 110px) var(--dcb-sec);
  background: var(--dcb-ink);
}

.dcb-ba-head {
  display: grid;
  gap: 18px;
  justify-items: start;
  margin-bottom: clamp(28px, 4.5vh, 48px);
}

/* One centred column. A side column beside the frame left the three
   takeaways in a ~300px gutter where every line broke after two or
   three words; stacked underneath they get the full measure, and the
   frame gets the width it deserves.

   900px against a 3312px source is still ~3.7x, so there is no
   upscaling even on a high-DPI screen. */
.dcb-ba-layout {
  display: grid;
  gap: clamp(28px, 4vw, 52px);
  max-width: 900px;
  margin-inline: auto;
}

.dcb-ba {
  --dcb-ba-x: 50;
  display: grid;
  gap: 16px;
  width: 100%;
}

/* --- room tabs -------------------------------------------- */

.dcb-ba-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.dcb-ba-tab {
  padding: 9px 17px;
  border-radius: 999px;
  border: 1px solid var(--dcb-line);
  background: transparent;
  color: var(--dcb-t3);
  font-size: 0.74rem;
  font-weight: 500;
  letter-spacing: 0.08em;
  cursor: pointer;
  transition: color 0.3s var(--dcb-ease), border-color 0.3s var(--dcb-ease),
    background 0.3s var(--dcb-ease);
}

.dcb-ba-tab:hover {
  color: var(--dcb-t1);
  border-color: var(--dcb-line-2);
}

.dcb-ba-tab.is-active {
  color: var(--dcb-ink);
  background: var(--dcb-gold-lt);
  border-color: var(--dcb-gold-lt);
}

/* --- the frame -------------------------------------------- */

.dcb-ba-stage {
  position: relative;
  /* Matches the renders' native 4:3 exactly, so nothing is cropped
     and nothing is upscaled: 1920x1440 source in a <=620px frame. */
  aspect-ratio: 4 / 3;
  border-radius: 12px;
  overflow: hidden;
  background: var(--dcb-ink-3);
  cursor: ew-resize;
  /* Horizontal drags belong to the handle, not the page. */
  touch-action: pan-y;
  -webkit-user-select: none;
  user-select: none;
}

.dcb-ba-pair {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity 0.5s var(--dcb-ease);
}

.dcb-ba-pair.is-active {
  opacity: 1;
}

.dcb-ba-pair img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  -webkit-user-drag: none;
  user-select: none;
}

/* The BEFORE sits on top, clipped to the wipe. Both layers are
   full-size and identically framed, so the seam is a true
   comparison of the same pixels. */
.dcb-ba-clip {
  position: absolute;
  inset: 0;
  overflow: hidden;
  clip-path: inset(0 calc(100% - var(--dcb-ba-x) * 1%) 0 0);
}

.dcb-ba-label {
  position: absolute;
  top: clamp(12px, 2.5vw, 20px);
  z-index: 4;
  padding: 6px 12px;
  border-radius: 999px;
  background: rgba(10, 10, 11, 0.74);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border: 1px solid var(--dcb-line-2);
  font-size: 0.62rem;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--dcb-cream);
  white-space: nowrap;
  pointer-events: none;
}

.dcb-ba-label-b {
  left: clamp(12px, 2.5vw, 20px);
}

.dcb-ba-label-a {
  right: clamp(12px, 2.5vw, 20px);
  border-color: var(--dcb-gold-dim);
  color: var(--dcb-gold-lt);
}

/* --- handle ----------------------------------------------- */

.dcb-ba-handle {
  position: absolute;
  top: 0;
  bottom: 0;
  left: calc(var(--dcb-ba-x) * 1%);
  z-index: 5;
  width: 1px;
  /* The clip edge falls exactly on --dcb-ba-x; a 1px line drawn from
     there sits a whole pixel to its right. Pull it back half a pixel
     so the rule straddles the seam rather than abutting it. */
  margin-left: -0.5px;
  background: var(--dcb-gold-lt);
  box-shadow: 0 0 18px rgba(201, 169, 98, 0.55);
}

/* Centred ON the seam by explicit offset + transform, not by grid
   alignment. The handle is 1px wide, and a grid item far wider than
   its track does not reliably centre under place-items — it can
   resolve to start, which parks the grip's left edge on the line
   instead of its middle.

   Every rule that re-declares transform must repeat the translate,
   or the grip jumps back off the line. */
.dcb-ba-grip {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  display: grid;
  place-items: center;
  width: 42px;
  height: 42px;
  border-radius: 50%;
  background: rgba(10, 10, 11, 0.8);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border: 1px solid var(--dcb-gold-lt);
  color: var(--dcb-gold-lt);
  transition: transform 0.3s var(--dcb-ease), background 0.3s var(--dcb-ease);
}

.dcb-ba-stage:hover .dcb-ba-grip,
.dcb-ba-handle:focus-visible .dcb-ba-grip {
  transform: translate(-50%, -50%) scale(1.1);
  background: var(--dcb-gold-lt);
  color: var(--dcb-ink);
}

.dcb-ba-handle:focus-visible {
  outline: none;
}

.dcb-ba-caption {
  font-size: 0.92rem;
  line-height: 1.6;
  font-weight: 300;
  color: var(--dcb-t3);
  max-width: 68ch;
}

/* --- the three takeaways ---------------------------------- */

/* A row beneath the frame, which is where three short items read
   best — one per column, each with room for a full line. */
.dcb-ba-points {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(18px, 3vw, 40px);
}

.dcb-ba-points li {
  display: grid;
  gap: 7px;
  padding-top: 18px;
  border-top: 1px solid var(--dcb-line);
  font-size: 0.92rem;
  line-height: 1.6;
  font-weight: 300;
  color: var(--dcb-t3);
}

.dcb-ba-points b {
  font-family: var(--font-display);
  font-size: 1.3rem;
  font-weight: 400;
  color: var(--dcb-cream);
}

/* ============================================================
   3. STYLE REEL — sticky media bed + vertical style list
   ------------------------------------------------------------
   Lifted from the reference's category reel. The rail scrolls;
   the stage is pinned; home.js writes --dcb-reel-i (fractional
   active index) and toggles .is-active on the centred item.
   ============================================================ */

.dcb-reel {
  position: relative;
  height: 420vh;
  background: var(--dcb-ink);
}

.dcb-reel-stage {
  position: sticky;
  top: 0;
  height: 100vh;
  height: 100svh;
  min-height: 560px;
  overflow: hidden;
  display: grid;
  align-items: center;
}

/* Stacked crossfading backdrops — one per style. */
.dcb-reel-bg {
  position: absolute;
  inset: 0;
  z-index: 0;
}

.dcb-reel-bg img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transform: scale(1.06);
  transition: opacity 0.9s var(--dcb-ease), transform 1.6s var(--dcb-ease);
  filter: brightness(0.64) saturate(0.95);
}

.dcb-reel-bg img.is-active {
  opacity: 1;
  transform: scale(1);
}

.dcb-reel-veil {
  position: absolute;
  inset: 0;
  z-index: 1;
  background:
    linear-gradient(to right, rgba(10, 10, 11, 0.92) 0%, rgba(10, 10, 11, 0.45) 46%, rgba(10, 10, 11, 0.1) 100%),
    linear-gradient(to bottom, rgba(10, 10, 11, 0.8), transparent 22%, transparent 74%, rgba(10, 10, 11, 0.9));
  pointer-events: none;
}

.dcb-reel-inner {
  position: relative;
  z-index: 2;
  width: 100%;
  max-width: var(--dcb-max);
  margin-inline: auto;
  padding-inline: var(--dcb-gutter);
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 0.9fr);
  align-items: center;
  gap: clamp(24px, 5vw, 80px);
}

.dcb-reel-copy {
  display: grid;
  gap: 18px;
  justify-items: start;
}

/* The list. Translated as one block so the active row always
   lands on the stage's centre line. */
.dcb-reel-listwrap {
  position: relative;
  /* One row height, shared by the items and by the list's
     translate. Declared here (not measured in JS) so the maths
     holds identically whether or not the module loaded. */
  --dcb-reel-row: clamp(56px, 7.4vw, 94px);
  height: clamp(300px, 52vh, 460px);
  overflow: hidden;
  /* Fade the ends so items dissolve rather than clip. */
  -webkit-mask-image: linear-gradient(to bottom, transparent, #000 22%, #000 78%, transparent);
  mask-image: linear-gradient(to bottom, transparent, #000 22%, #000 78%, transparent);
}

.dcb-reel-list {
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  display: grid;
  /* --dcb-reel-row is the measured row height; --dcb-reel-i the
     fractional index. Both written by home.js. */
  transform: translate3d(
    0,
    calc(var(--dcb-reel-row, 72px) * -0.5 - var(--dcb-reel-i, 0) * var(--dcb-reel-row, 72px)),
    0
  );
  transition: transform 0.45s var(--dcb-ease);
  will-change: transform;
}

.dcb-reel-item {
  height: var(--dcb-reel-row, 72px);
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 16px;
  font-family: var(--font-display);
  font-weight: 300;
  font-size: clamp(1.9rem, 4.1vw, 3.4rem);
  line-height: 1;
  letter-spacing: -0.02em;
  color: var(--dcb-t4);
  text-align: right;
  transition: color 0.45s var(--dcb-ease), opacity 0.45s var(--dcb-ease);
}

.dcb-reel-item.is-active {
  color: var(--dcb-cream);
}

.dcb-reel-item.is-active em {
  font-style: normal;
  color: var(--dcb-gold-lt);
}

/* A hairline that only the active row grows. */
.dcb-reel-item i {
  display: block;
  width: 0;
  height: 1px;
  background: var(--dcb-gold);
  transition: width 0.55s var(--dcb-ease);
}

.dcb-reel-item.is-active i {
  width: clamp(28px, 5vw, 64px);
}

/* ============================================================
   4. HOW IT WORKS — numbered steps, pinned frame
   ============================================================ */

.dcb-how {
  position: relative;
  padding-block: var(--dcb-sec);
  background: var(--dcb-ink-2);
  border-block: 1px solid var(--dcb-line);
}

.dcb-how-head {
  display: grid;
  gap: 18px;
  justify-items: start;
  margin-bottom: clamp(48px, 8vh, 96px);
}

.dcb-how-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(32px, 6vw, 96px);
  align-items: start;
}

/* The clips are 16:10 screen recordings. The frame takes their
   exact shape and they are never cropped (contain, not cover):
   trimming a recording's edges cuts away the UI it is there to
   show. Height follows the column width, so the sticky offset
   centres a frame of roughly that size rather than a fixed one. */
.dcb-how-visual {
  position: sticky;
  top: max(96px, calc(50svh - min(18vw, 220px)));
  aspect-ratio: 16 / 10;
  border-radius: 12px;
  overflow: hidden;
  background: var(--dcb-ink-4);
}

.dcb-how-visual video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  opacity: 0;
  transform: scale(1.04);
  transition: opacity 0.7s var(--dcb-ease), transform 1.3s var(--dcb-ease);
}

.dcb-how-visual video.is-active {
  opacity: 1;
  transform: scale(1);
}

.dcb-how-tag {
  position: absolute;
  left: 16px;
  bottom: 16px;
  z-index: 2;
  padding: 7px 13px;
  border-radius: 999px;
  background: rgba(10, 10, 11, 0.72);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border: 1px solid var(--dcb-line-2);
  font-size: 0.68rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--dcb-cream);
}

.dcb-how-steps {
  display: grid;
  gap: clamp(72px, 14vh, 150px);
  padding-block: clamp(24px, 6vh, 70px);
}

/* Per-step clips are a MOBILE-ONLY affordance — on desktop the
   pinned frame already carries the visual, so these stay out of the
   layout entirely. They are preload="none" and initHow() only plays
   a clip that is actually on screen, so desktop never fetches them. */
.dcb-how-step-media {
  display: none;
}

/* Second half of each step's copy. Present everywhere, dropped on
   small screens so a phone gets one tight line instead of four. */
.dcb-more {
  display: inline;
}

.dcb-how-step {
  display: grid;
  gap: 14px;
  justify-items: start;
  transition: opacity 0.5s var(--dcb-ease);
}

.motion-ready .dcb-how-step {
  opacity: 0.3;
}

.motion-ready .dcb-how-step.is-active {
  opacity: 1;
}

.dcb-how-meta {
  display: flex;
  align-items: center;
  gap: 14px;
}

.dcb-how-num {
  font-family: var(--font-display);
  font-size: 1.1rem;
  font-style: italic;
  color: var(--dcb-gold);
}

.dcb-how-label {
  font-size: 0.68rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--dcb-t3);
}

/* ============================================================
   5. MOAT — your own sample, rendered at full scale
   ============================================================ */

.dcb-moat {
  position: relative;
  padding-block: var(--dcb-sec);
  background: var(--dcb-ink);
}

.dcb-moat-head {
  display: grid;
  gap: 18px;
  justify-items: start;
  margin-bottom: clamp(40px, 6vh, 72px);
}

.dcb-moat-stage {
  display: grid;
  grid-template-columns: minmax(230px, 0.4fr) minmax(0, 1fr);
  gap: clamp(20px, 3vw, 40px);
  align-items: start;
}

.dcb-moat-list {
  display: grid;
  gap: 8px;
}

.dcb-moat-item {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 10px;
  border: 1px solid transparent;
  border-radius: 10px;
  background: transparent;
  text-align: left;
  cursor: pointer;
  transition: background 0.35s var(--dcb-ease), border-color 0.35s var(--dcb-ease);
}

.dcb-moat-item:hover {
  background: var(--dcb-ink-3);
}

.dcb-moat-item.is-active {
  background: var(--dcb-ink-3);
  border-color: var(--dcb-gold-dim);
}

.dcb-moat-thumb {
  flex: 0 0 auto;
  width: 54px;
  height: 54px;
  border-radius: 8px;
  overflow: hidden;
  background: var(--dcb-ink-4);
  filter: saturate(0.7) brightness(0.8);
  transition: filter 0.35s var(--dcb-ease);
}

.dcb-moat-item.is-active .dcb-moat-thumb {
  filter: none;
}

.dcb-moat-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.dcb-moat-text {
  display: grid;
  gap: 3px;
}

.dcb-moat-kicker {
  font-size: 0.6rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--dcb-t4);
}

.dcb-moat-name {
  font-family: var(--font-display);
  font-size: 1.22rem;
  color: var(--dcb-t2);
}

.dcb-moat-item.is-active .dcb-moat-name {
  color: var(--dcb-cream);
}

.dcb-moat-room {
  position: relative;
  margin: 0;
  border-radius: 12px;
  overflow: hidden;
  aspect-ratio: 16 / 10;
  background: var(--dcb-ink-4);
}

.dcb-moat-room img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transform: scale(1.03);
  transition: opacity 0.75s var(--dcb-ease), transform 1.4s var(--dcb-ease);
}

.dcb-moat-room img.is-active {
  opacity: 1;
  transform: scale(1);
}

.dcb-moat-cap {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 2;
  padding: clamp(20px, 4vw, 38px);
  display: grid;
  gap: 7px;
  background: linear-gradient(to top, rgba(10, 10, 11, 0.9), transparent);
  font-size: 0.98rem;
  color: var(--dcb-t2);
  font-weight: 300;
}

/* ============================================================
   6. 360° — synced photospheres (markup kept for script.js)
   ============================================================ */

.dcb-360 {
  position: relative;
  padding-block: var(--dcb-sec);
  background: var(--dcb-ink-2);
  border-block: 1px solid var(--dcb-line);
}

.dcb-360-head {
  display: grid;
  gap: 18px;
  justify-items: start;
  margin-bottom: clamp(32px, 5vh, 56px);
}

/* ============================================================
   7. SHOP THE LOOK — render + the list it produces
   ============================================================ */

.dcb-stl {
  position: relative;
  padding-block: var(--dcb-sec);
  background: var(--dcb-ink);
}

.dcb-stl-head {
  display: grid;
  gap: 18px;
  justify-items: start;
  margin-bottom: clamp(36px, 6vh, 64px);
}

.dcb-stl-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.25fr) minmax(300px, 0.75fr);
  gap: clamp(20px, 3vw, 44px);
  align-items: start;
}

.dcb-stl-frame {
  position: relative;
  margin: 0;
  border-radius: 12px;
  overflow: hidden;
  aspect-ratio: 16 / 10;
  background: var(--dcb-ink-4);
}

.dcb-stl-frame > img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* Marker + its price chip. Both are always visible: the old
   hover-only tooltip meant the section explained nothing on first
   look and nothing at all on touch. */
.dcb-stl-hotspot {
  position: absolute;
  left: var(--x);
  top: var(--y);
  z-index: 3;
  display: flex;
  align-items: center;
  gap: 8px;
  /* Anchor on the DOT, not on the middle of dot + chip: centring
     the whole thing slid the dot left by half the chip's width,
     off the product it is meant to mark. 5.5px = half the dot. */
  transform: translate(-5.5px, -50%);
}

.dcb-stl-dot {
  flex: 0 0 auto;
  position: relative;
  width: 11px;
  height: 11px;
  border-radius: 50%;
  background: var(--dcb-gold-lt);
  box-shadow: 0 0 0 3px rgba(10, 10, 11, 0.55);
}

.dcb-stl-dot::after {
  content: "";
  position: absolute;
  inset: -5px;
  border-radius: 50%;
  border: 1px solid var(--dcb-gold);
  opacity: 0;
  animation: dcb-ping 2.8s var(--dcb-ease) infinite;
}

@keyframes dcb-ping {
  0% { transform: scale(0.7); opacity: 0.7; }
  70% { transform: scale(1.7); opacity: 0; }
  100% { opacity: 0; }
}

.dcb-stl-chip {
  white-space: nowrap;
  padding: 6px 11px;
  border-radius: 999px;
  background: rgba(10, 10, 11, 0.8);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border: 1px solid var(--dcb-gold-dim);
  font-size: 0.68rem;
  font-weight: 500;
  letter-spacing: 0.04em;
  color: var(--dcb-cream);
}

/* --- the list panel --------------------------------------- */

.dcb-stl-panel {
  display: grid;
  gap: 0;
  border: 1px solid var(--dcb-line);
  border-radius: 12px;
  background: var(--dcb-ink-2);
  overflow: hidden;
}

.dcb-stl-panel-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 15px 18px;
  border-bottom: 1px solid var(--dcb-line);
  font-size: 0.64rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--dcb-t3);
}

.dcb-stl-panel-head b {
  font-size: 0.8rem;
  letter-spacing: 0;
  color: var(--dcb-gold-lt);
}

.dcb-stl-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.dcb-stl-list li {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 13px;
  padding: 14px 18px;
  border-bottom: 1px solid var(--dcb-line);
}

.dcb-stl-thumb {
  width: 42px;
  height: 42px;
  border-radius: 7px;
  overflow: hidden;
  background: var(--dcb-ink-4);
}

.dcb-stl-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.dcb-stl-item {
  display: grid;
  gap: 2px;
  min-width: 0;
}

.dcb-stl-item b {
  font-size: 0.88rem;
  font-weight: 500;
  color: var(--dcb-t1);
}

.dcb-stl-item span {
  font-size: 0.68rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--dcb-t4);
}

.dcb-stl-price {
  font-size: 0.84rem;
  font-weight: 500;
  color: var(--dcb-gold-lt);
  white-space: nowrap;
}

.dcb-stl-total {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  padding: 16px 18px;
  background: var(--dcb-ink-3);
}

.dcb-stl-total span {
  font-size: 0.64rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--dcb-t3);
}

.dcb-stl-total b {
  font-family: var(--font-display);
  font-size: 1.5rem;
  font-weight: 400;
  color: var(--dcb-cream);
}

.dcb-stl-disclosure {
  padding: 14px 18px 16px;
  font-size: 0.72rem;
  line-height: 1.5;
  color: var(--dcb-t4);
}

/* ============================================================
   8. STAT ROW
   ============================================================ */

.dcb-stats {
  padding-block: clamp(56px, 9vh, 110px);
  background: var(--dcb-ink);
  border-top: 1px solid var(--dcb-line);
}

.dcb-stats-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: clamp(24px, 4vw, 56px);
}

.dcb-stat {
  display: grid;
  gap: 8px;
  padding-top: 22px;
  border-top: 1px solid var(--dcb-line);
}

.dcb-stat b {
  font-family: var(--font-display);
  font-weight: 300;
  font-size: clamp(2.6rem, 5vw, 4rem);
  line-height: 1;
  letter-spacing: -0.03em;
  color: var(--dcb-cream);
}

.dcb-stat b sup {
  font-size: 0.42em;
  top: -0.7em;
  color: var(--dcb-gold);
}

.dcb-stat p {
  font-size: 0.92rem;
  line-height: 1.55;
  color: var(--dcb-t3);
  font-weight: 300;
  max-width: 30ch;
}

/* ============================================================
   9. CTA band + footer logo bed
   ============================================================ */

.dcb-cta {
  position: relative;
  padding-block: clamp(96px, 16vh, 190px);
  background: var(--dcb-ink-2);
  border-top: 1px solid var(--dcb-line);
  overflow: hidden;
}

.dcb-cta-inner {
  position: relative;
  z-index: 2;
  display: grid;
  gap: 24px;
  justify-items: center;
  text-align: center;
}

.dcb-cta-glow {
  position: absolute;
  inset: auto 0 -40% 0;
  height: 90%;
  background: radial-gradient(50% 60% at 50% 100%, rgba(201, 169, 98, 0.16), transparent 70%);
  pointer-events: none;
}

.dcb-cta .dcb-h2 {
  max-width: 22ch;
  text-align: center;
}

/* The closing shot: the same arches, discs and soft rectangles
   that float behind the hero, now standing in a row either side
   of the wordmark and rising toward it. The page ends on the
   shapes it opened with. The wordmark gets its own clear space
   in the middle instead of sitting on top of a photo.

   (.dcb-bed-disc is the hook home.js animates in; the shape
   itself comes from --ar / --rad, as on .dcb-amb-card.) */
.dcb-bed {
  position: relative;
  margin-top: clamp(48px, 8vh, 96px);
  padding: 28px var(--dcb-gutter, 16px) clamp(28px, 5vh, 56px);
  overflow: hidden;
}

.dcb-bed-row {
  display: flex;
  justify-content: center;
  align-items: flex-end;
  gap: clamp(8px, 1.6vw, 24px);
}

.dcb-bed-disc {
  position: relative;
  flex: 0 0 auto;
  width: var(--w);
  aspect-ratio: var(--ar, 3 / 4);
  border-radius: var(--rad, 18px);
  overflow: hidden;
  box-shadow: 0 30px 70px -24px rgba(0, 0, 0, 0.9);
  animation:
    dcb-amb-drift calc(var(--t, 14s) * 0.5) ease-in-out var(--dl, 0s) infinite alternate,
    dcb-amb-sway calc(var(--t, 14s) * 0.7) ease-in-out var(--dl, 0s) infinite alternate;
  --ax: 3;
  --ay: 10;
  --sw: 1.6;
}

.dcb-bed-disc::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  box-shadow: inset 0 0 0 1px rgba(246, 242, 234, 0.1);
  background: linear-gradient(160deg, rgba(246, 242, 234, 0.1), transparent 38%);
}

.dcb-bed-disc img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  filter: saturate(0.85) brightness(0.8);
}

.dcb-bed-markwrap {
  flex: 0 0 auto;
  align-self: center;
  padding-inline: clamp(12px, 2.4vw, 40px);
}

.dcb-bed-mark {
  display: block;
  width: clamp(150px, 18vw, 240px);
  height: auto;
}

/* Phones: six shapes and a wordmark do not fit on one line, so
   the wordmark takes its own row above them. */
@media (max-width: 680px) {
  .dcb-bed-row {
    flex-wrap: wrap;
    row-gap: 28px;
  }

  .dcb-bed-markwrap {
    order: -1;
    flex-basis: 100%;
    display: grid;
    justify-items: center;
  }
}

@media (prefers-reduced-motion: reduce) {
  .dcb-bed-disc {
    animation: none;
  }
}

/* ============================================================
   10. Overrides for the shared primitives from styles.css
   ============================================================ */

.home-v3 .pricing,
.home-v3 .faq-section {
  background: var(--dcb-ink);
}

.home-v3 .dcb-sec-head {
  display: grid;
  gap: 18px;
  justify-items: start;
  margin-bottom: clamp(40px, 6vh, 72px);
}

/* Header above the list. The previous split put a display heading in
   a ~500px column — where "Before you upload anything" set one word
   per line — and left a tall empty well beneath it once the question
   list ran past the aside. Stacked, the heading gets the full measure
   and there is no void to explain. */
.dcb-faq-grid {
  display: grid;
  gap: clamp(32px, 5vh, 56px);
}

.dcb-faq-aside {
  display: grid;
  gap: 18px;
  justify-items: start;
  max-width: 44ch;
}

/* ------------------------------------------------------------
   Headings in a narrow column
   ------------------------------------------------------------
   .dcb-h2's default size is tuned for a full-width band. Dropped
   into a ~40%-wide column it is far too large for the measure and
   breaks one word per line — Cormorant Light at display sizes is
   much wider per character than it looks.

   The FAQ aside gets its own smaller step plus balanced wrapping,
   sized with enough headroom that the longest word ("anything")
   clears the column at every width rather than only just fitting.
   ------------------------------------------------------------ */
/* Full measure now, so this can simply use the section heading size. */
.dcb-faq-aside .dcb-h2 {
  max-width: 20ch;
  text-wrap: balance;
}

.dcb-faq-aside .dcb-lede {
  max-width: 52ch;
  text-wrap: pretty;
}

/* Same problem, milder: the reel's copy column is wider, so it
   only needs the measure cap lifted off the heading. */
.dcb-reel-copy .dcb-h2 {
  font-size: clamp(2.1rem, 3.8vw, 3.6rem);
  max-width: 100%;
  text-wrap: balance;
}

/* ============================================================
   11. Responsive
   ============================================================ */

@media (max-width: 1000px) {
  .dcb-reel-inner,
  .dcb-how-grid,
  .dcb-moat-stage,
  .dcb-stl-grid {
    grid-template-columns: minmax(0, 1fr);
  }

  .dcb-reel-inner {
    gap: 28px;
  }

  .dcb-reel-copy {
    justify-items: center;
    text-align: center;
  }

  .dcb-reel-copy .dcb-eyebrow::before {
    display: none;
  }

  .dcb-reel-item {
    justify-content: center;
    text-align: center;
  }

  .dcb-reel-item i {
    display: none;
  }

  .dcb-reel-listwrap {
    height: clamp(230px, 36vh, 320px);
  }

  /* One shared frame above four stacked text blocks meant the
     visual had scrolled away by the time you read the steps. Each
     step carries its own clip instead, so the section reads as
     clip-then-caption four times over. */
  .dcb-how-visual {
    display: none;
  }

  .dcb-how-step-media {
    position: relative;
    display: block;
    margin: 0 0 4px;
    aspect-ratio: 16 / 10;
    border-radius: 12px;
    overflow: hidden;
    background: var(--dcb-ink-4);
  }

  .dcb-how-step-media video {
    width: 100%;
    height: 100%;
    object-fit: contain;
    display: block;
  }

  /* The step's own frame now owns the tag, so it positions against
     this figure rather than the shared pinned frame. */
  .dcb-how-step-media .dcb-how-tag {
    left: 12px;
    bottom: 12px;
  }

  .dcb-how-step {
    gap: 12px;
  }

  .dcb-how-steps {
    gap: clamp(48px, 8vh, 72px);
    padding-block: 0;
  }

  .motion-ready .dcb-how-step {
    opacity: 1;
  }

  .dcb-ba-points {
    gap: 24px;
  }
}

@media (max-width: 680px) {
  /* The split-headline move needs horizontal room the phone
     doesn't have, so the hero plays as a straight fade: the
     room still takes over, the words just don't travel.
     The runway is still long enough that the BEFORE → AFTER
     wipe (0.80–0.96 of it) gets ~30vh of scroll on its own, so
     a thumb flick can't skate past it half-done. */
  .dcb-hero {
    height: 290vh;
  }

  .dcb-hl-b {
    white-space: normal;
    flex-wrap: wrap;
  }

  .dcb-reel {
    height: 330vh;
  }

  .dcb-moat-stage {
    gap: 22px;
  }

  .dcb-moat-list {
    grid-auto-flow: column;
    grid-auto-columns: minmax(118px, 1fr);
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    padding-bottom: 8px;
    -webkit-overflow-scrolling: touch;
  }

  .dcb-moat-item {
    flex-direction: column;
    align-items: flex-start;
    scroll-snap-align: start;
  }

  /* The chips would collide at phone width; the list below the
     render carries the same information. */
  .dcb-stl-chip {
    display: none;
  }

  /* Most of this traffic is mobile, so the rest of this block is
     a real layout, not a fallback: one column throughout, touch
     targets at 44px, tightened rhythm. */
  .home-v3 {
    /* The desktop section rhythm is far too generous once
       everything is stacked. */
    --dcb-sec: clamp(72px, 10vh, 112px);
  }

  .dcb-ba-points {
    grid-template-columns: minmax(0, 1fr);
    gap: 20px;
  }

  /* Tabs scroll rather than wrapping into a ragged second row. */
  .dcb-ba-tabs {
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
    margin-inline: calc(var(--dcb-gutter) * -1);
    padding-inline: var(--dcb-gutter);
  }

  .dcb-ba-tabs::-webkit-scrollbar {
    display: none;
  }

  .dcb-ba-tab {
    flex: 0 0 auto;
    min-height: 44px;
  }

  /* Comfortable thumb target for the wipe. */
  .dcb-ba-grip {
    width: 48px;
    height: 48px;
  }

  .dcb-stl-list li {
    padding: 12px 14px;
    gap: 11px;
  }

  .dcb-stl-panel-head,
  .dcb-stl-total,
  .dcb-stl-disclosure {
    padding-inline: 14px;
  }

  .dcb-moat-item {
    min-height: 44px;
  }
}

/* --- Small phones ------------------------------------------- */
@media (max-width: 520px) {
  /* 2.9rem (40.6px) left "Forty-seven rooms you love." running to
     three lines at 320px and pushed the CTA under the fold. */
  .dcb-hero-title {
    font-size: clamp(1.95rem, 9.5vw, 2.8rem);
  }

  .dcb-hero-stack {
    gap: 14px;
  }

  .dcb-hero-sub {
    font-size: 0.95rem;
  }

  .dcb-reel-item {
    font-size: clamp(1.5rem, 8vw, 2.1rem);
  }

  /* The paragraphs are written for a desktop measure; on a phone the
     lead sentence carries the step on its own and the image does the
     rest of the work. */
  .dcb-more {
    display: none;
  }

  .dcb-stat b {
    font-size: clamp(2.2rem, 11vw, 3rem);
  }
}

/* --- Short viewports (landscape phones) ---------------------
   min-height: 560px on a 375px-tall landscape phone makes the
   pinned stage taller than the window, which clips the headline
   and the CTA. Below that height the stage simply tracks the
   viewport instead.
   ------------------------------------------------------------ */
@media (max-height: 600px) {
  .dcb-hero-pin,
  .dcb-reel-stage {
    min-height: 0;
  }
}

/* ============================================================
   12. Reduced motion
   ------------------------------------------------------------
   home.js also checks this and skips binding the scrubs, so the
   rails collapse to a single screen and every element sits in
   its final state.
   ============================================================ */

@media (prefers-reduced-motion: reduce) {
  .dcb-hero,
  .dcb-reel {
    height: auto;
  }

  /* relative, not static, for the same reason as .dcb-how-visual
     above: .dcb-hero-glow, .dcb-reel-bg and .dcb-reel-veil are all
     position:absolute children of these two. */
  .dcb-hero-pin,
  .dcb-reel-stage {
    position: relative;
    height: auto;
    min-height: 0;
    padding-block: var(--dcb-sec);
  }

  .dcb-reveal-media,
  .dcb-scroll-cue,
  .dcb-amb {
    display: none;
  }

  .dcb-reel-listwrap {
    height: auto;
    -webkit-mask-image: none;
    mask-image: none;
  }

  .dcb-reel-list {
    position: static;
    transform: none;
    transition: none;
  }

  .dcb-reel-item {
    height: auto;
    padding-block: 6px;
    color: var(--dcb-t2);
  }

  .dcb-amb-card,
  .dcb-amb-orb,
  .dcb-reel-list,
  .dcb-how-visual video,
  .dcb-ba-pair,
  .dcb-moat-room img {
    transition: none;
  }

  .dcb-scroll-cue i {
    animation: none;
  }

  .dcb-stl-dot::after {
    animation: none;
  }

  .home-v3 [data-dcb-reveal] {
    opacity: 1 !important;
    transform: none !important;
  }
}

/* ============================================================
   PRICING — plan cards, comparison table, credit guide.
   Scoped under .home-v3 .hp-pricing so it wins over the shared
   .pricing-card rules in styles.css (loaded earlier) without
   !important. Hooks kept for script.js / currency.js are listed
   in the markup comment above the grid.
   ============================================================ */
.home-v3 .hp-pricing .pr-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 340px));
  justify-content: center;
  align-items: stretch;
  gap: clamp(14px, 1.6vw, 22px);
  max-width: 100%;
  margin-top: 8px;
}

.home-v3 .hp-pricing .pr-card {
  position: relative;
  flex-direction: column;
  gap: 0;
  padding: 28px 24px 26px;
  border-radius: 22px;
  border: 1px solid var(--dcb-line);
  background: linear-gradient(180deg, var(--dcb-ink-3), var(--dcb-ink-2));
  box-shadow: none;
  transform: none;
  transition: border-color 0.3s ease, transform 0.4s var(--dcb-ease), box-shadow 0.4s ease;
}

.home-v3 .hp-pricing .pr-card:hover {
  border-color: var(--dcb-line-2);
  transform: translateY(-3px);
  box-shadow: 0 24px 50px -24px rgba(0, 0, 0, 0.8);
}

.home-v3 .hp-pricing .pr-featured {
  border-color: rgba(201, 169, 98, 0.55);
  background:
    radial-gradient(120% 60% at 50% 0%, rgba(201, 169, 98, 0.14), transparent 70%),
    linear-gradient(180deg, var(--dcb-ink-3), var(--dcb-ink-2));
  box-shadow: 0 0 0 1px rgba(201, 169, 98, 0.18), 0 30px 70px -30px rgba(201, 169, 98, 0.35);
}

.home-v3 .hp-pricing .pr-featured:hover {
  border-color: var(--dcb-gold);
}

.home-v3 .hp-pricing .pr-badge {
  position: absolute;
  top: -11px;
  left: 24px;
  padding: 4px 11px;
  border-radius: 999px;
  background: var(--dcb-gold);
  color: var(--dcb-ink);
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.home-v3 .hp-pricing .pr-badge-muted {
  background: var(--dcb-ink-4);
  color: var(--dcb-gold);
  border: 1px solid var(--dcb-gold-dim);
}

.home-v3 .hp-pricing .pr-name {
  margin: 0;
  font-family: var(--font-sans);
  font-size: 0.95rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  color: var(--dcb-t1);
}

.home-v3 .hp-pricing .pr-tagline {
  margin: 6px 0 0;
  font-family: var(--font-display);
  font-size: 1.35rem;
  line-height: 1.2;
  color: var(--dcb-t2);
}

.home-v3 .hp-pricing .pr-price {
  display: flex;
  align-items: baseline;
  gap: 2px;
  margin-top: 22px;
  color: var(--dcb-t1);
}

.home-v3 .hp-pricing .pr-price .currency {
  font-size: 1.3rem;
  align-self: flex-start;
  margin-top: 6px;
  color: var(--dcb-t2);
}

.home-v3 .hp-pricing .pr-price .price,
.home-v3 .hp-pricing .pr-amount {
  font-family: var(--font-sans);
  font-size: 2.9rem;
  font-weight: 600;
  letter-spacing: -0.03em;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}

.home-v3 .hp-pricing .pr-per {
  margin-left: 6px;
  font-size: 0.9rem;
  color: var(--dcb-t3);
}

.home-v3 .hp-pricing .pr-sub {
  margin: 8px 0 0;
  font-size: 0.85rem;
  color: var(--dcb-t3);
}

.home-v3 .hp-pricing .pr-sub .pr-each {
  color: var(--dcb-gold);
  font-weight: 600;
}

.home-v3 .hp-pricing .pr-yearly {
  margin: 4px 0 0;
  font-size: 0.82rem;
  color: var(--dcb-t2);
}

.home-v3 .hp-pricing .pr-yearly em {
  font-style: normal;
  color: #7fd6a1;
  font-weight: 600;
}

.home-v3 .hp-pricing .pr-yearly.hidden {
  display: none;
}

.home-v3 .hp-pricing .pr-credits {
  display: flex;
  align-items: baseline;
  gap: 10px;
  margin-top: 20px;
  padding: 14px 16px;
  border-radius: 14px;
  background: rgba(201, 169, 98, 0.08);
  border: 1px solid rgba(201, 169, 98, 0.18);
}

.home-v3 .hp-pricing .pr-credits strong {
  font-family: var(--font-display);
  font-size: 2.1rem;
  font-weight: 500;
  line-height: 1;
  color: var(--dcb-gold);
}

.home-v3 .hp-pricing .pr-credits span {
  font-size: 0.86rem;
  line-height: 1.35;
  color: var(--dcb-t2);
}

.home-v3 .hp-pricing .pr-cta {
  margin-top: 20px;
  border-radius: 999px;
  text-transform: none;
  letter-spacing: 0.01em;
  font-size: 0.92rem;
  font-weight: 600;
  padding: 14px 20px;
}

.home-v3 .hp-pricing .pr-includes {
  margin: 22px 0 10px;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--dcb-t3);
}

.home-v3 .hp-pricing .pr-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 11px;
}

.home-v3 .hp-pricing .pr-list li {
  position: relative;
  padding-left: 26px;
  font-size: 0.9rem;
  line-height: 1.45;
  color: var(--dcb-t2);
}

.home-v3 .hp-pricing .pr-list li b {
  color: var(--dcb-t1);
  font-weight: 600;
}

/* Gold check drawn in CSS — one less inline SVG per row. */
.home-v3 .hp-pricing .pr-list li::before {
  content: "";
  position: absolute;
  left: 2px;
  top: 0.32em;
  width: 15px;
  height: 15px;
  border-radius: 50%;
  background: var(--dcb-gold-dim)
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23c9a962' stroke-width='3.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 12.5l4 4 8-9'/%3E%3C/svg%3E")
    center / 10px no-repeat;
}

.home-v3 .hp-pricing .pr-upgrade-note {
  margin: 22px auto 0;
  text-align: center;
  font-size: 0.85rem;
  color: var(--dcb-t3);
}

/* ── Comparison table ── */
.home-v3 .hp-pricing .pr-compare {
  max-width: 980px;
  margin: 36px auto 0;
  border: 1px solid var(--dcb-line);
  border-radius: 18px;
  background: var(--dcb-ink-2);
  overflow: hidden;
}

.home-v3 .hp-pricing .pr-compare summary {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 18px 20px;
  cursor: pointer;
  list-style: none;
  font-size: 0.92rem;
  font-weight: 600;
  color: var(--dcb-t1);
  transition: background-color 0.2s ease;
}

.home-v3 .hp-pricing .pr-compare summary::-webkit-details-marker {
  display: none;
}

.home-v3 .hp-pricing .pr-compare summary::after {
  content: "";
  width: 8px;
  height: 8px;
  border-right: 1.5px solid var(--dcb-gold);
  border-bottom: 1.5px solid var(--dcb-gold);
  transform: translateY(-2px) rotate(45deg);
  transition: transform 0.3s var(--dcb-ease);
}

.home-v3 .hp-pricing .pr-compare[open] summary::after {
  transform: translateY(2px) rotate(-135deg);
}

.home-v3 .hp-pricing .pr-compare summary:hover {
  background: rgba(246, 242, 234, 0.03);
}

.home-v3 .hp-pricing .pr-table-wrap {
  overflow-x: auto;
  border-top: 1px solid var(--dcb-line);
}

.home-v3 .hp-pricing .pr-table {
  width: 100%;
  min-width: 560px;
  border-collapse: collapse;
  font-size: 0.86rem;
}

.home-v3 .hp-pricing .pr-table th,
.home-v3 .hp-pricing .pr-table td {
  padding: 12px 18px;
  text-align: center;
  border-bottom: 1px solid rgba(246, 242, 234, 0.05);
  color: var(--dcb-t2);
  font-weight: 400;
}

.home-v3 .hp-pricing .pr-table th[scope="row"],
.home-v3 .hp-pricing .pr-table thead th:first-child {
  text-align: left;
  color: var(--dcb-t1);
}

.home-v3 .hp-pricing .pr-table thead th {
  font-size: 0.74rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--dcb-t3);
}

/* Personal is the recommended column; tint it like its card. */
.home-v3 .hp-pricing .pr-table thead th:nth-child(3),
.home-v3 .hp-pricing .pr-table tbody td:nth-child(3) {
  background: rgba(201, 169, 98, 0.05);
}

.home-v3 .hp-pricing .pr-table thead th:nth-child(3) {
  color: var(--dcb-gold);
}

.home-v3 .hp-pricing .pr-table .pr-group th {
  padding-top: 18px;
  text-align: left;
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--dcb-gold);
  background: none;
}

.home-v3 .hp-pricing .pr-table .pr-yes {
  color: var(--dcb-gold);
  font-weight: 600;
}

.home-v3 .hp-pricing .pr-table .pr-no {
  color: var(--dcb-t4);
}

/* ── How credits work ── */
.home-v3 .hp-pricing .pr-credit-guide {
  max-width: 980px;
  margin: 18px auto 0;
  padding: 22px 24px;
  border-radius: 18px;
  border: 1px solid var(--dcb-line);
  background: var(--dcb-ink-2);
}

.home-v3 .hp-pricing .pr-guide-title {
  margin: 0 0 14px;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--dcb-t3);
}

.home-v3 .hp-pricing .pr-guide {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 12px;
}

.home-v3 .hp-pricing .pr-guide li {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 12px 14px;
  border-radius: 12px;
  background: rgba(246, 242, 234, 0.03);
}

.home-v3 .hp-pricing .pr-guide strong {
  font-size: 1rem;
  color: var(--dcb-gold);
}

.home-v3 .hp-pricing .pr-guide span {
  font-size: 0.82rem;
  color: var(--dcb-t2);
}

.home-v3 .hp-pricing .pr-guide-note {
  margin: 14px 0 0;
  font-size: 0.85rem;
  line-height: 1.55;
  color: var(--dcb-t3);
}

.home-v3 .hp-pricing .pr-guide-note strong {
  color: var(--dcb-t1);
}

@media (max-width: 760px) {
  .home-v3 .hp-pricing .pr-grid {
    grid-template-columns: minmax(0, 420px);
    gap: 22px;
  }

  .home-v3 .hp-pricing .pr-guide {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (prefers-reduced-motion: reduce) {
  .home-v3 .hp-pricing .pr-card,
  .home-v3 .hp-pricing .pr-compare summary::after {
    transition: none;
  }

  .home-v3 .hp-pricing .pr-card:hover {
    transform: none;
  }
}
