/* Demo player. Deliberately self-contained and prefixed so it can be dropped onto any host
   page (the showcase embed) without colliding with the host's styles. */

.dp {
  --dp-accent: #5b5bd6;
  --dp-accent-text: #fff;
  --dp-radius: 12px;
  --dp-overlay: 0.55;
  --dp-font: ui-sans-serif, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;

  position: relative;
  display: block;
  width: 100%;
  overflow: hidden;
  background: #0b0b0f;
  border-radius: var(--dp-radius);
  font-family: var(--dp-font);
  color: #18181b;
  -webkit-font-smoothing: antialiased;
}

.dp *,
.dp *::before,
.dp *::after {
  box-sizing: border-box;
}

/* The stage is sized to the captured viewport, then scaled to fit its container. Measuring
   targets in captured coordinates and scaling once keeps every rect exact. */
.dp__stage {
  position: absolute;
  top: 0;
  left: 0;
  transform-origin: top left;
  background: #fff;
}

/* Two stacked buffers. The next step is preloaded into the hidden one and cross-faded in, so
   advancing never flashes the white of a reloading iframe. */
.dp__frame {
  position: absolute;
  inset: 0;
  display: block;
  border: 0;
  background: #fff;
  opacity: 0;
  pointer-events: none;
  transition: opacity 190ms linear;
}
.dp__frame--on {
  opacity: 1;
  pointer-events: auto;
  z-index: 1;
}
/* The outgoing frame during a cross-fade: held fully opaque underneath the incoming one, so
   the fade never passes through a transparent moment. Dropped once the fade completes. */
.dp__frame--hold {
  opacity: 1;
  z-index: 0;
  transition: none;
}

/* Single off-switch for every overlay element, so they fade rather than pop. */
.dp__off {
  opacity: 0 !important;
  pointer-events: none !important;
}

.dp__viewport {
  position: relative;
  width: 100%;
  overflow: hidden;
}

/* Blocks stray clicks on the snapshot; the spotlight hole is the only live region. */
.dp__shield {
  position: absolute;
  inset: 0;
  z-index: 5;
  cursor: default;
}
.dp--freeroam .dp__shield {
  pointer-events: none;
}

/* The spotlight persists across steps and is only repositioned, so it glides from one target
   to the next instead of being rebuilt. That travel is what makes playback feel continuous. */
.dp__spot {
  position: absolute;
  z-index: 6;
  border-radius: 6px;
  box-shadow: 0 0 0 9999px rgba(9, 9, 14, var(--dp-overlay));
  pointer-events: none;
  transition:
    top 420ms cubic-bezier(0.32, 0.72, 0, 1),
    left 420ms cubic-bezier(0.32, 0.72, 0, 1),
    width 420ms cubic-bezier(0.32, 0.72, 0, 1),
    height 420ms cubic-bezier(0.32, 0.72, 0, 1),
    opacity 220ms linear;
}

/* The clickable hole. Sits over the target so the click is ours, not the snapshot's. */
.dp__hit {
  position: absolute;
  z-index: 8;
  cursor: pointer;
  border-radius: 6px;
  transition:
    top 420ms cubic-bezier(0.32, 0.72, 0, 1),
    left 420ms cubic-bezier(0.32, 0.72, 0, 1),
    width 420ms cubic-bezier(0.32, 0.72, 0, 1),
    height 420ms cubic-bezier(0.32, 0.72, 0, 1),
    opacity 220ms linear;
}
.dp__hit::after {
  content: '';
  position: absolute;
  inset: -3px;
  border-radius: 8px;
  border: 2px solid var(--dp-accent);
  opacity: 0.9;
}

