/* Flash — the marketing site.
 *
 * THE BRAND HERE IS THE PRODUCT'S BRAND, which it was not before. The app is
 * warm paper and deep green (#F7F6F2 / #00693E); the old site was near-black
 * and a brighter green it shares with nothing. A site that looks like a
 * different company than the thing it is selling makes the product feel like
 * someone else's, and a visitor notices it in the first second without being
 * able to say why.
 *
 * Tokens copied from web/app/globals.css so the two cannot drift silently. */

:root {
  --bg: #F7F6F2;          /* warm paper — the page */
  --surface: #F2F1EB;     /* recessed: wells, chips */
  --elevated: #FFFFFF;    /* lifted: cards genuinely above the page */
  --border: #E3E1D9;      /* hairline that survives warm paper */
  --border-strong: #D3D0C4;
  --ink: #101413;
  --ink-2: #3C4441;
  --muted: #6B746F;
  --primary: #00693E;
  --primary-tint: #E7F0EA;
  --invert: #101413;
  --radius: 18px;
  --max: 1120px;
  --shadow: 0 1px 2px rgba(16, 20, 19, 0.05), 0 8px 28px rgba(16, 20, 19, 0.06);
}

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font: 400 17px/1.6 ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif;
  -webkit-font-smoothing: antialiased;
}
a { color: inherit; }
img { max-width: 100%; height: auto; display: block; }

.wrap { max-width: var(--max); margin: 0 auto; padding: 0 24px; }
.wrap-wide { max-width: 1240px; }

/* ── Header ─────────────────────────────────────────────────────────── */
header {
  position: sticky; top: 0; z-index: 30;
  background: rgba(247, 246, 242, 0.82);
  backdrop-filter: saturate(180%) blur(14px);
  border-bottom: 1px solid var(--border);
}
.bar { display: flex; align-items: center; gap: 28px; height: 70px; }
.logo { display: flex; align-items: center; gap: 10px; font-weight: 700; letter-spacing: -0.025em; text-decoration: none; font-size: 20px; }
.logo svg { width: 24px; height: 24px; color: var(--primary); }
nav { display: flex; gap: 8px; margin-left: auto; align-items: center; }
nav a { text-decoration: none; color: var(--muted); font-size: 15px; font-weight: 550; padding: 8px 12px; border-radius: 10px; }
nav a:hover { color: var(--ink); background: var(--surface); }
nav a[aria-current] { color: var(--ink); }
nav a.pill { background: var(--invert); color: var(--bg); padding: 10px 18px; border-radius: 999px; }
nav a.pill:hover { opacity: 0.9; background: var(--invert); }

/* ── Type ───────────────────────────────────────────────────────────── */
h1 {
  font-size: clamp(42px, 7vw, 76px);
  line-height: 1.02;
  letter-spacing: -0.042em;
  font-weight: 700;
  margin: 0 0 22px;
  max-width: 15ch;
}
h2 {
  font-size: clamp(28px, 4vw, 44px);
  line-height: 1.1;
  letter-spacing: -0.034em;
  font-weight: 700;
  margin: 0 0 16px;
  max-width: 19ch;
}
h3 { font-size: 19px; line-height: 1.3; letter-spacing: -0.018em; font-weight: 650; margin: 0 0 8px; }
.lede { font-size: clamp(17px, 2.1vw, 21px); line-height: 1.55; color: var(--ink-2); max-width: 56ch; margin: 0 0 32px; }
p { margin: 0 0 16px; color: var(--muted); }
.eyebrow { font-size: 12px; font-weight: 700; letter-spacing: 0.12em; text-transform: uppercase; color: var(--primary); margin: 0 0 16px; }
.center { text-align: center; margin-left: auto; margin-right: auto; }
h1.center, h2.center, .lede.center { max-width: 22ch; }
.lede.center { max-width: 56ch; }

/* ── Sections ───────────────────────────────────────────────────────── */
section { padding: clamp(72px, 10vw, 128px) 0; }
@media (max-width: 720px) { section { padding: 52px 0; } section.hero { padding-top: 40px; } }
section.hero { padding-top: clamp(64px, 9vw, 104px); padding-bottom: clamp(48px, 6vw, 72px); }
section.tint { background: var(--surface); border-top: 1px solid var(--border); border-bottom: 1px solid var(--border); }
section.ink { background: var(--invert); color: var(--bg); }
section.ink h2 { color: var(--bg); }
section.ink p, section.ink .lede { color: rgba(247, 246, 242, 0.72); }
section.ink .eyebrow { color: #6BE3A6; }

/* ── Buttons ────────────────────────────────────────────────────────── */
.cta { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; }
.cta.center { justify-content: center; }
.btn {
  display: inline-flex; align-items: center; gap: 10px;
  height: 54px; padding: 0 28px; border-radius: 999px;
  font-size: 16.5px; font-weight: 650; text-decoration: none;
  border: 1px solid transparent; cursor: pointer;
  transition: transform 0.14s ease, opacity 0.14s ease, border-color 0.14s ease, background 0.14s ease;
}
.btn:active { transform: translateY(1px); }
.btn-primary { background: var(--primary); color: #fff; }
.btn-primary:hover { opacity: 0.92; }
.btn-dark { background: var(--invert); color: var(--bg); }
.btn-dark:hover { opacity: 0.9; }
.btn-ghost { border-color: var(--border-strong); color: var(--ink); background: var(--elevated); }
.btn-ghost:hover { border-color: var(--muted); }
.btn-light { background: var(--bg); color: var(--ink); }
.note { font-size: 14.5px; color: var(--muted); margin: 16px 0 0; }
section.ink .note { color: rgba(247, 246, 242, 0.5); }

/* ── Two doors ──────────────────────────────────────────────────────── */
.doors { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; margin-top: 44px; }
.door {
  display: block; text-decoration: none;
  background: var(--elevated); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 34px 30px 28px;
  box-shadow: var(--shadow);
  transition: transform 0.18s ease, border-color 0.18s ease;
}
.door:hover { transform: translateY(-3px); border-color: var(--primary); }
.door h3 { font-size: 22px; letter-spacing: -0.025em; }
.door p { color: var(--muted); font-size: 16px; margin-bottom: 0; }
.door .go { color: var(--primary); font-weight: 650; font-size: 15.5px; margin-top: 18px; display: inline-block; }

/* ── Grids & cards ──────────────────────────────────────────────────── */
.grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; }
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; }
.card { background: var(--elevated); border: 1px solid var(--border); border-radius: var(--radius); padding: 28px 26px; }
.card p { margin: 0; font-size: 16px; }
section.ink .card { background: rgba(255,255,255,0.05); border-color: rgba(255,255,255,0.1); }
section.ink .card h3 { color: var(--bg); }
section.ink .card p { color: rgba(247,246,242,0.66); }

