/* ═══════════════════════════════════════════════════════════════════════
   VegasBusinessAI — "The Call" scroll journey
   Layers on top of styles.css. Owns only the journey acts; every other
   section keeps its existing rules.

   Structure per act:
     .act            tall scroll track (gives the pin its travel)
       .act-stage    position:sticky, 100svh, holds everything visible
         .act-bed    full-bleed video or plate
         .act-scrim  legibility wash + vignette
         .act-body   the content that reads

   Progress is published by journey.js as --p (0..1) on the .act element.
   Everything animated here is transform / opacity / filter only.
   ═══════════════════════════════════════════════════════════════════════ */

:root {
  --act-pad: clamp(20px, 5vw, 64px);
  --stmt: clamp(2.1rem, 5.4vw, 4.9rem);
  --stmt-sm: clamp(1.5rem, 3.4vw, 2.6rem);
  --ease-out: cubic-bezier(.16, 1, .3, 1);
}

/* ─── Track + stage ──────────────────────────────────────────────────── */

.act {
  position: relative;
  --p: 0;
}

.act-stage {
  position: sticky;
  top: 0;
  height: 100svh;
  min-height: 560px;
  overflow: hidden;
  display: grid;
  isolation: isolate;
  /* The site nav is sticky and overlays the top of every pinned stage.
     Reserving its height here keeps act content optically centred in the
     space the reader can actually see. */
  padding-top: 86px;
}

.act-bed {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
}

.act-bed > img,
.act-bed > picture > img,
.act-bed > video,
.act-bed > canvas {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  /* held flat by default; JS adds the drift */
  transform: scale(1.1);
  will-change: transform;
  /* Shallow defocus. Reads as depth of field and keeps code-rendered type at
     full contrast. Plates are now 2048px, so the default is light; acts whose
     generated plate carries incidental signage push it back up (the point
     of the blur there is to make that signage illegible). */
  filter: blur(var(--bed-blur, 1.2px)) saturate(.94) brightness(.88);
}

.act-bed > picture { position: absolute; inset: 0; display: block; }
.act-ring .act-bed { --bed-blur: 2.4px; }
.act-answer .act-bed { --bed-blur: 1.8px; }

/* Scroll-scrubbed footage: a canvas the engine draws one frame into per
   scroll position. Hidden until every frame has decoded, so the poster or
   the looping video stands in and nothing ever flashes. */
.act-seq {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity .6s var(--ease);
}
.act-bed.seq-ready > .act-seq { opacity: 1; }
/* the grade is baked into the frames at extraction, so the canvas carries
   no live filter: a full-viewport blur re-rasterised per frame is the one
   thing that could take this act off 60fps */
.act-bed > canvas { filter: none; }
.act-bed.seq-ready > video { opacity: 0; }

.act-scrim {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background:
    radial-gradient(120% 90% at 50% 45%, transparent 20%, rgba(5, 5, 7, 0.72) 78%),
    linear-gradient(180deg, rgba(5, 5, 7, 0.86) 0%, rgba(5, 5, 7, 0.34) 34%, rgba(5, 5, 7, 0.42) 62%, rgba(5, 5, 7, 0.94) 100%);
}

.act-body {
  position: relative;
  z-index: 2;
  align-self: center;
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--act-pad);
}

/* ─── Shared journey typography ──────────────────────────────────────── */

.act-eyebrow {
  font-family: var(--font-mono);
  font-size: clamp(10px, 1.1vw, 12px);
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--fg-muted);
  margin: 0 0 clamp(18px, 3vw, 30px);
  display: flex;
  align-items: center;
  gap: 12px;
}

.act-place {
  color: var(--fg-faint);
  letter-spacing: .12em;
  text-transform: none;
  font-size: .95em;
}
.act-place::before { content: "/"; margin-right: 12px; color: var(--line-3); }

.threshold-route {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  margin: 0;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--fg-muted);
  opacity: 0;
  animation: rv-in .9s var(--ease-out) 1.1s forwards;
}
.threshold-route i { width: 34px; height: 1px; background: linear-gradient(90deg, transparent, var(--red)); }
@keyframes rv-in { to { opacity: 1; } }

.act-eyebrow::before {
  content: "";
  width: clamp(22px, 4vw, 46px);
  height: 1px;
  background: var(--red);
  flex: none;
}

.act-statement {
  font-family: var(--font-condensed);
  font-weight: 700;
  font-size: var(--stmt);
  line-height: 0.92;
  letter-spacing: -0.015em;
  text-transform: uppercase;
  margin: 0;
  text-wrap: balance;
}

.act-statement .hot { color: var(--red); }
.act-statement .ghost { color: var(--fg-faint); }

.act-lede {
  font-family: var(--font-body);
  font-size: clamp(15px, 1.5vw, 19px);
  line-height: 1.65;
  color: var(--fg-dim);
  max-width: 56ch;
  margin: clamp(20px, 3vw, 32px) 0 0;
}

.act-source {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.08em;
  color: var(--fg-faint);
  margin-top: 18px;
}

.act-source a { color: var(--fg-muted); text-underline-offset: 3px; }
.act-source a:hover { color: var(--red); }

/* Data figures use mono, per the house rule that mono is for DATA only. */
.act-figure {
  font-family: var(--font-mono);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  line-height: 1;
}

/* ─── Reveal primitive ───────────────────────────────────────────────── */

.rv {
  opacity: 0;
  transform: translate3d(0, 26px, 0);
  transition: opacity .8s var(--ease-out), transform .9s var(--ease-out);
}

.act-stage.is-live .rv { opacity: 1; transform: none; }
.act-stage.is-live .rv:nth-child(2) { transition-delay: .08s; }
.act-stage.is-live .rv:nth-child(3) { transition-delay: .16s; }
.act-stage.is-live .rv:nth-child(4) { transition-delay: .24s; }

/* ═══ ACT 0 — THRESHOLD ══════════════════════════════════════════════
   First thing anyone sees, so it is scaled to carry the room: full display
   type, a mark that reads at distance, and a signal dropping in from the
   top before anything else resolves. */

.act-threshold { height: 115svh; }

.act-threshold .act-bed img { transform: scale(1.12); }
.act-threshold .act-bed { --bed-blur: 0.6px; }

