/* ===== tokens.css ===== */
/* ==========================================================================
   AVELaunch Books — design tokens
   Source of truth: WEBSITE_DESIGN (Figma), page "Dekstop"
   Handoff document v1.0, 7 September 2026, sections 6 and 7
   No colour value may be written anywhere outside this file.
   ========================================================================== */

:root {
  /* --- 6.2 Primitive palette ------------------------------------------- */
  --rich-black-1:      #0B1424;  /* body text, inverse surfaces, 3px strokes */
  --rich-black-2:      #E8EDF5;
  --rich-black-3:      #C7D2E3;  /* 1px hairline, vertical grid lines       */
  --rich-black-4:      #93A3BD;
  --rich-black-5:      #5D6C86;  /* secondary text                          */
  --rich-black-6:      #08101D;
  --rich-black-7:      #050A14;

  --space-cadet-1:     #1B2A57;
  --space-cadet-2:     #EEF2FA;
  --space-cadet-3:     #CBD6EC;
  --space-cadet-4:     #9BAED3;
  --space-cadet-5:     #657BA8;
  --space-cadet-6:     #142042;
  --space-cadet-7:     #0D162D;

  --vista-blue-1:      #7C9EC7;  /* brand surface                           */
  --vista-blue-2:      #F3F7FC;  /* spelled "Vista Vlue 2" in the file      */
  --vista-blue-3:      #DCE8F5;
  --vista-blue-4:      #B7CBE3;
  --vista-blue-5:      #93B1D3;

  --columbia-blue-1:   #C2E6F9;
  --columbia-blue-2:   #FCFEFF;
  --columbia-blue-3:   #EEF8FD;
  --columbia-blue-4:   #D9EEF9;
  --columbia-blue-5:   #CBE8FA;

  --amber-1:           #F2BB16;
  --amber-2:           #F9E08A;
  --amber-3:           #F7CD52;
  --amber-4:           #E0A800;  /* accent: buttons, underlines, active     */

  --editorial-white-1: #F8F7F4;
  --editorial-white-2: #FFFFFF;
  --editorial-white-3: #FDFBF8;
  --editorial-white-4: #EEEAE3;  /* page background                         */

  /* --- 6.3 Semantic layer ----------------------------------------------
     Reference map from the file. The layout binds to primitives, exactly
     as the Figma layers do, so this layer stays a dictionary of roles.     */
  --surface-page:       var(--editorial-white-4);
  --surface-brand:      var(--vista-blue-1);
  --surface-accent:     var(--amber-4);
  --surface-inverse:    var(--rich-black-1);
  --content-primary:    var(--rich-black-1);
  --content-secondary:  var(--rich-black-5);
  --content-on-inverse: var(--editorial-white-4);
  --content-accent:     var(--amber-4);
  --content-on-accent:  var(--rich-black-1);
  --content-on-brand:   var(--rich-black-1);
  --border-strong:      var(--rich-black-1);   /* 3px */
  --border-hairline:    var(--rich-black-3);   /* 1px */
  --border-accent:      var(--amber-4);        /* 3px */
  --action-fill:        var(--amber-4);
  --action-fill-hover:  rgba(255, 255, 255, 0); /* no fill on hover        */
  --action-border-hover: var(--amber-4);

  /* --- 4.1 Grid ---------------------------------------------------------
     1440 reference · 12 columns · Stretch · margin 50 · gutter 25
     Working area 1340. Column width is derived, never written down.       */
  --layout-reference: 1440px;
  --layout-margin:    50px;
  --header-top:       0px;    /* 2026-10-27, client: no strip above the desktop header (was 50 in the file, then 20) */
  --layout-gutter:    25px;
  --layout-content:   1340px;
  --layout-floor:     1200px;   /* lower bound of the desktop layout       */

  /* --- 4.1 Vertical lines ----------------------------------------------
     Seven lines, step 180 of 1440 = 12.5 % of the window.
     THIS IS THE ONLY PLACE THE POSITIONS EXIST. Both layers — the page
     layer under the content and the header layer over its blurred
     background — read them from here. Writing them twice is what makes
     the two layers drift apart at the header edge.                        */
  --line-step:  12.5%;
  --line-width: 1px;
  --line-color: var(--rich-black-3);

  /* --- 8 Effects --------------------------------------------------------
     One effect on the whole site: BACKGROUND_BLUR 50 on the header plate. */
  --header-blur: 25px;
  --header-plate: rgb(238 234 227 / 0.75);
  --header-height: 61px;

  /* --- Motion ----------------------------------------------------------- */
  --t-fast: 150ms;
  --t-base: 300ms;
}

/* ===== base.css ===== */
/* ==========================================================================
   AVELaunch Books — fonts, typography scale, grid, vertical lines, layout
   intent tags. Handoff sections 4, 5, 7, 15.
   ========================================================================== */

/* --- 15.1 Fonts. Served from our own domain, never a third party. -------- */
@font-face {
  font-family: "Mulish";
  font-style: normal;
  font-weight: 200 1000;
  font-display: swap;
  src: url("../fonts/mulish-latin-wght-normal.woff2") format("woff2-variations");
  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: "Mulish";
  font-style: normal;
  font-weight: 200 1000;
  font-display: swap;
  src: url("../fonts/mulish-latin-ext-wght-normal.woff2") format("woff2-variations");
  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;
}
@font-face {
  font-family: "Mulish";
  font-style: italic;
  font-weight: 200 1000;
  font-display: swap;
  src: url("../fonts/mulish-latin-wght-italic.woff2") format("woff2-variations");
  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: "Comforter";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../fonts/comforter-latin-400-normal.woff2") format("woff2");
}

/* --- Reset -------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  min-width: var(--layout-floor);
  background: var(--surface-page);
  color: var(--content-primary);
  font-family: "Mulish", "Helvetica Neue", Arial, sans-serif;
  font-weight: 400;
  font-size: 15px;
  line-height: normal;
  -webkit-font-smoothing: antialiased;
}

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

a { color: inherit; text-decoration: none; }

button, input, textarea, select {
  font: inherit;
  color: inherit;
  margin: 0;
}

h1, h2, h3, h4, p, figure, blockquote, dl, dd { margin: 0; }
ul, ol { margin: 0; padding: 0; list-style: none; }

/* 9. Keyboard focus is visible on every interactive element: white plate,
   3px accent stroke — the decision taken for the form fields, applied site
   wide because the component sets carry no separate focus variant.        */
:focus-visible {
  outline: 3px solid var(--border-accent);
  outline-offset: 2px;
}

/* 2026-10-15, designer's desktop review of 13 Oct, items 10 and 18: fields
   stay Editorial White 4 #EEEAE3 in every state; focus adds only the 3 px
   Amber 4 #E0A800 outline. The tablet hand-off of 13 Oct: Editorial White 4
   is the only white. So on the desktop layer focus no longer paints a plate
   of pure white (#FFFFFF, --editorial-white-2) — it used to here, and as an
   element-type match it won over every input's own fill. The plate is kept
   below 1280 only, so the tablet and mobile layers, which have no focus
   rule of their own and inherited this one, behave exactly as before; that
   is their brief to change, not this one. A block that sets its own focus
   fill (sections/main/s15.css) still wins on specificity. */
@media (max-width: 1279.98px) {
  :focus-visible {
    background-color: var(--editorial-white-2);
  }
}

/* --- 7.3 Heading trim ---------------------------------------------------
   Headings in the file sit on the cap height, not on the line box. Without
   the trim every heading drops a few pixels and the spacing above it reads
   larger than the macket.                                                  */
.u-trim {
  text-box-trim: trim-both;
  text-box-edge: cap alphabetic;
}

/* --- 7.2 Type styles ----------------------------------------------------
   Letter spacing comes from Figma as a percentage of the type size, so it
   is written in em and never converted to pixels. Line height is Auto in
   every style, which is line-height: normal, not 100 %.                    */
.t-heading-accent       { font-family: "Comforter", cursive; font-weight: 400; font-size: 100px; letter-spacing: 0; text-transform: uppercase; }
.t-heading-accent-small { font-family: "Comforter", cursive; font-weight: 400; font-size: 100px; letter-spacing: 0; }
.t-heading              { font-weight: 1000; font-size: 50px; letter-spacing: 0.1em;  text-transform: uppercase; }
.t-heading-wide         { font-weight: 1000; font-size: 50px; letter-spacing: 0.06em; text-transform: uppercase; }
.t-heading-wide-light   { font-weight: 200;  font-size: 50px; letter-spacing: 0.06em; text-transform: uppercase; }
.t-subheading           { font-weight: 400;  font-size: 25px; letter-spacing: 0;      text-transform: uppercase; }
.t-intro                { font-weight: 400;  font-size: 25px; letter-spacing: 0; }
.t-intro-black          { font-weight: 1000; font-size: 25px; letter-spacing: 0;      text-transform: uppercase; }
.t-intro-black-wide     { font-weight: 1000; font-size: 25px; letter-spacing: 0.1em;  text-transform: uppercase; }
.t-base                 { font-weight: 400;  font-size: 15px; letter-spacing: 0; }
.t-base-black           { font-weight: 1000; font-size: 15px; letter-spacing: 0; }
.t-base-italic          { font-weight: 400;  font-size: 15px; font-style: italic; }
.t-base-down-black      { font-weight: 1000; font-size: 15px; text-transform: lowercase; }
.t-base-up              { font-weight: 400;  font-size: 15px; text-transform: uppercase; }
.t-base-up-black        { font-weight: 1000; font-size: 15px; text-transform: uppercase; }
.t-base-up-black-wide   { font-weight: 1000; font-size: 15px; letter-spacing: 0.1em;  text-transform: uppercase; }
.t-label                { font-weight: 400;  font-size: 25px; letter-spacing: 0.1em;  text-transform: uppercase; }
.t-label-wide           { font-weight: 400;  font-size: 25px; letter-spacing: 0.6em;  text-transform: uppercase; }
.t-label-big            { font-weight: 200;  font-size: 100px; text-transform: uppercase; }
.t-label-big-black      { font-weight: 1000; font-size: 100px; text-transform: uppercase; }

.u-secondary { color: var(--content-secondary); }
.u-accent    { color: var(--content-accent); }

/* 2026-10-27: the designer ships one carousel chevron (Arrow1.svg →
   assets/icon-arrow-prev.svg?v=b0bd3895, pointing left). A next arrow is the same file
   mirrored. */
.u-flip-x    { transform: scaleX(-1); }

/* --- 4.1 / 4.2 Working area ---------------------------------------------
   Above 1440 the working area holds at 1340 and centres; the margins grow.
   Between 1200 and 1440 the margin stays 50, the gutter stays 25, the
   columns narrow. Type sizes do not change.                               */
.container {
  width: min(var(--layout-content), 100% - var(--layout-margin) * 2);
  margin-inline: auto;
}

/* 12-column helper. The column width is derived from the grid, never set. */
.grid12 {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: var(--layout-gutter);
}

/* --- 5.1 Intent tags ----------------------------------------------------
   Five values cover all thirty-nine hand-composed blocks. Where Auto Layout
   in the file disagrees with the tag, the tag wins.                        */

/* fluid — lives inside the working area and narrows with it. Default. */
.is-fluid { width: 100%; }

/* flow — a row of equal elements that wraps when it stops fitting.
   The gap equals the gutter. The count per row is not fixed.              */
.is-flow {
  display: flex;
  flex-wrap: wrap;
  gap: var(--layout-gutter);
}
.is-flow > * { flex: 1 1 var(--flow-basis, 430px); min-width: 0; }

/* bleed:both — runs the full window width both sides. Text and cards
   inside stay in the working area.                                        */
.is-bleed-both {
  width: 100vw;
  margin-left: calc(50% - 50vw);
}

/* bleed:left / bleed:right — out past one margin only, never both.
   --bleed-stop is the macket coordinate of the edge that stays put,
   expressed as a share of the working area.

   The box stops growing at the reference frame. It used to run to the window
   edge (`margin-left: calc(50% - 50vw)`), which at 1440 made it exactly the
   macket's 1340 — every share inside is a share of 1340, so the composition
   was right there and only there. At 1920 the same box became 1580 and the
   photograph, the cards and the text stretched with it: the "block drifts
   left" the comments report, eighteen times over. Pinned to the frame, the
   proportions inside are the macket's at any width.

   What is supposed to keep running off the edge is the fill, not the
   composition — an amber slab, a coloured band. That is `.u-bleed-fill-left`
   below, on the fill itself. */
.is-bleed-left {
  width: calc(100% - var(--bleed-stop, 0%)
              + (var(--layout-reference) - var(--layout-content)) / 2);
  margin-left: calc((var(--layout-content) - var(--layout-reference)) / 2);
  margin-right: 0;
}
/* Mirror image: for bleed:right the stop is the LEFT inset, so it stays a
   margin and the width comes off the same side. */
.is-bleed-right {
  width: calc(100% - var(--bleed-stop, 0%)
              + (var(--layout-reference) - var(--layout-content)) / 2);
  margin-right: calc((var(--layout-content) - var(--layout-reference)) / 2);
  margin-left: var(--bleed-stop, 0%);
}

/* The fill carries on to the window edge from wherever it stops. It paints a
   viewport's worth sideways and the page clips it, so no width has to be
   worked out. `background: inherit` so the fill's own colour is the only
   place a colour is written. */
.u-bleed-fill-left::before,
.u-bleed-fill-right::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  width: 100vw;
  background: inherit;
}
.u-bleed-fill-left::before  { right: 100%; }
.u-bleed-fill-right::after  { left: 100%; }

/* --- 4.0 The frame ------------------------------------------------------
   Everything positioned from --line-step is positioned inside this box, and
   nothing else is: the macket's 1440 frame, centred, shrinking with the
   window below 1440 and holding still above it. Before this existed, the
   line layer was `inset: 0` on the page, so --line-step read as 12.5 % of
   the WINDOW: at 1440 the lines landed on 180 · 360 · … · 1260 exactly, and
   at 1920 they spread to a 240 step and left the working area behind. Same
   for the header's menu, which took its cells from the same percentage.
   One box, one source, so the page layer and the header layer cannot drift
   apart at any width.                                                      */
.u-frame {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 50%;
  width: min(100%, var(--layout-reference));
  transform: translateX(-50%);
}

/* --- 4.1 Vertical lines -------------------------------------------------
   One component, two placements. Positions are read from --line-step in
   tokens.css and exist nowhere else, so the page layer and the header layer
   cannot drift apart.                                                      */
.gridlines {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 50%;
  width: min(100%, var(--layout-reference));
  transform: translateX(-50%);
  pointer-events: none;
  z-index: 0;
}
.gridlines i {
  position: absolute;
  top: 0;
  bottom: 0;
  width: var(--line-width);
  background: var(--line-color);
  left: calc(var(--n) * var(--line-step));
}

/* The page layer sits under every section, the full height of the document.
   The header is the one exception: it keeps its own sticky positioning and
   rides above, because it draws its own copy of the lines over its plate. */
/* Bleeding blocks are drawn past the window edge on purpose — an amber band
   that runs off the left, a roller whose next card is cut by the right. The
   page clips them at the window. `clip` and not `hidden`: hidden would make
   this a scroll container and the pinned header would stop pinning. */
.page {
  position: relative;
  overflow-x: clip;
}
.page > .gridlines { z-index: 0; }

/* 2026-10-15, designer's desktop review of 13 Oct, item 1 ("no lines").
   The layer was present on all 27 pages at 180 · 360 · … · 1260 of the 1440
   frame and showed on the page ground for 30–85 % of each page's height (the
   rest is opaque section fills, which cover it in the file too — Main 1:3,
   `BackgroundLines` 73:593 sits under `Sections + footer`). What was missing
   is the strip above the header: the header's 50 margin-top collapses
   through `.page`, so `.page` — and the layer with `top: 0` — began at y 50
   and the 0–50 strip had no lines, where the file draws `UpperLines`
   152:1612. The layer now starts at the top of the document. Desktop only:
   the tablet and mobile layers hide this header, so nothing collapses
   there. */
@media (min-width: 1280px) {
  .page > .gridlines { top: calc(-1 * var(--header-top)); }
}
.page > *:not(.gridlines):not(.site-header):not(.site-up) { position: relative; z-index: 1; }
.page > .site-header { z-index: 2; }

/* Skip link — visible only once it takes focus. */
.skip-link {
  position: absolute;
  left: var(--layout-margin);
  top: 0;
  z-index: 10;
  transform: translateY(-200%);
  padding: 12px 25px;
  background: var(--editorial-white-2);
  color: var(--content-primary);
  font-weight: 1000;
  font-size: 15px;
  text-transform: uppercase;
  transition: transform var(--t-fast);
}
.skip-link:focus-visible { transform: translateY(0); }

/* --- Vertical rhythm between the blocks ---------------------------------
   The file stacks the screen's blocks on a fixed rhythm, and it is defined
   here once rather than inside each section: a section owns its own height,
   never the air around it.

   Read off the Main screen (1:3): the header's box ends at 111 and the first
   block starts at 180; every neighbouring pair of blocks sits 150 apart; the
   footer sits 100 below the last one.

   150 is only the Main screen's number. Services runs 150 · 100 · 0, How It
   Works runs 100 below its halfway point, and the gap under the header is a
   different number on every screen. So the default lives here and a block
   that departs from it writes its own value once, in the markup, as
   `style="--gap: 100px"` on the <section> — the measured Figma number, next
   to the block it belongs to, still not a margin the section sets on itself.

   The FAQ on Main carries `--gap: 0`: its full-width blue fill is meant to
   start exactly where the founder block above it ends.                      */
:root {
  --block-gap: 150px;
  --block-gap-first: 69px;   /* header box 111 → first block 180 */
  --block-gap-footer: 100px;
}

main > section + section  { margin-top: var(--gap, var(--block-gap)); }
main > section:first-child { margin-top: var(--gap, var(--block-gap-first)); }
.page > .site-footer { margin-top: var(--gap-footer, var(--block-gap-footer)); }

/* --- 13.3 Anchors -------------------------------------------------------
   Smooth scroll that accounts for the pinned header, so the target block
   does not hide underneath it.                                            */
html { scroll-behavior: smooth; }
[id] { scroll-margin-top: calc(var(--header-height) + 50px); }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}

/* --- Below the 1200 floor ------------------------------------------------
   The design stops at 1200: below that there is no narrower composition to
   fall back to, and `min-width` on its own gave a horizontal scrollbar — the
   headline cut off the left edge, half the hero off the right. A window at
   900 is not a phone; it is a laptop or a half-screen window, and a page you
   have to scroll sideways to read is broken in the only sense that matters.

   So the page keeps its 1200 layout and is scaled down to fit the window.
   Everything stays in proportion and simply reads smaller. This is not a
   narrow layout and it is no substitute for one — it is what the site does
   until a narrow composition is drawn.

   The scale itself cannot be written here: `zoom` needs a plain ratio, and
   no CSS expression turns a viewport width into one — dividing 100vw by 1200
   yields a length, which `zoom` rejects. So it is set by the small inline
   script the build puts at the top of every <body>, and `zoom` rather than
   `transform: scale()` because a transform would make the pinned header and
   the scroll-to-top control position against the transformed box instead of
   the window, and both would come unstuck.                                 */

/* An inline link inside body copy. The site has no underlines anywhere, so
   a link in the middle of a sentence has to be told apart some other way:
   it carries the accent colour and a 1px rule that thickens on hover. */
.u-link-inline {
  color: var(--content-accent);
  border-bottom: 1px solid currentColor;
  transition: border-bottom-width var(--t-fast), color var(--t-fast);
}
.u-link-inline:hover,
.u-link-inline:focus-visible {
  border-bottom-width: 3px;
}

/* 2026-11-02, client: a text link that keeps the colour of the words around
   it, so it reads on the page, on Vista Blue and on Amber plates alike — the
   privacy line under every form (js/forms.js) and "Read the story →" on the
   author cards. Same shape as .u-link-inline: a 1px rule under the words
   that thickens on hover and focus. Not in Figma. */
.u-link-text {
  color: inherit;
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  transition: text-decoration-thickness var(--t-fast);
}
.u-link-text:hover,
.u-link-text:focus-visible {
  text-decoration-thickness: 3px;
}

/* 2026-11-02, client: "Result" on the author cards (business b6/t4/m5,
   wellness w5/t4/m5) was an amber or outlined box that looked like a
   button. It is a label now: the word in Base Up Black Wide, Rich Black 1,
   after a short Amber 4 rule. No plate, no box, not focusable, not a link.
   The span inside carries u-trim (a flex item is a block box). Not in Figma,
   which draws the box. */
.c-result-label {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0;
  color: var(--content-primary);
}
.c-result-label::before {
  content: "";
  flex: 0 0 25px;
  height: 3px;
  background: var(--border-accent);
}
.c-result-more { margin: 0; color: var(--content-primary); }

/* 2026-10-27, client: the counters (js/stats.js). Digits keep one width while
   they count, and the "+" hangs outside the number so the number itself is
   what sits on the centre line (it looked off-centre with the "+" counted). */
.stat-n { font-variant-numeric: tabular-nums; }
.stat-wrap { position: relative; display: inline-block; }
/* 2026-10-27, client: centring the digits alone looked off the other way;
   the group sits between the two — shifted left by about half the "+" so
   the eye reads number and sign as centred. */
.stat-wrap:has(.stat-plus) { left: -0.17em; }
.stat-plus { position: absolute; left: 100%; top: 0; }

/* 2026-11-02, founders: the logo cursor of 2026-10-27 is gone — amber on
   amber buttons, and visitors could not tell what was clickable. The native
   cursor is back; anything clickable shows the pointing hand. */
a, button, [role="button"], label, summary, select,
[data-open-form], .is-tappable { cursor: pointer; }
/* A text field inside a clickable label keeps the text caret. */
input:not([type="checkbox"]):not([type="radio"]):not([type="submit"]):not([type="button"]),
textarea { cursor: text; }

/* --- Pull quote --------------------------------------------------------
   2026-10-27, client ("make the quote a quote"): the founder's quote on
   Main, About, For business experts and For wellness experts read like a
   heading (Intro Black, all caps, as Figma 998:11862 and its siblings draw
   it). It now speaks the site's own quote language, the one from the case
   pages' "In their own words" band (case.css .s-case-quote__*, caset.css
   .tb-cases-6__*): the amber opening mark in Label Big Black, the words in
   Intro beside it, the attribution under the words. The words are italic,
   as the quotes in Client Voices are (main/s7). The mobile reading of the
   same pattern is in m-base.css (.c-quote--m).

     <figure class="c-quote">
       <p class="c-quote__mark t-label-big-black u-trim" aria-hidden="true">“</p>
       <blockquote class="c-quote__words"><p class="t-intro u-trim">…</p></blockquote>
       <figcaption class="c-quote__by t-base-up-black u-trim">— Name</figcaption>
     </figure>                                                              */
.c-quote {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  column-gap: var(--layout-gutter);
  row-gap: var(--layout-gutter);
  align-items: start;
  text-align: left;
  /* 2026-10-27, client: more air between the quote and what is around it. */
  margin-block: 30px;
}
.c-quote__mark {
  grid-row: 1 / span 2;
  color: var(--content-accent);
}
.c-quote__words {
  grid-column: 2;
  font-style: italic;
}
.c-quote__by {
  grid-column: 2;
  color: var(--content-secondary);
}

/* 2026-10-27, client: the pull-quote types itself out (js/quote.js). The
   letters are hidden, not removed, so the quote keeps its size from the
   start; the attribution fades in when the last letter is down. */
.c-quote.is-typing .c-quote__ch { opacity: 0; }
.c-quote.is-typing .c-quote__ch.is-on { opacity: 1; }
.c-quote.is-typing .c-quote__by { opacity: 0; transition: opacity 500ms ease; }
.c-quote.is-typing .c-quote__by.is-on { opacity: 1; }

/* ===== header.css ===== */
/* ==========================================================================
   Site header — Figma component set 504:2789, instance 20:1973 on Main.
   Load AFTER css/base.css.

   Full window width, 61px tall, pinned to the top of the window. Three
   layers, bottom to top:

     1. the plate  — Editorial White 4 at 75 % over a background blur
                     (Figma "Rectangle 13", 1440 x 61)
     2. the lines  — the page's own .gridlines component, drawn a second
                     time so the seven lines sit OVER the plate
     3. the logo and the menu

   Geometry: the seven lines and the seven menu cells are the same seven
   positions. They are read from --line-step in tokens.css and appear
   nowhere else, so the page's line layer and the header's cannot drift.
   ========================================================================== */

.site-header {
  position: sticky;
  top: 0;
  z-index: 10;
  height: var(--header-height);
  /* Starts one strip down; the page's own lines show in that strip. The file
     draws it 50 (one page margin); 20 since 2026-10-27, the client's call
     after the designer's answer that the strip and its lines must stay. */
  margin-top: var(--header-top);
}

/* base.css pins every child of .page with `position: relative` at a higher
   weight than a single class, so the sticky behaviour is restated here at
   matching specificity. Width stays `auto` — the header must measure the
   same box as .page, not 100vw, or the scrollbar would offset its lines by
   a few pixels against the page's. */
.page > .site-header {
  position: sticky;
  z-index: 10;
}

/* --- 1. The plate ------------------------------------------------------- */
.site-header__plate {
  position: absolute;
  inset: 0;
  z-index: 0;
  background: var(--header-plate);
  -webkit-backdrop-filter: blur(var(--header-blur));
  backdrop-filter: blur(var(--header-blur));
}

/* --- 2. The lines -------------------------------------------------------
   The only modifier the shared component needs: it is lifted above the
   plate. The page layer keeps z-index 0 and stays under the content, so
   what shows inside the header is this crisp set at full strength, never
   the page's set dimmed and blurred through the translucent plate.       */
.site-header__lines {
  z-index: 1;
}

/* --- 3. Logo ------------------------------------------------------------ */
/* The macket's margin measured from the frame, not from the window: above
   1440 the frame centres, and a logo pinned to the window edge would sit
   240 away from the menu that starts at the frame's first line. */
.site-header__logo {
  position: absolute;
  z-index: 2;
  left: calc(max(0px, (100% - var(--layout-reference)) / 2) + var(--layout-margin));
  top: 50%;
  transform: translateY(-50%);
}

/* 15px tall, the wordmark's own ratio gives the width (107.45 in the
   macket). Fixed to the window margin, not to a share of the width. */
.site-header__logo img {
  width: auto;
  height: 15px;
}

/* --- 3. Menu ------------------------------------------------------------
   Each cell's line is at --n * --line-step; the label sits one gutter to
   the right of it. The cell width (150 in the macket) is never needed —
   the next cell is placed from the next line, not from this one's edge.  */
/* The frame box, not the window: the cells are placed from --line-step and
   the lines they belong to are now anchored to the macket's 1440 frame
   (base.css §4.0). Window-wide, the menu spread with the window and left
   its own lines behind above 1440. */
.site-header__nav {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 50%;
  width: min(100%, var(--layout-reference));
  transform: translateX(-50%);
  z-index: 2;
  /* The nav box covers the whole header, including the logo. It is
     transparent but would still take the clicks, so it is made inert and
     only the menu items themselves are given back to the pointer. */
  pointer-events: none;
}

.site-header__item {
  position: absolute;
  top: 0;
  bottom: 0;
  display: flex;
  align-items: center;
  pointer-events: auto;
  left: calc(var(--n) * var(--line-step) + var(--layout-gutter));
}

.site-header__link {
  white-space: nowrap;
  transition: color var(--t-fast);
}

/* Active page. The five variants in the set carry no other difference at
   this height, so one rule covers Main, Services, Process, Results and
   About. Styled off the attribute so the markup cannot drift from it. */
.site-header__link[aria-current="page"],
.site-header__link:hover,
.site-header__link:focus-visible {
  color: var(--content-accent);
}

/* 2026-10-27, desktop review 20 Oct item 14 ("the header does not show which
   section the visitor is on"). Read from every Dekstop frame's Header
   instance: the bar label of the section is Amber 4 (Button_text prop=hov
   colour, 2:385) on the section's own pages AND on its sub-pages —
   Discovery Sprint 504:3358 → Services; Free Resources 521:2838 / 818:6803
   and the three cases → Results; FAQ 521:3179 and Contact 521:3200 → About.
   The exact-page link already gets aria-current from build.py; the sub-pages
   only marked their own link in the (closed) sub-row, so nothing showed in
   the bar. The page's sub-nav group (data-subnav, from pages.json) now marks
   its owner too. The rows stay closed: the client ruled on 08 Oct that the
   header never opens by itself, although the frames draw it open.        */
.site-header[data-subnav="services"] .site-header__link[data-opens="services"],
.site-header[data-subnav="results"]  .site-header__link[data-opens="results"],
.site-header[data-subnav="about"]    .site-header__link[data-opens="about"] {
  color: var(--content-accent);
}

/* --- 4. The sub-navigation ----------------------------------------------
   Three of the five header variants in the set are 113 tall instead of 61:
   Services (966:7456), Results (521:2698) and About (521:3038). The extra
   52 is a second row of links that hangs under the item that owns it —
   All services / Discovery Sprint under Services, Author Stories / Free
   Resources under Results, Our Team & Story / FAQ / Contact under About.

   Each sub-item sits on the SAME seven positions as the bar above it, one
   gutter right of its line. The plate under the row is the bar's own plate,
   grown by 52 across the full width, with the seven lines carried down
   through it (Figma "Group 75") — see item 12 below, 2026-10-15. Until then
   the plate covered only the group's own columns and the rest was bare.

   The block is a child of the <li> that opens it, so :hover and
   :focus-within on that item are the entire interaction — no script, and
   the pointer can travel down into the row without losing the hover
   because it never leaves the <li>'s subtree.

   It is an OVERLAY, not flow: on Services the hero deliberately starts at
   110 and runs up behind the whole header. A page whose first block is
   meant to start below the open row writes that into its own --gap.     */
/* The row is a frame box, not a window-wide one: every piece inside it —
   plate, rule, line copy, labels — is placed from --line-step, and the line
   copy is now anchored to the macket's 1440 frame (base.css §4.0). If this
   row stayed window-wide the plate would sit at 12.5 % of the window while
   the lines sat on the frame, and above 1440 they would come apart. */
.site-header__sub {
  position: absolute;
  top: 100%;
  left: 50%;
  width: min(100%, var(--layout-reference));
  transform: translateX(-50%);
  height: 52px;
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--t-fast) ease, visibility var(--t-fast);
  /* The nav box above is inert so it cannot swallow clicks meant for the
     page; this row is its own box and takes its own. */
  pointer-events: auto;
}

/* The block is a sibling of the menu, not a child of the item that opens it:
   the item is itself absolutely positioned, so a descendant would be laid
   out against that one narrow cell instead of across the header. :has()
   carries the relationship instead.

   Three states, in this order, and the order is the whole logic:

     1. a page that belongs to a group holds that group's row open;
     2. the moment the pointer or the caret lands on ANY opening item, every
        row closes — otherwise the page's own row and the hovered one draw
        on top of each other in the same 52px strip, which is what the
        header did on all seven section pages;
     3. the row belonging to what is actually being pointed at opens.

   Step 3 also keeps the row open while the pointer is inside it, so
   travelling down from the label into the links does not close it. */

/* 1 — REMOVED 2026-10-08 at the client's request. The page used to hold
   its own group's row open (Services, Results, About). The client: the
   header must never open by itself — only under the pointer or the caret,
   which is what the Figma component's open variants (set 504:2789) are.
   The current page is still marked in the bar (aria-current, amber). */

/* 2 — anything being pointed at or tabbed to closes all of them first */
.site-header:has(.site-header__link[data-opens]:hover) .site-header__sub,
.site-header:has(.site-header__link[data-opens]:focus-visible) .site-header__sub,
.site-header:has(.site-header__sub:hover) .site-header__sub,
.site-header:has(.site-header__sub:focus-within) .site-header__sub {
  opacity: 0;
  visibility: hidden;
}

/* 3 — and only the one being pointed at opens */
.site-header:has(.site-header__link[data-opens="services"]:hover) .site-header__sub[data-group="services"],
.site-header:has(.site-header__link[data-opens="services"]:focus-visible) .site-header__sub[data-group="services"],
.site-header:has(.site-header__sub[data-group="services"]:hover) .site-header__sub[data-group="services"],
.site-header:has(.site-header__sub[data-group="services"]:focus-within) .site-header__sub[data-group="services"],
.site-header:has(.site-header__link[data-opens="results"]:hover) .site-header__sub[data-group="results"],
.site-header:has(.site-header__link[data-opens="results"]:focus-visible) .site-header__sub[data-group="results"],
.site-header:has(.site-header__sub[data-group="results"]:hover) .site-header__sub[data-group="results"],
.site-header:has(.site-header__sub[data-group="results"]:focus-within) .site-header__sub[data-group="results"],
.site-header:has(.site-header__link[data-opens="about"]:hover) .site-header__sub[data-group="about"],
.site-header:has(.site-header__link[data-opens="about"]:focus-visible) .site-header__sub[data-group="about"],
.site-header:has(.site-header__sub[data-group="about"]:hover) .site-header__sub[data-group="about"],
.site-header:has(.site-header__sub[data-group="about"]:focus-within) .site-header__sub[data-group="about"] {
  opacity: 1;
  visibility: visible;
}

/* 2026-10-15, designer's review of 13 Oct, item 12 — the open header is one
   block. The group's own piece of the plate and its own clipped copy of the
   lines used to be drawn here, column by column; the rest of the 52 strip was
   bare and the page scrolled visibly under it. The file draws the open
   variants (Services 966:7456, Results 521:2698, About 521:3038) as one
   1440 x 113 "Rectangle 13" under bar and row together, with all seven lines
   carried down ("Group 75"). So: the bar's plate grows by the row whenever
   any group is open, and one line layer (.site-header__row) runs through
   the row at all seven positions. Only the rule (Line 39) and the links stay
   per group. */
.site-header__plate {
  transition: bottom var(--t-fast) ease;
}

.site-header__row {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  height: 52px;
  z-index: 0;
  pointer-events: none;
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--t-fast) ease, visibility var(--t-fast);
}

