/* Fonts — self-hosted, subset to the glyphs this page uses (see docs/05-future/landing-page-release-spec.md §6.2) */
@font-face {
  font-family: "Archivo";
  font-style: normal;
  font-weight: 400 700;
  font-stretch: 100% 125%;
  font-display: swap;
  src: url("fonts/archivo-var.3c50e08ced7c.woff2") format("woff2-variations"), url("fonts/archivo-var.3c50e08ced7c.woff2") format("woff2");
}

@font-face {
  font-family: "Martian Mono";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("fonts/martian-mono-400.3e1e5523ad5b.woff2") format("woff2");
}

/* Amharic. The unicode-range is the whole point: browsers fetch these 198 KB
   only once Ethiopic glyphs are actually on the page, so the English page never
   pays for it while every stack below still has a face that can draw አማርኛ. */
@font-face {
  font-family: "Noto Sans Ethiopic";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("fonts/noto-sans-ethiopic-var.a0606f383bd4.woff2") format("woff2-variations"), url("fonts/noto-sans-ethiopic-var.a0606f383bd4.woff2") format("woff2");
  unicode-range: U+030E, U+1200-1399, U+2D80-2DDE, U+AB01-AB2E;
}

@font-face {
  font-family: "Caveat";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("fonts/caveat-600-subset.cec74a6eeb2c.woff2") format("woff2");
}

:root {
  /* Ground and ink — see spec §4.2 */
  --ink: #10241c;
  --ink-raised: #1b3a2d;
  --paper: #fbf8f1;
  --paper-dim: #f1ecdf;
  --gold: #e0a32e;
  --gold-deep: #96600c;
  --gold-deepest: #8a5809;
  --clay: #9c4a2f;

  --border: #ddd4bd;
  --border-on-ink: rgba(251, 248, 241, 0.16);
  --text-muted: #5b6b60;
  --text-on-ink-muted: rgba(251, 248, 241, 0.72);

  --shadow-sm: 0 2px 8px rgba(16, 36, 28, 0.06);
  --shadow-md: 0 4px 20px rgba(16, 36, 28, 0.1);
  --shadow-lg: 0 12px 40px rgba(16, 36, 28, 0.16);
  --radius: 18px;
  --radius-lg: 28px;
  /* The capsule plus its inset. The hero is pulled up by exactly this much so
     the bar floats on the hero's ground rather than on a band above it. */
  --nav-height: 5rem;

  --font-display: "Archivo", "Noto Sans Ethiopic", sans-serif;
  --font-body: "Archivo", "Noto Sans Ethiopic", sans-serif;
  --font-utility: "Martian Mono", "Noto Sans Ethiopic", ui-monospace, monospace;
  --font-wordmark: "Caveat", cursive;
}

* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

/* The page is sized in rem throughout, so this one number sets both the type
   scale and the spacing rhythm. */
html {
  scroll-behavior: smooth;
  font-size: 15px;
}

body {
  font-family: var(--font-body);
  font-size: 0.95rem;
  line-height: 1.45;
  color: var(--ink);
  background: var(--paper);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

img {
  max-width: 100%;
  height: auto;
  display: block;
}

.container {
  width: min(100% - 3rem, 1120px);
  margin-inline: auto;
}

::selection {
  background: var(--gold);
  color: var(--ink);
}

/* Figures line up column to column wherever the page shows them. */
.roster,
.months,
.compare__stat,
.verify {
  font-variant-numeric: tabular-nums;
}

/* Typography */
h1, h2, h3, h4, h5, h6 {
  line-height: 1.15;
}

h1, h2 {
  font-family: var(--font-display);
  font-weight: 700;
  font-variation-settings: "wdth" 118;
  letter-spacing: -0.02em;
}

h3 {
  font-family: var(--font-body);
  font-weight: 600;
  font-variation-settings: "wdth" 100;
  letter-spacing: -0.01em;
}

/* Even line lengths in headings, no single trailing word in body copy. */
h2,
h3 {
  text-wrap: balance;
}

p {
  text-wrap: pretty;
}

/* The one requirement that decides whether a group can use PaidBot at all, so
   it is marked the same way wherever it is stated rather than left in the run
   of the sentence. Utility face and gold, as the eyebrows and step numbers. */
.cbe-mark {
  font-family: var(--font-utility);
  font-size: 0.84em;
  letter-spacing: -0.01em;
  color: var(--gold-deepest);
  background: rgba(224, 163, 46, 0.16);
  border-bottom: 1.5px solid rgba(224, 163, 46, 0.55);
  /* Tight on the right: a wider inset reads as a space when the mark is
     followed by a full stop or comma, which it usually is. */
  padding: 0.12em 0.24em;
  border-radius: 0.3em;
  white-space: nowrap;
}

/* On the dark grounds the deep gold goes muddy — the bright one carries. */
.banks .cbe-mark,
.panel--ink .cbe-mark {
  color: var(--gold);
  background: rgba(224, 163, 46, 0.2);
  border-bottom-color: rgba(224, 163, 46, 0.65);
}

/* Skip link */
.skip-link {
  position: absolute;
  top: -3rem;
  left: 1rem;
  z-index: 1000;
  background: var(--ink);
  color: var(--paper);
  padding: 0.75rem 1.25rem;
  border-radius: 0 0 10px 10px;
  font-weight: 600;
  text-decoration: none;
  transition: top 0.2s ease;
}

.skip-link:focus {
  top: 0;
}

/* Buttons */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding: 0.68rem 1.35rem;
  font-family: var(--font-body);
  font-size: 0.95rem;
  font-weight: 600;
  border-radius: 980px;
  border: 1.5px solid transparent;
  cursor: pointer;
  text-decoration: none;
  transition: transform 0.4s cubic-bezier(0.4, 0, 0.2, 1), background-color 0.4s ease, box-shadow 0.4s ease;
  white-space: nowrap;
}

.btn--primary {
  background: var(--ink);
  color: var(--paper);
}

.btn--primary:hover {
  background: var(--ink-raised);
  transform: scale(1.02);
}

.btn--secondary {
  background: transparent;
  color: var(--ink);
  border-color: var(--border);
}

.btn--secondary:hover {
  background: var(--paper-dim);
}

.btn--gold {
  background: var(--gold);
  color: var(--ink);
}

.btn--gold:hover {
  background: #ecb44a;
  transform: scale(1.02);
}

.btn--outline-on-ink {
  background: transparent;
  color: var(--paper);
  border-color: var(--border-on-ink);
}

.btn--outline-on-ink:hover {
  background: rgba(251, 248, 241, 0.08);
}

.btn--large {
  padding: 0.78rem 1.6rem;
  font-size: 0.98rem;
}

.btn:active {
  transform: scale(0.985);
}

/* Phones: the long label runs edge to edge in a 393px viewport, so the button
   loses its suffix and some padding and sits clear of both margins. */
@media (max-width: 640px) {
  /* !important so the utility still wins on elements that carry their own
     display rule, e.g. the flex list items in the hero. */
  .hide-on-mobile {
    display: none !important;
  }

  .btn--large {
    padding: 0.8rem 1.4rem;
    font-size: 1rem;
  }
}

/* Navigation */
/* The bar floats: a bordered capsule inset from the page edges, with the page
   showing through around it rather than a full-width band. */
.nav {
  position: sticky;
  top: 0;
  z-index: 100;
  height: var(--nav-height);
  margin-bottom: calc(-1 * var(--nav-height));
  padding-top: 0.75rem;
  background: transparent;
}

/* Wider than the content column by roughly the capsule's own padding, so the
   brand still lines up with everything below it. */
.nav .container {
  width: min(100% - 2rem, 1168px);
}

.nav__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  padding: 0.4rem 0.4rem 0.4rem 1rem;
  min-height: 56px;
  border: 1px solid var(--border);
  border-radius: 20px;
  background: rgba(251, 248, 241, 0.9);
  backdrop-filter: blur(14px) saturate(1.3);
  -webkit-backdrop-filter: blur(14px) saturate(1.3);
  transition: background-color 0.4s ease, box-shadow 0.4s ease;
}

/* The capsule only lifts off the page once there is content passing under it. */
.nav.is-scrolled .nav__inner {
  background: rgba(251, 248, 241, 0.97);
  box-shadow: 0 10px 30px rgba(16, 36, 28, 0.1);
}

.nav__brand {
  display: flex;
  align-items: center;
  min-height: 44px;
  gap: 0.75rem;
  color: var(--ink);
  text-decoration: none;
  flex-shrink: 0;
}

.nav__brand-name {
  display: flex;
  align-items: baseline;
  gap: 0.05em;
  line-height: 1;
  white-space: nowrap;
}

.nav__brand-paid {
  font-family: var(--font-display);
  font-size: 1.25rem;
  font-weight: 700;
  font-variation-settings: "wdth" 112;
  letter-spacing: -0.02em;
  color: var(--ink);
}

.nav__brand-bot {
  font-family: var(--font-wordmark);
  font-size: 1.55rem;
  font-weight: 600;
  line-height: 1;
  color: var(--gold-deep);
  position: relative;
  top: 1px;
}

.nav__logo {
  width: 34px;
  height: 34px;
  object-fit: contain;
  flex-shrink: 0;
  border-radius: 10px;
  box-shadow: var(--shadow-sm);
}

/* One segmented track rather than three loose links: the section you are reading
   holds the raised segment (see main.js). */
.nav__links {
  display: none;
  align-items: center;
  gap: 0.15rem;
  padding: 0.25rem;
  border: 1px solid rgba(221, 212, 189, 0.75);
  border-radius: 999px;
  background: var(--paper-dim);
}

.nav__links a {
  padding: 0.45rem 0.95rem;
  border-radius: 999px;
  color: var(--text-muted);
  text-decoration: none;
  font-size: 0.88rem;
  font-weight: 500;
  white-space: nowrap;
  transition: color 0.35s ease, background-color 0.4s ease, box-shadow 0.4s ease;
}

.nav__links a:hover {
  color: var(--ink);
}

.nav__links a:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 2px;
}

.nav__links a.is-active {
  background: var(--paper);
  color: var(--ink);
  box-shadow: var(--shadow-sm);
}

/* A quiet mark at the end of the bar rather than a control with a box round it:
   the utility face and gold the page already uses for its small labels, set off
   from the section track by one hairline. The globe and the underline are what
   keep two letters from reading as a caption — an icon and a ruled word are both
   things a reader expects to be able to press. */
.nav__actions .nav__lang {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  height: 2rem;
  padding: 0 0.5rem 0 0.85rem;
  border-left: 1px solid var(--border);
  color: var(--gold-deepest);
  font-family: var(--font-utility);
  font-size: 0.72rem;
  letter-spacing: 0.06em;
  text-decoration: none;
  transition: color 0.3s ease;
}

.nav__lang-mark {
  text-decoration: underline;
  text-decoration-color: rgba(150, 96, 12, 0.4);
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  transition: text-decoration-color 0.3s ease;
}

.nav__lang-globe {
  flex-shrink: 0;
  opacity: 0.85;
}

.nav__actions .nav__lang:hover {
  color: var(--ink);
}

.nav__actions .nav__lang:hover .nav__lang-mark {
  text-decoration-color: currentColor;
}

.nav__actions .nav__lang:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 2px;
  border-radius: 6px;
}

/* Ethiopic has no case and falls to a different face than the mono, so it needs
   its own size to sit at the same optical weight as EN. */
.nav__actions .nav__lang[lang="am"] {
  font-size: 0.86rem;
  letter-spacing: 0.02em;
}

.nav__actions {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.nav .btn {
  padding: 0.55rem 1.3rem;
  font-size: 0.88rem;
}

.nav__toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  background: transparent;
  border: 1px solid var(--border);
  border-radius: 12px;
  color: var(--ink);
  cursor: pointer;
  flex-shrink: 0;
}

.nav__toggle svg {
  width: 22px;
  height: 22px;
}

.nav__toggle-icon--close {
  display: none;
}

.nav__toggle[aria-expanded="true"] .nav__toggle-icon--open {
  display: none;
}

.nav__toggle[aria-expanded="true"] .nav__toggle-icon--close {
  display: block;
}

/* The phone menu is a second floating card under the bar, not a drawer attached
   to it — the capsule keeps its shape when the menu is open. */
.nav__panel {
  display: none;
  flex-direction: column;
  gap: 0.25rem;
  margin-top: 0.5rem;
  padding: 0.5rem;
  border: 1px solid var(--border);
  border-radius: 20px;
  background: rgba(251, 248, 241, 0.96);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  box-shadow: var(--shadow-md);
}

.nav__panel[data-open="true"] {
  display: flex;
}

.nav__panel a {
  padding: 0.75rem 0.9rem;
  color: var(--ink);
  text-decoration: none;
  font-weight: 500;
  font-size: 1.05rem;
  border-radius: 10px;
}

.nav__panel a:hover {
  background: var(--paper-dim);
}

/* The bar's own button is icon-only at this width, so the menu carries the one
   place the action is spelled out. */
.nav__panel a.nav__panel-cta {
  margin-top: 0.25rem;
  text-align: center;
  background: var(--gold);
  font-weight: 600;
}