.dp__beacon {
  position: absolute;
  z-index: 9;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: var(--dp-accent);
  pointer-events: none;
  transition:
    top 420ms cubic-bezier(0.32, 0.72, 0, 1),
    left 420ms cubic-bezier(0.32, 0.72, 0, 1),
    opacity 220ms linear;
}
.dp__beacon::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: var(--dp-accent);
  animation: dp-ping 1.8s cubic-bezier(0, 0, 0.2, 1) infinite;
}
@keyframes dp-ping {
  0% { transform: scale(1); opacity: 0.7; }
  75%, 100% { transform: scale(2.8); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .dp__beacon::before { animation: none; }
  .dp__spot, .dp__hit, .dp__beacon, .dp__tip, .dp__frame { transition: none; }
  /* The guide cursor and key HUD are never shown at all — the player checks the same media
     query and skips the re-enactment, so these rules are just a belt for that suspender. */
  .dp__cursor, .dp__ripple, .dp__caret { animation: none; }
}

/* ---- guide cursor & keystroke HUD ---- */

/* Positioned by left/top with its hotspot (the arrow tip) at that point; all travel is done
   with WAAPI transforms so there is deliberately no left/top transition to fight with. */
.dp__cursor {
  position: absolute;
  z-index: 14;
  width: 22px;
  height: 22px;
  margin: -3px 0 0 -5px; /* puts the SVG arrow tip on the hotspot */
  pointer-events: none;
  transform-origin: 5px 3px;
  transition: opacity 260ms linear;
  filter: drop-shadow(0 1px 2.5px rgba(0, 0, 0, 0.45));
}

.dp__ripple {
  position: absolute;
  z-index: 13;
  width: 16px;
  height: 16px;
  margin: -8px 0 0 -8px;
  border-radius: 50%;
  border: 2.5px solid var(--dp-accent);
  pointer-events: none;
  animation: dp-ripple 620ms cubic-bezier(0, 0, 0.2, 1) forwards;
}
@keyframes dp-ripple {
  0% { transform: scale(0.5); opacity: 0.95; }
  100% { transform: scale(3.2); opacity: 0; }
}

/* Screencast-style readout of what the step "types". */
.dp__keys {
  position: absolute;
  z-index: 13;
  bottom: 64px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  max-width: min(520px, 86%);
  padding: 9px 14px;
  border-radius: 10px;
  background: rgba(16, 16, 20, 0.88);
  color: #fff;
  font: 500 13.5px/1.2 ui-monospace, SFMono-Regular, Menlo, monospace;
  box-shadow: 0 6px 24px rgba(0, 0, 0, 0.3);
  backdrop-filter: blur(8px);
  white-space: nowrap;
  overflow: hidden;
  transition: opacity 220ms linear;
}
.dp__caret {
  width: 2px;
  height: 15px;
  margin-left: 2px;
  background: var(--dp-accent);
  animation: dp-caret 950ms steps(2, start) infinite;
}
@keyframes dp-caret {
  50% { opacity: 0; }
}
.dp__kbd {
  padding: 4px 10px;
  border-radius: 6px;
  background: rgba(255, 255, 255, 0.14);
  box-shadow: inset 0 -2px 0 rgba(255, 255, 255, 0.16), 0 0 0 1px rgba(255, 255, 255, 0.1);
  font-size: 12.5px;
  font-weight: 600;
}

/* ---- tooltip ---- */

/* Persistent across steps: its contents are swapped while it is invisible, then it fades back
   in at the new position. Repositioning a *visible* card makes it slide across the screen,
   which reads as jank. Opacity-only, so it cannot fight the modal variant's centring transform. */
.dp__tip {
  position: absolute;
  z-index: 10;
  width: min(320px, 80%);
  background: #fff;
  border-radius: var(--dp-radius);
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.28), 0 0 0 1px rgba(0, 0, 0, 0.06);
  padding: 16px 18px;
  opacity: 1;
  transition: opacity 150ms ease;
}
.dp__tip.dp__fade { opacity: 0; }
.dp__tip--modal {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  width: min(440px, 86%);
  padding: 24px 26px;
}
.dp__tip--caption {
  left: 24px;
  bottom: 24px;
  top: auto;
  width: min(360px, 70%);
}

.dp__tip h3 {
  margin: 0;
  font-size: 15.5px;
  font-weight: 650;
  line-height: 1.32;
  color: #18181b;
  /* Headlines are short and often wrap to two lines; balancing avoids a lone trailing word. */
  text-wrap: balance;
}
/* Space below the headline belongs to whatever follows it, so a title-only card stays tight
   instead of carrying a phantom gap where the body would have been. */
.dp__tip h3 + * { margin-top: 7px; }
.dp__tip--modal h3 { font-size: 19px; }
.dp__tip p {
  margin: 0;
  font-size: 13.5px;
  line-height: 1.55;
  color: #52525b;
  white-space: pre-wrap;
}

.dp__tipfoot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-top: 14px;
}
/* Step controls that live inside the card. Hidden here and revealed by the phone breakpoint,
   where the floating bar stands down and these take over. A footer that exists only to carry
   them goes with them. */
.dp__tipnav,
.dp__tipfoot--phone {
  display: none;
}
.dp__tipback {
  align-items: center;
  justify-content: center;
  flex: none;
  width: 32px;
  height: 32px;
  padding: 0;
  appearance: none;
  cursor: pointer;
  color: #52525b;
  background: #fff;
  border: 1px solid #e4e4e7;
  border-radius: 50%;
}
.dp__tipback:disabled {
  opacity: 0.35;
  cursor: default;
}
.dp__count {
  font-size: 12px;
  color: #a1a1aa;
  font-variant-numeric: tabular-nums;
}
.dp__acts { display: flex; gap: 8px; align-items: center; }

