/* ===== VB24 Business — case study =====

   TRANSFERRED FROM FIGMA — file uMdjtaYVvRQFWSeG1yAV6v, page Cases,
   frame `VB24 Business App` node 37:170, 1440 x 19215. Sections are that
   frame's direct children (`Section · …`), read top to bottom; each <section>
   below carries the node id it came from in data-figma.

   THE CASE HAS ITS OWN STYLE, NOT THE SITE'S. Every colour, size and gap
   below is a --vb24-* custom property declared on `.case-vb24` (measure tokens
   also on `.vb24-topbar`, which is a sibling of the article), so
   css/base/tokens.css and the shared sheets stay untouched and this page
   cannot leak into them. The SHELL around the case — the sticky topbar and the
   nav dock — is the site's and stays themed, exactly as the other cases do it.

   DARK ONLY, by design: the Figma board is drawn on #232232 and the whole
   palette is built against it. No [data-theme] hooks anywhere in here.

   ── Typography differs from the PetLand case on purpose ──
   The VB24 brief sets the case in INTER (not SF Pro): "Шрифт текстов кейса —
   Inter. SF Pro не подключать." So --vb24-font leads with the self-hosted
   Inter the site already ships and never names a system SF face ahead of it.

   ── Variable dictionary (token → value → where in Figma 37:170) ──
     --vb24-bg            #232232  board ground (rendered frame fill)
     --vb24-surface       #2f2e3e  cards / plates / placeholders on the board
     --vb24-ink           #ffffff  primary text (titles, statements)
     --vb24-ink-soft      #555466  section-title LEAD word; divider base colour
     --vb24-ink-body      #a9a8bb  body paragraphs, Next descriptions (Reg 20)
     --vb24-list-label    #9a99ad  Next list labels (caps, SemiBold 14, +8%)
     --vb24-content       1040px   centred content slot (frame 1440, 200 sides)
     --vb24-pad-side      200px     frame side padding (1440 → 1040)  [≥1280]
     --vb24-pad-top       160px    section top padding (Figma auto-layout)
     --vb24-stack-gap     64px     gap inside a section's vertical stack
     --vb24-divider       rgb(85 84 102 / .25)  1px top rule between sections
     --vb24-list-rule     rgb(85 84 102 / .5)   Next list row rules
     --vb24-phone-radius  20px     phone mockup corner radius
     --vb24-title-size    46px     section title (Inter Bold)
*/

