/* css/about-mobile.css
   Scope: about.html, MOBILE ONLY (<= 991.98px).

   The desktop composition (`.vca-legacy` nodes: <main class="vc-about">, the
   divider after it and the `about-3` section) is untouched above 992px; below it
   the legacy nodes are hidden and the seven mobile chapters (`.vca-m`) take
   over. Nothing in this file applies at desktop widths, so including it globally
   is safe.

   One quiet vertical page, not a deck: ordinary native scrolling, one header at
   the top of the document, seven chapters of natural height separated by a
   hairline. Each chapter closes with a compact visual accent — the same finished
   artwork the desktop uses, scaled by the block's height and anchored right so
   the empty left third of the frame is cropped away and no face, phone or card
   is ever cut. Nothing here is full-bleed and nothing uses `cover`.
*/

/* The mobile chapters and the theme switch never exist on desktop. */
.vca-m,
.vcp-themeswitch {
  display: none;
}

@media (max-width: 991.98px) {

  /* ---------------------------------------------------------------- */
  /* Desktop composition off, mobile chapters on                       */
  /* ---------------------------------------------------------------- */

  .vca-legacy {
    display: none !important;
  }

  /* ---------------------------------------------------------------- */
  /* Tokens                                                            */
  /* ---------------------------------------------------------------- */

  .vca-m {
    --vca-red: #e8353b;          /* ViewChat coral red — accent lines, eyebrow */
    --vca-ink: #0c0c10;          /* headline black */
    --vca-body: #5c5c66;         /* body copy */
    --vca-muted: #8b8b95;        /* captions */
    --vca-line: rgba(12, 12, 16, 0.08);
    --vca-line-soft: rgba(12, 12, 16, 0.05);
    --vca-shadow: 0 8px 26px rgba(12, 12, 16, 0.06);
    --vca-page: #ffffff;         /* page ground */
    --vca-surface: #ffffff;      /* panels sitting on it */
    --vca-radius: 22px;
    --vca-pad: 22px;
    --vca-stage-pb: 38px;        /* the air a chapter keeps under itself */

    /* How a visual arrives.

       Not a short handover and not a white haze laid over a finished picture:
       the image itself rises out of the chapter's ground. It starts at
       effectively nothing at the top edge of the block, stays barely a texture
       for the first stretch, gains presence through the middle, and is at full
       strength well before the block's half-way mark — from there down the
       artwork is dense, contrasty and untouched.

       The curve matters as much as the length. A straight ramp reads as a
       band with two visible edges; these stops are an eased S — almost flat
       for the first fifth, steepest in the middle, flattening again as they
       land — so neither end of the fade has an edge to see. Alpha is carried
       on black stops only, so the gradient never shifts hue as it thins.

       Stated in pixels, not percentages: a percentage is read against the
       block it masks and would mean one distance on a 304px photograph and
       another on a 484px gallery. Pixels also make the figure identical in
       both themes and at every phone width — a mask reveals whatever is
       behind it, so only the ground changes.

       120px on a 304px visual: at a 390px viewport the artwork is fully
       readable from roughly its top 40% down, which is where the faces,
       phones and laptops sit. */
    --vcam-veil-len: clamp(70px, 21.8vw, 95px);
    --vcam-veil: linear-gradient(
      to bottom,
      rgba(0, 0, 0, 0) 0,
      rgba(0, 0, 0, 0.04) calc(var(--vcam-veil-len) * 0.21),
      rgba(0, 0, 0, 0.12) calc(var(--vcam-veil-len) * 0.29),
      rgba(0, 0, 0, 0.34) calc(var(--vcam-veil-len) * 0.45),
      rgba(0, 0, 0, 0.62) calc(var(--vcam-veil-len) * 0.62),
      rgba(0, 0, 0, 0.85) calc(var(--vcam-veil-len) * 0.80),
      rgba(0, 0, 0, 1) var(--vcam-veil-len)
    );


    /* The map is the one case the veil has to give way to the artwork, and it
       is the only visual the veil must not touch past its first pixels: the
       coral arcs, the nodes and the portrait pins ARE the picture, and a veil
       over them is a loss of contrast, not an arrival.

       So the curve is measured off the asset instead of chosen. Both files are
       transparent above the scene; the first opaque pixel is image row 44
       (light) / 42 (dark), and the img is drawn at 108% of a 390px viewport,
       i.e. 421px across a 1536px source — row 44 lands 12.1px into the block.
       The same eased shape therefore runs over 12px and is done before the
       topmost portrait pin starts. Between 360px and 430px that boundary moves
       only ~11.2–13.3px, so 12px stays clear of the pin at every phone width.

       There is no closing fade any more. The artwork ends 22px (light) / 11px
       (dark) above the foot of the block and its own alpha thins out there, so
       the map meets the page on its own; the old 28px tail bought nothing in
       light and dimmed the southern arcs and the bottom pins in dark, where
       coral runs to 270px of a 281px block. */
    --vcam-veil-map: linear-gradient(
      to bottom,
      rgba(0, 0, 0, 0) 0,
      rgba(0, 0, 0, 0.04) 2px,
      rgba(0, 0, 0, 0.16) 4px,
      rgba(0, 0, 0, 0.38) 6px,
      rgba(0, 0, 0, 0.62) 8px,
      rgba(0, 0, 0, 0.84) 10px,
      rgba(0, 0, 0, 1) 12px
    );

    /* The visual window: full-bleed width, and a height that keeps its own
       aspect at 1:0.78 so the crop maths below stay the same at every phone
       width. --vcam-art is how tall the artwork is drawn inside it. */
    --vcam-h: clamp(270px, 78vw, 340px);

    /* chapter 07's 2x2: one cell wide enough for one portrait card, so the
       artwork is drawn at the scale that makes a card fill a cell */
    --vcam-cell-w: calc((min(100vw, 560px) - 8px) / 2);
    --vcam-cell-art: calc(var(--vcam-cell-w) / 0.3046);
    --vcam-cell-h: clamp(200px, 61vw, 260px);
    /* just enough to read as four deliberate frames rather than four cropped
       fragments of a background — not a card corner */
    --vcam-cell-radius: 9px;

    display: block;
    background: var(--vca-page);
    /* .wsmobileheader is fixed and 80px tall on every mobile breakpoint */
    padding-top: 80px;
    overflow-x: hidden;
  }

  /* ---------------------------------------------------------------- */
  /* Chapter shell                                                     */
  /* ---------------------------------------------------------------- */

  .vca-m__stage {
    padding: 46px 0 var(--vca-stage-pb);
  }

  /* the first chapter opens under the fixed header */
  .vca-m__stage:first-child {
    padding-top: 34px;
  }

  .vca-m__in {
    padding-left: var(--vca-pad);
    padding-right: var(--vca-pad);
  }

  /* ---------------------------------------------------------------- */
  /* Typography                                                        */
  /* ---------------------------------------------------------------- */

  .vca-m__eyebrow {
    margin: 0 0 16px;
    font-family: 'Inter', 'Helvetica Neue', Helvetica, Arial, sans-serif;
    font-size: 11px;
    font-weight: 700;
    line-height: 1.2;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--vca-red);
  }

  .vca-m__title {
    margin: 0;
    font-family: 'Plus Jakarta Sans', 'Inter', Helvetica, Arial, sans-serif;
    font-size: clamp(30px, 8.2vw, 34px);
    font-weight: 700;
    line-height: 1.22;
    letter-spacing: -0.015em;
    text-transform: uppercase;
    text-wrap: balance;
    /* a few locales carry single words longer than a phone column (Russian
       chapter 03), so they hyphenate rather than run past the edge */
    hyphens: auto;
    overflow-wrap: break-word;
    color: var(--vca-ink);
  }

  .vca-m__title .vca-m__hl {
    color: var(--vca-red);
  }

  .vca-m__lead {
    margin: 22px 0 0;
  }

  .vca-m__lead p {
    margin: 0 0 12px;
    font-family: 'Inter', 'Helvetica Neue', Helvetica, Arial, sans-serif;
    font-size: 15.5px;
    font-weight: 400;
    line-height: 1.6;
    color: var(--vca-body);
  }

  .vca-m__lead p:last-child {
    margin-bottom: 0;
  }

  /* ---------------------------------------------------------------- */
  /* The visual half of a chapter                                      */
  /*                                                                   */
  /* A chapter is one tall composition: copy and real feature content   */
  /* on top, then a large cropped photograph filling the foot of it,    */
  /* edge to edge. Not a thumbnail after the text.                      */
  /*                                                                   */
  /* The artwork is wide (16:9) with an empty left third meant for      */
  /* desktop copy; on a phone that third is cropped away instead of     */
  /* shown. The block is a window: the artwork is drawn taller than the */
  /* window (--vcam-art), so the window shows a slice of it, and        */
  /* --vcam-fh is what fraction of the artwork's height that slice is.  */
  /* Because the window's own aspect is fixed by --vcam-h (78vw), the   */
  /* slice's horizontal reach follows from it:                          */
  /*     visible width = 0.716 x --vcam-fh  of the artwork              */
  /* so fh 0.80 starts the crop at 43% of the frame, fh 0.84 at 40%.    */
  /* The vertical anchor is picked per chapter so no face, phone,       */
  /* laptop or card is cut.                                             */
  /*                                                                   */
  /* Identical in both themes — dark mode changes tokens, never this.   */
  /* ---------------------------------------------------------------- */

  /* Full width, no frame of any kind, and no top edge: the mask hands the
     first 42% of the block back to the page, so the photograph appears out of
     the chapter's own background instead of on top of it. The mask reveals
     whatever is behind — the light ground in one theme and the near-black in
     the other — so this needs no colour of its own and cannot fall out of step
     with a theme.

     The block keeps its height and is pulled down over the chapter's bottom
     padding, so it runs to the foot of the chapter. Keeping the height is what
     keeps every crop below exactly as it was authored: the visible fraction of
     the artwork is width / (1.79104 x height) and neither has changed. */
  .vca-m__visual {
    margin: 30px calc(-1 * var(--vca-pad)) calc(-1 * var(--vca-stage-pb));
    height: var(--vcam-h);
    overflow: hidden;
    -webkit-mask-image: var(--vcam-veil);
    mask-image: var(--vcam-veil);
    background-repeat: no-repeat;
    /* resolved here, so each chapter's own --vcam-fh feeds it */
    background-size: auto calc(var(--vcam-h) / var(--vcam-fh, 0.84));
    background-position: var(--vcam-pos);
    background-image: var(--vcam-img);
  }

  /* Chapters 02–07 alone break out of the content measure. Their visuals
     touch the viewport edges and the foot of their own chapter; chapter 01
     deliberately keeps its approved composition unchanged. */
  #vcaMStage2 .vca-m__visual,
  #vcaMStage3 .vca-m__visual,
  #vcaMStage4 .vca-m__map,
  #vcaMStage5 .vca-m__visual,
  #vcaMStage6 .vca-m__visual,
  #vcaMStage7 .vca-m__collage {
    width: 100vw;
    max-width: 100vw;
    margin-inline: calc(50% - 50vw);
  }

  /* ---------------------------------------------------------------- */
  /* Chapter 01 — social proof, between the copy and the picture       */
  /*                                                                   */
  /* Two light objects in the ordinary content column, not a card and   */
  /* not a banner: a row of faces with a + after it, and one small chip */
  /* under it. Nothing here has a border or a panel behind it, and both */
  /* sit above the picture in the flow, so neither can overlap the copy */
  /* or the visual.                                                     */
  /* ---------------------------------------------------------------- */

  .vca-m__proof {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 14px;
    margin-top: 26px;
  }

  .vca-m__proof-people {
    display: flex;
    align-items: center;
    gap: 8px;
  }

  /* The five rings are one file with its own overlap and its own soft glow,
     so the height is what is set and the width follows the artwork. 46px is
     the ring diameter the file was drawn at. */
  .vca-m__proof-faces {
    display: block;
    height: 46px;
    width: auto;
  }

  /* the + is a mark, not a control: no href, no handler, aria-hidden with the
     rest of the block */
  .vca-m__proof-more {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 29px;
    height: 29px;
    border-radius: 50%;
    background: var(--vca-surface);
    box-shadow: 0 2px 8px rgba(12, 12, 16, 0.10),
                0 0 0 1px var(--vca-line-soft);
    font-family: 'Plus Jakarta Sans', 'Inter', Helvetica, Arial, sans-serif;
    font-size: 16px;
    font-weight: 600;
    line-height: 1;
    color: var(--vca-ink);
  }

  .vca-m__proof-stat {
    display: flex;
    align-items: center;
    gap: 10px;
    box-sizing: border-box;
    width: 132px;
    height: 61px;
    padding: 0 12px;
    border-radius: 13px;
    background: var(--vca-surface);
    box-shadow: 0 4px 14px rgba(12, 12, 16, 0.08),
                0 0 0 1px var(--vca-line-soft);
  }

  .vca-m__proof-icon {
    flex: 0 0 auto;
    color: var(--vca-red);
  }

  /* outweighs flaticon.css `span[class*=" flaticon-"]:before { font-size: 20px }` */
  .vca-m__proof-icon::before {
    font-size: 22px;
    line-height: 1;
  }

  .vca-m__proof-figures {
    display: block;
    min-width: 0;
  }

  .vca-m__proof-value {
    display: block;
    font-family: 'Plus Jakarta Sans', 'Inter', Helvetica, Arial, sans-serif;
    font-size: 17px;
    font-weight: 700;
    line-height: 1.15;
    letter-spacing: -0.01em;
    color: var(--vca-ink);
  }

  .vca-m__proof-label {
    display: block;
    margin-top: 2px;
    overflow: hidden;
    font-family: 'Inter', 'Helvetica Neue', Helvetica, Arial, sans-serif;
    font-size: 10.5px;
    font-weight: 500;
    line-height: 1.2;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--vca-muted);
  }

  /* Chapter 01 stays full-bleed, but it is a compact visual chapter rather
     than a second portrait screen. Its short mask still reveals the actual
     page ground in both themes. */
  .vca-m__visual--s1 {
    --vcam-img: url("../images/about/stage-01-mobile-video-call.png");
    --vcam-veil-len: clamp(60px, 17vw, 72px);
    --vcam-veil: linear-gradient(
      to bottom,
      rgba(0, 0, 0, 0) 0,
      rgba(0, 0, 0, 0.04) calc(var(--vcam-veil-len) * 0.21),
      rgba(0, 0, 0, 0.12) calc(var(--vcam-veil-len) * 0.29),
      rgba(0, 0, 0, 0.34) calc(var(--vcam-veil-len) * 0.45),
      rgba(0, 0, 0, 0.62) calc(var(--vcam-veil-len) * 0.62),
      rgba(0, 0, 0, 0.85) calc(var(--vcam-veil-len) * 0.80),
      rgba(0, 0, 0, 1) var(--vcam-veil-len)
    );
    height: calc(100vw * 1.7917);
    aspect-ratio: auto;
    margin-top: 22px;
    /* Preserve the portrait source ratio: the call card reaches its lower
       edge, so a cover crop would cut the controls off. */
    background-size: 100% auto;
    background-position: 50% 50%;
  }

  /* The room from the desktop scene, cropped for a phone. The file is very
     wide (2.36:1) against a block that is not, so this one is `cover` rather
     than the --vcam-fh window the 16:9 chapters use: the window maths assume a
     16:9 source and would mis-read this one.

     95% 50% is the measured mobile anchor: at 390px it keeps his face in the
     upper-right, the raised hand central, and the phone, hands and laptop
     corner inside the frame. It remains stable from 360px through 430px. */
  .vca-m__visual--s2 {
    --vcam-img: url("../images/about/hf_20260831_011813_662abce3-f8ad-4ead-bab2-c19416ddd7b3.png");
    height: auto;
    aspect-ratio: 1.24 / 1;
    background-size: cover;
    --vcam-pos: 95% 50%;
  }

  /* the laptop and the call on its screen are the accent; the window keeps
     his head and the whole screen and crops the table front */
  .vca-m__visual--s3 {
    --vcam-img: url("../images/about/stage-03-technology.webp");
    --vcam-fh: 0.75;
    --vcam-pos: right top;
  }

  /* both phones fill the frame; only the outer edges of the devices are
     touched by the crop */
  .vca-m__visual--s5 {
    --vcam-img: url("../images/about/stage-05-designed-for-you.webp");
    --vcam-fh: 0.80;
    --vcam-pos: right 45%;
  }

  /* This file's own right edge cuts through the two small video-call cards,
     and anchoring right used to put that cut on screen. The correction is
     shared with the desktop stage and lives in css/about-shared.css; all this
     side owes it is the fraction of the frame its own window shows, which the
     window's fixed 1:0.78 aspect makes 0.716 x --vcam-fh. Only the vertical
     anchor stays here. */
  .vca-m__visual--s6 {
    --vcam-img: url("../images/about/stage-06-real-impact.webp");
    --vcam-fh: 0.84;
    --vca-s6-window: calc(0.716 * var(--vcam-fh));
    --vcam-pos: right 38%;
  }

  /* --- Chapter 07: the four portraits as a 2x2 -------------------------- */
  /* The artwork holds them in one row, so each cell is its own window onto
     the same file, framed on one card. Same technique, same file, no new
     asset and no placeholder. */

  /* One supplied picture of four people with the spacing already in it: no
     grid, no tiles, no crop and no background — a plain <img> shown whole, so
     all four portraits and the white gaps between them are always on screen
     together. Full bleed and run down to the foot of the chapter like every
     other visual, and it takes the same short arrival, which is spent well
     inside its top row. */
  .vca-m__collage {
    display: block;
    margin: 30px calc(-1 * var(--vca-pad)) calc(-1 * var(--vca-stage-pb));
    -webkit-mask-image: var(--vcam-veil);
    mask-image: var(--vcam-veil);
  }

  .vca-m__collage img {
    display: block;
    width: 100%;
    height: auto;
    object-fit: contain;
    border-radius: 0;
  }

  /* ---------------------------------------------------------------- */
  /* Chapter 02 — call to action                                       */
  /* ---------------------------------------------------------------- */

  .vca-m__cta {
    margin: 30px 0 0;
  }

  .vca-m .vca-m__cta-btn.btn--theme {
    padding: 14px 30px;
    font-size: 14px;
    background-color: var(--vca-red) !important;
    border-color: var(--vca-red) !important;
  }

  /* ---------------------------------------------------------------- */
  /* Chapter 03 — supporting label                                     */
  /* ---------------------------------------------------------------- */

  .vca-m__label {
    margin: 26px 0 0;
    font-family: 'Inter', 'Helvetica Neue', Helvetica, Arial, sans-serif;
    font-size: 11px;
    font-weight: 700;
    line-height: 1.2;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--vca-muted);
  }

  .vca-m__label + .vca-m__panel {
    margin-top: 16px;
  }

  /* ---------------------------------------------------------------- */
  /* Chapters 03 / 06 — bordered panel rows                            */
  /* ---------------------------------------------------------------- */

  .vca-m__panel {
    margin-top: 28px;
    border: 1px solid var(--vca-line);
    border-radius: 20px;
    background: var(--vca-surface);
    box-shadow: var(--vca-shadow);
  }

  /* ---------------------------------------------------------------- */
  /* Chapter 03 — the five patented technologies as a rail            */
  /*                                                                   */
  /* Same markup, same five items, same order, same i18n keys: only the */
  /* panel's own display changes. The frame moves off the panel and     */
  /* onto the items, so one technology reads as one card.               */
  /*                                                                   */
  /* The rail spans the full width and pads itself back to the content  */
  /* column, which is what lets the first card line up with the copy    */
  /* while the second shows its edge. It scrolls only itself: its       */
  /* content cannot widen the page, overscroll-behavior keeps the       */
  /* gesture from chaining outwards, and it has nothing to scroll       */
  /* vertically, so the page keeps the vertical gesture.                */
  /*                                                                   */
  /* Chapter 06's panel and the desktop list are untouched — this is    */
  /* scoped to the one chapter by id.                                   */
  /* ---------------------------------------------------------------- */

  #vcaMStage3 .vca-m__panel {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: min(78%, 300px);
    gap: 12px;
    margin-inline: calc(-1 * var(--vca-pad));
    padding-inline: var(--vca-pad);
    overflow-x: auto;
    overflow-y: hidden;
    scroll-snap-type: x mandatory;
    scroll-padding-inline-start: var(--vca-pad);
    overscroll-behavior-x: contain;
    -webkit-overflow-scrolling: touch;
    /* the gesture stays, the bar goes */
    scrollbar-width: none;
    -ms-overflow-style: none;
    /* the panel is now a track, not a card */
    border: 0;
    border-radius: 0;
    background: none;
    box-shadow: none;
  }

  #vcaMStage3 .vca-m__panel::-webkit-scrollbar {
    display: none;
  }

  #vcaMStage3 .vca-m__row {
    flex-direction: column;
    align-items: flex-start;
    gap: 14px;
    padding: 18px;
    border: 1px solid var(--vca-line);
    border-radius: 18px;
    background: var(--vca-surface);
    box-shadow: var(--vca-shadow);
    scroll-snap-align: start;
  }

  /* the divider between stacked rows has no meaning between cards */
  #vcaMStage3 .vca-m__row + .vca-m__row {
    border-top: 1px solid var(--vca-line);
  }

  .vca-m__row {
    display: flex;
    align-items: center;
    gap: 16px;
    padding: 15px 18px;
  }

  .vca-m__row + .vca-m__row {
    border-top: 1px solid var(--vca-line-soft);
  }

  .vca-m__row-icon {
    flex: 0 0 auto;
    width: 26px;
    line-height: 1;
    text-align: center;
    color: var(--vca-red);
  }

  /* outweighs flaticon.css `span[class*=" flaticon-"]:before { font-size: 20px }` */
  .vca-m .vca-m__row-icon::before {
    font-size: 22px;
  }

  .vca-m__row-title {
    display: block;
    font-family: 'Plus Jakarta Sans', 'Inter', Helvetica, Arial, sans-serif;
    font-size: 14px;
    font-weight: 700;
    line-height: 1.35;
    color: var(--vca-ink);
  }

  /* ---------------------------------------------------------------- */
  /* Chapter 04 — provided world map                                   */
  /* ---------------------------------------------------------------- */

  /* The map is its own artwork and fills its frame edge to edge, so unlike the
     photographs it has no empty desktop margin to crop away. It runs full
     bleed and is drawn a little wider than the window so it stands as tall as
     the neighbouring visuals; only the outermost decorative ocean dots fall
     outside, never a continent or an avatar. */
  /* Chapter 04 is the one chapter whose visual is not a photograph arriving
     at its foot but a scene laid across the whole width: no box, no radius,
     no band around it — the map simply lifts out of the background, and the
     copy above and below stays in the ordinary column. The veil marks that
     entry only (12px, see --vcam-veil-map); from the first pixel of the scene
     down, the map is at the contrast of the file. */
  .vca-m__map {
    position: relative;   /* the vector network is laid over the <img> */
    /* pulled down over the chapter's own bottom padding, like every other
       visual on this page, so the map runs to the foot of the chapter */
    margin: 30px calc(-1 * var(--vca-pad)) calc(-1 * var(--vca-stage-pb));
    overflow: hidden;
    -webkit-mask-image: var(--vcam-veil-map);
    mask-image: var(--vcam-veil-map);
  }

  /* --- and the one moment on the page that moves ------------------- */
  /*                                                                   */
  /* The figure arrives first: a fade, 10px of travel and a hair under  */
  /* full size, once, when it enters the viewport. The network drawn    */
  /* over it (further down) then lights along its own arcs.             */
  /*                                                                   */
  /* js/about-viewchat.js is what puts `vca-m--reveal` on the chapters, */
  /* and it declines to under prefers-reduced-motion — so with no JS,   */
  /* no IntersectionObserver or motion turned down the map is simply    */
  /* there. Identical in light and dark: the dark artwork is swapped by */
  /* content: url() further down and this animates the element, not     */
  /* the file.                                                          */
  /* ---------------------------------------------------------------- */

  .vca-m--reveal .vca-m__map {
    opacity: 0;
    transform: translateY(10px) scale(0.985);
    will-change: opacity, transform;
  }

  .vca-m--reveal .vca-m__map.is-in {
    opacity: 1;
    transform: none;
    will-change: auto;
    transition: opacity 0.7s cubic-bezier(0.22, 0.61, 0.36, 1),
                transform 0.7s cubic-bezier(0.22, 0.61, 0.36, 1);
  }

  @media (prefers-reduced-motion: reduce) {
    .vca-m--reveal .vca-m__map,
    .vca-m--reveal .vca-m__map.is-in {
      opacity: 1;
      transform: none;
      transition: none;
      will-change: auto;
    }
  }

  .vca-m__map img {
    display: block;
    width: 108%;
    max-width: none;
    height: auto;
    margin-left: -4%;
  }

  /* ---------------------------------------------------------------- */
  /* Chapter 04 — the connection network, in vector                    */
  /*                                                                   */
  /* Two overlays, not one: the light and the dark chapter are two      */
  /* different files with two different networks (see about.html), so   */
  /* each carries its own paths, its own nodes and its own portrait     */
  /* mask. Only the one matching the theme is in the box at a time.     */
  /*                                                                   */
  /* Alignment needs no magic number. The <img> is drawn at 108% of the */
  /* figure starting at -4%, and its 1536x1024 box is what gives the    */
  /* figure its height — so an overlay pinned to those same three       */
  /* numbers, with the file's own viewBox, lands on the artwork at      */
  /* every phone width. It is inside the figure, which clips and        */
  /* carries the veil, so the overlay is cropped exactly like the map   */
  /* and adds no horizontal overflow of its own.                        */
  /*                                                                   */
  /* The arcs and nodes are baked into the webp and cannot be hidden    */
  /* without editing it, so this is not a draw-in from nothing: the     */
  /* vector network lands on the raster one and lights it up. That is   */
  /* also why the resting state here is the FINISHED state — with no    */
  /* JS, no IntersectionObserver or reduced motion the map is simply    */
  /* the map, at the contrast of the file, with nothing missing.        */
  /* ---------------------------------------------------------------- */

  .vca-m__net {
    position: absolute;
    top: 0;
    left: -4%;
    width: 108%;
    height: 100%;
    pointer-events: none;
  }

  .vca-m__net--dark { display: none; }
  html.vcp-dark .vca-m__net--light { display: none; }
  html.vcp-dark .vca-m__net--dark { display: block; }

  /* The width is measured, not chosen: the printed line is ~6.5 units of this
     1536 viewBox across in the light file and ~2.9 in the dark one (full width
     at half maximum). 3.2 sits inside both — the overlay brightens the line it
     covers rather than fattening it, which is the difference between the same
     network drawn again and a second, heavier one over the top. On a 390px
     screen that is 0.9px. */
  .vca-m__net-arcs {
    fill: none;
    stroke: #F2565C;
    stroke-width: 3.2;
    stroke-linecap: round;
  }

  /* Light needs nothing more: coral over coral-on-white deepens the line and
     cannot touch the white ground around it.

     Dark does. There the arcs are white-hot cores inside a red glow, and coral
     painted straight over them would dull the cores. `screen` can only lighten
     — coral over white stays white, coral over the dark glow burns up to coral
     — so the draw-in adds light to the existing network and never takes any
     away. Without blend-mode support it falls back to a coral line, which is
     still the brand colour on its own path. */
  .vca-m__net--dark .vca-m__net-arcs {
    mix-blend-mode: screen;
  }

  .vca-m__net-arcs path {
    /* pathLength="1" in the markup, so one unit is the whole arc */
    stroke-dasharray: 1;
    stroke-dashoffset: 0;
  }

  /* the pulse ring is only ever visible while it plays: it adds nothing to
     the resting picture, and there is no new pin, portrait or line here */
  .vca-m__ping {
    fill: none;
    stroke: #F2565C;
    stroke-width: 3.2;
    opacity: 0;
    /* the origin has to be each circle's own centre, not the SVG's 0 0 */
    transform-box: fill-box;
    transform-origin: center;
  }

  .vca-m__net--dark .vca-m__ping { mix-blend-mode: screen; }

  /* --- the arcs draw in, one after another ------------------------- */
  /*                                                                   */
  /* No new trigger and no new script: `vca-m--reveal` and `is-in` are  */
  /* the two classes js/about-viewchat.js already sets on this chapter, */
  /* once, releasing the target as soon as it has played — which is why */
  /* scrolling back up never replays any of this.                      */
  /*                                                                   */
  /* First arc at 240ms, 80ms between arcs, 740ms each: the tenth (and  */
  /* in the dark file the eleventh) lands at 1.70s / 1.78s.            */

  .vca-m--reveal .vca-m__net-arcs path {
    stroke-dashoffset: 1;
  }

  .vca-m--reveal .vca-m__map.is-in .vca-m__net-arcs path {
    stroke-dashoffset: 0;
    transition: stroke-dashoffset 740ms cubic-bezier(0.33, 0.72, 0.35, 1);
    transition-delay: calc(240ms + var(--vcam-seq, 0ms));
  }

  .vca-m__net-arcs path:nth-child(1) { --vcam-seq: 0ms; }
  .vca-m__net-arcs path:nth-child(2) { --vcam-seq: 80ms; }
  .vca-m__net-arcs path:nth-child(3) { --vcam-seq: 160ms; }
  .vca-m__net-arcs path:nth-child(4) { --vcam-seq: 240ms; }
  .vca-m__net-arcs path:nth-child(5) { --vcam-seq: 320ms; }
  .vca-m__net-arcs path:nth-child(6) { --vcam-seq: 400ms; }
  .vca-m__net-arcs path:nth-child(7) { --vcam-seq: 480ms; }
  .vca-m__net-arcs path:nth-child(8) { --vcam-seq: 560ms; }
  .vca-m__net-arcs path:nth-child(9) { --vcam-seq: 640ms; }
  .vca-m__net-arcs path:nth-child(10) { --vcam-seq: 720ms; }
  .vca-m__net-arcs path:nth-child(11) { --vcam-seq: 800ms; }

  /* --- then the nodes, west to east, one soft pulse each ----------- */

  .vca-m__net-nodes .vca-m__node:nth-child(1) { --vcam-seq: 0ms; }
  .vca-m__net-nodes .vca-m__node:nth-child(2) { --vcam-seq: 60ms; }
  .vca-m__net-nodes .vca-m__node:nth-child(3) { --vcam-seq: 120ms; }
  .vca-m__net-nodes .vca-m__node:nth-child(4) { --vcam-seq: 180ms; }
  .vca-m__net-nodes .vca-m__node:nth-child(5) { --vcam-seq: 240ms; }
  .vca-m__net-nodes .vca-m__node:nth-child(6) { --vcam-seq: 300ms; }
  .vca-m__net-nodes .vca-m__node:nth-child(7) { --vcam-seq: 360ms; }
  .vca-m__net-nodes .vca-m__node:nth-child(8) { --vcam-seq: 420ms; }
  .vca-m__net-nodes .vca-m__node:nth-child(9) { --vcam-seq: 480ms; }
  .vca-m__net-nodes .vca-m__node:nth-child(10) { --vcam-seq: 540ms; }
  .vca-m__net-nodes .vca-m__node:nth-child(11) { --vcam-seq: 600ms; }

  .vca-m--reveal .vca-m__map.is-in .vca-m__ping {
    animation: vcamNodePing 1.15s cubic-bezier(0.2, 0.6, 0.3, 1)
               calc(1500ms + var(--vcam-seq, 0ms)) both;
  }

  @keyframes vcamNodePing {
    0%   { opacity: 0; transform: scale(0.55); }
    20%  { opacity: 0.5; }
    70%  { opacity: 0.1; }
    100% { opacity: 0; transform: scale(2.5); }
  }

  /* Motion turned down: the finished network, drawn, not animating. The
     script already declines to add `vca-m--reveal` under this preference, so
     this only catches a preference changed after the page has loaded. */
  @media (prefers-reduced-motion: reduce) {
    .vca-m--reveal .vca-m__net-arcs path,
    .vca-m--reveal .vca-m__map.is-in .vca-m__net-arcs path {
      stroke-dashoffset: 0;
      transition: none;
    }

    .vca-m--reveal .vca-m__ping,
    .vca-m--reveal .vca-m__map.is-in .vca-m__ping {
      opacity: 0;
      animation: none;
    }
  }

  /* ---------------------------------------------------------------- */
  /* Header — one bar at the top of the document, nothing repeated     */
  /* inside the chapters. Only the tap targets are firmed up here; the */
  /* markup, the menu script and the language modal are untouched.     */
  /* ---------------------------------------------------------------- */

  /* the bars keep their exact position and the menu script is untouched; only
     the tappable area grows, via a pseudo-element that takes no layout space */
  .vca-d-page .wsmobileheader .wsanimated-arrow::after {
    content: "";
    position: absolute;
    top: -8px;
    bottom: -8px;
    right: 0;
    width: 62px;
  }

  /* Three controls now share the bar, so the language button is brought to the
     same compact circle Partners uses — the flag carries the meaning and the
     language name is in the list itself. Everything else about the control is
     untouched: same #langBtnMobile, same #languageOverlay, same
     js/language-modal.js, and i18n.js keeps swapping the flag.

     Through #header because lang-switcher-2.css loads later and sets
     `.lang-btn { display: inline-flex }` at the same specificity. */
  .vca-d-page #header .lang-btn--mobile {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    top: 23px;
    right: 74px;
    width: 34px;
    height: 34px;
    min-width: 0;
    padding: 0;
    background: var(--vcp-switch-bg);
    border: 1px solid var(--vcp-switch-line);
    border-radius: 50%;
    overflow: visible;
  }

  .vca-d-page #header .lang-btn--mobile .lang-btn__icon {
    width: 20px;
    height: 20px;
    border-radius: 50%;
    object-fit: cover;
  }

  .vca-d-page #header .lang-btn--mobile .lang-btn__label {
    display: none;
  }

  /* ---------------------------------------------------------------- */
  /* LIGHT / DARK — the Partners switch, reused                        */
  /*                                                                   */
  /* Same component, same `vcp-dark` class on <html>, same             */
  /* localStorage["vcp-theme"], same opt-in model: no                  */
  /* prefers-color-scheme, light is the default. The whole block lives */
  /* inside @media (max-width: 991.98px), which is what guarantees the */
  /* class cannot touch desktop About — it may sit on <html>, but from */
  /* 992px up not one of these rules applies.                          */
  /* ---------------------------------------------------------------- */

  .vcp-themeswitch {
    /* the header is already position:fixed (menu.css) with the hamburger at
       right:0 and the language button at right:74px; this joins that row */
    position: absolute;
    z-index: 103;
    top: 25px;
    right: 120px;
    display: inline-flex;
    align-items: center;
    justify-content: space-between;
    width: 62px;
    height: 30px;
    margin: 0;
    padding: 0 6px;
    background: var(--vcp-switch-bg);
    border: 1px solid var(--vcp-switch-line);
    border-radius: 999px;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    transition: background-color 0.2s ease, border-color 0.2s ease;
  }

  /* the controls keep their drawn size; the tappable area does not */
  .vcp-themeswitch::before,
  .vca-d-page #header .lang-btn--mobile::before {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    min-width: 46px;
    min-height: 46px;
    width: 100%;
    height: 100%;
    transform: translate(-50%, -50%);
  }

  /* with the slide-out menu open the header moves aside and the language
     button hides itself; this hides with it */
  .wsactive .vcp-themeswitch {
    display: none !important;
  }

  .vcp-themeswitch__knob {
    position: absolute;
    z-index: 0;
    top: 3px;
    left: 3px;
    width: 22px;
    height: 22px;
    background: var(--vcp-switch-knob);
    border-radius: 50%;
    box-shadow: 0 2px 6px rgba(16, 20, 32, 0.18);
    transition: transform 0.24s cubic-bezier(0.4, 0, 0.2, 1), background-color 0.2s ease;
  }

  .vcp-themeswitch__ico {
    position: relative;
    z-index: 1;
    flex: none;
    width: 15px;
    height: 15px;
    transition: color 0.2s ease;
  }

  /* the active icon is the one the knob sits under */
  .vcp-themeswitch__ico--sun { color: var(--vcp-switch-on); }
  .vcp-themeswitch__ico--moon { color: var(--vcp-switch-off); }

  .vcp-themeswitch:focus-visible,
  .vca-d-page #header .lang-btn--mobile:focus-visible {
    outline: 2px solid var(--vca-red, #e8353b);
    outline-offset: 3px;
  }

  /* Light values live on the controls themselves, not in the token block: a
     custom property declared on the element always beats an inherited one, so
     without :not(.vcp-dark) the dark values would never reach them. */
  html:not(.vcp-dark) .vcp-themeswitch,
  html:not(.vcp-dark) .vca-d-page #header .lang-btn--mobile {
    --vcp-switch-bg: #eef0f4;
    --vcp-switch-line: rgba(20, 22, 28, 0.10);
    --vcp-switch-knob: #ffffff;
    --vcp-switch-on: #14161c;
    --vcp-switch-off: #9aa1ad;
  }

  html.vcp-dark .vcp-themeswitch__knob {
    transform: translateX(30px);
  }

  html.vcp-dark .vcp-themeswitch__ico--sun { color: var(--vcp-switch-off); }
  html.vcp-dark .vcp-themeswitch__ico--moon { color: var(--vcp-switch-on); }

  /* --- Dark theme: one block of values ----------------------------------- */

  html.vcp-dark .vca-m,
  html.vcp-dark .vcp-themeswitch,
  html.vcp-dark .vca-d-page #header .lang-btn--mobile {
    /* on near-black the light coral goes dusty and loses contrast, so the
       accent is the cleaner red Partners uses in its own dark theme */
    --vca-red: #ff3138;
    --vca-ink: #f5f6f8;
    --vca-body: #dcdee4;
    --vca-muted: #9ba1ad;
    --vca-line: rgba(255, 255, 255, 0.12);
    --vca-line-soft: rgba(255, 255, 255, 0.09);
    --vca-shadow: 0 10px 28px rgba(0, 0, 0, 0.52);
    --vca-page: #07070a;
    --vca-surface: #15161b;

    /* No veil overrides here. The fades are the same curve over the same
       pixels in both themes: a mask reveals whatever is behind it, so the
       artwork that arrives is identical and only the ground it arrives out of
       changes — the light page in one theme, the near-black in the other. The
       dense part of every visual is therefore exactly as dense in the dark as
       in the light. */

    --vcp-switch-bg: #1b1d23;
    --vcp-switch-line: rgba(255, 255, 255, 0.16);
    --vcp-switch-knob: #34373f;
    --vcp-switch-on: #ffffff;
    --vcp-switch-off: #6f757f;
  }

  /* --- Canvas outside .vca-m --------------------------------------------- */
  /* The page ground, the header, the preloader and the footer come from the
     shared template and never see the chapter tokens; these are exactly as
     many rules as there are white surfaces. */

  html.vcp-dark,
  html.vcp-dark body,
  html.vcp-dark .page,
  html.vcp-dark #loading,
  html.vcp-dark .loading--theme {
    background-color: #07070a;
  }

  html.vcp-dark .tra-menu .wsmobileheader,
  html.vcp-dark .white-menu .wsmobileheader,
  html.vcp-dark .wsmobileheader {
    background-color: #07070a;
    box-shadow: 0 1px 0 rgba(255, 255, 255, 0.09);
  }

  html.vcp-dark .wsanimated-arrow span,
  html.vcp-dark .wsanimated-arrow span:before,
  html.vcp-dark .wsanimated-arrow span:after {
    background: #d7d9df;
  }

  /* The footer is a shared template block with its own colours and no access
     to the chapter tokens, so it is repainted exactly the way Partners does
     it: text, headings and the dividers. */

  html.vcp-dark .footer,
  html.vcp-dark .footer p,
  html.vcp-dark .footer li,
  html.vcp-dark .footer span,
  html.vcp-dark .footer a,
  html.vcp-dark .bottom-footer,
  html.vcp-dark .bottom-footer p {
    color: #dcdee4;
  }

  html.vcp-dark .footer h5,
  html.vcp-dark .footer h6,
  html.vcp-dark .footer .d-title,
  html.vcp-dark .footer .m-title {
    color: #f5f6f8;
  }

  html.vcp-dark .footer a:hover,
  html.vcp-dark .footer a:focus-visible {
    color: #ff3138;
  }

  html.vcp-dark .footer .fl-1,
  html.vcp-dark .footer .fl-2,
  html.vcp-dark .footer .fl-3 {
    border-bottom-color: rgba(255, 255, 255, 0.09);
  }

  html.vcp-dark .footer hr {
    border-top-color: rgba(255, 255, 255, 0.09);
  }

  /* --- Chapters in the dark ---------------------------------------------- */

  /* The visuals are deliberately identical in both themes: same box, same
     height, same crop. Only tokens change — no filter, no inversion, the
     artwork is shown exactly as authored. */

  /* Chapter 04 has its own dark artwork. content: url() instead of a second
     <img>: the markup does not change, the file is only requested once the
     rule actually applies (so never on desktop and never in light mode), and
     the element keeps its box, so nothing shifts. */
  html.vcp-dark .vca-m__map img {
    content: url("../images/about/stage-04-global-map-dark.webp");
  }

  /* ---------------------------------------------------------------- */
  /* Narrow phones                                                     */
  /* ---------------------------------------------------------------- */

  @media (max-width: 359.98px) {
    .vca-m {
      --vca-pad: 18px;
    }

    .vca-m__title {
      font-size: 28px;
    }
  }

  /* ---------------------------------------------------------------- */
  /* Tablet width — the same page, just a wider measure                */
  /* ---------------------------------------------------------------- */

  @media (min-width: 600px) {
    .vca-m__in {
      max-width: 560px;
      margin-left: auto;
      margin-right: auto;
    }

    .vca-m__title {
      font-size: 34px;
    }

    .vca-m__stage {
      padding: 58px 0 48px;
    }

    .vca-m__stage:first-child {
      padding-top: 44px;
    }
  }
}