.site-header:has(.site-header__link[data-opens]:hover) .site-header__plate,
.site-header:has(.site-header__link[data-opens]:focus-visible) .site-header__plate,
.site-header:has(.site-header__sub:hover) .site-header__plate,
.site-header:has(.site-header__sub:focus-within) .site-header__plate {
  bottom: -52px;
}
.site-header:has(.site-header__link[data-opens]:hover) .site-header__row,
.site-header:has(.site-header__link[data-opens]:focus-visible) .site-header__row,
.site-header:has(.site-header__sub:hover) .site-header__row,
.site-header:has(.site-header__sub:focus-within) .site-header__row {
  opacity: 1;
  visibility: visible;
}

/* 2026-11-11 — touch. Client: «на планшеті у горизонтальному вʼю не
   відкриваються підменю у хедері». A tablet in landscape (1024 and up) gets
   this layer, and js/touch-hover.js turns every :hover rule off after a
   touch, so nothing above could open the rows by finger. js/header-touch.js
   marks the tapped group on the header (data-touch-open; first tap opens,
   second tap on the same label follows its link, a touch outside closes).
   Drawn exactly like the hovered state: the group's row, the plate grown by
   52, the line layer, the label in amber. Placed after the rules above on
   purpose: same weight (0,4,0), so the later rule wins over step 2. */
.site-header[data-touch-open="services"] .site-header__sub[data-group="services"],
.site-header[data-touch-open="results"]  .site-header__sub[data-group="results"],
.site-header[data-touch-open="about"]    .site-header__sub[data-group="about"],
.site-header[data-touch-open] .site-header__row {
  opacity: 1;
  visibility: visible;
}
.site-header[data-touch-open] .site-header__plate {
  bottom: -52px;
}
.site-header[data-touch-open="services"] .site-header__link[data-opens="services"],
.site-header[data-touch-open="results"]  .site-header__link[data-opens="results"],
.site-header[data-touch-open="about"]    .site-header__link[data-opens="about"] {
  color: var(--content-accent);
}

/* Figma "Line 39": 1px at y 62, i.e. the first pixel of this row, spanning
   exactly the group's columns. */
.site-header__sub-rule {
  position: absolute;
  top: 1px;
  height: var(--line-width);
  left: calc(var(--from) * var(--line-step));
  width: calc(var(--span) * var(--line-step) + var(--line-width));
  background: var(--line-color);
  z-index: 2;
}

.site-header__submenu {
  position: absolute;
  inset: 0;
  z-index: 3;
}

/* Macket: label baseline at y 76 within the 113 header, i.e. 15 into this
   row; same one-gutter offset from the line as the bar above. */
.site-header__subitem {
  position: absolute;
  top: 15px;
  left: calc(var(--n) * var(--line-step) + var(--layout-gutter));
  pointer-events: auto;
}

/* Sentence case, Base Regular — the one place on the site where a menu
   label is not set in capitals. */
.site-header__sublink {
  white-space: nowrap;
  transition: color var(--t-fast);
}

.site-header__sublink[aria-current="page"],
.site-header__sublink:hover,
.site-header__sublink:focus-visible {
  color: var(--content-accent);
}

/* ===== footer.css ===== */
/* ==========================================================================
   Site footer — Figma symbol 152:1464, instance 966:8527.
   Load AFTER css/base.css.

   Full window width, 415 tall in the macket, Vista Blue 1. The fill is
   opaque, so it covers the page's vertical line layer — the macket shows
   no lines inside the footer.

   Vertical rhythm, read off the macket (footer top = 0):

        50  logo, 15 tall
        83  hairline, full working area
        98  tagline          |  50   Company / Services / Contact headings
       134  social icons     |  98   first link of each column
       184  Barcelona office | 289   last link of the Services column
       339  hairline
       354  legal links and copyright
       415  foot

   The right-hand link block starts level with the logo, so the first
   hairline crosses it. That is why the two halves are one grid with fixed
   rows rather than two stacked blocks: the rules span both columns while
   the link block spans the rows above and below the first of them.
   ========================================================================== */

.site-footer {
  background: var(--vista-blue-1);
  padding-block: var(--layout-margin);
  min-height: 415px;
}

.site-footer__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  /* logo band · hairline · body · hairline · bottom bar */
  grid-template-rows: 33px var(--line-width) 255px var(--line-width) auto;
}

/* --- Logo --------------------------------------------------------------- */
.site-footer__logo {
  grid-column: 1;
  grid-row: 1;
  justify-self: start;
}

.site-footer__logo img {
  width: auto;
  height: 15px;
}

/* --- Hairlines ---------------------------------------------------------- */
.site-footer__rule {
  grid-column: 1 / -1;
  margin: 0;
  border: 0;
  height: var(--line-width);
  background: var(--rich-black-1);
}
.site-footer__rule--top    { grid-row: 2; }
.site-footer__rule--bottom { grid-row: 4; }

/* --- Left half: tagline, socials, office -------------------------------- */
.site-footer__brand {
  grid-column: 1;
  grid-row: 3;
}

.site-footer__tagline { margin-top: 14px; }

.site-footer__social {
  display: flex;
  align-items: center;
  gap: var(--layout-gutter);
  margin-top: var(--layout-gutter);
}

.site-footer__office {
  display: block;
  font-style: normal;
  margin-top: var(--layout-gutter);
}
.site-footer__office span { display: block; }

/* --- Right half: three link columns -------------------------------------
   Spans from the logo band down past the first hairline, exactly as in the
   macket. 169 wide each, 50 apart — two gutters.                          */
.site-footer__nav {
  grid-column: 2;
  grid-row: 1 / 4;
  align-self: start;
  display: flex;
  gap: calc(var(--layout-gutter) * 2);
}

.site-footer__col {
  display: flex;
  flex-direction: column;
  gap: 30px;
  width: 169px;
}

.site-footer__list {
  display: flex;
  flex-direction: column;
  gap: var(--layout-gutter);
  align-items: start;
}

/* 2026-10-15, designer's desktop review of 13 Oct, item 11: "after the
   Discovery Sprint link the rule follows at once; 50 between them, as in
   the macket" (footer 152:1464 — last Services link ends at 289, rule at
   339). The links carry `.u-trim` but are inline <a>, and text-box-trim does
   nothing on an inline box (CLAUDE.md trap), so each link kept its 19 px
   line box instead of its 11 px cap height: six of them pushed the column
   48 px down and left 2 px above the rule. Blockified, the trim applies and
   the column ends at 289 again. Same for the legal row, which made the
   footer 423 tall instead of 415. */
.site-footer__list a,
.site-footer__legal a {
  display: block;
}

/* --- Bottom bar --------------------------------------------------------- */
.site-footer__bottom {
  grid-column: 1 / -1;
  grid-row: 5;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--layout-gutter);
  margin-top: 14px;
}

.site-footer__legal {
  display: flex;
  flex-wrap: wrap;
  gap: var(--layout-gutter);
}

.site-footer__copy {
  text-align: right;
  white-space: nowrap;
}

/* --- Links -------------------------------------------------------------- */
.site-footer a {
  transition: color var(--t-fast);
}
.site-footer a:hover,
.site-footer a:focus-visible {
  color: var(--content-accent);
}

/* --- The reduced footer — Figma `Footer_min` 917:7587, 1440 x 319 --------
   Used by the two paid-traffic landing pages. Same brand block, same legal
   row, same hairline; the three site-map columns are replaced by "Contact"
   and two ways to reach us, and the second hairline is gone.

   Measured from the symbol: logo 50,50 · rule y 83 · tagline y 98 · social
   y 134 · office y 184 · legal row and copyright y 258. With the 50 page
   padding those become a 33 logo band, the rule, a 160 body and the bottom
   bar — 319 in total.                                                     */
.site-footer--min {
  min-height: 319px;
}

.site-footer--min .site-footer__grid {
  /* logo band · hairline · body · bottom bar */
  grid-template-rows: 33px var(--line-width) 160px auto;
}

/* "Contact" sits on the logo's line, hard right. */
.site-footer--min .site-footer__contact {
  grid-column: 2;
  grid-row: 1;
  justify-self: end;
  align-self: start;
}

/* WhatsApp and the address share the tagline's line, right aligned. */
.site-footer--min .site-footer__reach {
  grid-column: 2;
  grid-row: 3;
  justify-self: end;
  align-self: start;
  display: flex;
  gap: 50px;
  margin-top: 14px;
}

.site-footer--min .site-footer__reach a {
  transition: color var(--t-fast);
}
.site-footer--min .site-footer__reach a:hover,
.site-footer--min .site-footer__reach a:focus-visible {
  color: var(--content-accent);
}

/* The bottom bar moves up one row, since there is no second hairline. */
.site-footer--min .site-footer__bottom {
  grid-row: 4;
}

/* ===== up.css ===== */
/* ==========================================================================
   Scroll-to-top control — `Button_form` 657:4075, macket 50,235 · 61 × 72.
   Load AFTER css/base.css.

   Fixed to the window at the page margin, at the same y the file draws it,
   so it sits in the empty strip left of the first vertical line and clear of
   the header. The label is set on its side reading bottom to top, which is
   what makes the box taller than it is wide.
   ========================================================================== */

.site-up {
  position: fixed;
  left: var(--layout-margin);
  /* The file draws this at y 235 — a static position on a page that does not
     scroll. As a floating control at the same coordinate it sits on top of
     whatever band happens to be passing: the Services list on the homepage
     runs its blue fill from the page margin, and the button covered the first
     row's line. So it keeps the file's x and moves to the foot of the window,
     out of the reading column and where a back-to-top control is looked for. */
  bottom: var(--layout-margin);
  z-index: 11;                      /* over the header's 10 */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 25px;
  border: 0;
  background: var(--action-fill);
  color: var(--content-on-accent);
  box-shadow: inset 0 0 0 3px var(--action-fill);
  cursor: pointer;
  opacity: 0;
  transition: opacity var(--t-base) ease,
              background-color var(--t-fast) ease,
              box-shadow var(--t-fast) ease;
}

/* `hidden` is removed by the script; `data-shown` is what fades it in, so
   the control is never a dead button and never a flash on load. */
.site-up[data-shown] { opacity: 1; }

.site-up__label {
  writing-mode: vertical-rl;
  transform: rotate(180deg);        /* reads bottom to top, as in the file */
  white-space: nowrap;
}

/* pas → hov on Button_form: the fill empties, the amber stroke stays, and
   the box does not change size because the stroke is drawn inside. */
.site-up:hover,
.site-up:focus-visible {
  background: var(--action-fill-hover);
  box-shadow: inset 0 0 0 3px var(--action-border-hover);
}

/* 2026-10-15, designer's desktop review of 13 Oct, item 2 (and item 3 of the
   28 Sep review): "at the top, directly under the header, as in the macket;
   it should read as a bookmark". Main 1:3 draws `Button_form` 657:4066 at
   x 50 of the frame, 61 x 72, its top 52 below the header's foot (header
   50–111, button 163–235). The 52 is exactly the open sub-navigation row,
   so the bookmark hangs from the header and an open row never covers it.
   With the header pinned its foot is at 61, so the top is 61 + 52 = 113.
   Same x rule as the header's logo: 50 from the 1440 frame, not from the
   window. The tablet layer did the same on 14 Oct (css/t-header.css).
   Supersedes the move to the window's foot recorded above. Desktop only:
   the mobile layer restyles this element and stays as it is. */
@media (min-width: 1280px) {
  .site-up {
    left: calc(max(0px, (100% - var(--layout-reference)) / 2) + var(--layout-margin));
    top: calc(var(--header-height) + 52px);
    bottom: auto;
    width: 61px;
    height: 72px;
    padding: 0;
  }
}

/* 2026-10-27, designer's answer to our question "кнопка UP" (Q&A of 20 Oct):
   the bookmark stays where it is; "on hover over yellow it changes its
   colour to white (EEEAE3) where possible". The Button_form hov variant
   empties the fill, which over an Amber 4 band (TrustLine, the yellow form
   blocks) leaves an amber ring on amber — the button disappears. So on
   desktop the hovered and keyboard-focused button is filled Editorial
   White 4; the 3 px amber ring stays. On the page ground (also Editorial
   White 4) this looks exactly like the old empty fill, so only the case
   over yellow changes. Mouse only for hover, as the brief asks; the tablet
   press state lives in css/t-header.css and is not changed here. */
@media (min-width: 1280px) and (hover: hover) and (pointer: fine) {
  .site-up:hover {
    background: var(--editorial-white-4);
  }
}
@media (min-width: 1280px) {
  .site-up:focus-visible {
    background: var(--editorial-white-4);
  }
}

/* 2026-10-27, designer's answer (UP over yellow): where the button sits on
   an Amber 4 surface it turns Editorial White 4 by itself, the amber ring
   kept — js/up.js sets [data-on-amber]. Desktop and tablet only. */
@media (min-width: 768px) {
  .site-up.site-up[data-on-amber] {
    background: var(--editorial-white-4);
    box-shadow: inset 0 0 0 3px var(--action-border-hover);
  }
}

/* 2026-11-04, client («давай» to the UP fixes): while a call to action lies under it, the button steps aside
   (js/up.js sets [data-over-control]) and the tap reaches the page. */
.site-up.site-up[data-shown][data-over-control] {
  opacity: 0;
  pointer-events: none;
}

/* ===== consent.css ===== */
/* ==========================================================================
   Cookie consent banner — partials/consent.html, behaviour in js/track.js
   Not in the Figma file (added 2026-10-08). Everything here is a token or a
   type style the site already has: page ground, the 3 px Rich Black 1 rule,
   the Amber 4 action and ring, 15 px type, the 25 / 50 spacing steps.

   Desktop: copy left, three buttons right; the settings panel opens below
   across the full working area. Phone: one column, buttons share a row.

   The banner sits outside .page, so base.css's z-index pin (`.page > *` at
   1, specificity 0,4,0) does not reach it and a plain number is enough.
   ========================================================================== */

.consent {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 30;
  max-height: 100vh;
  overflow-y: auto;
  background: var(--surface-page);
  border-top: 3px solid var(--border-strong);
  color: var(--content-primary);
}
.consent[hidden],
.consent [hidden] { display: none !important; }

.consent__inner {
  box-sizing: border-box;
  width: min(100%, var(--layout-reference));
  margin-inline: auto;
  padding: 25px var(--layout-margin);
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  column-gap: 50px;
  row-gap: 25px;
}

.consent__copy { display: grid; gap: 10px; max-width: 80ch; }
.consent__title,
.consent__text { margin: 0; }
.consent__text { line-height: 1.5; }
.consent__link {
  color: inherit;
  text-decoration: underline;
  text-decoration-color: var(--border-accent);
  text-decoration-thickness: 2px;
  text-underline-offset: 3px;
}

.consent__actions { display: flex; gap: 15px; }

.consent__btn {
  min-width: 150px;
  min-height: 44px;
  padding: 0 25px;
  border: 3px solid var(--border-accent);
  border-radius: 0;
  background: transparent;
  font-family: inherit;
  color: var(--content-on-accent);
  cursor: pointer;
  transition: background-color var(--t-fast);
}
.consent__btn--fill { background: var(--action-fill); }
.consent__btn--fill:hover { background: var(--action-fill-hover); }
.consent__btn--line:hover { background: var(--action-fill); }
.consent__btn--text {
  min-width: 0;
  padding: 0 10px;
  border-color: transparent;
  text-decoration: underline;
  text-decoration-color: var(--border-accent);
  text-decoration-thickness: 2px;
  text-underline-offset: 5px;
}
.consent__btn--text:hover { border-color: var(--border-accent); }
.consent__btn:focus-visible,
.consent__box:focus-visible {
  outline: 3px solid var(--border-strong);
  outline-offset: 3px;
}

/* Settings panel: spans both columns under the copy and the buttons. */
.consent__panel {
  grid-column: 1 / -1;
  display: grid;
  gap: 15px;
  justify-items: start;
  padding-top: 25px;
  border-top: 1px solid var(--border-hairline);
}
.consent__row {
  display: grid;
  grid-template-columns: 22px 1fr;
  gap: 15px;
  align-items: start;
  max-width: 80ch;
  cursor: pointer;
}
.consent__label { display: grid; gap: 5px; line-height: 1.5; }
.consent__box {
  width: 22px;
  height: 22px;
  margin: 0;
  accent-color: var(--amber-4);
  cursor: pointer;
}
.consent__box:disabled { cursor: default; }

/* Phone: one column; the three buttons share the row. */
@media (max-width: 767.98px) {
  .consent__inner {
    grid-template-columns: 1fr;
    row-gap: 15px;
    padding: 15px 25px calc(15px + env(safe-area-inset-bottom));
  }
  .consent__actions { gap: 10px; }
  .consent__btn { flex: 1; min-width: 0; padding: 0 10px; }
  .consent__panel { padding-top: 15px; }
  .consent__panel .consent__btn { width: 100%; }
}

/* 2026-11-04 (live from main, merged into dev) — Tetiana Lipatova's cookie edits, Marketing
   thread of 02.11, her reply of 03.11 20:00, and the web-pages playbook rule
   «consent banner on mobile: a strip, not a wall» (under 15% of the viewport;
   the hero headline stays visible). Overrides the 2026-10-08 phone layout.
   - The three buttons look the same at every width: same size, colour, type
     and contrast (before: Accept filled, Reject outlined, Settings a text link).
   - Phone: the banner is a strip of at most 90 px when closed — one sentence,
     the title kept for screen readers only, three equal buttons of 34 px.
     Each button's touch area still reaches 44 px tall through ::after
     (CONTRACT_MOBILE §5: invisible area, nothing visible moves). */
.consent__actions .consent__btn { background: transparent; }
.consent__actions .consent__btn:hover { background: var(--action-fill); }

@media (max-width: 767.98px) {
  .consent__inner {
    row-gap: 5px;
    padding: 6px 15px calc(6px + env(safe-area-inset-bottom));
  }
  .consent__copy { gap: 0; }
  .consent__title {
    position: absolute;
    width: 1px; height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
  }
  .consent__text { font-size: 13px; line-height: 1.3; }
  .consent__actions { gap: 8px; }
  .consent__actions .consent__btn {
    position: relative;
    flex: 1 1 0;
    min-height: 34px;
    padding: 0 6px;
    border-width: 2px;
    font-size: 13px;
  }
  .consent__actions .consent__btn::after {
    content: "";
    position: absolute;
    left: 0; right: 0;
    top: -5px; bottom: -6px;
  }
  .consent__panel { padding-top: 10px; gap: 10px; }
  .consent__panel .consent__text,
  .consent__panel .t-base { font-size: 13px; }
}

/* 2026-11-12 — Tetiana Lipatova «він має бути в один рядок»: on a phone the
   closed banner is ONE row — the sentence on a single line, the two buttons
   beside it. Overrides the 2026-11-04 phone strip (sentence, then a row of
   buttons: 88 px, three rows at 390).
   - Her full sentence cannot fit one line next to two buttons at 360, so the
     phone shows a short text (.consent__short, aria-hidden) and keeps the full
     sentence for screen readers (.consent__full, visually hidden). Same for
     «Cookie Notice» → «Notice» and «Accept all» / «Reject all» → «Accept» /
     «Reject»: the hidden words stay in the markup, so a screen reader and the
     click label in js/track.js still get the full text.
   - The two buttons stay equal: one grid track size for both.
   - Touch areas unchanged: 34 px buttons, ::after to 45 px tall.
   - At 768 and up nothing changes: .consent__short is never shown there.
   - Measured at 360: text 168 px in a 175 px column; under 360 it may wrap. */
.consent__short { display: none; }

@media (max-width: 767.98px) {
  .consent__inner {
    grid-template-columns: minmax(0, 1fr) auto;
    column-gap: 10px;
    row-gap: 0;
  }
  .consent__text { white-space: nowrap; }
  .consent__short { display: inline; }
  .consent__text .consent__full,
  .consent__btn .consent__full {
    position: absolute;
    width: 1px; height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
  }
  .consent__actions {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: 1fr;
    gap: 8px;
  }
  .consent__actions .consent__btn { padding: 0 6px; }
  .consent__copy { min-width: 0; }
}
/* Under 360 (e.g. 320) the short text no longer fits beside the buttons:
   it may wrap there rather than run under them. */
@media (max-width: 359.98px) {
  .consent__text { white-space: normal; }
}

/* ===== call-popup.css ===== */
/* "Book a call" popup (2026-10-27, client request; partials/call-popup.html,
   js/call-popup.js). Not in the Figma file: built from the site's tokens.
   The widget brings its own styles (assets/booking/booking.css, loaded on the
   first open); this file is only the dialog shell, so every page stays light.

   Stacking: the dialog is opened with showModal(), so it sits in the browser's
   top layer, above every z-index on the page, including the `.page > *` pin
   in base.css (0,4,0) and the consent banner (30). The dialog lives in <body>,
   outside .page, so that pin never applies to it. Where showModal() is missing
   the script opens it as a plain fixed box (.is-fallback) at z-index 40:
   above the consent banner and the menus (20), and the same weight the
   Greenlight page gives its own modal.

   The dialog fills the window and scrolls by itself; the box is centred in
   it. A click on the dialog outside the box is a click on the backdrop. */
.call-popup {
  position: fixed;
  inset: 0;
  z-index: 40;
  width: 100%;
  height: 100%;
  max-width: none;
  max-height: none;
  margin: 0;
  padding: 32px 16px;
  border: 0;
  background: transparent;
  color: var(--content-primary);
  overflow-y: auto;
  overscroll-behavior: contain;
}
.call-popup:not([open]) { display: none; }
.call-popup[open] {
  display: flex;
  align-items: flex-start;
  justify-content: center;
}
.call-popup::backdrop { background: rgb(11 20 36 / 0.72); }   /* Rich Black 1 at 72 %, as on the Greenlight modal */
.call-popup.is-fallback { background: rgb(11 20 36 / 0.72); }

.call-popup__box {
  position: relative;
  width: 100%;
  max-width: 820px;          /* the widget's own max width (booking.css .avl) */
  margin: auto 0;
  padding: 64px 56px 44px;
  background: var(--surface-page);   /* Editorial White 4 */
  color: var(--content-primary);     /* Rich Black 1 */
  border: 1px solid var(--border-hairline);
}

/* Close: the site's amber square button (Base Up Black buttons, css/base.css
   action tokens): amber fill and a 3 px amber frame; on hover the fill goes
   and the frame stays. The cross is two 20 × 2 bars, as in the menus. */
.call-popup__close {
  position: absolute;
  top: 0;
  right: 0;
  width: 48px;
  height: 48px;
  display: grid;
  place-items: center;
  padding: 0;
  border: 3px solid var(--action-fill);
  background: var(--action-fill);
  color: var(--content-on-accent);
  cursor: pointer;
  transition: background 0.15s;
}
.call-popup__close:hover { background: var(--action-fill-hover); }
.call-popup__close:focus-visible { outline: 2px solid var(--content-primary); outline-offset: 2px; }
.call-popup__close span { position: relative; display: block; width: 20px; height: 20px; }
.call-popup__close span::before,
.call-popup__close span::after {
  content: "";
  position: absolute;
  left: 0;
  top: 9px;
  width: 20px;
  height: 2px;
  background: currentColor;
}
.call-popup__close span::before { transform: rotate(45deg); }
.call-popup__close span::after  { transform: rotate(-45deg); }

.call-popup__loading { margin: 0; color: var(--content-secondary); }

/* 2026-11-02, form audit: the required-field stars and the «* Required fields»
   line that /call (sections/call/k1.css) and the product pages carry since
   27–29 Oct. The dialog holds the same widget on every other page and had
   neither. Rules copied from k1.css; the shared widget is untouched. */
.call-popup #avl-booking .avl-field:has(input[required]) > span::after,
.call-popup #avl-booking .avl-fieldset legend::after { content: " *"; color: #9B1C1C; font-weight: 1000; }
.call-popup #avl-booking[data-step="contacts"] .avl-who::after { content: "* Required fields"; display: block; margin-top: 8px; font-size: 13px; color: rgba(11, 20, 36, .72); }

/* The page under the dialog does not scroll. A classic scrollbar's width is
   kept as padding so nothing shifts (the same pair as the tablet menu). */
html.is-call-popup-open {
  overflow: hidden;
  padding-right: var(--call-sbw, 0px);
}

/* Phone width: the dialog is the whole screen. */
@media (max-width: 767.98px) {
  .call-popup { padding: 0; }
  .call-popup__box {
    max-width: none;
    min-height: 100%;
    margin: 0;
    padding: 64px 16px 32px;
    border: 0;
  }
}

/* ===== forms.css ===== */
/* ==========================================================================
   Form fields — required star, "* Required fields" line, inline errors
   (2026-11-02, pre-release form audit). Behaviour in js/forms.js. Not in the
   Figma file: the macket's forms have one status line and no field errors.

   The star and its colour are the product pages' (products/authority,
   sections/call/k1.css: " *" in #9B1C1C, the booking widget's --avl-err),
   so every form on the site marks required fields the same way.

   Most of the site's forms sit on Vista Blue 1 (#7C9EC7). That red on it is
   3.0 : 1 — enough for the star and a rule (non-text, 3 : 1), not for 15 px
   words (4.5 : 1). So the note and the messages are Rich Black 1 (6.8 : 1),
   and the red marks a message as an error with a 3 px rule at its left, the
   booking widget's own error mark (assets/booking/booking.css, .avl-err).
   ========================================================================== */

:root { --form-error: #9B1C1C; }

.f-req::after {
  content: " *";
  color: var(--form-error);
  font-weight: 1000;
}

/* "* Required fields": the form's last line (2026-11-03, client: «"*" і
   пояснення вниз»; js/forms.js arrange). A footnote, so it takes the privacy
   line's size and its distance: 15 from the line above, the form's own gap
   taken off (--f-gap). In a grid it spans every column. */
.f-note {
  display: block;
  grid-column: 1 / -1;
  align-self: stretch;
  margin: calc(15px - var(--f-gap, 0px)) 0 0;
  font-size: 13px;
  line-height: 1.4;
  text-align: left;
  color: var(--content-primary);
}

/* Desktop: the status and privacy lines in the button's row, right of the
   button (2026-11-03, client: «текст під кнопкою винести праворуч від кнопки
   в ряд»). The row centres them on the button's height; on Contact and FAQ
   WhatsApp keeps the right end. The selectors carry form[data-ave-form] so
   they outrank each block's own margins for its status line. */
form[data-ave-form] .f-row {
  display: flex;
  align-items: center;
  gap: var(--layout-gutter);
}
form[data-ave-form] .f-side {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
}
form[data-ave-form] .f-side > [role="status"] {
  margin: 0;
}

/* Tablet, the same row: the button takes its label's width instead of the
   form's, and the reply line reads as on the desktop (Base Up). */
.is-t form[data-ave-form] .f-row {
  flex-direction: row;
}
.is-t form[data-ave-form] .f-row > [type="submit"] {
  flex: 0 0 auto;
  width: auto;
  padding-left: 25px;
  padding-right: 25px;
}
.is-t form[data-ave-form] .f-side > :not(.f-privacy) {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: flex-start;
  gap: 8px var(--layout-gutter);
  margin: 0;
  padding: 0;
}
.is-t form[data-ave-form] .f-side .t-base:not(.f-privacy) {
  text-transform: uppercase;
}
.is-t form[data-ave-form] [data-f-prompt]:not([data-f-prompt-on]) {
  display: none;
}
.is-t form[data-ave-form] .f-lead {
  display: contents;
}

.f-error {
  display: block;
  margin-top: 8px;
  padding-left: 8px;
  border-left: 3px solid var(--form-error);
  color: var(--content-primary);
  font-weight: 1000;
  line-height: 1.3;
}
/* After the button of a one-row form (js/forms.js): a row of its own. */
.f-error--row {
  flex: 1 0 100%;
  grid-column: 1 / -1;
  margin-top: 0;
}

/* The privacy line under every form (2026-11-02, client; js/forms.js). Not
   in Figma. Small type, the colour of the form's own words: Rich Black 1 on
   the Vista Blue and Amber plates and on the light page, which is what the
   forms already set. The link is .u-link-text (css/base.css). In a flex or
   grid form it takes a row of its own across every column.

   One distance on every form: 15 from the line above it
   (--f-privacy-space; a block may set its own, as the guides do for
   Figma's 25). The form's own row gap would add to the margin, so
   js/forms.js writes that gap into --f-gap and the margin takes it off. */
.f-privacy {
  display: block;
  flex: 0 0 auto;
  grid-column: 1 / -1;
  align-self: stretch;
  width: 100%;
  max-width: 100%;
  margin: calc(var(--f-privacy-space, 15px) - var(--f-gap, 0px)) 0 0;
  font-size: 13px;
  font-weight: 400;
  line-height: 1.4;
  letter-spacing: 0;
  text-transform: none;
  text-align: left;
  color: inherit;
}

/* iOS Safari zooms the page into any field set under 16 px when it takes
   focus, and does not zoom back. The site's field type is 15 px (t-base), so
   fields are 16 px wherever a phone or tablet can show them: the tablet and
   mobile layers, and any touch screen. On the mobile layer a single-line
   field is also brought to the 44 px touch target (CONTRACT_MOBILE.md). */
@media (max-width: 1279.98px), (hover: none) and (pointer: coarse) {
  input:not([type="radio"]):not([type="checkbox"]):not([type="hidden"]),
  textarea:not([hidden]) {   /* the :not()s outweigh the 15 px type classes */
    font-size: 16px;
  }
}
@media (max-width: 767.98px) {
  form[data-ave-form] input:not([type="radio"]):not([type="checkbox"]):not([type="hidden"]) {
    min-height: 44px;
  }
}

/* 2026-11-04, client (phone review): «поле Your Idea … зробити fixed, і коли людина вводить більше
   тексту, просто додавати скрол». Every lead form's text area keeps its
   drawn size; longer text scrolls inside it. */
form[data-ave-form] textarea {
  resize: none;
  overflow-y: auto;
}

/* 2026-11-04, client (tablet photos): «відступ між першим, другим та третім
   блоком велика». Every tablet lead form: Name | Email, Your idea and the
   button row stand 25 apart (the idea field was 50 under the email row). */
@media (min-width: 768px) and (max-width: 1279.98px) {
  .is-t form[data-ave-form] .tb-form__fields { row-gap: var(--t-gap); }
  .is-t form[data-ave-form] [class*="__field"]:not(.tb-form__field):has(> textarea) { margin-top: var(--t-gap); }   /* the grid forms (Contact, FAQ) space it by row-gap */
}

/* ===== main/s2.css ===== */
/* ==========================================================================
   Section 2+3 — hero and proof band
   Figma node 152:1613 · "Section 2+3 [bleed:both]" · 1440 x 1489
   Intent tag: bleed:both. The hairlines, the stepped lockup, the photograph
   and the TrustLine band all run to the window edge; the copy, the stat tiles
   and the press logos stay inside the working area.

   The macket composes the hero absolutely (nothing above y 690 is in flow),
   so the hero is a fixed 690px stage. Two lengths drive it:
     --work  the working area, exactly as .container computes it
     --edge  the distance from the window edge to the working area's left edge
   Anything that belongs to the working area is offset by --edge; anything
   drawn on the 180-step grid is written as a share of the window.
   ========================================================================== */

.s-s2 {
  position: relative;
}

/* --- Hero stage ---------------------------------------------------------- */
.s-s2__hero {
  --work: min(var(--layout-content), 100% - var(--layout-margin) * 2);
  --edge: calc((100% - var(--work)) / 2);
  position: relative;
  height: 690px;
}

/* --- Hero picture (152:1671) ----------------------------------------------
   2026-10-27, desktop review 20 Oct item 1 and the designer's answer "Hero
   picture": the photograph lies behind the video and behind the grid. In
   Main 1:3 it is the bottom-most layer, rotated -180° with x 1440 as its
   rotated origin, so its real box is x 0–1440, y 111–720 of the frame: from
   the header's foot (69 above this section, the --block-gap-first air) to
   the fourth hairline at 540. Width is the 1440 frame, centred, never the
   window — the designer's rule for every hero picture (review 20 Oct, items
   8, 13, 15). Between 1280 and 1440 the frame narrows and the picture is
   cropped from the right (cover, anchored left top), so the face keeps its
   place on the grid. The file is the image fill's own source, mirrored and
   cropped as the fill draws it (1672 × 707, 1.16× the slot).               */
.s-s2__picture {
  position: absolute;
  top: calc(-1 * var(--block-gap-first));
  left: 50%;
  width: min(100%, var(--layout-reference));
  height: 609px;
  transform: translateX(-50%);
  overflow: hidden;
  pointer-events: none;
}

.s-s2__picture img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: left top;
}

/* The section sits above the page's line layer (base.css), so over the
   picture the seven lines are drawn again, as the header does over its
   plate — same component, same --line-step, so they cannot drift. Only as
   far down as the picture; below it the page layer shows through.        */
.s-s2__lines {
  top: calc(-1 * var(--block-gap-first));
  bottom: auto;
  height: 609px;
}

/* --- Group 60 (152:1611) --------------------------------------------------
   Four horizontal hairlines at y 0 · 180 · 360 · 540, full window width. They
   are this block's own rules — the seven vertical lines are drawn once by the
   page layer and are never repeated in a section.                            */
