/* Rebond Grotesque, the app's type, from the site's own fonts. */
@font-face {
  font-family: Rebond;
  src: url('/assets/fonts/Rebond-Regular.otf') format('opentype');
  font-weight: 400;
  font-display: swap;
}
@font-face {
  font-family: Rebond;
  src: url('/assets/fonts/Rebond-Medium.otf') format('opentype');
  font-weight: 500;
  font-display: swap;
}
@font-face {
  font-family: Rebond;
  src: url('/assets/fonts/Rebond-Semibold.otf') format('opentype');
  font-weight: 600 700;
  font-display: swap;
}
:root {
  color-scheme: light;
  --bg: #ffffff;
  --ink: #0c0b11;
  --muted: #6b6b72;
  --lead: #9aa6b4;
  --blue: #1293ff;
  --line: rgb(0 0 0 / 0.09);
  --page: calc(100dvh - 76px - env(safe-area-inset-top) - env(safe-area-inset-bottom));
  font-family: Rebond, system-ui, sans-serif;
  color: var(--ink);
  background: var(--bg);
  font-synthesis: none;
}
* {
  box-sizing: border-box;
}
body {
  margin: 0;
}
button,
a {
  -webkit-tap-highlight-color: transparent;
}
button,
input {
  font: inherit;
}
button {
  cursor: pointer;
  color: inherit;
}
button:disabled {
  cursor: default;
  opacity: 0.4;
}
button:focus-visible,
a:focus-visible {
  outline: 3px solid #075baf;
  outline-offset: 4px;
}
a {
  color: inherit;
}
[hidden] {
  display: none !important;
}
.shell {
  max-width: 480px;
  min-height: 100dvh;
  margin: auto;
  padding: env(safe-area-inset-top) 24px env(safe-area-inset-bottom);
  background: #fff;
}
.header {
  height: 76px;
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.brand {
  font-size: 24px;
  letter-spacing: -1px;
  font-weight: 700;
  text-decoration: none;
}
.brand span,
h1 span {
  color: var(--blue);
}
.round,
.header-spacer {
  width: 42px;
  height: 42px;
}
.round {
  border: 0;
  background: white;
  border-radius: 50%;
  font-size: 32px;
  line-height: 1;
  box-shadow: 0 5px 20px #00000008;
}
.header:has(#back[hidden]) .brand {
  margin-right: auto;
}
.screen {
  padding: 12px 0 30px;
  animation: appear 0.25s ease-out;
}
h1 {
  font-size: 36px;
  font-weight: 600;
  line-height: 1.12;
  letter-spacing: -1.5px;
  margin: 10px 0 20px;
}
h1:focus {
  outline: none;
}
p {
  line-height: 1.45;
}
h2 {
  font-size: 23px;
  font-weight: 600;
  margin: 0 0 16px;
}
.lede {
  font-size: 19px;
  color: var(--muted);
  margin: 0;
  max-width: 310px;
}
.intro-art {
  position: relative;
  height: clamp(220px, 35dvh, 320px);
  margin: 22px 0 10px;
  display: grid;
  place-items: center;
  background: radial-gradient(ellipse, #d7edff80, transparent 65%);
}
.intro-art img {
  /* Absolute sizing: Safari resolves a percentage height on a grid item
     against the image's natural size and lets it overflow the CTA. */
  position: absolute;
  inset: 3% 5%;
  width: 90%;
  height: 94%;
  object-fit: contain;
  filter: drop-shadow(0 24px 28px #819ab42b);
}
.orbit {
  position: absolute;
  inset: 9% 21%;
  border: 1px solid #1293ff30;
  border-radius: 50%;
  transform: rotate(-18deg);
  pointer-events: none;
}
.primary {
  border: 1px solid #1689ec;
  border-radius: 999px;
  background: #0577d4;
  color: #fff;
  text-shadow: 0 1px 1px #075baf55;
  min-height: 58px;
  width: 100%;
  padding: 15px 22px;
  font-size: 20px;
  font-weight: 600;
  box-shadow:
    inset 0 1px 1px #ffffff40,
    0 8px 28px #1293ff18;
}
.primary:hover {
  background: #0786ee;
}
.primary:active {
  transform: scale(0.99);
}
.privacy-line {
  font-size: 14px;
  text-align: center;
  color: var(--muted);
  margin: 18px 0;
}
.scan {
  text-align: center;
}
.scan h1 {
  font-size: 27px;
  letter-spacing: -0.8px;
  margin: 6px -10px 10px;
}
.hint {
  font-size: 16px;
  color: var(--muted);
  margin: 0 0 18px;
}
.viewfinder {
  position: relative;
  width: min(100%, 310px);
  aspect-ratio: 551/742;
  margin: 22px auto 12px;
  isolation: isolate;
}
.face-window {
  position: absolute;
  inset: 9%;
  clip-path: url(#face-clip);
  background: #e8e8e7;
}
.face-window video,
.face-window canvas {
  width: 100%;
  height: 100%;
  object-fit: cover;
  position: absolute;
  inset: 0;
}
.face-window video,
.face-window .camera-frames {
  /* Zoomed in on the middle, as capture-gate.js's PREVIEW_ZOOM, so a face fills the outline
     from further back. */
  transform: scaleX(-1) scale(var(--scan-zoom, 1));
}
#how-error:empty {
  display: none;
}
#how-error {
  margin: 10px 0 0;
  text-align: center;
}
.empty-face {
  position: absolute;
  inset: 0;
  background: radial-gradient(ellipse at 50% 34%, #fff, #dfe0e0);
  z-index: -1;
}
.viewfinder #ring {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
}
.viewfinder.has-face {
  filter: drop-shadow(0 0 17px #1293ff38);
}
#desktop-qr {
  margin: 24px auto;
  width: min(100%, 240px);
}
#desktop-qr svg {
  width: 100%;
  height: auto;
  display: block;
}
#photo-fallback {
  flex-direction: column;
}
.photo-actions {
  display: flex;
  gap: 10px;
  margin-top: 12px;
}
.secondary {
  border: 1px solid var(--line);
  background: #fff;
  border-radius: 999px;
  padding: 13px 8px;
  min-height: 48px;
  flex: 1;
  font-weight: 500;
}
.error {
  font-size: 14px;
  color: #9c382e;
  margin: 12px 0 0;
}
.error:empty {
  display: none;
}
.scan .privacy-line {
  font-size: 12px;
  margin: 10px -8px 20px;
}
.text-button {
  border: 0;
  background: none;
  text-decoration: underline;
  text-underline-offset: 4px;
  font-size: 14px;
  padding: 16px;
  color: var(--muted);
}
.analysis {
  text-align: center;
}
.analysis h1 {
  font-size: 29px;
  margin-top: 14px;
}
.analysis-visual {
  position: relative;
  height: 390px;
  margin: 24px -8px 8px;
  background: radial-gradient(ellipse at center, #bdddff70, transparent 65%);
}
.portrait-window {
  position: absolute;
  left: 19%;
  top: 8%;
  width: 62%;
  aspect-ratio: 551/742;
  clip-path: url(#face-clip);
  background: #e1e2e4;
  -webkit-mask-image: linear-gradient(to bottom, #000 72%, transparent 100%);
  mask-image: linear-gradient(to bottom, #000 72%, transparent 100%);
}
.portrait-window img,
.portrait-window canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.analysis-pills {
  position: absolute;
  inset: 0;
}
.analysis-pill {
  position: absolute;
  display: flex;
  align-items: center;
  gap: 10px;
  border: 1px solid #c6ceda;
  background: #ffffffd9;
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  padding: 10px 16px 10px 10px;
  border-radius: 999px;
  box-shadow: 0 12px 24px #30496d10;
  text-align: left;
  font-size: 16px;
  opacity: 0.45;
}
.analysis-pill:nth-child(1) {
  left: 0;
  top: 63%;
}
.analysis-pill:nth-child(2) {
  right: 0;
  top: 25%;
}
.analysis-pill:nth-child(3) {
  left: 0;
  top: 12%;
}
.analysis-pill:nth-child(4) {
  right: 0;
  top: 77%;
}
.analysis-pill.active,
.analysis-pill.done {
  opacity: 1;
}
.pill-progress {
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  border: 2px solid #c4e2ff;
  border-radius: 50%;
  color: #0674d1;
  font-size: 15px;
}
.analysis-pill.active .pill-progress {
  border-color: var(--blue);
  animation: analysing 1.4s ease-in-out infinite;
}
@keyframes analysing {
  50% {
    box-shadow: 0 0 0 6px #1293ff18;
  }
}
@media (prefers-reduced-motion: reduce) {
  .analysis-pill.active .pill-progress {
    animation: none;
  }
}
.analysis-pill small {
  display: block;
  font-size: 13px;
  color: #0674d1;
}
.analysis-progress {
  font-size: 68px;
  font-weight: 600;
  letter-spacing: -3px;
  margin: 22px 0 4px;
}
.analysis-progress small {
  font-size: 30px;
}
.analysis > .hint {
  font-size: 14px;
}
.checkout-bar {
  position: fixed;
  bottom: 0;
  left: 50%;
  transform: translateX(-50%);
  width: min(100%, 480px);
  padding: 22px 24px max(18px, env(safe-area-inset-bottom));
  background: linear-gradient(#f4f4f300, #f4f4f3 25%);
  z-index: 3;
}
.checkout-bar .error {
  background: var(--bg);
  text-align: center;
}
@keyframes results-appear {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}
@keyframes appear {
  from {
    opacity: 0;
    transform: translateY(5px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}
@media (max-width: 360px) {
  .shell {
    padding-left: 18px;
    padding-right: 18px;
  }
  /* Full-bleed screens bleed by the shell's own padding, or the page scrolls sideways. */
  .splash,
  .roadmap {
    margin: 0 -18px;
  }
  h1 {
    font-size: 32px;
  }
  .analysis-pill {
    font-size: 14px;
    padding: 8px;
  }
  .analysis-visual {
    height: 340px;
  }
  .results-visual {
    height: 290px;
  }
}
@media (max-height: 720px) {
  .header {
    height: 58px;
  }
  .scan .viewfinder {
    width: 230px;
    margin-top: 14px;
  }
  .intro-art {
    height: 230px;
  }
  .analysis-visual {
    height: 320px;
  }
  .analysis-progress {
    margin-top: 8px;
  }
}
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation: none !important;
    transition: none !important;
    scroll-behavior: auto !important;
  }
}

.checkout-note {
  font-size: 13px;
  margin: 0 0 9px;
  color: var(--muted);
  text-align: center;
}
.checkout-bar {
  background: linear-gradient(#f4f4f300, #f4f4f3 18%);
  padding-top: 26px;
}
.primary:hover {
  background: #006bc1;
}


@media (hover: none) and (pointer: coarse) {
  html, body {
    scrollbar-width: none;
  }
  html::-webkit-scrollbar, body::-webkit-scrollbar {
    display: none;
  }
}

/* ── The app's onboarding, on the web (Johan) ─────────────────────────────── */

.primary {
  border: 0;
  background: var(--blue);
  min-height: 56px;
  font-size: 18px;
  font-weight: 500;
  text-shadow: none;
  box-shadow: 0 10px 26px #1293ff33;
}
.primary:hover {
  background: #0d86ec;
}
.round {
  background: rgb(255 255 255 / 0.8);
  border: 1px solid rgb(0 0 0 / 0.06);
  box-shadow: 0 8px 22px rgb(12 11 17 / 0.08);
}
/* Past the intro the page carries no wordmark, as the app's screens don't. */
body:not([data-screen='intro']) .brand {
  visibility: hidden;
}
h1 {
  font-weight: 500;
  letter-spacing: -1.2px;
}
h1 span {
  color: var(--blue);
}
.glass-panel {
  border-radius: 26px;
  background: rgb(255 255 255 / 0.72);
  border: 1px solid rgb(0 0 0 / 0.06);
  box-shadow:
    inset 0 1px 0 #fff,
    0 14px 34px rgb(12 11 17 / 0.07);
  -webkit-backdrop-filter: blur(18px) saturate(1.4);
  backdrop-filter: blur(18px) saturate(1.4);
}
.ruler {
  width: 14px;
  height: 9px;
  flex-shrink: 0;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14 9'%3E%3Crect x='.75' y='.75' width='12.5' height='7.5' rx='1.5' fill='none' stroke='%231293ff' stroke-width='1.5'/%3E%3Cpath d='M4 1v3M7 1v4M10 1v3' stroke='%231293ff' stroke-width='1.3'/%3E%3C/svg%3E") center / contain no-repeat;
}
.cta-bar {
  position: sticky;
  bottom: 0;
  margin-top: auto;
  padding: 16px 0 max(18px, env(safe-area-inset-bottom));
  background: linear-gradient(#fff0, #fff 30%);
  z-index: 3;
}
.cta-bar .privacy-line {
  margin: 10px 0 0;
}

/* Coach: the app's chat. Pills along the top, the thread pinned low, the question big. */
.coach,
.how {
  display: flex;
  flex-direction: column;
  min-height: var(--page);
  padding: 0;
  animation: none;
}
.coach {
  padding-bottom: max(20px, env(safe-area-inset-bottom));
}
/* The coach is the app's chat screen: it fills what's visible of the screen, above the keyboard
   when that's up, and never scrolls, the newest lines on the question and the oldest running up
   out of view. The page scrolled away under a finger, and the keyboard pushed the question off
   the top (Johan). */
html:has(body[data-screen='coach']),
body[data-screen='coach'] {
  overflow: hidden;
  overscroll-behavior: none;
}
body[data-screen='coach'] .shell {
  position: fixed;
  top: var(--vvt, 0px);
  left: 0;
  right: 0;
  display: flex;
  flex-direction: column;
  height: var(--vvh, 100dvh);
  min-height: 0;
  padding-bottom: 0;
  overflow: hidden;
}
body[data-screen='coach'] .header {
  flex-shrink: 0;
}
body[data-screen='coach'] main {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  min-height: 0;
}
body[data-screen='coach'] .coach {
  flex: 1 1 auto;
  min-height: 0;
  padding-bottom: max(20px, env(safe-area-inset-bottom));
  overflow: hidden;
}
body[data-screen='coach'] .coach-pills {
  flex-shrink: 0;
}
body[data-screen='coach'] .coach-stage {
  flex: 1 1 auto;
  min-height: 0;
  margin-top: 0;
  justify-content: flex-end;
  overflow: hidden;
  /* What runs up out of view fades under the pills rather than being cut through. */
  -webkit-mask: linear-gradient(transparent, #000 36px);
  mask: linear-gradient(transparent, #000 36px);
}
body[data-screen='coach'] .coach-stage > * {
  flex-shrink: 0;
}
/* With the keyboard up the field sits just above it. What's visible already stops above iOS 26
   Safari's address pill and AutoFill bar (the coach ended exactly at the pill's top on Johan's
   iPhone), so no room is kept for them: that only pushed the question up under the pills. */
html.keyboard body[data-screen='coach'] .coach {
  padding-bottom: 0;
}
html.keyboard .coach-composer {
  padding-bottom: 10px;
}
/* A screen too short for the whole question above the field: the avatar steps out, then the
   lines come down a size, so the question always reads in full (Johan). */
html.coach-tight body[data-screen='coach'] .coach-avatar {
  display: none;
}
html.coach-tighter body[data-screen='coach'] .coach-lines {
  font-size: 27px;
  letter-spacing: -0.8px;
}
/* And on the shortest (an SE with the keyboard up) the back button's row and the gap above the
   field close up too. */
html.coach-tighter body[data-screen='coach'] .header {
  height: 56px;
}
html.coach-tighter body[data-screen='coach'] .coach-stage {
  padding-top: 8px;
}
html.coach-tighter .coach-composer {
  padding-top: 4px;
}
html.coach-tighter .composer-top:has(.composer-error:empty):has(.coach-skip[hidden]) {
  display: none;
}
/* A typed step has no choices: their empty row kept a gap between the question and the field. */
.coach.typing .coach-choices {
  display: none;
}
.coach-pills {
  display: flex;
  gap: 6px;
}
.coach-pill {
  flex: 1;
  min-width: 0;
  height: 36px;
  border-radius: 999px;
  display: grid;
  place-items: center;
  padding: 0 8px;
  font-size: 14px;
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  color: var(--muted);
  background: rgb(255 255 255 / 0.8);
  border: 1px solid rgb(0 0 0 / 0.06);
  box-shadow: 0 6px 18px rgb(12 11 17 / 0.06);
  transition: color 0.3s, border-color 0.3s;
}
.coach-pill.answered,
.coach-pill.asking {
  color: var(--ink);
}
.coach-pill.asking {
  border-color: rgb(12 11 17 / 0.22);
}
.coach-stage {
  margin-top: auto;
  padding-top: 18px;
  display: flex;
  flex-direction: column;
}
.coach-history {
  display: flex;
  flex-direction: column;
  gap: 18px;
  margin-bottom: 30px;
}
.coach-history:empty {
  margin: 0;
}
.coach-row {
  display: flex;
  flex-direction: column;
  gap: 8px;
  animation: appear 0.35s ease-out;
}
.coach-said {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  font-size: 16px;
  font-weight: 500;
  color: var(--lead);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.coach-mini {
  width: 22px;
  height: 22px;
  flex-shrink: 0;
}
.coach-bubble {
  align-self: flex-end;
  max-width: 82%;
  margin: 0;
  padding: 11px 18px;
  border-radius: 22px 22px 6px 22px;
  background: var(--blue);
  color: #fff;
  font-size: 17px;
  font-weight: 600;
  line-height: 1.25;
}
.coach-avatar {
  width: 56px;
  height: 56px;
  margin-bottom: 20px;
}
.coach-lines {
  margin: 0;
  font-size: 33px;
  font-weight: 500;
  letter-spacing: -1px;
  line-height: 1.12;
}
.coach-lead {
  display: block;
  color: var(--lead);
}
.coach-question {
  display: block;
  color: var(--ink);
}
/* The letters are spans in the heading: they take their line's colour, not the accent blue. */
.coach-lines .coach-word,
.coach-lines .coach-letter {
  display: inline-block;
  color: inherit;
}
.coach-lines .coach-letter {
  display: inline;
}
.coach-said span {
  overflow: hidden;
  text-overflow: ellipsis;
}
.coach-letter {
  opacity: 0;
  transition: opacity 0.12s;
}
.coach-letter.on {
  opacity: 1;
}
.coach-choices {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
  margin-top: 24px;
  opacity: 0;
  transform: translateY(12px);
  pointer-events: none;
  transition: opacity 0.35s, transform 0.35s;
}
.coach-choices.in {
  opacity: 1;
  transform: none;
  pointer-events: auto;
}
.coach-choice {
  min-height: 52px;
  padding: 12px 16px;
  border-radius: 999px;
  border: 1px solid rgb(0 0 0 / 0.07);
  background: rgb(255 255 255 / 0.85);
  box-shadow:
    inset 0 1px 0 #fff,
    0 8px 22px rgb(12 11 17 / 0.07);
  font-size: 16px;
  font-weight: 500;
  color: var(--ink);
  line-height: 1.2;
  transition: background 0.2s, color 0.2s;
}
.coach-choice.wide,
.coach-go {
  grid-column: 1 / -1;
}
.coach-choice[aria-pressed='true'] {
  background: var(--blue);
  border-color: var(--blue);
  color: #fff;
}

/* How it works: the app's paged steps, each card recorded off the app. */
.how-bars {
  display: flex;
  gap: 8px;
  margin: 2px 0 0;
}
.how-seg {
  position: relative;
  flex: 1;
  height: 4px;
  border-radius: 2px;
  overflow: hidden;
  background: rgb(0 0 0 / 0.08);
}
.how-seg.done {
  background: var(--blue);
}
.how-seg.now::after {
  content: '';
  position: absolute;
  inset: 0;
  background: var(--blue);
  transform-origin: left;
  animation: seg-fill var(--fill, 5s) linear forwards;
}
@keyframes seg-fill {
  from {
    transform: scaleX(0);
  }
}
.how-number {
  margin: 26px 0 4px;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.6px;
  color: var(--blue);
}
.how-title {
  min-height: 2.3em;
  margin: 0;
  font-size: 27px;
  letter-spacing: -0.8px;
  line-height: 1.15;
}
.how-title.in {
  animation: appear 0.4s ease-out;
}
.how.final .how-bars,
.how.final .how-number {
  display: none;
}
.how.final .how-title {
  margin-top: 30px;
  font-size: 34px;
  letter-spacing: -1.1px;
  line-height: 1.12;
}
.how-stage {
  position: relative;
  flex: 1;
  min-height: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 18px 0 8px;
  touch-action: pan-y;
}
.how-card {
  position: relative;
  height: 100%;
  max-height: 460px;
  max-width: 100%;
  aspect-ratio: 1046 / 1356;
  overflow: hidden;
  border-radius: 36px;
  background: #fff;
  border: 1px solid rgb(0 0 0 / 0.06);
  box-shadow: 0 18px 40px rgb(12 11 17 / 0.08);
}
.how-card :is(video, :where(canvas.canvas-video)) {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity 0.35s;
}
.how-card :is(video, :where(canvas.canvas-video)).on {
  opacity: 1;
}
.how-summary {
  display: none;
  height: 100%;
  max-height: 480px;
  max-width: 100%;
  aspect-ratio: 1086 / 1456;
  object-fit: contain;
}
.how.final .how-card {
  display: none;
}
.how.final .how-summary {
  display: block;
}
.how.final .how-stage {
  align-items: flex-start;
  padding-top: 14px;
}

/* Analysis: the readings running through under the counter, as the app's. */
.measure-panel {
  width: min(100%, 340px);
  margin: 6px auto 12px;
  padding: 10px 14px;
  text-align: left;
}
.measure-head {
  display: flex;
  align-items: center;
  gap: 6px;
  margin: 0 0 4px;
  font-size: 12.5px;
  font-weight: 600;
}
.measure-rows {
  height: 112px;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  -webkit-mask-image: linear-gradient(transparent, #000 35%);
  mask-image: linear-gradient(transparent, #000 35%);
}
.measure-row {
  display: flex;
  align-items: center;
  gap: 9px;
  height: 28px;
  font-size: 13.5px;
  color: rgb(12 11 17 / 0.6);
}
.measure-row.measuring {
  color: var(--ink);
  font-weight: 600;
}
.measure-ring {
  position: relative;
  width: 15px;
  height: 15px;
  flex-shrink: 0;
  border-radius: 50%;
  background: conic-gradient(var(--blue) calc(var(--fill) * 360deg), #1293ff26 0);
  -webkit-mask: radial-gradient(circle, transparent 5px, #000 5.5px);
  mask: radial-gradient(circle, transparent 5px, #000 5.5px);
}
.measure-row:not(.measuring) .measure-ring {
  -webkit-mask: none;
  mask: none;
  background: var(--blue) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 10'%3E%3Cpath d='M2.2 5.2 4.2 7.1 7.9 3' fill='none' stroke='%23fff' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / 9px no-repeat;
}
.measure-bar {
  margin-left: auto;
  width: 56px;
  height: 4px;
  border-radius: 4px;
  background: linear-gradient(to right, var(--blue) calc(var(--fill) * 100%), rgb(0 0 0 / 0.07) 0);
}
.measure-row:not(.measuring) .measure-bar {
  opacity: 0.45;
}

/* Potential: the app's PotentialGaugePage. One figure counting up as the areas tick in, where
   that leaves them, then the 28 days drawn into the room that's left. */
.potential {
  display: flex;
  flex-direction: column;
  height: var(--page);
  min-height: 0;
  padding: 8px 0 0;
}
.potential-hero {
  margin: 0;
}
.potential-line {
  display: block;
  font-size: 30px;
  font-weight: 500;
  letter-spacing: -1px;
  line-height: 1.15;
  color: var(--ink);
}
.potential-hero .potential-percent {
  display: inline-flex;
  align-items: baseline;
  margin: 2px 0;
  color: var(--blue);
  font-size: 90px;
  font-weight: 600;
  letter-spacing: -3.5px;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
.potential-percent small {
  font-size: 50px;
  letter-spacing: 0;
}
.potential-below {
  margin: 8px 0 0;
  font-size: 16px;
  color: var(--muted);
  opacity: 0;
  translate: 0 6px;
  transition: opacity 0.4s ease-out, translate 0.4s ease-out;
}
.potential-below.in {
  opacity: 1;
  translate: 0 0;
}
.sources {
  margin-top: 20px;
  padding: 12px;
}
.panel-eyebrow {
  display: flex;
  align-items: center;
  gap: 6px;
  margin: 0 0 10px 4px;
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--muted);
}
.sources-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
}
.source {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  min-width: 0;
  padding: 9px 10px;
  border-radius: 16px;
  background: rgb(255 255 255 / 0.8);
  opacity: 0.35;
}
.source-check {
  flex-shrink: 0;
  width: 18px;
  height: 18px;
  margin-top: 1px;
}
.source-check svg {
  display: block;
  width: 100%;
  height: 100%;
  overflow: visible;
}
.source-check .ring-track,
.source-check .ring {
  fill: none;
  stroke-width: 2;
}
.source-check .ring-track {
  stroke: rgb(12 11 17 / 0.12);
}
.source-check .ring {
  stroke: var(--blue);
  stroke-linecap: round;
  stroke-dasharray: 0 1;
  transform: rotate(-90deg);
  transform-origin: center;
}
.source-check .fill {
  fill: var(--blue);
  transform: scale(0.001);
  transform-origin: center;
}
.source-check .tick {
  fill: none;
  stroke: #fff;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  opacity: 0;
}
.source-words {
  min-width: 0;
}
.source-words strong {
  display: block;
  font-size: 14px;
  font-weight: 600;
  white-space: nowrap;
}
.source-words small {
  display: block;
  font-size: 11.5px;
  color: var(--muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.path-panel {
  display: flex;
  flex: 1 1 0;
  min-height: 96px;
  margin-top: 10px;
  padding: 14px;
}
.path-chart {
  display: block;
  flex: 1;
  width: 100%;
  min-height: 0;
  overflow: visible;
}
.path-gap {
  fill: url(#path-fill);
}
.path-without {
  fill: none;
  stroke: rgb(28 28 30 / 0.39);
  stroke-width: 2.5;
  stroke-dasharray: 5 6;
  stroke-linecap: round;
}
.path-with {
  fill: none;
  stroke: url(#path-ink);
  stroke-width: 4;
  stroke-linecap: round;
}
.path-dot {
  stroke: #fff;
  stroke-width: 2;
  filter: drop-shadow(0 1px 3px rgb(18 147 255 / 0.3));
}
.path-dot.now {
  fill: var(--ink);
}
.path-dot.end {
  fill: var(--blue);
}
.path-label,
.path-axis {
  font-family: Rebond, system-ui, sans-serif;
  font-size: 12px;
  font-weight: 600;
}
.path-label.with {
  fill: var(--blue);
}
.path-label.without,
.path-axis {
  fill: rgb(28 28 30 / 0.55);
}
/* A shorter screen: a smaller figure and tighter tiles, as the app's, so it all fits. */
.potential.compact .potential-line {
  font-size: 26px;
}
.potential.compact .potential-percent {
  font-size: 70px;
}
.potential.compact .potential-percent small {
  font-size: 40px;
}
.potential.compact .potential-below {
  margin-top: 4px;
  font-size: 15px;
}
.potential.compact .sources {
  margin-top: 14px;
}
.potential.compact .source {
  padding: 6px 10px;
}
.potential.compact .sources-grid {
  gap: 6px;
}
/* The smallest screens: the tiles name their areas only, the figure smaller again. */
.potential.tight .potential-line {
  font-size: 22px;
}
.potential.tight .potential-percent {
  font-size: 56px;
}
.potential.tight .potential-percent small {
  font-size: 32px;
}
.potential.tight .source-words small {
  display: none;
}
.potential.tight .source {
  align-items: center;
  padding: 6px 8px;
}
.potential.tight .sources {
  margin-top: 10px;
  padding: 10px;
}
.potential.tight .path-panel {
  min-height: 84px;
  padding: 10px 12px;
}
.plan.tight .transform-card,
.plan.tight .plan-card-web,
.plan.tight .bundle-row {
  padding: 14px;
}
.plan.tight .transform-summary,
.plan.tight .plan-today {
  height: 62px;
}
.plan.tight .plan-day-label {
  margin: 10px 0 6px;
}
.plan.tight .plan-today {
  margin-top: 10px;
}
.plan.tight .bundle-row {
  height: 96px;
}
.plan.tight .bundle-slot.settled {
  height: 96px;
}
.plan.tight .bundle-thumb,
.plan.tight .bundle-more {
  width: 46px;
  height: 64px;
}
.potential .cta-bar,
.plan .cta-bar {
  flex-shrink: 0;
}
.checkout-bar {
  background: linear-gradient(#fff0, #fff 18%);
}

/* The analysis keeps its readings in view: a smaller portrait and counter above them. */
.analysis .analysis-visual {
  height: clamp(220px, 34dvh, 300px);
  margin: 10px -8px 0;
  background: none;
}
.analysis .analysis-progress {
  margin: 8px 0 0;
  font-size: 56px;
}
.analysis > .hint {
  margin: 4px 0 0;
}
/* Sized by the height it's given, so it never runs down over the counter. */
.analysis .portrait-window {
  top: 2%;
  left: 50%;
  width: auto;
  height: 96%;
  translate: -50% 0;
}

/* ── Splash: the app's welcome wall (WelcomeWallView) ─────────────────────── */
body[data-screen='intro'] .header {
  display: none;
}
body[data-screen='intro'] .shell {
  background: #f4f4f3;
}
.splash {
  position: relative;
  min-height: 100dvh;
  margin: 0 -24px;
  padding: 0;
  overflow: hidden;
  background: #f4f4f3;
  animation: none;
}
.splash .wall {
  position: absolute;
  inset: 0 0 auto;
  height: clamp(300px, calc(100dvh - 270px), 600px);
  margin: 0;
  display: block;
  background: none;
}
.wall-columns {
  position: absolute;
  inset: 0;
  overflow: hidden;
}
.wall-column {
  position: absolute;
  top: 0;
  height: 100%;
}
.wall-track {
  will-change: transform;
  animation: wall-up linear infinite;
}
.wall-column.down .wall-track {
  animation-name: wall-down;
}
@keyframes wall-up {
  from {
    transform: translateY(0);
  }
  to {
    transform: translateY(calc(-1 * var(--loop)));
  }
}
@keyframes wall-down {
  from {
    transform: translateY(calc(-1 * var(--loop)));
  }
  to {
    transform: translateY(0);
  }
}
.phone {
  background: #2a2c31;
  box-shadow: 0 10px 24px rgb(12 11 17 / 0.14);
}
.phone-screen {
  position: relative;
  width: 100%;
  height: 100%;
  overflow: hidden;
  background: #fff;
  isolation: isolate;
}
.splash .phone-screen :is(video, :where(canvas.canvas-video)),
.splash .phone-screen img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top;
  filter: none;
}
.phone-island {
  position: absolute;
  left: 50%;
  translate: -50% 0;
  border-radius: 999px;
  background: #000;
}
.wall-fade {
  position: absolute;
  left: 0;
  right: 0;
  pointer-events: none;
}
.wall-fade.top {
  top: 0;
  height: 120px;
  background: linear-gradient(rgb(244 244 243 / 0.9), rgb(244 244 243 / 0));
}
.wall-fade.bottom {
  bottom: 0;
  height: 200px;
  background: linear-gradient(rgb(244 244 243 / 0), #f4f4f3 82%);
}
.splash .logo-pill {
  position: absolute;
  top: calc(env(safe-area-inset-top) + 26px);
  left: 50%;
  translate: -50% 0;
  z-index: 5;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 7px 16px 7px 7px;
  border-radius: 999px;
  background: rgb(255 255 255 / 0.8);
  -webkit-backdrop-filter: blur(16px) saturate(1.5);
  backdrop-filter: blur(16px) saturate(1.5);
  box-shadow: 0 8px 24px rgb(12 11 17 / 0.1);
  font-size: 20px;
  font-weight: 600;
  letter-spacing: -0.4px;
  color: #1d1f24;
}
.splash .logo-pill img {
  position: static;
  width: 30px;
  height: 30px;
  border-radius: 9px;
  filter: none;
}
.splash-copy {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 6;
  padding: 0 24px max(36px, calc(env(safe-area-inset-bottom) + 22px));
  text-align: center;
}
.pitch {
  margin-bottom: 36px;
  padding: 0 8px;
  transition: opacity 0.33s ease, transform 0.33s ease;
}
.pitch.out {
  opacity: 0;
  transform: translateY(6px);
}
.splash h1 {
  margin: 0 0 12px;
  font-size: 32px;
  font-weight: 600;
  letter-spacing: -0.9px;
  line-height: 1.12;
  color: #1d1f24;
}
.inline-icon {
  width: 30px;
  height: 30px;
  border-radius: 9px;
  vertical-align: -4px;
}
.pitch-sub {
  margin: 0;
  font-size: 15px;
  line-height: 1.4;
  color: #7c828c;
}
.get-started {
  min-height: 50px;
  font-size: 17px;
  font-weight: 600;
  letter-spacing: -0.2px;
}

/* The columns stack among themselves only, under the fades. */
.wall-columns {
  z-index: 0;
}
.wall-fade {
  z-index: 1;
}
/* Sized by flow.js to the room between the title and Next. */
.how-card,
.how-summary {
  flex: none;
  height: auto;
  max-height: none;
}

/* ── Coach field: the app's composer, sat on the keyboard ─────────────────── */

.coach-composer {
  flex-shrink: 0;
  padding: 12px 0 max(12px, env(safe-area-inset-bottom));
}
.composer-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: 22px;
  padding: 0 8px 6px;
}
.composer-error {
  margin: 0;
  font-size: 14px;
  font-weight: 500;
  color: #d0342c;
}
.coach-skip {
  margin-left: auto;
  border: 0;
  background: none;
  font-size: 15px;
  font-weight: 500;
  color: var(--muted);
}
.composer-row {
  display: flex;
  align-items: center;
  gap: 11px;
}
.composer-field {
  flex: 1;
  min-width: 0;
  height: 52px;
  padding: 0 18px;
  border-radius: 999px;
  border: 1px solid rgb(0 0 0 / 0.07);
  background: rgb(255 255 255 / 0.85);
  box-shadow:
    inset 0 1px 0 #fff,
    0 8px 22px rgb(12 11 17 / 0.07);
  font-size: 16px;
  color: var(--ink);
  outline: none;
}
.composer-field::placeholder {
  color: rgb(12 11 17 / 0.3);
}
.coach-send {
  flex-shrink: 0;
  width: 52px;
  height: 52px;
  border: 0;
  border-radius: 50%;
  background: var(--blue) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M10 16V4M4.5 9.5 10 4l5.5 5.5' fill='none' stroke='%23fff' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / 20px no-repeat;
  box-shadow: 0 8px 20px #1293ff40;
}
.coach-send:disabled {
  opacity: 0.35;
  box-shadow: none;
}

/* ── Results, simply (Johan): their face in the scan's outline, the one reading the scan gives,
   the rest locked, one button. Fits a phone's screen without scrolling. ─────────────────── */
html:has(body[data-screen='results']),
body[data-screen='results'],
body[data-screen='results'] .shell {
  background: #f4f4f3;
}
body[data-screen='results'] .header {
  display: none;
}
.glass {
  background: rgb(255 255 255 / 0.62);
  border: 1px solid rgb(255 255 255 / 0.75);
  box-shadow: 0 8px 24px rgb(0 0 0 / 0.06);
  -webkit-backdrop-filter: blur(20px) saturate(1.8);
  backdrop-filter: blur(20px) saturate(1.8);
}
.muted {
  color: var(--secondary);
}
.small {
  font-size: 13px;
}
.eyebrow {
  margin: 0;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: #1293ff;
}
.results {
  /* Opacity only: a transformed section would anchor the fixed button to it. */
  animation-name: results-appear;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: max(28px, env(safe-area-inset-top)) 0 128px;
  text-align: center;
}
.results-title {
  margin: 0;
  font-size: 30px;
  line-height: 1.12;
  letter-spacing: -0.02em;
}
.result-face {
  position: relative;
  width: min(64vw, 250px, calc(40dvh * 551 / 742));
  aspect-ratio: 551/742;
  margin: 22px auto 18px;
  filter: drop-shadow(0 0 17px #1293ff38);
}
.result-window {
  position: absolute;
  inset: 9%;
  clip-path: url(#face-clip);
  background: #e1e2e4;
}
.result-window img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
#result-ring {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
}
/* With the face in 3D: the face takes the screen's whole width and every bit of height the
   rest leaves, measured as it's shown, and the switch between its two views sits above it. The
   locked chips go: the pills on the face name what's locked. */
.result-views {
  display: none;
  gap: 2px;
  margin: 14px 0 0;
  padding: 3px;
  border-radius: 999px;
}
.result-views button {
  min-width: 96px;
  min-height: 34px;
  padding: 0 16px;
  border: 0;
  border-radius: 999px;
  background: none;
  font: inherit;
  font-size: 14px;
  font-weight: 600;
  color: #1d1f24;
  cursor: pointer;
  transition: background 0.3s, color 0.3s;
}
.result-views button.on {
  background: var(--blue);
  color: #fff;
}
.results.in-3d {
  height: 100dvh;
}
.results.in-3d .result-views {
  display: flex;
}
.results.in-3d .result-face {
  flex: 1 1 auto;
  width: calc(100% + 48px);
  min-height: 260px;
  aspect-ratio: auto;
  margin: 4px -24px 8px;
  filter: none;
}
.results.in-3d #result-ring,
.results.in-3d .result-window,
.results.in-3d .locked-chips {
  display: none;
}
.result-3d {
  position: absolute;
  inset: 0;
  touch-action: pan-y;
}
.result-3d canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}
.face-overlay,
.face-labels {
  transition: opacity 0.26s ease;
}
.face-overlay.out,
.face-labels.out {
  opacity: 0;
}
.face-labels {
  position: absolute;
  inset: 0;
  pointer-events: none;
}
.face-labels > * {
  position: absolute;
  left: 0;
  top: 0;
}
/* Over the face: glass pills in SF, as the app's 3D labels. */
.face-pill {
  display: flex;
  align-items: center;
  gap: 6px;
  height: 30px;
  padding: 0 11px;
  border: 1px solid rgb(255 255 255 / 0.75);
  border-radius: 999px;
  background: rgb(255 255 255 / 0.74);
  box-shadow: 0 4px 14px rgb(0 0 0 / 0.08);
  -webkit-backdrop-filter: blur(16px) saturate(1.8);
  backdrop-filter: blur(16px) saturate(1.8);
  font: 600 13px -apple-system, system-ui, sans-serif;
  color: #1d1f24;
  white-space: nowrap;
}
.face-pill .dot {
  flex: none;
  width: 6px;
  height: 6px;
  border-radius: 50%;
}
.face-pill .value {
  font-size: 12px;
  font-weight: 500;
  color: rgb(29 31 36 / 0.7);
}
.face-pill.lead {
  height: 34px;
  padding: 0 14px 0 12px;
  font-size: 14px;
}
.face-pill.lead .dot {
  width: 8px;
  height: 8px;
}
.face-pill.lead .value {
  font-size: 15px;
  font-weight: 700;
  color: #1d1f24;
}
.face-pill .lock-only {
  flex: none;
  width: 9px;
  height: 11px;
  margin-left: 1px;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 20'%3E%3Cpath d='M4 8.5V6a4 4 0 0 1 8 0v2.5' fill='none' stroke='%231d1f24' stroke-width='2.2'/%3E%3Crect x='1' y='8' width='14' height='11' rx='2.6' fill='%231d1f24'/%3E%3C/svg%3E") center / contain no-repeat;
  opacity: 0.6;
}
/* A locked value: its stand-in blurred, a padlock over it. */
.locked {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 24px;
  min-height: 18px;
  padding: 0 3px;
  font-size: 12px;
  font-weight: 500;
  line-height: 1;
  user-select: none;
  -webkit-user-select: none;
}
.locked .stand {
  filter: blur(5px);
  color: #1d1f24;
}
.locked .lock {
  position: absolute;
  left: 50%;
  top: 50%;
  translate: -50% -50%;
  width: 9px;
  height: 11px;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 20'%3E%3Cpath d='M4 8.5V6a4 4 0 0 1 8 0v2.5' fill='none' stroke='%231d1f24' stroke-width='2.2'/%3E%3Crect x='1' y='8' width='14' height='11' rx='2.6' fill='%231d1f24'/%3E%3C/svg%3E") center / contain no-repeat;
  opacity: 0.75;
}
@media (max-width: 380px) {
  .face-pill {
    height: 27px;
    padding: 0 9px;
    gap: 5px;
    font-size: 12px;
  }
  .face-pill.lead {
    height: 31px;
    font-size: 13px;
  }
}
.teaser {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-height: 50px;
  margin: 0;
  padding: 0 20px 0 18px;
  border-radius: 25px;
  background: #fff;
  box-shadow: 0 0 0 1px rgb(0 0 0 / 0.05), 0 8px 24px rgb(0 0 0 / 0.06);
  font-size: 17px;
  font-weight: 500;
}
.teaser-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: #1293ff;
  box-shadow: 0 0 0 5px rgb(18 147 255 / 0.16);
}
.teaser-value {
  font-variant-numeric: tabular-nums;
}
#teaser-score {
  font-size: 21px;
  font-weight: 600;
}
#teaser-of {
  color: var(--muted);
  font-size: 14px;
}
.teaser.waiting #teaser-name {
  color: var(--muted);
}
.teaser.waiting .teaser-dot {
  animation: teaser-pulse 1.4s ease-in-out infinite;
}
@keyframes teaser-pulse {
  50% {
    opacity: 0.35;
  }
}
.locked-chips {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
  width: min(100%, 320px);
  margin: 14px 0 0;
  padding: 0;
  list-style: none;
}
.locked-chips li {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 40px;
  border-radius: 20px;
  background: rgb(255 255 255 / 0.7);
  box-shadow: 0 0 0 1px rgb(0 0 0 / 0.04);
  font-size: 15px;
  font-weight: 500;
  color: rgb(29 31 36 / 0.72);
}
.chip-lock {
  width: 10px;
  height: 13px;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 20'%3E%3Cpath d='M4 8.5V6a4 4 0 0 1 8 0v2.5' fill='none' stroke='%231d1f24' stroke-width='2.2'/%3E%3Crect x='1' y='8' width='14' height='11' rx='2.6' fill='%231d1f24'/%3E%3C/svg%3E") center / contain no-repeat;
  opacity: 0.6;
}
/* What the full scan holds, locked: a glass box over blurred scores, a padlock, and where they
   are (Johan). The scores behind are only texture, too blurred to read. */
.locked-box {
  position: relative;
  /* Never squeezed by a long results page: clipping its contents, it had no floor to its height
     and shrank under its own padlock (Johan). */
  flex: none;
  display: flex;
  align-items: center;
  gap: 12px;
  width: min(100%, 345px);
  margin: 12px 0 0;
  padding: 11px 16px 11px 11px;
  overflow: hidden;
  border: 1px solid rgb(255 255 255 / 0.9);
  border-radius: 22px;
  background: rgb(255 255 255 / 0.72);
  box-shadow: 0 0 0 1px rgb(0 0 0 / 0.04), 0 10px 26px rgb(12 11 17 / 0.06);
  text-align: left;
}
.locked-box-behind {
  position: absolute;
  top: 50%;
  right: -6px;
  translate: 0 -50%;
  font-size: 26px;
  font-weight: 700;
  letter-spacing: 0.12em;
  white-space: nowrap;
  color: var(--ink);
  opacity: 0.3;
  filter: blur(5px);
  /* Only past the words, fading in toward the box's edge. */
  -webkit-mask: linear-gradient(90deg, transparent 40%, #000 85%);
  mask: linear-gradient(90deg, transparent 40%, #000 85%);
  pointer-events: none;
}
.locked-box-icon {
  position: relative;
  flex: none;
  width: 42px;
  height: 42px;
  border-radius: 50%;
  background: #1293ff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 20'%3E%3Cpath d='M4 8.5V6a4 4 0 0 1 8 0v2.5' fill='none' stroke='%23fff' stroke-width='2.2'/%3E%3Crect x='1' y='8' width='14' height='11' rx='2.6' fill='%23fff'/%3E%3C/svg%3E") center / 15px 18px no-repeat;
  box-shadow: 0 6px 16px rgb(18 147 255 / 0.35);
}
.locked-box-words {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 0;
}
.locked-box-words strong {
  font-size: 15px;
  font-weight: 600;
  color: var(--ink);
  white-space: nowrap;
}
.locked-box-words small {
  font-size: 13px;
  font-weight: 500;
  color: var(--muted);
  white-space: nowrap;
}
.result-note {
  margin: 12px 0 0;
  font-size: 14px;
  color: var(--muted);
}

/* The button floats at the foot of the screen. */
.results .cta-bar {
  position: fixed;
  left: 50%;
  bottom: 0;
  translate: -50% 0;
  width: min(100%, 480px);
  margin: 0;
  padding: 28px 24px max(28px, env(safe-area-inset-bottom));
  background: linear-gradient(rgb(244 244 243 / 0), rgb(244 244 243 / 0.92) 50%);
}
@media (max-height: 700px) {
  .results-title {
    font-size: 26px;
  }
  .result-face {
    margin: 14px auto 12px;
  }
  .locked-chips li {
    min-height: 36px;
  }
}
@media (max-width: 360px) {
  .results .cta-bar {
    padding-left: 18px;
    padding-right: 18px;
  }
}
@media (prefers-reduced-motion: reduce) {
  .teaser.waiting .teaser-dot {
    animation: none;
  }
}

/* ── Plan reveal: the app's PlanRevealPage ─────────────────────────────────── */
.plan {
  display: flex;
  flex-direction: column;
  height: var(--page);
  min-height: 0;
  padding: 8px 0 0;
}
.plan-title,
.plan-stack,
.potential-hero,
.potential-below,
.sources {
  flex-shrink: 0;
}
.plan.compact .plan-stack {
  gap: 10px;
}
.plan.tightest .plan-day-label,
.plan.tightest .plan-days {
  display: none;
}
.plan.compact .plan-title {
  height: 40px;
  font-size: 29px;
}
.plan-title {
  position: relative;
  height: 44px;
  margin: 0;
  font-size: 32px;
  font-weight: 500;
  letter-spacing: -1px;
  text-align: center;
  white-space: nowrap;
}
.plan-title > span {
  position: absolute;
  inset: 0;
  color: var(--ink);
  transition: opacity 0.45s ease, scale 0.45s ease;
}
.plan-title .plan-ready,
.plan.ready .plan-building {
  opacity: 0;
  scale: 0.96;
}
.plan.ready .plan-ready {
  opacity: 1;
  scale: 1;
}
.plan-title .plan-ready span {
  color: var(--blue);
}
.plan-stack {
  display: flex;
  flex-direction: column;
  gap: 16px;
}
.plan-stack > * {
  transition:
    opacity 0.5s ease,
    transform 0.5s cubic-bezier(0.2, 0.9, 0.3, 1);
  transform-origin: top center;
}
.plan-stack > .enter {
  opacity: 0;
  transform: scale(0.94);
}
.plan-card-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
}
.plan-card-title {
  font-size: 19px;
  font-weight: 500;
  color: #1d1f24;
}
.plan-card-title.small {
  font-size: 17px;
}
.plan-card-trailing {
  font-size: 12.5px;
  color: #9096a0;
}
.glass.blue {
  background: rgb(18 147 255 / 0.9);
  border-color: rgb(255 255 255 / 0.35);
  color: #fff;
  box-shadow: 0 10px 26px rgb(18 147 255 / 0.28);
}
/* Your transformation. */
.transform-card {
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 18px;
  border-radius: 36px;
  background: rgb(255 255 255 / 0.9);
  overflow: hidden;
}
.transform-rows {
  display: flex;
  flex-direction: column;
  gap: 8px;
  max-height: 400px;
  transition: max-height 0.75s ease, opacity 0.5s ease, margin 0.75s ease;
}
.transform-rows.folded {
  max-height: 0;
  margin-bottom: -14px;
  opacity: 0;
}
.transform-row {
  padding: 12px 14px;
  border-radius: 20px;
  background: #f4f4f3;
  transition: opacity 0.4s ease, transform 0.4s ease;
}
.transform-row.enter {
  opacity: 0;
  transform: translateY(12px);
}
.transform-row.complete {
  opacity: 0.4;
}
.transform-line {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 32px;
}
.transform-line b {
  flex: 1;
  font-size: 15.5px;
  font-weight: 600;
  color: #1d1f24;
}
.transform-collage {
  display: flex;
}
.transform-collage:empty {
  display: none;
}
.transform-photo {
  width: 32px;
  height: 32px;
  margin-left: -12px;
  border: 1.5px solid #fff;
  border-radius: 9px;
  object-fit: cover;
  box-shadow: 0 2px 6px rgb(29 31 36 / 0.14);
  rotate: var(--tilt);
  animation: photo-in 0.35s cubic-bezier(0.3, 1.4, 0.5, 1);
}
.transform-photo:first-child {
  margin-left: 0;
}
@keyframes photo-in {
  from {
    opacity: 0;
    scale: 0.4;
  }
}
.transform-done {
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--blue);
  color: #fff;
  padding: 3px;
  opacity: 0;
  scale: 0.6;
  transition: opacity 0.3s ease, scale 0.3s ease;
}
.transform-row.complete .transform-done,
.transform-rows:not(.folded) .transform-row:has(.transform-chip:last-child.on) .transform-done {
  opacity: 1;
  scale: 1;
}
.transform-done svg {
  display: block;
  width: 100%;
  height: 100%;
}
.transform-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
  margin-top: 8px;
}
.transform-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px 7px;
  border-radius: 999px;
  background: #fff;
  color: #9096a0;
  font-size: 11px;
  font-weight: 500;
  transition: background 0.25s, color 0.25s;
}
.transform-chip svg {
  width: 10px;
  height: 10px;
}
.transform-chip.on {
  background: rgb(18 147 255 / 0.1);
  color: var(--blue);
}
.transform-summary {
  display: flex;
  align-items: center;
  height: 76px;
  padding: 0 16px;
  border-radius: 26px;
  transition: opacity 0.6s ease, transform 0.6s ease;
}
.transform-summary.enter {
  opacity: 0;
  transform: translateY(8px);
}
.transform-summary small {
  display: block;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.7px;
  color: rgb(255 255 255 / 0.85);
}
.transform-figure {
  display: flex;
  align-items: baseline;
  gap: 6px;
}
.transform-figure b {
  font-size: 30px;
  font-weight: 600;
  letter-spacing: -0.8px;
  font-variant-numeric: tabular-nums;
}
.transform-figure span {
  font-size: 16px;
  font-weight: 500;
  color: rgb(255 255 255 / 0.9);
}
/* Your AR routines: the ring. */
.picker-card {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 18px;
  border-radius: 32px;
  background: rgb(255 255 255 / 0.9);
}
.picker-ring {
  position: relative;
  height: 178px;
  overflow: hidden;
  margin: 0 -18px;
}
.ring-card {
  position: absolute;
  top: 25px;
  left: 50%;
  width: 96px;
  height: 128px;
  overflow: hidden;
  border: 1px solid rgb(255 255 255 / 0.7);
  border-radius: 22px;
  background: center / cover no-repeat;
  box-shadow: 0 6px 10px rgb(29 31 36 / 0.14);
  transition: transform 0.45s cubic-bezier(0.25, 1.1, 0.4, 1), opacity 0.3s;
}
.ring-card :is(video, :where(canvas.canvas-video)) {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity 0.3s;
}
.ring-card.featured :is(video, :where(canvas.canvas-video)) {
  opacity: 1;
}
.ring-shade {
  position: absolute;
  inset: 0;
  background: linear-gradient(transparent 50%, rgb(0 0 0 / 0.55));
}
.ring-title {
  position: absolute;
  left: 10px;
  right: 10px;
  bottom: 10px;
  color: #fff;
  font-size: 11.5px;
  font-weight: 600;
  line-height: 1.15;
}
.ring-added {
  position: absolute;
  top: 7px;
  right: 7px;
  width: 24px;
  height: 24px;
  padding: 6px;
  border-radius: 50%;
  background: var(--blue);
  color: #fff;
  opacity: 0;
  scale: 0.4;
  transition: opacity 0.25s ease, scale 0.25s cubic-bezier(0.3, 1.5, 0.5, 1);
}
.ring-card.added .ring-added {
  opacity: 1;
  scale: 1;
}
.ring-added svg {
  display: block;
  width: 100%;
  height: 100%;
}
/* Your plan. */
.plan-card-web {
  display: flex;
  flex-direction: column;
  padding: 18px;
  border-radius: 36px;
}
.plan-day-label {
  margin: 14px 0 8px;
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.8px;
  color: #9096a0;
}
.plan-days {
  display: flex;
  justify-content: space-between;
  gap: 4px;
}
.plan-day {
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  border: 1px solid rgb(255 255 255 / 0.8);
  border-radius: 50%;
  background: rgb(255 255 255 / 0.6);
  color: #9096a0;
  font-size: 14px;
  font-weight: 600;
  box-shadow: 0 2px 8px rgb(0 0 0 / 0.06);
}
.plan-day.today {
  align-content: center;
  gap: 0;
  background: #1d1f24;
  color: #fff;
  line-height: 1;
}
.plan-day.today small {
  font-size: 9px;
  font-weight: 600;
  color: rgb(255 255 255 / 0.65);
}
.plan-day.today b {
  font-size: 16px;
  font-weight: 500;
}
.plan-today {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 76px;
  margin-top: 14px;
  padding: 0 16px;
  border-radius: 26px;
  background: center / cover no-repeat;
  color: #fff;
}
.plan-today-words small {
  display: block;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.7px;
  color: rgb(255 255 255 / 0.85);
}
.plan-today-words b {
  font-size: 16px;
  font-weight: 500;
}
.plan-play {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: rgb(0 0 0 / 0.28);
}
.plan-play svg {
  width: 14px;
  height: 14px;
  color: #fff;
}
/* The skincare bundle, matched. */
.bundle-slot {
  position: relative;
  height: 130px;
  transition: height 0.6s ease;
}
.bundle-slot.settled {
  height: 112px;
}
.bundle-slot > * {
  position: absolute;
  inset: 0;
  transition: opacity 0.5s ease;
}
.bundle-slot > .leave,
.bundle-slot > .enter {
  opacity: 0;
}
.matcher-card {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 18px;
  border-radius: 36px;
  background: rgb(255 255 255 / 0.9);
}
.matcher-lane {
  overflow: hidden;
  mask: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
  -webkit-mask: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
}
.matcher-strip {
  display: flex;
  gap: 10px;
  width: max-content;
  /* 420px a second, as the app's: six wells of 66px. */
  animation: matcher 0.94s linear infinite;
}
@keyframes matcher {
  to {
    transform: translateX(-50%);
  }
}
.matcher-well {
  flex: none;
  width: 56px;
  height: 66px;
  padding: 10px;
  border: 1px solid #fff;
  border-radius: 20px;
  background: #fff;
  box-shadow: 0 3px 6px rgb(29 31 36 / 0.08);
}
.matcher-well img,
.bundle-thumb img,
.unlock-shot img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}
.bundle-row {
  display: flex;
  align-items: center;
  gap: 12px;
  height: 112px;
  padding: 18px;
  border-radius: 36px;
}
.bundle-thumbs {
  display: flex;
  align-items: center;
}
.bundle-thumb,
.bundle-more {
  display: grid;
  place-items: center;
  width: 52px;
  height: 76px;
  margin-right: -20px;
  padding: 8px;
  border: 1px solid rgb(255 255 255 / 0.9);
  border-radius: 16px;
  background: #fff;
  box-shadow: 0 4px 10px rgb(0 0 0 / 0.12);
}
.bundle-more {
  margin-right: 0;
  color: var(--blue);
  font-size: 15px;
  font-weight: 600;
}
.bundle-words {
  display: flex;
  flex-direction: column;
  gap: 3px;
  margin-left: 6px;
}
.bundle-words small {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.7px;
  color: rgb(255 255 255 / 0.75);
}
.bundle-words b {
  font-size: 18px;
  font-weight: 500;
}
.bundle-words span {
  font-size: 12.5px;
  font-weight: 500;
  color: rgb(255 255 255 / 0.88);
}
#to-roadmap:disabled {
  opacity: 1;
  background: rgb(255 255 255 / 0.6);
  color: #a3a3a3;
  box-shadow: inset 0 0 0 1px rgb(0 0 0 / 0.06);
  transition: background 0.55s ease, color 0.55s ease;
}

/* ── Roadmap: the app's RoadmapGrowthPage and its Paywall HQ ───────────────── */
html:has(body[data-screen='roadmap']),
body[data-screen='roadmap'],
body[data-screen='roadmap'] .shell {
  background: #f4f4f3;
}
body[data-screen='roadmap'] .header {
  display: none;
}
/* Still under the climb; only the page itself scrolls, so the title stays pinned. */
html.roadmap-climbing {
  overflow: hidden;
  touch-action: none;
}
.roadmap {
  position: relative;
  margin: 0 -24px;
  padding: 0;
  animation-name: results-appear;
}
.roadmap-title {
  position: sticky;
  top: 0;
  z-index: 4;
  margin: 0;
  padding: calc(4px + env(safe-area-inset-top)) 24px 28px;
  background: linear-gradient(#f4f4f3 70%, rgb(244 244 243 / 0));
  /* One line on every phone: wrapped onto two on a 375pt screen, it sat over the deck's
     captions. */
  font-size: clamp(24px, 7.8vw, 32px);
  font-weight: 500;
  letter-spacing: -1px;
  text-align: center;
  white-space: nowrap;
}
.roadmap-title span {
  color: var(--blue);
}
.road {
  position: absolute;
  inset: 0 0 auto;
}
.road-svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
}
.road-track {
  fill: none;
  stroke: rgb(18 147 255 / 0.22);
  stroke-width: 2.5;
  stroke-dasharray: 4 6;
  stroke-linecap: round;
}
.road-line {
  fill: none;
  stroke: var(--blue);
  stroke-width: 3;
  stroke-linecap: round;
  filter: drop-shadow(0 0 4px rgb(18 147 255 / 0.35));
}
.road-node,
.road-dot {
  position: absolute;
  display: grid;
  place-items: center;
  translate: -50% -50%;
  border-radius: 50%;
  transition:
    background 0.5s ease,
    color 0.5s ease,
    scale 0.5s ease,
    box-shadow 0.5s ease;
}
.road-node {
  z-index: 1;
  width: 40px;
  height: 40px;
  border: 1.5px solid rgb(18 147 255 / 0.3);
  background: #fff;
  color: rgb(18 147 255 / 0.5);
  scale: 0.85;
}
.road-node svg {
  width: 17px;
  height: 17px;
}
.road-node.lit {
  border-color: var(--blue);
  background: var(--blue);
  color: #fff;
  scale: 1;
  box-shadow: 0 3px 10px rgb(18 147 255 / 0.4);
}
.road-node.first.lit {
  box-shadow:
    0 3px 10px rgb(18 147 255 / 0.4),
    0 0 0 12px rgb(18 147 255 / 0.16);
}
.road-dot {
  width: 22px;
  height: 22px;
  border: 1px solid rgb(18 147 255 / 0.25);
  background: #fff;
  color: rgb(18 147 255 / 0.55);
  font-size: 10.5px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  scale: 0.85;
}
.road-dot.lit {
  border-color: var(--blue);
  background: var(--blue);
  color: #fff;
  scale: 1;
}
.road-card {
  position: absolute;
  display: flex;
  gap: 10px;
  width: 56%;
  padding: 14px;
  border-radius: 22px;
  translate: 0 -50%;
  background: rgb(255 255 255 / 0.6);
  opacity: 0;
  transition: opacity 0.5s ease, transform 0.5s ease;
}
.road-card.with-video {
  width: 58%;
}
.road-card.on-right {
  right: 16px;
  transform: translateX(16px);
}
.road-card.on-left {
  left: 16px;
  transform: translateX(-16px);
}
.road-card.lit {
  opacity: 1;
  transform: none;
}
.road-card-words {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}
.road-card p {
  margin: 0;
}
.road-eyebrow {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 1.1px;
  color: var(--blue);
}
.road-here {
  padding: 3px 7px;
  border-radius: 999px;
  background: var(--blue);
  color: #fff;
  font-size: 9.5px;
  letter-spacing: 0.8px;
}
.road-title {
  font-size: 16.5px;
  font-weight: 600;
  color: #1d1f24;
}
.road-detail {
  font-size: 13px;
  line-height: 1.3;
  color: #9096a0;
}
.road-video {
  flex: none;
  width: 56px;
  height: 100px;
  border-radius: 12px;
  background: #0c0b11;
  object-fit: cover;
}
/* The slide, and Commit to yourself. */
.roadmap-finish {
  position: absolute;
  left: 24px;
  right: 24px;
  z-index: 3;
  text-align: center;
}
.commit-label {
  margin: 0 0 14px;
  font-size: 15px;
  font-weight: 500;
  opacity: 0;
  transition: opacity 0.6s ease;
}
.roadmap.commit-in .commit-label {
  opacity: 1;
}
.committed-text,
.roadmap.settled .commit-text {
  display: none;
}
.roadmap.settled .committed-text {
  display: inline;
}
.roadmap.settled .committed-text::before {
  content: '✓ ';
  color: var(--blue);
}
.buy-now,
.roadmap.settled .start-journey {
  display: none;
}
/* In with the label as the climb reaches it. */
.start-journey {
  width: 100%;
  opacity: 0;
  transform: translateY(10px);
  transition: opacity 0.5s ease, transform 0.5s cubic-bezier(0.2, 0.8, 0.2, 1);
}
.roadmap.commit-in .start-journey {
  opacity: 1;
  transform: none;
}
.roadmap.settled .buy-now {
  display: block;
}
/* The road starts just under the slide: the lines below it sit on the page's own colour, so it
   runs behind them rather than through the words. */
.roadmap-finish .privacy-line,
.roadmap-finish .error {
  width: fit-content;
  margin: 10px auto 0;
  padding: 1px 8px;
  border-radius: 8px;
  background: #f4f4f3;
}
/* Under everything else, out of the flow, so the slide keeps its place over the road's foot. */
.roadmap-finish .commit-terms {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  margin-top: 8px;
  font-size: min(12px, 3.05vw);
  white-space: nowrap;
}
.roadmap-finish .commit-terms a {
  color: inherit;
  text-decoration: underline;
}
.roadmap-finish .error:empty,
.roadmap:not(.commit-in) .roadmap-finish .privacy-line {
  display: none;
}
.slide {
  --x: 0px;
  --p: 0;
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  user-select: none;
  touch-action: none;
  position: relative;
  height: 78px;
  border-radius: 999px;
  user-select: none;
  -webkit-user-select: none;
  touch-action: none;
}
.slide.outline {
  border: 1.5px dashed rgb(18 147 255 / 0.3);
}
.slide.outline > *,
.slide.bead > :not(.slide-fill) {
  opacity: 0;
  pointer-events: none;
}
.slide.bead,
.slide.spread {
  border: 0;
}
.slide-fill {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: calc(var(--x) + 78px);
  border-radius: 999px;
  background: linear-gradient(90deg, rgb(18 147 255 / 0.35), var(--blue));
  opacity: min(1, calc(var(--p) * 4));
}
.slide.bead .slide-fill {
  left: 50%;
  width: 78px;
  translate: -50% 0;
  background: var(--blue);
  opacity: 1;
  animation: slide-bead 0.3s cubic-bezier(0.3, 1.5, 0.5, 1);
}
@keyframes slide-bead {
  from {
    scale: 0.05;
    transform-origin: bottom;
  }
}
.slide.spread .slide-fill {
  width: 100%;
  background: var(--blue);
  opacity: 1;
  transition: width 0.46s cubic-bezier(0.25, 1.1, 0.4, 1);
}
.slide.ready,
.slide.spread {
  background: rgb(255 255 255 / 0.45);
  -webkit-backdrop-filter: blur(20px) saturate(1.8);
  backdrop-filter: blur(20px) saturate(1.8);
  box-shadow:
    inset 0 0 0 1px rgb(255 255 255 / 0.7),
    0 8px 24px rgb(0 0 0 / 0.06);
}
.slide.ready .slide-fill {
  transition: opacity 0.6s ease;
}
.slide-label {
  position: absolute;
  inset: 0 0 0 40px;
  display: grid;
  place-items: center;
  font-size: 19px;
  font-weight: 500;
  color: rgb(29 31 36 / 0.38);
  opacity: calc(1 - var(--p) * 2.2);
  background: linear-gradient(90deg, rgb(29 31 36 / 0.38) 0%, rgb(29 31 36 / 0.9) 50%, rgb(29 31 36 / 0.38) 100%) -100% 0 / 50% 100% no-repeat,
    rgb(29 31 36 / 0.38);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  animation: slide-shimmer 2.4s linear infinite;
}
@keyframes slide-shimmer {
  to {
    background-position: 200% 0, 0 0;
  }
}
.slide-done {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  color: #fff;
  font-size: 19px;
  font-weight: 500;
  opacity: 0;
  scale: 0.94;
  transition: opacity 0.4s ease, scale 0.4s ease;
}
.slide-thumb {
  position: absolute;
  top: 6px;
  left: calc(6px + var(--x));
  width: 66px;
  height: 66px;
  border: 0;
  border-radius: 50%;
  background: linear-gradient(#3da6ff, var(--blue)) center / 100% no-repeat;
  box-shadow: 0 4px 9px rgb(18 147 255 / 0.3);
  cursor: grab;
  touch-action: none;
  transition: left 0.38s cubic-bezier(0.25, 1.3, 0.4, 1), scale 0.2s ease, box-shadow 0.2s ease;
}
.slide-thumb::after {
  content: '';
  position: absolute;
  inset: 0;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12h14M13 6l6 6-6 6'/%3E%3C/svg%3E") center / 26px no-repeat;
}
.slide.dragging .slide-thumb {
  scale: 1.06;
  box-shadow: 0 4px 14px rgb(18 147 255 / 0.45);
  transition: scale 0.2s ease, box-shadow 0.2s ease;
}
.slide.committed .slide-fill {
  width: 100%;
  opacity: 1;
}
.slide.committed .slide-label {
  opacity: 0;
}
.slide.committed .slide-done {
  opacity: 1;
  scale: 1;
}
.slide.committed .slide-thumb::after {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='2.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12.5l4.5 4.5L19 7.5'/%3E%3C/svg%3E");
}
/* The deck of what they unlock. */
.roadmap-deck {
  position: absolute;
  top: calc(64px + env(safe-area-inset-top));
  left: 0;
  right: 0;
  z-index: 2;
  display: flex;
  flex-direction: column;
  opacity: 0;
  translate: 0 24px;
  pointer-events: none;
  transition: opacity 0.8s ease, translate 0.8s ease;
}
.roadmap.deck-in .roadmap-deck {
  opacity: 1;
  translate: 0 0;
  pointer-events: auto;
}
.deck-pages {
  display: flex;
  flex: 1;
  min-height: 0;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
}
.deck-pages::-webkit-scrollbar {
  display: none;
}
.deck-page {
  display: flex;
  flex: none;
  flex-direction: column;
  width: 100%;
  padding: 0 20px 22px;
  scroll-snap-align: center;
}
.deck-title {
  margin: 0 0 10px;
  font-size: 20px;
  font-weight: 500;
  letter-spacing: -0.4px;
  text-align: center;
}
.deck-body {
  display: flex;
  flex: 1;
  flex-direction: column;
  min-height: 0;
  padding-top: 4px;
}
.deck-dots {
  display: flex;
  justify-content: center;
  gap: 6px;
  margin-top: 12px;
}
.deck-dot {
  width: 6px;
  height: 6px;
  border-radius: 999px;
  background: rgb(29 31 36 / 0.18);
  transition: width 0.2s ease-out, background 0.2s ease-out;
}
.deck-dot.on {
  width: 18px;
  background: #1d1f24;
}
.deck-face {
  position: relative;
  flex: 1;
  min-height: 180px;
  overflow: hidden;
  border: 1px solid rgb(29 31 36 / 0.06);
  border-radius: 32px;
  background: #fff;
}
.deck-face-stage {
  position: absolute;
  inset: 0;
}
.deck-face-stage canvas,
.deck-face-fallback {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}
.deck-face-fallback {
  object-fit: cover;
}
.deck-caption {
  position: absolute;
  top: 22px;
  left: 50%;
  translate: -50% 0;
  display: flex;
  align-items: center;
  gap: 6px;
  height: 30px;
  padding: 0 12px;
  border-radius: 999px;
  font: 600 13px -apple-system, system-ui, sans-serif;
  color: #1d1f24;
  white-space: nowrap;
}
.deck-caption-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
}
.deck-picker {
  position: absolute;
  left: 12px;
  right: 12px;
  bottom: 12px;
  display: flex;
  gap: 6px;
}
.deck-pick {
  display: grid;
  flex: 1;
  place-items: center;
  min-height: 44px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 600;
  color: #1d1f24;
  transition: background 0.3s, color 0.3s;
}
.deck-pick.on {
  background: var(--blue);
  border-color: var(--blue);
  color: #fff;
}
.deck-stack {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: 10px;
  min-height: 0;
}
.deck-video {
  position: relative;
  flex: 1;
  min-height: 140px;
  overflow: hidden;
  border-radius: 32px;
  background: #0c0b11 center / cover no-repeat;
}
.deck-video :is(video, :where(canvas.canvas-video)) {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity 0.25s cubic-bezier(0.33, 1, 0.68, 1);
}
.deck-video :is(video, :where(canvas.canvas-video)).on {
  opacity: 1;
}
/* (Not until it's playing: the card's picture shows till then, or should it not play.) */
.deck-video :is(video, :where(canvas.canvas-video)).on:not(.live) {
  opacity: 0;
}
/* The app's own recordings (360 x 778): just the camera's view, from under the app's header
   (its exercise and round, which a crop by percentage cut in half) and no further than above
   its controls, the frame's 15% to 53%, whatever the card's shape. */
.deck-video.app {
  container-type: size;
}
.deck-video.app :is(video, :where(canvas.canvas-video)) {
  inset: auto;
  top: 0;
  left: 50%;
  width: max(100cqw, 122cqh);
  height: auto;
  aspect-ratio: 360 / 778;
  translate: -50% -15%;
}
.deck-video-shade {
  position: absolute;
  inset: 0;
  background: linear-gradient(rgb(0 0 0 / 0.35), transparent 50%);
}
.deck-pills {
  position: absolute;
  top: 12px;
  left: 12px;
  right: 12px;
  display: flex;
  justify-content: space-between;
}
.deck-pill {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 7px 11px;
  border-radius: 999px;
  background: rgb(255 255 255 / 0.2);
  border-color: rgb(255 255 255 / 0.3);
  color: #fff;
  font-size: 12px;
  font-weight: 600;
}
.deck-pill.blue {
  padding: 6px 10px;
  background: var(--blue);
  font-size: 11.5px;
}
.deck-pill svg {
  width: 12px;
  height: 12px;
}
.deck-stack .plan-card-web {
  flex: none;
  padding: 14px;
  border-radius: 28px;
}
.deck-stack .plan-day-label {
  margin-top: 8px;
}
.deck-stack .plan-today {
  height: 64px;
  margin-top: 10px;
}
.deck-stats {
  display: flex;
  gap: 10px;
}
.deck-stat {
  display: flex;
  flex: 1;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding: 12px 6px;
  border-radius: 26px;
  color: var(--blue);
  font-size: 14.5px;
  font-weight: 600;
  text-align: center;
}
.deck-stat svg {
  width: 20px;
  height: 20px;
}
.deck-stat span {
  color: #1d1f24;
}
.reviews {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: 8px;
  min-height: 0;
}
.reviews-summary {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 14px;
  border-radius: 24px;
}
.reviews-avatars {
  display: flex;
}
.reviews-avatars img {
  width: 34px;
  height: 34px;
  margin-left: -10px;
  border: 2px solid #fff;
  border-radius: 50%;
  object-fit: cover;
}
.reviews-avatars img:first-child {
  margin-left: 0;
}
.reviews-reach {
  display: flex;
  flex: 1;
  flex-direction: column;
}
.reviews-reach b {
  font-size: 14.5px;
  font-weight: 600;
}
.reviews-reach small {
  font-size: 11.5px;
  font-weight: 500;
  color: #9096a0;
}
.review {
  display: flex;
  flex: 1;
  gap: 10px;
  min-height: 0;
  padding: 8px;
  border-radius: 24px;
}
.review-pair {
  display: flex;
  flex: none;
  gap: 3px;
  width: 128px;
  overflow: hidden;
  border-radius: 18px;
}
.review-shot {
  position: relative;
  flex: 1;
}
.review-shot img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.review-label {
  position: absolute;
  top: 5px;
  left: 5px;
  padding: 3px 7px;
  border-radius: 999px;
  background: rgb(0 0 0 / 0.35);
  color: #fff;
  font-size: 9px;
  font-weight: 600;
}
.review-shot.after .review-label {
  background: var(--blue);
}
.review-words {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 4px;
  min-width: 0;
}
.review-stars {
  display: flex;
  gap: 1px;
  color: #f5b400;
}
.review-stars svg {
  width: 10px;
  height: 10px;
}
.review-words q {
  display: -webkit-box;
  overflow: hidden;
  font-size: 13px;
  font-weight: 500;
  line-height: 1.25;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
}
.review-words small {
  font-size: 11px;
  font-weight: 600;
  color: #9096a0;
}
.unlock-grid {
  display: grid;
  flex: 1;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: 1fr 1fr 56px;
  gap: 10px;
  min-height: 0;
}
.unlock-routine {
  position: relative;
  grid-row: 1 / 3;
  overflow: hidden;
  border: 1px solid rgb(255 255 255 / 0.85);
  border-radius: 26px;
  background: center / cover no-repeat;
  box-shadow: 0 8px 18px rgb(29 31 36 / 0.12);
}
.unlock-play {
  position: absolute;
  top: 12px;
  right: 12px;
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: rgb(0 0 0 / 0.3);
  color: #fff;
}
.unlock-play svg {
  width: 12px;
  height: 12px;
}
.unlock-routine-words {
  position: absolute;
  left: 14px;
  right: 14px;
  bottom: 14px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
  color: #fff;
}
.unlock-routine-words small {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.7px;
  color: rgb(255 255 255 / 0.85);
}
.unlock-routine-words b {
  font-size: 16px;
  font-weight: 500;
}
.unlock-chat {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 8px;
  padding: 12px;
  border-radius: 26px;
}
.unlock-ask,
.unlock-reply {
  max-width: 90%;
  padding: 6px 10px;
  font-size: 11.5px;
  font-weight: 500;
  line-height: 1.25;
}
.unlock-ask {
  align-self: flex-end;
  border-radius: 999px;
  background: rgb(255 255 255 / 0.85);
}
.unlock-reply {
  align-self: flex-start;
  border-radius: 14px;
  background: var(--blue);
  color: #fff;
}
.unlock-report {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 12px;
  border-radius: 26px;
}
.unlock-report small {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.7px;
  color: #9096a0;
}
.unlock-spark {
  flex: 1;
  min-height: 0;
}
.unlock-spark svg {
  display: block;
  width: 100%;
  height: 100%;
}
.unlock-strip {
  display: flex;
  grid-column: 1 / 3;
  align-items: center;
  gap: 10px;
  padding: 8px;
  border-radius: 999px;
}
.unlock-shots {
  display: flex;
  gap: 6px;
}
.unlock-shot {
  width: 40px;
  height: 40px;
  padding: 5px;
  border-radius: 14px;
  background: #fff;
}
.unlock-strip-words {
  display: flex;
  flex-direction: column;
}
.unlock-strip-words b {
  font-size: 16px;
  font-weight: 500;
}
.unlock-strip-words span {
  font-size: 12px;
  font-weight: 500;
  color: rgb(255 255 255 / 0.88);
}

/* ── Variation B (?v=b): the short take for a younger audience ─────────────────
   Everything here is scoped to html.v-b, so the default funnel is untouched. */

.b-only {
  display: none;
}
.v-b .b-only {
  display: block;
}
.v-b {
  --b-gradient: linear-gradient(120deg, #2fa8ff 0%, #1283ff 48%, #6a5cff 100%);
  --b-solid: #1283ff;
  --b-soft: #f5f9ff;
}

/* The way to the plan, along the foot of the header, from the first question on. */
.v-b .header {
  position: relative;
}
.journey {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 2px;
  height: 5px;
  border-radius: 99px;
  background: #eef1f6;
  overflow: hidden;
}
.journey span {
  display: block;
  height: 100%;
  border-radius: inherit;
  background: var(--b-gradient);
  transform: scaleX(var(--done, 0));
  transform-origin: left;
  transition: transform 0.7s cubic-bezier(0.2, 0.8, 0.2, 1);
}
.v-b body[data-screen='intro'] .journey {
  display: none;
}

/* The splash: the proof above the hook, the hook's words in the gradient, a livelier button. */
.v-b .proof {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 16px;
  padding: 7px 14px 7px 12px;
  border-radius: 99px;
  background: rgb(255 255 255 / 0.86);
  border: 1px solid rgb(0 0 0 / 0.06);
  box-shadow: 0 6px 20px rgb(16 40 80 / 0.08);
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: -0.1px;
  color: #1d1f24;
}
.proof-stars {
  color: #ffb400;
  letter-spacing: 1px;
  font-size: 12px;
}
.v-b .splash h1 {
  font-size: 34px;
  letter-spacing: -1.1px;
}
.v-b .splash h1 span,
.v-b .results-title .accent {
  background: var(--b-gradient);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.v-b .pitch {
  margin-bottom: 28px;
}
.v-b .get-started {
  min-height: 58px;
  font-size: 18px;
  animation: b-glow 2.6s ease-in-out infinite;
}

/* Every main button: the gradient, a light catching across it now and then. */
.v-b .primary {
  position: relative;
  overflow: hidden;
  background: var(--b-gradient);
  font-weight: 600;
  box-shadow:
    inset 0 1px 0 rgb(255 255 255 / 0.35),
    0 12px 30px rgb(24 112 255 / 0.3);
}
.v-b .primary:hover {
  background: var(--b-gradient);
  filter: brightness(1.05);
}
.v-b .primary::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(105deg, transparent 35%, rgb(255 255 255 / 0.38) 50%, transparent 65%);
  transform: translateX(-120%);
  animation: b-shine 3.4s ease-in-out 1s infinite;
  pointer-events: none;
}
.v-b .primary:disabled::after {
  animation: none;
}
@keyframes b-shine {
  0%,
  62% {
    transform: translateX(-120%);
  }
  100% {
    transform: translateX(120%);
  }
}
@keyframes b-glow {
  0%,
  100% {
    box-shadow:
      inset 0 1px 0 rgb(255 255 255 / 0.35),
      0 12px 30px rgb(24 112 255 / 0.3);
  }
  50% {
    box-shadow:
      inset 0 1px 0 rgb(255 255 255 / 0.35),
      0 14px 40px rgb(90 92 255 / 0.48);
  }
}


@media (prefers-reduced-motion: reduce) {
  .v-b .get-started,
  .v-b .primary::after {
    animation: none;
  }
  .journey span {
    transition: none;
  }
}

/* B's quiz, How FaceKit works and the tips: one thing a page, the button at the foot. */
.quiz,
.guide,
.tips {
  display: flex;
  flex-direction: column;
  min-height: var(--page);
  padding: 18px 0 0;
}
.quiz.turn > :not(.cta-bar) {
  animation: b-rise 0.32s cubic-bezier(0.2, 0.8, 0.2, 1) both;
}
.quiz.turn > :nth-child(2) { animation-delay: 0.02s; }
.quiz.turn > :nth-child(3) { animation-delay: 0.05s; }
.quiz.turn > :nth-child(4) { animation-delay: 0.08s; }
.quiz.turn > :nth-child(5),
.quiz.turn > :nth-child(6) { animation-delay: 0.12s; }
@keyframes b-rise {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
}
.quiz-count {
  margin: 0 0 18px;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.2px;
  color: var(--b-solid);
}
.quiz-title {
  margin: 0;
  font-size: 30px;
  font-weight: 600;
  letter-spacing: -0.9px;
  line-height: 1.12;
  color: #0c0b11;
  outline: none;
}
.quiz-field {
  margin-top: 28px;
}
.quiz-input {
  width: 100%;
  height: 72px;
  padding: 0 22px;
  border: 1.5px solid #e4e7ec;
  border-radius: 22px;
  background: #fff;
  font-size: 30px;
  font-weight: 600;
  letter-spacing: -0.5px;
  color: #0c0b11;
  outline: none;
}
.quiz-input:focus {
  border-color: var(--b-solid);
  box-shadow: 0 0 0 4px rgb(18 131 255 / 0.12);
}
.quiz-input::placeholder {
  color: #c3c8d0;
}

/* How FaceKit works: the three steps, each lighting up in turn with its clip from the app. */
.guide-steps {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin: 24px 0 0;
  padding: 0;
  list-style: none;
}
.guide-step {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 10px;
  border: 1.5px solid #eef0f4;
  border-radius: 24px;
  background: #fff;
  opacity: 0.45;
  transform: scale(0.98);
  transition: opacity 0.4s ease, transform 0.4s ease, border-color 0.4s ease, box-shadow 0.4s ease;
  cursor: pointer;
}
.guide-step.seen {
  opacity: 0.8;
  transform: none;
}
.guide-step.on {
  opacity: 1;
  transform: none;
  border-color: #cfe4ff;
  box-shadow: 0 12px 32px rgb(18 112 255 / 0.12);
}
.guide-shot {
  flex: none;
  width: 92px;
  height: 118px;
  overflow: hidden;
  border-radius: 16px;
  background: #f1f3f6;
}
.guide-shot :is(video, :where(canvas.canvas-video)),
.guide-shot img.as-video {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.guide-step.on .guide-shot {
  width: 112px;
  height: 144px;
  transition: width 0.4s ease, height 0.4s ease;
}
.guide-words {
  display: flex;
  flex-direction: column;
  gap: 3px;
}
.guide-number {
  display: grid;
  place-items: center;
  width: 24px;
  height: 24px;
  margin-bottom: 4px;
  border-radius: 50%;
  background: #eef1f6;
  font-size: 13px;
  font-weight: 700;
  color: #6b7280;
}
.guide-step.on .guide-number,
.guide-step.seen .guide-number {
  background: var(--b-gradient);
  color: #fff;
}
.guide-words strong {
  font-size: 18px;
  font-weight: 600;
  letter-spacing: -0.3px;
}

/* The tips: the app's own scan screen, and the three things to do. */
.tips-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin: 0;
  padding: 0;
  list-style: none;
}
.tips-list li {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 12px 14px;
  border-radius: 18px;
  background: #f6f8fb;
}
.tips-icon {
  flex: none;
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border-radius: 12px;
  background: #fff;
  color: var(--b-solid);
}
.tips-icon svg {
  width: 22px;
  height: 22px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.tips-list strong {
  display: block;
  font-size: 16px;
  font-weight: 600;
}

/* B's results: their goals and the app's routines for them, what the plan unlocks, a real
   before and after. */
.v-b .b-results {
  display: flex;
  flex-direction: column;
  gap: 12px;
  width: min(100%, 345px);
  margin: 18px 0 0;
  text-align: left;
}
.b-card {
  padding: 16px;
  border: 1px solid #eef0f4;
  border-radius: 24px;
  background: #fff;
  box-shadow: 0 8px 26px rgb(16 40 80 / 0.06);
}
.b-eyebrow {
  margin: 0 0 12px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.6px;
  text-transform: uppercase;
  color: var(--b-solid);
}









@media (prefers-reduced-motion: reduce) {
  .quiz.turn > * {
    animation: none;
  }
}

/* B's answers: rows with a radio, and the goals as the app's routine covers. */
.quiz-options {
  margin-top: 24px;
}
.quiz-options.rows {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.quiz-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: 60px;
  padding: 0 18px 0 20px;
  border: 1.5px solid #ebedf1;
  border-radius: 18px;
  background: #fff;
  text-align: left;
  transition: border-color 0.15s ease, background 0.15s ease, transform 0.15s ease;
}
.quiz-row:active {
  transform: scale(0.98);
}
.quiz-row .quiz-label {
  font-size: 17px;
  font-weight: 500;
  letter-spacing: -0.2px;
  color: #1d1f24;
}
.quiz-radio {
  position: relative;
  flex: none;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  border: 1.5px solid #d4d8df;
  transition: border-color 0.15s ease;
}
.quiz-row[aria-pressed='true'] {
  border-color: var(--b-solid);
  background: var(--b-soft);
}
.quiz-row[aria-pressed='true'] .quiz-radio {
  border: 6.5px solid var(--b-solid);
}
.quiz-options.chips {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
}
.quiz-chip {
  min-height: 54px;
  padding: 0 14px;
  border: 1.5px solid #ebedf1;
  border-radius: 16px;
  background: #fff;
  font-size: 16px;
  font-weight: 500;
  letter-spacing: -0.2px;
  color: #1d1f24;
  transition: border-color 0.15s ease, background 0.15s ease, color 0.15s ease, transform 0.15s ease;
}
.quiz-chip:active {
  transform: scale(0.98);
}
.quiz-chip[aria-pressed='true'] {
  border-color: var(--b-solid);
  background: var(--b-solid);
  color: #fff;
}
/* The app's scan screen above the tips. */
.tips-shot {
  align-self: center;
  width: 150px;
  height: 196px;
  margin: 22px 0 18px;
  overflow: hidden;
  border-radius: 24px;
  border: 1px solid #eef0f4;
  box-shadow: 0 14px 34px rgb(16 40 80 / 0.1);
}
.tips-shot img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
/* B's splash is headlines only. */
.v-b .pitch-sub {
  display: none;
}
.v-b .locked-box-words small {
  display: none;
}

/* ── Short funnels: shared pieces ─────────────────────────────────────────── */

/* A headline's key words, starred in its copy, in the accent. */
.quiz-title span {
  color: var(--b-solid);
}

/* The app, App Store style: the icon, what lives there, and the device it's for. */
.app-card {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 14px 16px 14px 14px;
  border: 1px solid rgb(0 0 0 / 0.06);
  border-radius: 24px;
  background: #fff;
  box-shadow: 0 10px 30px rgb(16 24 40 / 0.07);
  text-align: left;
}
.v-b .app-card.b-only {
  display: flex;
}
.app-card img {
  flex: none;
  width: 52px;
  height: 52px;
  border-radius: 13px;
  box-shadow: 0 0 0 1px rgb(0 0 0 / 0.06);
}
.app-card strong {
  flex: 1;
  font-size: 16px;
  font-weight: 600;
  line-height: 1.25;
  letter-spacing: -0.2px;
  color: #1d1f24;
}
.app-card strong span {
  color: var(--b-solid);
}
.app-pill {
  flex: none;
  padding: 7px 13px;
  border-radius: 99px;
  background: #f0f1f4;
  font-size: 13px;
  font-weight: 700;
  color: var(--b-solid);
}

/* F: the funnel's own blue accents in rose (generated from the rules above whose final value is a blue). */
.v-f button:focus-visible {
  outline: 3px solid #a8285b;
}
.v-f a:focus-visible {
  outline: 3px solid #a8285b;
}
.v-f .orbit {
  border: 1px solid #e5467f30;
}
.v-f .viewfinder.has-face {
  filter: drop-shadow(0 0 17px #e5467f38);
}
.v-f .primary {
  box-shadow: 0 10px 26px #e5467f33;
}
.v-f .primary:hover {
  background: #c2306a;
}
.v-f .measure-ring {
  background: conic-gradient(var(--blue) calc(var(--fill) * 360deg), #e5467f26 0);
}
.v-f .path-dot {
  filter: drop-shadow(0 1px 3px rgb(229 70 127 / 0.3));
}
.v-f .coach-send {
  box-shadow: 0 8px 20px #e5467f40;
}
.v-f .eyebrow {
  color: #e5467f;
}
.v-f .result-face {
  filter: drop-shadow(0 0 17px #e5467f38);
}
.v-f .teaser-dot {
  background: #e5467f;
  box-shadow: 0 0 0 5px rgb(229 70 127 / 0.16);
}
.v-f .locked-box-icon {
  background: #e5467f url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 20'%3E%3Cpath d='M4 8.5V6a4 4 0 0 1 8 0v2.5' fill='none' stroke='%23fff' stroke-width='2.2'/%3E%3Crect x='1' y='8' width='14' height='11' rx='2.6' fill='%23fff'/%3E%3C/svg%3E") center / 15px 18px no-repeat;
  box-shadow: 0 6px 16px rgb(229 70 127 / 0.35);
}
.v-f .glass.blue {
  background: rgb(229 70 127 / 0.9);
  box-shadow: 0 10px 26px rgb(229 70 127 / 0.28);
}
.v-f .transform-chip.on {
  background: rgb(229 70 127 / 0.1);
}
.v-f .road-track {
  stroke: rgb(229 70 127 / 0.22);
}
.v-f .road-line {
  filter: drop-shadow(0 0 4px rgb(229 70 127 / 0.35));
}
.v-f .road-node {
  border: 1.5px solid rgb(229 70 127 / 0.3);
  color: rgb(229 70 127 / 0.5);
}
.v-f .road-node.lit {
  box-shadow: 0 3px 10px rgb(229 70 127 / 0.4);
}
.v-f .road-node.first.lit {
  box-shadow:
    0 3px 10px rgb(229 70 127 / 0.4),
    0 0 0 12px rgb(229 70 127 / 0.16);
}
.v-f .road-dot {
  border: 1px solid rgb(229 70 127 / 0.25);
  color: rgb(229 70 127 / 0.55);
}
.v-f .slide.outline {
  border: 1.5px dashed rgb(229 70 127 / 0.3);
}
.v-f .slide-fill {
  background: linear-gradient(90deg, rgb(229 70 127 / 0.35), var(--blue));
}
.v-f .slide-thumb {
  box-shadow: 0 4px 9px rgb(229 70 127 / 0.3);
}
.v-f .slide.dragging .slide-thumb {
  box-shadow: 0 4px 14px rgb(229 70 127 / 0.45);
}
.v-f {
  --blue: #e5467f;
}

/* ── F (?v=f): women, in BeautyKit's language ──────────────────────────────
   A whisper-warm canvas, rose on the key words only, black capsule buttons with no sheen, and
   content on white cards with a hairline. */
.v-f {
  --b-gradient: linear-gradient(120deg, #f7a3c4, #e5467f);
  --b-solid: #e5467f;
  --b-soft: #fceaf1;
  --f-canvas: #f8f5f4;
  --f-ink: #1d1f24;
  --f-deep: #c2306a;
}
.v-f body,
.v-f .shell,
.v-f body[data-screen='intro'] .shell,
.v-f .splash {
  background: var(--f-canvas);
}
.v-f .wall-fade.top {
  background: linear-gradient(rgb(248 245 244 / 0.9), rgb(248 245 244 / 0));
}
.v-f .wall-fade.bottom {
  background: linear-gradient(rgb(248 245 244 / 0), var(--f-canvas) 82%);
}
.v-f .cta-bar {
  background: linear-gradient(rgb(248 245 244 / 0), var(--f-canvas) 30%);
}
.v-f .results .cta-bar {
  background: linear-gradient(rgb(248 245 244 / 0), rgb(248 245 244 / 0.94) 50%);
}
/* Primary actions: the black capsule. */
.v-f .primary {
  min-height: 60px;
  background: var(--f-ink);
  font-size: 18px;
  font-weight: 500;
  letter-spacing: -0.2px;
  box-shadow: 0 12px 28px rgb(0 0 0 / 0.16);
  animation: none;
}
.v-f .primary:hover {
  background: #000;
  filter: none;
}
.v-f .primary::after {
  display: none;
}
.v-f .primary:disabled {
  opacity: 1;
  background: rgb(29 31 36 / 0.18);
  box-shadow: none;
}
.v-f .get-started {
  animation: none;
}
/* One accent: solid rose on the key words, never a gradient. */
.v-f .splash h1 span,
.v-f .results-title .accent {
  background: none;
  -webkit-background-clip: border-box;
  background-clip: border-box;
  color: var(--b-solid);
}
.v-f .journey span {
  background: var(--b-solid);
}
.v-f .journey {
  background: rgb(0 0 0 / 0.06);
}
.v-f .quiz-count,
.v-f .b-eyebrow {
  color: var(--f-deep);
}
/* Choices: white cards with a hairline; picked, rose. */
.v-f .quiz-row,
.v-f .quiz-chip,
.v-f .quiz-input,
.v-f .guide-step,
.v-f .b-card {
  border-color: rgb(0 0 0 / 0.06);
  box-shadow: 0 6px 18px rgb(16 24 40 / 0.04);
}
.v-f .quiz-row[aria-pressed='true'] {
  border-color: var(--b-solid);
  background: #fff;
}
.v-f .quiz-chip[aria-pressed='true'] {
  border-color: var(--b-solid);
  background: var(--b-solid);
}
.v-f .quiz-input:focus {
  border-color: var(--b-solid);
  box-shadow: 0 0 0 4px rgb(229 70 127 / 0.12);
}
.v-f .guide-step.on {
  border-color: #f7cfdf;
  box-shadow: 0 12px 32px rgb(229 70 127 / 0.12);
}
.v-f .guide-step.on .guide-number,
.v-f .guide-step.seen .guide-number {
  background: var(--b-solid);
}
.v-f .tips-list li {
  background: #fff;
  border: 1px solid rgb(0 0 0 / 0.05);
}
.v-f .tips-icon {
  background: var(--b-soft);
}
.v-f .proof-stars {
  color: #f5b400;
}
/* The results' own accents, in rose. */
.v-f .result-views button.on {
  background: var(--b-solid);
}
.v-f .teaser-dot {
  background: var(--b-solid);
  box-shadow: 0 0 0 5px rgb(229 70 127 / 0.16);
}
.v-f .locked-box-icon {
  background-color: var(--b-solid);
  box-shadow: 0 8px 20px rgb(229 70 127 / 0.3);
}
/* With their cards below the face, the short funnels' results grow past one screen: the face
   keeps a fixed height rather than filling it, and the page keeps its room under the button. */
.v-b .results.in-3d {
  height: auto;
  min-height: 100dvh;
}
.v-b .results.in-3d .result-face {
  flex: none;
  height: min(56dvh, 460px);
}
/* Scan first's: the face smaller (Johan: it was way too big), its scores and cards up under it. */
.v-s .results.in-3d .result-face {
  height: min(42dvh, 340px);
}

/* The short funnels' commit line: where the plan opens, the app's icon beside it. */
.commit-app {
  display: none;
}
.v-b .commit-text {
  display: none;
}
.v-b .roadmap:not(.settled) .commit-app {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}
.commit-app img {
  border-radius: 6px;
  box-shadow: 0 0 0 1px rgb(0 0 0 / 0.06);
}
.commit-app b {
  font-weight: 600;
  color: var(--b-solid);
}
/* F's slide: the rose gradient, BeautyKit's. */
.v-f .slide-thumb {
  background: linear-gradient(#f7a3c4, #e5467f) center / 100% no-repeat;
}
/* Clear of the deck's dots just above it. */
.v-b .commit-label {
  margin-top: 26px;
}

/* ── F's app screens, drawn in rose (mini-screens.js) ─────────────────────── */
.mini-frame {
  position: absolute;
  inset: 0;
  overflow: hidden;
  background: #f8f5f4;
}
.mini {
  position: absolute;
  top: 0;
  left: 0;
  width: 402px;
  height: 900px;
  padding: 0 20px;
  transform-origin: 0 0;
  background: #f8f5f4;
  color: #1d1f24;
  font-family: Rebond, system-ui, sans-serif;
  text-align: left;
}
.mini span[class],
.mini div {
  box-sizing: border-box;
}
.mini-status {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 54px;
  padding: 6px 12px 0;
  font-size: 16px;
  font-weight: 600;
}
.mini-island {
  width: 0;
}
.mini-icons {
  width: 64px;
  height: 12px;
  border-radius: 4px;
  background: linear-gradient(90deg, #1d1f24 0 26%, transparent 26% 37%, #1d1f24 37% 63%, transparent 63% 74%, #1d1f24 74%);
  opacity: 0.85;
}
.mini-title {
  margin: 10px 0 16px;
  font-size: 34px;
  font-weight: 600;
  letter-spacing: -1px;
}
.mini-hello {
  margin: 14px 0 -10px;
  font-size: 18px;
  font-weight: 500;
  color: #9096a0;
}
.mini-card {
  padding: 16px;
  border: 1px solid rgb(0 0 0 / 0.06);
  border-radius: 26px;
  background: #fff;
  box-shadow: 0 8px 24px rgb(16 24 40 / 0.05);
}
.mini-button {
  display: block;
  margin-top: 18px;
  padding: 19px 0;
  border-radius: 99px;
  background: #1d1f24;
  color: #fff;
  font-size: 19px;
  font-weight: 500;
  text-align: center;
}
.mini-tabs {
  display: inline-flex;
  gap: 4px;
  padding: 4px;
  border-radius: 99px;
  background: #fff;
  border: 1px solid rgb(0 0 0 / 0.06);
}
.mini-tabs span {
  padding: 9px 20px;
  border-radius: 99px;
  font-size: 16px;
  font-weight: 600;
  color: #4e525b;
}
.mini-tabs .on {
  background: #e5467f;
  color: #fff;
}
.mini-face {
  position: relative;
  display: block;
  height: 380px;
  margin: 16px 0;
  border-radius: 30px;
  background: #eee center 38% / cover no-repeat;
}
.mini-pin {
  position: absolute;
  padding: 8px 13px 8px 26px;
  border-radius: 99px;
  background: rgb(255 255 255 / 0.92);
  font-size: 14px;
  font-weight: 600;
  box-shadow: 0 6px 16px rgb(0 0 0 / 0.08);
}
.mini-pin::before {
  content: '';
  position: absolute;
  left: 11px;
  top: 50%;
  width: 8px;
  height: 8px;
  margin-top: -4px;
  border-radius: 50%;
  background: #e5467f;
}
.mini-pin.a { left: 14px; top: 78px; }
.mini-pin.b { right: 14px; top: 170px; }
.mini-pin.c { left: 22px; bottom: 60px; }
.mini-scores {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
}
.mini-score {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding: 14px 0;
  border: 1px solid rgb(0 0 0 / 0.06);
  border-radius: 22px;
  background: #fff;
  font-size: 14px;
  font-weight: 600;
  color: #4e525b;
}
.mini-ring {
  position: relative;
  display: grid;
  place-items: center;
}
.mini-ring svg {
  display: block;
  fill: none;
}
.mini-ring .t {
  stroke: #fceaf1;
}
.mini-ring .v {
  stroke: #e5467f;
  stroke-linecap: round;
}
.mini-ring b {
  position: absolute;
  font-size: 20px;
  font-weight: 600;
  color: #1d1f24;
}
.mini-days {
  display: flex;
  justify-content: space-between;
  margin-bottom: 18px;
}
.mini-days span {
  display: grid;
  place-items: center;
  width: 46px;
  height: 46px;
  border-radius: 50%;
  background: #fff;
  border: 1px solid rgb(0 0 0 / 0.06);
  font-size: 18px;
  font-weight: 600;
  color: #9096a0;
}
.mini-days .done {
  background: #fceaf1;
  border-color: transparent;
  color: #c2306a;
}
.mini-days .on {
  background: #1d1f24;
  border-color: transparent;
  color: #fff;
}
.mini-row {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 10px 0;
}
.mini-row + .mini-row {
  border-top: 1px solid rgb(0 0 0 / 0.06);
}
.mini-thumb {
  flex: none;
  width: 74px;
  height: 74px;
  border-radius: 18px;
  background: #eee center 30% / cover no-repeat;
}
.mini-words {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: 4px;
}
.mini-words b {
  font-size: 19px;
  font-weight: 600;
}
.mini-words small {
  font-size: 15px;
  color: #9096a0;
}
.mini-play {
  position: relative;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: #fceaf1;
}
.mini-play::after {
  content: '';
  position: absolute;
  left: 16px;
  top: 12px;
  border: 8px solid transparent;
  border-left: 12px solid #e5467f;
  border-right: 0;
}
.mini-hero {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 24px;
  border-radius: 28px;
  background: linear-gradient(135deg, #f7a3c4, #e5467f);
  color: #fff;
}
.mini-hero small {
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0.6px;
  text-transform: uppercase;
  opacity: 0.85;
}
.mini-hero b {
  font-size: 30px;
  font-weight: 600;
  letter-spacing: -0.6px;
}
.mini-products {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
  margin-top: 16px;
}
.mini-product {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 14px;
  border: 1px solid rgb(0 0 0 / 0.06);
  border-radius: 24px;
  background: #fff;
  font-size: 15px;
  font-weight: 600;
  line-height: 1.2;
}
.mini-bottle {
  display: block;
  height: 140px;
  border-radius: 16px;
  background: #fbf8f7 center / contain no-repeat;
}
.mini-chart {
  height: 230px;
  padding: 18px 18px 0;
  overflow: hidden;
}
.mini-chart svg {
  display: block;
  width: 100%;
  height: 150px;
  margin-top: 14px;
}
.mini-chart-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
}
.mini-chart-head b {
  font-size: 22px;
  font-weight: 600;
}
.mini-chart-head span {
  font-size: 15px;
  color: #9096a0;
}
.mini-pair {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
  margin-top: 14px;
}
.mini-shot {
  display: block;
  height: 300px;
  border-radius: 24px;
  background: #eee center 40% / cover no-repeat;
}
.mini-streak {
  display: flex;
  align-items: center;
  gap: 18px;
  margin-top: 22px;
}
.mini-today {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: 4px;
  height: 330px;
  margin-top: 14px;
  padding: 22px;
  border-radius: 28px;
  background: #eee center 30% / cover no-repeat;
  color: #fff;
  overflow: hidden;
  isolation: isolate;
}
.mini-today::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(rgb(0 0 0 / 0) 45%, rgb(0 0 0 / 0.55));
}
.mini-today small {
  font-size: 15px;
  font-weight: 600;
  letter-spacing: 0.6px;
  text-transform: uppercase;
  opacity: 0.85;
}
.mini-today b {
  font-size: 28px;
  font-weight: 600;
}
.guide-shot {
  position: relative;
}
/* The analysis panel's ruler, in rose. */
.v-f .ruler {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14 9'%3E%3Crect x='.75' y='.75' width='12.5' height='7.5' rx='1.5' fill='none' stroke='%23e5467f' stroke-width='1.5'/%3E%3Cpath d='M4 1v3M7 1v4M10 1v3' stroke='%23e5467f' stroke-width='1.3'/%3E%3C/svg%3E");
}
.v-f .plan-title {
  font-size: 29px;
}

/* ── Short funnels' results: the rest locked, in one by one ── */
.v-b .locked-chips,
.v-b .locked-box,
.v-b #potential-below {
  display: none;
}
/* No reading's score under the face (Rafael): the tour and the locked cards say it. */
.v-b .teaser {
  display: none;
}
/* The cards rise in after the face's sweep, one after another. */
.v-b .b-results > * {
  opacity: 0;
}
.v-b .b-results.in > * {
  animation: b-card-in 0.6s cubic-bezier(0.2, 0.8, 0.2, 1) both;
}
.v-b .b-results.in > :nth-child(1) { animation-delay: 1.5s; }
.v-b .b-results.in > :nth-child(2) { animation-delay: 1.75s; }
.v-b .b-results.in > :nth-child(3) { animation-delay: 2s; }
/* The app last, as it was before scan first's cards (hidden in B) came in among them. */
.v-b .b-results.in > .app-card { animation-delay: 1.75s; }
.v-b .b-results.in > .partner-card ~ .app-card { animation-delay: 2s; }
@keyframes b-card-in {
  from {
    opacity: 0;
    transform: translateY(18px) scale(0.98);
  }
  to {
    opacity: 1;
    transform: none;
  }
}
/* The other readings: three across, each value blurred under a lock. */
.b-locked-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px;
}
.b-tile {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  padding: 14px 6px 12px;
  border-radius: 18px;
  background: var(--b-soft);
  overflow: hidden;
}
.v-b .b-results.in .b-tile {
  animation: b-tile-in 0.45s ease both;
  animation-delay: calc(1.6s + var(--i) * 0.09s);
}
@keyframes b-tile-in {
  from {
    opacity: 0;
    transform: scale(0.92);
  }
}
.b-tile-name {
  font-size: 13px;
  font-weight: 600;
  color: #4e525b;
}
.b-tile-value {
  font-size: 30px;
  font-weight: 600;
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
  color: var(--b-solid);
  filter: blur(5px);
  user-select: none;
}
.b-tile-label {
  display: inline-flex;
  align-items: center;
  gap: 5px;
}
/* The value, blurred, with its lock over it (Johan: over the number, not by the name). */
.b-tile-figure {
  position: relative;
  display: grid;
  place-items: center;
}
.b-tile-figure .b-tile-lock {
  position: absolute;
  width: 26px;
  height: 26px;
  background-size: 10px 12px;
}
.b-tile-lock {
  flex: none;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: #fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 20'%3E%3Cpath d='M4 8.5V6a4 4 0 0 1 8 0v2.5' fill='none' stroke='%231d1f24' stroke-width='2.2'/%3E%3Crect x='1' y='8' width='14' height='11' rx='2.6' fill='%231d1f24'/%3E%3C/svg%3E") center / 8px 10px no-repeat;
  box-shadow: 0 2px 6px rgb(0 0 0 / 0.08);
}
/* A light passing over the locked values now and then. */
.b-tile::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(105deg, transparent 35%, rgb(255 255 255 / 0.55) 50%, transparent 65%);
  transform: translateX(-120%);
  animation: b-shine 4s ease-in-out infinite;
  animation-delay: calc(3s + var(--i) * 0.12s);
  pointer-events: none;
}
@media (prefers-reduced-motion: reduce) {
  .v-b .b-results > *,
  .v-b .b-results.in > *,
  .v-b .b-results.in .b-tile {
    opacity: 1;
    animation: none;
  }
  .b-tile::after {
    display: none;
  }
}

/* ── Short funnels: pages hand over instead of cutting ─────────────────────── */
/* The page on show fades out (app.js leaveThen), the next fades and rises in. */
.v-b .screen.leaving {
  opacity: 0;
  transform: translateY(-6px);
  transition: opacity 0.24s ease, transform 0.24s ease;
}
.v-b #quiz,
.v-b #guide,
.v-b #tips,
.v-b #scan,
.v-b #analysis,
.v-b #potential,
.v-b #plan {
  animation: b-screen-in 0.5s cubic-bezier(0.2, 0.8, 0.2, 1) both;
}
@keyframes b-screen-in {
  from {
    opacity: 0;
    transform: translateY(12px);
  }
}
/* The results and the roadmap fade only (a transform would anchor their fixed parts to them),
   and a little slower. */
.v-b #results,
.v-b #roadmap {
  animation-duration: 0.7s;
}
.v-b #results.leaving,
.v-b #roadmap.leaving {
  transform: none;
}
@media (prefers-reduced-motion: reduce) {
  .v-b #quiz,
  .v-b #guide,
  .v-b #tips,
  .v-b #scan,
  .v-b #analysis,
  .v-b #potential,
  .v-b #plan {
    animation: none;
  }
}

/* The results tour's caption: what the shot shows, a bar running out its time. */
.scene-caption {
  position: absolute;
  left: 50%;
  bottom: 6px;
  z-index: 3;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 9px 16px 11px 13px;
  border-radius: 99px;
  background: rgb(255 255 255 / 0.82);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  box-shadow: 0 0 0 1px rgb(0 0 0 / 0.05), 0 10px 26px rgb(16 24 40 / 0.1);
  translate: -50% 0;
  overflow: hidden;
  pointer-events: none;
  white-space: nowrap;
  transition: opacity 0.26s ease, translate 0.26s ease;
}
.scene-caption.out {
  opacity: 0;
  translate: -50% 6px;
}
.scene-caption b {
  font-size: 15px;
  font-weight: 600;
  letter-spacing: -0.2px;
  color: #1d1f24;
}
.scene-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--blue);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--blue) 18%, transparent);
  animation: scene-pulse 1.4s ease-in-out infinite;
}
@keyframes scene-pulse {
  50% {
    box-shadow: 0 0 0 7px color-mix(in srgb, var(--blue) 6%, transparent);
  }
}
.scene-bar {
  position: absolute;
  left: 14px;
  right: 14px;
  bottom: 4px;
  height: 2px;
  border-radius: 2px;
  background: var(--blue);
  transform: scaleX(0);
  transform-origin: left;
  opacity: 0.55;
}
.scene-caption.run .scene-bar {
  transform: scaleX(1);
  transition: transform var(--hold, 2900ms) linear;
}
@media (prefers-reduced-motion: reduce) {
  .scene-dot {
    animation: none;
  }
}

/* B and F's analysis: her face in 3D over the photo, which fades once it's built. */
.analysis-3d {
  position: absolute;
  inset: 0;
  pointer-events: none;
}
.analysis-3d canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}
.analysis-visual .portrait-window {
  transition: opacity 0.5s ease;
}
.analysis-visual.in-3d .portrait-window {
  opacity: 0;
}
.analysis-3d {
  animation: results-appear 0.6s ease both;
}
.v-f .analysis-visual {
  background: radial-gradient(ellipse at center, #f7cfdf70, transparent 65%);
}

/* The analysis pop-ups: what was just read, beside the face. */
.analysis-pops {
  position: absolute;
  inset: 0;
  z-index: 3;
  pointer-events: none;
}
.analysis-pop {
  position: absolute;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 14px 8px 8px;
  border-radius: 99px;
  background: rgb(255 255 255 / 0.88);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  box-shadow: 0 0 0 1px rgb(0 0 0 / 0.05), 0 10px 26px rgb(16 24 40 / 0.12);
  font-size: 14px;
  font-weight: 600;
  color: #1d1f24;
  white-space: nowrap;
  opacity: 0;
  transition: opacity 0.35s ease, transform 0.45s cubic-bezier(0.2, 1.4, 0.4, 1);
}
.analysis-pop.left {
  left: 4px;
  transform: translateX(-12px) scale(0.9);
}
.analysis-pop.right {
  right: 4px;
  transform: translateX(12px) scale(0.9);
}
.analysis-pop.in {
  opacity: 1;
  transform: none;
}
.analysis-pop-tick {
  position: relative;
  flex: none;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: var(--blue);
}
.analysis-pop-tick::after {
  content: '';
  position: absolute;
  left: 7px;
  top: 4px;
  width: 4px;
  height: 8px;
  border: solid #fff;
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}
.analysis-pop b {
  margin-left: 2px;
  font-size: 17px;
  color: var(--blue);
  font-variant-numeric: tabular-nums;
}
/* Her reading and her potential: bigger, and above the rest. */
.analysis-pop.lead {
  z-index: 1;
  padding: 10px 18px 10px 10px;
  font-size: 15px;
  box-shadow: 0 0 0 1px rgb(0 0 0 / 0.05), 0 14px 34px color-mix(in srgb, var(--blue) 28%, transparent);
}
.analysis-pop.lead b {
  font-size: 22px;
}
@media (prefers-reduced-motion: reduce) {
  .analysis-pop {
    transition: opacity 0.2s ease;
    transform: none;
  }
}

/* ── What can change (B and F): a real before and after, swept, then her goals ── */
.glowup {
  display: flex;
  flex-direction: column;
  min-height: var(--page);
  padding: 18px 0 0;
}
.glowup-title {
  margin-bottom: 18px;
}
.glowup-story {
  position: relative;
}
.glowup-shots {
  position: relative;
  aspect-ratio: 4 / 4.4;
  overflow: hidden;
  border-radius: 28px;
  background: #eceef1;
  box-shadow: 0 16px 40px rgb(16 24 40 / 0.14);
}
.glowup-shots img,
.glowup-after {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 30%;
}
/* The after, uncovered from the left as the line sweeps across. */
.glowup-after {
  clip-path: inset(0 0 0 var(--cut, 50%));
}
.glowup-divider {
  position: absolute;
  top: 0;
  bottom: 0;
  left: var(--cut, 50%);
  width: 3px;
  margin-left: -1.5px;
  background: #fff;
  box-shadow: 0 0 18px rgb(0 0 0 / 0.25);
}
.glowup-divider span {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 38px;
  height: 38px;
  margin: -19px 0 0 -19px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 6px 18px rgb(0 0 0 / 0.2);
}
.glowup-divider span::before,
.glowup-divider span::after {
  content: '';
  position: absolute;
  top: 50%;
  margin-top: -5px;
  border: 5px solid transparent;
}
.glowup-divider span::before {
  left: 7px;
  border-right: 7px solid var(--blue);
}
.glowup-divider span::after {
  right: 7px;
  border-left: 7px solid var(--blue);
}
@property --cut {
  syntax: '<percentage>';
  inherits: true;
  initial-value: 50%;
}
.glowup-story.sweep .glowup-shots {
  animation: glowup-sweep 4.2s cubic-bezier(0.65, 0, 0.35, 1) both;
}
@keyframes glowup-sweep {
  0% { --cut: 96%; }
  45% { --cut: 8%; }
  70% { --cut: 50%; }
  100% { --cut: 50%; }
}
.glowup-tag {
  position: absolute;
  bottom: 14px;
  padding: 6px 12px;
  border-radius: 99px;
  font-size: 13px;
  font-weight: 600;
}
.glowup-tag.before {
  left: 14px;
  background: rgb(255 255 255 / 0.92);
}
.glowup-tag.after {
  right: 14px;
  background: var(--blue);
  color: #fff;
}
.glowup-dots {
  display: flex;
  justify-content: center;
  gap: 6px;
  margin-top: 12px;
}
.glowup-dots span {
  width: 6px;
  height: 6px;
  border-radius: 99px;
  background: rgb(0 0 0 / 0.14);
  transition: width 0.3s ease, background 0.3s ease;
}
.glowup-dots span.on {
  width: 18px;
  background: var(--blue);
}
.glowup-quote {
  margin: 14px 4px 0;
  font-size: 16px;
  font-weight: 500;
  line-height: 1.4;
  text-align: center;
  color: #4e525b;
}
.glowup-plan {
  margin-top: 18px;
}
.glowup-goals {
  display: flex;
  flex-direction: column;
}
.glowup-goal {
  display: grid;
  grid-template-columns: 24px 1fr;
  align-items: center;
  column-gap: 12px;
  row-gap: 2px;
  padding: 11px 0;
  border-top: 1px solid rgb(0 0 0 / 0.06);
  animation: b-card-in 0.5s cubic-bezier(0.2, 0.8, 0.2, 1) both;
  animation-delay: calc(0.3s + var(--i) * 0.12s);
}
.glowup-goal:first-child {
  border-top: 0;
  padding-top: 2px;
}
.glowup-check {
  position: relative;
  grid-row: span 2;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: var(--blue);
}
.glowup-check::after {
  content: '';
  position: absolute;
  left: 8.5px;
  top: 5px;
  width: 5px;
  height: 10px;
  border: solid #fff;
  border-width: 0 2.2px 2.2px 0;
  transform: rotate(45deg);
}
.glowup-goal strong {
  font-size: 17px;
  font-weight: 600;
  letter-spacing: -0.2px;
}
.glowup-how {
  font-size: 14px;
  color: #8a909a;
}
.v-b #glowup {
  animation: b-screen-in 0.5s cubic-bezier(0.2, 0.8, 0.2, 1) both;
}
@media (prefers-reduced-motion: reduce) {
  .glowup-story.sweep .glowup-shots,
  .glowup-goal {
    animation: none;
  }
}

/* A creator's own funnel (partner.js, ?v=luke): their clips, face and name beside FaceKit's. */
.partner-hero {
  position: absolute;
  /* A few pixels short of the wall's foot: a composited video bleeds a hairline past its box,
     which showed as a line across the page under the fade (Johan's phone). */
  inset: 0 0 3px;
  width: 100%;
  height: calc(100% - 3px);
  object-fit: cover;
  object-position: 50% 30%;
}
/* Their stills where video can't play (TikTok's browser): stacked, turned over by flow.js. */
.partner-hero.stills {
  overflow: hidden;
}
.partner-hero.stills .hero-shot {
  position: absolute;
  inset: 0;
  background: 50% 30% / cover no-repeat;
  transform-origin: 50% 35%;
  opacity: 0;
  will-change: opacity, transform;
}
.partner-hero.stills .hero-moving {
  position: absolute;
  max-width: none;
  opacity: 0;
  transition: opacity 0.9s ease;
}
.partner-hero.stills .hero-moving.on {
  opacity: 1;
}
[data-partner]:not([data-partner='dynamic']) .wall-fade.top {
  height: 96px;
  background: linear-gradient(rgb(244 244 243 / 0.5), rgb(244 244 243 / 0));
}
.splash .logo-pill.partnered {
  gap: 7px;
  padding-right: 18px;
  font-size: 17px;
  white-space: nowrap;
}
/* A long name gives way (with an ellipsis) instead of running off both sides of the screen. */
.splash .logo-pill.partnered {
  max-width: calc(100% - 32px);
}
.splash .logo-pill.partnered > span:last-child {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}
.splash .logo-pill.partnered > :not(span:last-child) {
  flex: none;
}
.splash .logo-pill.partnered img {
  width: 28px;
  height: 28px;
}
.splash .logo-pill .partner-x {
  margin: 0 1px;
  font-weight: 500;
  color: #8a8d94;
}
.splash .logo-pill img.partner-logo-face {
  border-radius: 50%;
}
/* The plan's one-line title, a touch smaller for their name in it. */
[data-partner] .plan-title {
  font-size: 28px;
}
/* Them in the header's corner, past the splash. */
.partner-header-face {
  display: block;
  width: 34px;
  height: 34px;
  margin: 4px;
  border-radius: 50%;
  object-fit: cover;
  box-shadow: 0 0 0 2px #fff, 0 0 0 3.5px var(--blue);
}
body[data-screen='intro'] .partner-header-face {
  display: none;
}
.partner-count-face {
  width: 20px;
  height: 20px;
  margin-right: 7px;
  border-radius: 50%;
  object-fit: cover;
  vertical-align: -5px;
}
/* "Luke's" on their routines. */
.partner-badge {
  position: absolute;
  top: 8px;
  left: 8px;
  z-index: 1;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 8px 2px 2px;
  border-radius: 99px;
  background: rgb(255 255 255 / 0.92);
  font-size: 11px;
  font-weight: 700;
  color: #1d1f24;
}
/* Its own size, over the card's rule for its cover image. */
.partner-badge .partner-badge-face {
  width: 18px;
  height: 18px;
  border-radius: 50%;
  object-fit: cover;
}
.plan-today {
  position: relative;
}
.plan-today .partner-badge {
  top: 8px;
  left: auto;
  right: 52px;
}
/* Them at the top of the results: their clips playing, who they are, what of theirs is in the
   plan. */
.partner-card {
  display: flex;
  gap: 14px;
  align-items: stretch;
}
.partner-reel {
  flex: none;
  width: 104px;
  aspect-ratio: 9 / 16;
  border-radius: 18px;
  object-fit: cover;
  background: #0c0b11;
}
.partner-card-words {
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-width: 0;
}
.partner-card-words .b-eyebrow {
  margin-bottom: 10px;
}
.partner-who {
  display: flex;
  align-items: center;
  gap: 10px;
}
.partner-card-face {
  width: 38px;
  height: 38px;
  border-radius: 50%;
  object-fit: cover;
}
.partner-who-words {
  display: flex;
  flex-direction: column;
  line-height: 1.2;
}
.partner-who-words strong {
  font-size: 16px;
  font-weight: 700;
  color: #1d1f24;
}
.partner-who-words small {
  font-size: 12.5px;
  font-weight: 500;
  color: #6b7079;
}
.partner-card-line {
  margin: 12px 0 0;
  font-size: 14px;
  font-weight: 500;
  line-height: 1.35;
  color: #1d1f24;
}
/* A creator's own scan on the paywall: the app's scan page (360 x 786), just its ring, the frame's
   26% to 74% whatever the card's shape, on white with the pills dark over it. */
.deck-video.app-scan {
  container-type: size;
  background: #fff;
}
.deck-video.app-scan :is(video, :where(canvas.canvas-video)) {
  inset: auto;
  top: 0;
  left: 50%;
  width: max(100cqw, 95cqh);
  height: auto;
  aspect-ratio: 360 / 786;
  translate: -50% -26%;
}
.deck-video.app-scan .deck-video-shade {
  display: none;
}
.deck-video.app-scan .deck-pill {
  background: rgb(29 31 36 / 0.62);
  border-color: transparent;
}
/* Their own before and after on the results card: side by side across the top, the words under. */
.partner-card:has(.partner-ba) {
  flex-direction: column;
}
.partner-ba {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 6px;
}
.partner-ba-shot {
  position: relative;
  aspect-ratio: 3 / 4;
  overflow: hidden;
  border-radius: 16px;
  background: #0c0b11;
}
.partner-ba-shot img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.partner-ba-label {
  position: absolute;
  top: 8px;
  left: 8px;
  padding: 3px 9px;
  border-radius: 99px;
  background: rgb(12 11 17 / 0.55);
  font-size: 11px;
  font-weight: 700;
  color: #fff;
}
.partner-ba-shot.after .partner-ba-label {
  background: var(--blue);
}
/* A creator's own before and after on What can change: side by side and still, no slider. */
.glowup-story.side .glowup-shots {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
  aspect-ratio: auto;
  overflow: visible;
  border-radius: 0;
  background: none;
  box-shadow: none;
  animation: none;
}
.glowup-story.side #glowup-before,
.glowup-story.side .glowup-after {
  position: relative;
  inset: auto;
  height: auto;
  aspect-ratio: 3 / 4;
  border-radius: 22px;
  clip-path: none;
  overflow: hidden;
  box-shadow: 0 12px 30px rgb(16 24 40 / 0.14);
}
.glowup-story.side .glowup-divider,
.glowup-story.side + .glowup-quote:empty,
.glowup-story.side .glowup-dots {
  display: none;
}
.glowup-story.side .glowup-tag {
  top: 10px;
  bottom: auto;
}
.glowup-story.side .glowup-tag.before {
  left: 10px;
}
.glowup-story.side .glowup-tag.after {
  right: auto;
  left: calc(50% + 14px);
}
/* Scan first's: several stories side by side, its dots kept, each coming in with a fade. */
.glowup-story.side.many .glowup-dots {
  display: flex;
}
.glowup-story.side.fade .glowup-shots {
  animation: glowup-fade 0.6s ease both;
}
@keyframes glowup-fade {
  from {
    opacity: 0.25;
  }
}
@media (prefers-reduced-motion: reduce) {
  .glowup-story.side.fade .glowup-shots {
    animation: none;
  }
}
/* Scan first's plan: every area it works on, two across, in quicker. */
.glowup-goals.all {
  display: grid;
  grid-template-columns: 1fr 1fr;
  column-gap: 12px;
}
.glowup-goals.all .glowup-goal {
  grid-template-columns: 20px 1fr;
  column-gap: 8px;
  padding: 9px 0;
  animation-delay: calc(0.3s + var(--i) * 0.05s);
}
.glowup-goals.all .glowup-goal:nth-child(2) {
  border-top: 0;
  padding-top: 2px;
}
.glowup-goals.all .glowup-check {
  width: 20px;
  height: 20px;
}
.glowup-goals.all .glowup-check::after {
  left: 7px;
  top: 4px;
  width: 4px;
  height: 8px;
  border-width: 0 2px 2px 0;
}
.glowup-goals.all .glowup-goal strong {
  font-size: 15px;
}
.glowup-goals.all .glowup-how {
  font-size: 12px;
  line-height: 1.3;
}

/* The scan's countdown: 3, 2, 1 over the oval once the face holds in it, then the shutter's
   flash as the still is taken (Johan: "count down, auto scan, boom"). */
.scan-count {
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  z-index: 3;
  translate: 0 -50%;
  text-align: center;
  font-size: 112px;
  font-weight: 600;
  line-height: 1;
  letter-spacing: -0.04em;
  color: #fff;
  text-shadow: 0 0 2px rgb(12 11 17 / 0.35), 0 4px 18px rgb(12 11 17 / 0.55), 0 0 60px rgb(12 11 17 / 0.35);
  pointer-events: none;
  font-variant-numeric: tabular-nums;
}
.scan-count.pop {
  animation: scan-count-pop 0.7s cubic-bezier(0.2, 0.8, 0.2, 1) both;
}
@keyframes scan-count-pop {
  0% { opacity: 0; scale: 1.6; }
  22% { opacity: 1; scale: 1; }
  100% { opacity: 1; scale: 0.94; }
}
.viewfinder::after {
  content: '';
  position: absolute;
  inset: 9%;
  z-index: 4;
  clip-path: url(#face-clip);
  background: #fff;
  opacity: 0;
  pointer-events: none;
}
.viewfinder.snap::after {
  animation: scan-snap 0.55s ease-out both;
}
@keyframes scan-snap {
  0% { opacity: 0.95; }
  100% { opacity: 0; }
}
/* The deck drags with a mouse, and its dots are tappable. */
.deck-pages {
  cursor: grab;
}
.deck-dot {
  cursor: pointer;
}

/* A browser that won't play video in the page (TikTok's on iPhone) shows the poster, not its own
   play button over it. */
video::-webkit-media-controls-start-playback-button {
  display: none !important;
  -webkit-appearance: none;
}
/* There a tap on a video would open it full screen. */
.no-inline-video video {
  pointer-events: none;
}

/* Scan first (?v=s): how far their scan's reading has got, in the header while they answer and
   look round (Johan), then ready; and the proof's count. */
.s-only {
  display: none;
}
.v-s .s-only {
  display: block;
}
.scan-status {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  margin: 0 0 0 auto;
  padding: 6px 11px;
  border-radius: 99px;
  background: #eef5ff;
  color: #1283ff;
  font-size: 12.5px;
  font-weight: 500;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.scan-status[hidden] {
  display: none;
}
.scan-status-dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  border: 2px solid currentColor;
  border-right-color: transparent;
  animation: scan-status-turn 0.9s linear infinite;
}
.scan-status.ready {
  background: #eaf8ef;
  color: #12924a;
}
.scan-status.ready .scan-status-dot {
  border: 0;
  background: currentColor;
  animation: none;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 10'%3E%3Cpath d='M2 5.2l2 2 4-4.4' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / 100% no-repeat;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 10'%3E%3Cpath d='M2 5.2l2 2 4-4.4' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / 100% no-repeat;
}
@keyframes scan-status-turn {
  to {
    transform: rotate(360deg);
  }
}
.glowup-count {
  margin: 14px 0 0;
  text-align: center;
  font-size: 14px;
  color: var(--muted, #6b6b72);
}
.glowup-count strong {
  color: #1283ff;
}

/* Scan first's two results pages: under the face, the AR routines picked for them on structure,
   the skincare bundle locked on skin (Johan). */
.v-s #s-routines,
.v-s #s-bundle {
  display: none;
}
.v-s #results[data-page='structure'] #s-routines,
.v-s #results[data-page='skin'] #s-bundle {
  display: block;
}
.v-s .b-results.in > .b-card:not(.s-card) {
  animation-delay: 1.3s;
}
.v-s .b-results.in > .s-card {
  animation-delay: 1.55s;
}
.v-s .b-results.in > .app-card {
  animation-delay: 1.8s;
}
.s-card-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  margin: 0 0 12px;
}
.s-card-head .b-eyebrow {
  margin: 0;
}
.s-card-count {
  font-size: 12.5px;
  font-weight: 500;
  color: #8a8e98;
  white-space: nowrap;
}
.s-routine-list {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
}
.s-routine {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}
.s-routine-art {
  position: relative;
  aspect-ratio: 1;
  margin: 0 0 6px;
  border-radius: 18px;
  background: #eef0f4 center / cover no-repeat;
  overflow: hidden;
}
/* Its words sit on a soft shade at the bottom of the photo. */
.s-routine-art::after {
  content: '';
  position: absolute;
  inset: 55% 0 0;
  background: linear-gradient(transparent, rgb(12 11 17 / 0.28));
}
.s-routine-ar {
  position: absolute;
  top: 9px;
  left: 9px;
  z-index: 1;
  padding: 4px 8px;
  border-radius: 99px;
  background: rgb(12 11 17 / 0.62);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  color: #fff;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.5px;
}
.s-routine-art .b-tile-lock {
  position: absolute;
  right: 9px;
  bottom: 9px;
  z-index: 1;
  width: 26px;
  height: 26px;
  background-size: 10px 12px;
}
.s-routine-pick {
  position: absolute;
  left: 9px;
  bottom: 10px;
  z-index: 1;
  padding: 4px 8px;
  border-radius: 99px;
  background: #1283ff;
  color: #fff;
  font-size: 11px;
  font-weight: 600;
}
.s-routine b {
  font-size: 15px;
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: -0.2px;
  color: #1d1f24;
}
.s-routine-meta {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
  font-size: 12.5px;
  color: #8a8e98;
}
.s-routine-why {
  padding: 2px 8px;
  border-radius: 99px;
  background: var(--b-soft);
  color: var(--b-solid);
  font-weight: 500;
}
.s-bundle-title {
  display: block;
  margin: -4px 0 12px;
  font-size: 19px;
  font-weight: 600;
  letter-spacing: -0.3px;
  color: #1d1f24;
}
.s-bundle-list {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px;
}
.s-product {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1px;
  min-width: 0;
}
.s-product-shot {
  position: relative;
  display: grid;
  place-items: center;
  width: 100%;
  aspect-ratio: 0.8;
  margin: 0 0 8px;
  padding: 6px;
  border-radius: 18px;
  background: var(--b-soft);
  overflow: hidden;
}
/* The photos' white grounds dropped into the tile; each bottle there but blurred past reading. */
.s-product-shot img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  mix-blend-mode: multiply;
  filter: blur(4px) saturate(0.9);
  opacity: 0.85;
  transform: scale(1.1);
  user-select: none;
  pointer-events: none;
}
.s-product-lock {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 34px;
  height: 34px;
  translate: -50% -50%;
  border-radius: 50%;
  background: #1293ff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 20'%3E%3Cpath d='M4 8.5V6a4 4 0 0 1 8 0v2.5' fill='none' stroke='%23fff' stroke-width='2.2'/%3E%3Crect x='1' y='8' width='14' height='11' rx='2.6' fill='%23fff'/%3E%3C/svg%3E") center / 12px 15px no-repeat;
  box-shadow: 0 6px 16px rgb(18 147 255 / 0.35);
}
/* A light passing over the locked shots now and then, as over the locked scores. */
.s-product-shot::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(105deg, transparent 35%, rgb(255 255 255 / 0.55) 50%, transparent 65%);
  transform: translateX(-120%);
  animation: b-shine 4s ease-in-out infinite;
  animation-delay: 3s;
  pointer-events: none;
}
.s-product small {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.4px;
  text-transform: uppercase;
  color: #8a8e98;
}
.s-product b {
  font-size: 14px;
  font-weight: 600;
  color: #1d1f24;
}
.s-bundle-foot {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  margin: 14px 0 0;
  padding: 10px 12px;
  border-radius: 14px;
  background: #f5f6f8;
  font-size: 13.5px;
  font-weight: 500;
  color: #4e525b;
}
@media (prefers-reduced-motion: reduce) {
  .s-product-shot::after {
    animation: none;
  }
}

/* Scan first's questions: their foot (Continue and the scan's card) solid white, a short fade
   above it, so a long list of options passes under it rather than showing through (Johan). */
.v-s #quiz .cta-bar {
  background: linear-gradient(rgb(255 255 255 / 0), #fff 16px);
}
/* Scan first's first button (Johan): taller, a face scan's icon before its words, a line of light
   passing down the face in it now and then. */
.v-s .get-started {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 11px;
  min-height: 66px;
  font-size: 19px;
  letter-spacing: -0.3px;
}
.begin-icon {
  display: grid;
  flex: none;
  place-items: center;
  width: 36px;
  height: 36px;
  border-radius: 12px;
  background: rgb(255 255 255 / 0.18);
  box-shadow: inset 0 0 0 1px rgb(255 255 255 / 0.22);
}
.begin-icon svg {
  width: 24px;
  height: 24px;
  overflow: visible;
}
.begin-scanline {
  stroke-width: 1.6;
  opacity: 0;
  animation: begin-scan 2.6s ease-in-out 0.6s infinite;
}
/* Tapped, the camera on its way: the line runs on, quicker, and the button settles in. */
.v-s .get-started.opening {
  transform: scale(0.98);
  filter: brightness(0.96);
}
.v-s .get-started.opening .begin-scanline {
  animation-duration: 0.9s;
  animation-delay: 0s;
}
@keyframes begin-scan {
  0% {
    opacity: 0;
    transform: translateY(-6px);
  }
  15%,
  45% {
    opacity: 0.9;
  }
  60%,
  100% {
    opacity: 0;
    transform: translateY(6px);
  }
}
@media (prefers-reduced-motion: reduce) {
  .begin-scanline {
    animation: none;
  }
}

/* Scan first: the way from the scan to the questions (Johan). All but the 3D face out at once,
   then the face collapses up into the card's (app.js collapseThen). */
.analysis.collapsing > :not(.analysis-visual),
.analysis.collapsing .analysis-pops,
.analysis.collapsing .face-overlay,
body.s-collapsing .header {
  opacity: 0;
  transition: opacity 0.16s ease;
}

/* Scan first's 3D face (Johan): on its screen, nothing but the face, popping up in the middle of a
   clear page; then it goes up into the card. The photo, the readings, the dots over the face, the
   title, the number, the header and its bar: none of them here. */
.v-s #analysis:not([hidden]) {
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-height: var(--page);
}
.v-s #analysis > :not(.analysis-visual):not(.s-scan-done),
.v-s #analysis .analysis-pops,
.v-s #analysis .face-overlay,
.v-s #analysis .portrait-window {
  display: none;
}
.v-s body[data-screen='analysis'] .header {
  visibility: hidden;
}
.v-s #analysis .analysis-visual {
  isolation: isolate;
  height: clamp(280px, 44dvh, 400px);
  margin: 4px -8px 30px;
  background: none;
}
.v-s #analysis .analysis-visual .analysis-3d {
  animation: s-face-pop 0.55s cubic-bezier(0.3, 1.35, 0.5, 1) both;
}
@keyframes s-face-pop {
  from {
    opacity: 0;
    transform: scale(0.8);
  }
}