.nav__panel a.nav__panel-cta:hover {
  background: #ecb44a;
}

/* Phones: brand, labelled button and menu toggle can't share the bar without
   crowding it, so the button becomes its icon and the bar aligns with the page.
   The icon still has to be a comfortable target, hence the fixed 44px. */
@media (max-width: 560px) {
  .nav__inner {
    padding-left: 0.85rem;
  }

  .nav .btn__label {
    display: none;
  }

  .nav .btn {
    width: 44px;
    height: 44px;
    padding: 0;
  }

  .nav .btn__icon {
    width: 20px;
    height: 20px;
  }

  /* Four things now share the bar, so it closes up to the width the language
     mark needs — and with no section track beside it, the mark stands on its
     own rather than behind a divider. */
  .nav__inner {
    gap: 0.5rem;
  }

  .nav__actions {
    gap: 0.35rem;
  }

  .nav__actions .nav__lang {
    height: 44px;
    padding: 0 0.35rem;
    border-left: 0;
  }
}

@media (min-width: 768px) {
  .nav__inner {
    min-height: 60px;
  }

  /* Auto margins centre the track in the space the brand and button leave. */
  .nav__links {
    display: inline-flex;
    margin-inline: auto;
  }

  .nav__toggle,
  .nav__panel {
    display: none;
  }
}

/* Hero — ink ground, ledger rule texture. One centred column at every width:
   headline, subtitle, both actions, then the phone. No bottom padding — the
   cut across the frame is the section's bottom edge. */
.hero {
  position: relative;
  padding: calc(var(--nav-height) + 2rem) 0 0;
  background: var(--ink);
  color: var(--paper);
  text-align: center;
  overflow: hidden;
  background-image:
    radial-gradient(ellipse 900px 480px at 50% -10%, rgba(224, 163, 46, 0.16), transparent 65%),
    repeating-linear-gradient(0deg, var(--border-on-ink) 0, var(--border-on-ink) 1px, transparent 1px, transparent 44px);
}

.hero .container {
  max-width: 980px;
}

.hero__title {
  font-size: clamp(1.6rem, 4.6vw, 2.5rem);
  margin-bottom: 0.4rem;
  color: var(--paper);
  animation: fade-up 0.9s cubic-bezier(0.16, 1, 0.3, 1) both;
}

.hero__title span {
  color: var(--gold);
}

.hero__subtitle {
  font-size: clamp(0.9rem, 1.8vw, 1.02rem);
  color: var(--text-on-ink-muted);
  margin-bottom: 1.4rem;
  max-width: 620px;
  margin-inline: auto;
  animation: fade-up 0.9s cubic-bezier(0.16, 1, 0.3, 1) both;
  animation-delay: 0.12s;
}

.hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  justify-content: center;
  margin-bottom: 2rem;
  animation: fade-up 0.9s cubic-bezier(0.16, 1, 0.3, 1) both;
  animation-delay: 0.24s;
}

/* Half phone: the frame is taller than this box and the overflow is the cut, so
   it reads as rising from the bottom of the hero. The height is tuned to keep
   the whole exchange — receipt through the bot's reply — above the cut. */
.hero__visual {
  position: relative;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  overflow: hidden;
  max-height: 400px;
}

/* A pool of light behind the frame — no hard-edged shape, so the phone reads as
   lit and set forward rather than pasted flat onto the ink. It fades out well
   before the cut, which would otherwise leave a visible edge. */
.hero__visual::before {
  content: "";
  position: absolute;
  left: 50%;
  top: -6%;
  width: min(250%, 62rem);
  height: 96%;
  transform: translateX(-50%);
  background:
    radial-gradient(ellipse 40% 26% at 50% 30%, rgba(250, 214, 140, 0.42), transparent 68%),
    radial-gradient(ellipse 54% 38% at 50% 36%, rgba(64, 143, 104, 0.95), transparent 70%),
    radial-gradient(ellipse 72% 52% at 50% 42%, rgba(31, 78, 57, 0.85), transparent 74%);
  pointer-events: none;
}

/* Drawn at full size and scaled down, so the chat keeps its real proportions
   while the hero stays about one screen tall. */
.hero-phone,
.demo-img {
  --phone-scale: 0.8;
  position: relative;
  z-index: 1;
  transform: scale(var(--phone-scale));
  transform-origin: top center;
}

.demo-img {
  width: 100%;
  max-width: 380px;
  border-radius: 48px;
  box-shadow: var(--shadow-lg);
  object-fit: cover;
}

/* Hero phone — a recreated device frame, not a real screenshot or a copy of any
   vendor's marketing render. Telegram's own chat colors are used inside the
   screen so it reads as authentic; the bezel, buttons and status bar are an
   original illustration built from ordinary phone conventions. */