.s-s2__rules {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.s-s2__rules span {
  position: absolute;
  left: 0;
  right: 0;
  height: var(--line-width);
  background: var(--border-hairline);
}

.s-s2__rules span:nth-child(1) { top: 0; }
.s-s2__rules span:nth-child(2) { top: 180px; }
.s-s2__rules span:nth-child(3) { top: 360px; }
.s-s2__rules span:nth-child(4) { top: 540px; }

/* --- Rectangle 17 / 18 / 19 -----------------------------------------------
   The stepped lockup. Macket: 180→361 at y 0, 360→541 at y 180, 0→361 at
   y 360, each 181 tall. 180 · 360 are the vertical grid positions, so the
   boxes are written as shares of the window (12.5 % is --line-step) and stay
   on the grid at every width. The extra 1px is the stroke, which sits inside
   the box and lands exactly on the line.                                     */
/* On the frame, not the window: --line-step is 12.5 % of the box it is used
   in, so a window-wide box put the stepped lockup on a 240 grid at 1920 while
   the page lines stayed on 180. */
.s-s2__boxes {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 50%;
  width: min(100%, var(--layout-reference));
  transform: translateX(-50%);
  pointer-events: none;
}

.s-s2__box {
  position: absolute;
  height: 181px;
  border: var(--line-width) solid var(--amber-4);
}

.s-s2__box--1 {
  top: 0;
  left: var(--line-step);
  width: calc(var(--line-step) + var(--line-width));
}

.s-s2__box--2 {
  top: 180px;
  left: calc(var(--line-step) * 2);
  width: calc(var(--line-step) + var(--line-width));
}

.s-s2__box--3 {
  top: 360px;
  left: 0;
  width: calc(var(--line-step) * 2 + var(--line-width));
}

/* --- Lockup copy ----------------------------------------------------------
   The four words read as one line — "Done for you · book publishing for
   experts" — so they stay one paragraph and are placed word by word. The
   paragraph covers the stage, so it passes pointer events through and only
   the words themselves take them back.                                       */
.s-s2__lockup {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 50%;
  width: min(100%, var(--layout-reference));
  transform: translateX(-50%);
  pointer-events: none;
}

.s-s2__lock {
  position: absolute;
  white-space: nowrap;
  pointer-events: auto;
}

/* Macket: right edge at 336, i.e. 25 inside the first box. */
.s-s2__lock--done {
  top: 138px;
  right: calc(100% - var(--line-step) * 2 - var(--line-width));
  margin-right: var(--layout-gutter);
}

/* Macket: right edge at 437, left edge at 385 — 25 inside the second box. */
.s-s2__lock--for {
  top: 205px;
  right: calc(100% - var(--line-step) * 2 - 77px);
}

.s-s2__lock--you {
  top: 248px;
  left: calc(var(--line-step) * 2);
  margin-left: var(--layout-gutter);
}

/* Macket x 386 — this one is working-area copy, flush with the headline. */
.s-s2__lock--tag {
  top: 386px;
  left: var(--edge);
}

/* --- Video poster ---------------------------------------------------------
   Macket: 821 x 594 at x 619, running off the right edge of the window. 619 is
   the working area's left edge plus 569, and 569 is where the copy column
   below starts, so the two share one left edge at every width. The height is
   held at 594 and the artwork covers from its top left corner, which keeps the
   poster, the frame and the video registered on one another as the box widens.
   ------------------------------------------------------------------------ */
/* The right edge is the FRAME's, not the window's. In the macket the poster
   ends at x 1440 — the frame edge, which at a 1440 window is also the window
   edge, which is why `right: 0` looked right there and nowhere else: at 1920
   the poster grew by 480 and ran out past the working area, which is what the
   comment reports. */
.s-s2__video {
  position: absolute;
  top: 46px;
  right: calc(max(0px, (100% - var(--layout-reference)) / 2));
  left: calc(var(--edge) + var(--work) * 0.4246269);   /* macket 569 of 1340 */
  /* 2026-10-27, client: the plate takes the video's own 16 : 9 (821 x 462,
     739 x 416 after the 0.9 below), was 594. 2026-11-02: as a ratio, not a
     fixed 462 — the width is 821 from 1440 up but narrower below, and a
     fixed height cropped the picture there. Same box from 1440 up. */
  aspect-ratio: 16 / 9;
  overflow: hidden;
  /* 2026-10-15, review 13 Oct item 3: the shape of Rectangle 15 (27:2039)
     is a plain box with one 150 radius corner — the path of Rectangle 14
     (20:2036) is "M821.5 0.5H150.5C67.66 0.5 0.5 67.66 0.5 150.5V594.5H821.5",
     and the poster's own black corner follows the same 150 circle to within
     a pixel. Clipping here shapes the poster and the video alike.          */
  border-top-left-radius: 150px;
  /* 2026-10-27, client: the video plate 10 % smaller, its right edge (the
     bleed) kept in place. */
  scale: 0.9;
  transform-origin: 100% 50%;
}

/* 2026-11-02: the media is our own <video> (s2.js); the poster is its
   poster attribute. It fills the clip box, so the radius and the outline
   are the figure's. Box and video are both 16 : 9: nothing is cut off. */
.s-s2__media {
  width: 100%;
  height: 100%;
  object-fit: cover;
  background: var(--rich-black-1);
}

/* Rectangle 14 (20:2036) — the 1px Amber 4 outline along the top, the curve,
   the left side and the bottom; the file draws no right side, because the
   poster runs to the frame edge there. Drawn on the clip box, so it can
   never separate from the photograph.                                      */
.s-s2__video::after {
  content: "";
  position: absolute;
  inset: 0;
  border: var(--line-width) solid var(--amber-4);
  border-right: 0;
  border-top-left-radius: 150px;
  pointer-events: none;
}

/* --- Play control ---------------------------------------------------------
   Group 122 (1796:13270), 100 × 100. In the file its centre is (1030, 343)
   and the poster's is (1029.5, 343), so it is centred on the poster box.
   2026-10-15, review 13 Oct item 4: one inline SVG copied from the file
   replaces the ring and arrow PNGs, whose arrow was stretched off centre.  */
.s-s2__play {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 100px;
  height: 100px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: none;
  cursor: pointer;
}

.s-s2__play-icon {
  width: 100%;
  height: 100%;
}

.s-s2__play-ring  { fill: var(--editorial-white-4); }
.s-s2__play-arrow { fill: var(--rich-black-1); }

/* base.css paints a white plate behind every :focus-visible element; on a
   round control over a photograph that reads as a white square, so the
   plate is dropped here and only the 3px accent ring stays.             */
.s-s2__play:focus-visible {
  background: none;
}

/* --- Video controls, all three layers ---------------------------------------
   2026-11-02, founders: pause and sound on the plate itself (s2.js). Not in
   Figma; drawn in the play mark's language — an Editorial White 4 disc, a
   Rich Black 1 glyph — with the site's Amber 4 for hover. Unscoped because
   the tablet (t1) and mobile (m1) plates carry the same markup; this file
   ships with the home page on every layer. Each layer sets the size and the
   inset through the two custom properties. Shown on hover with a mouse,
   always on a touch screen, always while the video is paused, and whenever
   a control has the keyboard. */
.hero-video .hero-video__play[hidden] { display: none; }

.hero-video__bar {
  position: absolute;
  right: var(--video-inset-x, var(--video-inset, 20px));
  bottom: var(--video-inset, 20px);
  z-index: 1;
  display: flex;
  gap: var(--video-gap, 10px);
}
.hero-video:not(.is-ready) .hero-video__bar { display: none; }

.hero-video__btn {
  display: grid;
  place-items: center;
  width: var(--video-btn, 48px);
  height: var(--video-btn, 48px);
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: var(--editorial-white-4);
  color: var(--rich-black-1);
  cursor: pointer;
  transition: background-color 0.2s;
}
.hero-video__btn svg {
  width: 24px;
  height: 24px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.5;
}
.hero-video__btn .hero-video__fill { fill: currentColor; stroke: none; }
.hero-video__btn[aria-pressed="true"] .hero-video__if-unpressed,
.hero-video__btn[aria-pressed="false"] .hero-video__if-pressed { display: none; }

@media (hover: hover) and (pointer: fine) {
  .hero-video__bar {
    opacity: 0;
    transition: opacity 0.2s;
  }
  .hero-video:hover .hero-video__bar,
  .hero-video:focus-within .hero-video__bar,
  .hero-video.is-paused .hero-video__bar { opacity: 1; }
  .hero-video__btn:hover { background: var(--amber-4); }
}
@media (prefers-reduced-motion: reduce) {
  .hero-video__bar,
  .hero-video__btn { transition: none; }
}

/* Desktop plate: 52 discs, 47 after the plate's 0.9. The right inset puts the
   bar's edge on the working area's (50 from the frame edge, 56 before the
   scale); the plate itself runs on to the frame edge. */
.s-s2__video {
  --video-btn: 52px;
  --video-inset: 28px;
  --video-inset-x: 56px;
  --video-gap: 12px;
}

/* --- Headline -------------------------------------------------------------
   Macket: "YOUR EXPERTISE / INTO A BOOK" cap top at y 640, 544 wide; the
   handwritten "TURN" is live text in Comforter, cap top at y 590, laid over
   the first line and drawn above it.                                         */
.s-s2__head {
  position: absolute;
  top: 640px;
  left: var(--edge);
}

.s-s2__title {
  display: block;
  max-width: 544px;
}

.s-s2__accent {
  position: absolute;
  top: -50px;
  left: 0;
  z-index: 1;
  white-space: nowrap;
}

/* --- Body -----------------------------------------------------------------
   Frame 15: the copy column right aligned in the working area, 150 clear of
   the stat row, then 25 clear of the TrustLine band.                         */
.s-s2__body {
  padding-bottom: var(--layout-gutter);
}

.s-s2__copy {
  width: 57.5373%;         /* macket 771 of 1340 */
  margin-left: auto;
  margin-bottom: 150px;
  display: flex;
  flex-direction: column;
  gap: 50px;
}

.s-s2__lead,
.s-s2__aside {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--layout-gutter);
}

.s-s2__lede {
  width: 98.9624%;         /* macket 763 of 771 — holds the three-line break */
}

.s-s2__note {
  max-width: 70.5577%;     /* macket 544 of 771 */
}

/* --- Button_form ----------------------------------------------------------
   Two variants of the same component. Filled: amber plate, hover drops the
   fill to nothing and leaves the 3px accent stroke. Outlined: no fill, 3px
   Rich Black 1 stroke, hover takes the stroke to the accent. Both strokes are
   drawn inset so the resting and hovered boxes are the same size, which is
   also why the macket's 61px height holds with a 3px stroke and 25 padding.  */
.s-s2__cta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: var(--layout-gutter);
  color: var(--rich-black-1);
  transition: background-color var(--t-fast) linear, box-shadow var(--t-fast) linear;
}

.s-s2__cta--fill {
  background: var(--amber-4);
  box-shadow: inset 0 0 0 3px var(--action-fill-hover);   /* fully transparent */
}

.s-s2__cta--fill:hover {
  background: var(--action-fill-hover);
  box-shadow: inset 0 0 0 3px var(--action-border-hover);
}

.s-s2__cta--outline {
  background: var(--action-fill-hover);
  box-shadow: inset 0 0 0 3px var(--border-strong);
}

.s-s2__cta--outline:hover {
  box-shadow: inset 0 0 0 3px var(--action-border-hover);
}

/* --- Main_S3_Card ---------------------------------------------------------
   Five tiles across the working area: 248 wide with the gutter between them
   adds up to 1340 exactly, so equal columns reproduce the macket and narrow
   with the working area rather than wrapping.                                */
.s-s2__stats {
  display: flex;
  gap: var(--layout-gutter);
}

.s-s2__stat {
  flex: 1 1 0;
  min-width: 0;
  padding: 46px var(--layout-gutter) 47px;
  background: var(--vista-blue-1);
  color: var(--content-on-brand);
  text-align: center;
}

.s-s2__stat-num {
  margin-bottom: var(--layout-gutter);
}

/* 2026-10-15, review 13 Oct item 5: the Hov variant of Main_S3_Card
   (prop=S3_Card/Hov, 27:2202) is the same tile on Amber 4 instead of
   Vista Blue 1 — copy, size and type unchanged. Pointer devices only, so a
   tap on a touch screen does not leave a tile stuck amber.               */
@media (hover: hover) and (pointer: fine) {
  .s-s2__stat {
    transition: background-color var(--t-fast) linear;
  }
  .s-s2__stat:hover {
    background: var(--amber-4);
  }
}

/* --- TrustLine (287:758) --------------------------------------------------
   Amber band, 104 tall, full window width: 25 of padding, a 54 tall row, 25.
   The five logos keep their macket sizes and sit on their own baselines
   inside that row, exactly as the component places them.                     */
.s-s2__trust {
  height: 104px;
  display: flex;
  align-items: center;
  background: var(--amber-4);
  overflow: hidden;
}

.s-s2__trust-row {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  height: 54px;
}

.s-s2__logo {
  flex: 0 0 auto;
}

/* 2026-10-15, review 13 Oct item 6: the Hov variants of TrustLine (260:691
   Forbes, 260:685 IngramSpark, 260:735 NewYork, 260:708 Barnes, 260:728
   BBC) are the same marks recoloured from Rich Black 1 to Editorial White 4.
   All five PNGs are single-colour on transparency, so each is used as a
   mask over a token fill rather than shipped twice: the <img> keeps the
   size, the alt text and the link target, and is only made transparent.
   Pointer devices only, as the brief asks.                                */
.s-s2__logo {
  display: block;
  background-color: var(--rich-black-1);
  -webkit-mask: var(--logo) no-repeat 0 0 / 100% 100%;
          mask: var(--logo) no-repeat 0 0 / 100% 100%;
}

.s-s2__logo img {
  opacity: 0;
}

/* 2026-10-27: four marks are now the designer's SVGs (same Rich Black 1
   #0B1424 fill, same boxes). The 250x34 NYT and 175x50 BBC boxes are not
   the marks' own ratio; the PNGs stretched to fill them, so those two SVGs
   carry preserveAspectRatio="none" to stretch the same way and not shift.
   IngramSpark stays PNG: its Drive "SVG" is a wrapped raster.            */
.s-s2__logo--forbes      { --logo: url("../assets/s2-logo-forbes.svg?v=c22ce1ee"); }
.s-s2__logo--ingramspark { --logo: url("../assets/s2-logo-ingramspark.png?v=70ed1f58"); }
.s-s2__logo--nyt         { --logo: url("../assets/s2-logo-new-york-times.svg?v=f94105cf"); }
.s-s2__logo--barnes      { --logo: url("../assets/s2-logo-barnes-and-noble.svg?v=e3d816ce"); }
.s-s2__logo--bbc         { --logo: url("../assets/s2-logo-bbc.svg?v=9bf20b52"); }

@media (hover: hover) and (pointer: fine) {
  .s-s2__logo {
    transition: background-color var(--t-fast) linear;
  }
  .s-s2__logo:hover {
    background-color: var(--editorial-white-4);
  }
}

/* The logo's own focus ring stays (base.css); its white focus plate would
   be masked to the mark's shape and read as a hover, so it is dropped.   */
.s-s2__logo:focus-visible {
  background-color: var(--rich-black-1);
}

/* Macket: each logo's top offset inside the 54 tall row. */
.s-s2__logo--forbes      { margin-top: 3px; }
.s-s2__logo--ingramspark { margin-top: 14px; }
.s-s2__logo--nyt         { margin-top: 16px; }
.s-s2__logo--barnes      { margin-top: 11px; }
.s-s2__logo--bbc         { margin-top: 2px; }

/* 2026-10-27, client: the TrustLine is a running line (marquee), like the
   mobile band (review 20 Oct, mobile item 3). s2.js appends a second,
   aria-hidden copy of the five marks; the row slides left by exactly one
   set and starts over, so the seam is never seen. Each mark carries the
   gap as right margin, so both halves are the same width. The band stops
   under the pointer (so a logo can be hovered and clicked) and for
   keyboard focus; with reduced motion it stands still and the copy hides. */
.s-s2__trust-row.is-marquee {
  /* The band is a flex box: without flex-shrink 0 the row was squeezed to
     the window, so -50 % was not one set and the loop jumped (2026-10-27). */
  flex: 0 0 auto;
  width: max-content;
  margin-inline: 0;
  margin-left: max(var(--layout-margin), (100% - var(--layout-content)) / 2);
  justify-content: flex-start;
  animation: s-s2-marquee 80s linear infinite;
}
.s-s2__trust-row.is-marquee > .s-s2__logo { margin-right: 120px; }
.s-s2__trust:hover .s-s2__trust-row.is-marquee,
.s-s2__trust-row.is-marquee:focus-within { animation-play-state: paused; }
@keyframes s-s2-marquee {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}
@media (prefers-reduced-motion: reduce) {
  .s-s2__trust-row.is-marquee {
    animation: none;
    width: auto;
    justify-content: space-between;
  }
  .s-s2__trust-row.is-marquee > .s-s2__logo { margin-right: 0; }
  .s-s2__trust-row.is-marquee > [aria-hidden="true"] { display: none; }
}

/* 2026-10-27, client: two more press marks, eLearning Industry and LTEN
   (Focus on Training) — taken from their sites, recoloured to the single
   Rich Black of the other five, centred in the 54 row. */
.s-s2__logo--elearning-industry { --logo: url("../assets/s2-logo-elearning-industry.png?v=8b67b256"); margin-top: 5px; }
.s-s2__logo--lten               { --logo: url("../assets/s2-logo-lten.png?v=a3bb2fac"); margin-top: 7px; }

/* ===== main/s4.css ===== */
/* ==========================================================================
   Section 4 — "Who do we write for"
   Figma node 152:1615 · "Section 4 [bleed:both]" · 1440 x 1458
   Intent tag: bleed:both. The brand surface runs the full window width; the
   two expert blocks stay inside the working area.
   ========================================================================== */

.s-s4 {
  position: relative;
  background: var(--vista-blue-1);
  /* macket: the left amber block and the centre rule both run to y 1458,
     150px below the bottom of the taller expert block. */
  padding-bottom: 150px;
}

/* --- Headline -------------------------------------------------------------
   Macket: "DO WE WRITE FOR" cap top at y 100, 544 wide, centred on the page
   axis. The handwritten "WHO" is live text in Comforter laid over it, its cap
   top at y 50 and its left edge at x 596 — 124 left of the 720 axis.
   min-height holds the block row at y 331 exactly as in the macket.          */
.s-s4__head {
  position: relative;
  min-height: 331px;
  padding-top: 100px;
}

.s-s4__title {
  display: block;
  width: 544px;
  margin-inline: auto;
  text-align: center;
}

.s-s4__accent {
  position: absolute;
  top: 50px;
  left: 50%;
  transform: translateX(-124px);
  color: var(--editorial-white-4);
  white-space: nowrap;
}

/* --- The two expert blocks ------------------------------------------------
   Macket: row at y 331, x 164 to 1276, two 506 columns with 100 between them,
   so each column sits 50 clear of the centre axis. The columns shrink with
   the working area and stay symmetrical about the rule.                      */
.s-s4__cols {
  position: relative;
  display: flex;
  justify-content: center;
  align-items: flex-start;
  gap: 100px;
}

.s-s4__col {
  flex: 0 1 506px;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: var(--layout-gutter);
}

/* --- Centre rule ----------------------------------------------------------
   Macket: an open amber ring at y 232 (50 x 50, drawn rotated 180), a 25 long
   segment at y 281, then the long rule from y 331 to the foot of the section.
   All three are 3px amber strokes — this is the accent rule, not one of the
   seven 1px page grid lines, which this section's surface covers anyway.
   Anchoring the rule to the block row keeps its head level with the top of
   the wellness photograph at every width.                                    */
.s-s4__rule {
  position: absolute;
  left: 50%;
  top: 0;
  bottom: -150px;
  width: 3px;
  margin-left: -1.5px;
  background: var(--amber-4);
}

.s-s4__rule::before {
  content: "";
  position: absolute;
  left: 0;
  width: 100%;
  top: -50px;
  height: 25px;
  background: var(--amber-4);
}

.s-s4__rule-mark {
  position: absolute;
  left: 50%;
  top: -99px;
  /* No rotation. The exported ring already carries the orientation it has on
     the canvas — its gap faces left, which is what turns the ring plus the
     rule below it into a question mark. Turning it 180 here mirrored the gap
     to the right and the mark read upside down. */
  transform: translateX(-50%);
}

/* --- Block copy -----------------------------------------------------------
   Macket: the two words of the kicker step 43 apart on the cap height, which
   is the gutter once the cap trim is applied; "EXPERTS" is indented 114 of the
   506 column in the business block and flush left in the wellness block.      */
.s-s4__kicker {
  display: flex;
  flex-direction: column;
  gap: var(--layout-gutter);
}

.s-s4__kicker-in {
  margin-left: 22.529%;   /* macket 114 of 506 */
}

.s-s4__lede--right {
  padding-left: 22.529%;  /* macket 114 of 506, ragged left, flush right */
  text-align: right;
}

.s-s4__lede--left {
  padding-left: 15.020%;  /* macket 76 of 506 */
}

/* --- Button_form ----------------------------------------------------------
   Right aligned in the business block, left aligned in the wellness block.
   Hover drops the fill and leaves the 3px accent stroke; the inset stroke
   keeps the resting and hovered boxes the same size.                         */
.s-s4__cta {
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 25px;
  background: var(--amber-4);
  color: var(--rich-black-1);
  box-shadow: inset 0 0 0 3px var(--action-fill-hover);   /* the token is fully transparent */
  transition: background-color var(--t-fast) linear, box-shadow var(--t-fast) linear;
}

.s-s4__col--business .s-s4__cta {
  align-self: flex-end;
}

.s-s4__cta:hover {
  background: var(--action-fill-hover);
  box-shadow: inset 0 0 0 3px var(--action-border-hover);
}

/* --- Photographs and their amber blocks -----------------------------------
   Macket: the business block's amber rectangle runs off the left edge of the
   window and stops 114 into the photograph; the wellness block's amber band
   starts 190 into the photograph and runs off the right edge. Where the amber
   crosses a photograph the file drops it to 50 %, so each is drawn twice: the
   solid part outside the frame and the tinted part over it. The offsets into
   the frame are written as shares of the frame so the band keeps its place on
   the picture as the working area narrows.                                   */
.s-s4__photo {
  position: relative;
}

.s-s4__band,
.s-s4__tint {
  position: absolute;
  background: var(--amber-4);
  pointer-events: none;
}

.s-s4__tint {
  opacity: 0.5;
}

/* 2026-10-15, review 13 Oct item 7: the solid rectangle stopped at the
   photograph's left edge (164) while the tint over the photograph stopped
   at 278, so in the 25 strip above the photograph the two edges sat 114
   apart. In the file Rectangle 26 (38:127) is one rectangle, x 0 to 278,
   y 25 above the photograph to the foot of the section, lying UNDER the
   photograph, and the mask Rectangle 28 (46:145) repeats the same 0 to 278
   over it. So the band now runs to the tint's edge (114 of 506 into the
   frame) and the photograph is lifted above it; the wellness band is
   treated the same way (Rectangle 30 46:150 and Rectangle 31 46:151 both
   start at x 960, 190 of 506 into its frame).                            */
.s-s4__photo img {
  position: relative;   /* paints above the band, below the tint */
}

/* 2026-10-27, desktop review 20 Oct item 3 (the designer still sees the
   two edges apart). Measured again: at 1280 / 1440 / 1920, device pixel
   ratio 1 and 2, the band and the tint end on the same device pixel; at
   ratio 1.5 and 1366 they were one device pixel apart. The cause: the band's
   edge was `right: 77.471%` and the tint's `width: 22.529%` — two numbers,
   each a rounded 114 of 506 and 392 of 506, snapped separately. Both edges
   are now the SAME expression on the SAME box (the figure), so they resolve
   to one layout value and one pixel at any width and any zoom. Figma: both
   Rectangle 26 (38:127) and its mask copy Rectangle 28 (46:145) end at
   x 278, i.e. 114 of the 506 photograph.                                  */
.s-s4__band--business,
.s-s4__tint--business {
  right: calc(100% * 392 / 506);   /* edge at 114 of 506 */
}

.s-s4__band--business {
  top: -25px;
  bottom: -150px;   /* meets the foot of the section */
  left: -100vw;
}

.s-s4__tint--business {
  top: 0;
  bottom: 0;
  left: 0;
}

.s-s4__band--wellness {
  top: 6.667%;      /* macket 50 of 750 */
  height: 13.333%;  /* macket 100 of 750 */
  left: calc(100% * 190 / 506);   /* the tint's left edge — under the photograph */
  right: -100vw;
}

.s-s4__tint--wellness {
  top: 6.667%;
  height: 13.333%;
  left: calc(100% * 190 / 506);   /* macket 190 of 506, same expression as the band */
  right: 0;
}

/* 2026-10-27, client: the photograph comes alive on hover — a slow 4 % zoom
   inside its own frame. The frame cannot clip (the amber band runs outside
   it), so the picture clips itself: inset 1.923 % = (1 - 1 / 1.04) / 2 keeps
   the scaled picture exactly inside the original box. Mouse only; no motion
   for visitors who ask for less. */
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .s-s4__photo img {
    transition: transform 700ms cubic-bezier(.2, .7, .2, 1),
                clip-path 700ms cubic-bezier(.2, .7, .2, 1);
    clip-path: inset(0);
  }
  .s-s4__photo:hover img {
    transform: scale(1.04);
    clip-path: inset(1.923%);
  }
}

/* 2026-10-27, client: the Business portrait turns to the camera on hover.
   Two frames of one shoot (Pexels, Darina Belonogova, 7959585 / 7959593),
   aligned on the head; the second fades in over the first. */
.s-s4__photo img.is-turn {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
}
/* 2026-11-02, client: the second frame should come through the first «as if
   the person turns the head». Both frames drift 1.2 % the way the face turns
   (--turn: 1 to the right, -1 to the left) while the second fades in over
   1.5 s, so the features travel instead of doubling. Each picture still clips
   itself to the original box: the inset moves against the drift. */
.s-s4__photo { --turn: -1; }  /* 2026-11-02 set: both look to the right, then turn left to the camera */
.s-s4__col--wellness .s-s4__photo { --turn: -1; }
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .s-s4__photo img { transition: transform 1500ms cubic-bezier(.45, 0, .2, 1), clip-path 1500ms cubic-bezier(.45, 0, .2, 1), opacity 1500ms cubic-bezier(.45, 0, .2, 1); }
  .s-s4__photo:hover img:not(.is-turn) {
    transform: scale(1.04) translateX(calc(var(--turn) * 1.2%));
    clip-path: inset(1.923% calc(1.923% + var(--turn) * 1.2%) 1.923% calc(1.923% - var(--turn) * 1.2%));
  }
  .s-s4__photo img.is-turn {
    transform: scale(1.04) translateX(calc(var(--turn) * -1.2%));
    clip-path: inset(1.923% calc(1.923% - var(--turn) * 1.2%) 1.923% calc(1.923% + var(--turn) * 1.2%));
  }
  .s-s4__photo:hover img.is-turn { opacity: 1; transform: scale(1.04); clip-path: inset(1.923%); }
}

/* 2026-11-04, client: «і те і інше … людина може бути з мишкою і пальцем одночасно». On a device with a touch screen the turn also plays on scroll
   (s4.js sets .is-on when the photo reaches the middle of the screen) —
   next to the mouse hover above, not instead of it. */
@media (prefers-reduced-motion: no-preference) {
  .s-s4__photo.is-on img { transition: transform 1500ms cubic-bezier(.45, 0, .2, 1), clip-path 1500ms cubic-bezier(.45, 0, .2, 1), opacity 1500ms cubic-bezier(.45, 0, .2, 1); }
  .s-s4__photo.is-on img:not(.is-turn) {
    transform: scale(1.04) translateX(calc(var(--turn) * 1.2%));
    clip-path: inset(1.923% calc(1.923% + var(--turn) * 1.2%) 1.923% calc(1.923% - var(--turn) * 1.2%));
  }
  .s-s4__photo.is-on img.is-turn { opacity: 1; transform: scale(1.04); clip-path: inset(1.923%); }
}

/* ===== main/s5.css ===== */
/* ==========================================================================
   Section 5 — "When your expertise is bigger than your visibility…"
   Figma node 152:1616 · "Section 5 [flow]" · 1340 x 613
   Card component: Main_S5_Card, node 55:142 (variants S5_Card/Pas, /Hov)
   Intent tag: flow. The three cards are one row that wraps when it stops
   fitting; nothing bleeds, so the whole section lives in the working area.
   ========================================================================== */

.s-s5 {
  position: relative;
  /* The section box starts at the cap top of the handwritten "WHEN"; the
     Mulish headline begins 50 lower. */
  padding-top: 50px;
}

.s-s5__inner {
  display: flex;
  flex-direction: column;
}

/* --- Headline -------------------------------------------------------------
   Macket: headline cap top at y 50, flush left, full 1340 wide, broken after
   "YOUR EXPERTISE". The handwritten "WHEN" is live text in Comforter, amber,
   laid over it with its cap top at y 0 and its left edge on the working area. */
.s-s5__head {
  position: relative;
}

.s-s5__title {
  display: block;
}

.s-s5__accent {
  position: absolute;
  top: -50px;
  left: 0;
  white-space: nowrap;
}

/* --- Subheading -----------------------------------------------------------
   Macket: 430 wide at x 910 — the last four columns of the grid, so it stays
   pinned to the right edge of the working area as the columns narrow.        */
.s-s5__subrow {
  margin-top: var(--layout-gutter);
}

.s-s5__sub {
  grid-column: 9 / span 4;
}

/* --- Cards ----------------------------------------------------------------
   Macket: three 430 cards at y 322 with the 25 gutter between them, which is
   the full 1340 across. Main_S5_Card carries a hover variant that swaps the
   brand surface for the accent.                                              */
.s-s5__cards {
  /* 2026-11-04, client (Redmi Pad Pro landscape, 1280): «чому розтягується блок? чому вони тоді не поруч ідуть?» — the row keeps its cards side by side at every desktop width; each card takes an equal share instead of wrapping the last one onto a stretched row of its own. */
  --flow-basis: calc((100% - var(--layout-gutter) * 2) / 3 - 0.1px);
  margin-top: 100px;
}

.s-s5__card {
  padding: 25px;
  background: var(--vista-blue-1);
  transition: background-color var(--t-base) linear;
}

.s-s5__card:hover {
  background: var(--amber-4);
}

/* Macket: the body sits 43 below the title on the cap height, which is the
   gutter once the cap trim is applied, and is indented 50 inside the card. */
.s-s5__card-body {
  margin-top: var(--layout-gutter);
  padding-left: 50px;
}

/* --- Closing line ---------------------------------------------------------
   Macket: 884 wide, flush left — eight columns of the grid.                  */
.s-s5__closerow {
  margin-top: 100px;
}

.s-s5__close {
  grid-column: 1 / span 8;
}

/* ===== main/s6.css ===== */
/* ==========================================================================
   Section 6 — How it works
   Figma: Main / node 1344:8263, instance of How_it_works_main (66:554).
   The component carries seven stacked variants (00–06); here it is one arc
   with the steps as data. The arc never moves: the stops ride it, the open
   step always sits at the arc's rightmost point.

   Macket coordinates are 1440-wide frame coordinates. The stage below is the
   1340 working area, so every macket x is written here as x − 50.
   Arc: Figma "Ellipse 7", 1150 box at (−442, −25) with a 1px stroke, i.e.
   centre (83, 550) and radius 574.5 in stage coordinates.
   ========================================================================== */

.s-s6 {
  position: relative;
  height: 1100px;
  overflow: hidden;
  background: var(--surface-brand);
}

.s-s6__stage {
  position: relative;
  height: 100%;
}

/* --- Heading ------------------------------------------------------------
   "HOW" (Comforter) is laid over "IT WORKS" and paints above it, so it comes
   first in the DOM and is lifted with z-index rather than reordered.       */
.s-s6__accent {
  position: absolute;
  z-index: 1;
  top: 50px;
  left: 0;
  white-space: nowrap;
  color: var(--editorial-white-4);
}

.s-s6__title {
  position: absolute;
  top: 100px;
  left: 0;
  width: 100%;
  color: var(--content-on-brand);
}

/* --- The arc ------------------------------------------------------------
   Static. Clipped by the section on the left, top and bottom.             */
.s-s6__arc {
  position: absolute;
  top: -25px;
  left: -492px;
  pointer-events: none;
}

/* Stroke colours live here, not on the SVG: var() is a CSS value and does
   not resolve inside an XML presentation attribute.                        */
.s-s6__arc circle {
  stroke: var(--editorial-white-4);
}

/* --- The dial -----------------------------------------------------------
   Each stop is a zero-size origin at the circle centre, rotated by its
   offset from the open step. Its children then sit on the local x axis,
   which is the radius, so a child at x = 574.5 lands on the arc and one at
   x = 631.5 lands the 57px further out that the macket puts the numerals.
   The open step is offset 0, so it is not rotated at all.                 */
.s-s6__dial {
  position: absolute;
  inset: 0;
}

.s-s6__stop {
  position: absolute;
  top: 550px;
  left: 83px;
  width: 0;
  height: 0;
  display: none;
  transform: rotate(var(--s6-angle, 0deg));
}

.s-s6__stop[data-offset="-2"] { display: block; --s6-angle: -60deg; }
.s-s6__stop[data-offset="-1"] { display: block; --s6-angle: -30deg; }
.s-s6__stop[data-offset="0"]  { display: block; --s6-angle:   0deg; }
.s-s6__stop[data-offset="1"]  { display: block; --s6-angle:  30deg; }
.s-s6__stop[data-offset="2"]  { display: block; --s6-angle:  60deg; }

.s-s6__bullet {
  position: absolute;
  top: 0;
  left: 574.5px;
  margin: -7.5px 0 0 -7.5px;
  width: 15px;
  height: 15px;
  border-radius: 50%;
  background: var(--editorial-white-4);
}

.s-s6__stop[data-offset="0"] .s-s6__bullet {
  background: var(--rich-black-1);
}

.s-s6__num {
  position: absolute;
  top: 0;
  left: 631.5px;
  margin: -17.5px 0 0 -31.5px;
  width: 63px;
  height: 35px;
  padding: 0;
  border: 0;
  background: none;
  text-align: left;
  color: var(--editorial-white-4);
  cursor: pointer;
}

.s-s6__stop[data-offset="0"] .s-s6__num {
  color: var(--content-on-brand);
  cursor: default;
}

/* --- The open step ------------------------------------------------------
   In the macket the title's cap box is centred on the arc point and the body
   sits 25 below it, whether the title runs to one line or two. Centring the
   title alone and taking the body out of flow reproduces that without
   measuring either of them.                                                */
.s-s6__steps {
  position: absolute;
  top: 550px;
  right: 0;
  left: 771px;
}

.s-s6__step {
  position: absolute;
  top: 0;
  right: 0;
  left: 0;
  transform: translateY(-50%);
}

.s-s6__step[hidden] { display: none; }

.s-s6__steptitle {
  color: var(--content-on-brand);
}

.s-s6__stepbody {
  position: absolute;
  top: calc(100% + 25px);
  left: 0;
  width: 100%;
  max-width: 366px;
  color: var(--content-on-brand);
}

/* --- Chevrons -----------------------------------------------------------
   The pair occupies 500–625; with only one button left it right-aligns to
   625, which is where the macket puts the lone chevron on steps 00 and 06. */