.threshold-lockup {
  position: relative;
  display: grid;
  justify-items: center;
  text-align: center;
  gap: clamp(16px, 2.4vw, 26px);
}

/* a line arriving from above: the signal, before the brand */
.threshold-drop {
  position: absolute;
  top: clamp(-70px, -7vh, -40px);
  left: 50%;
  width: 1px;
  height: 0;
  background: linear-gradient(180deg, transparent, var(--red));
  animation: drop-in .9s var(--ease-out) .05s forwards;
}

@keyframes drop-in {
  to { height: clamp(38px, 6vh, 66px); }
}

.threshold-mark {
  width: clamp(190px, 27vw, 340px);
  height: auto;
  opacity: 0;
  filter: drop-shadow(0 0 54px rgba(240, 75, 87, 0.45));
  animation: threshold-in 1.4s var(--ease-out) .5s forwards;
}

@keyframes threshold-in {
  from { opacity: 0; transform: translate3d(0, 18px, 0) scale(.93); filter: blur(14px) drop-shadow(0 0 0 transparent); }
  to   { opacity: 1; transform: none; filter: blur(0) drop-shadow(0 0 54px rgba(240, 75, 87, 0.45)); }
}

.threshold-h {
  margin: 0;
  font-family: var(--font-condensed);
  font-weight: 700;
  font-size: clamp(2.4rem, 6.6vw, 6.2rem);
  line-height: 0.92;
  letter-spacing: -0.015em;
  text-transform: uppercase;
  text-wrap: balance;
  opacity: 0;
  animation: threshold-rise 1.1s var(--ease-out) .95s forwards;
}

@keyframes threshold-rise {
  from { opacity: 0; transform: translate3d(0, 22px, 0); }
  to   { opacity: 1; transform: none; }
}

.threshold-tagline {
  font-family: var(--font-mono);
  font-size: clamp(10px, 1.2vw, 13px);
  letter-spacing: 0.42em;
  text-transform: uppercase;
  color: var(--fg-muted);
  margin: 0;
  opacity: 0;
  animation: threshold-fade 1.1s var(--ease-out) 1.35s forwards;
}

.threshold-meta {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: clamp(12px, 2.4vw, 30px);
  list-style: none;
  margin: clamp(6px, 1.4vw, 14px) 0 0;
  padding: 0;
  opacity: 0;
  animation: threshold-fade 1.1s var(--ease-out) 1.6s forwards;
}

.threshold-meta li {
  position: relative;
  font-family: var(--font-mono);
  font-size: clamp(9px, 1vw, 11px);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--fg-faint);
}

.threshold-meta li + li::before {
  content: "";
  position: absolute;
  left: clamp(-7px, -1.2vw, -15px);
  top: 50%;
  width: 3px;
  height: 3px;
  border-radius: 50%;
  background: var(--red);
  transform: translateY(-50%);
}

.threshold-cue {
  position: absolute;
  left: 50%;
  bottom: clamp(26px, 5vh, 52px);
  transform: translateX(-50%);
  z-index: 3;
  display: grid;
  justify-items: center;
  gap: 10px;
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--fg-faint);
  opacity: 0;
  animation: threshold-fade 1s var(--ease-out) 2s forwards;
}

.threshold-cue span::after {
  content: "";
  display: block;
  width: 1px;
  height: 44px;
  margin: 8px auto 0;
  background: linear-gradient(180deg, var(--fg-faint), transparent);
  animation: cue-slide 2.4s ease-in-out infinite;
}

@keyframes threshold-fade { to { opacity: 1; } }
@keyframes cue-slide {
  0%, 100% { transform: scaleY(.4); transform-origin: top; opacity: .4; }
  50%      { transform: scaleY(1);  transform-origin: top; opacity: 1; }
}

/* ═══ ACT 1 — THE RING ═══════════════════════════════════════════════ */

.act-ring { height: 210svh; }

.ring-grid {
  display: grid;
  gap: clamp(28px, 5vw, 56px);
  align-items: center;
  grid-template-columns: 1fr;
}

@media (min-width: 900px) {
  .ring-grid { grid-template-columns: minmax(0, 1.25fr) minmax(0, .75fr); }
}

/* concentric pulse glyph = a phone ringing */
.ring-pulse {
  position: relative;
  width: clamp(150px, 21vw, 240px);
  aspect-ratio: 1;
  justify-self: center;
  display: grid;
  place-items: center;
}

.ring-pulse i {
  position: absolute;
  inset: 0;
  border: 1px solid var(--red);
  border-radius: 50%;
  opacity: 0;
  animation: ring-out 2.6s cubic-bezier(.2, .6, .3, 1) infinite;
}

.ring-pulse i:nth-child(2) { animation-delay: .55s; }
.ring-pulse i:nth-child(3) { animation-delay: 1.1s; }

.ring-pulse svg {
  width: 34%;
  height: auto;
  color: var(--red);
  filter: drop-shadow(0 0 22px rgba(240, 75, 87, .55));
  animation: ring-shake 2.6s ease-in-out infinite;
}

@keyframes ring-out {
  0%   { transform: scale(.34); opacity: 0; }
  22%  { opacity: .85; }
  100% { transform: scale(1); opacity: 0; }
}

@keyframes ring-shake {
  0%, 58%, 100% { transform: rotate(0); }
  62% { transform: rotate(-11deg); }
  66% { transform: rotate(9deg); }
  70% { transform: rotate(-6deg); }
  74% { transform: rotate(0); }
}

.ring-counter {
  display: flex;
  align-items: baseline;
  gap: 14px;
  margin: clamp(16px, 2.6vw, 26px) 0 0;
}

.ring-counter b {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-weight: 500;
  font-size: clamp(2.6rem, 6vw, 4.6rem);
  line-height: 1;
  color: var(--fg);
}

.ring-counter span {
  font-family: var(--font-body);
  font-size: clamp(13px, 1.4vw, 16px);
  color: var(--fg-muted);
  max-width: 22ch;
  line-height: 1.45;
}

/* ═══ ACT 2 — THE VOID ═══════════════════════════════════════════════ */

.act-void { height: 230svh; }