.dp__btn {
  appearance: none;
  border: 0;
  cursor: pointer;
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  padding: 8px 14px;
  border-radius: 8px;
  background: var(--dp-accent);
  color: var(--dp-accent-text);
  transition: filter 0.15s;
}
.dp__btn:hover { filter: brightness(1.1); }
.dp__btn--ghost {
  background: transparent;
  color: #71717a;
  padding: 8px 6px;
}
.dp__btn--ghost:hover { color: #18181b; }
.dp__btn:disabled { opacity: 0.4; cursor: default; }

/* Branch choices turn a step into a fork in the story. */
.dp__branches {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: 14px;
}
.dp__branch {
  appearance: none;
  cursor: pointer;
  font: inherit;
  font-size: 13.5px;
  font-weight: 550;
  text-align: left;
  padding: 11px 14px;
  border-radius: 9px;
  border: 1px solid #e4e4e7;
  background: #fafafa;
  color: #18181b;
  transition: all 0.15s;
}
.dp__branch:hover {
  border-color: var(--dp-accent);
  background: #fff;
  transform: translateX(2px);
}

/* ---- chrome ---- */

.dp__progress {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 3px;
  z-index: 12;
  background: rgba(255, 255, 255, 0.15);
  transition: opacity 220ms linear;
}
.dp__progressbar {
  height: 100%;
  width: 0;
  background: var(--dp-accent);
  transition: width 0.35s ease;
}

.dp__nav {
  position: absolute;
  z-index: 12;
  bottom: 14px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 6px 8px;
  border-radius: 999px;
  background: rgba(16, 16, 20, 0.82);
  backdrop-filter: blur(8px);
  box-shadow: 0 6px 24px rgba(0, 0, 0, 0.3);
  transition: opacity 220ms linear;
}
/* Round icon buttons: a fixed square that cannot wrap, whatever the bar's width. */
.dp__nav button {
  appearance: none;
  border: 0;
  background: transparent;
  color: #fff;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 30px;
  height: 30px;
  padding: 0;
  border-radius: 50%;
  transition: background 150ms ease;
}
.dp__nav button:hover:not(:disabled) { background: rgba(255, 255, 255, 0.16); }
.dp__nav button:active:not(:disabled) { background: rgba(255, 255, 255, 0.24); }
.dp__nav button:focus-visible { outline: 2px solid var(--dp-accent); outline-offset: 1px; }
.dp__nav button:disabled { opacity: 0.3; cursor: default; }
.dp__dots { display: flex; gap: 5px; padding: 0 6px; }
.dp__dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.3);
  cursor: pointer;
}
.dp__dot { transition: background 200ms ease, transform 200ms ease; }
.dp__dot--on { background: var(--dp-accent); transform: scale(1.25); }

/* ---- peek: hide the guide, keep the way back ---- */

/* Sits opposite the back/next bar, always on top, and never hides itself — it is the only way
   to restore the guide, so it must survive its own toggle. */
.dp__peek {
  position: absolute;
  z-index: 15;
  bottom: 14px;
  right: 14px;
  display: flex;
  align-items: center;
  gap: 7px;
  appearance: none;
  border: 0;
  cursor: pointer;
  font: inherit;
  font-size: 12.5px;
  font-weight: 600;
  padding: 8px 13px;
  border-radius: 999px;
  background: rgba(16, 16, 20, 0.82);
  color: #fff;
  backdrop-filter: blur(8px);
  box-shadow: 0 6px 24px rgba(0, 0, 0, 0.3);
  transition: background 160ms ease, transform 160ms ease;
}
.dp__peek:hover { background: rgba(32, 32, 38, 0.92); }
.dp__peek:active { transform: scale(0.97); }
.dp__peek:focus-visible { outline: 2px solid var(--dp-accent); outline-offset: 2px; }
.dp__peek svg { flex: none; opacity: 0.85; }

/* While peeking the guide fades out but the frame, the progress bar, the back/next bar and the
   toggle all stay — the viewer is inspecting the product, not leaving the tour. */