.s-s6__nav {
  position: absolute;
  top: 525px;
  left: 500px;
  display: flex;
  justify-content: flex-end;
  gap: var(--layout-gutter);
  width: 125px;
}

.s-s6__chev {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 50px;
  height: 50px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: var(--action-fill);
  box-shadow: inset 0 0 0 3px var(--action-fill);
  cursor: pointer;
  transition: background-color var(--t-base), box-shadow var(--t-base);
}

.s-s6__chev[hidden] { display: none; }

.s-s6__chev:hover {
  background: var(--action-fill-hover);
  box-shadow: inset 0 0 0 3px var(--action-border-hover);
}

.s-s6__chev path {
  stroke: var(--content-on-accent);
}

.s-s6__chev--prev svg { transform: rotate(180deg); }

/* --- Call to action ------------------------------------------------------ */
.s-s6__cta {
  position: absolute;
  top: 989px;
  right: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 25px;
  white-space: nowrap;
  color: var(--content-on-accent);
  background: var(--action-fill);
  box-shadow: inset 0 0 0 3px var(--action-fill);
  transition: background-color var(--t-base), box-shadow var(--t-base);
}

.s-s6__cta:hover {
  background: var(--action-fill-hover);
  box-shadow: inset 0 0 0 3px var(--action-border-hover);
}

/* ===== main/s7.css ===== */
/* ==========================================================================
   Section 7 — Client voices
   Figma: Main / node 152:1617 "Section 7 [flow]", 1340 × 572.
   Card component Main_S7_Card (76:696), variants Pas (76:695) and Hov
   (76:694). Three cards of 430 on the flow gutter of 25 — the full working
   area — so the row is .is-flow with the card width as its basis.
   ========================================================================== */

.s-s7 {
  position: relative;
}

/* --- Heading block ------------------------------------------------------
   572 = 178 (this block) + 394 (the cards). The three lines are centred on
   the working area; "CLIENT" is laid over "VOICES" and paints above it, so
   it comes first in the DOM and is lifted with z-index.                    */
.s-s7__head {
  position: relative;
  height: 178px;
}

.s-s7__accent {
  position: absolute;
  z-index: 1;
  top: 0;
  left: 50%;
  transform: translateX(-50%);
  white-space: nowrap;
  color: var(--content-accent);
}

.s-s7__title {
  position: absolute;
  top: 50px;
  left: 50%;
  transform: translateX(-50%);
  width: 544px;
  text-align: center;
  color: var(--content-primary);
}

.s-s7__sub {
  position: absolute;
  top: 110px;
  left: 50%;
  transform: translateX(-50%);
  white-space: nowrap;
  color: var(--content-primary);
}

/* The clip path lives in a zero-size <svg> and must not take up any room. */
.s-s7__defs {
  position: absolute;
  width: 0;
  height: 0;
  overflow: hidden;
}

/* --- Cards --------------------------------------------------------------- */
.s-s7__cards {
  /* 2026-11-04, client (Redmi Pad Pro landscape, 1280): «чому розтягується блок? чому вони тоді не поруч ідуть?» — the row keeps its cards side by side at every desktop width; each card takes an equal share instead of wrapping the last one onto a stretched row of its own. */
  --flow-basis: calc((100% - var(--layout-gutter) * 2) / 3 - 0.1px);
}

.s-s7__card {
  position: relative;
  height: 394px;
  background: var(--surface-brand);
  transition: background-color var(--t-base);
}

/* Main_S7_Card / Hov — the plate turns amber, nothing else moves. */
.s-s7__card:hover {
  background: var(--surface-accent);
}

/* --- Portrait -----------------------------------------------------------
   A 125 × 226 window at (25, 25) cut to the irregular outline of the file's
   vector mask (76:680), with the 235 × 242 photograph sitting behind it at
   (−57, −13) so the crop lands where the macket puts it.                   */
.s-s7__portrait {
  position: absolute;
  top: 25px;
  left: 25px;
  width: 125px;
  height: 226px;
  overflow: hidden;
}

.s-s7__portrait img {
  /* The export from Figma already carries the mask: the cut is baked into the
     file and the area outside it is the card's own Vista Blue, so the shape
     needs no clip-path here and cannot drift from the design. */
  display: block;
  width: 125px;
  height: 226px;
}

/* --- Card text ----------------------------------------------------------
   Content box 380 wide from the top edge at 126. The name and role sit in a
   230 column pushed to the right edge of that box; the quote runs its full
   width, 84 below.                                                          */
.s-s7__body {
  position: absolute;
  top: 126px;
  right: 25px;
  left: 25px;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 84px;
  color: var(--content-on-brand);
}

.s-s7__who {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--layout-gutter);
  /* 2026-11-04: at 1280 the card is ~377 wide, and a fixed 230 ran under the
     portrait (body-relative 0–125). The column takes what is right of the
     portrait plus 20, never more than the file's 230. */
  width: min(230px, 100% - 145px);
  max-width: 100%;
}

.s-s7__name,
.s-s7__role {
  width: 100%;
}

.s-s7__quote {
  width: 100%;
}

/* ===== main/s8.css ===== */
/* ==========================================================================
   Section 8 — Case Studies carousel
   Figma: Main / Section 8, node 86:356 (instance of Main_S8_Frame, 86:325)
   Inner card: Main_S8_inside_card, node 86:188
   Macket 1440 x 546. Content band 50 -> 496, working area 50 -> 1390.
   ========================================================================== */

.s-s8 {
  padding-block: 50px;
}

/* The row is nine columns of picker + cover + text, three columns of aside.
   Macket: aside 50..366, stage 391..1390.                                   */
.s-s8__inner {
  align-items: stretch;
}

/* --- Aside: headline, rotated line, arrows ------------------------------- */
.s-s8__aside {
  grid-column: 1 / span 3;
  position: relative;
}

/* Accent cap top at macket y 50, Mulish heading cap top at y 100.
   Both are trimmed, so the 50px padding is the exact macket offset.         */
.s-s8__head {
  position: relative;
  padding-top: 50px;
}
.s-s8__head-accent {
  position: absolute;
  top: 0;
  left: 0;
  white-space: nowrap;
}
.s-s8__head-main {
  display: block;
  white-space: nowrap;
}

/* Macket x 278 = 228 of the working area = 72.09 % of the three-column
   aside; y 189, i.e. 139 below the content band top. Rotated 90 degrees,
   reading downwards — writing-mode does that without a transform.           */
.s-s8__rotated {
  position: absolute;
  top: 139px;
  left: 72.09%;
  writing-mode: vertical-rl;
  white-space: nowrap;
}

/* Macket x 50 and 125, y 446..496 — flush with the bottom of the band.      */
.s-s8__nav {
  position: absolute;
  left: 0;
  bottom: 0;
  display: flex;
  gap: var(--layout-gutter);
}
.s-s8__arrow {
  flex: none;
  width: 50px;
  height: 50px;
  display: grid;
  place-items: center;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: var(--amber-4);
  cursor: pointer;
  transition: background-color var(--t-fast), box-shadow var(--t-fast);
}
.s-s8__arrow:hover {
  background: var(--action-fill-hover);
  box-shadow: inset 0 0 0 3px var(--action-border-hover);
}
/* 2026-10-27, desktop review 20 Oct item 7: the chevron is inline SVG from
   Arrow_graphic_button pas1 (269:1451), the same glyph and size as the How
   it works chevrons; the stroke colour comes from tokens here. */
.s-s8__arrow svg {
  display: block;
}
.s-s8__arrow path {
  stroke: var(--content-on-accent);
}

/* --- Stage: picker, large cover, text ----------------------------------- */
.s-s8__stage {
  grid-column: 4 / -1;
  display: grid;
  grid-template-columns: repeat(9, 1fr);
  gap: var(--layout-gutter);
  align-items: end;
  min-height: 446px;
}

/* Three covers per row, one column each. A fourth and any further entry
   wraps onto a row above — the list is managed and is not capped at four.   */
.s-s8__thumbs {
  grid-column: span 3;
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--layout-gutter);
}
.s-s8__thumbs > li {
  flex: 0 0 calc((100% - var(--layout-gutter) * 2) / 3);
}

.s-s8__thumb {
  position: relative;
  display: block;
  width: 100%;
  aspect-ratio: 89 / 126;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  transition: transform var(--t-base);
}
.s-s8__thumb img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
/* Passive state is the desaturated cover, hover swaps in the colour one. */
.s-s8__thumb-color {
  opacity: 0;
  transition: opacity var(--t-base);
}
/* Hover raises the cover 10px and leaves a 3px accent rule on the baseline
   it came from — component variant Hov, 136px tall against 126px passive.   */
.s-s8__thumb::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: calc(100% + 7px);
  height: 3px;
  background: var(--amber-4);
  opacity: 0;
  transition: opacity var(--t-base);
}
.s-s8__thumb:hover,
.s-s8__thumb:focus-visible {
  transform: translateY(-10px);
}
.s-s8__thumb:hover .s-s8__thumb-color,
.s-s8__thumb:focus-visible .s-s8__thumb-color,
.s-s8__thumb:hover::after,
.s-s8__thumb:focus-visible::after {
  opacity: 1;
}

.s-s8__cover {
  grid-column: span 3;
}
.s-s8__cover img {
  width: 100%;
  aspect-ratio: 316 / 446;
  object-fit: cover;
}

/* The text block is centred against the full height of the cover; the
   button is pinned to the bottom of the band, macket y 435..496.            */
.s-s8__meta {
  grid-column: span 3;
  align-self: stretch;
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.s-s8__meta-text {
  display: flex;
  flex-direction: column;
  gap: 100px;
}
.s-s8__meta-head {
  display: flex;
  flex-direction: column;
  gap: var(--layout-gutter);
}

.s-s8__cta {
  position: absolute;
  left: 0;
  bottom: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 25px;
  background: var(--amber-4);
  color: var(--rich-black-1);
  white-space: nowrap;
  transition: background-color var(--t-fast), box-shadow var(--t-fast);
}
.s-s8__cta:hover {
  background: var(--action-fill-hover);
  box-shadow: inset 0 0 0 3px var(--action-border-hover);
}

/* --- Labels for the icon-only arrows ------------------------------------ */
.s-s8__sr {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ===== main/s9.css ===== */
/* ==========================================================================
   Section 9 — Services. Intent tag: fluid.
   Figma: Main / "Section 9 [fluid]", node 152:1618, 1340 x 1239.
   Row component: Main_S9_Card, node 86:448.
   The block runs margin to margin, macket x 50 -> 1390, and narrows with
   the working area. Every offset below is a macket y, measured from the
   cap top of the handwritten word, which is the section's own top edge.
   ========================================================================== */

.s-s9 {
  /* One derived column of the twelve, used for the intro's six-column
     measure. The column width is never written down, only derived.        */
  --s9-column: calc((100% - var(--layout-gutter) * 11) / 12);
}

/* --- Heading ------------------------------------------------------------ */
.s-s9__head {
  text-align: center;
}

/* "SERVICES" sits at y 0, "FOR YOU" at y 50. Both are trimmed to the cap
   height, so the padding is the macket offset exactly.                      */
.s-s9__title {
  position: relative;
  padding-top: 50px;
}
.s-s9__title-accent {
  position: absolute;
  top: 0;
  left: 50%;
  transform: translateX(-50%);
  white-space: nowrap;
}
.s-s9__title-main {
  display: block;
}

/* y 110 — 25 below the cap bottom of the heading. */
.s-s9__sub {
  margin-top: 25px;
}

/* y 178 — 50 below the subheading. Six columns wide, centred. */
.s-s9__intro {
  width: calc(var(--s9-column) * 6 + var(--layout-gutter) * 5);
  margin-top: 50px;
  margin-inline: auto;
}

/* --- Rows --------------------------------------------------------------- */
/* y 258 — 50 below the intro. Five rows, 25 apart, each the full width of
   the working area.                                                         */
.s-s9__list {
  display: flex;
  flex-direction: column;
  gap: var(--layout-gutter);
  margin-top: 50px;
}

.s-s9__row {
  display: block;
  padding: 50px;
  background: var(--vista-blue-1);
  color: var(--rich-black-1);
  transition: background-color var(--t-base), color var(--t-base);
}
/* Variant S9_Card/Hov: the surface turns accent and every line, the price
   included, drops to the primary text colour.                               */
.s-s9__row:hover {
  background: var(--amber-4);
  color: var(--rich-black-1);
}

.s-s9__row-top {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--layout-gutter);
}
.s-s9__name,
.s-s9__price {
  white-space: nowrap;
}
.s-s9__price {
  color: var(--editorial-white-4);
  text-align: right;
}
.s-s9__row:hover .s-s9__price {
  color: inherit;
}

.s-s9__desc {
  display: block;
  margin-top: 25px;
}

/* --- Button ------------------------------------------------------------- */
/* y 1178 — 50 below the last row, centred on the working area. */
.s-s9__actions {
  margin-top: 50px;
  text-align: center;
}
.s-s9__cta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 25px;
  background: var(--amber-4);
  color: var(--rich-black-1);
  white-space: nowrap;
  transition: background-color var(--t-fast), box-shadow var(--t-fast);
}
.s-s9__cta:hover {
  background: var(--action-fill-hover);
  box-shadow: inset 0 0 0 3px var(--action-border-hover);
}

/* "from" and "/month" step down to Base so the figure carries the line. The
   size comes from the scale, not from a new value: 25 → 15, the two steps
   the type system already has. */
.s-s9__affix {
  font-size: 15px;
}

/* ===== main/s10.css ===== */
/* ==========================================================================
   Section 10 — Discovery Sprint.  Figma node 152:1619, 1188 x 900.
   Intent tag: bleed:left. The block runs off the LEFT window edge; its right
   edge is pinned to macket x = 1188, i.e. 1138 from the working area's left
   edge, so --bleed-stop is 1 - 1138 / 1340 = 15.075 %.
   Every horizontal measure inside the block is written as a share of the
   macket frame width (1188), so the composition holds while the frame
   narrows between 1200 and 1440. Vertical offsets that are tied to type
   stay in pixels, exactly as they are in the file.
   ========================================================================== */

.s-s10 .s-s10__bleed {
  --bleed-stop: 15.075%;
  position: relative;
  padding-top: 485px;          /* macket y of the panel column */
}

/* --- Amber band, macket 0 - 935 x 0 - 225 -------------------------------- */
.s-s10 .s-s10__band {
  position: absolute;
  left: 0;
  top: 0;
  width: 78.7037%;             /* 935 / 1188 */
  height: 225px;
  background: var(--amber-4);
  z-index: 0;
}

/* --- Photo, macket 253,50 · 935 x 526 ------------------------------------ */
.s-s10 .s-s10__media {
  position: absolute;
  left: 21.2963%;              /* 253 / 1188 */
  top: 50px;
  width: 78.7037%;             /* 935 / 1188 */
  margin: 0;
  z-index: 1;
}

.s-s10 .s-s10__media img {
  width: 100%;
  aspect-ratio: 935 / 526;
  object-fit: cover;
}

/* The band, at half opacity, carried across the top of the photo. In the
   file this is the same rectangle masked by the photo; the intersection is
   935 - 253 wide and 225 - 50 tall, measured from the photo's own corner.  */
.s-s10 .s-s10__tint {
  position: absolute;
  left: 0;
  top: 0;
  width: 72.9412%;             /* 682 / 935 */
  height: 175px;
  background: var(--amber-4);
  opacity: 0.5;
}

/* --- "DISCOVERY" over "SPRINT", centred on the photo --------------------- */
.s-s10 .s-s10__lockup {
  position: absolute;
  left: 60.6061%;              /* 720 / 1188 — the photo's centre line */
  top: 300px;
  width: 55.3872%;             /* 658 / 1188 */
  transform: translateX(-50%);
  display: grid;
  text-align: center;
  z-index: 2;
}

.s-s10 .s-s10__lockup > * {
  grid-area: 1 / 1;
}

.s-s10 .s-s10__script {
  color: var(--editorial-white-4);
  z-index: 1;                  /* the handwriting sits over the Mulish word */
}

.s-s10 .s-s10__word {
  margin-top: 50px;
  color: var(--amber-4);
}

/* --- Panel + button column, macket 505,485 · 430 wide -------------------- */
.s-s10 .s-s10__col {
  position: relative;
  z-index: 3;
  margin-left: 42.5084%;       /* 505 / 1188 */
  width: 36.1953%;             /* 430 / 1188 */
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--layout-gutter);
}

/* 2026-10-27, client: the spacing inside the panel looked uneven — 25 above
   the title, 50 under the price (Frame 33 110:252 draws it so: Frame 32 at
   y 25, 254 tall in a 329 frame). The inner padding is now equal, 50 top and
   bottom; the sides stay 25, so the text keeps the file's 380 width, and the
   25 gaps between the lines are the file's. The button stays where the file
   puts it: outside the panel, 25 under it, centred (Button_form 110:249). */
.s-s10 .s-s10__panel {
  width: 100%;
  background: var(--vista-blue-1);
  padding: 50px var(--layout-gutter);
}

.s-s10 .s-s10__panel-in {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--layout-gutter);
  text-align: center;
  color: var(--rich-black-1);
}

.s-s10 .s-s10__lead,
.s-s10 .s-s10__copy,
.s-s10 .s-s10__price {
  width: 100%;
}

.s-s10 .s-s10__price {
  color: var(--editorial-white-4);
}

/* --- Button_form --------------------------------------------------------
   The border is the same colour as the fill at rest, so the box does not
   change size when the hover state empties the fill.                       */
.s-s10 .s-s10__cta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 22px;
  border: 3px solid var(--action-fill);
  background: var(--action-fill);
  color: var(--rich-black-1);
  cursor: pointer;
  transition: background-color var(--t-fast) ease, border-color var(--t-fast) ease;
}

.s-s10 .s-s10__cta:hover,
.s-s10 .s-s10__cta:focus-visible {
  background: var(--action-fill-hover);
  border-color: var(--action-border-hover);
}

/* ===== main/s11.css ===== */
/* ==========================================================================
   Section 11 — "OUR TEAM".  Figma node 152:1620, 1440 x 1099.
   Two behaviours in one block, exactly as the handoff tags it:
     · the block itself is bleed:both — the roller runs the full window width
       and clips, so the card after the last visible one is cut by the edge;
     · the row of four cards under "HOW WE WORK WITH AUTHORS" is flow — it
       wraps as soon as four no longer fit.
   The roller is a managed list. The cards are built in sections/s11.js from
   a data array, so the list takes more than the eight people in the macket.
   ========================================================================== */

.s-s11 {
  /* The macket's grid, expressed against the live window, so the roller —
     which is outside the working area — can still line its first card up
     with the left margin and land the fourth card's edge on the right one. */
  --s11-work: min(var(--layout-content), 100vw - var(--layout-margin) * 2);
  --s11-side: calc((100vw - var(--s11-work)) / 2);
  --s11-col:  calc((var(--s11-work) - var(--layout-gutter) * 11) / 12);
  --s11-card: calc(var(--s11-col) * 3 + var(--layout-gutter) * 2);  /* 316 */
}

/* --- "OUR" written over "TEAM", centred on the window ------------------- */
.s-s11 .s-s11__lockup {
  display: grid;
  justify-items: center;
  text-align: center;
}

.s-s11 .s-s11__lockup > * {
  grid-area: 1 / 1;
}

.s-s11 .s-s11__script {
  color: var(--amber-4);
  white-space: nowrap;
  z-index: 1;                  /* the handwriting sits over the Mulish word */
}

.s-s11 .s-s11__word {
  margin-top: 50px;
  color: var(--rich-black-1);
}

.s-s11 .s-s11__sub {
  margin: var(--layout-gutter) auto 0;
  max-width: 700px;
  text-align: center;
  color: var(--rich-black-1);
}

/* --- Roller ------------------------------------------------------------- */
.s-s11 .s-s11__roller {
  margin-top: var(--layout-gutter);
  padding-block: var(--layout-gutter);
}

.s-s11 .s-s11__viewport {
  overflow: hidden;
}

.s-s11 .s-s11__track {
  display: flex;
  align-items: center;
  gap: var(--layout-gutter);
  padding-left: var(--s11-side);
  transform: translate3d(var(--s11-shift, 0px), 0, 0);
  transition: transform var(--t-base) ease;
  will-change: transform;
}

.s-s11 .s-s11__card {
  position: relative;
  flex: 0 0 var(--s11-card);
  aspect-ratio: 316 / 450;
}

.s-s11 .s-s11__photo {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* The amber block is a 150 x 150 square on a 316 x 450 card. */
.s-s11 .s-s11__plate {
  position: absolute;
  left: 0;
  top: 0;
  width: 47.4684%;
  height: 33.3333%;
  background: var(--amber-4);
}

.s-s11 .s-s11__meta {
  position: absolute;
  left: 7.9114%;               /* 25  / 316 */
  top: 5.5556%;                /* 25  / 450 */
  width: 84.1772%;             /* 266 / 316 — the widest thing it holds, the quote */
  display: flex;
  flex-direction: column;
  gap: 10px;
  color: var(--rich-black-1);
}

/* The name and the role sit in a 166 column in BOTH states — only the quote
   uses the full 266. Letting them have the quote's width ran "project
   manager" and "lead generation specialist" out past the 150 amber plate in
   the passive state, over the photograph. */
.s-s11 .s-s11__name {
  width: 62.4060%;             /* 166 / 266 */
  display: flex;
  flex-direction: column;
  gap: 10px;
}

/* --- Hover: the Team_cards Hov variant ----------------------------------
   The amber block grows from its 150 x 150 corner to the whole 316 x 450
   card, the photograph goes behind it, and the person's line and their
   social link appear. The quote and the link are always in the markup —
   hidden by opacity, not by display — so the card does not reflow and the
   link stays reachable from the keyboard.                                  */
.s-s11 .s-s11__card {
  --s11-plate-w: 47.4684%;     /* 150 / 316 */
  --s11-plate-h: 33.3333%;     /* 150 / 450 */
}

/* 2026-11-04, client: «і те і інше … людина може бути з мишкою і пальцем одночасно»: a tap opens the card too (.is-active, s11.js), next to the mouse hover. */
.s-s11 .s-s11__card:hover,
.s-s11 .s-s11__card:focus-within,
.s-s11 .s-s11__card.is-active {
  --s11-plate-w: 100%;
  --s11-plate-h: 100%;
}

.s-s11 .s-s11__plate {
  width: var(--s11-plate-w);
  height: var(--s11-plate-h);
  transition: width var(--t-base) ease, height var(--t-base) ease;
}

.s-s11 .s-s11__quote {
  margin-top: 65px;            /* macket: role at 67, quote at 153 */
  opacity: 0;
  transition: opacity var(--t-fast) ease;
}

.s-s11 .s-s11__social {
  position: absolute;
  left: 7.9114%;               /* 25 / 316 */
  top: 88.8889%;               /* 400 / 450 */
  display: block;
  opacity: 0;
  transition: opacity var(--t-fast) ease;
}

.s-s11 .s-s11__card:hover .s-s11__quote,
.s-s11 .s-s11__card:focus-within .s-s11__quote,
.s-s11 .s-s11__card:hover .s-s11__social,
.s-s11 .s-s11__card:focus-within .s-s11__social,
.s-s11 .s-s11__card.is-active .s-s11__quote,
.s-s11 .s-s11__card.is-active .s-s11__social {
  opacity: 1;
  transition-delay: 120ms;     /* let the plate arrive first */
}

/* --- Counter and next arrow -------------------------------------------- */
.s-s11 .s-s11__pager {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 21.213px;
  margin-top: var(--layout-gutter);
}

.s-s11 .s-s11__counter {
  color: var(--amber-4);
}

/* In the macket the arrow sits 115 px to the right of the counter's centre
   line, not on a grid line, so the offset is kept as a distance.          */
.s-s11 .s-s11__next {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(115px, -50%);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  transition: opacity var(--t-fast) ease;
}

.s-s11 .s-s11__next:hover,
.s-s11 .s-s11__prev:hover {
  opacity: 0.6;
}

/* 2026-10-15, review 13 Oct item 8: the back arrow. In Home_S11_Roller_2
   (115:940) the back chevron 115:731 ends at x 615.2, i.e. 104.8 left of
   the counter's centre line, while the next chevron 115:732 starts 115
   right of it. The same asset family as the next arrow, mirrored by the
   file itself (icon-arrow-prev.svg). */
.s-s11 .s-s11__prev {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(calc(-105px - 100%), -50%);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  transition: opacity var(--t-fast) ease;
}

/* The arrows are flex boxes, so the hidden attribute needs saying out loud. */
/* 2026-10-27, desktop review 20 Oct item 7: both chevrons are inline SVG of
   Main_S11_Arrows Pas (115:577) as the file exports it — 12.728 x 21.213,
   two 15 px lines, 3 px, butt ends — the same glyph and size as every other
   desktop carousel. They replace 13 x 21 PNGs. Colour from tokens.        */
.s-s11 .s-s11__prev svg,
.s-s11 .s-s11__next svg {
  display: block;
}
.s-s11 .s-s11__prev path,
.s-s11 .s-s11__next path {
  stroke: var(--rich-black-1);
}

.s-s11 .s-s11__next[hidden],
.s-s11 .s-s11__prev[hidden] {
  display: none;
}

/* --- Lede, six columns against the right margin ------------------------ */
.s-s11 .s-s11__lede {
  width: 49.0299%;             /* 657 / 1340 */
  margin-left: auto;
  margin-top: var(--layout-gutter);
  color: var(--rich-black-1);
}

.s-s11 .s-s11__label {
  margin-top: 50px;
  color: var(--rich-black-1);
}

/* --- "How we work with authors" — flow, wraps when four stop fitting ---- */
.s-s11 .s-s11__how {
  /* 2026-11-04, client (Redmi Pad Pro landscape, 1280): «чому розтягується блок? чому вони тоді не поруч ідуть?» — the row keeps its cards side by side at every desktop width; each card takes an equal share instead of wrapping the last one onto a stretched row of its own. */
  --flow-basis: calc((100% - var(--layout-gutter) * 3) / 4 - 0.1px);
  margin-top: var(--layout-gutter);
}

.s-s11 .s-s11__how-card {
  display: flex;
  border: 3px solid var(--rich-black-1);
  padding: var(--layout-gutter) var(--layout-gutter) 50px;
}

/* 2026-10-15, review 13 Oct item 9: hover state of the four cards. The
   review names the set Main_S3_Card, but these four are instances of
   Main_S11_Card (120:1106 · 120:1111 · 120:1115 · 120:1119), and its Hov
   variant 120:1084 changes one thing: the 3px stroke goes from Rich Black 1
   to Amber 4. Main_S3_Card is the stat tile set, whose hover is item 5.
   Pointer devices only. */
@media (hover: hover) and (pointer: fine) {
  .s-s11 .s-s11__how-card {
    transition: border-color var(--t-fast) linear;
  }
  .s-s11 .s-s11__how-card:hover {
    border-color: var(--amber-4);
  }
}

.s-s11 .s-s11__how-in {
  display: flex;
  flex-direction: column;
  gap: var(--layout-gutter);
  width: 100%;
  color: var(--rich-black-1);
}

/* 2026-10-27, client ("where is the grammar?"): the role keeps its own
   capitals — "Founder / COO", "Head of Product" — instead of the lowercase
   of Base Down Black; weight and size stay the style's. */
.s-s11 .s-s11__role { text-transform: none; }

/* 2026-10-27, client ("the role is cut off"): with its own capitals the role
   is wider and ran past the 150 amber plate at 1280. It now wraps inside the
   plate: 150 less 25 padding each side = 100 of the card, of the 166 column. */
.s-s11 .s-s11__role { max-width: 60.25%; }

/* 2026-10-27, client: the person's line reads as a quote — a large Rich
   Black opening mark (the pull-quote's, base.css .c-quote__mark, sized for
   the card), italic — and sits in the middle of the open card, not under
   the role. The meta column now spans the card's height (25 in at top and
   bottom) so the quote can be centred in it. */
.s-s11 .s-s11__meta { bottom: 5.5556%; }            /* 25 / 450 */
.s-s11 .s-s11__quote {
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  margin: 0;
  transform: translateY(-50%);
  font-style: italic;
}
.s-s11 .s-s11__quote::before {
  content: "\201C";
  display: block;
  margin-bottom: 15px;
  font-weight: 1000;
  font-style: normal;
  font-size: 80px;
  line-height: 0.6;
  height: 0.45em;
  overflow: hidden;
}

/* ===== main/s12.css ===== */
/* ==========================================================================
   Section 12 — the founder block.  Figma node 998:11852, tagged frame
   998:11853 ("Section 12 [bleed:left]", 1340 x 682).
   Intent tag: bleed:left. The amber slab runs off the LEFT window edge; the
   right edge is pinned to macket x = 1340, i.e. 1290 from the working area's
   left edge, so --bleed-stop is 1 - 1290 / 1340 = 3.7313 %.
   Horizontal measures are shares of the macket frame width (1340).
   ========================================================================== */

.s-s12 .s-s12__bleed {
  --bleed-stop: 3.7313%;
  display: flex;
  align-items: flex-start;
}

/* --- Portrait: amber slab, photo, amber tint over the slab's half -------- */
.s-s12 .s-s12__media {
  position: relative;
  flex: 0 0 44.3284%;          /* 594 / 1340 — slab 278 + photo out to 594 */
}

.s-s12 .s-s12__media img {
  position: relative;
  z-index: 1;
  width: 91.5825%;             /* 544 / 594 */
  margin-left: 8.4175%;        /* 50  / 594 */
  margin-top: var(--layout-gutter);
  aspect-ratio: 544 / 657;
  object-fit: cover;
}

.s-s12 .s-s12__slab,
.s-s12 .s-s12__tint {
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 46.8013%;             /* 278 / 594 */
  background: var(--amber-4);
}

/* The second slab lies over the photograph and tints its left half. */
.s-s12 .s-s12__tint {
  z-index: 2;
  opacity: 0.5;
}

/* --- Text column, macket 568.97 wide 771 --------------------------------
   It overlaps the photo column by one gutter, which is how the heading in
   the file reaches back past the photo's right edge.                       */
.s-s12 .s-s12__body {
  position: relative;
  z-index: 3;
  flex: 0 0 57.5373%;          /* 771 / 1340 */
  margin-left: -1.8657%;       /* -25 / 1340 */
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: var(--layout-gutter);
}

.s-s12 .s-s12__intro {
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 50px;
}

/* --- "FOUNDER" written over "ALEX TKACHENKO" ---------------------------- */
.s-s12 .s-s12__lockup {
  width: 100%;
  display: grid;
}

.s-s12 .s-s12__lockup > * {
  grid-area: 1 / 1;
}

.s-s12 .s-s12__script {
  width: 83.28%;
  color: var(--amber-4);
  z-index: 1;                  /* the handwriting sits over the Mulish name */
}

.s-s12 .s-s12__name {
  margin-top: 50px;
  color: var(--rich-black-1);
}

/* --- Six-column text blocks, right aligned in the column ---------------- */
.s-s12 .s-s12__sub,
.s-s12 .s-s12__bio,
.s-s12 .s-s12__quote {
  width: 85.214%;              /* 657 / 771 */
  color: var(--rich-black-1);
}

/* --- Social links ------------------------------------------------------- */
.s-s12 .s-s12__social {
  display: flex;
  align-items: center;
  gap: var(--layout-gutter);
}

.s-s12 .s-s12__social a {
  display: block;
  transition: opacity var(--t-fast) ease;
}

.s-s12 .s-s12__social a:hover {
  opacity: 0.6;
}

/* ===== main/s13.css ===== */
/* ==========================================================================
   Section 13 — FAQ accordion
   Figma: node 966:9237 "Section 13", 1440 x 758, Dekstop / Main
   Card component: Main_S13_Card, component set node 125:1398
   (NOT FAQ_S2_Card 657:3677 and NOT FAQ_S4_Card 657:4100 — see s13.assets.md)
   ========================================================================== */

/* Full-window Vista Blue 1 fill. 100 top and bottom: 100 + 558 + 100 = 758. */
.s-s13 {
  background: var(--vista-blue-1);
  padding-block: 100px;
}

/* The block is 885 = eight columns with their gutters, centred in the working
   area: two columns and a gutter on each side (2 + 8 + 2 = 12).              */
.s-s13__grid {
  row-gap: var(--layout-gutter);
}
.s-s13__intro,
.s-s13__list {
  grid-column: 3 / span 8;
}

/* --- Heading ------------------------------------------------------------
   The Comforter word lies over the Mulish heading in one grid cell. The
   heading sits 50 down inside the 85-tall group; the accent starts at 0.  */
.s-s13__intro {
  display: flex;
  flex-direction: column;
  gap: var(--layout-gutter);
  text-align: center;
}
.s-s13__title {
  display: grid;
  font: inherit;
}
.s-s13__title > * {
  grid-area: 1 / 1;
  width: 100%;
}
.s-s13__title-main {
  margin-top: 50px;
}
.s-s13__title-accent {
  color: var(--editorial-white-4);
}

/* --- Rows ---------------------------------------------------------------
   Collapsed row is 61: 25 + cap height 11 + 25. Gap between rows 25.      */
.s-s13__list {
  display: flex;
  flex-direction: column;
  gap: var(--layout-gutter);
}
.s-s13__item {
  background: var(--editorial-white-4);
}
.s-s13__question {
  font: inherit;
}
.s-s13__trigger {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--layout-gutter);
  width: 100%;
  padding: 25px 25px 25px 50px;
  border: 0;
  background: none;
  text-align: left;
  cursor: pointer;
}
.s-s13__label {
  color: var(--content-primary);
}

/* The chevron is Main_S11_Arrows: a 45-degree rule, 21.213 x 10.607.      */
.s-s13__chevron {
  flex: 0 0 auto;
  width: 21.213px;
  height: 10.607px;
  transition: transform var(--t-base) ease;
}
.s-s13__item.is-open .s-s13__chevron {
  transform: rotate(180deg);
}

/* --- Panel --------------------------------------------------------------
   Animated on grid-template-rows so the real content height is measured
   instead of guessed with a max-height. visibility keeps the collapsed
   answer out of the accessibility tree once the transition has finished. */
.s-s13__panel {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows var(--t-base) ease;
}
.s-s13__panel-inner {
  overflow: hidden;
  visibility: hidden;
  transition: visibility 0s linear var(--t-base);
}
.s-s13__item.is-open .s-s13__panel {
  grid-template-rows: 1fr;
}
.s-s13__item.is-open .s-s13__panel-inner {
  visibility: visible;
  transition-delay: 0s;
}