/* --decay (0..1) is written by journey.js and drives the signal loss */
.act-void .act-stage { --decay: 0; }

.void-statement {
  position: relative;
  filter: blur(calc(var(--decay) * 3px));
  opacity: calc(1 - var(--decay) * 0.45);
}

/* chromatic split that widens as the signal dies */
.void-statement::before,
.void-statement::after {
  content: attr(data-text);
  position: absolute;
  inset: 0;
  pointer-events: none;
  /* data-text carries an encoded newline so the ghosts break exactly where
     the real headline breaks. Without this they render as one long line and
     sit off-register. */
  white-space: pre-line;
  opacity: calc(var(--decay) * 0.55);
}

.void-statement::before {
  color: var(--red);
  transform: translate3d(calc(var(--decay) * -10px), 0, 0);
  mix-blend-mode: screen;
}

.void-statement::after {
  color: #2BD8D8;
  transform: translate3d(calc(var(--decay) * 10px), 0, 0);
  mix-blend-mode: screen;
}

.void-bars {
  display: flex;
  align-items: flex-end;
  gap: 6px;
  height: 46px;
  margin: clamp(24px, 4vw, 38px) 0 0;
}

.void-bars i {
  width: 8px;
  background: var(--fg-faint);
  transition: background .4s linear, opacity .4s linear;
}

.void-bars i:nth-child(1) { height: 26%; }
.void-bars i:nth-child(2) { height: 46%; }
.void-bars i:nth-child(3) { height: 66%; }
.void-bars i:nth-child(4) { height: 84%; }
.void-bars i:nth-child(5) { height: 100%; }
.void-bars i.dead { background: var(--red-deep); opacity: .35; }

.void-stat {
  display: grid;
  gap: 6px;
  margin-top: clamp(26px, 4vw, 40px);
}

.void-stat b {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-weight: 500;
  font-size: clamp(3.4rem, 9vw, 6.4rem);
  line-height: .9;
  color: var(--red);
}

.void-stat span {
  font-family: var(--font-body);
  font-size: clamp(14px, 1.5vw, 17px);
  color: var(--fg-dim);
  max-width: 44ch;
}

/* ═══ ACT 3 — THE ANSWER ═════════════════════════════════════════════
   The product, on screen. A phone rings, gets answered, fills with the real
   transcript as chat bubbles, books the job and fires the confirmation SMS.
   The transcript is still one <dl> in the DOM: crawlable, JS-free, and now
   also the phone's screen content. No duplicated copy. */

.act-answer { height: 380svh; }

.answer-grid {
  display: grid;
  gap: clamp(24px, 4vw, 64px);
  grid-template-columns: 1fr;
  align-items: center;
}

@media (min-width: 980px) {
  .answer-grid { grid-template-columns: minmax(0, 1fr) minmax(0, 380px); }
}

.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ── the device ── */

.phone-col { display: grid; place-items: center; }

.phone {
  position: relative;
  height: min(66svh, 660px);
  aspect-ratio: 9 / 19;
}

.phone-glow {
  position: absolute;
  inset: -14%;
  background: radial-gradient(closest-side, rgba(240,75,87,0.24), transparent 72%);
  filter: blur(22px);
  opacity: 0;
  transition: opacity 1.2s var(--ease-out);
}

.act-stage.is-live .phone-glow { opacity: 1; }

/* Pinned to the phone box rather than sized by its own content: the screen's
   height:100% has to resolve against a definite height, or the transcript's
   natural length inflates the whole device. */