.dp--peek .dp__spot,
.dp--peek .dp__hit,
.dp--peek .dp__beacon,
.dp--peek .dp__tip,
.dp--peek .dp__keys,
.dp--peek .dp__cursor {
  opacity: 0 !important;
  pointer-events: none !important;
}
/* Restored state reads as "the tour is running again". */
.dp--peek .dp__peek { background: var(--dp-accent); color: var(--dp-accent-text); }
.dp--peek .dp__peek:hover { filter: brightness(1.08); background: var(--dp-accent); }

/* Narrow embeds: the label is what makes the control obvious, so shrink rather than drop it. */
@media (max-width: 560px) {
  /* The card owns an edge, so this moves to the corner of the other one. It also drops its
     label: the words are worth a lot on a desktop, but here the pill was 30% of the screen's
     width and landed on top of the very element a step was pointing at. Icon only, in a corner,
     with the label kept for screen readers and as a tooltip. It can never hide itself — it is
     the only way back — so it cannot move into the card, which does hide while peeking. */
  .dp__peek {
    top: 8px;
    right: 8px;
    bottom: auto;
    width: 32px;
    height: 32px;
    padding: 0;
    gap: 0;
    justify-content: center;
    border-radius: 50%;
  }
  .dp__peek span { display: none; }

  /* The guidance stops floating and docks to the bottom edge.
     A 1440-wide capture shown at ~342px is far too small to host a card over it: measured on a
     390px phone, the centred modal covered 82% of the screen and collided with both the arrow
     bar and the Hide guide button. Docked, the product stays visible above it and the step
     controls move inside it, so there is nothing left to overlap.
     The !important flags are load-bearing: placeTip() writes left/top inline for anchored
     tooltips, and the modal variant carries a centring transform. Both must lose here. */
  .dp__tip,
  .dp__tip--modal,
  .dp__tip--caption {
    left: 0 !important;
    right: 0 !important;
    top: auto !important;
    bottom: 0 !important;
    transform: none !important;
    width: 100% !important;
    max-width: none;
    /* Typical step copy is a sentence or two and fits; anything longer scrolls inside the card
       rather than growing over the screen. */
    max-height: 62%;
    overflow-y: auto;
    overscroll-behavior: contain;
    padding: 13px 15px;
    border-radius: var(--dp-radius) var(--dp-radius) 0 0;
    box-shadow: 0 -8px 30px rgba(0, 0, 0, 0.34);
  }
  /* Flipped to the top edge when the step's target sits low enough that a bottom-docked card
     would cover it. The Hide guide button lives in the top corner, so it moves out of the way. */
  .dp__tip--sheettop {
    top: 0 !important;
    bottom: auto !important;
    border-radius: 0 0 var(--dp-radius) var(--dp-radius);
    box-shadow: 0 8px 30px rgba(0, 0, 0, 0.34);
  }
  .dp--sheettop .dp__peek { top: auto; bottom: 8px; }
  .dp--peekleft .dp__peek { right: auto; left: 8px; }

  .dp__tip h3,
  .dp__tip--modal h3 { font-size: 15px; }
  .dp__tip p { font-size: 12.5px; line-height: 1.45; }
  .dp__tip h3 + * { margin-top: 5px; }
  .dp__tipfoot { margin-top: 10px; }
  .dp__tipfoot--phone { display: flex; }
  .dp__tipnav { display: inline-flex; }
  .dp__branches { margin-top: 10px; }
  .dp__branch { padding: 9px 12px; font-size: 12.5px; }

  /* Back and next now sit in the card, so the floating bar would only be one more thing to
     collide with it. */
  .dp__nav { display: none; }

}

/* ---- cover: the optional entry page ---- */

/* The entry page sits over the demo's own first screen rather than on a slide of its own, which
   is what makes it read as the product rather than a splash. Above every guide element, below
   the lead-form / end-CTA panels (z 20).

   Type is sized from --dp-scale, the factor the stage is scaled by, so the headline keeps its
   proportion to the screen behind it in a small embed instead of to the browser window. */
.dp__cover {
  --cover-fg: #fff;
  --cover-mute: rgba(255, 255, 255, 0.8);
  /* Deliberately short of opaque. The point of covering the real first screen rather than a
     blank one is that the product stays visible underneath, so the wash goes only as far as the
     copy needs — the blur is doing most of the work of quietening it. */
  --cover-scrim: rgba(6, 6, 10, 0.76);
  --cover-scrim-soft: rgba(6, 6, 10, 0.16);

  position: absolute;
  inset: 0;
  z-index: 18;
  display: flex;
  overflow: hidden;
  opacity: 1;
  transition: opacity 380ms ease;
}
.dp__cover[data-theme='light'] {
  --cover-fg: #101014;
  --cover-mute: rgba(24, 24, 27, 0.68);
  /* Higher than the dark wash on purpose. Dark type needs the busy light UI of a typical app
     scrubbed further out before it stops ghosting through the headline. */
  --cover-scrim: rgba(250, 250, 253, 0.94);
  --cover-scrim-soft: rgba(250, 250, 253, 0.24);
}
.dp__cover--out {
  opacity: 0;
  pointer-events: none;
}