/* Open row: 25 + question + 50 + answer + 50 = 166 for a two-line answer.
   25 of the 50 between question and answer is the trigger's own bottom
   padding, which is what keeps the collapsed row at 61; the other 25 is
   here. The answer column is 607 wide — 228 stays empty on the right.    */
.s-s13__answer {
  padding: 25px 228px 50px 50px;
  color: var(--content-primary);
}

/* ===== main/s14.css ===== */
/* ==========================================================================
   Section 14 — three ways to start
   Figma: node 966:9200 "Section 14", 1340 x 759 — the whole working area.
   Card component: Service_S6_Card, instances 966:9207 / 966:9208 / 966:9209.
   ========================================================================== */

/* 159 heading + 50 + 550 cards = 759. No fill: the page background shows. */
.s-s14__inner {
  display: flex;
  flex-direction: column;
  gap: 50px;
}

/* --- Heading ------------------------------------------------------------
   The Comforter word lies over the Mulish heading in one grid cell. The
   heading sits 50 down inside the 85-tall group; the accent starts at 0.  */
.s-s14__intro {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--layout-gutter);
  text-align: center;
}
.s-s14__title {
  display: grid;
  width: 100%;
  max-width: 753px;
  font: inherit;
}
.s-s14__title > * {
  grid-area: 1 / 1;
  width: 100%;
}
.s-s14__title-main {
  margin-top: 50px;
}
.s-s14__title-accent {
  color: var(--amber-4);
}
.s-s14__subheading {
  width: 100%;
  max-width: 480px;
}

/* --- Cards --------------------------------------------------------------
   Three 430 blocks with the 25 gutter: 430 * 3 + 25 * 2 = 1340 exactly, so
   the row is the whole working area.

   The basis is written as that share of the row rather than as the literal
   430, and it resolves to exactly 430 at the 1440 reference. Written as
   430px the row wraps the moment the working area drops below 1340 — the
   flow helper wraps on the base size before it shrinks — and the three
   cards would break to 2 + 1 anywhere under 1440, which is the band the
   layout is required to hold. The 0.02 is there so sub-pixel rounding
   cannot tip the line into a wrap.                                        */
.s-s14__cards {
  /* 430 is three columns with their gutters. Kept as the literal card width,
     not a calc that forces three across: the flow tag says the row wraps when
     the cards stop fitting, and the acceptance list is explicit that flow rows
     wrap rather than shrink. Same basis as s5 and s7. */
  /* 2026-11-04, client (Redmi Pad Pro landscape, 1280): «чому розтягується блок? чому вони тоді не поруч ідуть?» — the row keeps its cards side by side at every desktop width; each card takes an equal share instead of wrapping the last one onto a stretched row of its own. */
  --flow-basis: calc((100% - var(--layout-gutter) * 2) / 3 - 0.1px);
}
/* --- Hover: the Service_S6_Card Hov variant -----------------------------
   The text panel swaps Rich Black 3 for Amber 4. Nothing else moves: the
   type stays Rich Black 1, the photograph and the button keep their place.
   :focus-within carries it to the keyboard, since the whole card is a
   target for the link inside it.                                           */
.s-s14__card {
  position: relative;
  display: flex;
  flex-direction: column;
  height: 550px;
  background: var(--rich-black-3);
  transition: background-color var(--t-base) ease;
}

.s-s14__card:hover,
.s-s14__card:focus-within {
  background: var(--amber-4);
}

/* The text panel ends at 229 in the macket (41.64 % of 550). It is a floor,
   not a fixed height: below 1440 the card narrows, the title wraps onto
   more lines and the panel grows into the photo rather than over it.      */
.s-s14__panel {
  flex: 0 0 auto;
  min-height: 229px;
  display: flex;
  flex-direction: column;
  gap: var(--layout-gutter);
  padding: 50px 25px 25px;
}
/* No font reset on the title: it carries .t-intro-black, and resetting the
   h3 here would win on the cascade and undo the type class.              */
.s-s14__card-title,
.s-s14__card-line {
  color: var(--content-primary);
}

.s-s14__photo-wrap {
  flex: 1 1 auto;
  min-height: 0;
  overflow: hidden;
}
.s-s14__photo {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* The button sits over the photo, 25 from the bottom and 25 from the right;
   its width is the label plus 25 of padding on each side, which is what
   makes the three buttons three different widths in the macket.           */
.s-s14__button {
  position: absolute;
  right: 25px;
  bottom: 25px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 25px;
  background: var(--action-fill);
  color: var(--content-on-accent);
  transition: background-color var(--t-fast) ease, box-shadow var(--t-fast) ease;
}
/* The label is trimmed to its cap height, so 25 + 11 + 25 gives the 61 of
   the macket. It carries the trim rather than the anchor because only a
   flex item is a block container of its own text.                        */
.s-s14__button-label {
  white-space: nowrap;
}
.s-s14__button:hover {
  background: var(--action-fill-hover);
  box-shadow: inset 0 0 0 3px var(--action-border-hover);
}

/* ===== main/s15.css ===== */
/* ==========================================================================
   Section 15 — "Your book starts here" contact form
   Figma: node 966:9240 "Section 15", 885 x 796, centred in the working area.
   Form component: Main_S14_Form, instance 966:8472, component set 1356:8297
   with the four states Default 152:994, Loading 1356:8298, Error 1356:8324,
   Send 1356:8351. Field plate: Main_S14_Form_text_card, set 144:914.
   ========================================================================== */

/* The heading block is 885 = eight columns with their gutters, centred:
   two columns and a gutter each side. The form is 657 = six columns, also
   centred, so it starts one column plus a gutter inside the heading.      */
.s-s15__grid {
  row-gap: 50px;
}
.s-s15__title {
  grid-column: 3 / span 8;
}
.s-s15__form {
  grid-column: 4 / span 6;
}

/* --- Heading ------------------------------------------------------------
   The Comforter word lies over the Mulish heading in one grid cell. The
   heading sits 50 down inside the 85-tall group; the accent starts at 0.  */
.s-s15__title {
  display: grid;
  justify-items: center;
  text-align: center;
  font: inherit;
}
.s-s15__title > * {
  grid-area: 1 / 1;
  width: 100%;
  max-width: 617px;
}
.s-s15__title-main {
  margin-top: 50px;
}
.s-s15__title-accent {
  color: var(--amber-4);
}

/* --- Form ---------------------------------------------------------------
   50 + 420 fields + 25 + 61 button + 44 + 11 status + 50 = 661.           */
.s-s15__form {
  display: flex;
  flex-direction: column;
  gap: var(--layout-gutter);
  padding: 50px 25px;
  background: var(--vista-blue-1);
}
.s-s15__fields {
  display: flex;
  flex-direction: column;
  gap: var(--layout-gutter);
}
.s-s15__field {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.s-s15__label {
  color: var(--content-on-brand);
}

/* --- Plates -------------------------------------------------------------
   Editorial White 4 plate, no border in the resting state. 15 of padding
   all round: 15 + cap height 11 + 15 = 41 for the two single-line fields. */
.s-s15__plate {
  width: 100%;
  border: 0;
  background: var(--editorial-white-4);
  color: var(--content-primary);
}
.s-s15__input {
  height: 41px;
  padding: 0 15px;
}
.s-s15__textarea {
  height: 225px;
  padding: 15px;
  resize: vertical;
}
.s-s15__plate::placeholder {
  color: var(--vista-blue-1);
  opacity: 1;
}

/* 2026-10-15, review 13 Oct item 10 — overrides the Act variants of
   Main_S14_Form_text_card (144:911, 808:6438, 144:910), which draw a white
   plate: the field stays Editorial White 4 in every state, and focus adds
   one thing only, a 3px Amber 4 stroke. The stroke is drawn inside the
   plate edge (outline-offset −3), as the Act variants place it, so the
   field does not grow. This also replaces base.css's white focus plate and
   its 2px-off ring for these fields, and covers plain :focus, so a mouse
   click gives the same single stroke as the keyboard. Autofill and
   validity styling are neutralised: Chromium paints autofilled fields its
   own blue and Firefox rings :user-invalid red, either of which reads as a
   second outline or as a glow.                                            */
.s-s15__plate {
  -webkit-appearance: none;
          appearance: none;
  border-radius: 0;
  box-shadow: none;
}
.s-s15__plate:focus,
.s-s15__plate:focus-visible {
  outline: 3px solid var(--border-accent);
  outline-offset: -3px;
  background-color: var(--editorial-white-4);
  box-shadow: none;
}
.s-s15__plate:-webkit-autofill,
.s-s15__plate:-webkit-autofill:hover,
.s-s15__plate:-webkit-autofill:focus {
  -webkit-text-fill-color: var(--content-primary);
  box-shadow: inset 0 0 0 1000px var(--editorial-white-4);
}
.s-s15__plate:user-invalid {
  box-shadow: none;
}

/* --- Actions ------------------------------------------------------------ */
.s-s15__actions {
  display: flex;
  align-items: center;
  gap: var(--layout-gutter);
}
.s-s15__submit {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 25px;
  border: 0;
  background: var(--action-fill);
  color: var(--content-on-accent);
  cursor: pointer;
  transition: background-color var(--t-fast) ease, box-shadow var(--t-fast) ease;
}
/* The label is trimmed to its cap height, so 25 + 11 + 25 gives the 61 of
   the macket. It carries the trim rather than the button because only a
   flex item is a block container of its own text.                        */
.s-s15__submit-label {
  white-space: nowrap;
}
.s-s15__submit:hover:not([disabled]) {
  background: var(--action-fill-hover);
  box-shadow: inset 0 0 0 3px var(--action-border-hover);
}

/* The Loading variant leaves the button looking exactly as it does at rest,
   so nothing is restyled here — it is only made unusable.                 */
.s-s15__submit[disabled] {
  cursor: progress;
}

/* --- Status line --------------------------------------------------------
   At rest the reassurance line stands alone on the left. In the three other
   states the state word takes the left and the message takes the right.   */
/* 25 of the 44 between the button row and the status line comes from the
   form's own gap, the remaining 19 from here.                            */
.s-s15__status {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--layout-gutter);
  margin-top: 19px;
  color: var(--content-on-brand);
}
.s-s15__message {
  text-align: right;
}
.s-s15__hint[hidden],
.s-s15__state[hidden],
.s-s15__message[hidden] {
  display: none;
}

/* ===== t-base.css ===== */
/* ==========================================================================
   Tablet foundation — Figma page "Tablet" (1826:8397), 36 frames 1024 wide.
   Added 2026-10-08. Load AFTER every desktop stylesheet and before the
   mobile ones. See CONTRACT_TABLET.md.

   Three layers now share one set of URLs:
     below 768        mobile   (`is-m` blocks, css/m-*.css)
     768 – 1279.98    tablet   (`is-t` blocks, this file and css/t-*.css)
     1280 and up      desktop  (every other block)
   Decided with the client 2026-10-08: tablet from 768 to 1279. Until then
   the desktop layer started at 1024 and was scaled down by `zoom` between
   1024 and 1199; from 1280 up the desktop never needs that.

   Like the mobile layer this is an overlay: every rule is inside the tablet
   media query, so at 1280 and up the desktop layer is untouched.
   ========================================================================== */

/* --- Layer bounds, 2026-10-15 — tablet hand-off §3.3 -----------------------
   "768 and 1280 as variables in one place; moving a bound must be a change
   of one number." CSS cannot put a custom property inside a media query, so
   the ONE place is tools/build.py: BP_TABLET = 768, BP_DESKTOP = 1280. The
   build rewrites, in every stylesheet it emits, the four media-query forms
   (min-width: 768px) (max-width: 767.98px) (max-width: 1279.98px)
   (min-width: 1280px) and the two values below from those constants, and
   prints every other width bound it meets (a block's own step inside a
   layer, such as 899.98, is allowed but listed). The sources keep the literal numbers so a file still reads on
   its own. Scripts read the bounds from these two properties (js/t-menu.js).
   Lives here and not in css/tokens.css so the desktop-only build stays
   byte-identical. */
:root {
  --bp-tablet:  768px;
  --bp-desktop: 1280px;
}

@media (min-width: 768px) and (max-width: 1279.98px) {

  /* --- Grid -------------------------------------------------------------
     Frame 1024 · margin 50 · working area 924 · three columns of 308.
     `BackgroundLines` (1826:20016 on Main_t): four lines at x 50, 358, 666
     and 974, the full height of the screen. Between 768 and 1024 the
     working area stretches with the window and the 50 margins hold; above
     1024 it stops at 924 and centres. Nothing scales.

     2026-10-15, tablet hand-off §3.2 (designer, 13 Oct 2026) — OVERRIDES
     CONTRACT_TABLET §4 ("margins stay 50"): below 1024 the side margins
     shrink from 50 toward 25 first, and only then does the working area
     shrink. So the area is 924 from 974 up (margins 25 at 974, 50 at 1024),
     and below 974 it is the window minus 25 + 25 (718 at 768). Above 1024
     the area stays 924, centred. `--t-margin` is that live margin and every
     consumer — .container, the page lines, the header's menu panel, the UP
     control, the footer and the blocks that bleed by `-1 * --t-margin` —
     reads it, so they move together. `--t-sbw` is the classic scrollbar's
     width, written by js/t-menu.js (0 with overlay scrollbars, i.e. on every
     tablet), so that 100vw means the same width as 100 % of the page. */
  :root {
    --t-reference: 1024px;
    --t-margin-min: 25px;
    --t-margin-max: 50px;
    --t-content:   924px;
    --t-margin:    clamp(var(--t-margin-min),
                         (100vw - var(--t-sbw, 0px) - var(--t-content)) / 2,
                         var(--t-margin-max));

    /* Spacing steps used by the tablet frames: the same five as the rest of
       the file, plus 100 between sections. */
    --t-gap-tight: 10px;
    --t-gap-mid:   15px;
    --t-gap:       25px;
    --t-gap-block: 50px;
    --t-gap-big:   75px;
    --t-gap-section: 100px;

    /* Header: logo at y 58, menu button at y 50, rule at y 108. */
    /* 2026-11-04, client (tablet photos, Redmi Pad Pro): «хедер дуже високий, треба зменшити»: the macket's top 50 is the device status bar; on a real tablet the
       browser bar is already above the page. 108 -> 60, as on mobile (89 -> 50). */
    --t-header-h:  60px;

    --t-tap:       44px;
  }

  body {
    min-width: 0;          /* the desktop floor is 1200 */
    overflow-x: clip;
  }

  .container {
    width: min(100% - var(--t-margin) * 2, var(--t-content));
    margin-inline: auto;
  }

  /* The page's line layer: four lines instead of seven, on the working area
     instead of the 1440 frame. */
  .page > .gridlines {
    width: min(100% - var(--t-margin) * 2, var(--t-content));
  }
  .page > .gridlines i:nth-child(n + 5) { display: none; }
  .page > .gridlines i { left: calc((var(--n) - 1) * (100% - var(--line-width)) / 3); }

  /* Touch targets, as on mobile: the area grows from the centre to 44 and
     never moves what is drawn. */
  .t-tap { position: relative; }
  .t-tap::after {
    content: "";
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    width:  max(100%, var(--tap-w, var(--t-tap)));
    height: max(100%, var(--tap-h, var(--t-tap)));
  }

  :target { scroll-margin-top: calc(var(--t-header-h) + var(--t-gap)); }

  /* Keyboard focus — tablet hand-off §15 and §6, 2026-10-15. A visible ring
     on every interactive element: the 3 px Amber 4 stroke base.css already
     draws, on an Editorial White 4 plate instead of base.css's Editorial
     White 2 — "Editorial white / 4 is the only white; add no new white"
     (§6, §12.1). Anchor scrolling stays smooth through base.css
     (`html { scroll-behavior: smooth }`, off under prefers-reduced-motion). */
  :focus-visible {
    outline: 3px solid var(--border-accent);
    outline-offset: 2px;
    background-color: var(--editorial-white-4);
  }
}

/* ==========================================================================
   Layer switch. A page carries all three sets of blocks; each layer hides the
   other two. Tablet blocks are marked `is-t`, mobile ones `is-m`.
   ========================================================================== */
@media (min-width: 768px) and (max-width: 1279.98px) {
  .page > main > section:not(.is-t) { display: none; }
  /* Sections+footer on every tablet frame: 50 under the header rule, 100
     between sections. A screen that differs sets --gap-t on the block. */
  .page > main > .is-t:first-child,
  .page > main > section:not(.is-t) + .is-t { margin-top: var(--t-gap-block); }
  .page > main > .is-t + .is-t { margin-top: var(--gap-t, var(--t-gap-section)); }
}
@media (max-width: 767.98px), (min-width: 1280px) {
  .page > main > .is-t { display: none; }
}

/* ==========================================================================
   Accordion chevrons — hover and press. 2026-10-27, designer's answer
   (tablet question 7, hand-off §9.1): the chevron in the rows of FAQ_*_t,
   Service_cards_t (the FAQ rows of Services and Discovery Sprint) and
   How_it_works_full_t takes the Hov of `Main_S11_Arrows` 1826:18090 —
   Rich Black 1 → Amber 4 — while its row is hovered with a real pointer,
   and while it is pressed on touch. Written once for the layer: every
   tablet accordion row is a button with aria-expanded holding the chevron
   file (assets/chevron-down.png?v=d31a804b, or t-process-chevron.svg on How it works).
   The drawing is moved out of the image's box and the box is painted Amber 4
   through the file's own shape, so the turn (open / closed) still applies.
   ========================================================================== */
@media (min-width: 768px) and (max-width: 1279.98px) and (hover: hover) and (pointer: fine) {
  .page .is-t button[aria-expanded]:hover img[src$="chevron-down.png"],
  .page .is-t button[aria-expanded]:hover img[src$="t-process-chevron.svg"] {
    object-position: 0 -9999px;
    background-color: var(--amber-4);
    -webkit-mask: no-repeat center / 100% 100%;
            mask: no-repeat center / 100% 100%;
  }
  .page .is-t button[aria-expanded]:hover img[src$="chevron-down.png"] {
    -webkit-mask-image: url("../assets/chevron-down.png?v=d31a804b");
            mask-image: url("../assets/chevron-down.png?v=d31a804b");
  }
  .page .is-t button[aria-expanded]:hover img[src$="t-process-chevron.svg"] {
    -webkit-mask-image: url("../assets/t-process-chevron.svg?v=99a9df03");
            mask-image: url("../assets/t-process-chevron.svg?v=99a9df03");
  }
}
@media (min-width: 768px) and (max-width: 1279.98px) {
  .page .is-t button[aria-expanded]:active img[src$="chevron-down.png"],
  .page .is-t button[aria-expanded]:active img[src$="t-process-chevron.svg"] {
    object-position: 0 -9999px;
    background-color: var(--amber-4);
    -webkit-mask: no-repeat center / 100% 100%;
            mask: no-repeat center / 100% 100%;
  }
  .page .is-t button[aria-expanded]:active img[src$="chevron-down.png"] {
    -webkit-mask-image: url("../assets/chevron-down.png?v=d31a804b");
            mask-image: url("../assets/chevron-down.png?v=d31a804b");
  }
  .page .is-t button[aria-expanded]:active img[src$="t-process-chevron.svg"] {
    -webkit-mask-image: url("../assets/t-process-chevron.svg?v=99a9df03");
            mask-image: url("../assets/t-process-chevron.svg?v=99a9df03");
  }
}

/* 2026-11-04, client (tablet photos 15:09): «при тапі не з'являється цитата»: the quote plate over a team portrait (main t9.js, about t3.js). */
@media (min-width: 768px) and (max-width: 1279.98px) {
  .tq-wrap { position: relative; display: block; cursor: pointer; }
  .tq-wrap > img { display: block; }
  .tq {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--t-gap-mid, 15px);
    background: var(--surface-accent);
    color: var(--content-on-accent);
    font-size: 15px;
    line-height: 1.35;
    text-align: center;
    opacity: 0;
    transition: opacity var(--t-base) ease;
    pointer-events: none;
  }
  .tq-wrap.is-on .tq { opacity: 1; }
}

/* ===== t-header.css ===== */
/* ==========================================================================
   Tablet header and menu — partials/t-header.html, js/t-menu.js.
   Figma: Logo_header 1826:20036, Menu_T 1826:20065 (Pas / Act), Line 54.
   Inside the tablet query; nothing here exists below 768 or at 1280 and up.
   ========================================================================== */

@media (min-width: 768px) and (max-width: 1279.98px) {

  /* The desktop header and footer are not part of the tablet frames; the
     tablet has its own. The UP control is shared and restyled below. */
  .page > .site-header,
  .page > .site-footer { display: none; }

  /* UP — Figma `Button_form` 1826:21402: 61 wide, 72 tall, label on its
     side, hanging from the header rule at x 50, y 110 on every tablet frame
     (measured on the frame renders, 2026-10-14). OVERRIDE of the earlier
     tablet build, which sent it to the foot of the window as the desktop and
     mobile layers do: the file — and the designer's review, item 3 — put it
     directly under the header, reading as a bookmark. It stays fixed there
     while the sticky header stays on screen; shown once a screen has been
     scrolled (js/up.js). */
  .site-up {
    left: max(var(--t-margin), (100% - var(--t-reference)) / 2 + var(--t-margin));
    top: calc(var(--t-header-h) + 2px);
    bottom: auto;
    width: 61px;
    height: 72px;
    padding: 0;
  }

  /* 2026-10-27, designer's answer (all pages, question 3: UP control): "on
     hover over the yellow it changes its colour to white (EEEAE3)". On the
     tablet the hover (mouse or trackpad only, hand-off §9.1) and the press
     (touch, while the finger is down) fill the button with Editorial White 4
     and keep the 3 px Amber 4 stroke inside, so it stays visible over an
     Amber 4 band, where up.css's transparent hover made it vanish. On touch
     the shared up.css :hover would stick after a tap, so without a fine
     pointer the resting drawing is restored. Keyboard focus takes the same
     white plate (hand-off §6: Editorial White 4 is the only white). */
  .site-up:hover,
  .site-up:focus-visible {
    background: var(--action-fill);
    box-shadow: inset 0 0 0 3px var(--action-fill);
  }
  .site-up:focus-visible,
  .site-up:active {
    background: var(--editorial-white-4);
    box-shadow: inset 0 0 0 3px var(--action-border-hover);
  }

  .t-header[hidden],
  .t-footer[hidden] { display: block; }   /* `hidden` is for the no-CSS case */

  /* base.css pins `.page > *:not(.gridlines):not(.site-header):not(.site-up)`
     at `position: relative; z-index: 1` — specificity 0,4,0. `.page >
     .t-menu` is only 0,2,0 and loses both properties, which put the menu in
     the flow under the header. The repeated class lifts each rule to 0,5,0;
     it is a weight, not a typo. */
  .page > .t-header.t-header.t-header.t-header { position: sticky; top: 0; z-index: 10; }
  .page > .t-menu.t-menu.t-menu.t-menu         { position: fixed;  z-index: 20; }

  .t-header {
    height: var(--t-header-h);
  }
  /* 2026-10-15, tablet hand-off §8: "no effects at all — zero shadows and
     zero blurs on all 37 screens; the tablet header has no background blur,
     it is solid." The plate was the desktop's 75 % Editorial White 4 with a
     25 px backdrop blur; on the tablet it is solid Editorial White 4. */
  .t-header__plate {
    position: absolute;
    inset: 0;
    background: var(--surface-page);
  }
  /* The solid plate would hide the page lines, but Main_t draws
     `BackgroundLines` (1826:20016) from y 0, through the header (sampled on
     the frame render, 2026-10-15: Rich Black 3 at x 50 · 358 · 666 · 974
     for y 0–107). The plate draws its own copy, in the same box and the
     same positions as `.page > .gridlines` in css/t-base.css: a 1 px line
     at background-position 0 / ⅓ / ⅔ / 100 % lands at (n − 1)(100 % − 1px)/3,
     which is exactly the page layer's formula. */
  .t-header__plate::before {
    content: "";
    position: absolute;
    top: 0;
    bottom: 0;
    left: 50%;
    transform: translateX(-50%);
    width: min(100% - var(--t-margin) * 2, var(--t-content));
    --t-line: linear-gradient(var(--line-color), var(--line-color));
    background:
      var(--t-line) 0       0 / var(--line-width) 100% no-repeat,
      var(--t-line) 33.333% 0 / var(--line-width) 100% no-repeat,
      var(--t-line) 66.667% 0 / var(--line-width) 100% no-repeat,
      var(--t-line) 100%    0 / var(--line-width) 100% no-repeat;
  }

  /* Logo 179 × 25, centred, top at 58. */
  .t-header__logo {
    position: absolute;
    z-index: 2;
    left: 50%;
    top: 13px;                           /* was 58: the header lost its status-bar band */
    transform: translateX(-50%);
    line-height: 0;
  }
  .t-header__logo img { width: 179px; height: 25px; }

  /* Menu_T Pas: 70 × 40 at y 50, flush with the right edge of the 1024
     frame — which is the window's edge below 1024 and the frame's above. */
  .t-header__toggle {
    position: absolute;
    z-index: 2;
    top: 5px;                            /* was 50 */
    right: max(0px, (100% - var(--t-reference)) / 2);
    width: 70px;
    height: 40px;
    padding: 10px;
    border: 0;
    background: var(--surface-page);
    display: grid;
    place-items: center start;
    cursor: pointer;
  }
  .t-header__bars,
  .t-header__bars::before,
  .t-header__bars::after {
    display: block;
    width: 25px;
    height: 2px;
    background: var(--content-primary);
  }
  .t-header__bars { position: relative; }
  .t-header__bars::before,
  .t-header__bars::after { content: ""; position: absolute; left: 0; }
  .t-header__bars::before { top: -8px; }
  .t-header__bars::after  { top:  8px; }

  /* Line 54: 2 px Rich Black at y 108–109, the width of the frame
     (measured on the frame renders, 2026-10-14; the earlier build drew the
     1 px grid line in Rich Black 3, which nearly vanished). */
  .t-header__rule {
    position: absolute;
    left: 50%;
    bottom: -2px;                         /* y 108–109, under the 108 header */
    transform: translateX(-50%);
    width: min(100%, var(--t-reference));
    margin: 0;
    border: 0;
    border-top: 2px solid var(--content-primary);
  }

  /* --- Menu_T Act -------------------------------------------------------
     A panel 1024 wide whose close button lands where the menu button was
     (y 50), so the X replaces the bars in place. Taller than the window on
     a short screen, it scrolls on its own. */
  .t-menu {
    position: fixed;
    top: 50px;
    left: 50%;
    transform: translateX(-50%);
    width: min(100%, var(--t-reference));
    max-height: calc(100vh - 50px);
    overflow-y: auto;
    overscroll-behavior: contain;
    background: var(--surface-page);
    border-bottom: 2px solid var(--border-strong);
  }
  /* 2026-10-27, designer's answer (tablet question 1, Menu_T Act 1826:20071):
     "the panel stretches to the full height and width of the page; a tap
     outside the links does nothing." OVERRIDES the 1024 x 758 panel above:
     it now covers the whole window (inset 0, 100dvh), so no part of the page
     shows under it at 768 x 1024 or wider than 1024. The content keeps the
     file's places: 50 of padding on top puts the close button at y 50, where
     the menu button was, and the links stay on the 924 working area. The
     Act frame's 2 px Rich Black 1 rule at its foot is dropped: the panel's
     foot is now the window's edge. Taps on the empty panel close nothing
     (js/t-menu.js closes only on a link, the close button, the menu button
     or Escape). */
  .t-menu {
    top: 0;
    left: 0;
    transform: none;
    width: 100%;
    height: 100vh;
    height: 100dvh;
    max-height: none;
    box-sizing: border-box;
    padding-top: 5px;                    /* close lands where the menu button is (was 50) */
    border-bottom: 0;
  }
  .t-menu[hidden] { display: none; }

  /* 2026-10-15, hand-off §10.1: the page under the open menu does not
     scroll (js/t-menu.js sets the class). The panel keeps its own scroll.
     A classic scrollbar's width is kept as padding so nothing shifts. */
  html.is-t-menu-open {
    overflow: hidden;
    padding-right: var(--t-sbw, 0px);
  }

  .t-menu__inner {
    width: min(100% - var(--t-margin) * 2, var(--t-content));
    margin-inline: auto;
    padding-bottom: var(--t-gap-block);
    display: flex;
    flex-direction: column;
    gap: var(--t-gap);
  }

  .t-menu__head {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
  }
  .t-menu__close {
    width: 45px;
    height: 40px;
    padding: 10px 12px 10px 13px;
    border: 0;
    background: none;
    cursor: pointer;
  }
  .t-menu__close span {
    position: relative;
    display: block;
    width: 20px;
    height: 20px;
  }
  .t-menu__close span::before,
  .t-menu__close span::after {
    content: "";
    position: absolute;
    left: -2px;
    top: 9px;
    width: 24px;
    height: 2px;
    background: var(--content-primary);
  }
  .t-menu__close span::before { transform: rotate(45deg); }
  .t-menu__close span::after  { transform: rotate(-45deg); }

  .t-menu__rule {
    width: 100%;
    margin: 0;
    border: 0;
    border-top: 2px solid var(--border-strong);
  }

  /* Nine links, 25 apart; from the second on, a hairline 15 above. */
  .t-menu__list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--t-gap);
  }
  .t-menu__list li + li {
    padding-top: var(--t-gap-mid);
    border-top: var(--line-width) solid var(--line-color);
  }
  .t-menu__list a {
    display: block;           /* u-trim needs a block box */
    width: fit-content;
    color: var(--content-primary);
    text-decoration: none;
  }

  .t-menu__foot {
    margin-top: calc(var(--t-gap-big) - var(--t-gap));
    display: flex;
    flex-direction: column;
    gap: var(--t-gap);
  }

  /* Button_form_m in the tablet menu: full width, 25 padding, the label
     trimmed to its cap height — 15 + 50 = 65 high. */
  .t-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    box-sizing: border-box;
    min-height: 65px;
    padding: 25px;
    color: var(--content-primary);
    text-decoration: none;
    text-align: center;
  }
  .t-btn--fill { background: var(--action-fill); }
  .t-btn--line { border: 3px solid var(--border-strong); padding: 22px; }
}

@media (min-width: 768px) and (max-width: 1279.98px) and (hover: hover) and (pointer: fine) {
  /* 2026-10-27, the UP hover on a real pointer — see the block above. */
  .site-up:hover {
    background: var(--editorial-white-4);
    box-shadow: inset 0 0 0 3px var(--action-border-hover);
  }
}

/* Above the tablet range and below it the tablet chrome does not exist. The
   script removes `hidden` unconditionally, so this has to say it. */
@media (max-width: 767.98px), (min-width: 1280px) {
  .t-header, .t-menu, .t-footer { display: none !important; }
}

/* ===== t-footer.css ===== */
/* ==========================================================================
   Tablet footer — partials/t-footer.html, Figma `Footer_t` 1899:15330.
   1024 × 335 in the file; the ground runs the full window, the 924 column
   centres. Inside the tablet query only.
   ========================================================================== */

@media (min-width: 768px) and (max-width: 1279.98px) {

  .page > .t-footer {
    margin-top: var(--t-gap-section);     /* Sections+footer: 100 */
    background: var(--surface-brand);
  }

  .t-footer__inner {
    width: min(100% - var(--t-margin) * 2, var(--t-content));
    margin-inline: auto;
    padding-block: var(--t-gap-block);
    display: flex;
    flex-direction: column;
    gap: var(--t-gap);
    color: var(--content-primary);
  }

  .t-footer__top {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: var(--t-gap);
  }
  .t-footer__logo { line-height: 0; }
  .t-footer__logo img { width: 179px; height: 25px; }
  .t-footer__tagline {
    display: block;
    margin: 0;
    max-width: 608px;
    text-align: right;
  }

  .t-footer__rule {
    width: 100%;
    margin: 0;
    border: 0;
    border-top: 2px solid var(--border-strong);
  }

  .t-footer__middle {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--t-gap);
  }
  .t-footer__left {
    width: min(450px, 60%);
    display: flex;
    flex-direction: column;
    gap: var(--t-gap);
  }

  .t-footer__social {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    align-items: center;
    gap: var(--t-gap);
    height: 25px;
  }
  .t-footer__social a { display: block; line-height: 0; }

  /* Three lines set solid: the file's paragraph has no gap between them.
     One block box trimmed to cap height at the top and the baseline at the
     foot, as Figma trims the paragraph — a flex column would leave the trim
     with nothing to act on and the footer 12 px taller than Footer_t's 335
     (found 2026-10-12). */
  .t-footer__office {
    font-style: normal;
    display: block;
    text-box-trim: trim-both;
    text-box-edge: cap alphabetic;
  }
  .t-footer__office span { display: block; line-height: normal; }

  .t-footer__reach,
  .t-footer__legal {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
  }
  .t-footer__reach {
    flex-direction: column;
    align-items: flex-end;
    gap: var(--t-gap);
  }
  /* The two lines sit on a 36 step (cap height + 25), so 44-tall touch
     areas overlapped by 8; 36 keeps them edge to edge (CONTRACT_TABLET §6,
     2026-10-14). */
  .t-footer__reach a { --tap-h: 36px; }
  .t-footer__legal {
    justify-content: flex-end;
    gap: var(--t-gap);
  }
  .t-footer a {
    display: block;            /* u-trim needs a block box */
    color: inherit;
    text-decoration: none;
  }
  .t-footer__legal a { color: var(--content-on-inverse); }   /* Editorial White 4 */
  /* 2026-10-15, hand-off §15: the focus plate is Editorial White 4
     (css/t-base.css), the same as these links' text — on focus the text
     turns Rich Black 1 so it stays readable inside the ring. */
  .t-footer__legal a:focus-visible { color: var(--content-primary); }
}

/* ===== main/t1.css ===== */
/* ==========================================================================
   Tablet Section 1 — Figma 1826:21580. Hero, counters, trust line.
   Also home of the two patterns every Main_t section repeats, so they are
   written once: the Group 110 lockup and Button_form. They are scoped to
   the tablet query like everything else here.
   ========================================================================== */