.phone-frame {
  position: absolute;
  inset: 0;
  border-radius: 40px;
  padding: 9px;
  background: linear-gradient(160deg, #26262e 0%, #0a0a0d 26%, #08080b 74%, #1d1d24 100%);
  box-shadow:
    0 0 0 1px rgba(255,255,255,0.09),
    0 40px 80px -20px rgba(0,0,0,0.9),
    inset 0 1px 0 rgba(255,255,255,0.14);
}

.phone-screen {
  position: relative;
  height: 100%;
  border-radius: 32px;
  overflow: hidden;
  background: radial-gradient(120% 80% at 50% 0%, #15121a 0%, #08080b 62%);
  display: flex;
  flex-direction: column;
  isolation: isolate;
}

/* status bar: a small realism tax that pays for itself */
/* Above the ringing overlay: a phone's status bar does not disappear when a
   call comes in, and keeping it visible sells the device. */
.phone-status {
  position: relative;
  z-index: 6;
  flex: none;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 12px 20px 6px;
  font-family: var(--font-mono);
  font-size: 9.5px;
  letter-spacing: .06em;
  color: var(--fg-muted);
}

.ps-right { display: inline-flex; gap: 5px; align-items: center; }
.ps-right i { display: block; background: var(--fg-muted); border-radius: 1px; }
.ps-sig  { width: 12px; height: 8px; clip-path: polygon(0 100%,25% 100%,25% 62%,0 62%,0 100%,37% 100%,37% 38%,62% 38%,62% 100%,75% 100%,75% 14%,100% 14%,100% 100%); }
.ps-wifi { width: 10px; height: 8px; clip-path: polygon(50% 100%, 0 34%, 12% 22%, 50% 60%, 88% 22%, 100% 34%); }
.ps-bat  { width: 15px; height: 8px; border-radius: 2px; }

/* ── incoming call ── */

.call-incoming {
  position: absolute;
  inset: 0;
  z-index: 4;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 24px;
  text-align: center;
  background: radial-gradient(90% 60% at 50% 34%, rgba(240,75,87,0.16), transparent 70%), #08080b;
  transition: opacity .5s var(--ease-out), transform .6s var(--ease-out), filter .5s var(--ease-out);
}

.phone.answered .call-incoming {
  opacity: 0;
  transform: scale(1.06);
  filter: blur(6px);
  pointer-events: none;
}

.ci-label {
  margin: 0;
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: .28em;
  text-transform: uppercase;
  color: var(--red);
}

.ci-num {
  margin: 0;
  font-family: var(--font-condensed);
  font-weight: 700;
  font-size: clamp(1.3rem, 3.6vw, 1.8rem);
  letter-spacing: .01em;
  color: var(--fg);
}

.ci-loc { margin: 0; font-size: 12px; color: var(--fg-muted); }

.ci-avatar {
  position: relative;
  width: 88px; height: 88px;
  margin: 12px 0 18px;
  display: grid;
  place-items: center;
}

.ci-avatar i {
  position: absolute;
  inset: 0;
  border: 1px solid var(--red);
  border-radius: 50%;
  opacity: 0;
  animation: ci-ring 2.4s cubic-bezier(.2,.6,.3,1) infinite;
}

.ci-avatar i:nth-child(2) { animation-delay: .5s; }
.ci-avatar i:nth-child(3) { animation-delay: 1s; }

.ci-avatar svg {
  width: 30px; height: 30px;
  color: var(--red);
  filter: drop-shadow(0 0 14px rgba(240,75,87,.6));
  animation: ci-shake 2.4s ease-in-out infinite;
}

@keyframes ci-ring {
  0%   { transform: scale(.44); opacity: 0; }
  22%  { opacity: .8; }
  100% { transform: scale(1.12); opacity: 0; }
}

@keyframes ci-shake {
  0%, 62%, 100% { transform: rotate(0); }
  66% { transform: rotate(-12deg); }
  70% { transform: rotate(10deg); }
  74% { transform: rotate(-5deg); }
  78% { transform: rotate(0); }
}

.ci-actions { display: flex; gap: 44px; }

.ci-btn {
  width: 44px; height: 44px;
  border-radius: 50%;
  position: relative;
}

.ci-decline { background: #3a1015; }
.ci-accept  { background: #1d6b3a; box-shadow: 0 0 0 0 rgba(46,190,110,.5); animation: ci-pulse 2.4s ease-out infinite; }

.ci-btn::after {
  content: "";
  position: absolute;
  inset: 0;
  margin: auto;
  width: 16px; height: 16px;
  background: currentColor;
  color: #fff;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M6.6 10.8c1.4 2.8 3.8 5.1 6.6 6.6l2.2-2.2c.3-.3.7-.4 1-.2 1.1.4 2.3.6 3.6.6.6 0 1 .4 1 1V20c0 .6-.4 1-1 1-9.4 0-17-7.6-17-17 0-.6.4-1 1-1h3.5c.6 0 1 .4 1 1 0 1.2.2 2.4.6 3.6.1.4 0 .8-.3 1z'/%3E%3C/svg%3E") center / contain no-repeat;
          mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M6.6 10.8c1.4 2.8 3.8 5.1 6.6 6.6l2.2-2.2c.3-.3.7-.4 1-.2 1.1.4 2.3.6 3.6.6.6 0 1 .4 1 1V20c0 .6-.4 1-1 1-9.4 0-17-7.6-17-17 0-.6.4-1 1-1h3.5c.6 0 1 .4 1 1 0 1.2.2 2.4.6 3.6.1.4 0 .8-.3 1z'/%3E%3C/svg%3E") center / contain no-repeat;
}

.ci-decline::after { transform: rotate(135deg); }

@keyframes ci-pulse {
  0%   { box-shadow: 0 0 0 0 rgba(46,190,110,.45); }
  70%  { box-shadow: 0 0 0 16px rgba(46,190,110,0); }
  100% { box-shadow: 0 0 0 0 rgba(46,190,110,0); }
}

/* ── live call ── */

.call-live {
  position: relative;
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  opacity: 0;
  transition: opacity .6s var(--ease-out) .12s;
}

.phone.answered .call-live { opacity: 1; }

.call-head {
  flex: none;
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 8px 18px 12px;
  border-bottom: 1px solid rgba(255,255,255,0.07);
}

.ch-dot {
  width: 7px; height: 7px;
  border-radius: 50%;
  background: #2EBE6E;
  flex: none;
  box-shadow: 0 0 0 0 rgba(46,190,110,.6);
  animation: ci-pulse 2s ease-out infinite;
}

.ch-name {
  flex: 1;
  min-width: 0;
  display: grid;
  line-height: 1.2;
}

.ch-name b,
.ch-name em {
  display: block;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.ch-name b {
  font-family: var(--font-body);
  font-size: 12px;
  font-weight: 600;
  color: var(--fg);
}

.ch-name em {
  font-style: normal;
  font-family: var(--font-mono);
  font-size: 8.5px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--fg-faint);
  margin-top: 2px;
}

.call-timer {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 11px;
  color: var(--red);
  flex: none;
}

/* ── transcript as the phone's screen ── */

.transcript {
  flex: 1;
  min-height: 0;
  margin: 0;
  padding: 14px 14px 18px;
  display: flex;
  flex-direction: column;
  gap: 9px;
  overflow: hidden;
  mask-image: linear-gradient(180deg, transparent 0, #000 9%, #000 82%, transparent 100%);
}

.transcript-line {
  display: block;
  max-width: 84%;
  opacity: 0;
  transform: translate3d(0, 12px, 0) scale(.96);
  transition: opacity .42s var(--ease-out), transform .42s var(--ease-out);
}

.transcript-line.is-said { opacity: 1; transform: none; }

.transcript-line dd {
  margin: 0;
  font-family: var(--font-body);
  font-size: 12.5px;
  line-height: 1.45;
  padding: 9px 12px;
  border-radius: 15px;
}

.transcript-line[data-who="caller"] { align-self: flex-start; }
.transcript-line[data-who="caller"] dd {
  background: rgba(255,255,255,0.075);
  color: var(--fg-dim);
  border-bottom-left-radius: 5px;
}

.transcript-line[data-who="agent"] { align-self: flex-end; }
.transcript-line[data-who="agent"] dd {
  background: linear-gradient(158deg, #C42230, #8E121C);
  color: #fff;
  border-bottom-right-radius: 5px;
  box-shadow: 0 6px 16px -8px rgba(240,75,87,.7);
}

.transcript-line[data-who="demo"] { align-self: center; max-width: 94%; }
.transcript-line[data-who="demo"] dd {
  background: none;
  padding: 4px 2px;
  text-align: center;
  font-family: var(--font-mono);
  font-size: 9.5px;
  line-height: 1.5;
  letter-spacing: .02em;
  color: var(--fg-faint);
}

/* ── booking card ── */

.booking-card {
  position: absolute;
  left: 12px; right: 12px; bottom: 12px;
  z-index: 3;
  padding: 13px 15px;
  border: 1px solid rgba(240,75,87,0.45);
  border-radius: 12px;
  background: linear-gradient(160deg, rgba(28,12,15,0.97), rgba(10,8,10,0.97));
  box-shadow: 0 20px 40px -18px rgba(0,0,0,.95);
  backdrop-filter: blur(6px);
  transform: translate3d(0, 150%, 0);
  opacity: 0;
  transition: transform .7s var(--ease-out), opacity .5s var(--ease-out);
}

.booking-card.show { transform: none; opacity: 1; }

.bk-label {
  margin: 0 0 3px;
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--red);
}

.bk-when {
  margin: 0 0 7px;
  font-family: var(--font-condensed);
  font-weight: 700;
  font-size: 1.25rem;
  letter-spacing: .01em;
  color: var(--fg);
}

.booking-card ul { margin: 0; padding: 0; list-style: none; display: grid; gap: 3px; }
.booking-card li { font-size: 11px; color: var(--fg-muted); line-height: 1.35; }

/* ── confirmation SMS ── */

.sms-toast {
  position: absolute;
  left: 12px; right: 12px; top: 44px;
  z-index: 5;
  display: grid;
  gap: 3px;
  padding: 11px 13px;
  border-radius: 13px;
  background: rgba(30,30,36,0.93);
  border: 1px solid rgba(255,255,255,0.12);
  box-shadow: 0 18px 34px -16px rgba(0,0,0,.95);
  backdrop-filter: blur(10px);
  transform: translate3d(0, -170%, 0);
  opacity: 0;
  transition: transform .65s var(--ease-out), opacity .4s var(--ease-out);
}

.sms-toast.show { transform: none; opacity: 1; }
.sms-toast b { font-size: 11.5px; color: var(--fg); font-weight: 600; }
.sms-toast span { font-size: 11px; color: var(--fg-muted); line-height: 1.4; }

/* ── audio control ── */

.audio-bar {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-top: clamp(20px, 3vw, 30px);
  flex-wrap: wrap;
}

.audio-toggle {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 12px 20px;
  border: 1px solid var(--red);
  background: rgba(240, 75, 87, .08);
  color: var(--fg);
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: .18em;
  text-transform: uppercase;
  border-radius: var(--radius);
  cursor: pointer;
  transition: background .25s var(--ease), transform .25s var(--ease);
}

.audio-toggle:hover { background: rgba(240, 75, 87, .18); }
.audio-toggle:active { transform: translateY(1px); }
.audio-toggle svg { width: 15px; height: 15px; }
.audio-toggle[data-playing] svg { transform: scaleX(.85); }

.audio-note {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--fg-faint);
}

.ribbon-wrap {
  position: relative;
  width: 100%;
  aspect-ratio: 6 / 1;
  max-height: 96px;
  margin-top: clamp(16px, 2.4vw, 24px);
  display: grid;
  place-items: center;
}

.ribbon-wrap canvas { width: 100%; height: 100%; display: block; }

/* ═══ ACT 4 — THE MACHINE ════════════════════════════════════════════
   The call record assembling itself, field by field, then routing. */

.act-machine { height: 210svh; }
.act-machine .act-stage { background: var(--bg); }

.machine-wrap {
  display: grid;
  gap: clamp(24px, 4vw, 56px);
  grid-template-columns: 1fr;
  align-items: center;
}

@media (min-width: 900px) {
  .machine-wrap { grid-template-columns: minmax(0, 1fr) minmax(0, 440px); }
}

.record {
  position: relative;
  border: 1px solid var(--line-2);
  border-radius: var(--radius-lg);
  background:
    linear-gradient(180deg, rgba(255,255,255,0.03), transparent 120px),
    var(--bg-elev);
  overflow: hidden;
  box-shadow: 0 30px 60px -30px rgba(0,0,0,.9);
}

.record-head {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 13px 18px;
  border-bottom: 1px solid var(--line);
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: .2em;
  text-transform: uppercase;
}

.rec-live {
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--red);
  animation: ci-pulse 2s ease-out infinite;
  box-shadow: 0 0 0 0 rgba(240,75,87,.6);
}

.rec-title { color: var(--fg-dim); flex: 1; }
.rec-id { color: var(--fg-faint); }

/* the scan line that walks the card as fields land */
.record-scan {
  position: absolute;
  left: 0; right: 0;
  top: 0;
  height: 2px;
  background: linear-gradient(90deg, transparent, var(--red), transparent);
  opacity: 0;
  transform: translate3d(0, 0, 0);
  pointer-events: none;
  z-index: 2;
}

.record.scanning .record-scan { opacity: .85; }

.record-fields { margin: 0; padding: 6px 18px; display: grid; }

.rf {
  display: grid;
  grid-template-columns: clamp(84px, 30%, 116px) 1fr;
  gap: 14px;
  align-items: baseline;
  padding: 12px 0;
  border-bottom: 1px dashed rgba(255,255,255,0.07);
}

.rf:last-child { border-bottom: none; }

.rf dt {
  font-family: var(--font-mono);
  font-size: 9.5px;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--fg-faint);
  transition: color .4s var(--ease);
}

.rf.filled dt { color: var(--red); }

.rf dd {
  margin: 0;
  position: relative;
  font-family: var(--font-body);
  font-size: clamp(13px, 1.35vw, 15px);
  color: var(--fg);
  min-height: 1.3em;
}

/* value wipes in, which reads as the field being written */
.rf dd span {
  display: inline-block;
  clip-path: inset(0 100% 0 0);
  opacity: .35;
  transition: clip-path .55s var(--ease-out), opacity .3s linear;
}

.rf.filled dd span { clip-path: inset(0 0 0 0); opacity: 1; }

/* caret sitting at the write head until the field lands */
.rf dd::after {
  content: "";
  position: absolute;
  left: 0; top: .15em;
  width: 7px; height: 1.05em;
  background: var(--red);
  opacity: 0;
  transition: opacity .2s linear;
}

.rf.writing dd::after { opacity: .9; animation: caret 1s steps(2) infinite; }

@keyframes caret { 50% { opacity: .15; } }

.record-routes {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  padding: 14px 18px 18px;
  border-top: 1px solid var(--line);
}

.route {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 7px 11px;
  border: 1px solid var(--line-2);
  border-radius: 2px;
  font-family: var(--font-mono);
  font-size: 9.5px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--fg-faint);
  transition: color .4s var(--ease), border-color .4s var(--ease), background .4s var(--ease), box-shadow .4s var(--ease);
}

.route svg {
  width: 12px; height: 12px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linejoin: round;
}

.route.lit {
  color: var(--fg);
  border-color: var(--red);
  background: rgba(240,75,87,0.09);
  box-shadow: 0 0 18px -6px rgba(240,75,87,.7);
}

.machine-clock {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: clamp(1.8rem, 4.4vw, 3rem);
  color: var(--red);
  line-height: 1;
  margin-top: clamp(16px, 2.4vw, 24px);
}

/* ═══ ACT 5 — THE ROOM ═══════════════════════════════════════════════ */

.act-room { height: 210svh; }

.room-body { max-width: 62ch; }

.room-list {
  list-style: none;
  padding: 0;
  margin: clamp(22px, 3vw, 34px) 0 0;
  display: grid;
  gap: 12px;
}

.room-list li {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 12px;
  align-items: start;
  font-family: var(--font-body);
  font-size: clamp(14px, 1.4vw, 16px);
  color: var(--fg-dim);
}

.room-list li::before {
  content: "";
  width: 6px;
  height: 6px;
  margin-top: 9px;
  background: var(--red);
  transform: rotate(45deg);
}

/* ═══ ACT 8 — THE CALL BACK ══════════════════════════════════════════ */

.act-callback { height: 170svh; }

.callback-body { text-align: center; display: grid; justify-items: center; }

.callback-number {
  display: inline-flex;
  align-items: center;
  gap: 14px;
  margin-top: clamp(24px, 4vw, 36px);
  font-family: var(--font-condensed);
  font-weight: 700;
  font-size: clamp(2.2rem, 6.4vw, 4.4rem);
  letter-spacing: .01em;
  color: var(--fg);
  text-decoration: none;
  padding: 14px clamp(20px, 4vw, 38px);
  border: 1px solid var(--line-3);
  border-radius: var(--radius);
  transition: border-color .3s var(--ease), background .3s var(--ease), transform .3s var(--ease);
}

.callback-number:hover {
  border-color: var(--red);
  background: rgba(240, 75, 87, .08);
  transform: translateY(-2px);
}

.callback-number svg { width: .58em; height: .58em; color: var(--red); flex: none; }

.callback-alt {
  margin-top: clamp(18px, 2.6vw, 26px);
  font-family: var(--font-body);
  font-size: 15px;
  color: var(--fg-muted);
}

.callback-alt a { color: var(--fg-dim); text-underline-offset: 3px; }
.callback-alt a:hover { color: var(--red); }

/* ═══ Route map ══════════════════════════════════════════════════════
   The drive, drawn down the right edge: a track, a red line that fills as
   you travel, and a named stop per act. Every stop is a real button. */

.drive {
  position: fixed;
  right: clamp(12px, 1.8vw, 28px);
  top: 50%;
  transform: translateY(-50%);
  z-index: 40;
  display: grid;
  gap: clamp(22px, 4.2vh, 40px);
  padding-right: 3px;
}

.drive-track {
  position: absolute;
  right: 8px;
  top: 6px;
  bottom: 6px;
  width: 1px;
  background: var(--line-2);
}
.drive-track i {
  position: absolute;
  inset: 0;
  background: var(--red);
  transform: scaleY(0);
  transform-origin: 50% 0;
  will-change: transform;
}

.drive-stop {
  all: unset;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 14px;
  cursor: pointer;
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--fg-muted);
  white-space: nowrap;
}
.drive-stop span {
  opacity: 0;
  transform: translateX(6px);
  transition: opacity .3s var(--ease), transform .3s var(--ease), color .3s var(--ease);
}
.drive-stop::after {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--bg);
  border: 1px solid var(--line-3);
  box-shadow: 0 0 0 4px var(--bg);
  transition: background .3s var(--ease), border-color .3s var(--ease), transform .3s var(--ease);
  margin-right: 2px;
}
.drive:hover .drive-stop span,
.drive-stop:focus-visible span,
.drive-stop.on span { opacity: 1; transform: none; }
.drive-stop:hover span { color: var(--fg); }
.drive-stop.on { color: var(--fg); }
.drive-stop.on::after,
.drive-stop.done::after { background: var(--red); border-color: var(--red); }
.drive-stop.on::after { transform: scale(1.35); box-shadow: 0 0 0 4px var(--bg), 0 0 18px rgba(240, 75, 87, .55); }
.drive-stop:focus-visible::after { outline: 2px solid var(--red); outline-offset: 3px; }