/* Inter, self-hosted. Same two faces (and the same SIL OFL 1.1 reasoning) as
   the other case pages: the site makes no third-party requests, and the
   variable file covers every weight in one download per subset. Here Inter is
   the PRIMARY face, not a fallback — see the note above. */
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("../../assets/fonts/inter-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
                 U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("../../assets/fonts/inter-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
                 U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF,
                 U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* ============================================================ tokens == */
/* Declared on BOTH the case and the topbar: the sticky bar is a SIBLING of
   the article, so a token scoped to the article alone does not reach it and
   `max-width: calc(var(--vb24-content) + …)` would be invalid there — the
   same trap the PetLand case documents on .pl-topbar. */
:where(.case-vb24, .vb24-topbar) {
  --vb24-content: 1040px;
  --vb24-gutter: 24px;
}

.case-vb24 {
  /* --- colour (the shared board palette; the frame paints #232232 and every
     plate sits on it, same ground as the PetLand case off the same file) --- */
  --vb24-bg:            #232232;
  --vb24-surface:       #2f2e3e;
  --vb24-ink:           #ffffff;
  --vb24-ink-soft:      #555466;   /* section-title lead word + divider base */
  --vb24-ink-body:      #a9a8bb;   /* body copy, Next descriptions */
  --vb24-list-label:    #9a99ad;   /* Next list labels */
  --vb24-ink-on-plate:  #9695aa;   /* type set ON a #2f2e3e plate */
  --vb24-divider:       rgb(85 84 102 / .25);
  --vb24-list-rule:     rgb(85 84 102 / .5);
  --vb24-plate-rule:    rgb(255 255 255 / .1);  /* hairline on a plate */
  --vb24-cursor-accent: #9747ff;   /* FigJam accent: stamp, cursor, tag */

  /* --- type --- */
  --vb24-font: "Inter", system-ui, "Segoe UI", Roboto, sans-serif;
  --vb24-lh: 1.2;
  --vb24-title-size: 46px;
  --vb24-title-lh: 1.15;

  /* --- measure / rhythm (Figma auto-layout on the section frames) --- */
  --vb24-pad-side: 200px;    /* 1440 → 1040; realised as the centred container */
  --vb24-pad-top: 160px;     /* section top padding */
  --vb24-stack-gap: 64px;    /* gap inside a section's vertical stack */

  /* --- shapes --- */
  --vb24-phone-radius: 20px;

  /* --- responsive knobs (no mobile mockups exist; these are set here, not in
     Figma, and every choice is recorded in VB24_BUILD_LOG.md) --- */
  --vb24-bp-tablet: 768px;
  --vb24-bp-mobile: 390px;

  position: relative;
  z-index: var(--z-content);
  background: var(--vb24-bg);
  color: var(--vb24-ink);
  font-family: var(--vb24-font);
  line-height: var(--vb24-lh);
  -webkit-font-smoothing: antialiased;
  /* Clearance for the fixed nav dock, same run-out the other cases hold. */
  padding-bottom: var(--dock-space);
}

/* typography.css sets `h1,h2,h3 { font-family: var(--font-display) }` (the
   site's Georgia) on the ELEMENT, so headings inside the case would not
   inherit --vb24-font and would come out serif. Put the case face back on
   them explicitly; the board has no serif anywhere. */
.case-vb24 :is(h1, h2, h3, h4) { font-family: var(--vb24-font); }

/* The board's ground runs edge to edge; `.vb24-container` holds content to
   1040 and centres it. */
.vb24-container {
  width: 100%;
  max-width: calc(var(--vb24-content) + var(--vb24-gutter) * 2);
  margin-inline: auto;
  padding-inline: var(--vb24-gutter);
}

/* Shared sticky topbar re-padding — case.css hard-codes its own --case-pad,
   undeclared out here, so zero the horizontal padding and let an inner
   .vb24-container place the row (same fix the other cases use). */
.vb24-topbar { padding: var(--space-4) 0; }
.vb24-topbar__row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
}

/* On the desktop the case header matches the landing page's: no plate, and the
   back link + controls sit at the WINDOW edges (outside the 1040 column), at
   the site header's own inset (--sp-3), so theme/language don't move when you
   go from home to the case. Mobile keeps the shared .case__topbar look. */
@media (min-width: 769px) {
  .vb24-topbar {
    background: none;
    backdrop-filter: none;
    padding: var(--sp-3);            /* 24px — same as .site-header */
    pointer-events: none;            /* empty middle doesn't eat clicks */
  }
  .vb24-topbar .vb24-topbar__row {
    max-width: none;                 /* out of the 1040 column, to the edges */
    padding-inline: 0;
  }
  .vb24-topbar .case__back,
  .vb24-topbar .pill-bar { pointer-events: auto; }
  /* strip the control capsule so the two controls read bare like on home */
  .vb24-topbar .pill-bar {
    background: none;
    box-shadow: none;
    padding: 0;
    gap: var(--space-1);
  }
  .vb24-topbar .pill-bar__btn:hover,
  .vb24-topbar .pill-bar__btn:focus-visible { background: none; }
}

/* ===================================================== section system == */
/* A section is a vertical stack on the 1040 column with SYMMETRIC vertical
   padding (160 top / 160 bottom, Figma), inner gap 64. The divider between
   two sections is the border-top of the section below the line: so
   content→divider is the upper section's 160 bottom padding and
   divider→content is this section's 160 top padding. */
.vb24-section {
  padding-block: var(--vb24-pad-top);
}
.vb24-section__inner {
  display: flex;
  flex-direction: column;
  gap: var(--vb24-stack-gap);
}
/* Divider: FULL-BLEED. The article paints edge to edge, so a border on the
   section itself runs the whole viewport width (100vw) at any window size —
   it is NOT held to the 1040 container. 1px, #555466 @25%.
   No divider above Hero, Key numbers, Challenge (they carry no --ruled). */
.vb24-section--ruled { border-top: 1px solid var(--vb24-divider); }

/* A forced line break that only applies on the wide desktop (≥1200): below
   that the headline wraps freely. (Figma line breaks are a desktop concern;
   on a phone the text should just reflow.) */
@media (max-width: 1199px) { br.desktop-only { display: none; } }

/* ===================================================== section title === */
/* Inter Bold 46, format "Lead. Statement." — the lead word quiet (#555466),
   the rest white. Marked up with a <span class="vb24-lead"> so the split is
   in the HTML, not guessed by CSS. */
.vb24-section__title {
  font-size: var(--vb24-title-size);
  line-height: var(--vb24-title-lh);
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--vb24-ink);
  margin: 0;
  max-width: var(--vb24-content);   /* 1040; line breaks come from <br class="desktop-only"> */
  text-wrap: pretty;
}
.vb24-section__title .vb24-lead { color: var(--vb24-ink-soft); }
/* Some headlines have a forced line wider than 1040 at Bold 46 — those opt out
   of the cap and run past 1040 to the right on purpose (per brief). Only on the
   wide desktop (≥1200): the block shrink-wraps to its widest line so that line
   doesn't wrap, and the gutter absorbs the overflow. Below 1200 the <br>s are
   off and the title wraps freely within the column. */