@media (min-width: 768px) and (max-width: 1279.98px) {

  /* --- Shared: Group 110 lockup -----------------------------------------
     The Comforter word and the Heading line share one cell; the heading
     opens 27 under the script's cap (mt 27 in every Group 110 on Main_t),
     and the script is drawn on top. Centred unless the block says left. */
  .tb-main__lockup {
    display: grid;
    text-align: center;
  }
  .tb-main__lockup > * { grid-area: 1 / 1; }
  .tb-main__script {
    position: relative;
    z-index: 1;
    pointer-events: none;
  }
  .tb-main__title { margin-top: 27px; }
  .tb-main__lockup--left { text-align: left; }
  .tb-main__script--light { color: var(--content-on-inverse); }

  /* --- Shared: Button_form ----------------------------------------------
     61 tall (25 of padding round an 11-tall trimmed label), full width of
     its column. Fill: Amber 4. Line: 3px Rich black 1 stroke drawn inside. */
  .tb-main__btn {
    display: grid;
    place-items: center;
    width: 100%;
    min-height: 61px;
    padding: var(--t-gap);
    border: 0;
    text-align: center;
    color: var(--content-primary);
    cursor: pointer;
  }
  .tb-main__btn > span { display: block; }
  .tb-main__btn--fill { background: var(--action-fill); color: var(--content-on-accent); }
  .tb-main__btn--line {
    background: none;
    box-shadow: inset 0 0 0 3px var(--border-strong);
  }

  /* --- Section 1 ---------------------------------------------------------- */

  /* Group 90: 633 × 449.6, right edge of the working area, top-left radius
     150. Below 683 of working area it takes the whole width and keeps the
     macket's ratio. */
  .tb-main-1__video {
    position: relative;
    width: min(633px, 100%);
    margin-left: auto;
    aspect-ratio: 16 / 9;   /* 2026-10-27, client: the plate takes the video's own shape, as on desktop; was 633 / 449.57 */
    border-top-left-radius: 150px;
    overflow: hidden;
  }
  .tb-main-1__media {
    width: 100%;
    height: 100%;
    object-fit: cover;
  }

  /* Group 87, 89.9 × 89.9, centred on the plate. */
  .tb-main-1__play {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    width: 90px;
    height: 90px;
    display: grid;
    place-items: center;
    padding: 0;
    border: 0;
    background: none;
    cursor: pointer;
  }
  /* 2026-10-27: one inline SVG (Group 122, 1796:13270, as the desktop) in
     place of the ring and arrow PNGs; the arrow PNG was stretched and
     nudged 6 px, so it sat off centre. Colours from tokens. */
  .tb-main-1__play-icon  { display: block; width: 90px; height: 90px; }
  .tb-main-1__play-ring  { fill: var(--editorial-white-4); }
  .tb-main-1__play-arrow { fill: var(--rich-black-1); }

  /* 2026-11-02, founders: our own <video> (s2.js) fills the plate, so the
     plate's radius clips it. The pause and sound discs (s2.css) are 40 here,
     with the 44 touch area of .t-tap, 15 in from the plate's corner. */
  .tb-main-1__media { background: var(--rich-black-1); }
  .tb-main-1__video {
    --video-btn: 40px;
    --video-inset: 15px;
    --video-gap: 10px;
  }

  /* Group 110, 50 under the plate, flush left. */
  .tb-main-1__head {
    margin-top: var(--t-gap-block);
    text-align: left;
  }

  /* Frame 624, 50 lower: 450 | 449, the right column opened by Line 55
     (2px Rich black 1, the full 197 height of the row). */
  .tb-main-1__copy {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    column-gap: var(--t-gap);
    margin-top: var(--t-gap-block);
  }
  .tb-main-1__lead,
  .tb-main-1__aside {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: var(--t-gap);
  }
  .tb-main-1__aside {
    border-left: 2px solid var(--border-strong);
    padding-left: 23px;   /* 25 from the line's centre */
  }

  /* Frame 241 + the wide card: 2 × 2 at 15, then one full row 15 lower.
     Each Main_S3_Card is 111 tall: number and label 25 apart, centred. */
  .tb-main-1__stats {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: var(--t-gap-mid);
    margin-top: var(--t-gap-big);
  }
  .tb-main-1__stat {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--t-gap);
    min-height: 111px;
    padding: 0 var(--t-gap);   /* 111 holds 72 of content centred */
    background: var(--surface-brand);
    color: var(--content-on-brand);
    text-align: center;
  }
  .tb-main-1__stat--wide { grid-column: 1 / -1; }

  /* TrustLine: full window, 50 under the counters. */
  .tb-main-1__trust {
    margin-top: var(--t-gap-block);
    padding: var(--t-gap) var(--t-margin);
    background: var(--surface-accent);
  }
  .tb-main-1__logos {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    align-items: center;
    gap: var(--t-gap) 85px;
    max-width: var(--t-content);
    margin-inline: auto;
  }
  .tb-main-1__logo {
    width: var(--w);
    height: 54px;
  }
  .tb-main-1__logo a,
  .tb-main-1__logo > span { display: block; }
  .tb-main-1__logo img {
    width: var(--w);
    height: auto;
    margin-top: var(--dy);
  }

}

/* === Tablet hover / press — hand-off §9.1 (added 2026-10-15) ===
   Replaces CONTRACT_TABLET §6 "no hover states": the tablet hand-off of
   13 Oct 2026, §9.1, gives every Components_Tablet set (1826:17360) that has
   a Hov variant its hover — only where the device has a real pointer — and
   uses the same drawing as the pressed state on touch: shown while the
   finger is down (:active), gone on release, never sticky; nothing is
   reachable only by hover. Disabled and aria-disabled controls take
   neither. Written once per page (this file is in every bundle of the
   page); the selectors carry `.page .is-t` so a block's own later rule
   cannot outweigh them. Sets with a Hov variant that are not here:
   Logo_header (tablet header, css/t-header.css — not this layer of
   files) and any set this page does not use. */
@media (min-width: 768px) and (max-width: 1279.98px) and (hover: hover) and (pointer: fine) {
  /* Button_form 1826:17361 — Pas (Amber 4 plate) → hov: no fill, a 3px Amber 4 stroke inside */
  .page .is-t .tb-main__btn--fill:not(:disabled):not([aria-disabled="true"]):hover {
    background-color: var(--action-fill-hover);
    box-shadow: inset 0 0 0 3px var(--action-border-hover);
  }

  /* Button_form, outlined instance (stroke drawn as an inset shadow) → Amber 4 */
  .page .is-t .tb-main__btn--line:not(:disabled):not([aria-disabled="true"]):hover {
    box-shadow: inset 0 0 0 3px var(--action-border-hover);
  }

  /* Arrow_graphic_button_m 1826:17405 — Pas 1826:17410 (Amber 4 disc) → Hov 1826:17417: no fill, a 3px Rich Black 1 ring, the chevron unchanged */
  .page .is-t .tb-main-9__arrow:not(:disabled):not([aria-disabled="true"]):hover {
    background-color: transparent;
    box-shadow: inset 0 0 0 3px var(--rich-black-1);
  }

  /* Icons_m 1826:17366 — Pas Rich Black 1 → Hov Amber 4. The icons are PNG
     files, so the drawing is moved out of its own box (object-position) and
     the box is painted Amber 4 through the icon's own shape (mask). */
  .page .is-t a:hover > img[src$="icon-instagram.svg"],
  .page .is-t a:hover > img[src$="icon-linkedin.svg"],
  .page .is-t a:hover > img[src$="icon-youtube.svg"] {
    object-position: 0 -9999px;
    background-color: var(--amber-4);
    -webkit-mask: no-repeat center / 100% 100%;
    mask: no-repeat center / 100% 100%;
  }
  .page .is-t a:hover > img[src$="icon-instagram.svg"] { -webkit-mask-image: url("../assets/icon-instagram.svg?v=ba19c3a4"); mask-image: url("../assets/icon-instagram.svg?v=ba19c3a4"); }
  .page .is-t a:hover > img[src$="icon-linkedin.svg"] { -webkit-mask-image: url("../assets/icon-linkedin.svg?v=6f2a7162"); mask-image: url("../assets/icon-linkedin.svg?v=6f2a7162"); }
  .page .is-t a:hover > img[src$="icon-youtube.svg"] { -webkit-mask-image: url("../assets/icon-youtube.svg?v=7b69b5e3"); mask-image: url("../assets/icon-youtube.svg?v=7b69b5e3"); }
}
@media (min-width: 768px) and (max-width: 1279.98px) {
  /* The same drawings as the pressed state, on touch and pointer alike. */
  .page .is-t .tb-main__btn--fill:not(:disabled):not([aria-disabled="true"]):active {
    background-color: var(--action-fill-hover);
    box-shadow: inset 0 0 0 3px var(--action-border-hover);
  }
  .page .is-t .tb-main__btn--line:not(:disabled):not([aria-disabled="true"]):active {
    box-shadow: inset 0 0 0 3px var(--action-border-hover);
  }
  .page .is-t .tb-main-9__arrow:not(:disabled):not([aria-disabled="true"]):active {
    background-color: transparent;
    box-shadow: inset 0 0 0 3px var(--rich-black-1);
  }
  .page .is-t a:active > img[src$="icon-instagram.svg"],
  .page .is-t a:active > img[src$="icon-linkedin.svg"],
  .page .is-t a:active > img[src$="icon-youtube.svg"] {
    object-position: 0 -9999px;
    background-color: var(--amber-4);
    -webkit-mask: no-repeat center / 100% 100%;
    mask: no-repeat center / 100% 100%;
  }
  .page .is-t a:active > img[src$="icon-instagram.svg"] { -webkit-mask-image: url("../assets/icon-instagram.svg?v=ba19c3a4"); mask-image: url("../assets/icon-instagram.svg?v=ba19c3a4"); }
  .page .is-t a:active > img[src$="icon-linkedin.svg"] { -webkit-mask-image: url("../assets/icon-linkedin.svg?v=6f2a7162"); mask-image: url("../assets/icon-linkedin.svg?v=6f2a7162"); }
  .page .is-t a:active > img[src$="icon-youtube.svg"] { -webkit-mask-image: url("../assets/icon-youtube.svg?v=7b69b5e3"); mask-image: url("../assets/icon-youtube.svg?v=7b69b5e3"); }
}

/* === 2026-10-27, desktop component sets in the tablet home frame ===
   Designer's answer (tablet question 7): hover per hand-off §9.1 — the
   desktop Hov drawing only with a real pointer, the same drawing as the
   pressed state on touch. Main_S3_Card Hov 27:2202: the counter tile on
   Amber 4. TrustLine Hov (260:691 …): the mark in Editorial White 4, painted
   through the PNG's own shape. Same rules as sections/business/t1.css. */
@media (min-width: 768px) and (max-width: 1279.98px) and (hover: hover) and (pointer: fine) {
  .page .is-t .tb-main-1__stat:hover { background: var(--amber-4); }
  .page .is-t .tb-main-1__logo:hover img {
    object-position: 0 -9999px;
    background-color: var(--editorial-white-4);
    -webkit-mask: no-repeat 0 0 / 100% 100%;
            mask: no-repeat 0 0 / 100% 100%;
  }
  .page .is-t .tb-main-1__logo:hover img[src$="s2-logo-forbes.svg"] { -webkit-mask-image: url("../assets/s2-logo-forbes.svg?v=c22ce1ee"); mask-image: url("../assets/s2-logo-forbes.svg?v=c22ce1ee"); }
  .page .is-t .tb-main-1__logo:hover img[src$="s2-logo-ingramspark.png"] { -webkit-mask-image: url("../assets/s2-logo-ingramspark.png?v=70ed1f58"); mask-image: url("../assets/s2-logo-ingramspark.png?v=70ed1f58"); }
  .page .is-t .tb-main-1__logo:hover img[src$="s2-logo-new-york-times.svg"] { -webkit-mask-image: url("../assets/s2-logo-new-york-times.svg?v=f94105cf"); mask-image: url("../assets/s2-logo-new-york-times.svg?v=f94105cf"); }
  .page .is-t .tb-main-1__logo:hover img[src$="s2-logo-barnes-and-noble.svg"] { -webkit-mask-image: url("../assets/s2-logo-barnes-and-noble.svg?v=e3d816ce"); mask-image: url("../assets/s2-logo-barnes-and-noble.svg?v=e3d816ce"); }
  .page .is-t .tb-main-1__logo:hover img[src$="s2-logo-bbc.svg"] { -webkit-mask-image: url("../assets/s2-logo-bbc.svg?v=9bf20b52"); mask-image: url("../assets/s2-logo-bbc.svg?v=9bf20b52"); }
}
@media (min-width: 768px) and (max-width: 1279.98px) {
  .page .is-t .tb-main-1__stat:active { background: var(--amber-4); }
  .page .is-t .tb-main-1__logo:active img {
    object-position: 0 -9999px;
    background-color: var(--editorial-white-4);
    -webkit-mask: no-repeat 0 0 / 100% 100%;
            mask: no-repeat 0 0 / 100% 100%;
  }
  .page .is-t .tb-main-1__logo:active img[src$="s2-logo-forbes.svg"] { -webkit-mask-image: url("../assets/s2-logo-forbes.svg?v=c22ce1ee"); mask-image: url("../assets/s2-logo-forbes.svg?v=c22ce1ee"); }
  .page .is-t .tb-main-1__logo:active img[src$="s2-logo-ingramspark.png"] { -webkit-mask-image: url("../assets/s2-logo-ingramspark.png?v=70ed1f58"); mask-image: url("../assets/s2-logo-ingramspark.png?v=70ed1f58"); }
  .page .is-t .tb-main-1__logo:active img[src$="s2-logo-new-york-times.svg"] { -webkit-mask-image: url("../assets/s2-logo-new-york-times.svg?v=f94105cf"); mask-image: url("../assets/s2-logo-new-york-times.svg?v=f94105cf"); }
  .page .is-t .tb-main-1__logo:active img[src$="s2-logo-barnes-and-noble.svg"] { -webkit-mask-image: url("../assets/s2-logo-barnes-and-noble.svg?v=e3d816ce"); mask-image: url("../assets/s2-logo-barnes-and-noble.svg?v=e3d816ce"); }
  .page .is-t .tb-main-1__logo:active img[src$="s2-logo-bbc.svg"] { -webkit-mask-image: url("../assets/s2-logo-bbc.svg?v=9bf20b52"); mask-image: url("../assets/s2-logo-bbc.svg?v=9bf20b52"); }
}

/* 2026-10-27: the two new press marks take the same hover / press as the others. */
@media (min-width: 768px) and (max-width: 1279.98px) and (hover: hover) and (pointer: fine) {
  .page .is-t .tb-main-1__logo:hover img[src$="s2-logo-elearning-industry.png"] { -webkit-mask-image: url("../assets/s2-logo-elearning-industry.png?v=8b67b256"); mask-image: url("../assets/s2-logo-elearning-industry.png?v=8b67b256"); }
  .page .is-t .tb-main-1__logo:hover img[src$="s2-logo-lten.png"] { -webkit-mask-image: url("../assets/s2-logo-lten.png?v=a3bb2fac"); mask-image: url("../assets/s2-logo-lten.png?v=a3bb2fac"); }
}
@media (min-width: 768px) and (max-width: 1279.98px) {
  .page .is-t .tb-main-1__logo:active img[src$="s2-logo-elearning-industry.png"] { -webkit-mask-image: url("../assets/s2-logo-elearning-industry.png?v=8b67b256"); mask-image: url("../assets/s2-logo-elearning-industry.png?v=8b67b256"); }
  .page .is-t .tb-main-1__logo:active img[src$="s2-logo-lten.png"] { -webkit-mask-image: url("../assets/s2-logo-lten.png?v=a3bb2fac"); mask-image: url("../assets/s2-logo-lten.png?v=a3bb2fac"); }
}

/* 2026-10-27, client: the press band is a marquee (see t1.js). Gaps become
   each mark's right margin so both halves are the same width; stops under
   the pointer; still with reduced motion. */
@media (min-width: 768px) and (max-width: 1279.98px) {
  .page .is-t .tb-main-1__trust { overflow: hidden; }
  .page .is-t .tb-main-1__logos.is-marquee {
    flex-wrap: nowrap;
    width: max-content;
    max-width: none;
    margin-inline: 0;
    gap: 0;
    animation: tb-main-1-marquee 80s linear infinite;
  }
  .page .is-t .tb-main-1__logos.is-marquee > li { flex: 0 0 auto; margin-right: 85px; }
  .page .is-t .tb-main-1__trust:hover .tb-main-1__logos.is-marquee { animation-play-state: paused; }
  @keyframes tb-main-1-marquee { from { transform: translateX(0); } to { transform: translateX(-50%); } }
}
@media (min-width: 768px) and (max-width: 1279.98px) and (prefers-reduced-motion: reduce) {
  .page .is-t .tb-main-1__logos.is-marquee { animation: none; flex-wrap: wrap; width: auto; justify-content: center; }
  .page .is-t .tb-main-1__logos.is-marquee > li[aria-hidden="true"] { display: none; }
}

/* ===== main/t2.css ===== */
/* ==========================================================================
   Tablet Section 2 — Figma 1826:21623. Who do we write for.
   ========================================================================== */

@media (min-width: 768px) and (max-width: 1279.98px) {

  .tb-main-2 {
    padding-block: var(--t-gap-block);
    background: var(--surface-brand);
    color: var(--content-on-brand);
    overflow-x: clip;     /* the bands run out to the window edge and stop */
  }

  .tb-main-2__cols {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    column-gap: var(--t-gap);
    align-items: center;
    margin-top: var(--t-gap-big);
  }
  .tb-main-2__col {
    display: flex;
    flex-direction: column;
    gap: var(--t-gap);
  }
  .tb-main-2__copy {
    display: flex;
    flex-direction: column;
    gap: var(--t-gap);
  }

  /* Both photographs are 537 tall at every width; the column decides the
     width and the picture is cropped, never scaled up. */
  .tb-main-2__stage {
    position: relative;
    height: 537px;
  }
  .tb-main-2__stage img {
    position: relative;
    width: 100%;
    height: 100%;
    object-fit: cover;
  }
  /* Rectangle 22 is drawn 125.8 % tall at −14.9 %: the crop sits a little
     below centre. */
  .tb-main-2__stage--business img { object-position: 50% 12%; }  /* 2026-11-02 set: keep the head whole */
  /* 2026-10-14: the wellness file is `Rectangle 22` 1826:21606 as rendered,
     449 x 537 at 1x, so at 1024 it fills the slot uncropped; narrower, the
     cover crop stays centred. */

  .tb-main-2__band {
    position: absolute;
    background: var(--surface-accent);
  }
  .tb-main-2__band--tint {
    z-index: 1;
    opacity: 0.5;
  }
  /* Rectangle 149/150: from the window's left edge to 133 into the photo. */
  .tb-main-2__stage--business .tb-main-2__band {
    top: 0;
    bottom: 0;
    left: -100vw;
    width: calc(100vw + 133px);
  }
  /* Rectangle 151/152: 150 tall, from 158 into the photo out to the
     window's right edge. */
  .tb-main-2__stage--wellness .tb-main-2__band {
    top: 0;
    height: 150px;
    left: 158px;
    right: -100vw;
  }

}

/* 2026-10-27, client: the same hover zoom as the desktop block (s4.css),
   for a tablet-width window driven by a mouse or trackpad. */
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .tb-main-2__stage img {
    transition: transform 700ms cubic-bezier(.2, .7, .2, 1),
                clip-path 700ms cubic-bezier(.2, .7, .2, 1);
    clip-path: inset(0);
  }
  .tb-main-2__stage:hover img {
    transform: scale(1.04);
    clip-path: inset(1.923%);
  }
}

/* 2026-10-27, client: the Business portrait turns to the camera on hover.
   Two frames of one shoot (Pexels, Darina Belonogova, 7959585 / 7959593),
   aligned on the head; the second fades in over the first. */
.tb-main-2__stage img.is-turn {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
}
/* 2026-11-02, client: the second frame should come through the first «as if
   the person turns the head». Both frames drift 1.2 % the way the face turns
   (--turn: 1 to the right, -1 to the left) while the second fades in over
   1.5 s, so the features travel instead of doubling. Each picture still clips
   itself to the original box: the inset moves against the drift. */
.tb-main-2__stage { --turn: -1; }  /* 2026-11-02 set: both turn left to the camera */
.tb-main-2__stage--wellness { --turn: -1; }
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .tb-main-2__stage img { transition: transform 1500ms cubic-bezier(.45, 0, .2, 1), clip-path 1500ms cubic-bezier(.45, 0, .2, 1), opacity 1500ms cubic-bezier(.45, 0, .2, 1); }
  .tb-main-2__stage:hover img:not(.is-turn) {
    transform: scale(1.04) translateX(calc(var(--turn) * 1.2%));
    clip-path: inset(1.923% calc(1.923% + var(--turn) * 1.2%) 1.923% calc(1.923% - var(--turn) * 1.2%));
  }
  .tb-main-2__stage img.is-turn {
    transform: scale(1.04) translateX(calc(var(--turn) * -1.2%));
    clip-path: inset(1.923% calc(1.923% - var(--turn) * 1.2%) 1.923% calc(1.923% + var(--turn) * 1.2%));
  }
  .tb-main-2__stage:hover img.is-turn { opacity: 1; transform: scale(1.04); clip-path: inset(1.923%); }
}

/* 2026-11-04, client: «фото для кого ми пишемо має бути як на мобільному». A touch tablet has no hover, so the turn above never played there.
   t2.js sets .is-on when the photo reaches the middle of the screen and
   drops it once the photo has left it — the mobile behaviour (main m3). */
@media (prefers-reduced-motion: no-preference) {
  .tb-main-2__stage img {
    clip-path: inset(0);
    transition: transform 1500ms cubic-bezier(.45, 0, .2, 1), clip-path 1500ms cubic-bezier(.45, 0, .2, 1), opacity 1500ms cubic-bezier(.45, 0, .2, 1);
  }
  .tb-main-2__stage.is-on img:not(.is-turn) {
    transform: scale(1.04) translateX(calc(var(--turn) * 1.2%));
    clip-path: inset(1.923% calc(1.923% + var(--turn) * 1.2%) 1.923% calc(1.923% - var(--turn) * 1.2%));
  }
  .tb-main-2__stage img.is-turn {
    transform: scale(1.04) translateX(calc(var(--turn) * -1.2%));
    clip-path: inset(1.923% calc(1.923% - var(--turn) * 1.2%) 1.923% calc(1.923% + var(--turn) * 1.2%));
  }
  .tb-main-2__stage.is-on img.is-turn { opacity: 1; transform: scale(1.04); clip-path: inset(1.923%); }
}

/* ===== main/t3.css ===== */
/* ==========================================================================
   Tablet Section 3 — Figma 1843:8964. Why a book is an asset.
   ========================================================================== */

@media (min-width: 768px) and (max-width: 1279.98px) {

  .tb-main-3__lede {
    margin-top: var(--t-gap);
    text-align: center;
  }

  .tb-main-3__cards {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--t-gap);
    margin-top: var(--t-gap-block);
  }
  .tb-main-3__card {
    display: flex;
    flex-direction: column;
    gap: var(--t-gap-mid);
    min-height: 144px;
    padding: var(--t-gap);
    background: var(--surface-brand);
    color: var(--content-on-brand);
  }

  .tb-main-3__close {
    margin-top: var(--t-gap);
    text-align: center;
  }

}

/* ===== main/t4.css ===== */
/* ==========================================================================
   Tablet Section 4 — Figma 1843:13893. How it works.
   ========================================================================== */

@media (min-width: 768px) and (max-width: 1279.98px) {

  .tb-main-4 {
    position: relative;
    padding-block: var(--t-gap-block);
    background: var(--surface-brand);
    color: var(--content-on-brand);
    overflow: clip;
  }

  /* Ellipse 7: a circle of radius 496.5 centred on the top-left corner of
     the block; the block clips everything but the quarter the file shows.
     A 1px stroke, drawn rather than exported. */
  .tb-main-4__arc {
    position: absolute;
    left: -496.5px;
    top: -496.5px;
    width: 993px;
    height: 993px;
    border: var(--line-width) solid var(--content-on-inverse);
    border-radius: 50%;
    pointer-events: none;
  }
  .tb-main-4 > .container { position: relative; }

  .tb-main-4__top {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    column-gap: var(--t-gap);
    align-items: start;
  }
  .tb-main-4__intro {
    display: flex;
    flex-direction: column;
    gap: var(--t-gap);
  }

  .tb-main-4__steps {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    grid-auto-rows: 1fr;
    gap: var(--t-gap);
    margin-top: var(--t-gap-block);
  }
  .tb-main-4__step {
    display: flex;
    flex-direction: column;
    gap: var(--t-gap-mid);
    min-height: 106px;
    padding: var(--t-gap);
    background: var(--surface-page);
    color: var(--content-primary);
  }
  .tb-main-4__row {
    display: flex;
    align-items: center;
    gap: var(--t-gap-mid);
  }
  .tb-main-4__row > span { display: block; }
  .tb-main-4__num { color: var(--surface-brand); }

  .tb-main-4__cta { margin-top: var(--t-gap); }

}

/* ===== main/t5.css ===== */
/* ==========================================================================
   Tablet Section 5 — Figma 1843:14048. Client voices.
   ========================================================================== */

@media (min-width: 768px) and (max-width: 1279.98px) {

  .tb-main-5__lede {
    margin-top: var(--t-gap);
    text-align: center;
  }

  .tb-main-5__cards {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--t-gap);
    margin-top: var(--t-gap-block);
  }
  .tb-main-5__card {
    display: flex;
    flex-direction: column;
    gap: var(--t-gap);
    min-height: 330px;
    padding: var(--t-gap) var(--t-gap) var(--t-gap) 24px;
    background: var(--surface-brand);
    color: var(--content-on-brand);
  }

  /* Group 100: the portrait at the top right, the two-line name ending on
     the portrait's bottom edge (45 + 30 = 75). `wrap-reverse` keeps that
     at 1024 and, where the card is too narrow for both side by side (768),
     lifts the portrait onto its own line above the name instead of letting
     the name run under it. */
  /* 2026-11-04, client (tablet photos #6): «чому фото зверху імені і прізвище, а не збоку … ім'я, прізвище ліворуч, фото праворуч». The name (first over last, as on mobile) stays left and the
     portrait right at every tablet width; on a narrow card the portrait
     shrinks instead of moving above the name. */
  .tb-main-5__top {
    display: flex;
    flex-wrap: nowrap;
    align-items: center;   /* 2026-11-04, client (tablet photos 15:09): «ім'я, прізвище … центрувати відносно до фото» */
    justify-content: space-between;
    gap: var(--t-gap-mid) var(--t-gap-tight);
  }
  .tb-main-5__name {
    flex: 1 1 auto;
    min-width: min-content;
  }
  .tb-main-5__avatar {
    flex: 0 1 75px;
    min-width: 48px;
    width: 75px;
    height: auto;
    aspect-ratio: 1;
    object-fit: cover;
  }

}

/* ===== main/t6.css ===== */
/* ==========================================================================
   Tablet Section 6 — Figma 1860:14444 / Author_case_t 1860:14383.
   ========================================================================== */

@media (min-width: 768px) and (max-width: 1279.98px) {

  .tb-main-6__lede {
    margin-top: var(--t-gap);
    text-align: center;
  }

  /* 450 | 449, bottom-aligned (items-end in the file). */
  .tb-main-6__case {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    column-gap: var(--t-gap);
    align-items: end;
    margin-top: var(--t-gap-block);
  }

  /* Rectangle 33: 450 × 636; narrower columns keep the cover's ratio. */
  .tb-main-6__cover img {
    width: 100%;
    height: auto;
    aspect-ratio: 450 / 636;
    object-fit: cover;
  }

  .tb-main-6__side {
    display: flex;
    flex-direction: column;
    gap: var(--t-gap-block);
  }
  .tb-main-6__meta {
    display: flex;
    flex-direction: column;
    gap: var(--t-gap-big);
  }
  .tb-main-6__names {
    display: flex;
    flex-direction: column;
    gap: var(--t-gap);
  }

  .tb-main-6__foot {
    display: flex;
    flex-direction: column;
    gap: 34px;   /* Frame 1860:14326 */
  }
  /* Three covers, 133 × 188 at 1024, 25 apart; at 768 they share the
     column and keep their ratio. */
  .tb-main-6__thumbs {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 133px));
    gap: var(--t-gap);
  }
  .tb-main-6__thumb {
    display: block;
    width: 100%;
    padding: 0;
    border: 0;
    background: none;
    cursor: pointer;
  }
  .tb-main-6__thumb img {
    width: 100%;
    height: auto;
    aspect-ratio: 133 / 188;
    object-fit: cover;
  }

}

/* ===== main/t7.css ===== */
/* ==========================================================================
   Tablet Section 7 — Figma 1860:14526. Services for you.
   ========================================================================== */

@media (min-width: 768px) and (max-width: 1279.98px) {

  .tb-main-7__lede {
    margin-top: var(--t-gap);
    text-align: center;
  }
  .tb-main-7__intro {
    width: min(608px, 100%);
    margin: var(--t-gap) auto 0;
    text-align: center;
  }

  .tb-main-7__cards {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    grid-auto-rows: minmax(125px, auto);
    gap: var(--t-gap);
    margin-top: var(--t-gap-block);
  }
  /* 2026-11-04, client (tablet photos 15:09): «п'ятий блок прям максимально розтягнутий» — the fifth card keeps
     one column's width, centred under the others (was the full row). */
  .tb-main-7__wide { grid-column: 1 / -1; justify-self: center; width: calc((100% - var(--t-gap)) / 2); }
  .tb-main-7__card {
    display: flex;
    flex-direction: column;
    gap: var(--t-gap-mid);
    height: 100%;
    padding: var(--t-gap);
    background: var(--surface-brand);
    color: var(--content-on-brand);
  }
  .tb-main-7__card > span:not(.tb-main-7__row),
  .tb-main-7__row > span { display: block; }

  /* Frame 357: name left, price right. Where the card is too narrow for
     both on one line (768), the price drops under the name, 10 below. */
  .tb-main-7__row {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    gap: var(--t-gap-tight) var(--t-gap);
  }
  /* 2026-11-04, client (tablet photos 15:09): at 800 the price sat beside some names and under others; it is
     always under the name now, as on mobile. */
  .tb-main-7__price { color: var(--content-on-inverse); flex-basis: 100%; }

  .tb-main-7__cta { margin-top: var(--t-gap); }

}

/* ===== main/t8.css ===== */
/* ==========================================================================
   Tablet Section 8 — Figma 1860:14546. Discovery Sprint.
   ========================================================================== */

@media (min-width: 768px) and (max-width: 1279.98px) {

  .tb-main-8__stage {
    position: relative;
    height: 526px;
  }
  .tb-main-8__stage img {
    width: 100%;
    height: 100%;
    object-fit: cover;
  }

  /* Group 43: 650 wide, centred, its top at 250 of the picture; "Sprint"
     50 under the Comforter word's cap, drawn under it. */
  .tb-main-8__head {
    position: absolute;
    left: 50%;
    top: 250px;
    width: min(650px, 100%);
    transform: translateX(-50%);
    display: grid;
    text-align: center;
  }
  .tb-main-8__head > * { grid-area: 1 / 1; }
  .tb-main-8__script {
    position: relative;
    z-index: 1;
    color: var(--content-on-inverse);
    pointer-events: none;
  }
  .tb-main-8__title { margin-top: var(--t-gap-block); }

  /* Frame 34: 608, centred, 91 up into the picture. */
  .tb-main-8__box {
    position: relative;
    z-index: 1;
    display: flex;
    flex-direction: column;
    gap: var(--t-gap);
    width: min(608px, 100%);
    margin: -91px auto 0;
  }
  .tb-main-8__card {
    display: flex;
    flex-direction: column;
    gap: var(--t-gap);
    /* 2026-10-27, client: the padding was 25 above the title and 50 under
       the price (Frame 33 1860:14552: Frame 32 at y 25, 235 tall in 310) and
       read as uneven. Now 50 top and bottom; sides 25 (the file's 558 text
       width); the 25 gaps and the button 25 under the card are the file's. */
    padding: var(--t-gap-block) var(--t-gap);
    background: var(--surface-brand);
    color: var(--content-on-brand);
    text-align: center;
  }
  .tb-main-8__price { color: var(--content-on-inverse); }

}

/* ===== main/t9.css ===== */
/* ==========================================================================
   Tablet Section 9 — Figma 1875:9378. Our team.
   ========================================================================== */

@media (min-width: 768px) and (max-width: 1279.98px) {

  .tb-main-9__lede {
    margin-top: var(--t-gap);
    text-align: center;
  }

  .tb-main-9__roller { margin-top: var(--t-gap-block); }

  /* One page per screen width of the working area; swipe with snap. */
  .tb-main-9__track {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: 100%;
    align-items: start;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scroll-behavior: smooth;
    overscroll-behavior-x: contain;
    scrollbar-width: none;
    /* A scroller clips both axes: room for the last line's descenders,
       given back underneath so the pager stays 50 below. */
    padding-bottom: var(--t-gap-tight);
    margin-bottom: calc(-1 * var(--t-gap-tight));
  }
  .tb-main-9__track::-webkit-scrollbar { display: none; }
  .tb-main-9__page {
    scroll-snap-align: start;
    scroll-snap-stop: always;
  }

  .tb-main-9__grid {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));   /* 2026-11-04, client (tablet photos #4): «чи є сенс отак 6 кубиків, чи можна 4 як на десктопі і свайпом?» — 4 a page, one row, swipe and arrows (was 3 × 2) */
    gap: var(--t-gap-block) var(--t-gap);
  }
  .tb-main-9__person {
    display: flex;
    flex-direction: column;
    gap: var(--t-gap);
    text-align: center;
  }
  .tb-main-9__person img {
    width: 100%;
    height: auto;
    aspect-ratio: 291.33 / 414;
    object-fit: cover;
    margin-bottom: 0;
  }

  /* Pager: 50 · 292 · 50, centred, 50 under the grid. */
  .tb-main-9__pager {
    display: flex;
    justify-content: center;
    align-items: center;
    margin-top: var(--t-gap-block);
  }
  .tb-main-9__count {
    width: 292px;
    text-align: center;
  }
  .tb-main-9__arrow {
    display: grid;
    place-items: center;
    width: 50px;
    height: 50px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: var(--action-fill);
    cursor: pointer;
  }
  .tb-main-9__arrow img { width: 11px; height: auto; }

  /* Frame 666: the lede in the right column, 50 under the pager. */
  .tb-main-9__about {
    width: calc((100% - var(--t-gap)) / 2);
    margin: var(--t-gap-block) 0 0 auto;
  }
  .tb-main-9__label { margin-top: var(--t-gap-block); }

  .tb-main-9__how {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: var(--t-gap);
    margin-top: var(--t-gap);
  }
  .tb-main-9__how-card {
    display: flex;
    flex-direction: column;
    gap: var(--t-gap);
    padding: var(--t-gap) var(--t-gap) var(--t-gap-block);
    /* The 3px stroke is drawn inside and takes no room, as in the file
       (179 tall, not 185). */
    box-shadow: inset 0 0 0 3px var(--border-strong);
  }

  /* 2026-10-27, designer's answer (tablet question 5, carousels —
     Team_block_t 1875:9165, the Insights articles, every tablet carousel):
     "hide the arrows at the ends", not dim them. The arrow keeps its slot
     (visibility, not display) so the counter does not jump sideways, and a
     hidden arrow is out of the tab order and the touch layer. */
  .tb-main-9__arrow[aria-disabled="true"],
  .tb-main-9__arrow[disabled] { visibility: hidden; }

}