/* While the entry page is up the player's own chrome stands down. A progress bar, a dot strip
   and a Hide guide button around a start button read as a tour that has already begun and
   stalled; one action reads as a door. They all fade back in behind it. */
.dp--covering .dp__nav,
.dp--covering .dp__peek,
.dp--covering .dp__progress,
.dp--covering .dp__tip,
.dp--covering .dp__spot,
.dp--covering .dp__hit,
.dp--covering .dp__beacon,
.dp--covering .dp__cursor,
.dp--covering .dp__keys {
  opacity: 0 !important;
  pointer-events: none !important;
}

/* Blurring the screen itself, rather than laying frosted glass over it, is what sells the
   depth: the product is genuinely behind the words. It eases back to sharp as the cover
   fades, so pressing start reads as one motion into the demo. */
.dp__stage {
  transition: filter 620ms cubic-bezier(0.32, 0.72, 0, 1);
}
.dp--cover-blur .dp__stage {
  filter: blur(14px) saturate(1.06);
}

.dp__coverscrim {
  position: absolute;
  inset: 0;
  z-index: 0;
}
/* Left-aligned copy wants the screen legible on one side and the type legible on the other, so
   the wash is directional. Centred copy sits on an even one, lifted at the edges.

   The full-strength stop (44%) is deliberately past the copy's own max-width (58%) measured
   against the same box, so the words sit inside the solid part of the wash at any container
   size — a rule in percentages holds where a pixel breakpoint would not. */
.dp__cover[data-align='left'] .dp__coverscrim {
  background: linear-gradient(90deg, var(--cover-scrim) 0%, var(--cover-scrim) 44%, var(--cover-scrim-soft) 100%);
}
.dp__cover[data-align='center'] .dp__coverscrim {
  background: radial-gradient(118% 116% at 50% 46%, var(--cover-scrim) 0%, var(--cover-scrim) 50%, var(--cover-scrim-soft) 100%);
}
.dp__cover[data-backdrop='dim'] {
  --cover-scrim-soft: rgba(6, 6, 10, 0.5);
}
.dp__cover[data-backdrop='dim'][data-theme='light'] {
  --cover-scrim-soft: rgba(250, 250, 253, 0.62);
}

/* Showing the screen off means keeping most of it clear, not leaving the copy to fend for
   itself: a light app under an even 30% wash swallows a white headline whole. So this one
   pools the wash where the words are and lets it fall away to almost nothing elsewhere —
   most of the screen on show, every word still readable on top of it. */
/* The pool still runs heavier than the blurred backdrop's wash, because here there is no blur
   softening the sharp text underneath and the copy has to win on the wash alone. */
.dp__cover[data-backdrop='clear'] {
  --cover-scrim: rgba(6, 6, 10, 0.82);
  --cover-scrim-soft: rgba(6, 6, 10, 0.22);
}
.dp__cover[data-backdrop='clear'][data-theme='light'] {
  --cover-scrim: rgba(250, 250, 253, 0.92);
  --cover-scrim-soft: rgba(250, 250, 253, 0.26);
}
.dp__cover[data-backdrop='clear'][data-align='left'] .dp__coverscrim {
  background:
    radial-gradient(76% 120% at -8% 50%, var(--cover-scrim) 0%, var(--cover-scrim) 36%, transparent 76%),
    linear-gradient(0deg, var(--cover-scrim-soft), var(--cover-scrim-soft));
}
/* This is the one backdrop where the screen underneath keeps its own sharp text, and a line of
   the app's UI running through a line of ours is unreadable however dark the wash is. So the
   type carries its own contrast here instead — which is what lets the wash stay this light. */
.dp__cover[data-backdrop='clear'] .dp__coverh,
.dp__cover[data-backdrop='clear'] .dp__coverp,
.dp__cover[data-backdrop='clear'] .dp__covermeta,
.dp__cover[data-backdrop='clear'] .dp__covereyebrow {
  text-shadow:
    0 1px 18px rgba(0, 0, 0, 0.9),
    0 1px 4px rgba(0, 0, 0, 0.7);
}
.dp__cover[data-backdrop='clear'][data-theme='light'] .dp__coverh,
.dp__cover[data-backdrop='clear'][data-theme='light'] .dp__coverp,
.dp__cover[data-backdrop='clear'][data-theme='light'] .dp__covermeta,
.dp__cover[data-backdrop='clear'][data-theme='light'] .dp__covereyebrow {
  text-shadow:
    0 1px 18px rgba(255, 255, 255, 0.95),
    0 1px 4px rgba(255, 255, 255, 0.8);
}