/* ── Scan first: the scan's card at the top (Johan: "bigger and better, the 3D scan taking more
   height on the left, the rest on the right, super clean"), from the questions to the results ── */
.s-analysing {
  position: relative;
  isolation: isolate;
  display: grid;
  grid-template-columns: 104px minmax(0, 1fr);
  column-gap: 14px;
  padding: 10px 14px 10px 10px;
  border: 1px solid transparent;
  border-radius: 26px;
  text-align: left;
}
.s-analysing[hidden] {
  display: none;
}
/* Its panel, a layer under its contents, so it can build out of the face. */
.s-analysing::before {
  content: '';
  position: absolute;
  inset: -1px;
  z-index: -1;
  border: 1px solid #edf0f5;
  border-radius: inherit;
  background: #fff;
  box-shadow: 0 1px 2px rgb(16 40 80 / 0.04), 0 14px 34px rgb(16 40 80 / 0.08);
  transform-origin: 63px 79px;
}
/* At the top, under the back button and the bar (Johan), the header a little shorter while it's
   there; the page under it that much shorter, so the questions fit as they did. app.js's
   collapseThen lands the face by these sizes. */
.shell > .s-analysing {
  height: 156px;
  margin: 6px 0 10px;
}
body.s-waiting .header {
  height: 64px;
}
body.s-waiting {
  --page: calc(100dvh - 64px - 172px - env(safe-area-inset-top) - env(safe-area-inset-bottom));
}