/* Phones: a single line across the top of the viewport, under the nav. */
.drive-bar {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 2px;
  z-index: 60;
  background: var(--red);
  transform: scaleX(0);
  transform-origin: 0 50%;
  will-change: transform;
  pointer-events: none;
}

@media (max-width: 860px) { .drive { display: none; } }
@media (min-width: 861px) { .drive-bar { display: none; } }

/* ═══ Reduced motion / no-JS ═════════════════════════════════════════ */

@media (prefers-reduced-motion: reduce) {
  .act { height: auto !important; }
  .act-stage {
    position: static;
    height: auto;
    min-height: 0;
    padding-block: clamp(64px, 12vh, 132px);
  }
  .act-bed img,
  .act-bed > video,
  .act-bed > canvas { transform: none; }
  .act-seq { display: none; }
  .rv { opacity: 1; transform: none; transition: none; }
  .ring-pulse i, .ring-pulse svg, .threshold-cue span::after { animation: none; }
  .threshold-mark, .threshold-tagline, .threshold-cue,
  .threshold-h, .threshold-meta { opacity: 1; animation: none; }
  .threshold-drop { display: none; }
  .void-statement { filter: none; opacity: 1; }
  .void-statement::before, .void-statement::after { display: none; }
  .transcript { max-height: none; mask-image: none; }
  .transcript-line { opacity: 1; transform: none; }
  .machine-diagram .wire { stroke-dashoffset: 0; }
  .drive, .drive-bar { display: none; }
}