.dp__cover[data-backdrop='clear'][data-align='center'] .dp__coverscrim {
  background:
    radial-gradient(58% 78% at 50% 50%, var(--cover-scrim) 0%, var(--cover-scrim) 30%, transparent 80%),
    linear-gradient(0deg, var(--cover-scrim-soft), var(--cover-scrim-soft));
}
/* Nothing of the capture shows: a branded field built from the demo's own accent, for a demo
   whose first screen is a login or an empty state not worth showing before the tour. */
.dp__cover[data-backdrop='solid'] .dp__coverscrim {
  background: #07070b;
}
.dp__cover[data-backdrop='solid'][data-theme='light'] .dp__coverscrim {
  background: #f6f6fa;
}
.dp__cover[data-backdrop='solid'] .dp__coverscrim::after {
  content: '';
  position: absolute;
  inset: 0;
  background:
    radial-gradient(72% 88% at 6% 0%, var(--dp-accent) 0%, transparent 64%),
    radial-gradient(64% 76% at 98% 100%, var(--dp-accent) 0%, transparent 62%),
    radial-gradient(46% 56% at 78% 8%, var(--dp-accent) 0%, transparent 68%);
  opacity: 0.62;
}
.dp__cover[data-backdrop='solid'][data-theme='light'] .dp__coverscrim::after {
  opacity: 0.28;
}

.dp__coverinner {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  gap: clamp(9px, calc(16px * var(--dp-scale, 1)), 16px);
  width: 100%;
  padding: clamp(26px, calc(78px * var(--dp-scale, 1)), 78px);
  color: var(--cover-fg);
}
.dp__cover[data-align='left'] .dp__coverinner {
  max-width: min(58%, 700px);
}
.dp__cover[data-align='center'] .dp__coverinner {
  align-items: center;
  text-align: center;
  max-width: min(86%, 780px);
  margin: 0 auto;
}

.dp__coverlogo {
  height: clamp(20px, calc(34px * var(--dp-scale, 1)), 34px);
  width: auto;
  max-width: 55%;
  object-fit: contain;
  object-position: left center;
}
.dp__cover[data-align='center'] .dp__coverlogo {
  object-position: center;
}

.dp__covereyebrow {
  margin: 0;
  font-size: clamp(10px, calc(12.5px * var(--dp-scale, 1)), 12.5px);
  font-weight: 680;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--dp-accent);
}

.dp__coverh {
  margin: 0;
  font-size: clamp(25px, calc(60px * var(--dp-scale, 1)), 60px);
  line-height: 1.04;
  font-weight: 700;
  letter-spacing: -0.033em;
  text-wrap: balance;
  color: var(--cover-fg);
}

.dp__coverp {
  margin: 0;
  max-width: 40ch;
  font-size: clamp(13px, calc(19px * var(--dp-scale, 1)), 19px);
  line-height: 1.5;
  color: var(--cover-mute);
  white-space: pre-wrap;
}

.dp__covermeta {
  margin: clamp(1px, calc(4px * var(--dp-scale, 1)), 4px) 0 0;
  font-size: clamp(10.5px, calc(12.5px * var(--dp-scale, 1)), 12.5px);
  font-weight: 500;
  color: var(--cover-mute);
  opacity: 0.78;
  font-variant-numeric: tabular-nums;
}

/* ---- the start button ---- */

/* Three decorative layers, all behind the button: an accent aura that breathes, a specular arc
   that travels the rim, and a sheen that crosses the face. Between them the button says "press
   me" without a word of instruction — and every one of them is off under reduced motion, or
   when the demo turns the glow off. */
.dp__coverstart {
  --cover-btn-radius: calc(var(--dp-radius) + 6px);
  position: relative;
  display: inline-flex;
  isolation: isolate;
  margin-top: clamp(8px, calc(18px * var(--dp-scale, 1)), 18px);
}

.dp__coveraura {
  position: absolute;
  inset: -10%;
  z-index: 0;
  border-radius: var(--cover-btn-radius);
  background: var(--dp-accent);
  filter: blur(clamp(13px, calc(28px * var(--dp-scale, 1)), 28px));
  opacity: 0.5;
  transition: opacity 320ms ease, transform 320ms ease;
}
.dp__cover--glow .dp__coveraura {
  animation: dp-cover-breathe 3.8s ease-in-out infinite;
}