/* The face's panel, tall, softly lit, the 3D face turning in it (docked by analysis-3d.js). */
.s-analysing-face {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  border-radius: 19px;
}
.s-analysing-face::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: radial-gradient(90% 70% at 50% 42%, #e3efff 0%, #f0f6ff 55%, #f6f8fb 100%);
}
.s-analysing-face .analysis-3d {
  position: absolute;
  inset: -10px -14px;
  animation: none;
}
/* (No 3D face, after a refresh: their photo, round, a ring turning about it.) */
.s-analysing-face img {
  position: absolute;
  left: 50%;
  top: 44%;
  width: 66px;
  height: 66px;
  translate: -50% -50%;
  border-radius: 50%;
  object-fit: cover;
}
.s-analysing-face::after {
  content: '';
  position: absolute;
  left: 50%;
  top: 44%;
  width: 76px;
  height: 76px;
  translate: -50% -50%;
  border: 2px solid #1283ff;
  border-right-color: transparent;
  border-radius: 50%;
  animation: scan-status-turn 1.1s linear infinite;
}
.s-analysing-face.three-d img,
.s-analysing-face.three-d::after {
  display: none;
}
/* How far, in a pill at the foot of the face's panel. */
.s-analysing-percent {
  position: absolute;
  left: 50%;
  bottom: 8px;
  z-index: 1;
  translate: -50% 0;
  padding: 3px 10px;
  border-radius: 99px;
  background: rgb(255 255 255 / 0.92);
  box-shadow: 0 2px 10px rgb(16 40 80 / 0.12);
  font-size: 13px;
  font-weight: 700;
  color: #1283ff;
  font-variant-numeric: tabular-nums;
}
.s-analysing.ready .s-analysing-percent {
  color: #12924a;
}