/* No JS: acts must still read as a normal stacked document. */
.no-js .act { height: auto; }
.no-js .act-stage { position: static; height: auto; min-height: 0; padding-block: clamp(64px, 12vh, 132px); }
.no-js .rv { opacity: 1; transform: none; }
.no-js .threshold-mark,
.no-js .threshold-h,
.no-js .threshold-tagline,
.no-js .threshold-meta,
.no-js .threshold-cue { opacity: 1; animation: none; }
.no-js .threshold-drop { display: none; }
.no-js .transcript { max-height: none; mask-image: none; }
.no-js .transcript-line { opacity: 1; transform: none; }
.no-js .machine-diagram .wire { stroke-dashoffset: 0; }
.no-js .drive, .no-js .drive-bar { display: none; }

/* ═══ Small screens ══════════════════════════════════════════════════ */

@media (max-width: 720px) {
  .threshold-route { justify-content: center; text-align: center; font-size: 10px; letter-spacing: .16em; }
  .threshold-route i { display: none; }
  .act-ring { height: 180svh; }
  .act-void { height: 195svh; }
  .act-answer { height: 300svh; }
  .act-machine { height: 260svh; }
  .act-room { height: 180svh; }
  .act-callback { height: 155svh; }
  .act-lede { font-size: 14.5px; line-height: 1.55; }

  /* Act 3 on a phone: the device is the act. The waveform is decorative and
     is the first thing to go; the disclosure copy is not negotiable, so the
     savings come from type size and the device itself. */
  .ribbon-wrap { display: none; }
  .answer-copy .act-lede { font-size: 13px; line-height: 1.5; margin-top: 16px; }
  .act-answer .act-statement { font-size: clamp(1.9rem, 8.4vw, 2.6rem); }
  .audio-bar { margin-top: 16px; gap: 10px; }
  .audio-toggle { padding: 10px 16px; font-size: 10px; }
  .phone { height: min(45svh, 400px); }
  .phone-frame { border-radius: 30px; padding: 7px; }
  .phone-screen { border-radius: 24px; }
  .transcript { padding: 10px 10px 14px; gap: 7px; }
  .transcript-line dd { font-size: 11.5px; padding: 7px 10px; }

  /* On a 400px device the overlays have to stay overlays: at desktop sizing
     they collide with each other and bury the transcript underneath. */
  .booking-card { left: 8px; right: 8px; bottom: 8px; padding: 9px 11px; border-radius: 10px; }
  .bk-label { font-size: 8px; letter-spacing: .16em; }
  .bk-when { font-size: 1.02rem; margin-bottom: 5px; }
  .booking-card li { font-size: 9.5px; line-height: 1.3; }
  .sms-toast { left: 8px; right: 8px; top: 34px; padding: 8px 10px; border-radius: 10px; }
  .sms-toast b { font-size: 10px; }
  .sms-toast span { font-size: 9.5px; line-height: 1.35; }
  .call-head { padding: 6px 12px 9px; gap: 7px; }
  .phone-status { padding: 9px 14px 4px; font-size: 8.5px; }
  .answer-grid { gap: 14px; }

  /* Act 4 was landing exactly on the limit; buy it some room. */
  .record-fields { padding: 2px 14px; }
  .rf { padding: 9px 0; }
  .record-head { padding: 11px 14px; }
  .record-routes { padding: 11px 14px 14px; }
  .act-scrim {
    background:
      radial-gradient(140% 100% at 50% 45%, transparent 6%, rgba(5, 5, 7, 0.8) 74%),
      linear-gradient(180deg, rgba(5, 5, 7, 0.9) 0%, rgba(5, 5, 7, 0.48) 32%, rgba(5, 5, 7, 0.58) 60%, rgba(5, 5, 7, 0.96) 100%);
  }
}