/* A large square of conic gradient spun behind a rounded, clipped window, so only the sliver
   around the button shows. Rotating the gradient's own angle would need @property; rotating a
   square never does, and this way the ring follows whatever radius the theme sets. */
.dp__coverring {
  position: absolute;
  inset: -2.5px;
  z-index: 1;
  overflow: hidden;
  border-radius: calc(var(--cover-btn-radius) + 2.5px);
  opacity: 0;
  /* Half a pixel of softening: at 2.5px the arc is thin enough that raw anti-aliasing on the
     pill's curve reads as a grubby edge rather than light. */
  filter: blur(0.5px);
  transition: opacity 400ms ease;
}
.dp__cover--glow .dp__coverring {
  opacity: 1;
}
.dp__coverring i {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 280%;
  aspect-ratio: 1;
  transform: translate(-50%, -50%);
  background: conic-gradient(
    from 0deg,
    transparent 0deg 152deg,
    rgba(255, 255, 255, 0.04) 166deg,
    rgba(255, 255, 255, 1) 180deg,
    rgba(255, 255, 255, 0.04) 194deg,
    transparent 208deg 360deg
  );
}
.dp__cover--glow .dp__coverring i {
  animation: dp-cover-orbit 3.6s linear infinite;
}
/* A white highlight has nothing to travel against on a light wash, so there the arc is drawn in
   the accent instead — the same gesture, the only colour that still reads. */
.dp__cover[data-theme='light'] .dp__coverring i {
  background: conic-gradient(
    from 0deg,
    transparent 0deg 152deg,
    rgba(255, 255, 255, 0) 166deg,
    var(--dp-accent) 180deg,
    rgba(255, 255, 255, 0) 194deg,
    transparent 208deg 360deg
  );
}

.dp__coverbtn {
  position: relative;
  z-index: 2;
  display: inline-flex;
  align-items: center;
  gap: clamp(6px, calc(10px * var(--dp-scale, 1)), 10px);
  appearance: none;
  border: 0;
  cursor: pointer;
  overflow: hidden;
  font: inherit;
  font-size: clamp(14px, calc(19px * var(--dp-scale, 1)), 19px);
  font-weight: 640;
  letter-spacing: -0.011em;
  padding: clamp(11px, calc(17px * var(--dp-scale, 1)), 17px) clamp(19px, calc(30px * var(--dp-scale, 1)), 30px);
  border-radius: var(--cover-btn-radius);
  background: var(--dp-accent);
  color: var(--dp-accent-text);
  box-shadow:
    0 10px 30px -10px rgba(0, 0, 0, 0.7),
    inset 0 1px 0 rgba(255, 255, 255, 0.24);
  transition:
    transform 240ms cubic-bezier(0.22, 0.61, 0.36, 1),
    box-shadow 240ms ease;
}
.dp__coverbtn svg {
  flex: none;
  opacity: 0.9;
  transition: transform 240ms cubic-bezier(0.22, 0.61, 0.36, 1);
}
/* Slow and infrequent, so it registers as a material catching the light rather than a spinner. */
.dp__cover--glow .dp__coverbtn::after {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(104deg, transparent 36%, rgba(255, 255, 255, 0.4) 50%, transparent 64%);
  transform: translateX(-140%);
  animation: dp-cover-sheen 4.8s cubic-bezier(0.4, 0, 0.2, 1) infinite;
}

.dp__coverbtn:hover {
  transform: translateY(-2px);
  box-shadow:
    0 18px 42px -12px rgba(0, 0, 0, 0.78),
    inset 0 1px 0 rgba(255, 255, 255, 0.32);
}
.dp__coverbtn:hover svg {
  transform: translateX(3px);
}
.dp__coverbtn:active {
  transform: translateY(0) scale(0.985);
}
.dp__coverbtn:focus-visible {
  outline: 3px solid var(--cover-fg);
  outline-offset: 4px;
}
/* Applies when the glow is off; while it is breathing the animation owns these properties, so
   hovering quickens the pulse instead. */
.dp__coverstart:hover .dp__coveraura {
  opacity: 0.82;
  transform: scale(1.06);
}
.dp__cover--glow .dp__coverstart:hover .dp__coveraura {
  animation-duration: 2.1s;
}