/* The right: what's happening, the check it's on, and the four sections as a list. */
.s-analysing-main {
  display: flex;
  flex-direction: column;
  min-width: 0;
  padding: 4px 0 2px;
}
#s-analysing-title {
  overflow: hidden;
  font-size: 16px;
  font-weight: 600;
  letter-spacing: -0.3px;
  color: #1d1f24;
  white-space: nowrap;
  text-overflow: ellipsis;
}
/* The ticker: one line, each check swiping up in, a tick popping on, then up and out. */
.s-ticker {
  position: relative;
  display: block;
  height: 17px;
  margin: 3px 0 0;
  overflow: hidden;
  font-size: 13px;
  color: #8a8e98;
}
.s-tick {
  position: absolute;
  inset: 0 auto auto 0;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  max-width: 100%;
  line-height: 17px;
  white-space: nowrap;
  animation: s-tick-in 0.38s cubic-bezier(0.2, 0.8, 0.2, 1) both;
}
.s-tick.out {
  animation: s-tick-out 0.34s ease both;
}
.s-tick.ticked::after {
  content: '';
  flex: none;
  width: 13px;
  height: 13px;
  border-radius: 50%;
  background: #12c45a url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 10'%3E%3Cpath d='M2.6 5.2l1.6 1.6 3.2-3.6' fill='none' stroke='white' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / 100% no-repeat;
  animation: s-tick-pop 0.3s 0.5s cubic-bezier(0.3, 1.6, 0.5, 1) both;
}
@keyframes s-tick-in {
  from {
    opacity: 0;
    transform: translateY(14px);
  }
}
@keyframes s-tick-out {
  to {
    opacity: 0;
    transform: translateY(-14px);
  }
}
@keyframes s-tick-pop {
  from {
    transform: scale(0);
  }
}
.s-stages {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin: auto 0 0;
  padding: 0;
  list-style: none;
}
.s-stages li {
  display: grid;
  grid-template-columns: 14px 64px minmax(0, 1fr);
  align-items: center;
  column-gap: 8px;
}
/* Each section's state: an empty ring to come, a turning one on it, a tick once it's done. */
.s-stage-icon {
  width: 14px;
  height: 14px;
  border: 1.5px solid #d8dde5;
  border-radius: 50%;
}
.s-stages li.on .s-stage-icon {
  border-color: #1283ff;
  border-right-color: transparent;
  animation: scan-status-turn 0.9s linear infinite;
}
.s-stages li.done .s-stage-icon {
  border: 0;
  background: #12c45a url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 10'%3E%3Cpath d='M2.6 5.2l1.6 1.6 3.2-3.6' fill='none' stroke='white' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / 100% no-repeat;
}
.s-stage-name {
  overflow: hidden;
  font-size: 12.5px;
  font-weight: 500;
  color: #a6abb5;
  white-space: nowrap;
}
.s-stages li.on .s-stage-name {
  color: #1d1f24;
}
.s-stages li.done .s-stage-name {
  color: #4e525b;
}
.s-stage-bar {
  height: 4px;
  overflow: hidden;
  border-radius: 99px;
  background: #eef1f6;
}
.s-stage-bar span {
  display: block;
  height: 100%;
  border-radius: inherit;
  background: linear-gradient(90deg, #4aa8ff, #1283ff);
  transform: scaleX(var(--fill, 0));
  transform-origin: left;
  transition: transform 0.4s ease;
}
.s-stages li.done .s-stage-bar span {
  background: #12c45a;
}

/* Building itself round the face that just landed in it (Johan: "a UI build"): its panel growing
   out of the face, the face's light coming up, its words and the check sliding in, the number
   popping on, and the four sections drawing in one after another. The face is there throughout. */
.s-analysing.build::before {
  animation: s-build-panel 0.42s cubic-bezier(0.2, 0.8, 0.2, 1) both;
}
.s-analysing.build .s-analysing-face::before {
  animation: s-build-fade 0.4s 0.08s both;
}
.s-analysing.build #s-analysing-title {
  animation: s-build-in 0.36s 0.12s cubic-bezier(0.2, 0.8, 0.2, 1) both;
}
.s-analysing.build .s-ticker {
  animation: s-build-in 0.36s 0.18s cubic-bezier(0.2, 0.8, 0.2, 1) both;
}
.s-analysing.build .s-analysing-percent {
  animation: s-build-pop 0.4s 0.3s cubic-bezier(0.3, 1.5, 0.5, 1) both;
}
.s-analysing.build .s-stages li {
  animation: s-build-in 0.34s cubic-bezier(0.2, 0.8, 0.2, 1) both;
}
.s-analysing.build .s-stage-bar {
  transform-origin: left;
  animation: s-build-bar 0.42s cubic-bezier(0.2, 0.8, 0.2, 1) both;
}
.s-analysing.build .s-stages li:nth-child(1),
.s-analysing.build .s-stages li:nth-child(1) .s-stage-bar { animation-delay: 0.24s; }
.s-analysing.build .s-stages li:nth-child(2),
.s-analysing.build .s-stages li:nth-child(2) .s-stage-bar { animation-delay: 0.3s; }
.s-analysing.build .s-stages li:nth-child(3),
.s-analysing.build .s-stages li:nth-child(3) .s-stage-bar { animation-delay: 0.36s; }
.s-analysing.build .s-stages li:nth-child(4),
.s-analysing.build .s-stages li:nth-child(4) .s-stage-bar { animation-delay: 0.42s; }
@keyframes s-build-panel {
  from {
    opacity: 0;
    transform: scale(0.14);
  }
}
@keyframes s-build-in {
  from {
    opacity: 0;
    transform: translateX(-8px);
  }
}
@keyframes s-build-bar {
  from {
    transform: scaleX(0);
  }
}
@keyframes s-build-fade {
  from {
    opacity: 0;
  }
}
@keyframes s-build-pop {
  from {
    opacity: 0;
    transform: scale(0.6);
  }
}
@media (prefers-reduced-motion: reduce) {
  .s-analysing-face::after,
  .s-stages li.on .s-stage-icon,
  .s-tick,
  .s-tick.out,
  .s-tick.ticked::after {
    animation: none;
  }
  .s-tick.out {
    display: none;
  }
}