.hero-phone {
  --hero-scene: 3.8s;
  width: 100%;
  max-width: 360px;
  /* Real handset proportions, so the frame is device-shaped rather than sized by
     however tall the conversation happens to be. */
  aspect-ratio: 1 / 2.06;
  display: flex;
  flex-direction: column;
  background: linear-gradient(155deg, #4a4a52 0%, #23232a 10%, #0c0c10 50%, #23232a 90%, #4a4a52 100%);
  border-radius: 58px;
  padding: 13px;
  box-shadow: 0 40px 90px rgba(0, 0, 0, 0.5), inset 0 0 0 1px rgba(255, 255, 255, 0.1);
  position: relative;
  animation: phone-rise 0.95s cubic-bezier(0.16, 1, 0.3, 1) both;
  animation-delay: 0.5s;
}

.hero-phone::before,
.hero-phone::after {
  content: "";
  position: absolute;
  left: -3px;
  width: 3px;
  border-radius: 3px 0 0 3px;
  background: #0a0a0e;
}

.hero-phone::before {
  top: 116px;
  height: 34px;
}

.hero-phone::after {
  top: 166px;
  height: 62px;
  box-shadow: 0 76px 0 #0a0a0e;
}

.hero-phone__power {
  position: absolute;
  right: -3px;
  top: 176px;
  width: 3px;
  height: 96px;
  border-radius: 0 3px 3px 0;
  background: #0a0a0e;
}

.hero-phone__notch {
  position: absolute;
  top: 22px;
  left: 50%;
  transform: translateX(-50%);
  width: 108px;
  height: 30px;
  background: #050507;
  border-radius: 18px;
  z-index: 4;
}

.hero-phone__screen {
  position: relative;
  flex: 1;
  min-height: 0;
  border-radius: 46px;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  /* The hero centres its text; chat content must read left-aligned. */
  text-align: left;
  /* Telegram-style patterned chat wallpaper, drawn with gradients (no bitmap). */
  background-color: #c3cfe8;
  background-image:
    radial-gradient(circle at 18% 22%, rgba(255, 255, 255, 0.30) 0 7px, transparent 8px),
    radial-gradient(circle at 82% 12%, rgba(255, 255, 255, 0.20) 0 11px, transparent 12px),
    radial-gradient(circle at 72% 68%, rgba(255, 255, 255, 0.24) 0 9px, transparent 10px),
    radial-gradient(circle at 28% 82%, rgba(255, 255, 255, 0.18) 0 13px, transparent 14px),
    radial-gradient(circle at 50% 45%, rgba(255, 255, 255, 0.14) 0 5px, transparent 6px),
    linear-gradient(165deg, #bcccea 0%, #c9c0e4 48%, #b9cbe9 100%);
  background-size: 118px 118px, 154px 154px, 136px 136px, 172px 172px, 96px 96px, 100% 100%;
}

.hero-phone__statusbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.95rem 1.7rem 0.35rem;
  color: #14141a;
  position: relative;
  z-index: 3;
}

.hero-phone__time {
  font-size: 0.95rem;
  font-weight: 700;
  letter-spacing: -0.01em;
}

.hero-phone__status-icons {
  display: flex;
  align-items: center;
  gap: 5px;
}

.hero-phone__status-icons svg {
  fill: currentColor;
}

.hero-phone__chat {
  flex: 1;
  display: flex;
  flex-direction: column;
  position: relative;
}

/* Floating header that sits over the wallpaper, as Telegram draws it. */
.hero-phone__header {
  position: absolute;
  top: 0.35rem;
  left: 0;
  right: 0;
  z-index: 3;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  padding: 0 0.8rem;
}

.hero-phone__circle-btn,
.hero-phone__group-avatar {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  background: rgba(255, 255, 255, 0.82);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  box-shadow: 0 1px 6px rgba(20, 20, 40, 0.12);
}

.hero-phone__circle-btn {
  color: #2f2f38;
}

.hero-phone__group-avatar {
  font-size: 1.05rem;
  background: linear-gradient(150deg, #7bb6f0, #4b8fe0);
}

/* Truncates rather than wraps, as Telegram does. A wrapped title would grow the
   floating header downwards onto the receipt beneath it on narrow phones. */
.hero-phone__title-pill {
  display: flex;
  flex-direction: column;
  align-items: center;
  min-width: 0;
  line-height: 1.25;
  padding: 0.3rem 0.95rem;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.82);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  box-shadow: 0 1px 6px rgba(20, 20, 40, 0.12);
}

.hero-phone__chat-name,
.hero-phone__chat-sub {
  max-width: 100%;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.hero-phone__chat-name {
  font-size: 0.95rem;
  font-weight: 700;
  color: #14141a;
  letter-spacing: -0.01em;
}

.hero-phone__chat-sub {
  font-size: 0.7rem;
  color: #6b6b7a;
}

.hero-phone__messages {
  flex: 1;
  display: flex;
  flex-direction: column;
  /* Conversation sits directly under the header rather than at the bottom of the
     screen, so the whole exchange survives the frame being cut off below. */
  justify-content: flex-start;
  gap: 0.55rem;
  padding: 3.6rem 0.75rem 0.6rem;
  position: relative;
  z-index: 1;
}

.hero-phone__msg {
  display: flex;
}

/* The exchange (receipt in, typing, reaction, reply) loops on an 8s cycle
   instead of playing once and freezing — see the hero-demo-* keyframes. */
.hero-phone__msg--out {
  justify-content: flex-end;
  position: relative;
  padding-bottom: 0.55rem;
  animation: hero-demo-msg-out var(--hero-scene) cubic-bezier(0.16, 1, 0.3, 1) infinite;
}

.hero-phone__msg--in {
  align-items: flex-end;
  gap: 0.4rem;
  padding-right: 0.6rem;
  animation: hero-demo-msg-in var(--hero-scene) cubic-bezier(0.16, 1, 0.3, 1) infinite;
}

/* Posted receipt screenshot — a real payment screenshot is a tall, narrow
   crop, not a square card, so the shape is fixed rather than left to its
   content's natural size. */
.hero-phone__photo {
  position: relative;
  container-type: inline-size;
  width: 46%;
  aspect-ratio: 5 / 8;
  border-radius: 18px;
  overflow: hidden;
  background: #fff;
  box-shadow: 0 2px 10px rgba(20, 20, 40, 0.18);
}

.hero-phone__photo-meta {
  position: absolute;
  right: 7px;
  bottom: 7px;
  display: flex;
  align-items: center;
  gap: 3px;
  padding: 0.1rem 0.4rem;
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.42);
  color: #fff;
  font-size: 0.62rem;
  font-weight: 500;
}

.hero-phone__photo-meta svg {
  color: #8fe3a0;
}

/* The posted screenshot: a bank's "payment successful" screen. Every length
   inside is em-based, so each place it appears sets one font-size and the
   whole thing scales — hero, step 2's thumbnails, step 3's smaller ones. */
.receipt {
  /* Sized from the card it fills, so hero and thumbnails stay in proportion.
     The px value is the fallback where container units are unsupported. */
  font-size: 9px;
  font-size: 9.8cqw;
  display: flex;
  flex-direction: column;
  height: 100%;
  background: #fff;
  color: #3a3a45;
}

/* The card is a fixed shape; its parts hold their size rather than squeezing
   to fit, or the QR collapses into a smudge. */
.receipt > * {
  flex-shrink: 0;
}

.receipt__head {
  position: relative;
  background: linear-gradient(135deg, #8b2fa8, #6d1f95);
  padding: 0.5em 0.55em 1em;
  /* Room for the tick that straddles the banner's edge — set here because a
     margin on the title would scale to the title's own smaller font. */
  margin-bottom: 1.35em;
}

.receipt__head-label {
  display: block;
  font-size: 0.6em;
  font-weight: 700;
  line-height: 1.3;
  color: #fff;
}

.receipt__head-label em {
  display: block;
  font-style: normal;
  font-size: 0.82em;
  font-weight: 500;
  color: rgba(255, 255, 255, 0.7);
}

/* The screenshot control the bank puts in its own banner. */
.receipt__scan {
  position: absolute;
  top: 0.5em;
  right: 0.5em;
  width: 1.15em;
  height: 1.15em;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.22);
}

.receipt__check {
  position: absolute;
  left: 50%;
  bottom: -1em;
  transform: translateX(-50%);
  width: 2em;
  height: 2em;
  border-radius: 50%;
  background: #fff;
  color: #2fa85c;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 1px 5px rgba(0, 0, 0, 0.18);
}

.receipt__check svg {
  width: 55%;
  height: 55%;
}

.receipt__title {
  display: block;
  margin: 0 0.5em;
  text-align: center;
  font-size: 0.55em;
  font-weight: 600;
}

/* The transaction detail stays redacted — the shape of the bank's summary
   panel, never anyone's figures. */
.receipt__summary {
  margin: 0.5em 0.5em 0;
  padding: 0.4em 0.42em;
  border-radius: 0.35em;
  background: #f1f2f6;
}

.receipt__summary-label {
  display: block;
  width: 48%;
  height: 0.2em;
  margin-bottom: 0.36em;
  border-radius: 1px;
  background: #c4c7d2;
}

.receipt__rows {
  display: flex;
  flex-direction: column;
  gap: 0.22em;
}

.receipt__rows span {
  height: 0.2em;
  border-radius: 1px;
  background: #d7dae3;
}

.receipt__qr {
  width: 2.2em;
  height: 2.2em;
  /* Auto margins hand the card's leftover height to the space around the QR,
     the way the bank's own screen breathes there, and keep Close at the foot. */
  margin: auto;
  background-color: #fff;
  background-image:
    repeating-linear-gradient(90deg, #2b2b33 0 3px, transparent 3px 6px),
    repeating-linear-gradient(0deg, #2b2b33 0 3px, transparent 3px 6px);
  background-size: 6px 6px;
  outline: 1px solid #e3e5eb;
}

.receipt__bank {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.3em;
}

.receipt__bank-mark {
  width: 0.95em;
  height: 0.95em;
  border-radius: 50%;
  background: linear-gradient(150deg, #d3b05e, #8a6a2f);
}

.receipt__bank-lines {
  display: flex;
  flex-direction: column;
  gap: 0.16em;
}

.receipt__bank-lines b,
.receipt__bank-lines i {
  display: block;
  border-radius: 1px;
  background: #c4c7d2;
}

.receipt__bank-lines b {
  width: 3.6em;
  height: 0.22em;
}

.receipt__bank-lines i {
  width: 2.7em;
  height: 0.16em;
  background: #d7dae3;
}

/* Receipt · Screenshot · Share, the row the bank puts above Close. */
.receipt__actions {
  display: flex;
  justify-content: space-around;
  margin: 0.35em 0.5em 0;
  padding-top: 0.32em;
  border-top: 1px solid #eceef3;
}

.receipt__actions span {
  width: 1.1em;
  height: 0.18em;
  border-radius: 1px;
  background: #c4c7d2;
}

.receipt__close {
  margin: 0.4em 0.5em 0.45em;
  padding: 0.3em;
  border-radius: 0.35em;
  background: #eceef3;
  font-size: 0.5em;
  font-weight: 600;
  text-align: center;
  color: #6b6b7a;
}

/* Telegram shows a single reactor's avatar in place of a count — this mirrors
   that convention rather than a generic "👍 1" badge. */
.hero-phone__reaction {
  position: absolute;
  right: 10px;
  bottom: -2px;
  display: flex;
  align-items: center;
  gap: 4px;
  background: #fff;
  border-radius: 999px;
  padding: 0.2rem 0.32rem 0.2rem 0.5rem;
  box-shadow: 0 2px 7px rgba(20, 20, 40, 0.2);
  animation: hero-demo-reaction var(--hero-scene) cubic-bezier(0.34, 1.56, 0.64, 1) infinite;
}

.hero-phone__reaction-emoji {
  font-size: 0.78rem;
  line-height: 1;
}

.hero-phone__reaction-avatar {
  width: 16px;
  height: 16px;
  border-radius: 50%;
  object-fit: cover;
  display: block;
}

.hero-phone__typing {
  align-self: flex-start;
  display: flex;
  align-items: center;
  gap: 5px;
  overflow: hidden;
  padding: 0.7rem 0.85rem;
  margin-left: 42px;
  background: #fff;
  border-radius: 17px;
  border-bottom-left-radius: 5px;
  box-shadow: 0 1px 4px rgba(20, 20, 40, 0.14);
  animation: hero-demo-typing var(--hero-scene) ease infinite;
}

.hero-phone__typing span {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: #a0a0ad;
  animation: dot-bounce 0.9s ease-in-out infinite;
}

.hero-phone__typing span:nth-child(2) { animation-delay: 0.15s; }
.hero-phone__typing span:nth-child(3) { animation-delay: 0.3s; }

.hero-phone__bot-avatar {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  flex-shrink: 0;
  box-shadow: 0 1px 4px rgba(20, 20, 40, 0.18);
}

.hero-phone__bubble {
  max-width: 100%;
  background: #fff;
  color: #14141a;
  padding: 0.5rem 0.7rem 0.55rem;
  border-radius: 17px;
  border-bottom-left-radius: 5px;
  box-shadow: 0 1px 5px rgba(20, 20, 40, 0.16);
}

.hero-phone__sender {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  font-size: 0.8rem;
  font-weight: 700;
  color: #2f7fd0;
  margin-bottom: 0.25rem;
}

.hero-phone__sender em {
  font-style: normal;
  font-size: 0.62rem;
  font-weight: 500;
  color: #8e8e9c;
}

.hero-phone__quote {
  display: flex;
  flex-direction: column;
  gap: 1px;
  border-left: 2.5px solid #2f7fd0;
  border-radius: 3px;
  background: rgba(47, 127, 208, 0.08);
  padding: 0.22rem 0.45rem;
  margin-bottom: 0.35rem;
}

.hero-phone__quote-name {
  font-size: 0.68rem;
  font-weight: 700;
  color: #2f7fd0;
}

.hero-phone__quote-text {
  font-size: 0.68rem;
  color: #6b6b7a;
}

.hero-phone__bubble p {
  font-size: 0.83rem;
  line-height: 1.4;
}

.hero-phone__tick {
  margin-right: 0.3em;
}

.hero-phone__bubble p + p {
  margin-top: 0.35rem;
}

.hero-phone__bubble-last {
  display: flex;
  align-items: baseline;
  gap: 0.6rem;
}

.hero-phone__time-inline {
  font-size: 0.62rem;
  color: #9a9aa8;
  flex-shrink: 0;
}

.hero-phone__inputbar {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin: 0 0.6rem 0.35rem;
  padding: 0.6rem 0.85rem;
  background: rgba(255, 255, 255, 0.95);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border-radius: 999px;
  color: #8e8e9c;
  position: relative;
  z-index: 2;
}

.hero-phone__input-placeholder {
  flex: 1;
  font-size: 0.88rem;
}

.hero-phone__home {
  height: 24px;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  z-index: 2;
}

.hero-phone__home::after {
  content: "";
  width: 122px;
  height: 5px;
  border-radius: 999px;
  background: #14141a;
  opacity: 0.55;
}

@media (max-width: 480px) {
  .hero-phone,
  .demo-img {
    max-width: 320px;
  }
}

/* Small phones: a step down keeps the headline to two lines. */
@media (max-width: 400px) {
  .hero__title {
    font-size: 1.6rem;
  }

  /* The pill has ~120px between the back button and the avatar here, so it
     claims the whole gap and the group name is stepped down to fit inside it
     rather than being ellipsised away. */
  .hero-phone__title-pill {
    flex: 1;
    padding-inline: 0.5rem;
  }

  .hero-phone__chat-name {
    font-size: 0.82rem;
  }

  .hero-phone__chat-sub {
    font-size: 0.62rem;
  }

  .hero-phone__circle-btn,
  .hero-phone__group-avatar {
    width: 32px;
    height: 32px;
  }
}

/* Phones: tighter copy, and the secondary action drops to a low-profile text
   button so the primary keeps all the weight. */
@media (max-width: 899px) {
  .hero {
    padding-top: calc(var(--nav-height) + 0.75rem);
  }

  .hero__subtitle {
    font-size: 0.95rem;
    line-height: 1.45;
    margin-bottom: 0.7rem;
    max-width: 26rem;
  }

  .hero__actions {
    gap: 0.4rem;
    margin-bottom: 0.9rem;
  }

  /* Reads as a plain text link but keeps a full-size touch target. */
  .hero__actions .btn--outline-on-ink {
    border-color: transparent;
    min-height: 44px;
    padding: 0.3rem 0.75rem;
    font-size: 0.95rem;
    text-decoration: underline;
    text-underline-offset: 4px;
  }

  .hero__visual {
    max-height: 355px;
  }

  /* Tighter chrome above the conversation — status bar and the gap under the
     floating header — so the bot's reply lands above the cut. The gap still has
     to clear the header pill itself, or the receipt starts underneath it. */
  .hero-phone__statusbar {
    padding: 0.6rem 1.5rem 0.2rem;
  }

  .hero-phone__messages {
    padding-top: 3.2rem;
    gap: 0.4rem;
  }

  .hero-phone__msg--out {
    padding-bottom: 0.35rem;
  }

  /* A more compact receipt keeps the exchange inside the visible slice —
     the portrait shape makes it taller per pixel of width, so it runs
     narrower here than the old square card did. */
  .hero-phone__photo {
    width: 30%;
  }
}

/* Desktop: same centred column, a larger frame and a deeper slice of it. */
@media (min-width: 900px) {
  .hero {
    padding-top: calc(var(--nav-height) + 3rem);
  }

  .hero-phone,
  .demo-img {
    --phone-scale: 0.85;
    max-width: 380px;
  }

  .hero__visual {
    max-height: 420px;
  }

  .hero-phone__photo {
    width: 34%;
  }
}

/* Sections are panels. Each carries its own ground and rides up over the one
   before it, so its rounded shoulders reveal the colour underneath — the page
   reads as a sequence of scenes rather than one continuous stretch. */
.panel {
  position: relative;
  padding: 4.5rem 0 3.25rem;
  margin-top: -2.25rem;
  border-radius: 2.25rem 2.25rem 0 0;
  background: var(--paper);
}

/* Ink panels reuse the hero's ledger-rule ground, at half its contrast: the
   rules sit close behind body text here, where the hero's are in open space. */
.panel--ink {
  background-color: var(--ink);
  color: var(--paper);
  overflow: hidden;
  background-image:
    radial-gradient(ellipse 700px 400px at 50% 110%, rgba(224, 163, 46, 0.14), transparent 65%),
    repeating-linear-gradient(0deg, rgba(251, 248, 241, 0.07) 0, rgba(251, 248, 241, 0.07) 1px, transparent 1px, transparent 44px);
}

/* Section headers — every section opens the same way: utility eyebrow, then a
   title whose closing clause takes the accent. */
.section-header {
  text-align: center;
  margin-bottom: 1.9rem;
}

.section-eyebrow {
  display: block;
  font-family: var(--font-utility);
  font-size: 0.68rem;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--gold-deep);
  margin-bottom: 0.75rem;
}

.panel--ink .section-eyebrow {
  color: var(--gold);
}

.section-title {
  font-size: clamp(1.45rem, 3.3vw, 2rem);
  margin-bottom: 0.6rem;
  text-wrap: balance;
}

.section-title span {
  color: var(--gold-deep);
}

.panel--ink .section-title span {
  color: var(--gold);
}

.section-subtitle {
  font-size: 0.98rem;
  color: var(--text-muted);
  max-width: 640px;
  margin-inline: auto;
}

/* How it works */
.how-section {
  background: var(--paper-dim);
  scroll-margin-top: 96px;
}

.how-grid {
  display: grid;
  gap: 1.25rem;
  grid-template-columns: 1fr;
}

.how-step {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 0.75rem;
}

.how-step__number {
  font-family: var(--font-utility);
  font-size: 0.75rem;
  font-weight: 400;
  letter-spacing: 0.1em;
  color: var(--gold-deep);
}

/* Plain wrapper — the device inside carries its own shape, bezel and shadow. */
.step-visual {
  display: flex;
  justify-content: center;
  width: 100%;
}

.step-title {
  font-size: 1.05rem;
}

.step-caption {
  font-size: 0.86rem;
  color: var(--text-muted);
  max-width: 260px;
  line-height: 1.5;
}

/* Phones and tablets: each step reads as a heading with its own animation
   underneath, and a rule closes the step, so no scene can be read as the
   caption of the next one. */
@media (max-width: 899px) {
  .how-grid {
    gap: 0;
  }

  .how-step {
    gap: 0.55rem;
    padding-bottom: 2.25rem;
  }

  .how-step + .how-step {
    padding-top: 2.25rem;
    border-top: 1px solid var(--border);
  }

  .how-step__number { order: 1; }
  .step-title { order: 2; }
  .step-visual { order: 4; }

  .step-caption {
    order: 3;
    max-width: 34ch;
    margin-bottom: 0.55rem;
  }
}

/* The pinned stage is desktop only: below 900px the three steps stack, each
   carrying its own frame, which is the layout phones already had. */
.how__stage {
  display: none;
}

/* From 900px the per-step frames give way to one frame that stays pinned while
   the steps scroll past it, so the sequence reads as one device changing. */
@media (min-width: 900px) {
  .how {
    display: grid;
    grid-template-columns: 1fr 288px;
    gap: 4rem;
    align-items: start;
    max-width: 900px;
    margin-inline: auto;
  }

  .how__stage {
    display: flex;
    order: 2;
    justify-content: center;
    position: sticky;
    /* Centred in the viewport where there is room, clear of the nav where there isn't. */
    top: max(6.5rem, calc(50vh - 260px));
  }

  /* Sized to the device it holds, so the sticky stage reserves the right space
     while each scene stacks inside it. */
  .how__frame {
    position: relative;
    width: 100%;
    max-width: var(--device-width);
    min-width: 0;
    aspect-ratio: var(--device-ratio);
  }

  .how__shot {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    opacity: 0;
    will-change: opacity;
    transition: opacity 0.6s cubic-bezier(0.16, 1, 0.3, 1);
  }

  .how__shot.is-active {
    opacity: 1;
  }

  .how-grid {
    order: 1;
    grid-template-columns: 1fr;
    gap: 0;
  }

  /* Each step owns a screenful, so the stage has time to change between them. */
  .how-step {
    align-items: flex-start;
    text-align: left;
    justify-content: center;
    min-height: 42vh;
    padding-left: 1.75rem;
    position: relative;
  }

  .how-step::before {
    content: "";
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    width: 2px;
    border-radius: 2px;
    background: var(--border);
    transition: background-color 0.35s ease;
  }

  .how-step.is-active::before {
    background: var(--gold-deep);
  }

  /* Only dimmed once the observer is driving the rail — without JS every step
     stays legible. */
  .how--enhanced .how-step {
    opacity: 0.45;
    transition: opacity 0.35s ease;
  }

  .how--enhanced .how-step.is-active {
    opacity: 1;
  }

  .how-step .step-visual {
    display: none;
  }

  .step-caption {
    max-width: 42ch;
  }
}

/* How it works — each step is a phone with Telegram open. The same scene
   markup renders twice: once per step for the mobile stack (.step-visual) and
   once inside the pinned desktop frame (.how__shot). */
.how {
  --device-width: 268px;
  --device-ratio: 1 / 2.03;

  /* One knob for the whole conversation: type, and the reveal heights the
     keyframes animate to. The phone-shaped frame needs the small end; the
     full-width mobile card reads well above it. */
  --scene-scale: 1;

  /* Reveals now open to the height they actually need, so they ease out
     without the overshoot the page's display curve carries. */
  --ease-beat: cubic-bezier(0.22, 0.68, 0.28, 1);
  --ease-pane: cubic-bezier(0.62, 0.02, 0.3, 1);
  --ease-pop: cubic-bezier(0.34, 1.42, 0.64, 1);
}

/* One clock per step: the pinned shot, the stacked visual and the progress
   rail all read it, so retiming a scene is a single number. */
.how-step[data-step="1"], .how__shot[data-step="1"] { --scene: 20s; }
.how-step[data-step="2"], .how__shot[data-step="2"] { --scene: 1.8s; }
.how-step[data-step="3"], .how__shot[data-step="3"] { --scene: 4s; }

/* Recreated flagship handset: titanium rail, flat sides, Dynamic Island. Drawn
   from ordinary device conventions — not traced from any vendor's artwork. */
.how-device {
  position: relative;
  width: 100%;
  max-width: var(--device-width);
  /* A flex item's min-width:auto would beat max-width and hold the frame at
     the chat's min-content width; below ~308px that overflows the column. */
  min-width: 0;
  aspect-ratio: var(--device-ratio);
  padding: 8px;
  border-radius: 46px;
  /* The rail catches light on its rounded edges and darkens across the flat
     face; the tight stops are what read as brushed metal rather than plastic. */
  background: linear-gradient(96deg,
    #efebe4 0%, #b6afa5 3%, #6d685f 9%,
    #44403b 22%, #393632 50%, #44403b 78%,
    #6d685f 91%, #b6afa5 97%, #efebe4 100%);
  box-shadow:
    0 26px 55px rgba(16, 36, 28, 0.34),
    0 6px 16px rgba(16, 36, 28, 0.2),
    inset 0 0 0 1px rgba(255, 255, 255, 0.22);
}

/* Side buttons, cut from the same rail: Action and the volume pair on the
   left, the side button on the right. */
.how-device__btn {
  position: absolute;
  width: 2px;
  background: linear-gradient(180deg, #56514b, #312e2a);
}

.how-device__btn--action {
  left: -2px;
  top: 15.5%;
  height: 3.6%;
  border-radius: 2px 0 0 2px;
}

.how-device__btn--vol-up {
  left: -2px;
  top: 22.5%;
  height: 6.4%;
  border-radius: 2px 0 0 2px;
}

.how-device__btn--vol-down {
  left: -2px;
  top: 30.6%;
  height: 6.4%;
  border-radius: 2px 0 0 2px;
}

.how-device__btn--side {
  right: -2px;
  top: 25.5%;
  height: 9.2%;
  border-radius: 0 2px 2px 0;
}

.how-device__screen {
  position: relative;
  height: 100%;
  border-radius: 39px;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  background: #000;
}

.how-device__island {
  position: absolute;
  top: 9px;
  left: 50%;
  transform: translateX(-50%);
  width: 31%;
  height: 21px;
  border-radius: 999px;
  background: #08080a;
  z-index: 6;
}

/* Front camera, set into the island's right end. */
.how-device__island::after {
  content: "";
  position: absolute;
  right: 13%;
  top: 50%;
  transform: translateY(-50%);
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: radial-gradient(circle at 32% 28%, #2c3654 0 30%, #0d1018 62%, #05060a 100%);
}

.how-scene {
  position: relative;
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  text-align: left;
  /* Telegram-style patterned chat wallpaper, drawn with gradients (no bitmap). */
  background-color: #c3cfe8;
  background-image:
    radial-gradient(circle at 18% 22%, rgba(255, 255, 255, 0.30) 0 7px, transparent 8px),
    radial-gradient(circle at 82% 12%, rgba(255, 255, 255, 0.20) 0 11px, transparent 12px),
    radial-gradient(circle at 72% 68%, rgba(255, 255, 255, 0.24) 0 9px, transparent 10px),
    radial-gradient(circle at 28% 82%, rgba(255, 255, 255, 0.18) 0 13px, transparent 14px),
    radial-gradient(circle at 50% 45%, rgba(255, 255, 255, 0.14) 0 5px, transparent 6px),
    linear-gradient(165deg, #bcccea 0%, #c9c0e4 48%, #b9cbe9 100%);
  background-size: 118px 118px, 154px 154px, 136px 136px, 172px 172px, 96px 96px, 100% 100%;
}

/* iOS draws the nav bar up behind the status bar as one translucent block. */
.how-scene__navbar {
  position: relative;
  z-index: 5;
  flex-shrink: 0;
  background: rgba(247, 247, 250, 0.94);
  backdrop-filter: blur(18px);
  -webkit-backdrop-filter: blur(18px);
  box-shadow: 0 0.5px 0 rgba(20, 20, 40, 0.16);
}

.how-scene__statusbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 36px;
  padding: 8px 19px 0;
  color: #14141a;
}

.how-scene__clock {
  font-size: calc(0.68rem * var(--scene-scale));
  font-weight: 700;
  letter-spacing: -0.01em;
}

.how-scene__status-icons {
  display: flex;
  align-items: center;
  gap: 4px;
}

.how-scene__status-icons svg {
  fill: currentColor;
}

.how-scene__header {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0 0.5rem 0.42rem;
}

.how-scene__back {
  display: flex;
  align-items: center;
  color: #2f7fd0;
  flex-shrink: 0;
}

.how-scene__title {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  line-height: 1.2;
}

.how-scene__title-name {
  font-size: calc(0.72rem * var(--scene-scale));
  font-weight: 700;
  color: #14141a;
  white-space: nowrap;
}

.how-scene__title-sub {
  font-size: calc(0.56rem * var(--scene-scale));
  color: #6b6b7a;
}

.how-scene__avatar {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}

.how-scene__header .how-scene__avatar {
  width: 29px;
  height: 29px;
}

.how-scene__avatar--bot {
  background: #fff;
  box-shadow: inset 0 0 0 1px rgba(20, 20, 40, 0.08);
}

.how-scene__avatar--bot img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.how-scene__avatar--group {
  font-size: calc(0.8rem * var(--scene-scale));
  background: linear-gradient(150deg, #7bb6f0, #4b8fe0);
}

.how-scene__avatar--a {
  background: linear-gradient(150deg, #4fb583, #1f6b47);
  color: #fff;
  font-size: calc(0.6rem * var(--scene-scale));
  font-weight: 700;
}

.how-scene__avatar--b {
  background: linear-gradient(150deg, var(--gold), var(--clay));
  color: #fff;
  font-size: calc(0.6rem * var(--scene-scale));
  font-weight: 700;
}

/* Newest message sits at the bottom, as in a chat scrolled to the end —
   anything taller than the screen is clipped at the top rather than squashed. */
.how-scene__body {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: 0.34rem;
  padding: 0.5rem 0.5rem 0.42rem;
  overflow: hidden;
  position: relative;
  z-index: 1;
}

.how-scene__msg {
  display: flex;
}

/* The margin an incoming bubble stops short of, held by the row so the bubble
   can use the whole width left beside the avatar. */
.how-scene__msg--in {
  padding-right: 0.5rem;
}

/* A chat taller than the screen scrolls off the top, it doesn't compress. */
.how-scene__body > * {
  flex-shrink: 0;
}

/* Messages that grow in are clipped while collapsed; the tail sits inside the
   row (past the avatar), so it survives the overflow. */
.how-scene--done .how-scene__msg {
  overflow: hidden;
}

/* Telegram's centred service pill — "X added Y", date separators. */
.how-scene__service {
  align-self: center;
  max-width: 90%;
  text-align: center;
  font-size: calc(0.55rem * var(--scene-scale));
  font-weight: 600;
  color: #fff;
  background: rgba(18, 22, 38, 0.34);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  border-radius: 999px;
  padding: 0.2rem 0.55rem;
}

.how-scene__msg--in {
  align-items: flex-end;
  gap: 0.3rem;
}

.how-scene__msg--out {
  justify-content: flex-end;
}

.how-scene__bubble {
  position: relative;
  max-width: 100%;
  background: #fff;
  color: #14141a;
  font-size: calc(0.68rem * var(--scene-scale));
  line-height: 1.35;
  padding: 0.34rem 0.5rem;
  border-radius: 13px;
  border-bottom-left-radius: 3px;
  box-shadow: 0 1px 3px rgba(20, 20, 40, 0.14);
}

/* Telegram's flick of a tail on the last bubble of a run. */
.how-scene__bubble::after {
  content: "";
  position: absolute;
  bottom: 0;
  left: -5px;
  width: 0;
  height: 0;
  border-style: solid;
  border-width: 0 0 8px 6px;
  border-color: transparent transparent #fff transparent;
}

.how-scene__msg--out .how-scene__bubble {
  background: #e3fec8;
  border-radius: 13px;
  border-bottom-right-radius: 3px;
}

/* PaidBot's confirmation, built like the hero's reply: who sent it, the receipt
   it answers, then exactly what was recorded. */
.how-scene__sender {
  display: flex;
  align-items: baseline;
  gap: 0.4rem;
  font-size: calc(0.62rem * var(--scene-scale));
  font-weight: 700;
  color: #2f7fd0;
  margin-bottom: 0.14rem;
}

.how-scene__sender em {
  font-style: normal;
  font-size: calc(0.48rem * var(--scene-scale));
  font-weight: 500;
  color: #8e8e9c;
}

.how-scene__quote {
  display: flex;
  align-items: center;
  gap: 0.28rem;
  border-left: 2px solid #2f7fd0;
  border-radius: 3px;
  background: rgba(47, 127, 208, 0.08);
  padding: 0.16rem 0.32rem;
  margin-bottom: 0.22rem;
}

.how-scene__quote-thumb {
  container-type: inline-size;
  position: relative;
  flex-shrink: 0;
  width: 17px;
  height: 17px;
  border-radius: 3px;
  overflow: hidden;
  background: #fff;
}

.how-scene__quote-body {
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 0;
}

.how-scene__quote-name {
  font-size: calc(0.54rem * var(--scene-scale));
  font-weight: 700;
  color: #2f7fd0;
}

.how-scene__quote-text {
  font-size: calc(0.54rem * var(--scene-scale));
  color: #6b6b7a;
}

.how-scene__bubble p {
  margin: 0;
  font-size: calc(0.64rem * var(--scene-scale));
  line-height: 1.32;
}

.how-scene__bubble p + p {
  margin-top: 0.18rem;
}

.how-scene__tick {
  margin-right: 0.25em;
}

.how-scene__bubble-last {
  display: flex;
  align-items: baseline;
  gap: 0.45rem;
}

.how-scene__time-inline {
  font-size: calc(0.48rem * var(--scene-scale));
  color: #9a9aa8;
  flex-shrink: 0;
}

.how-scene__msg--out .how-scene__bubble::after {
  left: auto;
  right: -5px;
  border-width: 0 6px 8px 0;
  border-color: transparent transparent #e3fec8 transparent;
}

/* Same collapse trick as the hero demo: max-height carries the exit so the
   messages below don't inherit a dead gap once this disappears mid-cycle. */
.how-scene__typing {
  align-self: flex-start;
  display: flex;
  align-items: center;
  gap: 4px;
  overflow: hidden;
  padding: 0.36rem 0.55rem;
  background: #fff;
  border-radius: 13px;
  border-bottom-left-radius: 3px;
  box-shadow: 0 1px 3px rgba(20, 20, 40, 0.14);
}

.how-scene__typing span {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: #a0a0ad;
  animation: dot-bounce 0.9s ease-in-out infinite;
}

.how-scene__typing span:nth-child(2) { animation-delay: 0.15s; }
.how-scene__typing span:nth-child(3) { animation-delay: 0.3s; }

/* In the group, the bubble clears the sender avatar column; the setup DM has
   no avatars, so it stays flush. */
.how-scene--done .how-scene__typing {
  margin-left: 26px;
}

/* --- Setup scene: the private-chat wizard ---------------------------------
   Telegram's newer iOS look, which is what the bot actually renders: no
   bubble tails, a sender capsule above the message, and inline keyboards as
   separate full-width buttons rather than a hairline-split table. */
.how-scene--setup {
  --setup-key-bg: rgba(116, 110, 206, 0.72);
  --setup-key-fg: #fff;
  --setup-pill-bg: rgba(255, 255, 255, 0.94);
  --setup-pill-fg: #14141a;
}

/* The scene plays two chats: the group hands off to the private chat, so both
   panes stack in the same body and cross-slide the way Telegram pushes. */
.how-scene--setup .how-scene__body {
  padding: 0;
  gap: 0;
}

.how-setup-pane {
  position: absolute;
  inset: 0;
  will-change: transform, opacity;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: 0.3rem;
  padding: 0.5rem 0.5rem 0.42rem;
  overflow: hidden;
}

/* Once the conversation is taller than the screen the oldest messages scroll
   off the top, the way a chat does — without this the whole stack squeezes. */
.how-setup-pane > * {
  flex-shrink: 0;
}

/* The two chat titles swap in place with their panes. */
.how-scene__header-stack {
  position: relative;
}

.how-scene__header-stack .how-scene__header + .how-scene__header {
  position: absolute;
  inset: 0;
}

/* Everything in this scene collapses on exit, so the chat grows off the
   composer instead of sitting in reserved space. */
.how-scene--setup .how-scene__msg,
.how-scene__sender-pill,
.how-setup-state {
  overflow: hidden;
}

/* Group messages keep the tail the other two scenes draw; the wizard's
   full-width cards in the private chat have none. */
.how-setup-pane--dm .how-scene__bubble::after {
  display: none;
}

/* A group message is indented past the sender's avatar, and its keyboard
   lines up with the bubble rather than the screen. */
.how-setup-pane--group .how-scene__keyboard {
  width: calc(100% - 22px - 0.3rem - 0.5rem);
  margin-left: calc(22px + 0.3rem);
}

/* The bot's name capsule that sits above each of its messages. */
.how-scene__sender-pill {
  align-self: flex-start;
  display: inline-flex;
  align-items: baseline;
  gap: 0.24rem;
  margin-bottom: -0.16rem;
  padding: 0.16rem 0.44rem;
  border-radius: 999px;
  background: var(--setup-pill-bg);
  color: var(--setup-pill-fg);
  font-size: calc(0.56rem * var(--scene-scale));
  box-shadow: 0 1px 3px rgba(20, 20, 40, 0.14);
}

.how-scene__sender-pill b {
  font-weight: 700;
}

.how-scene__sender-pill em {
  font-style: normal;
  font-size: calc(0.46rem * var(--scene-scale));
  color: #9a9aa8;
}

/* The wizard is one message Telegram edits in place, so its states share a
   slot and only one is ever on screen. */
.how-setup-state {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 3px;
}

.how-setup-state .how-scene__bubble {
  max-width: calc(100% - 0.5rem);
  border-radius: 13px;
}

.how-scene__keyboard {
  width: calc(100% - 0.5rem);
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 3px;
}

.how-scene__key {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.24rem;
  min-height: 25px;
  padding: 0.24rem 0.3rem;
  border-radius: 9px;
  background: var(--setup-key-bg, rgba(116, 110, 206, 0.72));
  color: var(--setup-key-fg, #fff);
  font-size: calc(0.58rem * var(--scene-scale));
  font-weight: 600;
  text-align: center;
}

.how-scene__key--wide {
  grid-column: 1 / -1;
}

.how-scene__key--link {
  position: relative;
}

.how-scene__key--link::after {
  content: "↗";
  position: absolute;
  top: 1px;
  right: 4px;
  font-size: calc(0.5rem * var(--scene-scale));
  opacity: 0.75;
}

/* Telegram's blank line between the step label and the question reads as a
   full line, not a paragraph gap. */
.how-scene--setup .how-scene__bubble p + p {
  margin-top: 0.42rem;
}

/* The trailing timestamp rides the last line of a wrapped message. */
.how-scene--setup .how-scene__bubble-last {
  align-items: flex-end;
}

/* The bot's persistent reply keyboard, parked under the composer. */
.how-scene__reply-keyboard {
  flex-shrink: 0;
  padding: 0 0.42rem 0.3rem;
  background: rgba(247, 247, 250, 0.94);
}

.how-scene__reply-key {
  display: block;
  border-radius: 9px;
  padding: 0.3rem;
  background: var(--setup-key-bg, rgba(116, 110, 206, 0.72));
  color: var(--setup-key-fg, #fff);
  font-size: calc(0.58rem * var(--scene-scale));
  font-weight: 600;
  text-align: center;
}

.how-scene__photo-card {
  position: relative;
  display: flex;
  flex-direction: column;
  background: #fff;
  border-radius: 13px;
  border-bottom-left-radius: 3px;
  box-shadow: 0 1px 3px rgba(20, 20, 40, 0.16);
}

/* Same tall, narrow shape as the hero's posted receipt — a real payment
   screenshot, not a square card. */
.how-scene__photo {
  position: relative;
  container-type: inline-size;
  width: 104px;
  aspect-ratio: 5 / 8;
  border-radius: 13px;
  border-bottom-left-radius: 3px;
  overflow: hidden;
  background: #fff;
}

/* Step 3 shows the same receipts at the same size as step 2; the chat simply
   runs past the top of the screen. The reaction owns the card's bottom-right
   corner there, so the time chip gives way to it. */
.how-scene--done .how-scene__photo-time {
  display: none;
}

/* Where the bank's own screenshot carries it — and step 3, the only scene
   with a reaction on that corner, hides the chip entirely. */
.how-scene__photo-time {
  position: absolute;
  right: 5px;
  bottom: 5px;
  font-size: calc(0.5rem * var(--scene-scale));
  font-weight: 500;
  color: #fff;
  background: rgba(0, 0, 0, 0.42);
  border-radius: 999px;
  padding: 0.04rem 0.3rem;
}

/* Telegram shows a single reactor's avatar in place of a count. */
/* Telegram floats a reaction over the bottom-right of the media, inside the
   message — which also keeps it clear of the row's clipping. */
.how-scene__reaction {
  position: absolute;
  right: 6px;
  bottom: 6px;
  display: flex;
  align-items: center;
  gap: 3px;
  background: #fff;
  border-radius: 999px;
  padding: 0.13rem 0.24rem 0.13rem 0.34rem;
  box-shadow: 0 2px 6px rgba(20, 20, 40, 0.22);
}

.how-scene__reaction-emoji {
  font-size: calc(0.58rem * var(--scene-scale));
  line-height: 1;
}

.how-scene__reaction-avatar {
  width: 11px;
  height: 11px;
  border-radius: 50%;
  object-fit: cover;
  display: block;
}

.how-scene__inputbar {
  flex-shrink: 0;
  position: relative;
  z-index: 4;
  display: flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.34rem 0.5rem 0.28rem;
  background: rgba(247, 247, 250, 0.94);
  backdrop-filter: blur(18px);
  -webkit-backdrop-filter: blur(18px);
  box-shadow: 0 -0.5px 0 rgba(20, 20, 40, 0.14);
  color: #8b8b98;
}

.how-scene__input {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.4rem;
  padding: 0.26rem 0.45rem;
  background: #fff;
  border-radius: 999px;
  box-shadow: inset 0 0 0 1px rgba(20, 20, 40, 0.12);
  font-size: calc(0.62rem * var(--scene-scale));
  color: #a3a3b0;
}

.how-scene__home {
  flex-shrink: 0;
  height: 18px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(247, 247, 250, 0.94);
}

.how-scene__home::after {
  content: "";
  width: 36%;
  height: 4px;
  border-radius: 999px;
  background: #14141a;
  opacity: 0.82;
}

/* Scene 1 — the bot lands in the group and posts its welcome; "Set up PaidBot
   (private)" pushes to the private chat, where the wizard runs through steps
   1-4 and the summary is confirmed; the group then slides back with the
   activation announcement. Runs once per activation, over 24s.

   At rest — before the step is reached, on an inactive step in the mobile
   stack, or with motion turned down — the scene holds that ending: the group,
   set up. Every rule below is the resting state; the keyframes play the story
   on top of it and land back on exactly these values. */
.how-setup-pane--dm {
  opacity: 0;
  transform: translateX(20%);
}

.how-setup-head-dm {
  opacity: 0;
}

.how-setup-typing,
.how-setup-replykey {
  opacity: 0;
  max-height: 0;
  padding-top: 0;
  padding-bottom: 0;
}

@keyframes how-setup-added {
  0% { opacity: 0; transform: translateY(6px); }
  1.44% { opacity: 1; transform: translateY(0); }
}

@keyframes how-setup-typing {
  0%, 2% { opacity: 0; max-height: 0; padding-top: 0; padding-bottom: 0; transform: translateY(6px); }
  3.36% { opacity: 1; max-height: calc(20px * var(--scene-scale)); padding-top: 0.36rem; padding-bottom: 0.36rem; transform: translateY(0); }
  5.36% { opacity: 1; max-height: calc(20px * var(--scene-scale)); padding-top: 0.36rem; padding-bottom: 0.36rem; }
  6.32%, 100% { opacity: 0; max-height: 0; padding-top: 0; padding-bottom: 0; }
}

@keyframes how-setup-hello {
  0%, 6.32% { opacity: 0; max-height: 0; transform: translateY(8px); }
  7.68% { opacity: 1; max-height: calc(84px * var(--scene-scale)); transform: translateY(0); }
}

@keyframes how-setup-hello-kb {
  0%, 7.04% { opacity: 0; max-height: 0; transform: translateY(6px); }
  8.32% { opacity: 1; max-height: calc(60px * var(--scene-scale)); transform: translateY(0); }
}

/* Telegram dims the button it is opening. */
@keyframes how-setup-tap-setup {
  0%, 11% { background: var(--setup-key-bg); }
  11.68%, 12.64% { background: #4f46b8; }
  13.36%, 100% { background: var(--setup-key-bg); }
}

/* The push into the private chat, and the pop back out of it once setup is
   confirmed. */
@keyframes how-setup-pane-group {
  0%, 13.36% { opacity: 1; transform: translateX(0); }
  15.36%, 67.68% { opacity: 0; transform: translateX(-16%); }
  69.68%, 100% { opacity: 1; transform: translateX(0); }
}

@keyframes how-setup-pane-dm {
  0%, 13.36% { opacity: 0; transform: translateX(20%); }
  15.68%, 67.68% { opacity: 1; transform: translateX(0); }
  69.68%, 100% { opacity: 0; transform: translateX(20%); }
}

@keyframes how-setup-head-group {
  0%, 13.36% { opacity: 1; }
  15.04%, 68% { opacity: 0; }
  70%, 100% { opacity: 1; }
}

@keyframes how-setup-head-dm {
  0%, 14% { opacity: 0; }
  15.68%, 67.68% { opacity: 1; }
  69.36%, 100% { opacity: 0; }
}

@keyframes how-setup-replykey {
  0%, 14% { opacity: 0; max-height: 0; padding-bottom: 0; }
  15.68%, 67.68% { opacity: 1; max-height: calc(38px * var(--scene-scale)); padding-bottom: 0.3rem; }
  69.36%, 100% { opacity: 0; max-height: 0; padding-bottom: 0; }
}

@keyframes how-setup-pill-a {
  0%, 16.32% { opacity: 0; max-height: 0; padding-top: 0; padding-bottom: 0; transform: translateY(6px); }
  17.68% { opacity: 1; max-height: calc(21px * var(--scene-scale)); padding-top: 0.16rem; padding-bottom: 0.16rem; transform: translateY(0); }
}

@keyframes how-setup-s1 {
  0%, 17% { opacity: 0; max-height: 0; }
  18.4% { opacity: 1; max-height: calc(175px * var(--scene-scale)); }
  24% { opacity: 1; max-height: calc(175px * var(--scene-scale)); }
  25.36%, 100% { opacity: 0; max-height: 0; }
}

@keyframes how-setup-tap1 {
  0%, 21.68% { background: var(--setup-key-bg); }
  22.32%, 23.36% { background: #4f46b8; }
  24.32%, 100% { background: var(--setup-key-bg); }
}

@keyframes how-setup-s2 {
  0%, 24.32% { opacity: 0; max-height: 0; }
  25.68% { opacity: 1; max-height: calc(145px * var(--scene-scale)); }
  31.68% { opacity: 1; max-height: calc(145px * var(--scene-scale)); }
  33.04%, 100% { opacity: 0; max-height: 0; }
}

@keyframes how-setup-tap2 {
  0%, 29.36% { background: var(--setup-key-bg); }
  30%, 31% { background: #4f46b8; }
  32%, 100% { background: var(--setup-key-bg); }
}

@keyframes how-setup-s3 {
  0%, 32% { opacity: 0; max-height: 0; }
  33.36% { opacity: 1; max-height: calc(98px * var(--scene-scale)); }
}

@keyframes how-setup-account {
  0%, 37.68% { opacity: 0; max-height: 0; transform: translateY(8px); }
  39.04% { opacity: 1; max-height: calc(30px * var(--scene-scale)); transform: translateY(0); }
}

@keyframes how-setup-pill-b {
  0%, 40.32% { opacity: 0; max-height: 0; padding-top: 0; padding-bottom: 0; transform: translateY(6px); }
  41.68% { opacity: 1; max-height: calc(21px * var(--scene-scale)); padding-top: 0.16rem; padding-bottom: 0.16rem; transform: translateY(0); }
}

@keyframes how-setup-s3b {
  0%, 41% { opacity: 0; max-height: 0; }
  42.4% { opacity: 1; max-height: calc(98px * var(--scene-scale)); }
}

@keyframes how-setup-holder {
  0%, 46.64% { opacity: 0; max-height: 0; transform: translateY(8px); }
  48% { opacity: 1; max-height: calc(30px * var(--scene-scale)); transform: translateY(0); }
}

@keyframes how-setup-pill-c {
  0%, 49.36% { opacity: 0; max-height: 0; padding-top: 0; padding-bottom: 0; transform: translateY(6px); }
  50.64% { opacity: 1; max-height: calc(21px * var(--scene-scale)); padding-top: 0.16rem; padding-bottom: 0.16rem; transform: translateY(0); }
}

@keyframes how-setup-review {
  0%, 50% { opacity: 0; max-height: 0; }
  51.68% { opacity: 1; max-height: calc(180px * var(--scene-scale)); }
  58.32% { opacity: 1; max-height: calc(180px * var(--scene-scale)); }
  59.68%, 100% { opacity: 0; max-height: 0; }
}

@keyframes how-setup-tap-confirm {
  0%, 56% { background: var(--setup-key-bg); }
  56.64%, 57.68% { background: #4f46b8; }
  58.64%, 100% { background: var(--setup-key-bg); }
}

@keyframes how-setup-done {
  0%, 59% { opacity: 0; max-height: 0; transform: translateY(8px); }
  61.36% { opacity: 1; max-height: calc(190px * var(--scene-scale)); transform: translateY(0); }
}

/* Posted into the group while the admin is still in the private chat, so it is
   already waiting when the group slides back. */
@keyframes how-setup-live {
  0%, 67.68% { opacity: 0; max-height: 0; transform: translateY(8px); }
  69.68% { opacity: 1; max-height: calc(112px * var(--scene-scale)); transform: translateY(0); }
}

@keyframes how-setup-live-kb {
  0%, 68.32% { opacity: 0; max-height: 0; transform: translateY(6px); }
  70.4% { opacity: 1; max-height: calc(29px * var(--scene-scale)); transform: translateY(0); }
}

/* Gated on .is-playing, which the observer adds the moment a step becomes the
   one being read and rewinds on the way back — so the story always opens on its
   first frame instead of part-way through a run nobody watched. */
.is-playing .how-setup-typing { animation: how-setup-typing var(--scene) var(--ease-beat) both; }
.is-playing .how-setup-added { animation: how-setup-added var(--scene) var(--ease-beat) both; }
.is-playing .how-setup-hello { animation: how-setup-hello var(--scene) var(--ease-beat) both; }
.is-playing .how-setup-hello-kb { animation: how-setup-hello-kb var(--scene) var(--ease-beat) both; }
.is-playing .how-setup-replykey { animation: how-setup-replykey var(--scene) var(--ease-beat) both; }
.is-playing .how-setup-pill-a { animation: how-setup-pill-a var(--scene) var(--ease-beat) both; }
.is-playing .how-setup-s1 { animation: how-setup-s1 var(--scene) var(--ease-beat) both; }
.is-playing .how-setup-s2 { animation: how-setup-s2 var(--scene) var(--ease-beat) both; }
.is-playing .how-setup-s3 { animation: how-setup-s3 var(--scene) var(--ease-beat) both; }
.is-playing .how-setup-account { animation: how-setup-account var(--scene) var(--ease-beat) both; }
.is-playing .how-setup-pill-b { animation: how-setup-pill-b var(--scene) var(--ease-beat) both; }
.is-playing .how-setup-s3b { animation: how-setup-s3b var(--scene) var(--ease-beat) both; }
.is-playing .how-setup-holder { animation: how-setup-holder var(--scene) var(--ease-beat) both; }
.is-playing .how-setup-pill-c { animation: how-setup-pill-c var(--scene) var(--ease-beat) both; }
.is-playing .how-setup-review { animation: how-setup-review var(--scene) var(--ease-beat) both; }
.is-playing .how-setup-done { animation: how-setup-done var(--scene) var(--ease-beat) both; }
.is-playing .how-setup-live { animation: how-setup-live var(--scene) var(--ease-beat) both; }
.is-playing .how-setup-live-kb { animation: how-setup-live-kb var(--scene) var(--ease-beat) both; }
.is-playing .how-setup-tap-setup { animation: how-setup-tap-setup var(--scene) steps(1, end) both; }
.is-playing .how-setup-tap1 { animation: how-setup-tap1 var(--scene) steps(1, end) both; }
.is-playing .how-setup-tap2 { animation: how-setup-tap2 var(--scene) steps(1, end) both; }
.is-playing .how-setup-tap-confirm { animation: how-setup-tap-confirm var(--scene) steps(1, end) both; }
.is-playing .how-setup-pane--group { animation: how-setup-pane-group var(--scene) var(--ease-pane) both; }
.is-playing .how-setup-pane--dm { animation: how-setup-pane-dm var(--scene) var(--ease-pane) both; }
.is-playing .how-setup-head-group { animation: how-setup-head-group var(--scene) ease both; }
.is-playing .how-setup-head-dm { animation: how-setup-head-dm var(--scene) ease both; }

/* Scenes 2 and 3 play once on arrival and hold their ending, the way scene 1
   does. A loop would have to reset every element at once, and that snap is the
   one moment in the sequence a reader always notices. */
.how--scenes .how-pay-msg1 {
  opacity: 0;
}

.how--scenes .how-pay-msg2 {
  opacity: 0;
  max-height: 0;
  margin-top: -0.34rem;
  overflow: hidden;
}

/* Scene 2 — one receipt lands, then the second pushes it up the chat. 3s. */
@keyframes how-pay-msg1 {
  0%, 4% { opacity: 0; transform: translateY(10px); }
  22%, 100% { opacity: 1; transform: translateY(0); }
}

@keyframes how-pay-msg2 {
  0%, 46% { opacity: 0; max-height: 0; margin-top: -0.34rem; transform: translateY(10px); }
  64%, 100% { opacity: 1; max-height: calc(186px * var(--scene-scale)); margin-top: 0; transform: translateY(0); }
}

.is-playing .how-pay-msg1 { animation: how-pay-msg1 var(--scene) var(--ease-beat) both; }
.is-playing .how-pay-msg2 { animation: how-pay-msg2 var(--scene) var(--ease-beat) both; }

/* Scene 3 — opens on step 2's closing frame, both receipts already posted, and
   works through them in order: react, reply, react, reply. Only the reactions
   and the replies animate; the photos are simply already there. 6.5s. */
.how--scenes .how-done-reaction-1,
.how--scenes .how-done-reaction-2 {
  opacity: 0;
}

.how--scenes .how-done-typing-1,
.how--scenes .how-done-typing-2 {
  opacity: 0;
  max-height: 0;
  margin-top: -0.34rem;
  padding-top: 0;
  padding-bottom: 0;
}

.how--scenes .how-done-reply-1,
.how--scenes .how-done-reply-2 {
  opacity: 0;
  max-height: 0;
  margin-top: -0.34rem;
  overflow: hidden;
}

@keyframes how-done-reaction-1 {
  0%, 3% { opacity: 0; transform: scale(0.5); }
  10%, 100% { opacity: 1; transform: scale(1); }
}

@keyframes how-done-typing-1 {
  0%, 14% { opacity: 0; max-height: 0; margin-top: -0.34rem; padding-top: 0; padding-bottom: 0; transform: translateY(6px); }
  20% { opacity: 1; max-height: calc(20px * var(--scene-scale)); margin-top: 0; padding-top: 0.38rem; padding-bottom: 0.38rem; transform: translateY(0); }
  30% { opacity: 1; max-height: calc(20px * var(--scene-scale)); margin-top: 0; padding-top: 0.38rem; padding-bottom: 0.38rem; }
  35%, 100% { opacity: 0; max-height: 0; margin-top: -0.34rem; padding-top: 0; padding-bottom: 0; }
}

@keyframes how-done-reply-1 {
  0%, 32% { opacity: 0; max-height: 0; margin-top: -0.34rem; transform: translateY(8px); }
  42%, 100% { opacity: 1; max-height: calc(115px * var(--scene-scale)); margin-top: 0; transform: translateY(0); }
}

@keyframes how-done-reaction-2 {
  0%, 48% { opacity: 0; transform: scale(0.5); }
  55%, 100% { opacity: 1; transform: scale(1); }
}

@keyframes how-done-typing-2 {
  0%, 59% { opacity: 0; max-height: 0; margin-top: -0.34rem; padding-top: 0; padding-bottom: 0; transform: translateY(6px); }
  65% { opacity: 1; max-height: calc(20px * var(--scene-scale)); margin-top: 0; padding-top: 0.38rem; padding-bottom: 0.38rem; transform: translateY(0); }
  75% { opacity: 1; max-height: calc(20px * var(--scene-scale)); margin-top: 0; padding-top: 0.38rem; padding-bottom: 0.38rem; }
  80%, 100% { opacity: 0; max-height: 0; margin-top: -0.34rem; padding-top: 0; padding-bottom: 0; }
}

@keyframes how-done-reply-2 {
  0%, 77% { opacity: 0; max-height: 0; margin-top: -0.34rem; transform: translateY(8px); }
  87%, 100% { opacity: 1; max-height: calc(115px * var(--scene-scale)); margin-top: 0; transform: translateY(0); }
}

.is-playing .how-done-reaction-1 { animation: how-done-reaction-1 var(--scene) var(--ease-pop) both; }
.is-playing .how-done-typing-1 { animation: how-done-typing-1 var(--scene) var(--ease-beat) both; }
.is-playing .how-done-reply-1 { animation: how-done-reply-1 var(--scene) var(--ease-beat) both; }
.is-playing .how-done-reaction-2 { animation: how-done-reaction-2 var(--scene) var(--ease-pop) both; }
.is-playing .how-done-typing-2 { animation: how-done-typing-2 var(--scene) var(--ease-beat) both; }
.is-playing .how-done-reply-2 { animation: how-done-reply-2 var(--scene) var(--ease-beat) both; }

/* Phones: the scene stops pretending to be a phone.
   A drawn handset inside a real one costs a third of the width to bezel and
   renders the conversation at ~9px — the one place on the page that has to be
   read closely is the hardest to read. Here the frame becomes a plain chat
   card the width of the column, the device chrome nobody needs on a phone
   (status bar, home bar, side buttons, island) goes, and the freed width is
   spent retyping the conversation at --scene-scale. Desktop keeps the handset:
   .step-visual is display:none from 900px, so none of this reaches it. */
@media (max-width: 899px) {
  .step-visual {
    --scene-scale: 1.42;
  }

  /* Fills a phone column; capped so a tablet gets a chat card rather than a
     squat, over-wide one. */
  .step-visual .how-device {
    max-width: 420px;
    aspect-ratio: auto;
    padding: 0;
    border-radius: 22px;
    background: none;
    box-shadow: 0 14px 34px rgba(16, 36, 28, 0.16), 0 3px 10px rgba(16, 36, 28, 0.08);
  }

  .step-visual .how-device__btn,
  .step-visual .how-device__island,
  .step-visual .how-scene__statusbar,
  .step-visual .how-scene__home {
    display: none;
  }

  /* Fixed so the card doesn't resize under the reader while the scene plays,
     and so the chat runs off the top the way a real one does. */
  .step-visual .how-device__screen {
    height: 490px;
    border-radius: 22px;
  }

  .how-step[data-step="1"] .how-device__screen {
    height: 435px;
  }

  /* Spacing is in rem, so it does not follow --scene-scale on its own; these are
     the places where leaving it behind would show. */
  .step-visual .how-scene__header {
    gap: 0.5rem;
    padding: 0.5rem 0.7rem 0.6rem;
  }

  .step-visual .how-scene__avatar {
    width: 31px;
    height: 31px;
  }

  .step-visual .how-scene__header .how-scene__avatar {
    width: 38px;
    height: 38px;
  }

  .step-visual .how-scene__body {
    gap: 0.48rem;
    padding: 0.7rem 0.7rem 0.6rem;
  }

  .step-visual .how-scene__service {
    padding: 0.28rem 0.78rem;
  }

  .step-visual .how-scene__bubble {
    padding: 0.48rem 0.7rem;
    border-radius: 18px;
    border-bottom-left-radius: 4px;
  }

  .step-visual .how-scene__msg--out .how-scene__bubble {
    border-radius: 18px;
    border-bottom-right-radius: 4px;
  }

  .step-visual .how-scene__bubble::after {
    left: -7px;
    border-width: 0 0 11px 8px;
  }

  .step-visual .how-scene__msg--out .how-scene__bubble::after {
    right: -7px;
    border-width: 0 8px 11px 0;
  }

  .step-visual .how-scene__quote {
    padding: 0.23rem 0.45rem;
  }

  .step-visual .how-scene__quote-thumb {
    width: 24px;
    height: 24px;
  }

  .step-visual .how-scene__photo {
    width: 140px;
    border-radius: 18px;
  }

  .step-visual .how-scene__reaction-avatar {
    width: 15px;
    height: 15px;
  }

  .step-visual .how-scene__typing {
    padding: 0.5rem 0.78rem;
    border-radius: 18px;
  }

  .step-visual .how-scene__typing span {
    width: 7px;
    height: 7px;
  }

  .step-visual .how-scene__inputbar {
    gap: 0.55rem;
    padding: 0.48rem 0.7rem 0.42rem;
  }

  .step-visual .how-scene__input {
    padding: 0.37rem 0.64rem;
  }
}

/* Comparison — the claim is latency, and the cards argue it by shape: the old
   way stays small, flat and muted; PaidBot's card is larger, lit and raised. */
.compare {
  background: var(--paper);
}

.compare__grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1rem;
  max-width: 940px;
  margin-inline: auto;
  align-items: center;
}

.compare__card {
  border-radius: var(--radius-lg);
  padding: 1.5rem;
}

.compare__label {
  display: block;
  font-family: var(--font-utility);
  font-size: 0.62rem;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  margin-bottom: 0.6rem;
}

.compare__stat {
  font-family: var(--font-display);
  font-weight: 700;
  font-variation-settings: "wdth" 112;
  letter-spacing: -0.02em;
  line-height: 1.1;
  margin-bottom: 1.25rem;
}

.compare__list {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 0.7rem;
  line-height: 1.45;
}

.compare__list li {
  display: flex;
  gap: 0.6rem;
}

.compare__list li::before {
  flex-shrink: 0;
  font-weight: 700;
}

.compare__card--before {
  background: var(--paper-dim);
  border: 1px solid var(--border);
  color: var(--text-muted);
}

.compare__card--before .compare__label {
  color: var(--clay);
}

.compare__card--before .compare__stat {
  font-size: 1.15rem;
  color: var(--text-muted);
}

.compare__card--before .compare__list {
  font-size: 0.9rem;
}

.compare__card--before .compare__list li::before {
  content: "\00d7";
  color: var(--clay);
}

.compare__card--after {
  background: var(--ink);
  color: var(--paper);
  box-shadow: var(--shadow-lg);
  /* Glow only: the ledger rules read as stripes at card size. */
  background-image: radial-gradient(ellipse 420px 260px at 50% 0%, rgba(224, 163, 46, 0.2), transparent 70%);
}

.compare__card--after .compare__label {
  color: var(--gold);
}

.compare__card--after .compare__stat {
  font-size: clamp(2rem, 6vw, 3rem);
  color: var(--gold);
}

.compare__card--after .compare__list {
  font-size: 1rem;
  color: var(--text-on-ink-muted);
}

.compare__card--after .compare__list li::before {
  content: "\2713";
  color: var(--gold);
}

@media (min-width: 768px) {
  /* Deliberately uneven: the old way gets the narrow column. */
  .compare__grid {
    grid-template-columns: 0.78fr 1.22fr;
    gap: 1.75rem;
  }

  .compare__card--before {
    padding: 1.5rem 1.35rem;
  }

  .compare__card--after {
    padding: 2.1rem 1.9rem;
  }
}

/* Bank strip — the fastest answer to "will it work with what my members use".
   Names are set as text, so no bank's trademark artwork is reproduced. */
.banks {
  background-color: #0c1a14;
  color: var(--paper);
  padding: 2.75rem 0 3.25rem;
  border-top: 1px solid var(--border-on-ink);
  text-align: center;
}

.banks__label {
  font-family: var(--font-utility);
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--text-on-ink-muted);
  margin-bottom: 1.5rem;
}

.banks__list {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.85rem 2.25rem;
  margin-bottom: 1.5rem;
}

.banks__list li {
  font-family: var(--font-display);
  font-size: clamp(1.05rem, 2.6vw, 1.35rem);
  font-weight: 700;
  font-variation-settings: "wdth" 108;
  letter-spacing: -0.01em;
  color: var(--paper);
  opacity: 0.82;
}

.banks__note {
  font-size: 0.85rem;
  color: var(--text-on-ink-muted);
  max-width: 34rem;
  margin-inline: auto;
}

/* The collection-account requirement gets its own line rather than trailing the
   verification note — a treasurer who reads nothing else should catch this. */
.banks__requirement {
  margin-top: 0.85rem;
  font-size: 0.9rem;
  color: var(--paper);
}

/* Trust band — the objection that stops a treasurer, given its own scene. */
.trust__inner {
  display: grid;
  grid-template-columns: 1fr;
  gap: 2rem;
}

.trust__lede .section-header,
.trust__lede {
  text-align: center;
}

.trust__lede .section-title {
  margin-bottom: 0;
}

.trust__points {
  list-style: none;
  display: grid;
  gap: 1.6rem;
}

.trust__points h3 {
  font-size: 1.05rem;
  margin-bottom: 0.35rem;
  color: var(--paper);
}

.trust__points p {
  font-size: 0.95rem;
  line-height: 1.6;
  color: var(--text-on-ink-muted);
  max-width: 46ch;
}

@media (min-width: 900px) {
  .trust__inner {
    grid-template-columns: 0.9fr 1.1fr;
    gap: 3.5rem;
    align-items: start;
  }

  .trust__lede,
  .trust__lede .section-header {
    text-align: left;
  }
}

/* Features grid */
.features-grid {
  background: var(--paper);
  scroll-margin-top: 96px;
}

/* Feature rows — the three features that are quicker to show than to describe.
   Each demo is drawn in CSS: no screenshots, no new assets. */
.feature-rows {
  display: flex;
  flex-direction: column;
  gap: 1.75rem;
  margin-bottom: 1.9rem;
}

.feature-row {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1.25rem;
  align-items: center;
}

.feature-row__demo {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
  background: var(--paper-dim);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
}

.feature-row__copy h3 {
  font-size: 1.15rem;
  margin-bottom: 0.45rem;
}

.feature-row__copy p {
  color: var(--text-muted);
  font-size: 0.92rem;
  line-height: 1.55;
}

/* Same reading order as the steps below 900px: the feature is named first and
   its drawn demo sits under it, so a demo is never mistaken for the next
   feature's illustration. */
@media (max-width: 899px) {
  .feature-rows {
    gap: 2.5rem;
  }

  .feature-row {
    gap: 0.9rem;
  }

  .feature-row__copy { order: 1; }
  .feature-row__demo { order: 2; }
}

@media (min-width: 900px) {
  .feature-rows {
    gap: 3rem;
    margin-bottom: 3.25rem;
  }

  .feature-row {
    grid-template-columns: 1fr 1fr;
    gap: 3.25rem;
  }

  /* Alternate which side the demo sits on. */
  .feature-row:nth-child(even) .feature-row__demo {
    order: 2;
  }

  .feature-row__demo {
    padding: 1.75rem;
    min-height: 230px;
  }

  .feature-row__copy h3 {
    font-size: 1.25rem;
  }
}

/* Demo: the receipt's own numbers set against the bank's record of the same
   transaction — the match *is* the verification, so both sides are drawn. */
.verify {
  width: 100%;
  max-width: 300px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0;
}

.verify__card {
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
  padding: 0.85rem 1rem;
  background: #fff;
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
}

.verify__card--bank {
  background: var(--ink);
  color: var(--paper);
  box-shadow: var(--shadow-md);
}

.verify__label {
  font-family: var(--font-utility);
  font-size: 0.55rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-muted);
}

.verify__label--bank {
  color: var(--gold);
}

.verify__line {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  font-size: 0.82rem;
}

.verify__line em {
  font-style: normal;
  color: var(--text-muted);
}

.verify__card--bank .verify__line em {
  color: var(--text-on-ink-muted);
}

.verify__line b {
  font-weight: 600;
  letter-spacing: -0.01em;
}

/* The seam between the two cards: a hairline the check sits on, so the eye
   reads "these two agree" rather than "here are two boxes". */
.verify__link {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 1.85rem;
}

.verify__link::before {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  width: 2px;
  background: var(--border);
}

.verify__link-badge {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.5rem;
  height: 1.5rem;
  border-radius: 50%;
  background: var(--gold);
  color: var(--ink);
  box-shadow: 0 0 0 4px var(--paper-dim);
}

.verify__stamp {
  margin-top: 0.85rem;
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.4rem 0.9rem;
  border-radius: 980px;
  border: 1px solid var(--border);
  background: #fff;
  font-family: var(--font-utility);
  font-size: 0.58rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--gold-deep);
}

/* Demo: the admin's unpaid list — the same shape the bot sends: who owes,
   how much, and one total that covers the whole group. */
.roster {
  width: 100%;
  max-width: 320px;
  background: #fff;
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
}

.roster__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 0.7rem 0.9rem;
  border-bottom: 1px solid var(--border);
}

/* The bot heads this list with a red dot; on paper that reads better as a
   mark of its own than as an emoji. */
.roster__title {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-weight: 600;
  font-size: 0.9rem;
}

.roster__title::before {
  content: "";
  width: 0.45rem;
  height: 0.45rem;
  border-radius: 50%;
  background: var(--clay);
}

.roster__count {
  font-family: var(--font-utility);
  font-size: 0.6rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--gold-deep);
}

.roster__list {
  list-style: none;
}

/* Rank, name and amount on the first line; the arrears note tucks under the
   name in the second — the same two-line row the bot's message uses. */
.roster__list li {
  display: grid;
  grid-template-columns: 1.1rem 1fr auto;
  align-items: baseline;
  column-gap: 0.55rem;
  row-gap: 0.15rem;
  padding: 0.55rem 0.9rem;
  font-size: 0.82rem;
}

.roster__list li + li {
  border-top: 1px solid var(--paper-dim);
}

.roster__rank {
  font-family: var(--font-utility);
  font-size: 0.6rem;
  color: var(--text-muted);
}

/* min-width:0 so a long name shrinks inside the grid track instead of pushing
   the amount off the card on a narrow screen. */
.roster__who {
  min-width: 0;
}

.roster__who b {
  font-weight: 600;
}

.roster__amount {
  font-weight: 600;
  white-space: nowrap;
  color: var(--clay);
}

.roster__months {
  grid-column: 2 / -1;
  font-size: 0.68rem;
  color: var(--text-muted);
}

.roster__foot {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 0.7rem 0.9rem;
  border-top: 1px solid var(--border);
  background: var(--paper);
  font-size: 0.8rem;
}

.roster__foot b {
  font-weight: 700;
  font-size: 0.92rem;
}

/* Demo: billing runs on Ethiopian months, and Pagume is never one of them. */
.months {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 0.6rem;
  width: 100%;
  max-width: 320px;
}

.month {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  padding: 0.75rem 0.85rem;
  background: #fff;
  border-radius: 14px;
  box-shadow: var(--shadow-sm);
}

.month__name {
  font-weight: 600;
  font-size: 0.92rem;
}

.month__state {
  font-family: var(--font-utility);
  font-size: 0.58rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-muted);
}

.month__state--paid {
  color: var(--ink-raised);
}

.month__state--due {
  color: var(--gold-deep);
}

.month--skipped {
  background: transparent;
  box-shadow: none;
  border: 1px dashed var(--border);
}

.month--skipped .month__name {
  color: var(--text-muted);
  text-decoration: line-through;
  text-decoration-thickness: 1px;
}

.feature-cards {
  display: grid;
  gap: 1.1rem;
  grid-template-columns: 1fr;
}

.feature-card {
  background: #fff;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1.5rem;
  box-shadow: var(--shadow-sm);
  transition: transform 0.45s ease, box-shadow 0.45s ease;
}

.feature-card:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow-md);
}

.feature-icon {
  width: 42px;
  height: 42px;
  border-radius: 12px;
  background: rgba(224, 163, 46, 0.16);
  color: var(--gold-deep);
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 0.8rem;
}

.feature-icon svg {
  width: 22px;
  height: 22px;
}

.feature-card h3 {
  font-size: 1.02rem;
  margin-bottom: 0.45rem;
}

.feature-card p {
  font-size: 0.88rem;
  color: var(--text-muted);
  line-height: 1.55;
}

@media (min-width: 640px) {
  .feature-cards {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (min-width: 968px) {
  .feature-cards {
    grid-template-columns: repeat(3, 1fr);
  }
}

/* Use cases */
.use-cases {
  background: var(--paper);
}

/* Two audiences, so the grid never widens past two columns — a four-column
   track would strand them both in the left half of the page. */
.use-case-grid {
  display: grid;
  gap: 1.4rem;
  grid-template-columns: 1fr;
  max-width: 46rem;
  margin-inline: auto;
}

.use-case {
  text-align: center;
  padding: 1.25rem 1rem;
}

.use-case-emoji {
  font-size: 2.2rem;
  margin-bottom: 0.65rem;
}

.use-case h3 {
  font-size: 1.02rem;
  margin-bottom: 0.35rem;
}

.use-case p {
  font-size: 0.88rem;
  color: var(--text-muted);
}

@media (min-width: 640px) {
  .use-case-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

/* FAQ — a board with the question list on one side and the answer to the
   selected question on the other. Below 900px, and without JS at any width, the
   same markup reads as a plain accordion inside the list card. */
.faq-section {
  background: var(--paper-dim);
  scroll-margin-top: 96px;
}

.faq-board {
  position: relative;
  max-width: 1040px;
  margin-inline: auto;
  padding: 1.5rem;
  border-radius: var(--radius-lg);
  background: #e8e1ce;
}

.faq-board__list {
  padding: 1.5rem 1.25rem;
  border-radius: 24px;
  background-color: var(--ink);
  background-image: radial-gradient(ellipse 420px 320px at 50% 120%, rgba(224, 163, 46, 0.13), transparent 65%);
}

.faq-board__label {
  font-family: var(--font-utility);
  font-size: 0.68rem;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: rgba(251, 248, 241, 0.55);
  margin-bottom: 1rem;
  padding-inline: 0.25rem;
}

.faq-q {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  width: 100%;
  padding: 0.75rem 0.9rem;
  border: 0;
  border-radius: 14px;
  background: transparent;
  font-family: inherit;
  font-size: 0.94rem;
  font-weight: 500;
  line-height: 1.35;
  text-align: left;
  color: rgba(251, 248, 241, 0.78);
  cursor: pointer;
  transition: background-color 0.35s ease, color 0.35s ease;
}

.faq-q:hover {
  background: rgba(251, 248, 241, 0.06);
  color: var(--paper);
}

/* The default ring all but disappears on the ink card. */
.faq-q:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: -2px;
}

/* The selected question keeps a raised fill and a gold marker down its edge. */
.faq-q[aria-expanded="true"] {
  position: relative;
  background: var(--ink-raised);
  color: var(--paper);
}

.faq-q[aria-expanded="true"]::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.7rem;
  bottom: 0.7rem;
  width: 2px;
  border-radius: 2px;
  background: var(--gold);
}

.faq-q__chevron {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
  transition: transform 0.35s ease;
}

.faq-q[aria-expanded="true"] .faq-q__chevron {
  transform: rotate(180deg);
}

.faq-a {
  margin: 0.25rem 0.25rem 0.75rem;
  padding: 1rem 1.15rem;
  border-radius: 16px;
  background: var(--paper);
}

.faq-a p {
  color: var(--text-muted);
  font-size: 0.9rem;
  line-height: 1.6;
}

.faq-board__answer-head {
  display: none;
}

/* Two panes: the list holds the first column, and the answer is lifted out of
   the flow into the second — one board height, whichever answer is open. */
@media (min-width: 900px) {
  .faq-board--enhanced {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1.5rem;
    align-items: start;
  }

  .faq-board--enhanced .faq-board__list {
    padding: 1.75rem 1.4rem;
  }

  .faq-board--enhanced .faq-q__chevron {
    display: none;
  }

  .faq-board--enhanced .faq-board__answer-head {
    display: block;
    height: 5.25rem;
    padding-top: 0.25rem;
  }

  .faq-board--enhanced .faq-board__answer-head .faq-board__label {
    color: var(--gold-deep);
    margin-bottom: 0.85rem;
  }

  .faq-board--enhanced .faq-board__echo {
    color: var(--text-muted);
    font-size: 0.98rem;
    line-height: 1.4;
  }

  /* Half the board plus half the gap puts the answer's left edge on the second
     column, whichever question opened it. */
  .faq-board--enhanced .faq-a {
    position: absolute;
    top: 6.75rem;
    left: calc(50% + 0.75rem);
    right: 1.5rem;
    margin: 0;
    padding: 1.35rem 1.5rem;
    box-shadow: var(--shadow-sm);
    animation: faq-answer-in 0.3s cubic-bezier(0.16, 1, 0.3, 1) both;
  }

  .faq-board--enhanced .faq-a p {
    font-size: 1rem;
  }
}

@keyframes faq-answer-in {
  from {
    opacity: 0;
    transform: translateY(8px);
  }
}

/* Contact — one line, one button, nothing else to read */
.contact {
  padding: 4.25rem 0 3.25rem;
  scroll-margin-top: 96px;
}

.contact__inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}

.contact .section-header {
  margin-bottom: 1.75rem;
}

.contact__btn {
  padding: 0.74rem 1.5rem;
}

.contact__note {
  margin-top: 0.9rem;
  font-size: 0.85rem;
  color: var(--text-muted);
}

/* CTA — ink ground */
.cta {
  padding-bottom: 4.25rem;
  text-align: center;
}

.cta-title {
  font-size: clamp(1.45rem, 3.3vw, 2rem);
  margin-bottom: 0.6rem;
  position: relative;
}

.cta-subtitle {
  font-size: 0.98rem;
  color: var(--text-on-ink-muted);
  margin-bottom: 1.5rem;
  position: relative;
}

.cta .btn {
  position: relative;
}

/* Footer — ink ground */
.footer {
  padding: 2.25rem 0;
  background: var(--ink);
  color: var(--text-on-ink-muted);
  border-top: 1px solid var(--border-on-ink);
}

.footer__inner {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  align-items: center;
  text-align: center;
}

.footer__brand {
  display: flex;
  align-items: center;
  gap: 0.625rem;
}

.footer__brand .nav__logo {
  width: 32px;
  height: 32px;
}

.footer__brand .nav__brand-paid {
  font-size: 1.2rem;
  color: var(--paper);
}

.footer__brand .nav__brand-bot {
  font-size: 1.45rem;
  color: var(--gold);
}

.footer__note {
  font-size: 0.8rem;
  max-width: 600px;
  line-height: 1.5;
}

.footer__link {
  position: relative;
  font-size: 0.8rem;
  color: var(--paper);
  text-decoration: none;
  border-bottom: 1px solid var(--border-on-ink);
  padding-bottom: 1px;
  transition: border-color 0.3s ease;
}

/* Thumb-sized target without padding the underline away from the word. */
.footer__link::after {
  content: "";
  position: absolute;
  inset: -14px -12px;
}

.footer__link:hover {
  border-bottom-color: var(--gold);
}

.footer__copy {
  font-family: var(--font-utility);
  font-size: 0.75rem;
  letter-spacing: 0.04em;
  opacity: 0.7;
}

/* Phones — the same page at a calmer density: every section keeps less padding
   and the step frames are shorter, so the page reads as one short scroll rather
   than a stack of full-height blocks. */
@media (max-width: 640px) {
  .panel {
    padding: 3.25rem 0 2rem;
    margin-top: -1.5rem;
    border-radius: 1.5rem 1.5rem 0 0;
  }

  .cta {
    padding-bottom: 3rem;
  }

  .section-header {
    margin-bottom: 1.35rem;
  }

  .compare__card {
    padding: 1.35rem 1.25rem;
  }

  .feature-rows {
    gap: 2.25rem;
    margin-bottom: 1.75rem;
  }

  .feature-row__demo {
    padding: 1.25rem 1rem;
  }

  .feature-card {
    padding: 1.25rem;
  }

  .feature-icon {
    margin-bottom: 0.9rem;
  }

  .use-case {
    padding: 0.5rem 0.25rem;
  }

  .faq-board {
    padding: 0.75rem;
    border-radius: 1.85rem;
  }

  .faq-board__list {
    padding: 1.25rem 0.75rem;
  }

  .faq-q {
    padding: 0.8rem;
    font-size: 0.98rem;
  }

  .faq-a {
    margin: 0.25rem 0 0.75rem;
    padding: 1rem 1.1rem;
  }

  .contact {
    padding: 3rem 0 2.5rem;
  }

  .contact__btn {
    width: min(100%, 24rem);
  }

  .cta {
    padding: 2.5rem 0;
  }

  .cta .btn {
    width: min(100%, 24rem);
  }

  .cta-subtitle {
    font-size: 0.92rem;
  }
}

/* Focus visibility */
a:focus-visible,
button:focus-visible,
summary:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 3px;
  border-radius: 6px;
}

.hero :is(a, button):focus-visible,
.cta :is(a, button):focus-visible {
  outline-color: var(--gold);
}

/* Reveal-on-scroll (activated by main.js's existing IntersectionObserver) */
.reveal {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity 0.85s cubic-bezier(0.16, 1, 0.3, 1), transform 0.85s cubic-bezier(0.16, 1, 0.3, 1);
}

.reveal.is-visible {
  opacity: 1;
  transform: translateY(0);
}

/* Page-load sequence */
@keyframes fade-up {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* Same entrance as fade-up, carrying the frame's scale through it. The frame
   itself rises once; only the conversation below loops. */
@keyframes phone-rise {
  from {
    opacity: 0;
    transform: translateY(10px) scale(var(--phone-scale));
  }
  to {
    opacity: 1;
    transform: translateY(0) scale(var(--phone-scale));
  }
}

/* Hero demo loop — an 8s cycle: receipt lands, PaidBot types, reacts, then
   replies, holds, and resets. All four keyframes below run on --hero-scene, so
   their percentages line up on one timeline. The loop is what a reader who
   arrives part-way through has to wait out, so it holds the payoff only as long
   as it takes to read. */
@keyframes hero-demo-msg-out {
  0%, 2% { opacity: 0; transform: translateY(10px); }
  12% { opacity: 1; transform: translateY(0); }
}

/* The typing bubble collapses its own height on the way out so the reply that
   follows it doesn't sit below an empty gap. It is a beat, not a wait — just
   long enough to register, then the reply is straight in behind it. */
@keyframes hero-demo-typing {
  0%, 15% { opacity: 0; max-height: 0; padding-top: 0; padding-bottom: 0; transform: translateY(6px); }
  21% { opacity: 1; max-height: 28px; padding-top: 0.7rem; padding-bottom: 0.7rem; transform: translateY(0); }
  34% { opacity: 1; max-height: 28px; padding-top: 0.7rem; padding-bottom: 0.7rem; }
  39%, 100% { opacity: 0; max-height: 0; padding-top: 0; padding-bottom: 0; margin-bottom: -0.55rem; }
}

@keyframes hero-demo-reaction {
  0%, 24% { opacity: 0; transform: scale(0.5); }
  31% { opacity: 1; transform: scale(1); }
}

@keyframes hero-demo-msg-in {
  0%, 37% { opacity: 0; transform: translateY(10px); }
  48% { opacity: 1; transform: translateY(0); }
}

@keyframes dot-bounce {
  0%, 60%, 100% { transform: translateY(0); opacity: 0.5; }
  30% { transform: translateY(-3px); opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  * {
    animation: none !important;
    transition: none !important;
  }

  /* Without its animation the typing bubble never collapses, and it would push
     the bot's reply past the cut across the phone. The wizard's mid-flow
     keyboards are transient in the same way — the loop ends without them. */
  .hero-phone__typing,
  .how-scene__typing {
    display: none;
  }

  /* Scenes 2 and 3 rest collapsed because an animation normally opens them.
     With no animation to run, they show the state the story ends on. */
  .how--scenes :is(.how-pay-msg1, .how-pay-msg2, .how-done-reaction-1, .how-done-reaction-2, .how-done-reply-1, .how-done-reply-2) {
    opacity: 1 !important;
    max-height: none !important;
    margin-top: 0 !important;
    transform: none !important;
  }

  html {
    scroll-behavior: auto;
  }
}


/* Amharic. Ethiopic syllables are taller and denser than Latin at the same size,
   so the page keeps its type scale and only opens the leading up. */
html[lang="am"] body {
  line-height: 1.6;
}

html[lang="am"] .hero__title,
html[lang="am"] .section-title,
html[lang="am"] .cta-title {
  line-height: 1.35;
}

html[lang="am"] .section-eyebrow,
html[lang="am"] .how-step__number,
html[lang="am"] .compare__label {
  letter-spacing: 0;
}