@keyframes dp-cover-breathe {
  0%, 100% { opacity: 0.42; transform: scale(0.97); }
  50% { opacity: 0.72; transform: scale(1.05); }
}
@keyframes dp-cover-orbit {
  from { transform: translate(-50%, -50%) rotate(0turn); }
  to { transform: translate(-50%, -50%) rotate(1turn); }
}
@keyframes dp-cover-sheen {
  0%, 62% { transform: translateX(-140%); }
  92%, 100% { transform: translateX(140%); }
}

/* Entrance. Carried by a class rather than applied to the elements outright, because the studio
   repaints this cover on every keystroke while its copy is being written and re-running the
   entrance each time would be unusable. */
.dp__cover--enter .dp__coverscrim {
  animation: dp-cover-fade 520ms ease both;
}
.dp__cover--enter .dp__coverinner > * {
  animation: dp-cover-rise 700ms cubic-bezier(0.22, 0.61, 0.36, 1) both;
}
.dp__cover--enter .dp__coverinner > *:nth-child(1) { animation-delay: 90ms; }
.dp__cover--enter .dp__coverinner > *:nth-child(2) { animation-delay: 150ms; }
.dp__cover--enter .dp__coverinner > *:nth-child(3) { animation-delay: 210ms; }
.dp__cover--enter .dp__coverinner > *:nth-child(4) { animation-delay: 270ms; }
.dp__cover--enter .dp__coverinner > *:nth-child(5) { animation-delay: 330ms; }
.dp__cover--enter .dp__coverinner > *:nth-child(6) { animation-delay: 390ms; }
@keyframes dp-cover-fade {
  from { opacity: 0; }
  to { opacity: 1; }
}
@keyframes dp-cover-rise {
  from { opacity: 0; transform: translateY(16px); }
  to { opacity: 1; transform: none; }
}

/* On a phone a 16:10 capture is a couple of hundred pixels tall, so a side-weighted wash leaves
   the copy sitting on whatever the screenshot happens to show. Flatten it and use the width. */
@media (max-width: 560px) {
  .dp__cover:not([data-backdrop='solid']) .dp__coverscrim {
    background: var(--cover-scrim);
  }
  .dp__cover[data-align='left'] .dp__coverinner {
    max-width: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .dp__stage { transition: none; }
  .dp__cover--enter .dp__coverscrim,
  .dp__cover--enter .dp__coverinner > *,
  .dp__cover--glow .dp__coveraura,
  .dp__cover--glow .dp__coverring i,
  .dp__cover--glow .dp__coverbtn::after {
    animation: none;
  }
}

/* ---- panels (lead form, end CTA, loading) ---- */

.dp__panel {
  position: absolute;
  inset: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(9, 9, 14, 0.72);
  backdrop-filter: blur(6px);
  padding: 24px;
}
.dp__card {
  width: min(420px, 100%);
  background: #fff;
  border-radius: 16px;
  padding: 28px;
  box-shadow: 0 24px 70px rgba(0, 0, 0, 0.4);
}
.dp__card h2 {
  margin: 0 0 8px;
  font-size: 20px;
  font-weight: 680;
  color: #18181b;
}
.dp__card p {
  margin: 0 0 18px;
  font-size: 14px;
  line-height: 1.55;
  color: #52525b;
}
.dp__field { margin-bottom: 12px; }
.dp__field label {
  display: block;
  font-size: 12.5px;
  font-weight: 600;
  color: #3f3f46;
  margin-bottom: 5px;
}
.dp__field input,
.dp__field select {
  width: 100%;
  font: inherit;
  font-size: 14px;
  padding: 10px 12px;
  border: 1px solid #e4e4e7;
  border-radius: 9px;
  background: #fff;
  color: #18181b;
}
.dp__field input:focus,
.dp__field select:focus {
  outline: 2px solid var(--dp-accent);
  outline-offset: -1px;
  border-color: transparent;
}
.dp__card .dp__btn { width: 100%; padding: 11px; font-size: 14px; }
.dp__endacts {
  display: flex;
  gap: 8px;
  justify-content: center;
  margin-top: 12px;
}
.dp__endacts .dp__btn { width: auto; padding: 8px 12px; font-size: 13px; }

.dp__loading {
  position: absolute;
  inset: 0;
  z-index: 30;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #0b0b0f;
  color: #a1a1aa;
  font-size: 13px;
  transition: opacity 0.3s;
}
.dp__loading--gone { opacity: 0; pointer-events: none; }

.dp__err {
  padding: 32px;
  color: #fca5a5;
  font-size: 13px;
  line-height: 1.6;
  font-family: ui-monospace, monospace;
}