/* Scan first's How it works under the card (there till the results): its steps more compact, so
   the page fits under it as it did without it. */
body.s-waiting .guide-steps {
  gap: 8px;
  margin-top: 14px;
}
body.s-waiting .guide-step {
  padding: 8px;
}
body.s-waiting .guide-shot {
  width: 62px;
  height: 78px;
}
body.s-waiting .guide-step.on .guide-shot {
  width: 74px;
  height: 94px;
}

/* ── Scan first: the scan done (Johan: "Face scan successful", sexy, more to fill the space): a
   green tick popping in over the title, the 3D face coming up in a soft glow with a dotted orbit
   turning round it, and three checks landing beside it, floating. Then all but the face out, and
   the face up into the card. */
.s-scan-done,
.s-scan-chips {
  display: none;
}
.v-s #analysis .s-scan-done {
  display: flex;
  flex-direction: column;
  align-items: center;
}
.s-scan-badge {
  display: grid;
  place-items: center;
  width: 54px;
  height: 54px;
  border-radius: 50%;
  background: linear-gradient(145deg, #34d27a, #12b85a);
  box-shadow: 0 0 0 8px rgb(18 196 90 / 0.12), 0 10px 26px rgb(18 184 90 / 0.35);
}
.s-scan-badge svg {
  width: 28px;
  height: 28px;
  fill: none;
  stroke: #fff;
  stroke-width: 2.6;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-dasharray: 24;
  stroke-dashoffset: 24;
}
.s-scan-title {
  margin: 16px 0 0;
  font-size: 30px;
  font-weight: 600;
  letter-spacing: -0.8px;
  color: var(--ink);
}
.s-scan-title span {
  background: linear-gradient(120deg, #16c060, #0f9e4f);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.s-scan-sub {
  margin: 4px 0 0;
  font-size: 15px;
  color: var(--muted);
}
.v-s #analysis:not([hidden]) .s-scan-badge {
  animation: s-badge-pop 0.55s 0.05s cubic-bezier(0.3, 1.6, 0.5, 1) both;
}
.v-s #analysis:not([hidden]) .s-scan-badge svg {
  animation: s-tick-draw 0.4s 0.35s ease-out forwards;
}
.v-s #analysis:not([hidden]) .s-scan-title {
  animation: s-rise 0.5s 0.15s cubic-bezier(0.2, 0.8, 0.2, 1) both;
}
.v-s #analysis:not([hidden]) .s-scan-sub {
  animation: s-rise 0.5s 0.25s cubic-bezier(0.2, 0.8, 0.2, 1) both;
}
/* The glow and the orbit, under the face. */
.v-s #analysis .analysis-visual::before,
.v-s #analysis .analysis-visual::after {
  content: '';
  position: absolute;
  left: 50%;
  top: 48%;
  z-index: -1;
  aspect-ratio: 1;
  translate: -50% -50%;
  border-radius: 50%;
  transition: opacity 0.16s ease;
}
.v-s #analysis .analysis-visual::before {
  width: 92%;
  max-width: 380px;
  background: radial-gradient(closest-side, rgb(18 131 255 / 0.2), rgb(18 131 255 / 0.07) 58%, transparent);
  animation: s-glow 2.6s ease-in-out infinite alternate;
}
.v-s #analysis .analysis-visual::after {
  width: 78%;
  max-width: 320px;
  border: 1.5px dashed rgb(18 131 255 / 0.28);
  animation: s-orbit 14s linear infinite;
}
.v-s #analysis .s-scan-chips {
  display: block;
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  transition: opacity 0.16s ease;
}
.s-chip {
  position: absolute;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 7px 12px 7px 7px;
  border-radius: 99px;
  background: rgb(255 255 255 / 0.92);
  box-shadow: 0 6px 20px rgb(16 40 80 / 0.12);
  font-size: 13px;
  font-weight: 600;
  white-space: nowrap;
  color: #1d1f24;
  opacity: 0;
}
.s-chip::before {
  content: '';
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: #12c45a url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 10'%3E%3Cpath d='M2.6 5.2l1.6 1.6 3.2-3.6' fill='none' stroke='white' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / 100% no-repeat;
}
.s-chip:nth-child(1) {
  left: 4%;
  top: 12%;
}
.s-chip:nth-child(2) {
  right: 2%;
  top: 42%;
}
.s-chip:nth-child(3) {
  left: 6%;
  top: 74%;
}
.v-s #analysis .analysis-visual.in-3d .s-chip {
  animation: s-chip-in 0.5s calc(0.4s + var(--i) * 0.25s) cubic-bezier(0.3, 1.4, 0.5, 1) both,
    s-bob 3s calc(1s + var(--i) * 0.5s) ease-in-out infinite alternate;
}
.analysis.collapsing .s-scan-chips,
.analysis.collapsing .analysis-visual::before,
.analysis.collapsing .analysis-visual::after {
  opacity: 0;
}
@keyframes s-badge-pop {
  from {
    opacity: 0;
    transform: scale(0.4);
  }
}
@keyframes s-tick-draw {
  to {
    stroke-dashoffset: 0;
  }
}
@keyframes s-rise {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
}
@keyframes s-glow {
  to {
    opacity: 0.6;
    scale: 1.06;
  }
}
@keyframes s-orbit {
  to {
    rotate: 360deg;
  }
}
@keyframes s-chip-in {
  from {
    opacity: 0;
    scale: 0.6;
  }
  to {
    opacity: 1;
    scale: 1;
  }
}
@keyframes s-bob {
  to {
    translate: 0 -6px;
  }
}