/* ── Product shots ──────────────────────────────────────────────────── */
.shot {
  border-radius: 14px; border: 1px solid var(--border);
  box-shadow: var(--shadow); overflow: hidden; background: var(--elevated);
}
.shot-lead { margin-top: 52px; }
.shot-pair { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; margin-top: 40px; }
.split { display: grid; grid-template-columns: 1fr 1.15fr; gap: clamp(32px, 5vw, 64px); align-items: center; }
.split.flip > :first-child { order: 2; }

/* ── Steps ──────────────────────────────────────────────────────────── */
.steps { counter-reset: s; display: grid; gap: 0; margin: 36px 0 0; padding: 0; list-style: none; }
.steps li { counter-increment: s; display: flex; gap: 18px; padding: 20px 0; border-top: 1px solid var(--border); }
.steps li::before {
  content: counter(s); flex: none;
  width: 30px; height: 30px; border-radius: 999px;
  background: var(--primary-tint); color: var(--primary);
  font-size: 13.5px; font-weight: 700;
  display: grid; place-items: center;
}
.steps strong { display: block; font-weight: 650; color: var(--ink); margin-bottom: 4px; font-size: 17px; }
.steps span { color: var(--muted); font-size: 16px; }
section.ink .steps li { border-color: rgba(255,255,255,0.12); }
section.ink .steps strong { color: var(--bg); }
section.ink .steps span { color: rgba(247,246,242,0.62); }
section.ink .steps li::before { background: rgba(107,227,166,0.16); color: #6BE3A6; }

/* ── Footer ─────────────────────────────────────────────────────────── */
footer { border-top: 1px solid var(--border); padding: 48px 0 64px; }
footer p { font-size: 14.5px; color: var(--muted); margin: 0; }
.foot-links { display: flex; gap: 22px; flex-wrap: wrap; margin-bottom: 18px; }
.foot-links a { text-decoration: none; color: var(--ink-2); font-size: 15px; font-weight: 550; }
.foot-links a:hover { color: var(--primary); }

@media (max-width: 860px) {
  .split, .grid-2 { grid-template-columns: 1fr; }
  .split.flip > :first-child { order: 0; }
}
@media (max-width: 720px) {
  .doors, .grid-3, .shot-pair { grid-template-columns: 1fr; }
  /* The two doors MUST stay reachable. Hiding them left a two-sided site with
     one visible link on the device most people arrive on — a shopper landing
     on the business page had no way back. Tightened instead of removed. */
  .bar { gap: 10px; height: 62px; }
  .logo { font-size: 18px; }
  .logo svg { width: 21px; height: 21px; }
  nav { gap: 2px; }
  nav a { font-size: 14px; padding: 7px 8px; }
  nav a.pill { padding: 9px 14px; font-size: 14px; }
}
@media (max-width: 380px) {
  /* Below this the three will not fit honestly, so the pill goes — signing in
     is the one thing a returning user can find from either door. */
  nav a.pill { display: none; }
}

/* ── Devices ─────────────────────────────────────────────────────────
 *
 * A screenshot floating on a page is evidence with no scale: nothing says
 * whether it is a phone or a wall display, and it reads as a picture of a
 * design rather than a thing that runs. A frame supplies that in one glance,
 * and it costs nothing — these are borders and radii, not images, so they stay
 * sharp at any density and add no bytes to load.
 *
 * Deliberately plain. A photorealistic mock with reflections and a desk
 * competes with the screen it is meant to present, and the screen is the
 * argument. */

.laptop { position: relative; margin: 0 auto; max-width: 940px; }
.laptop-screen {
  background: #101413;
  border-radius: 14px 14px 4px 4px;
  padding: 12px 12px 0;
  box-shadow: 0 24px 60px rgba(16, 20, 19, 0.16), 0 2px 8px rgba(16, 20, 19, 0.08);
}
.laptop-screen img { border-radius: 5px 5px 0 0; display: block; width: 100%; height: auto; }
/* The lip: a laptop's base is wider than its lid, which is the cue that reads
   as "laptop" rather than "framed picture". */
.laptop-base {
  height: 14px; margin: 0 auto;
  width: 106%; max-width: none; transform: translateX(-2.85%);
  background: linear-gradient(180deg, #23282A 0%, #171B1D 62%, #0C0F10 100%);
  border-radius: 0 0 12px 12px;
  position: relative;
}
.laptop-base::after {
  content: ""; position: absolute; left: 50%; top: 0;
  width: 88px; height: 5px; transform: translateX(-50%);
  background: rgba(0, 0, 0, 0.42); border-radius: 0 0 6px 6px;
}

.phone {
  position: relative; margin: 0 auto; width: 100%; max-width: 296px;
  background: #101413; border-radius: 46px; padding: 11px;
  box-shadow: 0 24px 60px rgba(16, 20, 19, 0.18), 0 2px 8px rgba(16, 20, 19, 0.1);
}
.phone img { border-radius: 36px; display: block; width: 100%; height: auto; }
/* The island, not a notch — this is a 15 Pro and getting it wrong is the kind
   of detail that makes the whole frame read as fake. */
.phone::after {
  content: ""; position: absolute; top: 24px; left: 50%;
  width: 88px; height: 26px; transform: translateX(-50%);
  background: #101413; border-radius: 999px;
}
.phone-row { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(28px, 5vw, 64px); align-items: center; }
@media (max-width: 860px) { .phone-row { grid-template-columns: 1fr; } }

/* A row of phones, for showing a flow rather than a feature. Three screens in
   sequence say "this is a thing that happens" where one says "this exists". */
.phones { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(16px, 3vw, 36px); margin-top: 48px; align-items: start; }
.phones .phone { max-width: 100%; border-radius: 34px; padding: 8px; }
.phones .phone img { border-radius: 27px; }
.phones .phone::after { top: 18px; width: 66px; height: 20px; }
.phone-cap { font-size: 14.5px; color: var(--muted); text-align: center; margin: 16px 0 0; }
section.ink .phone-cap { color: rgba(247,246,242,0.6); }
@media (max-width: 720px) { .phones { grid-template-columns: 1fr; max-width: 300px; margin-inline: auto; } }

/* ── The flow ────────────────────────────────────────────────────────
 *
 * Three equal phones in a row reads as a catalogue: three things that exist,
 * in no particular relationship. What we are showing is a LOOP — money asked
 * for, money arriving, proof handed over — and a loop needs direction, so the
 * composition supplies it. The middle device is raised and larger because it is
 * the moment the money actually moves; the outer two sit lower and turn
 * slightly inward, which is what makes the eye travel left to right instead of
 * stopping on whichever is nearest.
 *
 * Depth here is overlap and shadow, not skeuomorphism. No desks, no
 * reflections, no hands — those compete with the screen, and the screen is the
 * argument.
 */
/* ── The story ───────────────────────────────────────────────────────
 *
 * NOT A ROW OF THREE. A row is the template move — it treats three screens as
 * equal items in a list, gives each a third of the width, and shrinks them to
 * roughly 330px, at which point nobody can read a single figure on them. These
 * captures are full of the argument: K38,650 taken this month, a receipt for
 * K7,300 that says paid in full, a claim waiting to be confirmed. Shrunk to a
 * thumbnail, all of that is decoration.
 *
 * So each screen gets its own band, alternating sides, at a size where the
 * words on it can actually be read — and the copy beside it says what you are
 * looking at. Scrolling becomes the sequence, which is what scrolling is for,
 * and each moment of the loop lands on its own instead of competing with two
 * neighbours.
 */
.story { display: grid; gap: clamp(72px, 9vw, 132px); margin-top: clamp(56px, 7vw, 92px); }
.beat {
  display: grid; grid-template-columns: 1fr 1fr;
  gap: clamp(36px, 6vw, 96px); align-items: center;
}
.beat:nth-child(even) .beat-art { order: 2; }
.beat-art { position: relative; display: flex; justify-content: center; }
/* A wash so the device sits in the page rather than on it. */
.beat-art::before {
  content: ""; position: absolute; inset: 6% 4%;
  background: radial-gradient(58% 62% at 50% 46%, rgba(0, 105, 62, 0.11), transparent 72%);
  filter: blur(18px); pointer-events: none;
}
.beat-art .phone {
  position: relative; max-width: 340px; width: 100%;
  border-radius: 46px; padding: 10px;
  box-shadow: 0 44px 96px rgba(16,20,19,0.19), 0 4px 14px rgba(16,20,19,0.09);
}
.beat-art .phone img { border-radius: 37px; }
.beat-art .phone::after { top: 22px; width: 86px; height: 25px; }

.beat-copy .step {
  display: inline-flex; align-items: center; gap: 9px;
  font-size: 11.5px; font-weight: 700; letter-spacing: 0.13em;
  text-transform: uppercase; color: var(--primary);
  margin: 0 0 18px;
}
.beat-copy .step i {
  font-style: normal; width: 26px; height: 26px; border-radius: 999px;
  background: var(--primary-tint); display: grid; place-items: center;
  font-size: 12px; letter-spacing: 0;
}
.beat-copy h3 { font-size: clamp(24px, 3.1vw, 34px); line-height: 1.14; letter-spacing: -0.03em; font-weight: 700; margin: 0 0 14px; max-width: 17ch; }
.beat-copy p { font-size: 17.5px; line-height: 1.55; color: var(--ink-2); max-width: 44ch; margin: 0; }
section.ink .beat-copy h3 { color: var(--bg); }
section.ink .beat-copy p { color: rgba(247,246,242,0.7); }
section.ink .beat-copy .step { color: #6BE3A6; }
section.ink .beat-copy .step i { background: rgba(107,227,166,0.15); }
section.ink .beat-art::before { background: radial-gradient(58% 62% at 50% 46%, rgba(107,227,166,0.14), transparent 72%); }

@media (max-width: 820px) {
  .beat { grid-template-columns: 1fr; gap: 32px; }
  .beat:nth-child(even) .beat-art { order: 0; }
  .beat-art .phone { max-width: 300px; }
}

/* ── Reveal on scroll ────────────────────────────────────────────────
 *
 * Sequenced left to right so the eye is walked through the loop in the order
 * it happens, rather than everything appearing at once and leaving the visitor
 * to work out the order themselves. Small distances and short durations: this
 * is meant to direct attention, not to be noticed.
 *
 * Anything not revealed stays visible if the script never runs — a page that
 * depends on JavaScript to show its content is a page that is blank for
 * whoever it fails on.
 */
@media (prefers-reduced-motion: no-preference) {
  .reveal { opacity: 0; transform: translateY(18px); transition: opacity 0.62s cubic-bezier(0.22, 0.8, 0.3, 1), transform 0.62s cubic-bezier(0.22, 0.8, 0.3, 1); }
  .reveal.in { opacity: 1; transform: none; }
}

/* ── Scroll-driven screens ───────────────────────────────────────────
 *
 * The phone stays put and its SCREEN changes as you scroll — an invoice
 * raised, then part-paid and waiting on a confirmation, then paid and
 * receipted. Scroll drives it rather than a timer, so each beat lands when the
 * reader arrives instead of playing to an empty room.
 *
 * WHY NOT THE EXPLODED-3D TREATMENT everyone else uses: sites selling an
 * abstraction have to invent a visual, because there is nothing to photograph.
 * We have the opposite problem — a real thing on a real screen — and rendering
 * a receipt as a floating translucent panel would make a concrete product look
 * abstract. That is a downgrade dressed as sophistication.
 *
 * No WebGL, no canvas, no library. Three stills and an opacity transition.
 */
.scroller-inner { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(40px, 7vw, 110px); align-items: start; }
.scroller-art {
  position: sticky; top: 92px;
  display: flex; justify-content: center;
  padding: 0;
  /* Bounded so the phone can never be taller than the space it is pinned in.
     A sticky element taller than its viewport slot scrolls out of view, which
     defeats the entire point of pinning it. */
  max-height: calc(100vh - 116px);
}
.scroller-art .phone {
  position: relative; width: min(300px, 100%);
  border-radius: 46px; padding: 10px;
  box-shadow: 0 44px 96px rgba(16,20,19,0.2), 0 4px 14px rgba(16,20,19,0.09);
}
.scroller-art .phone::after { top: 22px; width: 86px; height: 25px; z-index: 3; }
/* The stack. The first is in normal flow so it sets the height; the rest are
   layered over it. Without JavaScript you still see that first screen. */
.scr { border-radius: 37px; transition: opacity 0.5s ease, transform 0.5s ease; }
.scr + .scr { position: absolute; inset: 10px; width: calc(100% - 20px); height: auto; opacity: 0; }
.scr.off { transform: scale(1.015); }
.scr.on { opacity: 1; transform: none; }
.scr.off { opacity: 0; }

/* Tight enough that two steps are never both fully off-screen, loose enough
   that the screen has changed before the next sentence arrives. 74vh left
   voids the size of a paragraph between beats. */
.sstep { min-height: 46vh; display: flex; flex-direction: column; justify-content: center; padding: 3vh 0; }
.sstep:first-child { padding-top: 0; }
.sstep:last-child { min-height: 62vh; }
/* The rail. Three marks, filled as you pass them — the only thing on the page
   that says how much of this section is left, which is the question a reader
   asks before deciding to keep going. */
.scroller-steps { position: relative; padding-left: 34px; }
.scroller-steps::before {
  content: ""; position: absolute; left: 5px; top: 12%; bottom: 12%;
  width: 2px; background: var(--border);
}
.sstep::before {
  content: ""; position: absolute; left: -34px; top: 50%; width: 11px; height: 11px;
  margin-top: -5px; border-radius: 999px; background: var(--border-strong);
  transition: background 0.32s ease, transform 0.32s ease;
}
.sstep { position: relative; }
.sstep.on::before { background: var(--primary); transform: scale(1.4); }
section.ink .scroller-steps::before { background: rgba(255,255,255,0.14); }
section.ink .sstep::before { background: rgba(255,255,255,0.24); }
section.ink .sstep.on::before { background: #6BE3A6; }
.sstep .step { display: inline-flex; align-items: center; gap: 9px; font-size: 11.5px; font-weight: 700; letter-spacing: 0.13em; text-transform: uppercase; color: var(--primary); margin: 0 0 18px; }
.sstep .step i { font-style: normal; width: 26px; height: 26px; border-radius: 999px; background: var(--primary-tint); display: grid; place-items: center; font-size: 12px; letter-spacing: 0; }
.sstep h3 { font-size: clamp(24px, 3.2vw, 36px); line-height: 1.12; letter-spacing: -0.03em; font-weight: 700; margin: 0 0 14px; max-width: 17ch; }
.sstep p { font-size: 17.5px; line-height: 1.55; color: var(--ink-2); max-width: 44ch; margin: 0; }
/* Dim the ones you are not on, so the eye knows which screen it is reading. */
@media (prefers-reduced-motion: no-preference) {
  .sstep { opacity: 0.32; transition: opacity 0.45s ease; }
  .sstep.on { opacity: 1; }
}
section.ink .sstep h3 { color: var(--bg); }
section.ink .sstep p { color: rgba(247,246,242,0.7); }
section.ink .sstep .step { color: #6BE3A6; }
section.ink .sstep .step i { background: rgba(107,227,166,0.15); }

@media (max-width: 900px) {
  /* Stacked, and smaller. Two attempts at something cleverer both failed:
     pinning took 480px of an 844px viewport and left the active heading either
     showing through the device or hidden behind it, and moving the screens
     into each step produced two of everything. Simple and readable beats
     clever and broken.
     The device is 196px rather than 300px, because three 300px mockups put
     nearly 2,000px of imagery in front of 121 words. */
  .scroller-inner { grid-template-columns: 1fr; gap: 24px; }
  .scroller-steps { padding-left: 0; }
  .scroller-steps::before, .sstep::before { display: none; }
  .scroller-art { position: static; max-height: none; padding: 0; display: flex; }
  .scroller-art .phone { width: min(196px, 52vw); border-radius: 30px; padding: 6px; }
  .scroller-art .phone img { border-radius: 25px; }
  .scroller-art .phone::after { top: 13px; width: 56px; height: 16px; }
  .scr + .scr { inset: 6px; width: calc(100% - 12px); }
  .sstep { min-height: 0; margin: 0 0 34px; padding: 0; opacity: 1 !important; }
  .sstep::after { display: none; }
  .sstep h3 { font-size: 25px; }
  .sstep p { font-size: 16.5px; }
}

@media (max-width: 720px) {
  .doors, .grid-3, .shot-pair { grid-template-columns: 1fr; }
  /* The two doors MUST stay reachable. Hiding them left a two-sided site with
     one visible link on the device most people arrive on — a shopper landing
     on the business page had no way back. Tightened instead of removed. */
  .bar { gap: 10px; height: 62px; }
  .logo { font-size: 18px; }
  .logo svg { width: 21px; height: 21px; }
  nav { gap: 2px; }
  nav a { font-size: 14px; padding: 7px 8px; }
  nav a.pill { padding: 9px 14px; font-size: 14px; }
}
@media (max-width: 380px) {
  /* Below this the three will not fit honestly, so the pill goes — signing in
     is the one thing a returning user can find from either door. */
  nav a.pill { display: none; }
}

/* ── Devices ─────────────────────────────────────────────────────────
 *
 * A screenshot floating on a page is evidence with no scale: nothing says
 * whether it is a phone or a wall display, and it reads as a picture of a
 * design rather than a thing that runs. A frame supplies that in one glance,
 * and it costs nothing — these are borders and radii, not images, so they stay
 * sharp at any density and add no bytes to load.
 *
 * Deliberately plain. A photorealistic mock with reflections and a desk
 * competes with the screen it is meant to present, and the screen is the
 * argument. */

.laptop { position: relative; margin: 0 auto; max-width: 940px; }
.laptop-screen {
  background: #101413;
  border-radius: 14px 14px 4px 4px;
  padding: 12px 12px 0;
  box-shadow: 0 24px 60px rgba(16, 20, 19, 0.16), 0 2px 8px rgba(16, 20, 19, 0.08);
}
.laptop-screen img { border-radius: 5px 5px 0 0; display: block; width: 100%; height: auto; }
/* The lip: a laptop's base is wider than its lid, which is the cue that reads
   as "laptop" rather than "framed picture". */
.laptop-base {
  height: 14px; margin: 0 auto;
  width: 106%; max-width: none; transform: translateX(-2.85%);
  background: linear-gradient(180deg, #23282A 0%, #171B1D 62%, #0C0F10 100%);
  border-radius: 0 0 12px 12px;
  position: relative;
}
.laptop-base::after {
  content: ""; position: absolute; left: 50%; top: 0;
  width: 88px; height: 5px; transform: translateX(-50%);
  background: rgba(0, 0, 0, 0.42); border-radius: 0 0 6px 6px;
}

.phone {
  position: relative; margin: 0 auto; width: 100%; max-width: 296px;
  background: #101413; border-radius: 46px; padding: 11px;
  box-shadow: 0 24px 60px rgba(16, 20, 19, 0.18), 0 2px 8px rgba(16, 20, 19, 0.1);
}
.phone img { border-radius: 36px; display: block; width: 100%; height: auto; }
/* The island, not a notch — this is a 15 Pro and getting it wrong is the kind
   of detail that makes the whole frame read as fake. */
.phone::after {
  content: ""; position: absolute; top: 24px; left: 50%;
  width: 88px; height: 26px; transform: translateX(-50%);
  background: #101413; border-radius: 999px;
}
.phone-row { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(28px, 5vw, 64px); align-items: center; }
@media (max-width: 860px) { .phone-row { grid-template-columns: 1fr; } }

/* A row of phones, for showing a flow rather than a feature. Three screens in
   sequence say "this is a thing that happens" where one says "this exists". */
.phones { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(16px, 3vw, 36px); margin-top: 48px; align-items: start; }
.phones .phone { max-width: 100%; border-radius: 34px; padding: 8px; }
.phones .phone img { border-radius: 27px; }
.phones .phone::after { top: 18px; width: 66px; height: 20px; }
.phone-cap { font-size: 14.5px; color: var(--muted); text-align: center; margin: 16px 0 0; }
section.ink .phone-cap { color: rgba(247,246,242,0.6); }
@media (max-width: 720px) { .phones { grid-template-columns: 1fr; max-width: 300px; margin-inline: auto; } }

/* ── The flow ────────────────────────────────────────────────────────
 *
 * Three equal phones in a row reads as a catalogue: three things that exist,
 * in no particular relationship. What we are showing is a LOOP — money asked
 * for, money arriving, proof handed over — and a loop needs direction, so the
 * composition supplies it. The middle device is raised and larger because it is
 * the moment the money actually moves; the outer two sit lower and turn
 * slightly inward, which is what makes the eye travel left to right instead of
 * stopping on whichever is nearest.
 *
 * Depth here is overlap and shadow, not skeuomorphism. No desks, no
 * reflections, no hands — those compete with the screen, and the screen is the
 * argument.
 */
/* ── The story ───────────────────────────────────────────────────────
 *
 * NOT A ROW OF THREE. A row is the template move — it treats three screens as
 * equal items in a list, gives each a third of the width, and shrinks them to
 * roughly 330px, at which point nobody can read a single figure on them. These
 * captures are full of the argument: K38,650 taken this month, a receipt for
 * K7,300 that says paid in full, a claim waiting to be confirmed. Shrunk to a
 * thumbnail, all of that is decoration.
 *
 * So each screen gets its own band, alternating sides, at a size where the
 * words on it can actually be read — and the copy beside it says what you are
 * looking at. Scrolling becomes the sequence, which is what scrolling is for,
 * and each moment of the loop lands on its own instead of competing with two
 * neighbours.
 */
.story { display: grid; gap: clamp(72px, 9vw, 132px); margin-top: clamp(56px, 7vw, 92px); }
.beat {
  display: grid; grid-template-columns: 1fr 1fr;
  gap: clamp(36px, 6vw, 96px); align-items: center;
}
.beat:nth-child(even) .beat-art { order: 2; }
.beat-art { position: relative; display: flex; justify-content: center; }
/* A wash so the device sits in the page rather than on it. */
.beat-art::before {
  content: ""; position: absolute; inset: 6% 4%;
  background: radial-gradient(58% 62% at 50% 46%, rgba(0, 105, 62, 0.11), transparent 72%);
  filter: blur(18px); pointer-events: none;
}
.beat-art .phone {
  position: relative; max-width: 340px; width: 100%;
  border-radius: 46px; padding: 10px;
  box-shadow: 0 44px 96px rgba(16,20,19,0.19), 0 4px 14px rgba(16,20,19,0.09);
}
.beat-art .phone img { border-radius: 37px; }
.beat-art .phone::after { top: 22px; width: 86px; height: 25px; }

.beat-copy .step {
  display: inline-flex; align-items: center; gap: 9px;
  font-size: 11.5px; font-weight: 700; letter-spacing: 0.13em;
  text-transform: uppercase; color: var(--primary);
  margin: 0 0 18px;
}
.beat-copy .step i {
  font-style: normal; width: 26px; height: 26px; border-radius: 999px;
  background: var(--primary-tint); display: grid; place-items: center;
  font-size: 12px; letter-spacing: 0;
}
.beat-copy h3 { font-size: clamp(24px, 3.1vw, 34px); line-height: 1.14; letter-spacing: -0.03em; font-weight: 700; margin: 0 0 14px; max-width: 17ch; }
.beat-copy p { font-size: 17.5px; line-height: 1.55; color: var(--ink-2); max-width: 44ch; margin: 0; }
section.ink .beat-copy h3 { color: var(--bg); }
section.ink .beat-copy p { color: rgba(247,246,242,0.7); }
section.ink .beat-copy .step { color: #6BE3A6; }
section.ink .beat-copy .step i { background: rgba(107,227,166,0.15); }
section.ink .beat-art::before { background: radial-gradient(58% 62% at 50% 46%, rgba(107,227,166,0.14), transparent 72%); }

@media (max-width: 820px) {
  .beat { grid-template-columns: 1fr; gap: 32px; }
  .beat:nth-child(even) .beat-art { order: 0; }
  .beat-art .phone { max-width: 300px; }
}

/* ── Reveal on scroll ────────────────────────────────────────────────
 *
 * Sequenced left to right so the eye is walked through the loop in the order
 * it happens, rather than everything appearing at once and leaving the visitor
 * to work out the order themselves. Small distances and short durations: this
 * is meant to direct attention, not to be noticed.
 *
 * Anything not revealed stays visible if the script never runs — a page that
 * depends on JavaScript to show its content is a page that is blank for
 * whoever it fails on.
 */
@media (prefers-reduced-motion: no-preference) {
  .reveal { opacity: 0; transform: translateY(18px); transition: opacity 0.62s cubic-bezier(0.22, 0.8, 0.3, 1), transform 0.62s cubic-bezier(0.22, 0.8, 0.3, 1); }
  .reveal.in { opacity: 1; transform: none; }
}

/* ── Scroll-driven screens ───────────────────────────────────────────
 *
 * The phone stays put and its SCREEN changes as you scroll — an invoice
 * raised, then part-paid and waiting on a confirmation, then paid and
 * receipted. Scroll drives it rather than a timer, so each beat lands when the
 * reader arrives instead of playing to an empty room.
 *
 * WHY NOT THE EXPLODED-3D TREATMENT everyone else uses: sites selling an
 * abstraction have to invent a visual, because there is nothing to photograph.
 * We have the opposite problem — a real thing on a real screen — and rendering
 * a receipt as a floating translucent panel would make a concrete product look
 * abstract. That is a downgrade dressed as sophistication.
 *
 * No WebGL, no canvas, no library. Three stills and an opacity transition.
 */
.scroller-inner { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(40px, 7vw, 110px); align-items: start; }
.scroller-art {
  position: sticky; top: 92px;
  display: flex; justify-content: center;
  padding: 0;
  /* Bounded so the phone can never be taller than the space it is pinned in.
     A sticky element taller than its viewport slot scrolls out of view, which
     defeats the entire point of pinning it. */
  max-height: calc(100vh - 116px);
}
.scroller-art .phone {
  position: relative; width: min(300px, 100%);
  border-radius: 46px; padding: 10px;
  box-shadow: 0 44px 96px rgba(16,20,19,0.2), 0 4px 14px rgba(16,20,19,0.09);
}
.scroller-art .phone::after { top: 22px; width: 86px; height: 25px; z-index: 3; }
/* The stack. The first is in normal flow so it sets the height; the rest are
   layered over it. Without JavaScript you still see that first screen. */
.scr { border-radius: 37px; transition: opacity 0.5s ease, transform 0.5s ease; }
.scr + .scr { position: absolute; inset: 10px; width: calc(100% - 20px); height: auto; opacity: 0; }
.scr.off { transform: scale(1.015); }
.scr.on { opacity: 1; transform: none; }
.scr.off { opacity: 0; }

/* Tight enough that two steps are never both fully off-screen, loose enough
   that the screen has changed before the next sentence arrives. 74vh left
   voids the size of a paragraph between beats. */
.sstep { min-height: 46vh; display: flex; flex-direction: column; justify-content: center; padding: 3vh 0; }
.sstep:first-child { padding-top: 0; }
.sstep:last-child { min-height: 62vh; }
/* The rail. Three marks, filled as you pass them — the only thing on the page
   that says how much of this section is left, which is the question a reader
   asks before deciding to keep going. */
.scroller-steps { position: relative; padding-left: 34px; }
.scroller-steps::before {
  content: ""; position: absolute; left: 5px; top: 12%; bottom: 12%;
  width: 2px; background: var(--border);
}
.sstep::before {
  content: ""; position: absolute; left: -34px; top: 50%; width: 11px; height: 11px;
  margin-top: -5px; border-radius: 999px; background: var(--border-strong);
  transition: background 0.32s ease, transform 0.32s ease;
}
.sstep { position: relative; }
.sstep.on::before { background: var(--primary); transform: scale(1.4); }
section.ink .scroller-steps::before { background: rgba(255,255,255,0.14); }
section.ink .sstep::before { background: rgba(255,255,255,0.24); }
section.ink .sstep.on::before { background: #6BE3A6; }
.sstep .step { display: inline-flex; align-items: center; gap: 9px; font-size: 11.5px; font-weight: 700; letter-spacing: 0.13em; text-transform: uppercase; color: var(--primary); margin: 0 0 18px; }
.sstep .step i { font-style: normal; width: 26px; height: 26px; border-radius: 999px; background: var(--primary-tint); display: grid; place-items: center; font-size: 12px; letter-spacing: 0; }
.sstep h3 { font-size: clamp(24px, 3.2vw, 36px); line-height: 1.12; letter-spacing: -0.03em; font-weight: 700; margin: 0 0 14px; max-width: 17ch; }
.sstep p { font-size: 17.5px; line-height: 1.55; color: var(--ink-2); max-width: 44ch; margin: 0; }
/* Dim the ones you are not on, so the eye knows which screen it is reading. */
@media (prefers-reduced-motion: no-preference) {
  .sstep { opacity: 0.32; transition: opacity 0.45s ease; }
  .sstep.on { opacity: 1; }
}
section.ink .sstep h3 { color: var(--bg); }
section.ink .sstep p { color: rgba(247,246,242,0.7); }
section.ink .sstep .step { color: #6BE3A6; }
section.ink .sstep .step i { background: rgba(107,227,166,0.15); }

@media (max-width: 720px) {
  .doors, .grid-3, .shot-pair { grid-template-columns: 1fr; }
  /* The two doors MUST stay reachable. Hiding them left a two-sided site with
     one visible link on the device most people arrive on — a shopper landing
     on the business page had no way back. Tightened instead of removed. */
  .bar { gap: 10px; height: 62px; }
  .logo { font-size: 18px; }
  .logo svg { width: 21px; height: 21px; }
  nav { gap: 2px; }
  nav a { font-size: 14px; padding: 7px 8px; }
  nav a.pill { padding: 9px 14px; font-size: 14px; }
}
@media (max-width: 380px) {
  /* Below this the three will not fit honestly, so the pill goes — signing in
     is the one thing a returning user can find from either door. */
  nav a.pill { display: none; }
}

/* ── Devices ─────────────────────────────────────────────────────────
 *
 * A screenshot floating on a page is evidence with no scale: nothing says
 * whether it is a phone or a wall display, and it reads as a picture of a
 * design rather than a thing that runs. A frame supplies that in one glance,
 * and it costs nothing — these are borders and radii, not images, so they stay
 * sharp at any density and add no bytes to load.
 *
 * Deliberately plain. A photorealistic mock with reflections and a desk
 * competes with the screen it is meant to present, and the screen is the
 * argument. */

.laptop { position: relative; margin: 0 auto; max-width: 940px; }
.laptop-screen {
  background: #101413;
  border-radius: 14px 14px 4px 4px;
  padding: 12px 12px 0;
  box-shadow: 0 24px 60px rgba(16, 20, 19, 0.16), 0 2px 8px rgba(16, 20, 19, 0.08);
}
.laptop-screen img { border-radius: 5px 5px 0 0; display: block; width: 100%; height: auto; }
/* The lip: a laptop's base is wider than its lid, which is the cue that reads
   as "laptop" rather than "framed picture". */
.laptop-base {
  height: 14px; margin: 0 auto;
  width: 106%; max-width: none; transform: translateX(-2.85%);
  background: linear-gradient(180deg, #23282A 0%, #171B1D 62%, #0C0F10 100%);
  border-radius: 0 0 12px 12px;
  position: relative;
}
.laptop-base::after {
  content: ""; position: absolute; left: 50%; top: 0;
  width: 88px; height: 5px; transform: translateX(-50%);
  background: rgba(0, 0, 0, 0.42); border-radius: 0 0 6px 6px;
}

.phone {
  position: relative; margin: 0 auto; width: 100%; max-width: 296px;
  background: #101413; border-radius: 46px; padding: 11px;
  box-shadow: 0 24px 60px rgba(16, 20, 19, 0.18), 0 2px 8px rgba(16, 20, 19, 0.1);
}
.phone img { border-radius: 36px; display: block; width: 100%; height: auto; }
/* The island, not a notch — this is a 15 Pro and getting it wrong is the kind
   of detail that makes the whole frame read as fake. */
.phone::after {
  content: ""; position: absolute; top: 24px; left: 50%;
  width: 88px; height: 26px; transform: translateX(-50%);
  background: #101413; border-radius: 999px;
}
.phone-row { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(28px, 5vw, 64px); align-items: center; }
@media (max-width: 860px) { .phone-row { grid-template-columns: 1fr; } }

/* A row of phones, for showing a flow rather than a feature. Three screens in
   sequence say "this is a thing that happens" where one says "this exists". */
.phones { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(16px, 3vw, 36px); margin-top: 48px; align-items: start; }
.phones .phone { max-width: 100%; border-radius: 34px; padding: 8px; }
.phones .phone img { border-radius: 27px; }
.phones .phone::after { top: 18px; width: 66px; height: 20px; }
.phone-cap { font-size: 14.5px; color: var(--muted); text-align: center; margin: 16px 0 0; }
section.ink .phone-cap { color: rgba(247,246,242,0.6); }
@media (max-width: 720px) { .phones { grid-template-columns: 1fr; max-width: 300px; margin-inline: auto; } }

/* ── The flow ────────────────────────────────────────────────────────
 *
 * Three equal phones in a row reads as a catalogue: three things that exist,
 * in no particular relationship. What we are showing is a LOOP — money asked
 * for, money arriving, proof handed over — and a loop needs direction, so the
 * composition supplies it. The middle device is raised and larger because it is
 * the moment the money actually moves; the outer two sit lower and turn
 * slightly inward, which is what makes the eye travel left to right instead of
 * stopping on whichever is nearest.
 *
 * Depth here is overlap and shadow, not skeuomorphism. No desks, no
 * reflections, no hands — those compete with the screen, and the screen is the
 * argument.
 */
/* ── The story ───────────────────────────────────────────────────────
 *
 * NOT A ROW OF THREE. A row is the template move — it treats three screens as
 * equal items in a list, gives each a third of the width, and shrinks them to
 * roughly 330px, at which point nobody can read a single figure on them. These
 * captures are full of the argument: K38,650 taken this month, a receipt for
 * K7,300 that says paid in full, a claim waiting to be confirmed. Shrunk to a
 * thumbnail, all of that is decoration.
 *
 * So each screen gets its own band, alternating sides, at a size where the
 * words on it can actually be read — and the copy beside it says what you are
 * looking at. Scrolling becomes the sequence, which is what scrolling is for,
 * and each moment of the loop lands on its own instead of competing with two
 * neighbours.
 */
.story { display: grid; gap: clamp(72px, 9vw, 132px); margin-top: clamp(56px, 7vw, 92px); }
.beat {
  display: grid; grid-template-columns: 1fr 1fr;
  gap: clamp(36px, 6vw, 96px); align-items: center;
}
.beat:nth-child(even) .beat-art { order: 2; }
.beat-art { position: relative; display: flex; justify-content: center; }
/* A wash so the device sits in the page rather than on it. */
.beat-art::before {
  content: ""; position: absolute; inset: 6% 4%;
  background: radial-gradient(58% 62% at 50% 46%, rgba(0, 105, 62, 0.11), transparent 72%);
  filter: blur(18px); pointer-events: none;
}
.beat-art .phone {
  position: relative; max-width: 340px; width: 100%;
  border-radius: 46px; padding: 10px;
  box-shadow: 0 44px 96px rgba(16,20,19,0.19), 0 4px 14px rgba(16,20,19,0.09);
}
.beat-art .phone img { border-radius: 37px; }
.beat-art .phone::after { top: 22px; width: 86px; height: 25px; }

.beat-copy .step {
  display: inline-flex; align-items: center; gap: 9px;
  font-size: 11.5px; font-weight: 700; letter-spacing: 0.13em;
  text-transform: uppercase; color: var(--primary);
  margin: 0 0 18px;
}
.beat-copy .step i {
  font-style: normal; width: 26px; height: 26px; border-radius: 999px;
  background: var(--primary-tint); display: grid; place-items: center;
  font-size: 12px; letter-spacing: 0;
}
.beat-copy h3 { font-size: clamp(24px, 3.1vw, 34px); line-height: 1.14; letter-spacing: -0.03em; font-weight: 700; margin: 0 0 14px; max-width: 17ch; }
.beat-copy p { font-size: 17.5px; line-height: 1.55; color: var(--ink-2); max-width: 44ch; margin: 0; }
section.ink .beat-copy h3 { color: var(--bg); }
section.ink .beat-copy p { color: rgba(247,246,242,0.7); }
section.ink .beat-copy .step { color: #6BE3A6; }
section.ink .beat-copy .step i { background: rgba(107,227,166,0.15); }
section.ink .beat-art::before { background: radial-gradient(58% 62% at 50% 46%, rgba(107,227,166,0.14), transparent 72%); }

@media (max-width: 820px) {
  .beat { grid-template-columns: 1fr; gap: 32px; }
  .beat:nth-child(even) .beat-art { order: 0; }
  .beat-art .phone { max-width: 300px; }
}

/* ── Reveal on scroll ────────────────────────────────────────────────
 *
 * Sequenced left to right so the eye is walked through the loop in the order
 * it happens, rather than everything appearing at once and leaving the visitor
 * to work out the order themselves. Small distances and short durations: this
 * is meant to direct attention, not to be noticed.
 *
 * Anything not revealed stays visible if the script never runs — a page that
 * depends on JavaScript to show its content is a page that is blank for
 * whoever it fails on.
 */
@media (prefers-reduced-motion: no-preference) {
  .reveal { opacity: 0; transform: translateY(18px); transition: opacity 0.62s cubic-bezier(0.22, 0.8, 0.3, 1), transform 0.62s cubic-bezier(0.22, 0.8, 0.3, 1); }
  .reveal.in { opacity: 1; transform: none; }
}

/* ── Scroll-driven screens ───────────────────────────────────────────
 *
 * The phone stays put and its SCREEN changes as you scroll — an invoice
 * raised, then part-paid and waiting on a confirmation, then paid and
 * receipted. Scroll drives it rather than a timer, so each beat lands when the
 * reader arrives instead of playing to an empty room.
 *
 * WHY NOT THE EXPLODED-3D TREATMENT everyone else uses: sites selling an
 * abstraction have to invent a visual, because there is nothing to photograph.
 * We have the opposite problem — a real thing on a real screen — and rendering
 * a receipt as a floating translucent panel would make a concrete product look
 * abstract. That is a downgrade dressed as sophistication.
 *
 * No WebGL, no canvas, no library. Three stills and an opacity transition.
 */
.scroller-inner { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(40px, 7vw, 110px); align-items: start; }
.scroller-art {
  position: sticky; top: 92px;
  display: flex; justify-content: center;
  padding: 0;
  /* Bounded so the phone can never be taller than the space it is pinned in.
     A sticky element taller than its viewport slot scrolls out of view, which
     defeats the entire point of pinning it. */
  max-height: calc(100vh - 116px);
}
.scroller-art .phone {
  position: relative; width: min(300px, 100%);
  border-radius: 46px; padding: 10px;
  box-shadow: 0 44px 96px rgba(16,20,19,0.2), 0 4px 14px rgba(16,20,19,0.09);
}
.scroller-art .phone::after { top: 22px; width: 86px; height: 25px; z-index: 3; }
/* The stack. The first is in normal flow so it sets the height; the rest are
   layered over it. Without JavaScript you still see that first screen. */
.scr { border-radius: 37px; transition: opacity 0.5s ease, transform 0.5s ease; }
.scr + .scr { position: absolute; inset: 10px; width: calc(100% - 20px); height: auto; opacity: 0; }
.scr.off { transform: scale(1.015); }
.scr.on { opacity: 1; transform: none; }
.scr.off { opacity: 0; }

/* Tight enough that two steps are never both fully off-screen, loose enough
   that the screen has changed before the next sentence arrives. 74vh left
   voids the size of a paragraph between beats. */
.sstep { min-height: 46vh; display: flex; flex-direction: column; justify-content: center; padding: 3vh 0; }
.sstep:first-child { padding-top: 0; }
.sstep:last-child { min-height: 62vh; }
/* The rail. Three marks, filled as you pass them — the only thing on the page
   that says how much of this section is left, which is the question a reader
   asks before deciding to keep going. */
.scroller-steps { position: relative; padding-left: 34px; }
.scroller-steps::before {
  content: ""; position: absolute; left: 5px; top: 12%; bottom: 12%;
  width: 2px; background: var(--border);
}
.sstep::before {
  content: ""; position: absolute; left: -34px; top: 50%; width: 11px; height: 11px;
  margin-top: -5px; border-radius: 999px; background: var(--border-strong);
  transition: background 0.32s ease, transform 0.32s ease;
}
.sstep { position: relative; }
.sstep.on::before { background: var(--primary); transform: scale(1.4); }
section.ink .scroller-steps::before { background: rgba(255,255,255,0.14); }
section.ink .sstep::before { background: rgba(255,255,255,0.24); }
section.ink .sstep.on::before { background: #6BE3A6; }
.sstep .step { display: inline-flex; align-items: center; gap: 9px; font-size: 11.5px; font-weight: 700; letter-spacing: 0.13em; text-transform: uppercase; color: var(--primary); margin: 0 0 18px; }
.sstep .step i { font-style: normal; width: 26px; height: 26px; border-radius: 999px; background: var(--primary-tint); display: grid; place-items: center; font-size: 12px; letter-spacing: 0; }
.sstep h3 { font-size: clamp(24px, 3.2vw, 36px); line-height: 1.12; letter-spacing: -0.03em; font-weight: 700; margin: 0 0 14px; max-width: 17ch; }
.sstep p { font-size: 17.5px; line-height: 1.55; color: var(--ink-2); max-width: 44ch; margin: 0; }
/* Dim the ones you are not on, so the eye knows which screen it is reading. */
@media (prefers-reduced-motion: no-preference) {
  .sstep { opacity: 0.32; transition: opacity 0.45s ease; }
  .sstep.on { opacity: 1; }
}
section.ink .sstep h3 { color: var(--bg); }
section.ink .sstep p { color: rgba(247,246,242,0.7); }
section.ink .sstep .step { color: #6BE3A6; }
section.ink .sstep .step i { background: rgba(107,227,166,0.15); }

@media (max-width: 900px) {
  /* KEEP IT PINNED ON A PHONE — do not stack three mockups.
   *
   * Stacking put 1,950px of device imagery in front of 121 words, and showing
   * somebody three pictures of a phone while they are holding one is the least
   * useful thing on the page. Sticky works on mobile, so the device pins at
   * the top and its screen changes as the copy scrolls beneath it — the same
   * interaction, and it costs one device instead of three.
   */
  .scroller-inner { grid-template-columns: 1fr; gap: 0; }
  .scroller-steps { padding-left: 0; }
  .scroller-steps::before, .sstep::before { display: none; }
  .scroller-art {
    position: sticky; top: 70px; z-index: 2;
    max-height: none; padding: 12px 0 18px;
    /* SOLID, and full-bleed. A gradient let the copy show through beneath the
       device, which is worse than stacking — the headline was legible THROUGH
       a phone. A pinned band has to actually be a band. */
    background: var(--bg);
    margin-inline: -24px; padding-inline: 24px;
    box-shadow: 0 10px 18px -12px rgba(16,20,19,0.25);
  }
  section.tint .scroller-art { background: var(--surface); }
  section.ink .scroller-art { background: var(--invert); }
  .scroller-art .phone { width: min(190px, 48vw); border-radius: 30px; padding: 6px; }
  .scroller-art .phone img { border-radius: 25px; }
  .scroller-art .phone::after { top: 13px; width: 54px; height: 16px; }
  .scr + .scr { inset: 6px; width: calc(100% - 12px); }
  .sstep { min-height: 42vh; margin: 0; padding: 2vh 0; justify-content: center; }
  .sstep:last-child { min-height: 46vh; }
  .sstep h3 { font-size: 26px; }
  .sstep p { font-size: 16.5px; }
}


/* ── The hero's product shot ─────────────────────────────────────────
 *
 * Everyone sees the hero; a fraction scroll the whole page. It carried a
 * headline, a paragraph and two text cards — all assertion, nothing a visitor
 * could check. The dashboard goes here because it is the fastest way to answer
 * "is this a real thing", and it answers it before anyone has to decide
 * whether to keep reading.
 *
 * It sits BELOW the two doors' explanation and above them in the DOM order the
 * eye actually uses: headline, proof, then choose your side.
 */
/* A PHONE, NOT A LAPTOP. Flash is mobile-first and this page speaks to a
   shopper and a shopkeeper at once; a desktop dashboard tells both of them
   this is desk software they will need a computer for. The laptop belongs on
   /business, where "runs in a browser on the machine you already have" is the
   actual claim being made. */
.hero-art { margin: clamp(40px, 5vw, 64px) auto 0; display: flex; justify-content: center; }
.hero-art .phone {
  width: min(304px, 78vw);
  border-radius: 46px; padding: 10px;
  box-shadow: 0 50px 110px rgba(16,20,19,0.2), 0 4px 14px rgba(16,20,19,0.09);
}
.hero-art .phone img { border-radius: 37px; }
.hero-art .phone::after { top: 22px; width: 86px; height: 25px; }
.hero-art + .doors { margin-top: clamp(48px, 6vw, 76px); }