/* === 2026-10-27, desktop component sets in the tablet frames ===
   Designer's answer (tablet question 7): their hover follows hand-off §9.1 —
   the desktop Hov drawing, only with a real pointer (hover: hover and
   pointer: fine), and the same drawing as the pressed state on touch while
   the finger is down (:active). Nothing is reachable only by hover. */
@media (min-width: 768px) and (max-width: 1279.98px) and (hover: hover) and (pointer: fine) {
  /* Main_S11_Card, Hov 120:1084 (desktop sections/main/s11.css): the 3px
     stroke turns from Rich Black 1 to Amber 4; nothing else changes. */
  .page .is-t .tb-main-9__how-card:hover { box-shadow: inset 0 0 0 3px var(--amber-4); }
}
@media (min-width: 768px) and (max-width: 1279.98px) {
  /* Main_S11_Card, Hov 120:1084 (desktop sections/main/s11.css): the 3px
     stroke turns from Rich Black 1 to Amber 4; nothing else changes. */
  .page .is-t .tb-main-9__how-card:active { box-shadow: inset 0 0 0 3px var(--amber-4); }
}

/* 2026-10-27, client ("where is the grammar?"): team roles keep their own
   capitals — "Founder / COO", "Head of Product" — not Base Down Black's
   lowercase. */
@media (min-width: 768px) and (max-width: 1279.98px) {
  .page .is-t .tb-main-9__person .t-base-down-black { text-transform: none; }
}

/* ===== main/t10.css ===== */
/* ==========================================================================
   Tablet Section 10 — Figma 1875:9417. Founder.
   ========================================================================== */

@media (min-width: 768px) and (max-width: 1279.98px) {

  .tb-main-10 { overflow-x: clip; }

  .tb-main-10__cols {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    column-gap: var(--t-gap);
    align-items: start;
    margin-top: var(--t-gap-block);
  }

  /* image 10: 502 tall at every width; the column sets the width. */
  .tb-main-10__stage {
    position: relative;
    height: 502px;
  }
  .tb-main-10__stage img {
    position: relative;
    width: 100%;
    height: 100%;
    object-fit: cover;
  }
  /* Rectangle 156/157: from the window's left edge to 158 into the photo. */
  .tb-main-10__band {
    position: absolute;
    top: 0;
    bottom: 0;
    left: -100vw;
    width: calc(100vw + 158px);
    background: var(--surface-accent);
  }
  .tb-main-10__band--tint {
    z-index: 1;
    opacity: 0.5;
  }

  .tb-main-10__body {
    display: flex;
    flex-direction: column;
    gap: var(--t-gap-block);
  }

  .tb-main-10__social {
    display: flex;
    justify-content: flex-end;
    align-items: center;
    gap: var(--t-gap);
    margin-top: calc(var(--t-gap) - var(--t-gap-block));
  }
  .tb-main-10__social a { display: block; }

}

/* ===== main/t11.css ===== */
/* ==========================================================================
   Tablet Section 11 — Figma 1875:9730 / FAQ_1_t 1875:9623. FAQ accordion.
   ========================================================================== */

@media (min-width: 768px) and (max-width: 1279.98px) {

  .tb-main-11 {
    padding-block: var(--t-gap-block);
    background: var(--surface-brand);
    color: var(--content-on-brand);
  }

  .tb-main-11__list {
    display: grid;
    gap: var(--t-gap);
    margin-top: var(--t-gap-block);
  }
  .tb-main-11__item {
    background: var(--surface-page);
    color: var(--content-primary);
  }

  /* The whole row is the trigger: 25 of padding round an 11-tall label,
     61 tall closed. The chevron (21 × 11) sits at the right. */
  .tb-main-11__q {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--t-gap);
    width: 100%;
    padding: var(--t-gap);
    border: 0;
    background: none;
    text-align: left;
    cursor: pointer;
  }
  .tb-main-11__q > span { display: block; }
  .tb-main-11__chev {
    flex: none;
    width: 21px;
    height: 11px;          /* Main_S11_Arrows turned: 21.2 × 10.6 */
    object-fit: contain;
    transition: transform var(--t-base);
  }
  .tb-main-11__item.is-open .tb-main-11__chev { transform: rotate(180deg); }

  .tb-main-11__panel {
    display: grid;
    grid-template-rows: 0fr;
    transition: grid-template-rows var(--t-base);
  }
  .tb-main-11__item.is-open .tb-main-11__panel { grid-template-rows: 1fr; }
  .tb-main-11__panel-in { overflow: hidden; }
  /* 2026-10-15: a closed answer is out of reach — no tab stop and no tap on
     the link clipped inside it, which overlapped the next question's row
     (hand-off §5). Hidden after the closing animation. */
  .tb-main-11__item:not(.is-open) .tb-main-11__panel-in { visibility: hidden; transition: visibility 0s var(--t-base); }
  /* Act: the answer 50 under the question; the trigger already carries 25. */
  .tb-main-11__a { padding: var(--t-gap) var(--t-gap) var(--t-gap); }

  @media (prefers-reduced-motion: reduce) {
    .tb-main-11__panel,
    .tb-main-11__chev { transition: none; }
  }

  /* 2026-10-15 — tablet hand-off §5: `u-link-inline` (base.css) is a 20-tall
     inline link whose underline is a border, so padding would move it. The
     tap area grows instead with a transparent 44-tall layer centred on the
     link; nothing drawn moves. */
  .tb-main-11 .u-link-inline { position: relative; }
  .tb-main-11 .u-link-inline::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    top: 50%;
    height: var(--t-tap);
    transform: translateY(-50%);
  }
}

/* ===== main/t12.css ===== */
/* ==========================================================================
   Tablet Section 12 — Figma 1875:9819. Three ways to start.
   ========================================================================== */

@media (min-width: 768px) and (max-width: 1279.98px) {

  .tb-main-12__lede {
    margin-top: var(--t-gap);
    text-align: center;
  }

  .tb-main-12__cards {
    display: grid;
    gap: var(--t-gap);
    margin-top: var(--t-gap-block);
  }
  .tb-main-12__card {
    position: relative;
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    column-gap: var(--t-gap);
    min-height: 265px;
    background: var(--rich-black-3);
    color: var(--content-primary);
  }
  .tb-main-12__copy {
    display: flex;
    flex-direction: column;
    gap: var(--t-gap);
    padding: var(--t-gap) 0 var(--t-gap) var(--t-gap);
  }
  .tb-main-12__cta { margin-top: auto; }
  /* Rectangle 106–108: the right column, the card's full height — which is
     265, or what the copy needs where it runs longer (768). Positioned so
     the picture's own ratio never sets the card's height. */
  .tb-main-12__photo {
    position: absolute;
    top: 0;
    right: 0;
    width: calc((100% - var(--t-gap)) / 2);
    height: 100%;
    object-fit: cover;
  }

}

/* ===== main/t13.css ===== */
/* ==========================================================================
   Tablet Section 13 — Figma 1875:15178 / Form_t 1875:15100. Contact form.
   ========================================================================== */

@media (min-width: 768px) and (max-width: 1279.98px) {

  .tb-main-13__form {
    display: flex;
    flex-direction: column;
    margin-top: var(--t-gap-block);
    padding: 23px var(--t-gap) var(--t-gap-block);
    background: var(--surface-brand);
    color: var(--content-on-brand);
  }

  .tb-main-13__pair {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: var(--t-gap);
  }
  .tb-main-13__field {
    display: flex;
    flex-direction: column;
    gap: var(--t-gap-mid);
  }
  .tb-main-13__field > label { display: block; }
  .tb-main-13__field--idea { margin-top: var(--t-gap-block); }

  /* Form_cards_t: Editorial white, 50 tall, 15 in from the left; the big
     one 225 tall with 15 all round. Placeholder in Vista blue 1. */
  .tb-main-13__input {
    width: 100%;
    height: 50px;
    padding: 0 var(--t-gap-mid);
    border: 0;
    border-radius: 0;
    background: var(--surface-page);
    color: var(--content-primary);
  }
  .tb-main-13__input--big {
    height: 225px;
    padding: var(--t-gap-mid);
    resize: vertical;
  }
  .tb-main-13__input::placeholder { color: var(--surface-brand); opacity: 1; }
  /* 2026-10-15 — tablet hand-off §12.1 and desktop review item 10: in focus
     the field keeps the Editorial White 4 ground (base.css's #FFFFFF plate is
     overridden — the only white is Editorial White 4) and gains one 3px
     Amber 4 outline, flush with the field. */
  .tb-main-13__input:focus-visible { outline: 3px solid var(--border-accent); outline-offset: 0; background-color: var(--editorial-white-4); }

  .tb-main-13__actions {
    display: flex;
    flex-direction: column;
    gap: var(--t-gap);
    margin-top: var(--t-gap);
  }
  .tb-main-13__actions button:disabled { cursor: progress; }

  .tb-main-13__foot {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: var(--t-gap);
    margin-top: var(--t-gap-block);
  }
  .tb-main-13__note { text-align: right; }

}

/* ===== m-base.css ===== */
/* ==========================================================================
   Mobile foundation — Figma page "Mobile", hand-off document v1.0.
   Load AFTER every desktop stylesheet. See CONTRACT_MOBILE.md.

   The whole file is one media query. Below 768 this layer overrides the
   desktop layer; at 768 and up not a single rule here applies, so the
   desktop layout is untouched byte for byte.

   Why an overlay rather than two wrapped halves: the desktop CSS is live and
   already verified. Wrapping it would rewrite every one of its rules to prove
   a layout that is not changing. This way the desktop bytes stay as they are
   and the mobile layer states only its differences.
   ========================================================================== */

@media (max-width: 767.98px) {

  /* --- 3.1 Grid ---------------------------------------------------------
     402 reference · 6 columns · Stretch · margin 25 · gutter 25
     Working area 352. Column 37.83 is derived and written nowhere.        */
  :root {
    --m-reference: 402px;
    --m-margin:    25px;
    --m-gutter:    25px;
    --m-content:   352px;   /* at the reference width                      */
    --m-max:       430px;   /* the column stops growing here (3.2)         */

    /* 4. Three gaps carry 94 % of 3 010 Auto Layout nodes. */
    --m-gap-tight: 10px;
    --m-gap-mid:   15px;
    --m-gap:       25px;
    --m-gap-block: 50px;
    --m-gap-big:   75px;

    /* 9.1 Header: logo at y 59, rule at y 89 in the macket, whose top 44 is the
       phone's status bar. 2026-11-04, client (phone review): «прибрати відступ на хедері на всіх
       сторінках» — on a real phone the browser bar is already above the page,
       so the band is gone: the bar is 50, burger at 5, logo at 17. */
    --m-header-h:  50px;

    /* 5.2 Touch targets grow from the centre toward this. */
    --m-tap:       44px;
  }

  /* --- 3.2 Reflow -------------------------------------------------------
     The desktop floor is 1200 and it is what puts a horizontal scrollbar on
     a phone. Below the breakpoint there is no floor: the page is as wide as
     the window and never wider.                                           */
  body {
    min-width: 0;
    overflow-x: clip;
  }

  /* Working area. Below 430 it stretches with the window and the 25 margins
     hold; above 430 it stops at 380 and centres, and the window fills with
     the page ground. Nothing scales — sizes and spacing are the macket's.  */
  .container {
    width: min(100% - var(--m-margin) * 2, calc(var(--m-max) - var(--m-margin) * 2));
    margin-inline: auto;
  }

  /* 6 columns, not 12. A block that asked for the desktop grid gets the
     mobile one without having to know which layer it is in.               */
  .grid12 {
    grid-template-columns: repeat(6, 1fr);
    gap: var(--m-gutter);
  }

  /* --- Intent tags ------------------------------------------------------
     `flow` on mobile is a single column: two 430-basis children side by side
     cannot fit 352. Bleed keeps its meaning — the full window, which above
     430 is wider than the column.                                          */
  .is-flow { display: block; }
  .is-flow > * + * { margin-top: var(--m-gap); }

  .is-bleed-left,
  .is-bleed-right,
  .is-bleed-both,
  .m-bleed {
    width: 100vw;
    margin-left: calc(50% - 50vw);
    margin-right: 0;
  }

  /* --- 3.1 Background lines ---------------------------------------------
     Unlike desktop, where the line layer spans the page, `BackgroundLines`
     on mobile is 352 wide and starts below the header — it lives inside the
     working area. The desktop layer's seven lines at 12.5 % of the window
     are wrong here and are switched off; each screen draws its own set
     inside its own container.                                              */
  .page > .gridlines { display: none; }

  /* --- 5.6 Touch targets ------------------------------------------------
     The area grows from the centre of the element toward 44 on each axis,
     independently, and never moves or resizes what is drawn. Where a
     neighbour is closer than 44, the block sets --tap-h (or --tap-w) to
     twice the half-gap for EVERY item in that row, so the row is even under
     the thumb (5.3).

     ::after and not padding: padding would move the element.               */
  .m-tap { position: relative; }
  .m-tap::after {
    content: "";
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    width:  max(100%, var(--tap-w, var(--m-tap)));
    height: max(100%, var(--tap-h, var(--m-tap)));
  }

  /* An indicator is not a target: carousel dots and arrows show that more
     exists, they do not move anything (5.7).                               */
  .m-indicator { pointer-events: none; }

  /* --- 7 Type -----------------------------------------------------------
     Eleven of the twelve mobile styles are the desktop values unchanged —
     the 15 and 25 sizes are the same file-wide. Only the Comforter accent
     differs, and it differs by half: 50 on mobile against 100 on desktop.
     The styles are named "… Mobile" in Figma for exactly this reason.      */
  .t-heading-accent,
  .t-heading-accent-small { font-size: 50px; }

  /* 7.2 The one style with no desktop counterpart: the numeral on the error
     page. 500 is the size, not a typo.                                     */
  .t-404 {
    font-family: "Comforter", cursive;
    font-weight: 400;
    font-size: 500px;
    letter-spacing: 0.05em;
  }

  /* --- 3.2 Long pages ---------------------------------------------------
     Screens run to 14 382. Smooth anchor scrolling has to clear the pinned
     header or the target lands underneath it.                              */
  :target { scroll-margin-top: calc(var(--m-header-h) + var(--m-gap)); }

  /* --- 12 Form fields in focus (2026-10-27) -----------------------------
     Mobile review 20 Oct, items 6 and 9: on every page a field in focus
     keeps the Editorial White 4 ground of the page — never #FFFFFF — and
     shows one 3 px Amber 4 stroke on its own edge. base.css paints the white
     on every `:focus-visible` below 1280 and puts the ring 2 px off the
     edge, which over a coloured form plate reads as a double outline. This
     overrides CONTRACT_MOBILE §12 ("white ground"); the designer's review is
     newer. Block rules that set their own focus state carry the same values. */
  input:focus-visible,
  textarea:focus-visible,
  select:focus-visible {
    background-color: var(--editorial-white-4);
    outline: 3px solid var(--border-accent);
    outline-offset: 0;
  }

}

/* ==========================================================================
   Layer switch. A page carries both sets of blocks; each layer hides the
   other's. The mobile blocks are marked `is-m` by the screen that writes
   them; everything else in <main> is the desktop layer.

   The second query is the only rule in this file that applies at 768 and up,
   and it can only hide blocks that a desktop-only build never emits — so the
   desktop layer is still untouched.
   ========================================================================== */
@media (max-width: 767.98px) {
  .page > main > section:not(.is-m) { display: none; }
  .page > main > .is-m + .is-m { margin-top: var(--gap-m, var(--m-gap-big)); }
  .page > main > .is-m:first-child { margin-top: 0; }
}
@media (min-width: 768px) {
  .page > main > .is-m { display: none; }
}

/* --- Pull quote, mobile (2026-10-27, client) -----------------------------
   The founder's quote on the four mobile pages, read as the case pages'
   mobile quote band reads (casem.css .s-cam6__*): the opening mark on its
   own line, Mulish Regular 75 in Amber (the file's measurement, no style
   in the file), the words in Base italic, the attribution under them, all
   centred as every mobile founder block is. Desktop and tablet: base.css. */
@media (max-width: 767.98px) {
  .c-quote.c-quote--m {
    grid-template-columns: minmax(0, 1fr);
    row-gap: var(--m-gap-mid);
    text-align: center;
  }
  .c-quote--m .c-quote__mark {
    grid-row: auto;
    font-weight: 400;
    font-size: 75px;
    /* Trimmed to the cap, the box is 53 tall but the mark's ink is only its
       top 16 (measured 2026-10-27); without this the words sat 52 under the
       ink instead of 15. The box is cut to the ink (0.22em = 16.5 of 75);
       the empty part of the line overflows invisibly. */
    height: 0.22em;
  }
  .c-quote--m .c-quote__words,
  .c-quote--m .c-quote__by { grid-column: auto; }

  /* 2026-11-04, client (phone review): «Show filters» / «Hide filters» on Results and Insights
     (sections/results/m2, sections/insights/bm1). A chip-like button with a
     chevron; the panel under it opens on tap. */
  .f-toggle {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    padding: 13px 15px;
    border: 1px solid var(--rich-black-1);
    background: transparent;
    color: var(--rich-black-1);
    cursor: pointer;
  }
  .f-toggle > span { font-size: 13px; }
  /* The chevron is its own span: .m-tap already owns ::after (the 44 touch area). */
  .f-toggle__chev {
    width: 7px;
    height: 7px;
    border-right: 2px solid currentColor;
    border-bottom: 2px solid currentColor;
    transform: translateY(-2px) rotate(45deg);
    transition: transform var(--t-base) ease;
  }
  .f-toggle[aria-expanded="true"] .f-toggle__chev { transform: translateY(2px) rotate(-135deg); }
  .f-panel { margin-top: var(--m-gap-mid); }
  .f-panel[hidden] { display: none; }
}

/* ===== m-header.css ===== */
/* ==========================================================================
   Mobile header and menu — Figma `Menu_mob` 1244:11197.
   Inside the mobile media query; nothing here exists at 768 and up.
   ========================================================================== */

@media (max-width: 767.98px) {

  /* The desktop header and its three sub-rows do not appear on a phone: the
     mobile menu is an overlay with its own, flatter list. */
  .page > .site-header { display: none; }

  .m-header[hidden] { display: block; }   /* `hidden` is for the no-CSS case */

  .m-header {
    position: sticky;
    top: 0;
    z-index: 10;
    height: var(--m-header-h);            /* 89 — the rule sits on the edge   */
  }
  /* 2026-10-27 · mobile review 20 Oct, items 7 and 8. `base.css` pins
     `.page > *:not(.gridlines):not(.site-header):not(.site-up)` at
     `position: relative` with weight 0,4,0, and the 0,2,0 rules here lost to
     it: the header scrolled away with the page (item 7) and the overlay
     opened in the flow under the burger instead of over the window (item 8).
     The selectors below carry 0,5,0, the same cure the tablet header uses. */
  .page > .m-header.m-header.m-header.m-header.m-header { position: sticky; top: 0; z-index: 10; }
  .page > .m-menu.m-menu.m-menu.m-menu.m-menu          { position: fixed; inset: 0; z-index: 20; }

  /* 8. The one effect in the whole mobile version. */
  .m-header__plate {
    position: absolute;
    inset: 0;
    z-index: 0;
    background: var(--header-plate);
    -webkit-backdrop-filter: blur(var(--header-blur));
    backdrop-filter: blur(var(--header-blur));
  }

  /* Logo at 25,59. Its touch area reaches 44 on the vertical — the room is
     there, and nothing else is near it. */
  .m-header__logo {
    position: absolute;
    z-index: 2;
    left: var(--m-margin);
    top: 17px;                           /* was 59: header without the status-bar band */
    --tap-w: 107px;
  }
  .m-header__logo img { width: auto; height: 15px; }

  /* The button at 332,49 is 70 × 40 in the file: wide enough across, four
     pixels short down. The area takes the full 44 on both axes; the nearest
     other target is the logo, 200 away. */
  .m-header__toggle {
    position: absolute;
    z-index: 2;
    right: var(--m-margin);
    top: 5px;                            /* was 49 */
    width: 45px;
    height: 40px;
    display: grid;
    place-items: center;
    padding: 0;
    border: 0;
    background: none;
    cursor: pointer;
  }

  /* Three bars drawn in CSS, as the file draws them — not an exported icon. */
  .m-header__bars,
  .m-header__bars::before,
  .m-header__bars::after {
    display: block;
    width: 20px;
    height: 2px;
    background: var(--content-primary);
  }
  .m-header__bars { position: relative; }
  .m-header__bars::before,
  .m-header__bars::after { content: ""; position: absolute; left: 0; }
  .m-header__bars::before { top: -6px; }
  .m-header__bars::after  { top:  6px; }

  /* Line 54 at y 89, 352 wide — inside the working area, not edge to edge. */
  .m-header__rule {
    position: absolute;
    left: 50%;
    transform: translateX(-50%);
    bottom: 0;
    width: min(100% - var(--m-margin) * 2, calc(var(--m-max) - var(--m-margin) * 2));
    margin: 0;
    border: 0;
    border-top: var(--line-width) solid var(--line-color);
  }

  /* --- The overlay ------------------------------------------------------
     402 × 830 in the file, anchored under the header. On a real phone it
     takes the window, because a fixed height would leave the page showing
     under it on a tall screen and cut the buttons off on a short one.     */
  .page > .m-header { position: sticky; z-index: 10; }
  .page > .m-menu   { position: fixed;  z-index: 20; }

  .m-menu {
    position: fixed;
    inset: 0;
    z-index: 20;
    background: var(--surface-page);
    overflow-y: auto;
    overscroll-behavior: contain;
  }
  .m-menu[hidden] { display: none; }

  .m-menu__inner {
    display: flex;
    flex-direction: column;
    min-height: 100%;
    padding-block: 5px var(--m-gap-block);   /* close lands where the burger is (was 49) */
  }

  /* Close at 332,0 · 45 × 40 with a 20 × 20 glyph, then the rule at y 40. */
  .m-menu__head { position: relative; height: 40px; }

  .m-menu__close {
    position: absolute;
    right: 0;
    top: 0;
    width: 45px;
    height: 40px;
    display: grid;
    place-items: center;
    padding: 0;
    border: 0;
    background: none;
    cursor: pointer;
  }
  .m-menu__close span,
  .m-menu__close span::before,
  .m-menu__close span::after { display: block; }
  .m-menu__close span {
    position: relative;
    width: 20px;
    height: 20px;
  }
  .m-menu__close span::before,
  .m-menu__close span::after {
    content: "";
    position: absolute;
    left: 0;
    top: 9px;
    width: 20px;
    height: 2px;
    background: var(--content-primary);
  }
  .m-menu__close span::before { transform: rotate(45deg); }
  .m-menu__close span::after  { transform: rotate(-45deg); }

  .m-menu__rule,
  .m-menu__list li + li {
    border: 0;
    border-top: var(--line-width) solid var(--line-color);
  }
  .m-menu__rule { position: absolute; bottom: 0; left: 0; right: 0; margin: 0; }
  /* 2026-10-27 · review 20 Oct, item 8 ("all elements as in the file"):
     Line 55 1244:11210 under the cross is Rich Black 1 in the Act variant;
     only the rules between the items are Rich Black 3. */
  .m-menu__rule { border-top-color: var(--content-primary); }

  /* Nine items on a 41 step: the label sits 15 below its own rule, the row is
     26 tall. 41 between centres is under 44, so by 5.2 every area takes half
     the gap on each side — 41 — and by 5.3 every item in the list takes the
     same one, so the first and last are not larger than the rest. */
  .m-menu__list { margin-top: var(--m-gap); }
  .m-menu__list li { padding-bottom: 15px; }
  /* 15 above the label and 15 below gives a 42 step, not the file's 41: in
     Figma the rule is a zero-height line, in CSS it is a real pixel. The
     padding above absorbs it so the step lands on 41 exactly. */
  .m-menu__list li + li { padding-top: 14px; }
  .m-menu__list a { display: block; --tap-h: 41px; }

  /* The two calls to action and the address, at the foot of the overlay.
     `margin-top: auto` pins them down however tall the window is, which is
     what the file's fixed 646 does on a 830 frame. */
  .m-menu__foot {
    margin-top: auto;
    padding-top: var(--m-gap-big);
    display: grid;
    justify-items: center;
    gap: var(--m-gap-mid);
  }

  .m-menu__foot .m-btn {
    display: grid;
    place-items: center;
    width: 253px;
    max-width: 100%;
    height: 41px;
    text-align: center;
  }
  .m-menu__foot .m-btn--fill {
    background: var(--action-fill);
    color: var(--content-on-accent);
  }
  .m-menu__foot .m-btn--line {
    box-shadow: inset 0 0 0 3px var(--border-strong);
    color: var(--content-primary);
  }

  .m-menu__mail { margin-top: calc(var(--m-gap-block) + 6px); }
  .m-menu__mail a { --tap-h: 44px; }

  /* While the overlay is open the page underneath does not scroll. */
  body.is-m-menu-open { overflow: hidden; }

}

/* The mobile chrome exists in the markup at every width; only the media query
   keeps it off the desktop layer. `hidden` is removed by the script as soon
   as it runs, so without this the header renders twice at 768 and up. */
@media (min-width: 768px) {
  .m-header, .m-menu, .m-footer { display: none !important; }
}

/* ===== m-footer.css ===== */
/* ==========================================================================
   Mobile footer — Figma `Footer_m` 1774:15900, 402 × 449.
   Inside the mobile media query; nothing here exists at 768 and up.
   ========================================================================== */

@media (max-width: 767.98px) {

  .page > .site-footer { display: none; }
  .m-footer[hidden] { display: block; }

  /* The file leaves 75 between the last block and the footer. The desktop
     layer sets its own gap on .site-footer, which is hidden down here, so
     this one has to be stated. */
  .page > .m-footer { margin-top: var(--m-gap-big); }

  .m-footer {
    background: var(--surface-brand);
    color: var(--content-on-brand);
    text-align: center;
  }

  /* The block runs edge to edge; the content keeps the 25 margins. */
  .m-footer__inner { padding-block: var(--m-gap) var(--m-gap-block); }

  .m-footer__logo {
    display: inline-block;
    --tap-h: 44px;
    --tap-w: 107px;
  }
  .m-footer__logo img { width: auto; height: 15px; }

  /* Three groups. The file sets them 10 apart, not 25: `Frame 481` runs
     logo 15 · 10 · group 169 · 10 · group 62 · 10 · group 98 = 374, which
     with the 25 above and 50 below is the footer's 449. The 25 that stood
     here was what made the block 46 too tall on all 37 screens. */
  .m-footer__group { margin-top: var(--m-gap-tight); }
  .m-footer__rule {
    margin: 0 0 var(--m-gap-mid);
    border: 0;
    border-top: var(--line-width) solid var(--content-on-brand);
  }

  /* Two lines, 30 tall in the file: 11 a line on a 19 step. */
  .m-footer__tagline { margin-inline: auto; max-width: 30ch; line-height: 19px; }

  /* Three marks on a 50 step: 50 between centres clears 44, so each area is
     the full 44 × 44 and they still do not touch. */
  .m-footer__social {
    display: flex;
    justify-content: center;
    gap: 25px;
    margin-top: var(--m-gap);
  }
  .m-footer__social a { display: block; }

  /* `text-box-trim` only takes effect on a block box: a bare <span> inside a
     grid is still inline, the trim is ignored, and the line keeps its full
     leading. Every trimmed label here is blockified for that reason — the
     same trap that put 202px of drift into the FAQ.
     Figma writes the three address lines on an 18 step from a 49-tall box. */
  .m-footer__office span { display: block; }
  .m-footer__office {
    display: grid;
    gap: 7px;
    margin-top: var(--m-gap);
    font-style: normal;
  }

  /* 5.3 — one row, one size. The step is 36 in the file, so every link in
     both lists takes a 36 band: the rows stay even under the thumb and no
     two areas meet. This is the floor the contract records at §5.4.        */
  .m-footer__reach,
  .m-footer__legal {
    display: grid;
    gap: 25px;
  }
  /* `block`, not `inline-block`: an inline-block still sits in a line box, so
     the <li> keeps the full leading even after the label itself is trimmed and
     the row measures 19 where the file measures 11. */
  .m-footer__reach a,
  .m-footer__legal a {
    display: block;
    --tap-h: 36px;
  }

  .m-footer__legal a { color: var(--content-on-inverse); }

}

/* ===== m-up.css ===== */
/* ==========================================================================
   Mobile "up" control — Figma `Button_form` 41 × 52, drawn at 25,143 on all
   37 screens. Contract §9.2.
   ========================================================================== */

@media (max-width: 767.98px) {

  /* The desktop control is 61 × 72 and sits at the desktop margin; the mobile
     one is its own size at its own place, so the shared element is restyled
     rather than duplicated. */
  .site-up { position: relative; }
  .site-up::after {
    content: "";
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    width:  max(100%, var(--tap-w, var(--m-tap)));
    height: max(100%, var(--tap-h, var(--m-tap)));
  }

  .site-up {
    position: fixed;
    left: var(--m-margin);
    bottom: var(--m-margin);
    padding: 0;
    width: 41px;
    height: 52px;

    /* 5.5 — three pixels short across. The room is there: the nearest other
       target is the footer, and on a scrolled page nothing sits beside it. */
    --tap-w: 44px;
    --tap-h: 52px;
  }

  /* The file draws it at y 143, under the header. As a floating control it
     keeps the file's x and moves to the foot of the window, out of the
     reading column — the same decision as on desktop, and for the same
     reason: at 143 it would sit on whatever band is passing under it. */

  .site-up__label { font-size: 15px; }

}

/* ===== main/m1.css ===== */
/* ==========================================================================
   Mobile Section 1 — Figma 1244:14040. Hero: video plate, lockup, two calls.
   Every rule sits inside the mobile query; nothing here exists at 768 and up.
   ========================================================================== */

@media (max-width: 767.98px) {

  /* Rectangle 128: 352 × 250, one rounded corner at the top left. The plate
     keeps the macket's ratio at every width, so the block never jumps while
     the picture decodes. */
  .s-m1__video {
    position: relative;
    aspect-ratio: 16 / 9;   /* 2026-10-27, client: the plate takes the video's own shape, as on desktop; was 352 / 250 */
    border-top-left-radius: 100px;
    overflow: hidden;
  }
  .s-m1__media {
    width: 100%;
    height: 100%;
    object-fit: cover;
    background: var(--rich-black-1);
  }

  /* Group 87, 50 × 50 at 151,100 — the centre of the plate. */
  .s-m1__play {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    width: 50px;
    height: 50px;
    display: grid;
    place-items: center;
    padding: 0;
    border: 0;
    background: none;
    cursor: pointer;
  }
  /* 2026-10-27, mobile review 20 Oct item 2: one inline SVG (Group 122,
     1796:13270, as the desktop) in place of the ring and arrow PNGs, so the
     triangle's centroid sits on the ring's centre. Colours from tokens. */
  .s-m1__play-icon  { display: block; width: 50px; height: 50px; }
  .s-m1__play-ring  { fill: var(--editorial-white-4); }
  .s-m1__play-arrow { fill: var(--rich-black-1); }

  /* 2026-11-02, founders: our own <video> (s2.js) fills the plate, clipped
     by its radius. The pause and sound discs (s2.css) are 36 here, small on
     a phone, with the 44 touch area of .m-tap, 10 in from the corner. */
  .s-m1__video {
    margin-top: var(--m-gap-block);   /* 2026-11-04: the video now follows the call button, 50 under it */
    --video-btn: 36px;
    --video-inset: 10px;
    --video-gap: 10px;
  }

  /* Group 89: the Comforter word is drawn over the title, its cap on the
     block's top edge, and the title starts 15 lower. */
  .s-m1__head {
    display: grid;
    margin-top: var(--m-gap);
  }
  /* Group 89 / 90: the script and the title share one cell, so the
     lockup is as tall as whichever is taller — the Comforter word, or
     the offset plus the title. That is the file's own rule and it needs
     no measured height. */
  .s-m1__head > * { grid-area: 1 / 1; }
  .s-m1__script {
    z-index: 1;
    pointer-events: none;
  }
  .s-m1__title { margin-top: 15px; }

  .s-m1__lede { margin-top: var(--m-gap-mid); }

  /* Button_form, 61 tall, 25 of air each side of the label. The fill variant
     is Amber 4 on Rich black 1; the line variant is the 3px stroke, drawn
     inside so the button keeps its measured width. */
  .s-m1__cta {
    display: grid;
    place-items: center;
    min-height: 61px;
    padding-inline: var(--m-gap);
    text-align: center;
  }
  .s-m1__cta--fill {
    margin-top: var(--m-gap);
    background: var(--action-fill);
    color: var(--content-on-accent);
  }
  .s-m1__cta--line {
    margin-top: var(--m-gap-mid);
    box-shadow: inset 0 0 0 3px var(--border-strong);
    color: var(--content-primary);
  }

  .s-m1__aside { margin-top: var(--m-gap-block); }
  .s-m1__note  { margin-top: var(--m-gap-mid); }

}