/* ── Scan first: the card's results-ready moment (Johan: "a sexy your results are ready"): its
   edge going green with a light passing over it once, the face's light green, the number a green
   Ready, and the four sections settling into four green ticked pills, two by two. */
.s-analysing.ready::before {
  border-color: #cdeedb;
  box-shadow: 0 0 0 1px #dff5e8, 0 16px 38px rgb(18 196 90 / 0.16);
  transition: box-shadow 0.5s ease, border-color 0.5s ease;
}
.s-analysing.ready::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 2;
  border-radius: inherit;
  background: linear-gradient(105deg, transparent 42%, rgb(255 255 255 / 0.75) 50%, transparent 58%) no-repeat;
  background-size: 260% 100%;
  pointer-events: none;
  animation: s-ready-shine 1.3s 0.15s ease both;
}
.s-analysing.ready .s-analysing-face::before {
  background: radial-gradient(90% 70% at 50% 42%, #d8f6e4 0%, #edfbf3 55%, #f6f8fb 100%);
}
.s-analysing.ready .s-analysing-percent {
  background: #12c45a;
  color: #fff;
  box-shadow: 0 4px 14px rgb(18 196 90 / 0.35);
  animation: s-build-pop 0.4s cubic-bezier(0.3, 1.5, 0.5, 1) both;
}
.s-analysing.ready .s-stages {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 5px;
}
.s-analysing.ready .s-stages li {
  grid-template-columns: 14px minmax(0, 1fr);
  column-gap: 5px;
  padding: 6px 7px 6px 6px;
  border-radius: 99px;
  background: #edfaf2;
  animation: s-ready-pill 0.45s calc(var(--n) * 0.07s) cubic-bezier(0.3, 1.4, 0.5, 1) both;
}
.s-analysing.ready .s-stage-bar {
  display: none;
}
.s-analysing.ready .s-stage-name {
  font-weight: 600;
  color: #12924a;
}
/* A small phone's card is narrower: the names stay whole ("Structure" was cut). */
@media (max-width: 380px) {
  .s-analysing.ready .s-stage-name {
    font-size: 11.5px;
  }
}
@keyframes s-ready-shine {
  from {
    background-position: 160% 0;
  }
  to {
    background-position: -60% 0;
  }
}
@keyframes s-ready-pill {
  from {
    opacity: 0;
    transform: scale(0.85);
  }
}

/* ── Scan first's "Here's how much you can level up" all on one screen (Johan): the before and
   after smaller, the quote tighter, and what the plan works on one line swiping through them all. */
.v-s .glowup-title {
  margin-bottom: 12px;
}
/* (Johan: "looks so shit"): the two photos one card, joined, a fine white line between them with an
   arrow on it, their labels along the foot; as tall as the screen allows. */
.v-s .glowup-story.side .glowup-shots {
  position: relative;
  gap: 0;
  max-width: 340px;
  height: clamp(190px, 30dvh, 270px);
  margin: 0 auto;
  overflow: hidden;
  border-radius: 26px;
  box-shadow: 0 18px 40px rgb(16 24 40 / 0.16), 0 0 0 1px rgb(16 24 40 / 0.04);
}
.v-s .glowup-story.side #glowup-before,
.v-s .glowup-story.side .glowup-after {
  height: 100%;
  aspect-ratio: auto;
  border-radius: 0;
  box-shadow: none;
  object-position: 50% 30%;
}
.v-s .glowup-story.side .glowup-after img {
  object-position: 50% 30%;
}
/* The line, and the arrow on it. */
.v-s .glowup-story.side .glowup-shots::before {
  content: '';
  position: absolute;
  top: 0;
  bottom: 0;
  left: 50%;
  z-index: 2;
  width: 2px;
  translate: -50% 0;
  background: rgb(255 255 255 / 0.9);
}
.v-s .glowup-story.side .glowup-shots::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  z-index: 3;
  width: 34px;
  height: 34px;
  translate: -50% -50%;
  border-radius: 50%;
  background: #fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%231283ff' stroke-width='2.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12h13M13 6l6 6-6 6'/%3E%3C/svg%3E") center / 18px no-repeat;
  box-shadow: 0 4px 14px rgb(16 24 40 / 0.2);
}
.v-s .glowup-story.side .glowup-tag {
  top: auto;
  bottom: 10px;
  padding: 5px 10px;
  font-size: 12px;
}
.v-s .glowup-story.side .glowup-tag.before {
  left: 10px;
  background: rgb(12 11 17 / 0.55);
  color: #fff;
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
}
.v-s .glowup-story.side .glowup-tag.after {
  left: auto;
  right: 10px;
}
.v-s .glowup-dots {
  margin-top: 8px;
}
.v-s .glowup-quote {
  margin: 8px 4px 0;
  font-size: 14px;
}
.v-s .glowup-plan {
  margin-top: 12px;
  padding: 12px 16px;
}
.v-s .glowup-plan .b-eyebrow {
  margin: 0 0 6px;
}
.v-s .glowup-goals.all {
  display: block;
  position: relative;
  height: 24px;
  overflow: hidden;
}
.v-s .glowup-goals.all .glowup-goal {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 0;
  border: 0;
  animation: s-tick-in 0.38s cubic-bezier(0.2, 0.8, 0.2, 1) both;
}
.v-s .glowup-goals.all .glowup-goal.out {
  animation: s-tick-out 0.34s ease both;
}
.v-s .glowup-goals.all .glowup-check {
  flex: none;
  width: 20px;
  height: 20px;
}
.v-s .glowup-goals.all .glowup-goal strong {
  flex: none;
  font-size: 16px;
}
.v-s .glowup-goals.all .glowup-how {
  overflow: hidden;
  font-size: 13px;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.v-s .glowup-count {
  margin-top: 10px;
}

/* ── Scan first's potential (Johan): what the 3D scan looks at, smaller, as a row of chips
   running past; the graph taking the room that leaves. */
.v-s .sources {
  margin-top: 14px;
  padding: 12px 0;
  overflow: hidden;
}
.v-s .sources .panel-eyebrow {
  margin: 0 0 10px;
  padding: 0 16px;
}
.v-s .sources-grid {
  display: flex;
  width: max-content;
  gap: 8px;
  padding: 0 8px 0 0;
  animation: s-marquee 26s linear infinite;
}
.v-s .source {
  flex: none;
  align-items: center;
  gap: 7px;
  padding: 7px 13px 7px 8px;
  border-radius: 99px;
  background: #f3f8ff;
}
.v-s .source-words small {
  display: none;
}
.v-s .source-words strong {
  font-size: 14px;
  white-space: nowrap;
}
.v-s .path-panel {
  margin-top: 12px;
}
@keyframes s-marquee {
  to {
    transform: translateX(-50%);
  }
}

/* ── Scan first's Start my plan filling with colour as the plan is built (Johan), white on a
   soft blue till then; plan.js sets how far (--built). */
.v-s #to-roadmap {
  position: relative;
  isolation: isolate;
  overflow: hidden;
}
.v-s #to-roadmap:disabled {
  background: #c9d7ee;
  color: #fff;
  box-shadow: none;
}
.v-s #to-roadmap::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--b-gradient);
  transform: scaleX(var(--built, 0));
  transform-origin: left;
  transition: transform var(--fill-time, 0.4s) linear;
}