/* ═══ DISCLOSURE ═════════════════════════════════════════════════════
   Homepage-only. Deep detail stays in the DOM (and therefore indexed and
   rankable) but stops presenting as a wall. The FAQ already worked this
   way; this is the same idea applied to the long product sections.
   ─────────────────────────────────────────────────────────────────── */

.recep-cue {
  font-family: var(--font-body);
  font-size: clamp(14px, 1.4vw, 16px);
  line-height: 1.6;
  color: var(--fg-muted);
  max-width: 52ch;
  margin: 0 0 clamp(18px, 3vw, 30px);
}

.disclose {
  border-top: 1px solid var(--line);
}

.disclose:last-of-type {
  border-bottom: 1px solid var(--line);
  margin-bottom: clamp(26px, 4vw, 42px);
}

.disclose > summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  padding: clamp(15px, 2vw, 20px) 0;
  font-family: var(--font-display);
  font-size: clamp(15px, 1.6vw, 18px);
  font-weight: 600;
  color: var(--fg-dim);
  transition: color .25s var(--ease);
}

.disclose > summary::-webkit-details-marker { display: none; }
.disclose > summary:hover { color: var(--fg); }

.disclose > summary::after {
  content: "";
  flex: none;
  width: 10px;
  height: 10px;
  border-right: 1.5px solid var(--red);
  border-bottom: 1.5px solid var(--red);
  transform: translateY(-2px) rotate(45deg);
  transition: transform .3s var(--ease);
}

.disclose[open] > summary { color: var(--fg); }
.disclose[open] > summary::after { transform: translateY(2px) rotate(-135deg); }

.disclose-body { padding-bottom: clamp(18px, 3vw, 30px); }

/* the nested blocks keep their own rules, just without the top spacing they
   used when they were full-width sections */
.disclose-body > .recep-block-label:first-child { margin-top: 0; }

@media (prefers-reduced-motion: reduce) {
  .disclose > summary::after { transition: none; }
}

/* ═══ PORTFOLIO — live sites showcase ════════════════════════════════
   Replaces the clipped auto-carousel. One site at a time, shown large in
   a browser frame with its real domain in the URL bar, and the phone
   capture overlapping so the responsive build is visible rather than
   claimed. All five panels stay in the DOM; JS only decides which is on.
   ─────────────────────────────────────────────────────────────────── */