.vb24-section__title--wide { max-width: none; }
@media (min-width: 1200px) {
  .vb24-section__title--wide { width: max-content; max-width: calc(100vw - var(--vb24-gutter) * 2); }
}

/* A statement set like a title but all-white (no lead word) — e.g. the Audit
   "On mobile the platform layout falls apart" line (638:24737). */
.vb24-statement {
  font-size: var(--vb24-title-size);
  line-height: var(--vb24-title-lh);
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--vb24-ink);
  margin: 0;
  max-width: var(--vb24-content);
}

/* Body copy on the board ground. */
.vb24-prose {
  font-size: 20px;
  line-height: 1.5;
  color: var(--vb24-ink-body);
  max-width: 62ch;
  margin: 0;
}

/* ===================================================== Next-style list == */
/* Label caps Inter SemiBold 14 #9A99AD +8% tracking. Row: term Inter Medium 20
   white in a 320 column + description Regular 20 #A9A8BB. Gap 40, padding 20,
   row rules #555466 50%. */
.vb24-list__label {
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--vb24-list-label);
  margin: 0 0 24px;
}
.vb24-list { display: flex; flex-direction: column; }
.vb24-list__row {
  display: grid;
  grid-template-columns: 320px 1fr;
  gap: 40px;
  padding: 20px 0;
  border-top: 1px solid var(--vb24-list-rule);
}
.vb24-list__row:last-child { border-bottom: 1px solid var(--vb24-list-rule); }
.vb24-list__term {
  font-size: 20px;
  font-weight: 500;
  color: var(--vb24-ink);
  margin: 0;
}
.vb24-list__desc {
  font-size: 20px;
  font-weight: 400;
  color: var(--vb24-ink-body);
  margin: 0;
}

/* ===================================================== media / visuals == */
/* Every raster scales proportionally; the internal layout never reflows. */
.case-vb24 img { max-width: 100%; height: auto; display: block; }
.vb24-figure { margin: 0; }
.vb24-figure--center { display: flex; justify-content: center; }

/* Phone mockups keep the board's 20px radius. */
.vb24-phone { border-radius: var(--vb24-phone-radius); overflow: hidden; }

/* A row of phone screens (Audit / First launch): 4 across on desktop,
   40px between (the board's own spacing). */
.vb24-screens {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 40px;
}
.vb24-screens img { border-radius: var(--vb24-phone-radius); }

/* Wide schemas (Audit IA map, Decision, User flow, Wireflow) are 1040 wide and
   must not reflow. On a narrow screen they get a horizontal scroller with a
   hint rather than shrinking to illegibility. */