/* ── Scan first's road ends on their face (Johan): floating, no box, its scores round it, locked
   till the app, bobbing gently. */
.v-s .deck-face.float {
  overflow: visible;
  border: 0;
  background: none;
}
.deck-lock {
  position: absolute;
  z-index: 2;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 6px 7px 6px 12px;
  border-radius: 99px;
  background: rgb(255 255 255 / 0.88);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  box-shadow: 0 6px 18px rgb(16 40 80 / 0.1);
  font-size: 12.5px;
  font-weight: 600;
  color: #1d1f24;
  animation: s-bob 3.2s var(--d, 0s) ease-in-out infinite alternate;
}
.deck-lock.left {
  left: 2px;
}
.deck-lock.right {
  right: 2px;
}
.deck-lock-value {
  font-variant-numeric: tabular-nums;
  color: var(--blue);
  filter: blur(4px);
  user-select: none;
}
.deck-lock-icon {
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: #1d1f24 url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 20'%3E%3Cpath d='M4 8.5V6a4 4 0 0 1 8 0v2.5' fill='none' stroke='%23fff' stroke-width='2.2'/%3E%3Crect x='1' y='8' width='14' height='11' rx='2.6' fill='%23fff'/%3E%3C/svg%3E") center / 8px 10px no-repeat;
}
@media (prefers-reduced-motion: reduce) {
  .v-s .sources-grid,
  .deck-lock,
  .v-s #analysis .analysis-visual::before,
  .v-s #analysis .analysis-visual::after {
    animation: none;
  }
}