.pf { padding-block: clamp(64px, 9vw, 124px); }

.pf-showcase {
  display: grid;
  gap: clamp(26px, 3.4vw, 52px);
  grid-template-columns: 1fr;
  align-items: start;
  margin-top: clamp(30px, 4vw, 52px);
}

@media (min-width: 1000px) {
  .pf-showcase { grid-template-columns: minmax(240px, 300px) minmax(0, 1fr); }
}

/* ── rail ── */

.pf-list { list-style: none; margin: 0; padding: 0; display: grid; }

.pf-item {
  width: 100%;
  display: flex;
  align-items: baseline;
  gap: 14px;
  padding: clamp(13px, 1.6vw, 17px) 16px;
  background: none;
  border: 0;
  border-left: 2px solid var(--line);
  color: inherit;
  text-align: left;
  cursor: pointer;
  font: inherit;
  transition: border-color .3s var(--ease), background .3s var(--ease);
}

.pf-item:hover { background: rgba(255,255,255,0.03); border-left-color: var(--line-3); }

.pf-item[aria-selected="true"] {
  border-left-color: var(--red);
  background: linear-gradient(90deg, rgba(240,75,87,0.10), transparent 78%);
}

.pf-item-n {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: .12em;
  color: var(--fg-faint);
  flex: none;
  transition: color .3s var(--ease);
}

.pf-item[aria-selected="true"] .pf-item-n { color: var(--red); }

.pf-item-txt { display: grid; gap: 3px; min-width: 0; }

.pf-item-txt b {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(14px, 1.5vw, 16px);
  color: var(--fg-dim);
  line-height: 1.25;
  transition: color .3s var(--ease);
}

.pf-item[aria-selected="true"] .pf-item-txt b { color: var(--fg); }

.pf-item-txt em {
  font-style: normal;
  font-family: var(--font-mono);
  font-size: 9.5px;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--fg-faint);
}

/* ── stage ── */

/* All panels occupy the SAME grid cell, so the stage is always as tall as
   its tallest panel and switching project can never reflow the page.
   visibility (not display) also keeps hidden panels out of the tab order. */
.pf-stage {
  position: relative;
  min-width: 0;
  display: grid;
  grid-template-areas: "stage";
}

.pf-panel {
  grid-area: stage;
  visibility: hidden;
  opacity: 0;
  pointer-events: none;
  transition: opacity .4s var(--ease-out);
}

.pf-panel.is-active {
  visibility: visible;
  opacity: 1;
  pointer-events: auto;
  animation: pf-in .5s var(--ease-out);
}

@keyframes pf-in {
  from { opacity: 0; transform: translate3d(0, 14px, 0); }
  to   { opacity: 1; transform: none; }
}

.pf-device {
  position: relative;
  padding-bottom: clamp(30px, 4vw, 54px);
  padding-left: clamp(0px, 3vw, 46px);
}

/* browser frame */
.pf-browser {
  border: 1px solid var(--line-2);
  border-radius: 8px;
  overflow: hidden;
  background: var(--bg-elev);
  box-shadow: 0 34px 70px -34px rgba(0,0,0,.95), 0 0 0 1px rgba(255,255,255,0.03);
}

.pf-chrome {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 9px 14px;
  background: linear-gradient(180deg, #1a1a21, #131318);
  border-bottom: 1px solid rgba(255,255,255,0.07);
}

.pf-wdots { display: inline-flex; gap: 6px; flex: none; }
.pf-wdots i { width: 9px; height: 9px; border-radius: 50%; background: #35353f; display: block; }
.pf-wdots i:first-child { background: #4a2226; }

.pf-url {
  flex: 1;
  min-width: 0;
  padding: 5px 12px;
  border-radius: 20px;
  background: rgba(0,0,0,0.42);
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: .04em;
  color: var(--fg-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.pf-desktop {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 1600 / 741;
  object-fit: cover;
  object-position: top center;
  background: var(--bg-elev-2);
}

/* the phone, hanging off the lower-left corner */
.pf-handset {
  position: absolute;
  left: 0;
  bottom: 0;
  width: clamp(88px, 11vw, 136px);
  border-radius: 14px;
  padding: 4px;
  background: linear-gradient(160deg, #26262e, #0a0a0d 40%, #101016);
  box-shadow: 0 26px 46px -18px rgba(0,0,0,.95), 0 0 0 1px rgba(255,255,255,0.08);
}

.pf-handset img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 390 / 844;
  object-fit: cover;
  object-position: top center;
  border-radius: 11px;
  background: var(--bg-elev-2);
}

@media (max-width: 700px) {
  .pf-device { padding-left: 0; padding-bottom: 0; }
  .pf-handset { display: none; }
}

/* ── info ── */

.pf-info { margin-top: clamp(16px, 2.2vw, 24px); }

.pf-info h3 {
  margin: 0 0 8px;
  font-family: var(--font-condensed);
  font-weight: 700;
  font-size: clamp(1.5rem, 3vw, 2.1rem);
  letter-spacing: .005em;
  text-transform: uppercase;
  color: var(--fg);
}

.pf-info p {
  margin: 0;
  font-size: clamp(14px, 1.45vw, 16px);
  line-height: 1.6;
  color: var(--fg-dim);
  max-width: 62ch;
}

.pf-note {
  margin-top: 10px !important;
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--fg-faint) !important;
}

.pf-visit {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  margin-top: clamp(14px, 2vw, 20px);
  padding: 11px 18px;
  border: 1px solid var(--line-3);
  border-radius: var(--radius);
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--fg);
  text-decoration: none;
  transition: border-color .25s var(--ease), background .25s var(--ease), transform .25s var(--ease);
}

.pf-visit:hover {
  border-color: var(--red);
  background: rgba(240,75,87,0.09);
  transform: translateY(-1px);
}

/* ── no JS: every project simply stacks ── */

.no-js .pf-stage { display: block; }
.no-js .pf-panel { visibility: visible; opacity: 1; pointer-events: auto; animation: none; margin-bottom: clamp(40px, 6vw, 72px); }
.no-js .pf-rail { display: none; }

@media (prefers-reduced-motion: reduce) {
  .pf-panel.is-active { animation: none; }
}