.vb24-scroll { position: relative; }
.vb24-scroll__viewport { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.vb24-scroll__viewport > img { max-width: none; width: var(--vb24-content); }
.vb24-scroll__hint {
  display: none;
  font-size: 13px;
  letter-spacing: 0.06em;
  color: var(--vb24-list-label);
  margin-top: 8px;
  text-align: center;
}

/* Video placeholder: a block of the Figma size, board rule ground, centred
   caption. Cristina drops the mp4/webm in later; the <video> markup is ready
   and commented in the HTML. */
.vb24-video-ph {
  position: relative;
  border-radius: var(--vb24-phone-radius);
  background: rgb(85 84 102 / .25);
  display: grid;
  place-items: center;
  overflow: hidden;
}
.vb24-video-ph__label {
  color: var(--vb24-list-label);
  font-size: 15px;
  text-align: center;
  padding: 0 16px;
  line-height: 1.4;
}
/* The <video> sits over the label; empty, it's transparent so the label and
   the #555466/25% ground show. When Cris adds the file it covers them. */
.vb24-video-ph video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }

/* Prototype: a row of four phone-shaped video placeholders (1157:20152). */
.vb24-proto-row {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 54px;
}
.vb24-proto-row .vb24-video-ph { aspect-ratio: 215 / 468; }

/* ===================================================== 11 — ALERTS ======= */
/* Live HTML block (164:140): a phone mockup centred, two glass callouts either
   side. Each callout is EDGE-ALIGNED to the push it describes (See the money's
   bottom = the first banner's bottom; Convert's top = the second banner's top),
   which is how Figma shows which callout is about which push. 1040×558 stage,
   scaled to the column by vb24.js; stacked at ≤480. The phone is a mockup for
   now and can later be swapped for a looping screen recording. */