/* Scan first's routines slide (Johan: no screen-recording look, sharp): the sharper takes
   (666 x 796) show only their camera's view, the band between the app's header (to 27% down)
   and its controls (from 82%), the card shaped to it, so nothing is zoomed and nothing of the
   app shows; the slide's two cards together in its middle. */
.v-s .deck-stack.coached {
  justify-content: center;
}
.v-s .deck-video.app.sharp {
  flex: none;
  aspect-ratio: 3 / 2;
}
.v-s .deck-video.app.sharp :is(video, :where(canvas.canvas-video)) {
  width: max(100cqw, 152cqh);
  aspect-ratio: 666 / 796;
  translate: -50% -27%;
}

/* Scan first's proof on a shorter screen (the scan's card above it): the photos, the title, the
   quote and the plan's line a little smaller, so it all still fits above the button. */
@media (max-height: 820px) {
  .v-s .glowup-title {
    font-size: 26px;
    margin-bottom: 10px;
  }
  .v-s .glowup-story.side .glowup-shots {
    height: clamp(160px, 22dvh, 230px);
  }
  .v-s .glowup-dots {
    margin-top: 6px;
  }
  .v-s .glowup-quote {
    margin-top: 6px;
    font-size: 13px;
  }
  .v-s .glowup-plan {
    margin-top: 10px;
    padding: 10px 14px;
  }
  .v-s .glowup-count {
    margin-top: 8px;
    font-size: 13px;
  }
}

/* The on-page checkout (checkout-sdk.js): the paywall fills just the screen that shows (the SDK
   sizes it 100vh, which on an iPhone runs on under Safari's toolbar, so it could be dragged up and
   down), and the page under it stays put while it's up (Johan: sideways swipes only). */
[data-sw-presenter='overlay'] {
  overscroll-behavior: none;
  touch-action: pan-x;
}
[data-sw-presenter='iframe'] {
  width: 100% !important;
  height: 100% !important;
}
html.sw-open,
html.sw-open body {
  overflow: hidden;
  overscroll-behavior: none;
}


/* Design QA 2026-10-17 */
/* The quiz's Continue sits above the keyboard (flow.js keeps --kb at the keyboard's height). */
html.keyboard .quiz .cta-bar {
  position: fixed;
  left: var(--gutter, 20px);
  right: var(--gutter, 20px);
  bottom: var(--kb, 0px);
  padding-bottom: 14px;
}
/* The method: all three steps at once, equal, each clip playing. */
.guide-steps.all-on .guide-step {
  opacity: 1;
  transform: none;
  border-color: #eef0f4;
  box-shadow: none;
  cursor: default;
}
.guide-steps.all-on .guide-step .guide-shot {
  width: 92px;
  height: 118px;
}
/* The photo step: the error reads first, under the title; one line of subtext; a plain analysing state. */
#scan-error:not(:empty) + #scan-hint,
.scan:has(#photo-fallback:not([hidden])) .privacy-line,
.scan.analysing .privacy-line,
.scan.analysing #photo-fallback,
.scan.analysing #scan-hint {
  display: none;
}
#scan-error:not(:empty) {
  margin: 8px 0 16px;
}
.scan-analysing {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  margin: 24px 0;
  font-size: 17px;
  font-weight: 500;
  color: #333;
}
.scan-analysing-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--b-gradient, #1270ff);
  animation: scan-pulse 1s ease-in-out infinite;
}
@keyframes scan-pulse {
  0%, 100% { transform: scale(0.7); opacity: 0.5; }
  50% { transform: scale(1); opacity: 1; }
}
@media (prefers-reduced-motion: reduce) { .scan-analysing-dot { animation: none; } }
/* A creator's hero: the still shows until the clip really plays, then the clip eases in. */
.partner-hero.waiting {
  opacity: 0;
}
:is(video, :where(canvas.canvas-video)).partner-hero {
  transition: opacity 0.5s ease;
}

/* A creator's address paints as theirs from the first frame: their poster under the wall straight from
   CSS, the stock phone wall and proof pill never shown, and the pitch and button held back until
   app.js has put their words in (html.partner-in). */
html[data-partner]:not([data-partner='dynamic']) .splash .wall-column,
html[data-partner]:not([data-partner='dynamic']) .splash .proof {
  display: none;
}
/* Only the words wait for the creator's; the button is there from the first frame, and the words
   show by themselves after 1.2s whatever the script did (fail open: never a page without a button). */
html[data-partner]:not([data-partner='dynamic']):not(.partner-in) .splash .pitch {
  visibility: hidden;
  animation: splash-reveal 0s 1.2s forwards;
}
@keyframes splash-reveal { to { visibility: visible; } }
html[data-partner='luke'] #wall { background: #111 50% 30% / cover url('/start/media/luke/aura.jpg'); }
html[data-partner='omikko'] #wall { background: #111 50% 30% / cover url('/start/media/omikko/aura.jpg'); }
html[data-partner='logan'] #wall { background: #111 50% 30% / cover url('/start/media/logan/aura.jpg'); }

/* The tips are the camera's pre-permission page: the camera, or a photo instead. */
.tips .tips-photo {
  display: block;
  margin: 12px auto 0;
  min-height: 44px;
  font-size: 15px;
  font-weight: 600;
}

/* An iPhone too old for the app: the message alone, no field to fill or button to press. */
.checkout-email.too-old form {
  display: none;
}

/* The original video remains addressable by callers, but never starts in this WKWebView. */
.no-inline-video video[data-canvas-video] { display: none !important; }
.canvas-video { pointer-events: none; }
/* The poster owns layout/visibility observation until the first decoded frame takes its place. */
.canvas-video:not([data-ready]) {
  display: none !important;
}