/* ===== main/m2.css ===== */
/* ==========================================================================
   Mobile Section 2 — Figma 1244:14059. Counters and the press band.
   ========================================================================== */

@media (max-width: 767.98px) {

  /* Two columns on the 15 gutter the file uses between these cards — not the
     25 page gutter: 168.5 + 15 + 168.5 = 352. */
  .s-m2__stats {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--m-gap-mid);
  }
  .s-m2__stat--wide { grid-column: 1 / -1; }

  /* 111 is the macket's card; `min-height` and not `height` so a label that
     wraps on a 320 screen makes the card taller instead of spilling. */
  .s-m2__stat {
    min-height: 111px;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    gap: var(--m-gap);
    padding-inline: var(--m-gap-tight);
    background: var(--surface-brand);
    color: var(--content-on-brand);
    text-align: center;
  }

  /* The counter needs no rule of its own: it is the 50 Heading style and
     `.u-trim` sits it on its cap, with the label 25 under it. */

  /* --- 3.1 Background lines (2026-10-27 · review 20 Oct, item 1) --------
     `BackgroundLines` 1244:14032 on `Main_m`: four lines at 0, 33.33, 66.67
     and 100 per cent of the 352 working area, from the header rule to the
     end of the screen. Same recipe as About m1: one absolute layer whose
     containing block is <main> (this section is not positioned), z-index -1
     so every plate and word stays above it. */
  .s-m2__lines {
    position: absolute;
    inset: 0;
    z-index: -1;
    pointer-events: none;
  }
  .s-m2__lines > .container { position: relative; height: 100%; }
  .s-m2__lines i {
    position: absolute;
    top: 0;
    bottom: 0;
    width: var(--line-width);
    background: var(--line-color);
  }
  .s-m2__lines i:nth-child(1) { left: 0; }
  .s-m2__lines i:nth-child(2) { left: 33.333%; }
  .s-m2__lines i:nth-child(3) { left: 66.667%; }
  .s-m2__lines i:nth-child(4) { right: 0; }

  /* TrustLine, 402 × 52, Amber 4, edge to edge. */
  .s-m2__trust {
    margin-top: var(--m-gap-mid);
    background: var(--surface-accent);
    overflow-x: clip;
  }

  /* 2026-10-27 · review 20 Oct, item 3. A marquee: the row is two identical
     sets, it opens at the page margin and slides left by exactly one set,
     then starts over, so the seam is never seen. Each mark carries its 15
     gap as right padding instead of a flex gap, so the two halves are the
     same width and -50 % lands on the start of the copy. */
  .s-m2__logos {
    display: flex;
    align-items: center;
    width: max-content;
    height: 52px;
    margin-left: var(--m-margin);
    animation: s-m2-marquee 30s linear infinite;
  }
  .s-m2__logos > li {
    flex: 0 0 auto;
    padding-right: var(--m-gap-mid);
  }
  .s-m2__logos:focus-within { animation-play-state: paused; }

  @keyframes s-m2-marquee {
    from { transform: translateX(0); }
    to   { transform: translateX(-50%); }
  }

  /* The marks are 16 to 25 tall. Before this fix the link was a block with
     an inline image in it, so each mark sat on the text baseline and the row
     was ragged; a flex link with a block image centres every mark on the
     band's middle line (review 20 Oct, item 3). */
  .s-m2__logos a,
  .s-m2__logos li > span {
    display: flex;
    align-items: center;
    --tap-h: 44px;
  }
  .s-m2__logos img { display: block; }

  /* No motion wanted: the band stands still, the copy goes, and the row is
     swiped as it was before the marquee. */
  @media (prefers-reduced-motion: reduce) {
    .s-m2__logos {
      animation: none;
      width: auto;
      margin-left: 0;
      padding-inline: var(--m-margin);
      overflow-x: auto;
      scrollbar-width: none;
    }
    .s-m2__logos::-webkit-scrollbar { display: none; }
    .s-m2__logos > li[aria-hidden="true"] { display: none; }
  }

}

/* ===== main/m3.css ===== */
/* ==========================================================================
   Mobile Section 3 — Figma 1244:14074. Who do we write for.
   ========================================================================== */

@media (max-width: 767.98px) {

  .s-m3 {
    background: var(--surface-brand);
    color: var(--content-on-brand);
    padding-block: var(--m-gap) var(--m-gap-block);
  }

  /* Group 89, 352 × 43: the title opens 25 under the script's cap here — the
     one lockup on this screen that is not on the 15 offset. Both are centred. */
  .s-m3__head {
    display: grid;
    text-align: center;
  }
  /* Group 89 / 90: the script and the title share one cell, so the
     lockup is as tall as whichever is taller — the Comforter word, or
     the offset plus the title. That is the file's own rule and it needs
     no measured height. */
  .s-m3__head > * { grid-area: 1 / 1; }
  .s-m3__script {
    z-index: 1;
    color: var(--content-on-inverse);
    pointer-events: none;
  }
  .s-m3__title { margin-top: var(--m-gap); }

  .s-m3__block { margin-top: var(--m-gap); }
  .s-m3__block--wellness { margin-top: var(--m-gap-block); }

  /* Rectangle 22 / 23, 314 × 375, hard against one window edge; Rectangle
     130 / 133, 250 × 100, against the other. The band is painted twice —
     solid beneath the picture and at half strength above it — so the overlap
     tints the photograph and the rest of the band stays flat amber. */
  .s-m3__stage {
    position: relative;
    height: 375px;
    margin-top: 0;
  }
  .s-m3__stage img {
    position: absolute;
    top: 0;
    width: 314px;
    max-width: 100%;
    height: 375px;
    object-fit: cover;
  }
  .s-m3__band,
  .s-m3__tint {
    position: absolute;
    width: 250px;
    max-width: 100%;
    height: 100px;
    background: var(--surface-accent);
  }
  .s-m3__tint { opacity: 0.5; }

  .s-m3__stage--business img { left: 0; object-position: 50% 0; }   /* 2026-11-04: framed from the top, her eyes sit ~45 lower and clear of the band */
  .s-m3__stage--business .s-m3__band,
  .s-m3__stage--business .s-m3__tint { right: 0; top: 0; }   /* 2026-11-04, client (phone review): was 160, over her lips; now at the top, as on his photo — the eyes sit at ~105 */

  .s-m3__stage--wellness img { right: 0; }
  .s-m3__stage--wellness .s-m3__band,
  .s-m3__stage--wellness .s-m3__tint { left: 0; top: 0; }

  .s-m3__copy { margin-top: var(--m-gap); }
  .s-m3__lede { margin-top: var(--m-gap-mid); }

  /* The wellness column reads from the right, as the file sets it. */
  .s-m3__block--wellness .s-m3__copy { text-align: right; }

  /* Button_form: 61 tall, 25 of air each side of the label. */
  .s-m3__cta {
    display: inline-grid;
    place-items: center;
    min-height: 61px;
    margin-top: var(--m-gap);
    padding-inline: var(--m-gap);
    background: var(--action-fill);
    color: var(--content-on-accent);
    text-align: center;
  }

  /* 2026-11-04, client (phone review): «при скролі екрану фотка має змінюватися так, як вона змінюється
     на головному екрані веб-версії». The desktop's hover turn (s4.css): the
     second frame comes through the first over 1.5 s while both drift 1.2 %
     the way the face turns. Here m3.js sets .is-on when the photo reaches the
     middle of the screen and drops it once the photo has left the screen. */
  .s-m3__stage img.is-turn { opacity: 0; }
  .s-m3__stage { --turn: -1; }
  @media (prefers-reduced-motion: no-preference) {
    .s-m3__stage img {
      clip-path: inset(0);
      transition: transform 1500ms cubic-bezier(.45, 0, .2, 1), clip-path 1500ms cubic-bezier(.45, 0, .2, 1), opacity 1500ms cubic-bezier(.45, 0, .2, 1);
    }
    .s-m3__stage.is-on img:not(.is-turn) {
      transform: scale(1.04) translateX(calc(var(--turn) * 1.2%));
      clip-path: inset(1.923% calc(1.923% + var(--turn) * 1.2%) 1.923% calc(1.923% - var(--turn) * 1.2%));
    }
    .s-m3__stage img.is-turn {
      transform: scale(1.04) translateX(calc(var(--turn) * -1.2%));
      clip-path: inset(1.923% calc(1.923% - var(--turn) * 1.2%) 1.923% calc(1.923% + var(--turn) * 1.2%));
    }
    .s-m3__stage.is-on img.is-turn { opacity: 1; transform: scale(1.04); clip-path: inset(1.923%); }
  }
}

/* ===== main/m4.css ===== */
/* ==========================================================================
   Mobile Section 4 — Figma 1244:14100. Authority · Clients · Legacy.
   ========================================================================== */

@media (max-width: 767.98px) {

  /* Group 89: script at the block's top left, title 15 lower and under it. */
  .s-m4__head {
    display: grid;
  }
  /* Group 89 / 90: the script and the title share one cell, so the
     lockup is as tall as whichever is taller — the Comforter word, or
     the offset plus the title. That is the file's own rule and it needs
     no measured height. */
  .s-m4__head > * { grid-area: 1 / 1; }
  .s-m4__script {
    z-index: 1;
    pointer-events: none;
  }
  .s-m4__title { margin-top: var(--m-gap-mid); }

  .s-m4__lede { margin-top: var(--m-gap-mid); }

  /* Frame 273 / 274 / 275 — 352 × 125, 25 of padding, 15 between them. */
  .s-m4__cards {
    display: grid;
    gap: var(--m-gap-mid);
    margin-top: var(--m-gap);
  }
  .s-m4__card {
    display: grid;
    gap: var(--m-gap-mid);
    padding: var(--m-gap);
    background: var(--surface-brand);
    color: var(--content-on-brand);
  }

  .s-m4__close { margin-top: var(--m-gap); }

}

/* ===== main/m5.css ===== */
/* ==========================================================================
   Mobile Section 5 — Figma 1244:14120. How it works, six steps.
   ========================================================================== */

@media (max-width: 767.98px) {

  .s-m5 {
    position: relative;
    background: var(--surface-brand);
    color: var(--content-on-brand);
    padding-block: var(--m-gap) var(--m-gap-block);
    overflow: hidden;
  }

  /* Ellipse 20 — a full ellipse centred on the block's top left corner,
     radii 244.5 × 279.85. The block clips it, so only the quarter the macket
     shows survives. Drawn, not exported: it is a 1px stroke, not a picture. */
  .s-m5__arc {
    position: absolute;
    left: -244.5px;
    top: -279.85px;
    width: 489px;
    height: 559.7px;
    border: var(--line-width) solid var(--content-on-inverse);
    border-radius: 50%;
    pointer-events: none;
  }

  .s-m5 > .container { position: relative; z-index: 1; }

  .s-m5__head {
    display: grid;
  }
  /* Group 89 / 90: the script and the title share one cell, so the
     lockup is as tall as whichever is taller — the Comforter word, or
     the offset plus the title. That is the file's own rule and it needs
     no measured height. */
  .s-m5__head > * { grid-area: 1 / 1; }
  .s-m5__script {
    z-index: 1;
    color: var(--content-on-inverse);
    pointer-events: none;
  }
  .s-m5__title { margin-top: var(--m-gap-mid); }

  .s-m5__lede  { margin-top: var(--m-gap-mid); }
  .s-m5__claim { margin-top: var(--m-gap); }

  /* Frame 280…285 — 352 × 125 on Editorial white, 25 of padding, 15 between. */
  .s-m5__steps {
    display: grid;
    gap: var(--m-gap-mid);
    grid-auto-rows: 1fr;
    margin-top: var(--m-gap);
  }
  .s-m5__step {
    display: grid;
    align-content: start;
    gap: var(--m-gap-mid);
    padding: var(--m-gap);
    background: var(--surface-page);
    color: var(--content-primary);
  }

  /* Frame 278: the numeral is 18 wide and the name opens at 33 — a 15 gap. */
  .s-m5__row {
    display: flex;
    gap: var(--m-gap-mid);
  }
  .s-m5__num {
    flex: 0 0 18px;
    color: var(--vista-blue-1);
  }

  .s-m5__foot {
    margin-top: var(--m-gap-mid);
    text-align: center;
  }
  .s-m5__cta {
    display: inline-grid;
    place-items: center;
    min-height: 61px;
    padding-inline: var(--m-gap);
    background: var(--action-fill);
    color: var(--content-on-accent);
    text-align: center;
  }

}

/* ===== main/m6.css ===== */
/* ==========================================================================
   Mobile Section 6 — Figma 1244:14170. Client voices, swipe carousel.
   ========================================================================== */

@media (max-width: 767.98px) {

  .s-m6__head {
    display: grid;
    text-align: center;
  }
  /* Group 89 / 90: the script and the title share one cell, so the
     lockup is as tall as whichever is taller — the Comforter word, or
     the offset plus the title. That is the file's own rule and it needs
     no measured height. */
  .s-m6__head > * { grid-area: 1 / 1; }
  .s-m6__script {
    z-index: 1;
    pointer-events: none;
  }
  .s-m6__title { margin-top: var(--m-gap-mid); }

  /* The row is as wide as the window and stops growing at 430, where the
     page column stops too. The card is 276 in the macket and never wider
     than the working area, so a 320 screen keeps its 25 margins. */
  .s-m6__roller {
    --m6-card: min(276px, calc(100vw - var(--m-margin) * 2));
    margin-top: var(--m-gap);
    width: min(100vw, var(--m-max));
    margin-inline: auto;
  }

  /* Scroll-snap and nothing else: no autoplay, no wrap, no switcher. */
  .s-m6__track {
    display: flex;
    align-items: stretch;
    gap: var(--m-gutter);
    padding-inline: calc((min(100vw, var(--m-max)) - var(--m6-card)) / 2);
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior-x: contain;
  }
  .s-m6__track::-webkit-scrollbar { display: none; }

  .s-m6__card {
    flex: 0 0 var(--m6-card);
    scroll-snap-align: center;
    display: flex;
    flex-direction: column;
    padding: var(--m-gap);
    background: var(--surface-brand);
    color: var(--content-on-brand);
  }

  /* Rectangle 140, 75 × 75, hard against the card's right edge; the name sits
     on the picture's bottom line. */
  .s-m6__top {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: var(--m-gap-tight);
    min-height: 75px;
  }
  .s-m6__avatar {
    flex: 0 0 75px;
    width: 75px;
    height: 75px;
    object-fit: cover;
  }

  .s-m6__role  { margin-top: var(--m-gap); }
  .s-m6__quote { margin-top: var(--m-gap); }

  /* Group 98: three 10px marks on a 25 step, 15 under the row. 5.7 — an
     indicator is not a target and takes no touch area. */
  .s-m6__dots {
    display: flex;
    justify-content: center;
    gap: var(--m-gap-mid);
    margin-top: var(--m-gap-mid);
  }
  .s-m6__dots span {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background: var(--rich-black-3);
  }
  .s-m6__dots span.is-on { background: var(--content-primary); }

}

/* ===== main/m7.css ===== */
/* ==========================================================================
   Mobile Section 7 — Figma 1244:14175. Case studies, swipe carousel.
   ========================================================================== */

@media (max-width: 767.98px) {

  .s-m7__head {
    display: grid;
    text-align: center;
  }
  /* Group 89 / 90: the script and the title share one cell, so the
     lockup is as tall as whichever is taller — the Comforter word, or
     the offset plus the title. That is the file's own rule and it needs
     no measured height. */
  .s-m7__head > * { grid-area: 1 / 1; }
  .s-m7__script {
    z-index: 1;
    pointer-events: none;
  }
  .s-m7__title { margin-top: var(--m-gap-mid); }

  .s-m7__roller {
    --m7-card: min(276px, calc(100vw - var(--m-margin) * 2));
    margin-top: var(--m-gap);
    width: min(100vw, var(--m-max));
    margin-inline: auto;
  }

  .s-m7__track {
    display: flex;
    align-items: flex-start;
    gap: var(--m-gutter);
    padding-inline: calc((min(100vw, var(--m-max)) - var(--m7-card)) / 2);
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior-x: contain;
  }
  /* 2026-11-04, client (phone, About): «кубіки з фото різні по розміру».
     The track was 4 px taller inside than out (the trimmed last line of
     text), so a slanted swipe also scrolled it up and cut 4 px off the top
     row. No vertical scroll now; 8 px of room below, given back by the
     margin, so nothing under the track moves. Same fix on About m3, Main
     m7 and m10, landing-full m5 and FAQ m1. */
  .s-m7__track { overflow-y: hidden; padding-bottom: 8px; margin-bottom: -8px; }
  .s-m7__track::-webkit-scrollbar { display: none; }

  .s-m7__card {
    flex: 0 0 var(--m7-card);
    scroll-snap-align: center;
  }

  /* Rectangle 144 — 276 × 390. The ratio is the macket's, so the row does not
     jump while the covers decode. */
  .s-m7__cover {
    width: 100%;
    aspect-ratio: 276 / 390;
    object-fit: cover;
  }

  /* Frame 351: the caption opens 15 under the cover and runs on a 15 rhythm. */
  .s-m7__author,
  .s-m7__book,
  .s-m7__note { margin-top: var(--m-gap-mid); }

  .s-m7__dots {
    display: flex;
    justify-content: center;
    gap: var(--m-gap-mid);
    margin-top: var(--m-gap-mid);
  }
  .s-m7__dots span {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background: var(--rich-black-3);
  }
  .s-m7__dots span.is-on { background: var(--content-primary); }

  .s-m7__foot {
    margin-top: var(--m-gap);
    text-align: center;
  }
  .s-m7__cta {
    display: inline-grid;
    place-items: center;
    min-height: 61px;
    padding-inline: var(--m-gap);
    background: var(--action-fill);
    color: var(--content-on-accent);
    text-align: center;
  }

}

/* ===== main/m8.css ===== */
/* ==========================================================================
   Mobile Section 8 — Figma 1244:14182. The five formats.
   ========================================================================== */

@media (max-width: 767.98px) {

  .s-m8__head {
    display: grid;
    text-align: center;
  }
  /* Group 89 / 90: the script and the title share one cell, so the
     lockup is as tall as whichever is taller — the Comforter word, or
     the offset plus the title. That is the file's own rule and it needs
     no measured height. */
  .s-m8__head > * { grid-area: 1 / 1; }
  .s-m8__script {
    z-index: 1;
    pointer-events: none;
  }
  .s-m8__title { margin-top: var(--m-gap-mid); }

  .s-m8__cards {
    display: grid;
    gap: var(--m-gap-mid);
    margin-top: var(--m-gap);
  }
  .s-m8__card {
    display: grid;
    gap: var(--m-gap-mid);
    padding: var(--m-gap);
    background: var(--surface-brand);
    color: var(--content-on-brand);
  }

  /* Frame 357: the name opens the row, the price closes it against the right
     edge of the card's inner box. Both are the 15 ExtraBlack style. */
  .s-m8__row {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: var(--m-gap-tight);
    /* 2026-10-27: the price now reads "from $X/month" (designer and client
       answers of 20 Oct, all prices with "from"); where the card is too
       narrow for name and price on one line, the price drops under the
       name, 10 below — as the tablet card does (t7.css). */
    flex-wrap: wrap;
  }
  .s-m8__price {
    flex: 0 0 100%;   /* 2026-11-04, client (phone review): always under the name, on every card (was beside it when it fitted) */
    color: var(--content-on-inverse);
  }

  .s-m8__foot {
    margin-top: var(--m-gap);
    text-align: center;
  }
  .s-m8__cta {
    display: inline-grid;
    place-items: center;
    min-height: 61px;
    padding-inline: var(--m-gap);
    background: var(--action-fill);
    color: var(--content-on-accent);
    text-align: center;
  }

}

/* ===== main/m9.css ===== */
/* ==========================================================================
   Mobile Section 9 — Figma 1244:14218. The Discovery Sprint.
   ========================================================================== */

@media (max-width: 767.98px) {

  /* Group 108, 352 × 198: the lockup is centred on the picture, both axes. */
  .s-m9__stage {
    position: relative;
    aspect-ratio: 352 / 198;
  }
  .s-m9__stage img {
    width: 100%;
    height: 100%;
    object-fit: cover;
  }
  .s-m9__head {
    position: absolute;
    left: 0;
    right: 0;
    top: 50%;
    transform: translateY(-50%);
    text-align: center;
    display: grid;
  }
  /* Group 89 / 90: the script and the title share one cell, so the
     lockup is as tall as whichever is taller — the Comforter word, or
     the offset plus the title. That is the file's own rule and it needs
     no measured height. */
  .s-m9__head > * { grid-area: 1 / 1; }
  .s-m9__script {
    z-index: 1;
    color: var(--content-on-inverse);
    pointer-events: none;
  }
  .s-m9__title {
    margin-top: var(--m-gap-mid);
    color: var(--content-accent);
  }

  /* Frame 367, 352 × 300, 25 of padding, everything centred. */
  .s-m9__card {
    margin-top: var(--m-gap);
    padding: var(--m-gap-block) var(--m-gap);   /* 2026-11-04, client (phone review): 50 above and below (was 25 all round) */
    background: var(--surface-brand);
    color: var(--content-on-brand);
    text-align: center;
  }
  .s-m9__body  { margin-top: var(--m-gap-mid); }

  /* The price sits 50 under the body — the one large gap inside a card on
     this screen, and it is the file's. */
  .s-m9__price {
    margin-top: var(--m-gap-block);
    color: var(--content-on-inverse);
  }

  .s-m9__foot {
    margin-top: var(--m-gap);
    text-align: center;
  }
  .s-m9__cta {
    display: inline-grid;
    place-items: center;
    min-height: 61px;
    padding-inline: var(--m-gap);
    background: var(--action-fill);
    color: var(--content-on-accent);
    text-align: center;
  }

}

/* ===== main/m10.css ===== */
/* ==========================================================================
   Mobile Section 10 — Figma 1244:14231. Our team, and how we work.
   ========================================================================== */

@media (max-width: 767.98px) {

  .s-m10__head {
    display: grid;
    text-align: center;
  }
  /* Group 89 / 90: the script and the title share one cell, so the
     lockup is as tall as whichever is taller — the Comforter word, or
     the offset plus the title. That is the file's own rule and it needs
     no measured height. */
  .s-m10__head > * { grid-area: 1 / 1; }
  .s-m10__script {
    z-index: 1;
    pointer-events: none;
  }
  .s-m10__title { margin-top: var(--m-gap-mid); }

  .s-m10__sub {
    margin-top: var(--m-gap-mid);
    text-align: center;
  }

  /* The roller stays inside the working area — the file's pages are 352, the
     width of the column, not of the window. */
  .s-m10__roller { margin-top: var(--m-gap); }

  .s-m10__track {
    display: flex;
    gap: var(--m-gutter);
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior-x: contain;
  }
  /* 2026-11-04, client (phone, About): «кубіки з фото різні по розміру».
     The track was 4 px taller inside than out (the trimmed last line of
     text), so a slanted swipe also scrolled it up and cut 4 px off the top
     row. No vertical scroll now; 8 px of room below, given back by the
     margin, so nothing under the track moves. Same fix on About m3, Main
     m7 and m10, landing-full m5 and FAQ m1. */
  .s-m10__track { overflow-y: hidden; padding-bottom: 8px; margin-bottom: -8px; }
  .s-m10__track::-webkit-scrollbar { display: none; }

  .s-m10__page {
    flex: 0 0 100%;
    scroll-snap-align: start;
  }

  /* Frame 374: 163.5 + 25 + 163.5 = 352, rows on the same 25. */
  .s-m10__grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--m-gutter);
  }
  /* The portraits are the desktop layer's 316 × 450 files; the macket crops
     them square and frames the head, so the crop is biased to the top rather
     than centred. */
  .s-m10__person img {
    width: 100%;
    aspect-ratio: 163.5 / 164;
    object-fit: cover;
    object-position: 50% 22%;
  }
  .s-m10__name { margin-top: var(--m-gap-mid); }
  .s-m10__role { margin-top: var(--m-gap-mid); }

  .s-m10__dots {
    display: flex;
    justify-content: center;
    gap: var(--m-gap-mid);
    margin-top: var(--m-gap-mid);
  }
  .s-m10__dots span {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background: var(--rich-black-3);
  }
  .s-m10__dots span.is-on { background: var(--content-primary); }

  .s-m10__lede  { margin-top: var(--m-gap-block); }
  .s-m10__label {
    margin-top: var(--m-gap-block);
    text-align: center;
  }

  /* Frame 363 / 377 / 378 / 379 — the file equalises the four cards on the
     tallest. `1fr` rows do the same from the content, so a longer line still
     grows the row instead of being cut. */
  .s-m10__how {
    display: grid;
    gap: var(--m-gap-mid);
    grid-auto-rows: 1fr;
    margin-top: var(--m-gap);
  }
  .s-m10__how-card {
    display: grid;
    align-content: start;
    gap: var(--m-gap-mid);
    padding: var(--m-gap);
    /* 2026-10-27 · mobile review 20 Oct, item 5: the cards are Rich Black 3,
       not the Vista Blue 1 brand surface. */
    background: var(--rich-black-3);
    color: var(--content-primary);
  }

  /* 2026-11-04, client (phone review): the quote over the portrait, on tap (m10.js). */
  .s-m10__photo {
    position: relative;
    display: block;
    width: 100%;
    padding: 0;
    border: 0;
    background: none;
    cursor: pointer;
  }
  .s-m10__quote {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--m-gap-mid);
    /* 2026-11-04, client (phone review): «при тапі на фото команди все фото заливається жовтим і цитата на весь квадратик» — Main and About alike: the About card's Amber 4 plate and Base type. */
    background: var(--surface-accent);
    color: var(--content-on-accent);
    font-size: 15px;
    line-height: 1.35;
    text-align: center;
    opacity: 0;
    transition: opacity var(--t-base) ease;
    pointer-events: none;
  }
  .s-m10__photo[aria-expanded="true"] .s-m10__quote { opacity: 1; }
}

/* ===== main/m11.css ===== */
/* ==========================================================================
   Mobile Section 11 — Figma 1244:14264. The founder.
   ========================================================================== */

@media (max-width: 767.98px) {

  /* Group 109, 402 × 350. Rectangle 147 is the amber panel at the left edge;
     image 10 is 314 wide against the right; Rectangle 146 is the same amber
     again at half strength, so the overlap tints the photograph and the rest
     of the panel stays flat. */
  .s-m11__stage {
    position: relative;
    height: 350px;
  }
  .s-m11__stage img {
    position: absolute;
    right: 0;
    top: 0;
    width: 314px;
    max-width: 100%;
    height: 350px;
    object-fit: cover;
  }
  .s-m11__band,
  .s-m11__tint {
    position: absolute;
    left: 0;
    top: 0;
    width: 151px;
    max-width: 100%;
    height: 350px;
    background: var(--surface-accent);
  }
  .s-m11__tint { opacity: 0.5; }

  .s-m11__head {
    display: grid;
    margin-top: var(--m-gap);
    text-align: center;
  }
  /* Group 89 / 90: the script and the title share one cell, so the
     lockup is as tall as whichever is taller — the Comforter word, or
     the offset plus the title. That is the file's own rule and it needs
     no measured height. */
  .s-m11__head > * { grid-area: 1 / 1; }
  .s-m11__script {
    z-index: 1;
    pointer-events: none;
  }
  .s-m11__title { margin-top: var(--m-gap-mid); }

  .s-m11__lede  { margin-top: var(--m-gap-mid); text-align: center; }
  .s-m11__body  { margin-top: var(--m-gap);     text-align: center; }
  .s-m11__quote { margin-top: var(--m-gap);     text-align: center; }

  /* Frame 458: three marks on a 50 step, so every area is the full 44 × 44
     and no two meet — 44 across a 50 step leaves 6 between them. */
  .s-m11__social {
    display: flex;
    justify-content: center;
    align-items: center;
    gap: var(--m-gutter);
    margin-top: var(--m-gap);
  }
  .s-m11__social a {
    display: block;
    --tap-w: 44px;
    --tap-h: 44px;
  }
  .s-m11__social img { height: 25px; width: auto; }

}

/* ===== main/m12.css ===== */
/* ==========================================================================
   Mobile Section 12 — Figma 1244:14281. FAQ accordion.
   ========================================================================== */

@media (max-width: 767.98px) {

  .s-m12 {
    background: var(--surface-brand);
    color: var(--content-on-brand);
    padding-block: var(--m-gap);
  }

  .s-m12__head {
    display: grid;
    text-align: center;
  }
  /* Group 89 / 90: the script and the title share one cell, so the
     lockup is as tall as whichever is taller — the Comforter word, or
     the offset plus the title. That is the file's own rule and it needs
     no measured height. */
  .s-m12__head > * { grid-area: 1 / 1; }
  .s-m12__script {
    z-index: 1;
    color: var(--content-on-inverse);
    pointer-events: none;
  }
  .s-m12__title { margin-top: var(--m-gap-mid); }

  .s-m12__list {
    display: grid;
    gap: var(--m-gap-mid);
    margin-top: var(--m-gap);
  }
  .s-m12__item {
    background: var(--surface-page);
    color: var(--content-primary);
  }

  /* The row is the whole card: 352 wide, 25 of padding, so the collapsed item
     is 61 — or 80 where the question runs to two lines. Far more than the 44
     the touch rule asks for, and the next row is 15 away. */
  /* The label is blockified: `text-box-trim` trims a block container's first
     and last line, and does nothing on an inline box — an inline label put a
     full 19 line box in a row the file draws 11 tall. */
  .s-m12__q > span { display: block; }

  .s-m12__q {
    display: block;
    width: 100%;
    padding: var(--m-gap);
    border: 0;
    background: none;
    text-align: left;
    cursor: pointer;
  }

  /* Height driven by the answer, never a fixed value: `0fr` to `1fr` measures
     the content and cannot cut a longer answer off. */
  .s-m12__panel {
    display: grid;
    grid-template-rows: 0fr;
    transition: grid-template-rows var(--t-base);
  }
  .s-m12__item.is-open .s-m12__panel { grid-template-rows: 1fr; }
  .s-m12__panel-in { overflow: hidden; }

  /* The trigger already carries 25 under the question, so the answer needs
     only its own 25 at the foot. */
  .s-m12__a { padding: 0 var(--m-gap) var(--m-gap); }

  @media (prefers-reduced-motion: reduce) {
    .s-m12__panel { transition: none; }
  }

}

/* ===== main/m13.css ===== */
/* ==========================================================================
   Mobile Section 13 — Figma 1244:14292. Three ways to start.
   ========================================================================== */

@media (max-width: 767.98px) {

  .s-m13__head {
    display: grid;
    text-align: center;
  }
  /* Group 89 / 90: the script and the title share one cell, so the
     lockup is as tall as whichever is taller — the Comforter word, or
     the offset plus the title. That is the file's own rule and it needs
     no measured height. */
  .s-m13__head > * { grid-area: 1 / 1; }
  .s-m13__script {
    z-index: 1;
    pointer-events: none;
  }
  .s-m13__title { margin-top: var(--m-gap-mid); }

  .s-m13__lede {
    margin-top: var(--m-gap-mid);
    text-align: center;
  }

  /* Frame 464 / 465 / 466 — 352 wide, 25 of padding, 15 between. Space cadet
     3 is one of the two colours the file keeps for isolated cases; this is
     the only block on the screen that uses it. */
  .s-m13__cards {
    display: grid;
    gap: var(--m-gap-mid);
    margin-top: var(--m-gap);
  }
  .s-m13__card {
    padding: var(--m-gap);
    background: var(--space-cadet-3);
    color: var(--content-primary);
    text-align: center;
  }

  .s-m13__body { margin-top: var(--m-gap); }
  .s-m13__foot { margin-top: var(--m-gap); }

  .s-m13__cta {
    display: inline-grid;
    place-items: center;
    min-height: 61px;
    padding-inline: var(--m-gap);
    background: var(--action-fill);
    color: var(--content-on-accent);
    text-align: center;
  }

}

/* ===== main/m14.css ===== */
/* ==========================================================================
   Mobile Section 14 — Figma 1244:14317. The contact form.
   ========================================================================== */

@media (max-width: 767.98px) {

  .s-m14__head {
    display: grid;
    text-align: center;
  }
  /* Group 89 / 90: the script and the title share one cell, so the
     lockup is as tall as whichever is taller — the Comforter word, or
     the offset plus the title. That is the file's own rule and it needs
     no measured height. */
  .s-m14__head > * { grid-area: 1 / 1; }
  .s-m14__script {
    z-index: 1;
    pointer-events: none;
  }
  .s-m14__title { margin-top: var(--m-gap-mid); }

  /* Form_Pas — 352 × 592 on the brand surface, 25 of padding all round. */
  .s-m14__form {
    margin-top: var(--m-gap);
    padding: var(--m-gap);
    background: var(--surface-brand);
    color: var(--content-on-brand);
  }

  /* Frame 469 / 470 / 471 on a 25 rhythm; inside each, the label sits 10
     above its field — the tightest gap the file uses. */
  .s-m14__fields {
    display: grid;
    gap: var(--m-gap);
  }
  .s-m14__field {
    display: grid;
    gap: var(--m-gap-tight);
  }

  /* Form_cards_mobile: Small 302 × 41, Big 302 × 225. */
  .s-m14__input {
    width: 100%;
    height: 41px;
    padding-inline: var(--m-gap-tight);
    border: 0;
    background: var(--surface-page);
    color: var(--content-primary);
  }
  .s-m14__input--big {
    height: 225px;
    padding-block: var(--m-gap-tight);
    resize: vertical;
  }
  .s-m14__input::placeholder { color: var(--vista-blue-1); opacity: 1; }

  .s-m14__foot {
    margin-top: var(--m-gap);
    text-align: center;
  }
  .s-m14__submit {
    display: inline-grid;
    place-items: center;
    min-height: 61px;
    padding-inline: var(--m-gap);
    border: 0;
    background: var(--action-fill);
    color: var(--content-on-accent);
    text-align: center;
    cursor: pointer;
  }
  /* 12. A second tap while the request is in flight must be impossible. */
  .s-m14__submit[disabled] { cursor: default; }

  .s-m14__status {
    margin-top: var(--m-gap);
    text-align: center;
  }

}