.vb24-alerts-frame { width: 100%; }
.vb24-alerts-stage {
  position: relative;
  width: 1040px; height: 558px;
  transform-origin: top left;
  font-family: var(--vb24-font);
}
.vb24-alerts__phone { position: absolute; left: 352px; top: 22px; width: 337px; height: auto; }
.vb24-callout {
  position: absolute; box-sizing: border-box;
  background: rgb(255 255 255 / .06);
  border-radius: 16px;
  padding: 16px 20px;
  display: flex; flex-direction: column; gap: 8px;
}
.vb24-callout--see { left: 77.82px; top: 285.75px; width: 300px; }
.vb24-callout--convert { left: 661.82px; top: 409.07px; width: 334px; }
.vb24-callout__title { margin: 0; font-size: 20px; font-weight: 600; color: #fff; }
.vb24-callout__body { margin: 0; font-size: 15px; line-height: 23px; color: rgb(255 255 255 / .8); }

/* ===================================================== 12 — TOKENS ======= */
/* The panels stay an image; the counters (1157:19925) are rebuilt as live
   cards: 4 across, 21 gap, #2f2e3e r17.4, padding 28/20, number SemiBold 72,
   caption Regular 22, centred on both axes. */
.vb24-counters { display: grid; grid-template-columns: repeat(4, 1fr); gap: 21px; }
.vb24-counter {
  background: var(--vb24-surface);
  border-radius: 17.44px;
  padding: 28px 20px;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px;
  text-align: center;
}
.vb24-counter__n { margin: 0; font-size: 72px; font-weight: 600; line-height: 1; color: #fff; }
.vb24-counter__c { margin: 0; font-size: 22px; font-weight: 400; color: #a09fb0; }

/* ============================================================ 01 — HERO = */
/* Board draws the hero full-bleed at 1440: logo at x=303 y=174, title y=263
   (478 wide, two lines), standfirst y=392, meta row y=469, splash phone at
   x=802 y=118 (224x487). Reproduced on the 1040 column: text left, phone
   right. The phone art starts higher than the logo, so the text column is
   nudged down to match (174 - 118 ≈ 56). */
.vb24-hero { padding-top: 56px; }
/* Hero sits on the SAME 844 grid as Key numbers: two equal columns. The text
   fills column 1 (its left edge lands on the plate's left edge below), and the
   phone is centred in column 2 — directly above the "10 → 5" stat. Figma gaps:
   text paddingTop 56, title group → meta 59, logo → headline 28, headline →
   subtitle 19, meta columns 96.5, label → value 4.5. */
.vb24-hero__inner {
  max-width: 844px;
  margin-inline: auto;
  display: grid;
  grid-template-columns: 1fr 1fr;
  align-items: start;
  column-gap: 21px;
}
.vb24-hero__text {
  grid-column: 1;
  display: flex;
  flex-direction: column;
  padding-top: 56px;
}
/* liquid glass, frame 2111:8135; the shadow is here because the file has none */
.vb24-hero__logo { width: 61px; height: 61px; border-radius: 14px; box-shadow: 0 9px 20px -6px rgb(18 48 140 / .65); }
.vb24-hero__title {
  font-size: var(--vb24-title-size);
  line-height: 1.2;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--vb24-ink);
  margin: 28px 0 0;
  /* break ONLY at the explicit <br> (Business Banking / on the go); the first
     line is a hair wider than the 411 column, so let it run into the 21px gap
     rather than wrap to a third line. */
  white-space: nowrap;
}
.vb24-hero__standfirst {
  font-size: 15px;
  color: var(--vb24-ink-body);
  margin: 19px 0 0;
}
.vb24-hero__meta { display: flex; gap: 96.5px; margin: 59px 0 0; }
.vb24-hero__meta div { min-width: 0; }
.vb24-hero__meta dt { font-size: 13px; color: var(--vb24-ink-soft); margin: 0; }
.vb24-hero__meta dd { font-size: 15px; color: var(--vb24-ink); margin: 4.5px 0 0; }
/* 224 on the board; the export carries a little shadow bleed, so ~232 lands
   the phone body at the drawn width. Centred in column 2. */
.vb24-hero__splash { grid-column: 2; justify-self: center; align-self: start; width: 232px; height: auto; border-radius: 0; }

/* ====================================================== 02 — KEY NUMBERS = */
/* A #2f2e3e plate (844 wide, radius 20) centred in the 1040 slot, two stats
   split by a 1px white/10% hairline (58:140). Numbers Inter SemiBold 72 —
   the "before" muted (#9695aa), the "after" white; arrow Inter Bold 44 on
   #555466; caption Inter Regular 22 #9695aa. */
.vb24-keynums__card {
  background: var(--vb24-surface);
  border-radius: 20px;
  display: flex;
  align-items: center;
  max-width: 844px;
  margin-inline: auto;
  padding-inline: 48px;
  min-height: 207px;
}
.vb24-stat {
  flex: 1 0 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
}
.vb24-stat__value {
  display: flex;
  align-items: center;
  gap: 14px;
  margin: 0;
  white-space: nowrap;
  line-height: 1;
}
.vb24-stat__from { font-size: 72px; font-weight: 600; color: var(--vb24-ink-on-plate); }
.vb24-stat__arrow { font-size: 44px; font-weight: 700; color: var(--vb24-ink-soft); }
.vb24-stat__to { font-size: 72px; font-weight: 600; color: var(--vb24-ink); }
.vb24-stat__caption { font-size: 22px; color: var(--vb24-ink-on-plate); margin: 0; }
.vb24-keynums__divider { flex: none; width: 1px; height: 140px; background: var(--vb24-plate-rule); }

/* ====================================================== 03 — CHALLENGE === */
.vb24-challenge .vb24-figure img { width: 100%; max-width: var(--vb24-content); }

/* Next is the last section and has no footer under it — give it a deep bottom
   padding (320, Figma) so the closing statement reads mid-screen rather than
   jammed against the bottom / the nav dock. */
.vb24-next { padding-bottom: 320px; }

/* First launch: the board spaces its four screens 54px apart, not 40. */
.vb24-first .vb24-screens { gap: 54px; }
/* Edge cases: four screens 45px apart. */
.vb24-edge .vb24-screens { gap: 45px; }

/* Before and after: two baked comparison blocks (Home, Exchange), each one
   PNG centred on the column; they scale as a whole on mobile (single
   compositions, same reasoning as the Same-bank block). */
.vb24-ba__block { width: 100%; max-width: var(--vb24-content); margin-inline: auto; }
.vb24-ba__block img { width: 100%; height: auto; display: block; }

/* ============================================ 07 — SAME BANK, FASTER DOOR = */
/* Rebuilt as LIVE HTML/CSS (1182:3744), not a PNG — text stays crisp on retina.
   A fixed 1040×684 stage holds everything at its Figma coordinates; vb24.js
   scales the stage to the column on the desktop/tablet range, and at ≤480 the
   CSS below reflows it into a stacked Before→After column. The Face-ID zone is
   a ready, empty <video> (Cris adds the file). Chips #3b394d, captions/labels
   per Figma; the divider circle sits 90px from the steps and 90px from the
   video (1182:3748). */
.vb24-signin-frame { width: 100%; }
.vb24-signin-stage {
  position: relative;
  width: 1040px;
  height: 684px;
  transform-origin: top left;
  font-family: var(--vb24-font);
}
.vb24-signin__label {
  position: absolute; top: 0; margin: 0;
  font-size: 30px; font-weight: 700; color: var(--vb24-ink-soft); white-space: nowrap;
}
.vb24-signin__label--before { left: 213px; }
.vb24-signin__label--after  { left: 730px; }
.vb24-signin__steps {
  position: absolute; left: 90px; top: 140px;
  display: flex; flex-direction: column; align-items: center; gap: 6px;
}
.vb24-step {
  box-sizing: border-box; width: 340px;
  display: flex; align-items: center; gap: 12px;
  background: #3b394d; border-radius: 14px; padding: 14px 16px;
}
.vb24-step__n { margin: 0; font-size: 16px; font-weight: 700; color: #8c91a3; }
.vb24-step__t { margin: 0; font-size: 17px; font-weight: 700; color: #fff; }
.vb24-signin__down { margin: 0; font-size: 18px; font-weight: 700; line-height: 1; color: #8c91a3; }
.vb24-signin__divider { position: absolute; left: 520px; top: 296.84px; width: 44px; height: 44px; }
.vb24-signin__divider svg { display: block; width: 44px; height: 44px; max-width: none; }
.vb24-signin__video {
  position: absolute; left: 654px; top: 78.39px; width: 228px; height: 496px;
  background: #3b394d; border: 1.5px dashed #6b6b80; border-radius: 28px;
  overflow: hidden; display: grid; place-items: center;
}
.vb24-signin__video video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.vb24-signin__video-label { color: #8c91a3; font-size: 15px; font-weight: 700; text-align: center; line-height: 1.35; padding: 0 12px; }
.vb24-signin__cap {
  position: absolute; top: 594px; margin: 0;
  font-size: 18px; font-weight: 700; color: #8c91a3; white-space: nowrap;
}
.vb24-signin__cap--before { left: 110.5px; }
.vb24-signin__cap--after  { left: 700.5px; }

/* ============================================ 05 — HYPOTHESES / BOARD ==== */
/* A FigJam board rebuilt in HTML/CSS (642:24975), 1040.5 × 470.7 on #2f2e3e,
   radius 16.26. Stickers absolutely placed with their board rotations; dot
   grid is a CSS radial-gradient (dots #59586E, 20px step, from 647:3529).
   The cursor + tag drift slowly (vb24.js); hover tilts a sticker. Both off
   under prefers-reduced-motion. No sound/haptic here. */
.vb24-board-frame { width: 100%; }
.vb24-board {
  position: relative;
  width: 1040.5px;
  height: 470.7px;
  transform-origin: top left;   /* vb24.js scales this to the container */
  background: var(--vb24-surface);
  border-radius: 16.26px;
  overflow: hidden;
  font-family: var(--vb24-font);
}
.vb24-board__dots {
  position: absolute;
  inset: 20px 18.5px 8.5px 20px;          /* 1022 × 442 window */
  background-image: radial-gradient(#59586e 1px, transparent 1.6px);
  background-size: 20px 20px;
  pointer-events: none;
}

/* sticky wrappers reproduce Figma's "centre a rotated note in a box" */
.vb24-sticky-wrap, .vb24-stamp-wrap, .vb24-note-wrap {
  position: absolute;
  display: flex;
  align-items: center;
  justify-content: center;
}
.vb24-sticky {
  box-sizing: border-box;
  width: 290.2px;
  height: 290.2px;
  padding: 22.76px;
  border-radius: 2px;
  box-shadow: 0 4.88px 11.38px rgb(0 0 0 / .22);
  display: flex;
  flex-direction: column;
  gap: 11.38px;
  overflow: clip;
  color: #1e1e1e;
  transform: rotate(var(--rot));
  transition: transform .2s ease-out;
}
@media (hover: hover) {
  .vb24-sticky:hover { transform: rotate(var(--rot-h)) scale(1.02); }
}
.vb24-sticky--1 { background: #ffe58f; --rot: 2.5deg;  --rot-h: 4.5deg; }
.vb24-sticky--2 { background: #b8f0c4; --rot: -1deg;   --rot-h: -3deg; }
.vb24-sticky--3 { background: #bfe0ff; --rot: 1.5deg;  --rot-h: 4deg; }
.vb24-sticky__label {
  margin: 0;
  font-size: 9.76px;
  font-weight: 600;
  letter-spacing: .78px;
  color: rgb(30 30 30 / .55);
  white-space: nowrap;
}
.vb24-sticky__body {
  margin: 0;
  font-size: 14.63px;
  line-height: 21.14px;
  color: #1e1e1e;
}
.vb24-sticky__body b { font-weight: 700; }
.vb24-sticky__body .med { font-weight: 500; }
.vb24-sticky__sign {
  margin: auto 0 0;           /* spacer: pin to the bottom */
  font-size: 11px;
  color: rgb(30 30 30 / .45);
}

.vb24-stamp-wrap { width: 35.81px; height: 30.28px; }
.vb24-stamp {
  transform: rotate(8deg);
  background: #fff;
  border: 1.63px solid var(--vb24-cursor-accent);
  border-radius: 81px;
  padding: 4.88px 8.13px;
}
.vb24-stamp span { font-size: 10.57px; font-weight: 700; color: var(--vb24-cursor-accent); }

.vb24-note-wrap { width: 174.75px; height: 58.77px; }
.vb24-note {
  transform: rotate(-2deg);
  background: #3e3d52;
  border-radius: 3.25px;
  padding: 11.38px 13px;
  box-shadow: 0 2px 6px rgb(0 0 0 / .12);
}
.vb24-note p { margin: 0; font-size: 10.57px; font-weight: 500; line-height: 14.63px; color: #a9a8ba; white-space: nowrap; }

/* 46 × 38 is the arrow and tag together. The children are absolute, so the box
   would be 0 × 0, and shy-cards.js measures the cursor's distance from this box. */
.vb24-cursor-group { position: absolute; left: 961.65px; top: 324.34px; width: 46px; height: 38px; z-index: 3; pointer-events: none; }
/* The shared reset gives every svg `max-width:100%`, but .vb24-cursor-group is
   an absolute, zero-width box, so that resolved to max-width:0 and collapsed
   the arrow's width. Opt out and size it explicitly (642:24991, 13.8 × 20.3). */
.vb24-cursor-group .vb24-cursor-arrow { position: absolute; left: 0; top: 0; width: 13.8px; height: 20.3px; max-width: none; display: block; }
.vb24-cursor-group .vb24-cursor-tag {
  position: absolute;
  left: 11.4px;                      /* +11.4 / +19.5 from the arrow (642:24992) */
  top: 19.5px;
  background: var(--vb24-cursor-accent);
  border-radius: 4.9px;
  padding: 3.25px 6.5px;
  display: flex; align-items: center; justify-content: center;
}
.vb24-cursor-group .vb24-cursor-tag span { font-size: 9.76px; font-weight: 600; color: #fff; white-space: nowrap; }

/* ========================================================= responsive == */
/* ≥1280 — as in Figma (the base styles above). */

/* 160/160 holds down to 1200 (the desktop line-break boundary); below that
   the padding eases. */
@media (max-width: 1199px) {
  .case-vb24 { --vb24-pad-top: 112px; --vb24-stack-gap: 48px; }
}

/* 768 — content fills the width with 40px fields, titles ~36, padding eased. */
@media (max-width: 768px) {
  :where(.case-vb24, .vb24-topbar) { --vb24-gutter: 40px; }
  .case-vb24 {
    --vb24-title-size: 36px;
    --vb24-pad-top: 96px;
    --vb24-stack-gap: 40px;
  }
  .vb24-list__row { grid-template-columns: 200px 1fr; gap: 24px; }
  .vb24-scroll__viewport > img { width: var(--vb24-content); }
  .vb24-scroll__hint { display: block; }
  /* Hero stacks: text first, then the phone, left-aligned. */
  .vb24-hero__inner { grid-template-columns: 1fr; max-width: none; row-gap: 40px; }
  .vb24-hero__text { padding-top: 0; }
  .vb24-hero__splash { grid-column: 1; justify-self: start; }
  /* Key numbers: ease the figures so two columns still fit the plate. */
  .vb24-keynums__card { padding-inline: 32px; }
  .vb24-stat__from, .vb24-stat__to { font-size: 60px; }
  .vb24-stat__arrow { font-size: 36px; }
}

/* 390 — 20px fields, titles ~28, four-screen rows become 2×2. */
@media (max-width: 480px) {
  :where(.case-vb24, .vb24-topbar) { --vb24-gutter: 20px; }
  .case-vb24 {
    --vb24-title-size: 28px;
    --vb24-pad-top: 72px;
    --vb24-stack-gap: 32px;
  }
  .vb24-screens { grid-template-columns: repeat(2, 1fr); }
  .vb24-proto-row { grid-template-columns: repeat(2, 1fr); gap: 24px; }
  .vb24-counters { grid-template-columns: repeat(2, 1fr); gap: 16px; }
  .vb24-counter__n { font-size: 56px; }
  .vb24-list__row { grid-template-columns: 1fr; gap: 6px; }
  /* Key numbers stack; the hairline turns horizontal (no mobile mock — logged). */
  .vb24-keynums__card { flex-direction: column; gap: 28px; padding: 32px 24px; max-width: 100%; }
  .vb24-keynums__divider { width: 140px; height: 1px; }
  .vb24-stat__from, .vb24-stat__to { font-size: 56px; }

  /* Board stacks: stickers in a column (keeping their angles) on the dotted
     ground; stamp/note/cursor fall to the end. No scaling, no drift (logged). */
  .vb24-board {
    width: 100%;
    height: auto;
    transform: none !important;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 28px;
    padding: 32px 20px;
  }
  .vb24-sticky-wrap, .vb24-stamp-wrap, .vb24-note-wrap { position: static; }
  .vb24-sticky { width: min(290px, 100%); height: auto; min-height: 210px; }
  .vb24-stamp-wrap, .vb24-note-wrap { align-self: flex-end; }
  .vb24-cursor-group { position: static; align-self: flex-end; width: 0; height: 0; transform: none !important; will-change: auto; }
  .vb24-board__dots { inset: 0; }

  /* Same bank: Before over After. The stage flows as a column; the divider
     circle turns to point down. */
  .vb24-signin-stage {
    position: static; width: 100%; height: auto !important;
    transform: none !important;
    display: flex; flex-direction: column; align-items: center; gap: 16px;
  }
  .vb24-signin__backdrop { display: none; }
  .vb24-signin__label, .vb24-signin__steps, .vb24-signin__cap,
  .vb24-signin__divider, .vb24-signin__video { position: static; left: auto; top: auto; }
  .vb24-signin__label { font-size: 24px; align-self: center; }
  .vb24-signin__divider { transform: rotate(90deg); }
  .vb24-step { width: min(340px, 100%); }

  /* Alerts: phone on top, callouts stacked under it. */
  .vb24-alerts-stage {
    position: static; width: 100%; height: auto !important;
    transform: none !important;
    display: flex; flex-direction: column; align-items: center; gap: 20px;
  }
  .vb24-alerts__phone, .vb24-callout { position: static; left: auto; top: auto; }
  .vb24-alerts__phone { width: min(260px, 72%); }
  .vb24-callout { width: min(334px, 100%); }
}
