/* ============================================================
   VERION - AI Automation Agency
   Design system & components · see DESIGN-SYSTEM.md
   ============================================================ */

/* ---------- Tokens ---------- */
:root {
  --bg: #EBEBEA; /* nudged brighter/less warm 2026-09-12 (was #E6E6E3) */
  --bg-soft: #E2E2E0; /* nudged to match (was #DDDDD9) */
  --surface: #FFFFFF;
  --ink: #141311;
  --ink-soft: #3A3833;
  --muted: #6E6B63;
  --line: #E5E3DB;
  --line-strong: #D8D5CC;
  --brand: #141311;
  --brand-deep: #0B0B0A;
  --brand-soft: #E6E6E4;
  --brand-ghost: #F3F3F2;
  --grad: linear-gradient(135deg, #3A3833 0%, #141311 100%);
  --success: #0E9F6E;
  --success-soft: #E5F6EF;
  --error: #D92D20;
  --error-soft: #FEEFEE;

  --font-body: 'Switzer', 'Satoshi', 'Segoe UI', -apple-system, sans-serif;
  --font-display: 'Switzer', 'Satoshi', 'Segoe UI', sans-serif;
  --font-serif: 'Instrument Serif', Georgia, serif;
  --font-mono: 'JetBrains Mono', 'Cascadia Code', monospace;

  --r-input: 12px;
  --r-card: 20px;
  --r-panel: 28px;
  --r-pill: 999px;

  --shadow-s: 0 1px 2px rgba(22,20,46,.05), 0 4px 12px rgba(22,20,46,.05);
  --shadow-m: 0 2px 4px rgba(22,20,46,.05), 0 12px 32px rgba(22,20,46,.09);
  --shadow-l: 0 4px 8px rgba(22,20,46,.06), 0 24px 64px rgba(20,19,17,.14);

  --ease-out: cubic-bezier(.22, 1, .36, 1);
  --container: 1160px;
}

/* ---------- Base ---------- */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

html { scroll-behavior: smooth; }

/* Hide the browser scrollbar everywhere while keeping wheel / trackpad /
   touch / keyboard scrolling fully functional. Firefox uses
   scrollbar-width, WebKit/Blink the ::-webkit-scrollbar pseudo-element,
   old Edge/IE -ms-overflow-style. */
html { scrollbar-width: none; -ms-overflow-style: none; }
html::-webkit-scrollbar, body::-webkit-scrollbar { width: 0; height: 0; display: none; }

body {
  font-family: var(--font-body);
  font-size: 1.0625rem;
  line-height: 1.65;
  color: var(--ink-soft);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

/* ---------- Dot field background ----------
   Fixed grid of soft grey dots with a slow, non-directional wave
   (drawn by scripts/dotfield.js). Painted just above the page's base
   colour and below all content; fades in only while a [data-dotfield]
   section is on screen (always on where the page has none, e.g. booking). */
.dotfield {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  opacity: 0;
  transition: opacity .8s var(--ease-out);
}
.dotfield.is-visible { opacity: 1; }
@media (prefers-reduced-motion: reduce) {
  .dotfield { transition: none; }
}
/* Lift every content wrapper above the dot field. The wrappers have no
   background of their own, so dots still show through the gaps between
   their content. */
.hero-morph-pin,
.flow-wrap,
.footer-has-hills,
.page-booking .bk-viewport {
  position: relative;
  z-index: 1;
}

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

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

::selection { background: var(--brand); color: #fff; }

h1, h2, h3, h4 {
  font-weight: 700;
  color: var(--ink);
  letter-spacing: -0.03em;
  line-height: 1.12;
  text-wrap: balance;
}

/* Display voice: editorial - clean grotesk with italic serif accents */
h1, h2 {
  font-family: var(--font-display);
  font-weight: 500;
  letter-spacing: -0.03em;
}
h1 { font-size: clamp(3.4rem, 5.2vw, 4.75rem); line-height: 1.04; }
h2 { font-size: clamp(2.1rem, 3vw, 2.65rem); line-height: 1.1; }
h3 { font-size: 1.375rem; letter-spacing: -0.02em; font-weight: 600; }

.accent-serif {
  font-family: var(--font-serif);
  font-style: italic;
  font-weight: 400;
  letter-spacing: -0.015em;
  color: inherit;
}

.container { max-width: var(--container); margin: 0 auto; padding: 0 32px; }

section { padding: 160px 0; }

.eyebrow {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--muted);
  display: inline-flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 20px;
}
.eyebrow::before {
  content: '';
  width: 22px; height: 1px;
  background: var(--muted);
  opacity: .6;
}

.section-head { max-width: 640px; margin-bottom: 80px; }
.section-head.center { margin-left: auto; margin-right: auto; text-align: center; }
.section-head.center .eyebrow::after {
  content: ''; width: 22px; height: 1px; background: var(--brand); opacity: .6;
}
.section-head p { margin-top: 20px; font-size: 1.125rem; color: var(--muted); }

.band { background: var(--bg); }

:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 3px;
  border-radius: 4px;
}

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  font-family: var(--font-body);
  font-size: 0.9375rem;
  font-weight: 500;
  letter-spacing: -0.005em;
  padding: 14px 28px;
  border-radius: var(--r-pill);
  border: 1px solid transparent;
  cursor: pointer;
  transition: background-color .2s var(--ease-out), border-color .2s var(--ease-out),
              color .2s var(--ease-out), box-shadow .25s var(--ease-out), transform .2s var(--ease-out);
  white-space: nowrap;
}
.btn svg { width: 16px; height: 16px; transition: transform .25s var(--ease-out); }
.btn:hover svg { transform: translateX(3px); }

.btn-primary {
  background: var(--ink);
  color: #fff;
  box-shadow: 0 1px 2px rgba(20,19,17,.2), 0 10px 26px rgba(20,19,17,.16);
}
.btn-primary:hover {
  background: #000;
  transform: translateY(-1px);
  box-shadow: 0 2px 4px rgba(20,19,17,.2), 0 16px 34px rgba(20,19,17,.22);
}
.btn-primary:active { transform: translateY(0) scale(.975); transition-duration: .08s; }
.btn-secondary:active { transform: translateY(0) scale(.975); transition-duration: .08s; }

.btn-secondary {
  background: rgba(255,255,255,.75);
  color: var(--ink);
  border-color: var(--line-strong);
  box-shadow: 0 1px 2px rgba(20,19,17,.04);
}
.btn-secondary:hover {
  border-color: var(--ink);
  background: #fff;
  transform: translateY(-1px);
  box-shadow: 0 6px 18px rgba(20,19,17,.08);
}

.btn-lg { padding: 17px 34px; font-size: 1rem; }
.btn-sm { padding: 11px 24px; font-size: 0.9375rem; }

/* ---------- CTA button - ripple-fill (ported from styled-components; animation kept 1:1:
   .3s/.6s cubic-bezier(.23,1,.32,1), center circle scale 0→3, hover scale 1.1) ---------- */
.btn-cta {
  cursor: pointer;
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 12px 28px;
  font-family: var(--font-body);
  font-size: 1rem;
  font-weight: 600;
  letter-spacing: -0.005em;
  text-decoration: none;
  border: 2px solid transparent;
  border-radius: 34px;
  background-color: transparent;
  overflow: hidden;
  isolation: isolate;
  transition: all 0.3s cubic-bezier(0.23, 1, 0.320, 1);
}
.btn-cta::before {
  content: '';
  position: absolute;
  inset: 0;
  margin: auto;
  /* sized to the button so scale(3) always floods it edge-to-edge,
     however wide the label (fixed 50px left gaps on long buttons) */
  width: 50%;
  height: auto;
  aspect-ratio: 1 / 1;
  border-radius: 50%;
  scale: 0;
  z-index: -1;
  transition: all 0.8s cubic-bezier(0.23, 1, 0.320, 1);
}
.btn-cta:hover::before { scale: 3; }
.btn-cta:hover { scale: 1.1; }
.btn-cta:active { scale: 1; }
.btn-cta svg { width: 18px; height: 18px; flex-shrink: 0; }
.btn-cta-sm { padding: 10px 22px; font-size: 0.875rem; }

/* ---------- Primary CTA - arrow-swap button (System B, ported 1:1:
   .6s/.8s cubic-bezier(.23,1,.32,1), arrows trade places, circle floods.
   Default: black bg / white text. Hover: white bg / black text.
   Shape stays pill - no border-radius change on hover. ---------- */
.btn-anim {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  /* Slimmed to match .btn-cta (12px 28px) so hero + section buttons read as
     a matched pair rather than two different button systems side by side. */
  padding: 12px 28px;
  border: 2px solid var(--ink);
  font-family: var(--font-body);
  font-size: 1rem;
  background-color: var(--ink);
  border-radius: 100px;
  font-weight: 600;
  letter-spacing: -0.005em;
  color: #fff;
  cursor: pointer;
  overflow: hidden;
  text-decoration: none;
  transition: all 0.6s cubic-bezier(0.23, 1, 0.32, 1);
}
.btn-anim svg {
  position: absolute;
  width: 24px;
  fill: #fff;
  z-index: 9;
  transition: all 0.8s cubic-bezier(0.23, 1, 0.32, 1);
}
.btn-anim .arr-1 { right: 16px; }
.btn-anim .arr-2 { left: -25%; }
.btn-anim .circle {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 20px;
  height: auto;
  aspect-ratio: 1 / 1;
  background-color: #fff;
  border-radius: 50%;
  opacity: 0;
  transition: all 0.8s cubic-bezier(0.23, 1, 0.32, 1);
}
.btn-anim .text {
  position: relative;
  z-index: 1;
  transform: translateX(-12px);
  transition: all 0.8s cubic-bezier(0.23, 1, 0.32, 1);
}
.btn-anim:hover {
  color: var(--ink);
}
.btn-anim:hover .arr-1 { right: -25%; }
.btn-anim:hover .arr-2 { left: 16px; }
.btn-anim:hover .text { transform: translateX(12px); }
.btn-anim:hover svg { fill: var(--ink); }
.btn-anim:active {
  scale: 0.95;
}
.btn-anim:hover .circle {
  width: max(220px, 115%);
  opacity: 1;
}

/* dark variant - header CTA: premium black, fills to white on hover */
.btn-cta-dark {
  background-color: var(--ink);
  color: #fff;
  border-color: var(--ink);
}
.btn-cta-dark::before { background-color: #fff; }
.btn-cta-dark:hover {
  color: var(--ink);
  border-color: var(--ink);
  box-shadow: 0 0 20px rgba(20, 19, 17, .22);
}

/* light variant - hero / section CTAs: white, fills to premium black on hover */
.btn-cta-light {
  background-color: #fff;
  color: var(--ink);
  border-color: #fff;
  box-shadow: var(--shadow-s);
}
.btn-cta-light::before { background-color: var(--ink); }
.btn-cta-light:hover {
  color: #fff;
  border-color: var(--ink);
  box-shadow: 0 0 20px rgba(20, 19, 17, .28);
}

.btn[disabled] { opacity: .55; cursor: not-allowed; pointer-events: none; }

/* ---------- Site loader - 21st.dev "loader-3" (Ravi Katiyar), ported
   verbatim ----------
   The two earlier attempts at this were both wrong because 21st.dev's
   public "Copy prompt" export (what got pasted into chat) only ever
   contained the @keyframes - never the real .loader/.box/.ground/:before/
   :after rules that actually build and position the cube. That geometry
   is NOT published anywhere on the component's page (even after paying
   for an "unlock", the revealed panel is the same partial snippet) - it
   only exists compiled into the live preview's own bundled HTML
   (cdn.21st.dev/.../bundle.<hash>.html). Every rule below was read
   straight out of that bundle's <style>, unedited. This is the real,
   complete component - not a reconstruction.
   Two intentional differences from the untouched original, both
   explicitly requested (separately from "keep every color/size exact"):
     1. `--clr` (the color the mask wedges + trapdoor gradient blend
        into) is set to this site's own --bg instead of the component's
        own default #fff/.dark #000 - --clr exists specifically so this
        piece matches whatever page background surrounds it, and our
        surrounding background is --bg, not pure white or black. This
        is applying the variable as designed, not recoloring the cube.
     2. Every animation runs ONCE instead of the original's `infinite`
        loop - every rule below sets animation-name/duration/timing/
        fill-mode as separate longhands rather than the `animation`
        shorthand the original used (which included `infinite`), so
        iteration-count is left at CSS's own default of 1. main.js
        fades the whole overlay out once this finishes (~3s, matches
        --duration below unchanged from the original).
   The cube itself (#275efe / #2f71ff), every box's position/--x/--y,
   the ground/mask geometry, and all keyframe timings are byte-for-byte
   what 21st.dev's own preview renders. */
.site-loader {
  position: fixed; inset: 0; z-index: 10000;
  --loader-bg: #F0F0EE;  /* halfway between the site grey and the first, brighter try */
  background: var(--loader-bg);
  opacity: 1;
  transition: opacity .3s var(--ease-out);
}
.site-loader.done { opacity: 0; pointer-events: none; }

.site-loader .loader {
  --clr: var(--loader-bg);
  --duration: 2.5s; /* a little faster again */
  /* Recolored from the original blue to a charcoal family, not a flat
     pure black - the cube's own lit/side faces are the SAME base color
     lightened via filter:brightness(1.2)/(1.4) (see .box div:before/
     :after below, untouched), and multiplying an already-near-black
     value by 1.2-1.4 barely moves it, which would read as one flat
     blob with no visible shading. #2a2a2a -> #323232 -> #3b3b3b keeps
     it reading unmistakably as "black" while still visibly separating
     the cube's three faces, and stays soft against the cream page
     background instead of a stark, overpowering pure-black cutout. */
  --primary: #2a2a2a;
  --primary-light: #3a3a3a;
  --primary-rgba: #2a2a2a00;
  position: absolute;
  left: 50%;
  top: 50%;
  margin: -120px 0 0 -100px; /* nudged down again, 10px more (was -130px) - total 40px down from dead-centre now */
  width: 200px;
  height: 320px;
  transform-style: preserve-3d;
}
@media (max-width: 480px) {
  .site-loader .loader { zoom: .44; }
}
.site-loader .loader:before,
.site-loader .loader:after {
  --r: 20.5deg;
  content: "";
  background: var(--clr);
  width: 320px;
  height: 140px;
  transform: translateZ(200px) rotate(var(--r));
  position: absolute;
  bottom: -11px;
  right: 32%;
  animation-name: mask;
  animation-duration: var(--duration);
  animation-timing-function: linear;
  animation-fill-mode: forwards;
}
.site-loader .loader:after {
  --r: -20.5deg;
  left: 32%;
  right: auto;
}
.site-loader .loader .ground {
  transform-style: preserve-3d;
  position: absolute;
  bottom: -120px;
  left: -50px;
  transform: rotateY(-47deg) rotateX(-15deg) rotate(15deg) scale(1);
}
.site-loader .loader .ground div {
  background: linear-gradient(45deg, var(--primary) 0%, var(--primary) 50%, var(--primary-light) 50%, var(--primary-light) 100%);
  width: 200px;
  height: 200px;
  transform-style: preserve-3d;
  transform: rotateX(90deg) rotateY(0) translate(-48px, -120px) translateZ(100px) scale(0);
  animation-name: ground;
  animation-duration: var(--duration);
  animation-timing-function: linear;
  animation-fill-mode: forwards;
}
.site-loader .loader .ground div:before,
.site-loader .loader .ground div:after {
  --rx: 90deg; --ry: 0deg; --x: 44px; --y: 162px; --z: -50px;
  content: "";
  opacity: 0;
  background: linear-gradient(var(--primary), var(--primary-rgba));
  width: 156px;
  height: 300px;
  transform: rotateX(var(--rx)) rotateY(var(--ry)) translate(var(--x), var(--y)) translateZ(var(--z));
  position: absolute;
  animation-name: ground-shine;
  animation-duration: var(--duration);
  animation-timing-function: linear;
  animation-fill-mode: forwards;
}
.site-loader .loader .ground div:after {
  --rx: 90deg; --ry: 90deg; --x: 0; --y: 177px; --z: 150px;
}
.site-loader .loader .box {
  --x: 0; --y: 0;
  position: absolute;
  transform: translate(var(--x), var(--y));
  animation-duration: var(--duration);
  animation-timing-function: linear;
  animation-fill-mode: forwards;
}
.site-loader .loader .box div {
  background-color: var(--primary);
  width: 48px;
  height: 48px;
  position: relative;
  transform-style: preserve-3d;
  transform: rotateY(-47deg) rotateX(-15deg) rotate(15deg) scale(0);
  animation-duration: var(--duration);
  animation-timing-function: ease;
  animation-fill-mode: forwards;
}
.site-loader .loader .box div:before,
.site-loader .loader .box div:after {
  --rx: 90deg; --ry: 0deg; --z: 24px; --y: -24px; --x: 0;
  content: "";
  background-color: inherit;
  width: inherit;
  height: inherit;
  position: absolute;
  transform: rotateX(var(--rx)) rotateY(var(--ry)) translate(var(--x), var(--y)) translateZ(var(--z));
  filter: brightness(var(--b, 1.2));
}
.site-loader .loader .box div:after {
  --rx: 0deg; --ry: 90deg; --x: 24px; --y: 0; --b: 1.4;
}
.site-loader .loader .box.box0 { --x: -220px; --y: -120px; top: 108px; left: 58px; }
.site-loader .loader .box.box1 { --x: -260px; --y: 120px; top: 120px; left: 25px; }
.site-loader .loader .box.box2 { --x: 120px; --y: -190px; top: 64px; left: 58px; }
.site-loader .loader .box.box3 { --x: 280px; --y: -40px; top: 120px; left: 91px; }
.site-loader .loader .box.box4 { --x: 60px; --y: 200px; top: 132px; left: 58px; }
.site-loader .loader .box.box5 { --x: -220px; --y: -120px; top: 76px; left: 25px; }
.site-loader .loader .box.box6 { --x: -260px; --y: 120px; top: 76px; left: 91px; }
.site-loader .loader .box.box7 { --x: -240px; --y: 200px; top: 87px; left: 58px; }
.site-loader .loader .box0 { animation-name: box-move0; }
.site-loader .loader .box0 div { animation-name: box-scale0; }
.site-loader .loader .box1 { animation-name: box-move1; }
.site-loader .loader .box1 div { animation-name: box-scale1; }
.site-loader .loader .box2 { animation-name: box-move2; }
.site-loader .loader .box2 div { animation-name: box-scale2; }
.site-loader .loader .box3 { animation-name: box-move3; }
.site-loader .loader .box3 div { animation-name: box-scale3; }
.site-loader .loader .box4 { animation-name: box-move4; }
.site-loader .loader .box4 div { animation-name: box-scale4; }
.site-loader .loader .box5 { animation-name: box-move5; }
.site-loader .loader .box5 div { animation-name: box-scale5; }
.site-loader .loader .box6 { animation-name: box-move6; }
.site-loader .loader .box6 div { animation-name: box-scale6; }
.site-loader .loader .box7 { animation-name: box-move7; }
.site-loader .loader .box7 div { animation-name: box-scale7; }
/* Every rule above sets animation-name/duration/timing/fill-mode as
   separate longhands, never the `animation` shorthand the original used
   (which included `infinite`) - animation-iteration-count is left
   unset, so it takes CSS's own default value of 1. That alone is what
   makes everything play exactly once instead of looping forever. */

@keyframes box-move0 {
  12% { transform: translate(var(--x), var(--y)); }
  25%, 52% { transform: translate(0, 0); }
  80% { transform: translate(0, -32px); }
  90%, 100% { transform: translate(0, 188px); }
}
@keyframes box-scale0 {
  6% { transform: rotateY(-47deg) rotateX(-15deg) rotate(15deg) scale(0); }
  14%, 100% { transform: rotateY(-47deg) rotateX(-15deg) rotate(15deg) scale(1); }
}
@keyframes box-move1 {
  16% { transform: translate(var(--x), var(--y)); }
  29%, 52% { transform: translate(0, 0); }
  80% { transform: translate(0, -32px); }
  90%, 100% { transform: translate(0, 188px); }
}
@keyframes box-scale1 {
  10% { transform: rotateY(-47deg) rotateX(-15deg) rotate(15deg) scale(0); }
  18%, 100% { transform: rotateY(-47deg) rotateX(-15deg) rotate(15deg) scale(1); }
}
@keyframes box-move2 {
  20% { transform: translate(var(--x), var(--y)); }
  33%, 52% { transform: translate(0, 0); }
  80% { transform: translate(0, -32px); }
  90%, 100% { transform: translate(0, 188px); }
}
@keyframes box-scale2 {
  14% { transform: rotateY(-47deg) rotateX(-15deg) rotate(15deg) scale(0); }
  22%, 100% { transform: rotateY(-47deg) rotateX(-15deg) rotate(15deg) scale(1); }
}
@keyframes box-move3 {
  24% { transform: translate(var(--x), var(--y)); }
  37%, 52% { transform: translate(0, 0); }
  80% { transform: translate(0, -32px); }
  90%, 100% { transform: translate(0, 188px); }
}
@keyframes box-scale3 {
  18% { transform: rotateY(-47deg) rotateX(-15deg) rotate(15deg) scale(0); }
  26%, 100% { transform: rotateY(-47deg) rotateX(-15deg) rotate(15deg) scale(1); }
}
@keyframes box-move4 {
  28% { transform: translate(var(--x), var(--y)); }
  41%, 52% { transform: translate(0, 0); }
  80% { transform: translate(0, -32px); }
  90%, 100% { transform: translate(0, 188px); }
}
@keyframes box-scale4 {
  22% { transform: rotateY(-47deg) rotateX(-15deg) rotate(15deg) scale(0); }
  30%, 100% { transform: rotateY(-47deg) rotateX(-15deg) rotate(15deg) scale(1); }
}
@keyframes box-move5 {
  32% { transform: translate(var(--x), var(--y)); }
  45%, 52% { transform: translate(0, 0); }
  80% { transform: translate(0, -32px); }
  90%, 100% { transform: translate(0, 188px); }
}
@keyframes box-scale5 {
  26% { transform: rotateY(-47deg) rotateX(-15deg) rotate(15deg) scale(0); }
  34%, 100% { transform: rotateY(-47deg) rotateX(-15deg) rotate(15deg) scale(1); }
}
@keyframes box-move6 {
  36% { transform: translate(var(--x), var(--y)); }
  49%, 52% { transform: translate(0, 0); }
  80% { transform: translate(0, -32px); }
  90%, 100% { transform: translate(0, 188px); }
}
@keyframes box-scale6 {
  30% { transform: rotateY(-47deg) rotateX(-15deg) rotate(15deg) scale(0); }
  38%, 100% { transform: rotateY(-47deg) rotateX(-15deg) rotate(15deg) scale(1); }
}
@keyframes box-move7 {
  40% { transform: translate(var(--x), var(--y)); }
  53%, 52% { transform: translate(0, 0); }
  80% { transform: translate(0, -32px); }
  90%, 100% { transform: translate(0, 188px); }
}
@keyframes box-scale7 {
  34% { transform: rotateY(-47deg) rotateX(-15deg) rotate(15deg) scale(0); }
  42%, 100% { transform: rotateY(-47deg) rotateX(-15deg) rotate(15deg) scale(1); }
}
@keyframes ground {
  0%, 65% { transform: rotateX(90deg) rotateY(0) translate(-48px, -120px) translateZ(100px) scale(0); }
  75%, 90% { transform: rotateX(90deg) rotateY(0) translate(-48px, -120px) translateZ(100px) scale(1); }
  100% { transform: rotateX(90deg) rotateY(0) translate(-48px, -120px) translateZ(100px) scale(0); }
}
@keyframes ground-shine {
  0%, 70% { opacity: 0; }
  75%, 87% { opacity: .2; }
  100% { opacity: 0; }
}
@keyframes mask {
  0%, 65% { opacity: 0; }
  66%, 100% { opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .site-loader .loader,
  .site-loader .loader *,
  .site-loader .loader *:before,
  .site-loader .loader *:after { animation: none; }
}

/* ---------- Full-screen menu (ported from 21st.dev hyperiux
   "immersive-full-screen-nav", demo config: #101014 panel, wipes from the
   left). Every size/duration/ease below is the component's own Tailwind
   value, measured off its live preview. Verion-specific changes only:
   logo instead of brand text, 5 links (so the link size is capped by
   screen height too), placeholder frames instead of photos, no location,
   and the logo/menu button flip black/white over light/dark backgrounds.
   Behaviour lives in main.js ("Full-screen menu"). ---------- */
.fsn-header {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 70;
  display: flex;
  /* top-aligned, not vertically centred in a fixed-height bar: that gave the
     logo a ~14px gap to the top edge against a ~37px gap to the left edge -
     an uneven "corner" (Nicky compared it to offmenu.design, whose logo and
     menu icon sit an equal distance from both edges). Padding-top now
     matches the side padding so both edges read the same. */
  align-items: flex-start;
  justify-content: space-between;
  padding: 32px 32px 0;
  pointer-events: none;
}
.fsn-header > * { pointer-events: auto; }
/* The logo is black artwork on a transparent PNG, so white is a pure
   filter flip - and deliberately no transition: it switches instantly. */
.fsn-logo.is-light { filter: brightness(0) invert(1); }

/* Groups the persistent "Book a Call" link with the menu toggle so they
   sit together on the right, both riding the SAME corner nudge the toggle
   used to carry alone (15px right, 15px up - past the header's own edge
   padding, landing level with the logo on the opposite corner). Moving the
   nudge here (instead of leaving it on .fsn-toggle) keeps the two new
   elements aligned with each other without needing a second nudge. */
.fsn-header-right {
  display: flex;
  align-items: center;
  gap: 16px; /* closer to the menu button so the two read as one group */
  position: relative;
  right: -12px; /* horizontal position kept 10px further in from the screen edge */
  top: -15px; /* buttons' tops line up with the logo's top edge: both corners get the same 17px margin */ /* was -15px: the logo grew to 62px, so this puts the button and dots on the logo's centre line */
  pointer-events: auto;
}
.fsn-toggle {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 42px; height: 42px; /* was 46px */
  padding: 0;
  background: none;
  border: 0;
  cursor: pointer;
}
@media (max-width: 1025px) { .fsn-toggle { width: 62px; height: 62px; } }
@media (max-width: 767px)  { .fsn-toggle { width: 46px; height: 46px; } }

/* Persistent header CTA - outlined, not filled: quiet next to the black
   dot-grid toggle, unlike the site's bold filled CTAs elsewhere (this is
   the one spot that should NOT compete for attention). Flips white/on-dark
   the same way the logo and toggle do, via .fsn-header.on-dark (see
   fsnUpdateTone in main.js - it already samples this same header region). */
.fsn-book-btn {
  display: inline-flex;
  align-items: center;
  height: 42px;
  padding: 0 20px;
  border: 1px solid rgba(20, 19, 17, .3);
  border-radius: 999px;
  font-family: var(--font-body);
  font-size: 13px;
  font-weight: 500;
  letter-spacing: .01em;
  color: var(--ink);
  text-decoration: none;
  white-space: nowrap;
  transition: background-color .25s var(--ease-out), color .25s var(--ease-out), border-color .25s var(--ease-out);
}
.fsn-book-btn:hover { background: var(--ink); color: #fff; border-color: var(--ink); }
.fsn-header.on-dark .fsn-book-btn { color: #fff; border-color: rgba(255, 255, 255, .35); }
.fsn-header.on-dark .fsn-book-btn:hover { background: #fff; color: var(--ink); border-color: #fff; }
/* Same "covered by the dark menu wipe" flip the toggle button already gets
   (fsnSetToggleCovered in main.js drives both together, so they flip at
   the same moment the wipe's edge reaches them). */
.fsn-book-btn.is-light { color: #fff; border-color: rgba(255, 255, 255, .35); }
.fsn-book-btn.is-light:hover { background: #fff; color: var(--ink); border-color: #fff; }
@media (max-width: 560px) { .fsn-book-btn { display: none; } }
/* ---------- Liquid glass "Book a Call" ----------
   Ported from the 21st.dev "liquid-glass-button" (Ali Imam): a bevelled edge drawn with stacked
   inset shadows (.lg-edge) over a glass layer (.lg-glass) whose backdrop is run through the
   component's own SVG filter (turbulence -> displacement -> blur, #container-glass in the page).
   Browsers that cannot run an SVG backdrop filter (Safari, Firefox) keep the plain blur
   declared first. The white tint is mine: the original is fully clear, this is a bit milkier.
   Same size as the button it replaces (42px tall, 13px text); light by default, switches to the
   component's dark-mode edge + white text over dark sections or under the open menu. */
.lg-defs { position: absolute; width: 0; height: 0; overflow: hidden; pointer-events: none; }
.fsn-book-btn.liquid-btn {
  height: 42px; /* same height as the menu button next to it */
  padding: 0 24px;
  font-size: 14px;
  position: relative;
  isolation: isolate;
  border: 0;
  background: transparent;
  color: var(--ink);
  transition: transform .3s ease, color .25s var(--ease-out);
}
.fsn-book-btn.liquid-btn:hover { background: transparent; border-color: transparent; color: var(--ink); transform: scale(1.05); }
.lg-label { position: relative; z-index: 2; pointer-events: none; }
.lg-edge {
  position: absolute;
  inset: 0;
  z-index: 1;
  border-radius: 999px;
  pointer-events: none;
  box-shadow:
    0 0 6px rgba(0,0,0,.03), 0 2px 6px rgba(0,0,0,.06),
    inset 3px 3px .5px -3px rgba(0,0,0,.42), inset -3px -3px .5px -3px rgba(0,0,0,.38),
    inset 1px 1px 1px -.5px rgba(0,0,0,.26), inset -1px -1px 1px -.5px rgba(0,0,0,.26),
    inset 0 0 6px 6px rgba(0,0,0,.05), inset 0 0 2px 2px rgba(0,0,0,.03),
    0 0 12px rgba(255,255,255,.15);
  transition: box-shadow .3s ease;
}
.lg-glass {
  position: absolute;
  inset: 0;
  z-index: 0;
  border-radius: 999px;
  overflow: hidden;
  pointer-events: none;
  background: rgba(255, 255, 255, .36);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  backdrop-filter: url("#container-glass");
  transition: background-color .3s ease;
}
.fsn-header.on-dark .fsn-book-btn.liquid-btn,
.fsn-book-btn.liquid-btn.is-light { color: #fff; border-color: transparent; }
.fsn-header.on-dark .fsn-book-btn.liquid-btn:hover,
.fsn-book-btn.liquid-btn.is-light:hover { background: transparent; border-color: transparent; color: #fff; }
.fsn-header.on-dark .liquid-btn .lg-edge,
.liquid-btn.is-light .lg-edge {
  box-shadow:
    0 0 8px rgba(0,0,0,.03), 0 2px 6px rgba(0,0,0,.08),
    inset 3px 3px .5px -3.5px rgba(255,255,255,.09), inset -3px -3px .5px -3.5px rgba(255,255,255,.5),
    inset 1px 1px 1px -.5px rgba(255,255,255,.34), inset -1px -1px 1px -.5px rgba(255,255,255,.34),
    inset 0 0 6px 6px rgba(255,255,255,.12), inset 0 0 2px 2px rgba(255,255,255,.06),
    0 0 12px rgba(0,0,0,.15);
}
.fsn-header.on-dark .liquid-btn .lg-glass,
.liquid-btn.is-light .lg-glass { background: rgba(255, 255, 255, .12); }
@media (max-width: 560px) { .fsn-book-btn.liquid-btn { display: none; } }

/* Menu button - ported from 21st.dev "loading-state" (@theshanelevine), its
   top "Drive" variant only (the label + elapsed-timer parts, and the Dots/
   Orbit variants, are dropped - Nicky only wanted the 3x3 square grid).
   Replaces the old burger/X: this never changes shape, it just always
   churns, so the button reads as "click to load the menu" rather than
   "click to close an X". Cell size/gap raised from the component's 4px/
   1.5px (Nicky asked twice: bumped again to 7px/5px), and the cycle
   slowed from the component's 650ms down to 1800ms (Nicky: "too fast...
   very slow... smooth elegant, should not catch the user's attention") -
   the original delays (0/90/180/270ms, a chevron wavefront driving
   left-to-right) are scaled by the same ratio each time so the wave shape
   is unchanged, just slower. */
.fsn-load-grid {
  display: grid;
  grid-template-columns: repeat(3, 7px);
  gap: 4.5px;
}
.fsn-load-cell {
  display: block;
  width: 7px;
  height: 7px;
  border-radius: 50%; /* was 1px (squares) - now circles, Nicky's own ask;
     stays crisp at 7px, no pixelation from the shape change itself */
  background: #000;
  opacity: .15;
  animation: fsn-load-pulse 3400ms ease-in-out infinite; /* was 1800ms, then 2600ms - slower again */
}
/* Over a dark section on the PAGE: white, instantly - no transition, so a
   fast scroll never leaves it lagging half-flipped. */
.fsn-header.on-dark .fsn-load-cell { background: #fff; }
/* Synced to the menu's own wipe reaching the button (fsnSetToggleCovered in
   main.js), not to .is-open/.is-closing directly - it used to snap white
   the instant the panel started opening, well before the wipe had visibly
   reached it. This one DOES get a transition (below), so the swap reads as
   a quick, deliberate fade timed to the wipe, not a hard cut. */
.fsn-toggle.is-light .fsn-load-cell {
  background: #fff;
  transition: background-color .3s ease-out;
}
/* No hover recolour on this button (tried the brand purple, Nicky backed
   it out - "don't need to change the colour, just don't make it purple").
   It's not real text/graphic content, just decorative squares, so it isn't
   suitable for the flip-to-opposite treatment either - the on-dark/is-open
   rules above already give it the right colour for wherever it sits, and
   the cursor circle's own hover-grow (magnetic-cursor.js) is its only
   hover feedback, same as every other icon-only button on the site. */
@keyframes fsn-load-pulse {
  0%, 100% { opacity: .15; }
  50% { opacity: 1; }
}

.fsn-overlay {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  overflow-y: auto;
  background: #101014;
  clip-path: polygon(0% 0%, 0% 0%, 0% 100%, 0% 100%);
  pointer-events: none;
}
.fsn.is-open .fsn-overlay { pointer-events: auto; }
.fsn.is-open .fsn-overlay, .fsn.is-closing .fsn-overlay { will-change: clip-path; }
.fsn-wrap {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 100vw;
  min-height: 100vh;
}
.fsn-panel {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 32px;
  width: 100%;
  min-height: 100vh;
  padding: 96px 88px 28px; /* component: 112px 112px 40px - links sit higher, contact row lower, slimmer side margins so links + frames can both be bigger */
  /* frame width: 25.2vw (component: 25vw), shrinking on narrower desktops
     so the frames can never run into the longest link at its biggest size */
  --fsn-frame-w: calc(min(25.2vw, calc(32.5vw - 126px)) + 5px);
  position: relative; /* anchors the bottom-right caption */
  background: #101014;
  color: #fff;
  font-family: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
  font-weight: 400;
  line-height: 1.5;
  letter-spacing: normal;
  text-align: left;
}
.fsn-mid {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px; /* component: 40px - narrowed so the longest link still fits beside the bigger frames */
}
.fsn-links { display: flex; flex-direction: column; gap: 0; position: relative; top: -5px; }
.fsn-link + .fsn-link { margin-top: .14em; } /* extra breathing room between the five */
/* Component: 6vw at line-height 1.5. Verion: the rows are tightened to
   1.2 and the size is capped by what's left of the screen height once the
   header space (96px) and the one-line contact row below are taken out - so the
   five links are as big as the screen allows without the panel scrolling. */
.fsn-link { font-size: min(7.1vw, calc((100vh - 188px) / 6.7)); line-height: 1.2; white-space: nowrap; }
.fsn-link a { display: inline-block; color: inherit; text-decoration: none; font-weight: 400; }
/* top-aligned so each row is exactly its 1.2 line-height (middle alignment
   padded every row out to ~1.3 and pushed the panel past the screen) */
.fsn-link a, .fsn-link .fsn-chars { vertical-align: top; }
.fsn-sr {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}
.fsn-chars {
  position: relative;
  display: inline-block;
  overflow: hidden;
  vertical-align: middle;
  line-height: 1.08;
}
.fsn-chars > span {
  position: relative;
  display: inline-block;
  white-space: pre;
  text-shadow: 0 1.2em currentColor;
  transition: transform .5s cubic-bezier(.625,.05,0,1);
}
.fsn-link a:hover .fsn-chars > span,
.fsn-link a:focus-visible .fsn-chars > span { transform: translateY(-1.2em); }

.fsn-media {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  justify-content: center;
  height: 100%;
  padding: 20px 0;
}
.fsn-frames { display: flex; align-items: flex-end; gap: 32px; margin-right: 10px; }
.fsn-frame {
  position: relative;
  width: var(--fsn-frame-w);
  aspect-ratio: 25 / 18; /* the component's frame shape */
  overflow: hidden;
  border-radius: 14px;
}
/* Placeholder picture: same frame, same hover zoom as the component's photos. */
.fsn-frame-fill {
  position: absolute;
  inset: 0;
  background: #1d1d23;
  transition: transform .5s cubic-bezier(.4,0,.2,1);
}
.fsn-frame-fill:hover { transform: scale(1.05); }

.fsn-bottom { display: flex; align-items: center; justify-content: space-between; }
.fsn-contact { display: flex; align-items: center; }

/* Bottom-right contact block: two columns (tagline / contact) split by a
   vertical divider, matching the reference layout Nicky picked. */
.fsn-caption { display: flex; align-items: center; position: relative; top: -40px; }
.fsn-caption-col {}
.fsn-caption-divider {
  width: 1px;
  height: 40px;
  margin: 0 28px;
  background: rgba(255,255,255,.16);
  flex-shrink: 0;
}
.fsn-eyebrow {
  margin: 0 0 8px;
  font-size: 11px;
  line-height: 16px;
  font-weight: 500;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: rgba(255,255,255,.4);
}
.fsn-tagline { margin: 0; font-size: 16px; line-height: 24px; color: rgba(255,255,255,.6); }
.fsn-tag-strong { color: #fff; font-weight: 500; }
.fsn-label {
  margin: 0 0 8px;
  font-size: 11px;
  line-height: 16px;
  font-weight: 500;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: rgba(255,255,255,.4);
}
.fsn-email {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  font-size: 16px;
  line-height: 24px;
  color: #fff;
  text-decoration: none;
}
.fsn-email-arrow {
  width: 20px;
  height: 20px;
  flex-shrink: 0;
  transition: transform .3s var(--ease-out);
}
.fsn-email:hover .fsn-email-arrow,
.fsn-email:focus-visible .fsn-email-arrow { transform: translateX(4px); }
.fsn-socials { display: flex; align-items: center; gap: 22px; margin-left: 5px; }
.fsn-socials a { display: block; color: #fff; }
.fsn-socials svg { display: block; width: 28px; height: 28px; }

@media (max-width: 1025px) {
  /* 120px top (component: 80px): the tagline no longer sits up here, so
     the links get breathing room under the header instead */
  .fsn-panel { padding: 120px 24px 80px; }
  .fsn-mid { flex-direction: column; align-items: flex-start; gap: 72px; }
  .fsn-link { font-size: 7vw; }
  .fsn-media { width: 100%; align-items: flex-start; gap: 24px; padding: 0; }
  .fsn-frames { width: 100%; flex-direction: column; align-items: flex-start; gap: 12px; }
  .fsn-frame { width: 60vw; height: 30vw; aspect-ratio: auto; border-radius: 8px; }
  .fsn-frames { margin-right: 0; }
  .fsn-links { top: 0; }
  .fsn-bottom { flex-direction: column; align-items: flex-start; gap: 32px; padding-bottom: 40px; }
  .fsn-socials { gap: 24px; margin-left: 0; }
  .fsn-socials svg { width: 32px; height: 32px; }
}
@media (max-width: 767px) {
  .fsn-socials svg { width: 24px; height: 24px; }
}
@media (max-width: 560px) {
  .fsn-caption { flex-direction: column; align-items: flex-start; gap: 18px; }
  .fsn-caption-divider { width: 32px; height: 1px; margin: 0; }
  .fsn-tag-line { display: block; }
}

@media (prefers-reduced-motion: reduce) {
  /* freezes on its dim state, per the component's own reduced-motion spec */
  .fsn-load-cell { animation: none; opacity: .15; }
  .fsn-frame-fill, .fsn-frame-fill:hover { transition: none; transform: none; }
}
/* While the menu is open (or wiping away) the chat dock sits UNDER the
   panel instead of floating on top of it; the closing wipe uncovers it. */
html.fsn-open .vc-root { z-index: 55; }
.nav {
  pointer-events: auto;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 3px 8px 3px 22px;
  background: rgba(255,255,255,.82);
  backdrop-filter: blur(20px) saturate(1.4);
  -webkit-backdrop-filter: blur(20px) saturate(1.4);
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  box-shadow: 0 1px 2px rgba(20,19,17,.04), 0 10px 30px rgba(20,19,17,.07);
  transition: box-shadow .3s var(--ease-out), background-color .3s var(--ease-out);
}
.nav.scrolled {
  background: rgba(255,255,255,.92);
  box-shadow: 0 1px 3px rgba(20,19,17,.06), 0 16px 40px rgba(20,19,17,.1);
}

/* Icon-mark only, no wordmark (Nicky, 2026-09-24 - inspired by offmenu.design's
   bold icon-only "O/M" mark): cropped straight from the source hexagon
   (pixel bounds measured directly: x 177-531, y 224-530 of the 1827x752
   file), scaled up and shown alone. Sized bigger than the old 32px-tall
   combined lockup - 44px tall now - so it carries the brand on its own
   the way a wordmark used to help do. */
.nav-logo {
  display: block;
  width: 70.8px; height: 62.4px; /* 59x52 x1.2 - a tad bigger again */
  background: url('../images/verion-logo.png') no-repeat -25.68px -33.72px;
  background-size: 314.28px 129.36px;
  image-rendering: auto;
  position: relative; top: -15px; left: -15px; /* midpoint between -10 (too far from the corner) and -20 (too close) */
}
.nav-logo-img { display: none; }

.nav-links {
  display: flex;
  align-items: center;
  gap: 2px;
  list-style: none;
  margin-left: 24px;
  margin-right: 14px;
}
.nav-links a {
  display: block;
  padding: 8px 14px;
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--muted);
  border-radius: var(--r-pill);
  transition: color .2s, background-color .2s;
}
.nav-links a:hover { color: var(--ink); background: rgba(20,19,17,.05); }
.nav-links a.active { color: var(--ink); background: rgba(20,19,17,.06); font-weight: 600; }

/* ---------- Hero ---------- */
.hero {
  position: relative;
  padding: 208px 0 140px;
  overflow: hidden;
}
.hero-bg {
  position: absolute; inset: 0;
  background:
    radial-gradient(52% 46% at 78% 30%, rgba(20,19,17,.13) 0%, transparent 100%),
    radial-gradient(40% 38% at 12% 82%, rgba(20,19,17,.08) 0%, transparent 100%);
  pointer-events: none;
}
.hero-grid {
  position: relative;
  display: grid;
  grid-template-columns: 1.05fr 1fr;
  gap: 48px;
  align-items: center;
}
.hero-copy h1 { margin: 0 0 26px; }
.hero-copy .lede {
  font-size: 1.1875rem;
  color: var(--muted);
  max-width: 500px;
  margin-bottom: 40px;
}
.hero-ctas { display: flex; align-items: center; gap: 16px; margin-bottom: 52px; }

.hero-centered { padding: 200px 0 140px; }
.hero-centered .hero-copy .eyebrow { justify-content: center; }
.hero-h1-sm { font-size: clamp(2.25rem, 4vw, 3.25rem) !important; line-height: 1.18 !important; }

/* ---------- Editorial hero (luxury studio) ---------- */
.hero-editorial {
  position: relative;
  min-height: 84vh;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 140px 24px 90px;
  overflow: hidden;
}
.hero-editorial .hero-inner {
  position: relative;
  z-index: 2;
  max-width: 720px;
}
.hero-badge {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 0.78125rem;
  font-weight: 500;
  color: var(--ink-soft);
  background: rgba(255,255,255,.8);
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  padding: 6px 15px;
  box-shadow: 0 1px 2px rgba(20,19,17,.04);
}
.hero-badge .dot {
  width: 6px; height: 6px;
  border-radius: 50%;
  background: #23A35B;
  box-shadow: 0 0 0 3px rgba(35,163,91,.18);
}
.hero-editorial h1 {
  font-size: clamp(2.5rem, 5.4vw, 4.75rem);
  line-height: 1.04;
  font-weight: 500;
  letter-spacing: -0.035em;
  margin: 24px 0 20px;
  color: var(--ink);
}
.hero-editorial h1 .accent-serif {
  letter-spacing: -0.01em;
}
.hero-editorial .hero-sub {
  font-size: 1.0625rem;
  line-height: 1.6;
  color: var(--muted);
  max-width: 500px;
  margin: 0 auto 34px;
}
.hero-editorial .hero-ctas {
  justify-content: center;
  margin: 0;
}

/* Floating premium objects */
.hero-objects {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 1;
}
.h-obj {
  position: absolute;
  animation: objFloat var(--dur, 9s) ease-in-out var(--del, 0s) infinite;
}
.h-obj svg { display: block; width: 100%; height: auto; }
@keyframes objFloat {
  0%, 100% { transform: translateY(0) rotate(var(--rot, 0deg)); }
  50% { transform: translateY(-16px) rotate(calc(var(--rot, 0deg) + 2.5deg)); }
}
.h-obj-1 { top: 14%; left: 7%; width: 150px; --rot: -8deg; --dur: 10s; }
.h-obj-2 { top: 9%; right: 9%; width: 130px; --rot: 12deg; --dur: 11.5s; --del: -3s; }
.h-obj-3 { bottom: 16%; left: 12%; width: 110px; --rot: 6deg; --dur: 9.5s; --del: -5s; }
.h-obj-4 { bottom: 20%; right: 8%; width: 140px; --rot: -10deg; --dur: 12s; --del: -7s; }
.h-obj-5 { top: 46%; left: 2.5%; width: 64px; --rot: 0deg; --dur: 8s; --del: -2s; }
.h-obj-6 { top: 52%; right: 3%; width: 56px; --rot: 0deg; --dur: 8.8s; --del: -4.5s; }

@media (prefers-reduced-motion: reduce) {
  .h-obj { animation: none; }
}
@media (max-width: 900px) {
  .h-obj-1 { width: 90px; top: 11%; left: 4%; }
  .h-obj-2 { width: 84px; right: 5%; }
  .h-obj-4 { width: 76px; bottom: 5%; right: 3%; }
  .h-obj-3, .h-obj-5, .h-obj-6 { display: none; }
  .hero-editorial { min-height: 84vh; padding-top: 150px; }
}

/* ---------- Phone split section ---------- */
.phone-split {
  display: grid;
  /* text column is widened - the empty half will hold a video later, and the
     text needs room to breathe on 2 lines rather than being squeezed to 3-4. */
  grid-template-columns: 1.25fr 1fr;
  gap: 80px;
  align-items: center;
}
.phone-split-text { max-width: 720px; }
.phone-split-text p {
  font-size: 1.125rem;
  line-height: 1.7;
  color: var(--muted);
  margin-bottom: 14px;
}
.phone-split-text p strong { color: var(--ink); }
.phone-split-text h2 { margin-bottom: 28px; }
.phone-hero-h2 {
  /* larger by design - it is the section headline, sits on 2 lines with the
     widened column so this size never wraps into a wall of text. */
  font-size: clamp(2.2rem, 3.8vw, 3.4rem);
  line-height: 1.1;
  font-weight: 500;
  letter-spacing: -0.028em;
  margin-bottom: 28px;
}
.phone-split-text .phone-hero-h2 { margin-bottom: 28px; }
.phone-features {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 18px 44px;
  margin: 28px 0 36px;
}
.phone-feat {
  display: flex;
  align-items: center;
  gap: 14px;
}
.phone-feat-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: 12px;
  background: var(--bg-soft);
  flex-shrink: 0;
}
.phone-feat-icon svg {
  width: 22px;
  height: 22px;
  color: var(--ink-soft);
}
.phone-feat-label {
  font-size: 0.9375rem;
  font-weight: 500;
  color: var(--ink);
}
.phone-callouts {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 16px;
  margin-top: 28px;
}
.phone-callout {
  font-family: var(--font-mono);
  font-size: 0.8125rem;
  font-weight: 500;
  color: var(--brand);
  letter-spacing: 0.01em;
}

/* ---------- Phone mockup ---------- */
.phone-mockup {
  width: 320px;
  margin: 0 auto;
  background: var(--ink);
  border-radius: 40px;
  padding: 12px;
  box-shadow: 0 24px 80px rgba(22,20,46,.18), 0 4px 16px rgba(22,20,46,.08);
}
.phone-screen {
  background: #fff;
  border-radius: 30px;
  overflow: hidden;
  min-height: 560px;
}
.phone-status-bar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 14px 24px 8px;
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--ink);
}
.phone-notch {
  width: 80px;
  height: 26px;
  background: var(--ink);
  border-radius: 20px;
}
.phone-signal svg { width: 18px; height: 18px; }
.phone-conversation {
  padding: 16px 16px 24px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.phone-bubble {
  padding: 12px 16px;
  border-radius: 18px;
  font-size: 0.8125rem;
  line-height: 1.5;
  max-width: 88%;
  opacity: 0;
  transform: translateY(12px);
  animation: phoneBubbleIn .5s ease forwards;
}
.phone-label {
  display: block;
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin-bottom: 4px;
}
.phone-incoming {
  background: var(--bg-soft);
  color: var(--ink);
  align-self: flex-start;
  border-bottom-left-radius: 6px;
}
.phone-incoming .phone-label { color: var(--muted); }
.phone-ai {
  background: var(--brand);
  color: #fff;
  align-self: flex-end;
  border-bottom-right-radius: 6px;
}
.phone-ai .phone-label { color: rgba(255,255,255,.7); }
.phone-anim-1 { animation-delay: .3s; }
.phone-anim-2 { animation-delay: 1s; }
.phone-anim-3 { animation-delay: 2.2s; }
.phone-anim-4 { animation-delay: 3.2s; }
.phone-anim-5 { animation-delay: 4.4s; }
.phone-anim-6 { animation-delay: 5.4s; }
@keyframes phoneBubbleIn {
  to { opacity: 1; transform: translateY(0); }
}

/* ---------- Laptop split section ---------- */
.laptop-split {
  display: grid;
  /* visual left, text right - text column widened so a 2-line heading fits
     without dropping to 3+ lines. */
  grid-template-columns: 1fr 1.25fr;
  gap: 80px;
  align-items: center;
}
.laptop-split-text { max-width: 720px; }
.laptop-split-text p {
  font-size: 1.125rem;
  line-height: 1.7;
  color: var(--muted);
  margin-bottom: 14px;
}
.laptop-split-text p strong { color: var(--ink); }
.laptop-split-text h2 { margin-bottom: 28px; }

/* ---------- Automation pillars (4-col icon + label) ----------
   All four items share one structure: left-aligned, equal gap, no
   dividers — so the row reads as a clean set and lines up with the
   paragraph above it. */
.auto-pillars {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 28px;
  margin: 32px 0;
}
.auto-pillar {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  text-align: left;
  gap: 12px;
}
.auto-pillar-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: 12px;
  background: var(--bg-soft);
}
.auto-pillar-icon svg {
  width: 22px;
  height: 22px;
  color: var(--ink-soft);
}
.auto-pillar-label {
  font-size: 0.875rem;
  font-weight: 500;
  line-height: 1.35;
  color: var(--ink);
}
/* ---------- Check list ---------- */
.auto-checks {
  list-style: none;
  padding: 0;
  margin: 0 0 40px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.auto-checks li {
  display: flex;
  align-items: center;
  gap: 12px;
  font-size: 0.9375rem;
  color: var(--ink-soft);
}
.auto-checks svg {
  width: 22px;
  height: 22px;
  flex-shrink: 0;
  color: var(--muted);
}

/* ---------- Laptop mockup ---------- */
.laptop-mockup { perspective: 1200px; }
.laptop-lid {
  background: #1a1a2e;
  border-radius: 12px 12px 0 0;
  padding: 8px 8px 0;
  transform-origin: bottom center;
  transform: rotateX(6deg);
  transition: transform .8s cubic-bezier(.22,1,.36,1);
}
.laptop-mockup.is-open .laptop-lid { transform: rotateX(0deg); }
.laptop-screen {
  background: #fff;
  border-radius: 6px 6px 0 0;
  overflow: hidden;
  aspect-ratio: 16 / 10;
}
.laptop-base {
  height: 14px;
  background: linear-gradient(180deg, #d0d0d8, #bbbbc4);
  border-radius: 0 0 8px 8px;
  position: relative;
}
.laptop-base::before {
  content: '';
  position: absolute;
  top: 0; left: 50%;
  transform: translateX(-50%);
  width: 80px;
  height: 4px;
  background: #a8a8b4;
  border-radius: 0 0 4px 4px;
}

/* ---------- Dashboard UI ---------- */
.dash {
  display: flex;
  height: 100%;
  font-size: 9px;
  font-family: var(--font-body);
  color: var(--ink);
}
.dash-sidebar {
  width: 30%;
  background: #F8F8FC;
  border-right: 1px solid var(--line);
  padding: 10px 8px;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.dash-logo {
  display: flex;
  align-items: center;
  gap: 5px;
  font-weight: 700;
  font-size: 10px;
  margin-bottom: 10px;
  padding: 2px;
}
.dash-logo svg { width: 18px; height: 18px; flex-shrink: 0; }
.dash-nav-item {
  display: flex;
  align-items: center;
  gap: 5px;
  padding: 5px 6px;
  border-radius: 6px;
  font-size: 8.5px;
  font-weight: 500;
  color: var(--muted);
  cursor: default;
}
.dash-nav-item svg { width: 13px; height: 13px; flex-shrink: 0; }
.dash-nav-item.active {
  background: var(--brand);
  color: #fff;
}
.dash-nav-item.active svg { stroke: #fff; }

.dash-main {
  flex: 1;
  padding: 10px 12px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  overflow: hidden;
}
.dash-header {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
}
.dash-greeting {
  font-weight: 700;
  font-size: 11px;
  color: var(--ink);
}
.dash-date {
  font-size: 8px;
  color: var(--muted);
  font-family: var(--font-mono);
}

.dash-stats {
  display: flex;
  gap: 6px;
}
.dash-stat {
  flex: 1;
  background: #F8F8FC;
  border-radius: 8px;
  padding: 8px;
  text-align: center;
  opacity: 0;
  transform: translateY(6px);
  transition: opacity .5s ease, transform .5s ease;
}
.dash-stat-num {
  display: block;
  font-size: 16px;
  font-weight: 700;
  color: var(--brand);
  line-height: 1.2;
}
.dash-stat-label {
  font-size: 7px;
  color: var(--muted);
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.dash-leads {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.dash-lead {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 6px 8px;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 8px;
  opacity: 0;
  transform: translateX(-8px);
  transition: opacity .45s ease, transform .45s ease;
}
.dash-lead-avatar {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  font-size: 9px;
  color: var(--ink);
  flex-shrink: 0;
}
.dash-lead-info {
  flex: 1;
  min-width: 0;
}
.dash-lead-info strong {
  display: block;
  font-size: 8.5px;
  font-weight: 600;
}
.dash-lead-info span {
  font-size: 7.5px;
  color: var(--muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  display: block;
}
.dash-tag {
  font-size: 6.5px;
  font-weight: 600;
  padding: 2px 6px;
  border-radius: 10px;
  white-space: nowrap;
  text-transform: uppercase;
  letter-spacing: 0.03em;
}
.dash-tag-new { background: #E6E6E4; color: var(--brand); }
.dash-tag-booked { background: #D4F5E9; color: #1a7a4c; }
.dash-tag-follow { background: #FFF0D4; color: #9a6c00; }

.dash-ai-note {
  display: flex;
  gap: 6px;
  align-items: flex-start;
  padding: 8px;
  background: #F0EEFF;
  border-radius: 8px;
  border-left: 3px solid var(--brand);
  opacity: 0;
  transform: translateY(6px);
  transition: opacity .5s ease, transform .5s ease;
}
.dash-ai-note svg { width: 14px; height: 14px; flex-shrink: 0; margin-top: 1px; }
.dash-ai-note strong {
  display: block;
  font-size: 8px;
  font-weight: 700;
  color: var(--brand);
  margin-bottom: 1px;
}
.dash-ai-note span { font-size: 7.5px; color: var(--muted); line-height: 1.4; }

/* Dashboard scroll-triggered animation states */
.laptop-mockup.is-open .dash-stat,
.laptop-mockup.is-open .dash-lead,
.laptop-mockup.is-open .dash-ai-note {
  opacity: 1;
  transform: translate(0);
}
.laptop-mockup.is-open .dash-anim-1 { transition-delay: .3s; }
.laptop-mockup.is-open .dash-anim-2 { transition-delay: .45s; }
.laptop-mockup.is-open .dash-anim-3 { transition-delay: .6s; }
.laptop-mockup.is-open .dash-anim-4 { transition-delay: .8s; }
.laptop-mockup.is-open .dash-anim-5 { transition-delay: 1s; }
.laptop-mockup.is-open .dash-anim-6 { transition-delay: 1.2s; }
.laptop-mockup.is-open .dash-anim-7 { transition-delay: 1.4s; }
.laptop-mockup.is-open .dash-anim-8 { transition-delay: 1.7s; }

/* ---------- Laptop split reverse (text left, laptop right) ---------- */
.laptop-split-reverse {
  /* HTML places text first, visual second - we want text on the LEFT and it
     stays the wider column, so columns swap to 1.25fr : 1fr. */
  grid-template-columns: 1.25fr 1fr;
}
.laptop-split-reverse .laptop-split-text { order: 0; }

/* ---------- Timeline UI (laptop #2) ---------- */
.dash-timeline {
  display: flex;
  flex-direction: column;
  gap: 0;
  position: relative;
  padding-left: 14px;
}
.dash-timeline::before {
  content: '';
  position: absolute;
  left: 4px;
  top: 4px;
  bottom: 4px;
  width: 1.5px;
  background: var(--line);
}
.tl-item {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  padding: 6px 0;
  position: relative;
  opacity: 0;
  transform: translateY(6px);
  transition: opacity .45s ease, transform .45s ease;
}
.tl-dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  flex-shrink: 0;
  margin-top: 2px;
  margin-left: -14px;
  position: relative;
  z-index: 1;
  background: var(--line);
  transition: background .4s ease;
}
.laptop-mockup-2.is-open .tl-dot.tl-done { background: #1a7a4c; }
.tl-content { flex: 1; min-width: 0; }
.tl-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 6px;
}
.tl-row strong {
  font-size: 8px;
  font-weight: 600;
  color: var(--ink);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.tl-meta {
  font-size: 7px;
  color: var(--muted);
  display: block;
  margin-top: 1px;
}

.dash-auto-summary {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 7px 10px;
  background: #D4F5E9;
  border-radius: 8px;
  margin-top: 4px;
  opacity: 0;
  transform: translateY(6px);
  transition: opacity .5s ease, transform .5s ease;
}
.dash-auto-summary svg { width: 13px; height: 13px; flex-shrink: 0; }
.dash-auto-summary span { font-size: 7.5px; color: #1a7a4c; }
.dash-auto-summary strong { font-weight: 700; }

/* Laptop #2 scroll-triggered animations */
.laptop-mockup-2.is-open .tl-item,
.laptop-mockup-2.is-open .dash-auto-summary {
  opacity: 1;
  transform: translateY(0);
}
.laptop-mockup-2.is-open .tl-anim-1 { transition-delay: .4s; }
.laptop-mockup-2.is-open .tl-anim-2 { transition-delay: .7s; }
.laptop-mockup-2.is-open .tl-anim-3 { transition-delay: 1s; }
.laptop-mockup-2.is-open .tl-anim-4 { transition-delay: 1.3s; }
.laptop-mockup-2.is-open .tl-anim-5 { transition-delay: 1.6s; }
.laptop-mockup-2.is-open .tl-anim-6 { transition-delay: 2s; }

/* ============================================================
   How It Works — "GrainientImagesSection" (ported from a 21st.dev/
   design-layer React+framer-motion component; see hiwGrainientInit()
   in main.js for the scroll-progress math this drives).

   A ~220vh pinned track: the `.grainient-images-stage` sticks for one
   viewport while you scroll through it. First 70vh: the 13 tiles fly
   toward the camera (translateZ) and fade out over the last 30% of that
   phase (shortened twice 2026-09-12: 150vh -> 90vh -> 70vh - each pass
   still took too much scroll to complete). Last 50vh: a centred title
   scales + fades in.

   Colour: switched from the reference's own black-bg/off-white-text to
   the site's normal cream bg + ink text, and NO background of its own
   (transparent) — same as every other [data-dotfield] section — so the
   fixed .dotfield canvas shows through and this reads as part of the
   page rather than a black box dropped into it. Tiles are plain
   placeholder boxes for now (no real photos yet). */
.grainient-images-section {
  position: relative;
  width: 100%;
  color: var(--ink);
  overflow: clip;
}
/* The sticky stage's containing block: exactly the stage (100vh) + the
   two spacer divs (70vh + 50vh) = 220vh, nothing more. Without this
   wrapper the stage and spacers were direct children of the same
   section as the 3 later text-parallax panels, so the stage's "sticky"
   range and the JS scroll-progress math (which measures this element,
   see hiwGrainientInit() in main.js) both stretched across the WHOLE
   section instead of stopping after 220vh — tiles stayed pinned far
   too long and the title only resolved near the very end. */
.grainient-images-track {
  position: relative;
  width: 100%;
}
.grainient-images-stage {
  height: 100vh;
  width: 100%;
  position: sticky;
  top: 0;
  z-index: 1;
  overflow: visible;
  perspective: 1200px;
}
.grainient-images-zoom {
  position: absolute;
  inset: 0;
  transform-origin: 50% 50%;
  transform-style: preserve-3d;
  will-change: transform;
}
/* The 4 words of "BUILT AROUND YOUR BUSINESS" - real text overlaid on
   the 7 tiles above, positioned to match the user's own reference
   collage (see the HTML comment above .gis-collage-text). Switzer 700
   (already loaded site-wide), dark ink to match this section's cream
   background - same treatment as everything else under this
   [data-dotfield] section, just pushed to its boldest weight for one
   high-impact moment.
   --rx/--ry/--tz are written every frame by hiwGrainientInit() in
   main.js: --rx/--ry push the word outward from the stage's centre (the
   same "radiate outward" burst the 7 tiles get, not just straight at
   the camera) and --tz is a REAL translateZ zoom - the same 3D push the
   tiles use - so the text travels the same kind of distance as the
   tiles instead of a flatter CSS scale(). */
.gis-collage-text {
  position: absolute;
  color: var(--ink);
  font-family: var(--font-display);
  font-weight: 700;
  line-height: 0.88;
  letter-spacing: -0.02em;
  text-shadow: 0 6px 18px rgba(20, 19, 17, 0.16);
  text-transform: uppercase;
  white-space: nowrap;
  pointer-events: none;
  transform-style: preserve-3d;
  /* --ex/--ey/--erot: per-word fine-tune offsets set inline in the HTML,
     layered underneath the JS-driven radiate/zoom vars - lets each word
     get its own hand-placed nudge without fighting the animation.
     Defaults are no-ops for words/vars that don't set them. */
  transform: translate(calc(var(--ex, 0px) + var(--rx, 0px)), calc(var(--ey, 0px) + var(--ry, 0px))) rotate(var(--erot, 0deg)) translateZ(var(--tz, 0px));
}
.gis-collage-text--rotated {
  transform-origin: left top;
  transform: rotate(-90deg) translateY(-100%) translate(calc(var(--ex, 0px) + var(--rx, 0px)), calc(var(--ey, 0px) + var(--ry, 0px))) rotate(var(--erot, 0deg)) translateZ(var(--tz, 0px));
}
.grainient-images-title {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 100%;
  max-width: 820px;
  text-align: center;
  font-family: var(--font-display);
  color: var(--ink);
  pointer-events: none;
  opacity: 0;
  transform: translate(-50%, -50%) scale(0.5);
  will-change: transform, opacity;
}
/* Two-tier hierarchy (2026-09-12): was one uniform line of text for both
   the headline and the supporting sentence - reads as a label, not a
   statement. The headline now carries the weight, the supporting line
   sits clearly beneath it as a secondary, quieter thought. */
.grainient-images-title .gis-title-main {
  display: block;
  font-size: clamp(36px, 5.1vw, 74px);
  font-weight: 600;
  letter-spacing: -0.025em;
  line-height: 1.04;
  text-wrap: balance;
}
.grainient-images-title .gis-title-main .accent-serif { font-weight: 400; letter-spacing: -0.01em; }
/* the supporting lines inherit the headline's tight tracking from the h2, which crushed the letters
   together; reset it so the words breathe */
.grainient-images-title .gis-title-main { margin-bottom: clamp(12px, 1.3vw, 18px); }
.grainient-images-title .gis-title-sub {
  display: block;
  font-size: clamp(16px, 1.4vw, 21px);
  font-weight: 400;
  letter-spacing: 0;
  word-spacing: 0;
  line-height: 1.55;
  color: var(--ink-soft);
  text-wrap: balance;
}
.grainient-images-tile-wrap {
  position: absolute;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  overflow: visible;
  transform-style: preserve-3d;
  transform: translate(-50%, -50%);
  will-change: transform;
}
.grainient-images-tile-wrap--y-only {
  transform: translateY(-50%);
}
.grainient-images-tile {
  width: 100%;
  position: relative;
  border: 0;
  border-radius: 5px;
  box-shadow: 0 1px 2px rgba(20, 19, 17, 0.18), 0 10px 22px -8px rgba(20, 19, 17, 0.32), 0 26px 44px -22px rgba(20, 19, 17, 0.38);
  overflow: visible;
  /* Solid black fill - stands in for a real photo so the composition
     can be previewed with something opaque in each frame, instead of
     the clear/transparent placeholder look. */
  background: #14130f;
}

/* ============================================================
   How It Works — "TextParallaxContentScroll" (21st.dev component,
   ported 1:1 to plain HTML/CSS/JS; see hiwParallaxInit() in main.js).
   3 panels, each: a sticky image (150vh scroll stage — the image
   shrinks + darkens as you scroll through it) with a centred
   subheading/heading that drifts and fades over it, then a two-column
   content block below. Continues straight out of the tile-zoom above,
   same #how-it-works section, same page background either side.
   Stage height went 150vh -> 200vh -> back to 150vh (2026-09-12): the
   200vh bump was to buy scroll DISTANCE for a hard freeze-hold, which
   has since been replaced with a stateless wheel-damping slow-down (see
   hiwParallaxInit in main.js) that doesn't need the extra room - and
   the taller stage was itself making the section feel like it demanded
   too much scrolling. ============================================================ */
.tpc-panel { padding: 0 12px; }
.tpc-stage { position: relative; height: 150vh; }
.tpc-sticky-image {
  position: sticky;
  top: 12px;
  z-index: 0;
  height: calc(100vh - 24px);
  overflow: hidden;
  border-radius: 24px;
  will-change: transform;
}
.tpc-placeholder-img {
  background: linear-gradient(155deg, #1c1a17 0%, #0e0d0c 100%);
}

/* Step 2 picture: black-and-grey ribbed-glass abstract, with a steady 35% dark layer baked in
   so the white headline and the moving tool icons stay readable at every scroll position. */
#tpc-img-2.tpc-placeholder-img {
  /* a soft pool of shade behind the headline (so the bright ribs do not cut through the letters),
     a gentler 30% layer everywhere else so the edges keep their shine */
  background:
    radial-gradient(ellipse 52% 38% at 50% 46%, rgba(8, 8, 8, 0.42) 0%, rgba(8, 8, 8, 0.22) 55%, rgba(8, 8, 8, 0) 100%),
    linear-gradient(rgba(10, 10, 10, 0.30), rgba(10, 10, 10, 0.30)),
    url(../images/step2/step2-bg.jpg) center / cover no-repeat,
    #0e0d0c;
}

/* Step 1 and Step 3 pictures (Images 2 / step 1.png, step 3.png, shipped as images/hiw/step-N.jpg).
   Same layers as step 2: a soft pool of shade behind the headline plus a gentle even dark layer,
   so the white headline reads on the lighter parts of the pictures. */
#tpc-img-1.tpc-placeholder-img,
#tpc-img-3.tpc-placeholder-img {
  background:
    radial-gradient(ellipse 58% 40% at 50% 50%, rgba(8, 8, 8, 0.62) 0%, rgba(8, 8, 8, 0.38) 58%, rgba(8, 8, 8, 0) 100%),
    linear-gradient(rgba(10, 10, 10, 0.26), rgba(10, 10, 10, 0.26)),
    var(--tpc-pic) center / cover no-repeat,
    #0e0d0c;
}
#tpc-img-1.tpc-placeholder-img { --tpc-pic: url(../images/hiw/step-1.jpg); }
#tpc-img-3.tpc-placeholder-img { --tpc-pic: url(../images/hiw/step-3.jpg); }

/* Step 2's "We Build Around You" image - a scrolling strip of the
   real tools this actually integrates with (ported from a 21st.dev
   "IntegrationHero" reference, trimmed down to only the icons that
   correlate with what an AI-automation agency for SMBs would
   actually integrate - the reference's own set mixed in things like
   Nike, GitHub, a Linux distro, and raw language/spec logos that
   have nothing to do with "integrations" a business owner would
   recognize). Sits behind .tpc-overlay-dark (inserted before it in
   the DOM) so it dims along with the rest of the image on scroll,
   same as everything else in this photo - "act like it's in the
   image" rather than a UI layer floating on top of it. Positioned in
   the lower half with real clearance from the bottom edge, and
   rotated a few degrees so it reads as a natural design element, not
   a straight UI bar. */
.tpc-tools-strip {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 15%;
  overflow: hidden;
  padding: 10px 0;
  transform: rotate(-6deg);
  pointer-events: none;
}
.tpc-tools-row {
  display: flex;
  align-items: center;
  gap: 30px;
  width: max-content;
  will-change: transform;
}
.tpc-tools-row-a {
  margin-bottom: 28px;
  animation: tpc-tools-scroll-left 40s linear infinite;
}
.tpc-tools-row-b {
  animation: tpc-tools-scroll-right 40s linear infinite;
}
@keyframes tpc-tools-scroll-left {
  from { transform: translateX(0); }
  to   { transform: translateX(-33.333%); }
}
@keyframes tpc-tools-scroll-right {
  from { transform: translateX(-33.333%); }
  to   { transform: translateX(0); }
}
.tpc-tools-icon {
  flex-shrink: 0;
  width: 76px;
  height: 76px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(255,255,255,.08);
  border: 1px solid rgba(255,255,255,.18);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  box-shadow: 0 8px 20px rgba(0,0,0,.35);
}
.tpc-tools-icon img { width: 38px; height: 38px; object-fit: contain; }
/* Explicit correction: the edge-fade overlays used to sit here as two
   solid-to-transparent gradient rectangles meant to fade the icons in
   from the strip's own edges. Their flat end colour (#0e0d0c) never
   quite matched the placeholder's own diagonal gradient at that exact
   spot, so it read as a visible long dark "card" floating behind the
   icons instead of blending in - removed entirely; just the icons
   float directly over the image now, nothing else. */
@media (prefers-reduced-motion: reduce) {
  .tpc-tools-row-a, .tpc-tools-row-b { animation: none; }
}

.tpc-overlay-dark {
  position: absolute;
  inset: 0;
  background: rgba(20, 19, 17, .78);
  opacity: 0;
  will-change: opacity;
}
.tpc-overlay-copy {
  position: absolute;
  top: 0; left: 0;
  width: 100%;
  height: 100vh;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  color: #fff;
  pointer-events: none;
  will-change: transform, opacity;
}
.tpc-overlay-copy .tpc-sub {
  font-size: clamp(1.125rem, 2vw, 1.5rem);
  margin-bottom: 14px;
  opacity: 1;
  color: #f6f4ef;
  text-shadow: 0 1px 14px rgba(0, 0, 0, .6);
}
.tpc-overlay-copy .tpc-head {
  font-family: var(--font-display);
  font-size: clamp(2.25rem, 6vw, 4.5rem);
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.05;
  max-width: 16ch;
  /* warm off-white (matches the site's cream) + a soft dark halo so the letters hold against the bright ribs */
  color: #f6f4ef;
  text-shadow: 0 2px 28px rgba(0, 0, 0, .55), 0 1px 2px rgba(0, 0, 0, .35);
}
.tpc-content {
  max-width: 1290px;
  margin: 0 auto;
  /* Bottom padding widened 120px -> clamp(160,..,240)px (2026-09-12): each
     panel's text needs real breathing room before the next panel's sticky
     image starts pinning right underneath it - it read as cramped before. */
  padding: 128px 24px clamp(160px, 16vw, 240px);
  display: grid;
  grid-template-columns: 1fr;
  gap: 32px;
}
/* Title column - a small italic step index ("/01") sitting right-
   aligned directly above the title, within the title's own column
   (not the far right of the whole panel) - explicit request, replacing
   the old "Book Your Free Audit" button under each step (unprofessional
   repeated three times down the page - the section already ends in its
   own CTA). Index uses the site's own --font-display, just italic -
   no new font brought in for it. */
/* Explicit fix: the index row used to sit IN FLOW above the h3, which
   pushed the title down by its own height + margin - so the title and
   the paragraph column (which has nothing pushing it down) no longer
   started at the same vertical level, even though the grid itself has
   align-items:start. Taking the index out of flow (absolutely
   positioned, anchored to sit just above the column's own top edge)
   means the title-col's box now starts exactly where the h3 does, so
   it lines up level with the paragraph column again - the index just
   floats above both without affecting either's position. */
/* Layout from Nicky's reference images (2026-10-09): title (2 lines, sans) with the
   serif-italic number at its top-right corner and a tracked label under it;
   paragraphs in the right half. Title column hugs the longest title line so the
   number lands on that line's right edge. */
.tpc-title-col { position: relative; width: fit-content; max-width: 100%; }
.tpc-step-index-row {
  position: absolute;
  bottom: 100%;
  left: calc(100% + 2.5rem);
  margin-bottom: 0.1rem;
  white-space: nowrap;
}
/* Same serif-italic treatment as .accent-serif elsewhere on the site
   (the hero's "today," / "scale") - explicit request to match the
   reference's elegant italic numeral look exactly, rather than the
   site's own sans-serif italicized (which read as just a slanted
   version of the body font, not a genuine distinct italic). */
.tpc-step-index {
  font-family: var(--font-serif);
  font-style: italic;
  font-weight: 400;
  font-size: clamp(1.25rem, 1.9vw, 1.75rem);
  line-height: 1;
  color: #75757a;
}
.tpc-content h3 {
  /* Dramatically bigger (explicit request) - was clamp(1.5rem,2.6vw,2rem),
     which read small/timid next to the reference. Paired with the wider
     title column below so longer titles ("No workflow changes, no
     retraining your team") still wrap to a reasonable 2-3 lines instead
     of stacking one word per line. */
  font-family: 'Instrument Sans', var(--font-body);
  font-size: clamp(2.5rem, 4.6vw, 4.25rem);
  font-weight: 400;
  color: #111113;
  letter-spacing: -0.03em;
  line-height: 1.03;
}
.tpc-labels {
  margin-top: 1.9rem;
  font-family: 'Instrument Sans', var(--font-body);
  font-size: clamp(0.6875rem, 0.9vw, 0.8125rem);
  font-weight: 400;
  letter-spacing: 0.24em;
  word-spacing: 0.25em;
  text-transform: uppercase;
  color: #8d8d92;
}
.tpc-content-body { padding-top: 0.3rem; }
.tpc-content-body p {
  font-family: 'Instrument Sans', var(--font-body);
  font-size: clamp(1rem, 1.28vw, 1.15rem);
  font-weight: 400;
  letter-spacing: -0.006em;
  line-height: 1.55;
  color: #333847;
  margin-bottom: 1.5em;
}
.tpc-content-body p:last-child { margin-bottom: 0; }
@media (min-width: 860px) {
  .tpc-content { grid-template-columns: 1fr 1fr; align-items: start; gap: 0; }
}
@media (max-width: 859px) {
  .tpc-step-index-row { left: 0; margin-bottom: 0.6rem; }
}

/* ---------- DORMANT — the black-card/indicator build this replaced.
   Not deleted in case any of it gets reused; nothing in the markup
   references these classes anymore. ---------- */
.hiw-main-title { font-size: clamp(2.2rem, 3.8vw, 3.2rem); }

/* step indicators + connecting line, sitting above the grid on the page's
   normal (light) background. Black, per spec — not the page's usual --line
   grey, so it reads as one system with the black cards below it. */
.hiw-indicator {
  position: relative;
  max-width: 1080px;
  margin: 0 auto 36px;
  width: 100%;
}
.hiw-indicator-line {
  position: absolute;
  left: 16.6667%;
  right: 16.6667%;
  top: 50%;
  height: 2px;
  transform: translateY(-50%);
  background: rgba(14,13,12,.28);
}
/* Green progress fill, drawn on top of the base line. Spans the exact same
   16.6667%-to-83.3333% run (dot-1 centre to dot-3 centre) as the base line;
   JS scales it 0->1 from the left edge as you hover step 1/2/3. */
.hiw-indicator-line-fill {
  position: absolute;
  left: 16.6667%;
  right: 16.6667%;
  top: 50%;
  height: 2px;
  transform: translateY(-50%) scaleX(0);
  transform-origin: left center;
  background: #22C55E;
  will-change: transform;
}
.hiw-indicator-grid {
  position: relative;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
}
.hiw-indicator-dot {
  position: relative;
  justify-self: center;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: #0E0D0C;
  color: #fff;
  font-family: var(--font-mono);
  font-weight: 600;
  font-size: 1rem;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 0 0 6px var(--bg);
  transition: background-color .3s ease;
}
/* number and checkmark sit stacked on top of each other; hovering swaps
   which one is visible with a quick "pop" rather than a plain cross-fade. */
.hiw-dot-num,
.hiw-dot-check {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: opacity .25s ease, transform .3s cubic-bezier(.34, 1.56, .64, 1);
}
.hiw-dot-check {
  width: 18px;
  height: 18px;
  margin: auto;
  opacity: 0;
  transform: scale(.4) rotate(-20deg);
}
.hiw-indicator-dot.is-lit {
  background: #22C55E;
}
.hiw-indicator-dot.is-lit .hiw-dot-num {
  opacity: 0;
  transform: scale(.4);
  transition-duration: .15s;
}
.hiw-indicator-dot.is-lit .hiw-dot-check {
  opacity: 1;
  transform: scale(1) rotate(0deg);
  transition-delay: .05s;   /* number ducks out first, then the check pops */
}
@media (prefers-reduced-motion: reduce) {
  .hiw-indicator-line-fill,
  .hiw-indicator-dot,
  .hiw-dot-num,
  .hiw-dot-check { transition: none; }
}

/* the 3 cards — one row, equal columns */
.hiw-journey-v3 {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 32px;
  max-width: 1080px;
  margin: 0 auto;
}
.hiw-card {
  position: relative;
  z-index: 1;
  background: #0E0D0C;
  border: 1px solid rgba(255,255,255,.10);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-s);
  width: 100%;
}
/* Merges with .reveal's own entrance transition (opacity/transform/filter).
   transform/box-shadow/border-color/background-color are all on one snappy
   150ms ease-in-out — sped up from 300ms so the hover reacts instantly. */
.hiw-journey-v3 .hiw-card {
  transition:
    opacity .7s cubic-bezier(.16, 1, .3, 1),
    filter .8s cubic-bezier(.16, 1, .3, 1),
    transform .15s ease-in-out,
    box-shadow .15s ease-in-out,
    border-color .15s ease-in-out,
    background-color .15s ease-in-out;
}
/* THE BUG: `.hiw-card:hover` (2 selector components: 1 class + 1
   pseudo-class) and `.reveal.in` (2 classes, defined further down the
   sheet — it's what clears the entrance slide-up) land on the exact same
   specificity. Equal specificity means whichever is LATER in the file
   wins, full stop — and `.reveal.in{transform:none}` sits after this rule,
   so it was silently overwriting `transform:scale(1.05)` on every hover.
   That's why the "pop" never showed up. Fixed by adding one more class to
   this selector (3 components now) so it always outranks `.reveal.in`
   regardless of where either sits in the file. Only the card itself
   changes on hover — scale, shadow, border, the same muted background the
   icon box already sits on — matching the reference exactly; the icon box
   has no hover rule of its own, so its edge just melts into the card. */
.hiw-journey-v3 .hiw-card:hover {
  transform: scale(1.05);
  box-shadow: var(--shadow-l);
  border-color: rgba(255,255,255,.35);
  background: #1C1A1A;
}
.hiw-card-inner {
  padding: 40px 36px;
  text-align: left;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}

/* icon box, top-left of the card — fixed muted background, white icon.
   Same #1C1A1A as .hiw-card:hover above, on purpose (see note there). */
.hiw-icon-box {
  width: 52px;
  height: 52px;
  border-radius: 14px;
  background: #1C1A1A;
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 24px;
  flex-shrink: 0;
}
.hiw-icon-box svg { width: 26px; height: 26px; }

.hiw-card-inner h3 {
  font-family: var(--font-display);
  font-size: 1.375rem;
  font-weight: 600;
  color: #fff;
  letter-spacing: -0.015em;
  margin-bottom: 12px;
}
.hiw-card-inner p {
  font-size: 1rem;
  line-height: 1.6;
  color: #8B877E;
  margin-bottom: 0;
}

/* benefit bullets under the description */
.hiw-benefits {
  list-style: none;
  margin: 22px 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 13px;
}
.hiw-benefits li {
  display: flex;
  align-items: center;
  gap: 12px;
  font-size: .9375rem;
  line-height: 1.5;
  color: #8B877E;
}
.hiw-benefit-dot {
  width: 17px;
  height: 17px;
  border-radius: 50%;
  background: rgba(255,255,255,.16);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.hiw-benefit-dot span {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: #fff;
}

@media (max-width: 900px) {
  .hiw-journey-v3 { grid-template-columns: 1fr; gap: 24px; }
  .hiw-indicator { display: none; }
}

/* ---------- Services circular showcase ---------- */
.svc-hint {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  color: var(--muted);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  margin-top: 20px;
}
.svc-wheel { position: relative; }
.svc-stage {
  position: relative;
  width: min(920px, 100%);
  height: 880px;
  margin: 0 auto;
}

.svc-center {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  width: 540px;
  height: 540px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 2px 6px rgba(22,20,46,.05), 0 30px 80px rgba(22,20,46,.10);
}
.svc-panel {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 48px 100px;
  opacity: 0;
  visibility: hidden;
  transform: translateY(10px);
  transition: opacity .4s ease, transform .4s ease, visibility 0s .4s;
}
.svc-panel.active {
  opacity: 1;
  visibility: visible;
  transform: none;
  transition: opacity .55s ease .25s, transform .55s ease .25s, visibility 0s;
}
.svc-panel-icon {
  width: 64px;
  height: 64px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 14px;
  flex-shrink: 0;
}
.svc-panel-icon svg { width: 26px; height: 26px; stroke: var(--ink); }
.svc-panel h3 {
  font-family: var(--font-display);
  font-size: 1.5rem;
  font-weight: 600;
  color: var(--ink);
  letter-spacing: -0.015em;
  margin-bottom: 12px;
}
.svc-panel p {
  font-size: 0.875rem;
  line-height: 1.6;
  color: var(--muted);
  margin-bottom: 8px;
  max-width: 340px;
}
.svc-benefits {
  list-style: none;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 6px 20px;
  margin: 10px 0 20px;
  padding: 0;
}
.svc-benefits li {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  font-weight: 500;
  color: var(--brand);
  text-align: left;
  white-space: nowrap;
}

.svc-orb {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 96px;
  height: 96px;
  margin: -48px 0 0 -48px;
  border: none;
  background: none;
  padding: 0;
  cursor: pointer;
  will-change: transform;
  z-index: 2;
}
.svc-orb-disc {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 96px;
  height: 96px;
  border-radius: 50%;
  box-shadow: 0 6px 20px rgba(22,20,46,.10);
  transition: box-shadow .3s ease;
}
.svc-orb-disc svg { width: 32px; height: 32px; stroke: var(--ink); fill: none; }
.svc-orb:hover .svc-orb-disc { box-shadow: 0 10px 28px rgba(22,20,46,.16); }
.svc-orb-label {
  position: absolute;
  top: calc(100% + 8px);
  left: 50%;
  transform: translateX(-50%);
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  color: var(--muted);
  white-space: nowrap;
  letter-spacing: 0.02em;
}
.svc-orb.active .svc-orb-disc {
  box-shadow: 0 0 0 3px #fff, 0 0 0 5px var(--brand), 0 12px 32px rgba(20,19,17,.22);
}
.svc-orb.active .svc-orb-label { color: var(--brand); font-weight: 500; }

.svc-arrow {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  z-index: 5;
  width: 52px;
  height: 52px;
  border-radius: 50%;
  border: 1px solid var(--line);
  background: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: border-color .25s ease, box-shadow .25s ease;
}
.svc-arrow:hover { border-color: var(--brand); box-shadow: 0 8px 24px rgba(22,20,46,.10); }
.svc-arrow svg { width: 20px; height: 20px; stroke: var(--ink); }
.svc-prev { left: 8px; }
.svc-next { right: 8px; }

.svc-dots {
  display: flex;
  justify-content: center;
  gap: 10px;
  margin-top: 24px;
}
.svc-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  border: none;
  padding: 0;
  background: var(--line);
  cursor: pointer;
  transition: background .25s ease, transform .25s ease;
}
.svc-dot.active { background: var(--brand); transform: scale(1.35); }

@media (max-width: 1060px) {
  .svc-stage { height: 680px; }
  .svc-center { width: min(460px, 82vw); height: min(460px, 82vw); }
  .svc-panel { padding: 36px 64px; }
  .svc-panel-icon { display: none; }
  .svc-panel h3 { font-size: 1.25rem; }
  .svc-panel p { font-size: 0.8125rem; max-width: 300px; }
  .svc-benefits li { font-size: 0.66rem; }
  .svc-orb, .svc-orb-disc { width: 68px; height: 68px; }
  .svc-orb { margin: -34px 0 0 -34px; }
  .svc-orb-disc svg { width: 24px; height: 24px; }
  .svc-orb-label { display: none; }
}
@media (max-width: 720px) {
  .svc-orb { display: none; }
  .svc-stage { height: 560px; }
  .svc-panel { padding: 28px 40px; }
  .svc-benefits li { white-space: normal; }
}

/* ---------- Hero ecosystem (orbits) ---------- */
.ecosystem {
  position: relative;
  width: 560px; height: 560px;
  margin-left: auto;
  flex-shrink: 0;
}
.orbit {
  position: absolute;
  top: 50%; left: 50%;
  border: 1px dashed rgba(20,19,17,.22);
  border-radius: 50%;
  translate: -50% -50%;
}
.orbit-1 { width: 340px; height: 340px; }
.orbit-2 { width: 520px; height: 520px; border-color: rgba(20,19,17,.14); }

.chip-pos {
  position: absolute;
  top: 50%; left: 50%;
  transform: rotate(var(--a)) translateX(var(--r)) rotate(calc(-1 * var(--a)));
}

.eco-chip {
  position: relative;
  width: 58px; height: 58px;
  margin: -29px 0 0 -29px;
  display: flex; align-items: center; justify-content: center;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 18px;
  box-shadow: var(--shadow-m);
  animation: bob 7s ease-in-out infinite;
  animation-delay: var(--d, 0s);
}
.eco-chip svg { width: 26px; height: 26px; stroke: var(--brand); }

/* Story-loop highlight ring - one 14s cycle shared by the whole hero */
.eco-chip::after {
  content: '';
  position: absolute; inset: -7px;
  border-radius: 24px;
  border: 2px solid var(--brand);
  opacity: 0;
  transform: scale(.9);
}
.eco-chip.hl-phone::after { animation: chip-hl 14s var(--ease-out) infinite; }
.eco-chip.hl-cal::after   { animation: chip-hl 14s var(--ease-out) infinite; animation-delay: 5s; }
.eco-chip.hl-crm::after   { animation: chip-hl 14s var(--ease-out) infinite; animation-delay: 8.5s; }
@keyframes chip-hl {
  0%, 2%   { opacity: 0; transform: scale(.9); }
  6%       { opacity: 1; transform: scale(1); }
  14%      { opacity: 0; transform: scale(1.12); }
  100%     { opacity: 0; transform: scale(.9); }
}

/* Connection lines: drawn in sequence phone → core → calendar → CRM */
.eco-lines { position: absolute; inset: 0; pointer-events: none; z-index: 1; }
.eco-lines path {
  fill: none;
  stroke: var(--brand);
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
  opacity: 0;
}
.eco-lines .l1 { animation: line-draw 14s linear infinite; }
.eco-lines .l2 { animation: line-draw 14s linear infinite; animation-delay: 3.6s; }
.eco-lines .l3 { animation: line-draw 14s linear infinite; animation-delay: 7.1s; }
@keyframes line-draw {
  0%      { stroke-dashoffset: 1; opacity: 0; }
  2%      { opacity: .75; }
  12%     { stroke-dashoffset: 0; opacity: .75; }
  22%     { stroke-dashoffset: 0; opacity: .35; }
  30%     { stroke-dashoffset: 0; opacity: 0; }
  100%    { stroke-dashoffset: 1; opacity: 0; }
}

@keyframes bob {
  0%, 100% { translate: 0 0; }
  50% { translate: 0 -7px; }
}

.eco-core {
  position: absolute;
  top: 50%; left: 50%;
  translate: -50% -50%;
  width: 128px; height: 128px;
  display: flex; align-items: center; justify-content: center;
  background: var(--grad);
  border-radius: 36px;
  box-shadow: 0 8px 20px rgba(20,19,17,.35), 0 32px 80px rgba(20,19,17,.35);
  z-index: 2;
}
.eco-core svg { width: 60px; height: 60px; }
.eco-core::before, .eco-core::after {
  content: '';
  position: absolute; inset: -14px;
  border-radius: 44px;
  border: 1px solid rgba(20,19,17,.28);
  animation: core-pulse 3.2s var(--ease-out) infinite;
}
.eco-core::after { animation-delay: 1.6s; }

@keyframes core-pulse {
  0% { opacity: .8; transform: scale(.92); }
  100% { opacity: 0; transform: scale(1.28); }
}

.pulse-dot {
  position: absolute;
  top: 50%; left: 50%;
  width: 7px; height: 7px;
  margin: -3.5px 0 0 -3.5px;
  border-radius: 50%;
  background: var(--brand);
  box-shadow: 0 0 12px 3px rgba(20,19,17,.55);
  offset-path: circle(var(--r) at 0 0);
  animation: travel 14s linear infinite;
  animation-delay: var(--d, 0s);
}
@keyframes travel {
  0% { offset-distance: 0%; opacity: 0; }
  6% { opacity: 1; }
  46% { opacity: 1; }
  52% { offset-distance: 52%; opacity: 0; }
  100% { offset-distance: 52%; opacity: 0; }
}

.eco-note {
  position: absolute;
  display: flex; align-items: center; gap: 12px;
  background: rgba(255,255,255,.92);
  backdrop-filter: blur(10px);
  border: 1px solid var(--line);
  border-radius: 16px;
  padding: 12px 18px 12px 12px;
  box-shadow: var(--shadow-m);
  z-index: 3;
}
/* Notes appear at their moment in the 14s story, then rest */
.eco-note.n-booked { opacity: 0; animation: note-in 14s var(--ease-out) infinite; animation-delay: 5.6s; }
.eco-note.n-crm    { opacity: 0; animation: note-in 14s var(--ease-out) infinite; animation-delay: 9.1s; }
@keyframes note-in {
  0%       { opacity: 0; transform: translateY(10px); }
  4%       { opacity: 1; transform: translateY(0); }
  52%      { opacity: 1; transform: translateY(0); }
  58%      { opacity: 0; transform: translateY(-8px); }
  100%     { opacity: 0; transform: translateY(10px); }
}

/* Hours-saved ticker - the loop's punchline */
.eco-saved {
  position: absolute;
  z-index: 3;
  background: var(--ink);
  color: #fff;
  border-radius: 16px;
  padding: 14px 20px;
  box-shadow: 0 12px 32px rgba(22,20,46,.28);
}
.eco-saved strong {
  display: block;
  font-family: var(--font-mono);
  font-size: 1.25rem;
  font-weight: 500;
  letter-spacing: -0.02em;
  line-height: 1.2;
}
.eco-saved span {
  font-family: var(--font-mono);
  font-size: 0.65625rem;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: #A5A2C0;
}
.eco-saved strong em { font-style: normal; color: #9D8FFF; }
.eco-saved.tick strong em { animation: saved-tick .5s var(--ease-out); }
@keyframes saved-tick {
  0% { opacity: 0; }
  100% { opacity: 1; }
}
.eco-note .note-icon {
  width: 36px; height: 36px;
  flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  border-radius: 11px;
  background: var(--success-soft);
}
.eco-note .note-icon svg { width: 18px; height: 18px; stroke: var(--success); }
.eco-note strong { display: block; font-size: 0.8125rem; color: var(--ink); letter-spacing: -0.01em; line-height: 1.3; }
.eco-note span { font-size: 0.71875rem; color: var(--muted); font-family: var(--font-mono); }

/* ---------- Trust strip ---------- */
.trust { padding: 40px 0; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); background: var(--surface); }
.trust p {
  text-align: center;
  font-family: var(--font-mono);
  font-size: 0.71875rem;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  color: var(--muted);
  margin-bottom: 26px;
}
.trust-line {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 14px;
  flex-wrap: wrap;
}
.trust-line .t-seg {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-size: 1rem;
  font-weight: 500;
  color: var(--ink-soft);
}
.trust-line .t-seg svg { width: 19px; height: 19px; stroke: var(--brand); opacity: .8; }
.trust-line .t-seg strong { color: var(--ink); font-weight: 700; }
.trust-line .t-dot { width: 4px; height: 4px; border-radius: 50%; background: var(--line-strong); }
.marquee { overflow: hidden; position: relative; -webkit-mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent); mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent); }
.marquee-track {
  display: flex;
  gap: 72px;
  width: max-content;
  animation: marquee 36s linear infinite;
}
@keyframes marquee { to { transform: translateX(-50%); } }
.marquee-track span {
  font-size: 1.1875rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  color: #B4B1CB;
  white-space: nowrap;
  display: flex; align-items: center; gap: 10px;
}
.marquee-track span svg { width: 20px; height: 20px; stroke: #B4B1CB; }

/* ---------- Cards ---------- */
.card-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px; }
.card-grid.two { grid-template-columns: repeat(2, 1fr); }

.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  padding: 36px;
  box-shadow: var(--shadow-s);
  transition: box-shadow .25s var(--ease-out), border-color .25s var(--ease-out);
}
a.card, .card.hoverable { cursor: pointer; }
a.card:hover, .card.hoverable:hover {
  box-shadow: var(--shadow-m);
  border-color: rgba(20,19,17,.35);
}
.card .card-icon {
  width: 52px; height: 52px;
  display: flex; align-items: center; justify-content: center;
  background: var(--brand-soft);
  border-radius: 15px;
  margin-bottom: 24px;
}
.card .card-icon svg { width: 25px; height: 25px; stroke: var(--brand); }
.card h3 { margin-bottom: 12px; }
.card p { font-size: 0.9875rem; color: var(--muted); }
.card .card-link {
  display: inline-flex; align-items: center; gap: 7px;
  margin-top: 22px;
  font-size: 0.9375rem; font-weight: 700;
  color: var(--brand);
}
.card .card-link svg { width: 15px; height: 15px; transition: transform .25s var(--ease-out); }
a.card:hover .card-link svg, .card.hoverable:hover .card-link svg { transform: translateX(3px); }

/* ---------- Before / After transformation (draggable scrub) ---------- */
.scrub {
  position: relative;
  max-width: 1040px;
  margin: 0 auto;
  border-radius: var(--r-panel);
  border: 1px solid var(--line);
  box-shadow: var(--shadow-l);
  overflow: hidden;
  --cut: 97%;
  touch-action: pan-y;
}
.scrub-layer { padding: 60px 64px; }
.scrub-layer.after {
  position: absolute;
  inset: 0;
  background: var(--ink);
  clip-path: inset(0 0 0 var(--cut));
}
.scrub-handle {
  position: absolute;
  top: 0; bottom: 0;
  left: var(--cut);
  width: 2px;
  margin-left: -1px;
  background: var(--brand);
  z-index: 4;
  cursor: ew-resize;
}
.scrub-handle .grip {
  position: absolute;
  top: 50%; left: 50%;
  translate: -50% -50%;
  width: 46px; height: 46px;
  display: flex; align-items: center; justify-content: center;
  background: var(--brand);
  border-radius: 50%;
  box-shadow: 0 4px 12px rgba(20,19,17,.4), 0 0 0 5px rgba(255,255,255,.55);
  transition: transform .2s var(--ease-out);
}
.scrub:hover .scrub-handle .grip { transform: scale(1.06); }
.scrub-handle .grip svg { width: 20px; height: 20px; stroke: #fff; }
.scrub-handle:focus-visible { outline: none; }
.scrub-handle:focus-visible .grip { box-shadow: 0 4px 12px rgba(20,19,17,.4), 0 0 0 3px #fff, 0 0 0 6px var(--brand); }

.scrub .side-tag {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: 0.71875rem;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  padding: 7px 14px;
  border-radius: var(--r-pill);
  margin-bottom: 30px;
}
.scrub-layer.before .side-tag { background: var(--bg-soft); color: var(--muted); }
.scrub-layer.after .side-tag { background: rgba(255,255,255,.12); color: #C9C5E8; }
.scrub-layer h3 { font-size: 1.625rem; margin-bottom: 34px; }
.scrub-layer.after h3 { color: #fff; }

.scrub-row {
  display: flex; gap: 14px; align-items: flex-start;
  padding: 16px 0;
  min-height: 84px;
  border-top: 1px solid var(--line);
}
.scrub-layer.after .scrub-row { border-top-color: rgba(255,255,255,.12); }
.scrub-row svg { width: 19px; height: 19px; flex-shrink: 0; margin-top: 3px; stroke: var(--error); }
.scrub-layer.after .scrub-row svg { stroke: #7EF0C4; }
.scrub-row strong { display: block; font-size: 0.9875rem; color: var(--ink); letter-spacing: -0.01em; }
.scrub-layer.after .scrub-row strong { color: #fff; }
.scrub-row span { font-size: 0.875rem; color: var(--muted); }
.scrub-layer.after .scrub-row span { color: #A5A2C0; }

.scrub-stat {
  margin-top: 30px;
  padding-top: 26px;
  border-top: 1px solid var(--line);
  font-family: var(--font-mono);
}
.scrub-layer.after .scrub-stat { border-top-color: rgba(255,255,255,.12); }
.scrub-stat strong { font-size: 2.375rem; font-weight: 500; color: var(--ink); letter-spacing: -0.03em; display: block; line-height: 1.1; }
.scrub-layer.after .scrub-stat strong { color: #fff; }
.scrub-stat span { font-size: 0.8125rem; color: var(--muted); }
.scrub-layer.after .scrub-stat span { color: #A5A2C0; }

.scrub-hint {
  text-align: center;
  font-family: var(--font-mono);
  font-size: 0.71875rem;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--muted);
  margin-top: 22px;
  display: flex; align-items: center; justify-content: center; gap: 10px;
}
.scrub-hint svg { width: 15px; height: 15px; stroke: var(--muted); }

/* ---------- Before / After transformation (legacy static panel, inner pages) ---------- */
.transform-panel {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0;
  border-radius: var(--r-panel);
  overflow: hidden;
  border: 1px solid var(--line);
  box-shadow: var(--shadow-l);
}
.transform-side { padding: 60px 56px; background: var(--surface); }
.transform-side.after { background: var(--grad); }
.transform-side .side-label {
  font-family: var(--font-mono);
  font-size: 0.71875rem;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  display: inline-flex; align-items: center; gap: 8px;
  padding: 7px 14px;
  border-radius: var(--r-pill);
  margin-bottom: 32px;
}
.transform-side.before .side-label { background: var(--bg-soft); color: var(--muted); }
.transform-side.after .side-label { background: rgba(255,255,255,.16); color: #fff; }
.transform-side h3 { font-size: 1.75rem; margin-bottom: 8px; }
.transform-side.after h3, .transform-side.after .t-item strong { color: #fff; }
.transform-side .t-sub { font-size: 0.9375rem; color: var(--muted); margin-bottom: 36px; }
.transform-side.after .t-sub { color: rgba(255,255,255,.72); }

.t-item { display: flex; gap: 14px; padding: 15px 0; border-top: 1px solid var(--line); align-items: flex-start; }
.transform-side.after .t-item { border-top-color: rgba(255,255,255,.16); }
.t-item svg { width: 19px; height: 19px; flex-shrink: 0; margin-top: 3px; stroke: var(--error); }
.transform-side.after .t-item svg { stroke: #7EF0C4; }
.t-item strong { display: block; font-size: 0.9875rem; color: var(--ink); letter-spacing: -0.01em; }
.t-item span { font-size: 0.875rem; color: var(--muted); }
.transform-side.after .t-item span { color: rgba(255,255,255,.68); }

.transform-stat {
  margin-top: 40px;
  padding-top: 28px;
  border-top: 1px solid var(--line);
  font-family: var(--font-mono);
}
.transform-side.after .transform-stat { border-top-color: rgba(255,255,255,.16); }
.transform-stat strong { font-size: 2.5rem; font-weight: 500; color: var(--ink); letter-spacing: -0.03em; display: block; line-height: 1.1; }
.transform-side.after .transform-stat strong { color: #fff; }
.transform-stat span { font-size: 0.8125rem; color: var(--muted); }
.transform-side.after .transform-stat span { color: rgba(255,255,255,.68); }

/* ---------- Steps (How it works) ---------- */
.steps { display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px; counter-reset: step; }
.step {
  position: relative;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  padding: 40px 36px;
  box-shadow: var(--shadow-s);
}
.step .step-num {
  font-family: var(--font-mono);
  font-size: 0.8125rem;
  font-weight: 500;
  color: var(--brand);
  background: var(--brand-soft);
  width: 44px; height: 44px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 13px;
  margin-bottom: 26px;
}
.step h3 { margin-bottom: 12px; }
.step p { font-size: 0.9875rem; color: var(--muted); }

/* ---------- Metrics band ---------- */
.metrics {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 24px;
  text-align: center;
}
.metric strong {
  display: block;
  font-family: var(--font-mono);
  font-size: clamp(2.6rem, 4vw, 3.4rem);
  font-weight: 500;
  letter-spacing: -0.04em;
  color: var(--ink);
  line-height: 1.05;
}
.metric strong em { font-style: normal; color: var(--brand); }
.metric span { font-size: 0.9375rem; color: var(--muted); }

/* ---------- Industry cards ---------- */
.industry-card {
  position: relative;
  border-radius: var(--r-panel);
  padding: 56px 52px;
  background: var(--surface);
  border: 1px solid var(--line);
  box-shadow: var(--shadow-s);
  overflow: hidden;
  transition: box-shadow .3s var(--ease-out), border-color .3s var(--ease-out), transform .4s var(--ease-out);
  will-change: transform;
  display: block;
  cursor: pointer;
}
.industry-card:hover { box-shadow: var(--shadow-l); border-color: rgba(20,19,17,.35); }
.industry-card::before {
  content: '';
  position: absolute; top: -80px; right: -80px;
  width: 260px; height: 260px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(20,19,17,.12), transparent 70%);
  transition: opacity .3s;
  opacity: 0;
}
.industry-card:hover::before { opacity: 1; }
.industry-card .card-icon {
  width: 56px; height: 56px;
  display: flex; align-items: center; justify-content: center;
  background: var(--brand-soft); border-radius: 16px; margin-bottom: 28px;
}
.industry-card .card-icon svg { width: 27px; height: 27px; stroke: var(--brand); }
.industry-card h3 { font-size: 1.625rem; margin-bottom: 12px; }
.industry-card > p { color: var(--muted); font-size: 1rem; max-width: 420px; }
.industry-tags { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 28px; }
.industry-tags span {
  font-size: 0.8125rem; font-weight: 500;
  padding: 7px 14px;
  background: var(--bg-soft);
  border-radius: var(--r-pill);
  color: var(--ink-soft);
}

/* ---------- Testimonials (editorial: no stars, no fake avatars) ---------- */
.quote-card { display: flex; flex-direction: column; position: relative; }
.quote-card .quote-mark {
  font-family: var(--font-serif);
  font-style: italic;
  font-size: 3.25rem;
  line-height: 1;
  color: var(--brand);
  opacity: .35;
  margin-bottom: 10px;
  user-select: none;
}
.quote-card blockquote { font-size: 1.0625rem; color: var(--ink-soft); flex: 1; }
.quote-card .quote-who {
  display: flex; align-items: center; gap: 12px;
  margin-top: 28px;
  padding-top: 20px;
  border-top: 1px solid var(--line);
}
.quote-card .quote-who .q-icon {
  width: 38px; height: 38px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  background: var(--brand-soft);
  border-radius: 12px;
}
.quote-card .quote-who .q-icon svg { width: 18px; height: 18px; stroke: var(--brand); }
.quote-card .quote-who strong { display: block; font-size: 0.9375rem; color: var(--ink); }
.quote-card .quote-who span { font-size: 0.8125rem; color: var(--muted); }

/* ---------- FAQ - premium two-column cards ---------- */
.faq-x { padding: 140px 0; }
.faq-x .container { max-width: 1120px; }
.faq-x-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 24px;
  flex-wrap: wrap;
  margin-bottom: 68px;
}
.faq-x-title {
  user-select: none;
  -webkit-user-select: none;
  font-size: clamp(2.2rem, 3.6vw, 3.1rem);
  line-height: 1.1;
  font-weight: 500;
  letter-spacing: -0.03em;
  color: var(--ink);
}
.faq-x-title span { color: #B8B5AC; }
.faq-x-cta {
  background: #fff;
  margin-bottom: 8px;
  box-shadow: 0 1px 2px rgba(20,19,17,.04), 0 6px 18px rgba(20,19,17,.06);
}

.faq-x-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 24px;
  align-items: start;
}
.faq-x-col {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.fq-card {
  background: #fff;
  border-radius: 18px;
  box-shadow: 0 1px 2px rgba(20,19,17,.03), 0 10px 28px rgba(20,19,17,.05);
  transition: box-shadow .35s var(--ease-out), transform .35s var(--ease-out), background-color .4s var(--ease-out);
}
/* Opening a question changes no colours: the card stays white and the icon circle keeps its
   look. Only the plus rotates (below) and the answer slides open. */
.fq-card:hover {
  box-shadow: 0 2px 4px rgba(20,19,17,.04), 0 16px 40px rgba(20,19,17,.09);
}

.fq-q {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  text-align: left;
  background: none;
  border: 0;
  cursor: pointer;
  font-family: var(--font-body);
  font-size: 0.9375rem;
  font-weight: 500;
  letter-spacing: -0.01em;
  color: var(--ink);
  padding: 22px 26px;
  border-radius: 18px;
}
.fq-icon {
  width: 34px; height: 34px;
  border-radius: 50%;
  background: none; /* just the plus, no circle behind it */
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  transition: transform .5s var(--ease-out), background-color .3s var(--ease-out);
}
.fq-icon svg { width: 18px; height: 18px; stroke: var(--ink); stroke-width: 2.2; transition: stroke .3s var(--ease-out); }
.fq-card.open .fq-icon {
  transform: rotate(135deg);
}

.fq-a {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows .55s var(--ease-out);
}
.fq-a > div { overflow: hidden; }
.fq-a p {
  padding: 0 50px 22px 26px;
  font-size: 0.9375rem;
  line-height: 1.65;
  color: var(--muted);
}
.fq-card.open .fq-a { grid-template-rows: 1fr; }

@media (max-width: 800px) {
  .faq-x { padding: 100px 0; }
  .faq-x-grid { grid-template-columns: 1fr; }
  .faq-x-cta { margin-bottom: 4px; }
}

/* ---------- FAQ accordion ---------- */
.faq-list { max-width: 760px; margin: 0 auto; }
.faq-item {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 16px;
  margin-bottom: 16px;
  overflow: hidden;
  transition: border-color .25s var(--ease-out), box-shadow .25s var(--ease-out);
}
.faq-item.open { border-color: rgba(20,19,17,.35); box-shadow: var(--shadow-s); }
.faq-q {
  width: 100%;
  display: flex; align-items: center; justify-content: space-between; gap: 20px;
  padding: 24px 28px;
  background: none; border: none;
  font-family: var(--font-body);
  font-size: 1.0625rem; font-weight: 700; letter-spacing: -0.015em;
  color: var(--ink);
  text-align: left;
  cursor: pointer;
}
.faq-q .faq-chevron {
  width: 32px; height: 32px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  border-radius: 50%;
  background: var(--bg-soft);
  transition: background-color .25s, transform .3s var(--ease-out);
}
.faq-q .faq-chevron svg { width: 15px; height: 15px; stroke: var(--ink-soft); transition: stroke .25s; }
.faq-item.open .faq-chevron { background: var(--brand); transform: rotate(180deg); }
.faq-item.open .faq-chevron svg { stroke: #fff; }
.faq-a {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows .35s var(--ease-out);
}
.faq-item.open .faq-a { grid-template-rows: 1fr; }
.faq-a > div { overflow: hidden; }
.faq-a p { padding: 0 28px 26px; font-size: 0.9875rem; color: var(--muted); max-width: 640px; }

/* ---------- CTA band (ink dark, calm) ---------- */
.cta-band {
  position: relative;
  border-radius: var(--r-panel);
  background: var(--ink);
  padding: 112px 72px;
  text-align: center;
  overflow: hidden;
  box-shadow: 0 24px 64px rgba(22,20,46,.25);
}
.cta-band::before {
  content: '';
  position: absolute; inset: 0;
  background: radial-gradient(56% 70% at 50% 0%, rgba(255,255,255,.08), transparent 70%);
}
.cta-band > * { position: relative; }
.cta-band h2 { color: #fff; margin-bottom: 18px; }
.cta-band p { color: #A3A099; font-size: 1.125rem; max-width: 520px; margin: 0 auto 40px; }
.cta-band .btn-primary {
  background: #fff; color: var(--ink);
  box-shadow: 0 8px 28px rgba(0,0,0,.35);
}
.cta-band .btn-primary:hover { background: var(--bg); color: var(--ink); }
.cta-band .cta-note { font-family: var(--font-mono); font-size: 0.78125rem; color: #6B6760; margin: 22px 0 0; }

/* ---------- CTA "Let's work together" (layout from Nicky's reference image; click animation ported from the 21st.dev "lets-work-section" component) ---------- */
.menu-showcase {
  position: relative;
  overflow: hidden;
  padding: 68px 0 68px;
  margin-bottom: 190px; /* breathing room before the footer curtain reveal */
  /* Geist: the component's own font (shadcn/v0 default), light weight for the display text */
  font-family: 'Geist', var(--font-body);
  --ms-ink: #141311;
  --ms-line: #d9dce2;
  --ms-muted: #7c808c;
  --ms-expo: cubic-bezier(.16, 1, .3, 1);
}
/* Frame positions below come from the reference image (1673 x 940): 1 ref px = 1/16.73 vw.
   The inner box is tall enough for the whole tablet frame plus its shadow. */
.ms-inner { position: relative; min-height: calc(70vw - 136px); }
.ms-left {
  position: relative;
  z-index: 2;
  margin-left: 225px; /* design size at 1440 wide; .ms-left is zoomed with the viewport */
  width: 492px;
  zoom: var(--ms-zoom, 1);
}

/* The animated block: .ms-stage holds the original content (it keeps its space when it
   fades, so nothing below moves) and .ms-success is laid over it after the click. */
.ms-hero { position: relative; }
/* The whole text block (eyebrow down to the checklist) sits 5% smaller as one unit */
.ms-hero, .ms-list { zoom: .95; }

.ms-eyebrow {
  display: flex;
  align-items: center;
  gap: 9px;
  margin-bottom: 8px;
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ms-muted);
  transition: opacity .5s ease, transform .5s ease;
}
.ms-eyebrow-dot { position: relative; display: flex; width: 6px; height: 6px; flex-shrink: 0; border-radius: 50%; background: #10b981; }
.ms-ping {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: #34d399;
  opacity: .75;
  animation: ms-ping 1.6s cubic-bezier(0, 0, .2, 1) infinite;
}
@keyframes ms-ping { 75%, 100% { transform: scale(2.4); opacity: 0; } }

.ms-trigger { display: block; width: fit-content; cursor: pointer; }

.ms-title {
  font-family: inherit;
  font-size: 4.725rem;
  font-weight: 300;
  line-height: .98;
  letter-spacing: -0.025em;
  color: var(--ms-ink);
  margin: 0;
  transition: opacity .7s var(--ms-expo), transform .7s var(--ms-expo);
}
/* two clipping lines; on hover the text slides up inside them (second line a beat later) */
.ms-line { display: block; overflow: hidden; padding: .1em 0 .14em; margin: -.1em 0 -.14em; }
.ms-line-in { display: block; transition: transform .7s var(--ms-expo); }
.ms-line-in-2 { transition-delay: 75ms; }
.ms-title-mute { color: rgba(20, 19, 17, .38); }

.ms-arrow {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 67.9px;
  height: 67.9px;
  margin: 14px 0 0 4px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--ms-ink);
  cursor: pointer;
}
.ms-arrow-ring {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  border: 1px solid #e0e1e5;
  background: #f8f7f4; /* warm off-white so the circle reads as a solid button at rest */
  box-shadow: 0 1px 2px rgba(20, 19, 17, .05), 0 6px 16px -6px rgba(20, 19, 17, .12);
  /* Must stay hit-testable: the site's cursor reads the fill under it to flip white over the dark hover state */
  transition: border-color .5s ease-out, background-color .5s ease-out, transform .5s ease-out, opacity .5s ease-out;
}
.ms-arrow svg {
  position: relative;
  width: 25.2px;
  height: 25.2px;
  transition: transform .5s var(--ms-expo), opacity .5s var(--ms-expo), color .5s var(--ms-expo);
}
.ms-arrow:focus-visible { outline: 2px solid var(--ms-ink); outline-offset: 4px; border-radius: 50%; }

@media (hover: hover) and (pointer: fine) {
  .ms-left:not(.is-clicked) .ms-trigger:hover .ms-line-in { transform: translateY(-8%); }
  .ms-left:not(.is-clicked) .ms-trigger:hover .ms-arrow-ring { border-color: var(--ms-ink); background: var(--ms-ink); transform: scale(1.1); }
  .ms-left:not(.is-clicked) .ms-trigger:hover .ms-arrow svg { color: #fff; transform: translate(2px, -2px); }
}

.ms-sub {
  margin: 16px 0 0;
  max-width: 30rem;
  font-size: 1.0125rem;
  line-height: 1.45;
  color: var(--ms-muted);
  transition: opacity .5s ease .1s, transform .5s ease .1s;
}

/* ---- Click: everything lifts away, the circle swells and fades, the arrow flies off ---- */
.ms-left.is-clicked .ms-trigger { pointer-events: none; }
.ms-left.is-clicked .ms-eyebrow { opacity: 0; transform: translateY(-20px); }
.ms-left.is-clicked .ms-title { opacity: 0; transform: translateY(-40px) scale(.95); }
.ms-left.is-clicked .ms-arrow-ring { border-color: var(--ms-ink); background: transparent; transform: scale(3); opacity: 0; transition-duration: .7s; }
.ms-left.is-clicked .ms-arrow svg { transform: translate(100px, -100px) scale(.5); opacity: 0; transition-duration: .6s; }
.ms-left.is-clicked .ms-sub { opacity: 0; transform: translateY(20px); pointer-events: none; }

/* ---- Result: "Let's talk" + Book a call, fading up where the title was ---- */
.ms-success {
  position: absolute;
  inset: 0; /* the whole column: the headline block, checklist and box have all faded away */
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  gap: 30px;
  opacity: 0;
  transform: translateY(20px) scale(.95);
  transform-origin: center;
  pointer-events: none;
  transition: opacity .7s var(--ms-expo), transform .7s var(--ms-expo);
}
.ms-left.is-success .ms-success { opacity: 1; transform: none; pointer-events: auto; }

.ms-success-eyebrow,
.ms-success-title,
.ms-success-sub,
.ms-book { transition: opacity .5s ease, transform .5s ease; opacity: 0; }
.ms-success-eyebrow {
  font-size: 0.75rem;
  font-weight: 500;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--ms-muted);
  transform: translateY(10px);
  transition-delay: .1s;
}
.ms-success-title {
  font-family: inherit;
  font-size: 5.4rem;
  font-weight: 300;
  line-height: 1;
  letter-spacing: -0.03em;
  color: var(--ms-ink);
  margin: -14px 0 0;
  transform: translateY(10px);
  transition-delay: .2s;
}
.ms-success-sub {
  font-size: 0.8125rem;
  font-weight: 400;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: rgba(124, 128, 140, .85);
  transform: translateY(10px);
  transition-delay: .45s;
}
.ms-book {
  display: flex;
  align-items: center;
  gap: 20px;
  transform: translateY(15px);
  transition-delay: .15s;
  cursor: pointer;
}
.ms-left.is-success .ms-success-eyebrow,
.ms-left.is-success .ms-success-title,
.ms-left.is-success .ms-success-sub,
.ms-left.is-success .ms-book { opacity: 1; transform: none; }

/* Solid ink pill at rest (a clear call to action); hover lifts it and nudges the arrow */
.ms-book-wrap {
  position: relative;
  display: block;
  border-radius: 999px;
  /* --mx/--my/--scale are driven by the magnet loop in cta-morph.js (same physics as the chat dock) */
  transform: translate3d(var(--mx, 0px), var(--my, 0px), 0) scale(var(--scale, 1));
}
.ms-book-pulse {
  position: absolute;
  inset: 0;
  border-radius: 999px;
  border: 1.5px solid var(--ms-ink);
  opacity: 0;
  pointer-events: none;
}
.ms-book-wrap.is-pulsing .ms-book-pulse { animation: ms-pill-pulse .8s cubic-bezier(.16, 1, .3, 1) forwards; }
@keyframes ms-pill-pulse {
  0% { opacity: .55; transform: scale(1); }
  100% { opacity: 0; transform: scale(1.65); }
}
.ms-book-pill {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 20px 42px;
  border-radius: 999px;
  border: 1px solid var(--ms-ink);
  background: var(--ms-ink);
  color: #fff;
  box-shadow: 0 14px 34px -12px rgba(20, 19, 17, .55), 0 2px 6px rgba(20, 19, 17, .12);
  overflow: hidden;
  transition: background-color .5s ease, box-shadow .5s ease, transform .5s ease;
}
.ms-book-pill svg { width: 22px; height: 22px; flex-shrink: 0; transition: transform .5s ease; }
.ms-book-text { font-size: 1.1875rem; font-weight: 500; letter-spacing: 0.01em; line-height: 1; }
.ms-book-line {
  width: 72px;
  height: 1px;
  background: #c9ccd4;
  transition: transform .5s ease, opacity .5s ease;
}
.ms-book:focus-visible { outline: 2px solid var(--ms-ink); outline-offset: 6px; border-radius: 999px; }

@media (hover: hover) and (pointer: fine) {
  .ms-book:hover .ms-book-pill {
    background: #2a2825;
    box-shadow: 0 0 30px rgba(20, 19, 17, .12), 0 18px 44px -10px rgba(20, 19, 17, .5);
  }
  .ms-book:hover .ms-book-arrow { transform: translate(3px, -3px) scale(1.1); }
  .ms-book:hover .ms-book-line { transform: scaleX(0); opacity: 0; }
}

/* The checklist and the white box fade out with the headline block (same lift-and-fade) */
.ms-left .ms-list.reveal.is-gone,
.ms-left .ms-card.reveal.is-gone {
  opacity: 0;
  transform: translateY(20px);
  pointer-events: none;
  transition: opacity .5s ease .1s, transform .5s ease .1s;
}

/* Going back (Book a call clicked): the result fades out quickly, then everything above
   returns by the same transitions in reverse. */
.ms-left.is-leaving .ms-success {
  opacity: 0;
  transform: translateY(20px) scale(.95);
  pointer-events: none;
  transition: opacity .35s ease, transform .35s ease;
}
.ms-left.is-leaving .ms-success-eyebrow,
.ms-left.is-leaving .ms-success-title,
.ms-left.is-leaving .ms-success-sub,
.ms-left.is-leaving .ms-book { transition-duration: .25s; transition-delay: 0s; }

@media (prefers-reduced-motion: reduce) {
  .ms-ping { animation: none; }
  .ms-left *, .ms-left { transition-duration: .01ms !important; transition-delay: 0s !important; }
}

.ms-list {
  list-style: none;
  margin: 22px 0 0;
  padding: 0;
  display: grid;
  grid-template-rows: repeat(3, auto);
  grid-auto-flow: column;
  grid-template-columns: 228px 1fr;
  row-gap: 7px;
}
.ms-list li {
  display: flex;
  align-items: center;
  gap: 12px;
  font-size: 0.83rem;
  line-height: 1.4;
  color: #4d4a45;
}
.ms-check { display: inline-flex; flex-shrink: 0; }
.ms-check svg { width: 18px; height: 18px; color: #5e5b55; }

/* White box under the list: the budget finder (scripts/price-slider.js). The two-handle range
   slider over a bar chart is adapted from the 21st.dev "range-slider". */
.ms-card {
  margin-top: 30px;
  width: clamp(488px, 39vw, 560px);
  padding: 14px 22px 12px;
  border-radius: 14px;
  background: #fff;
  box-shadow: 0 1px 2px rgba(20, 19, 17, .05), 0 14px 30px -14px rgba(20, 19, 17, .2);
}
.mp-fallback { font-size: .875rem; color: var(--ms-muted); }
.mp-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 12px; margin-bottom: 10px; }
.mp-head-l { display: flex; align-items: baseline; gap: 10px; }
.mp-title { font-size: .72rem; font-weight: 500; letter-spacing: .1em; text-transform: uppercase; color: var(--ms-muted); }
.mp-value { font-size: 1.5rem; font-weight: 500; letter-spacing: -.025em; line-height: 1; color: #3A3833; font-variant-numeric: tabular-nums; }
.mp-count { font-size: .8125rem; color: var(--ms-muted); }
/* the bars follow the mouse: no handles, no click, no hold */
.mp-chart { position: relative; height: 40px; touch-action: pan-y; user-select: none; -webkit-user-select: none; outline: none; }
.mp-chart:focus-visible { outline: 2px solid var(--ms-ink); outline-offset: 4px; border-radius: 4px; }
.mp-bars { position: absolute; inset: 0; display: flex; align-items: flex-end; gap: 1px; }
.mp-bar { flex: 1; width: 100%; border-radius: 2px 2px 0 0; background: #E4E4E1; }
.mp-bar.in { background: #4f4c47; }
/* every system, two columns; the ones the budget covers are dark and sit on a light chip */
.mp-list { list-style: none; margin: 10px 0 0; padding: 0; display: grid; grid-template-columns: 1fr 1fr; gap: 3px 10px; }
.mp-row {
  display: flex; align-items: center; gap: 7px; min-width: 0;
  padding: 2px 7px; border-radius: 7px;
  font-size: .72rem; line-height: 1.25; color: #aeaeab;
  transition: color .25s ease, background-color .25s ease;
}
.mp-dot { flex: none; width: 7px; height: 7px; border-radius: 50%; border: 1.5px solid #cfcfcc; transition: background-color .25s ease, border-color .25s ease, transform .25s ease; }
.mp-name { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mp-price { flex: none; white-space: nowrap; font-variant-numeric: tabular-nums; }
.mp-price i { font-style: normal; opacity: .75; }
.mp-row.on { color: #3A3833; background: #F1F1EF; }
.mp-row.on .mp-dot { background: #4f4c47; border-color: #4f4c47; }
.mp-row-open.on .mp-price { opacity: 1; }
.mp-row.pop { animation: mp-pop .7s cubic-bezier(.22, 1, .36, 1); }
.mp-row.pop .mp-dot { animation: mp-dot .7s cubic-bezier(.22, 1, .36, 1); }
@keyframes mp-pop { 0% { background: #D6D6D3; transform: translateX(-5px); } 100% { background: #F1F1EF; transform: none; } }
@keyframes mp-dot { 0% { transform: scale(2); } 100% { transform: scale(1); } }
.mp-note { margin-top: 7px; font-size: .7rem; line-height: 1.3; color: #8d8d92; }
@media (prefers-reduced-motion: reduce) { .mp-row.pop, .mp-row.pop .mp-dot { animation: none; } }
/* Right side: two placeholder frames, rotated about their top-left corner to match the
   reference: A leans ~1.7deg, B's top edge rises ~10deg to the right. */
.ms-right { position: absolute; inset: 0; pointer-events: none; }
.ms-frame {
  position: absolute;
  overflow: hidden;
  pointer-events: auto;
  transform-origin: 0 0;
}
.ms-frame-a {
  left: calc(68.44% - 5px);
  top: calc(10.82vw - 98px);
  width: 37.9vw;
  height: calc(37.9vw / 1.5); /* top.jpg is 3:2, so the whole photo fits with its corners on the frame's corners */
  border-radius: 1.3vw;
  background: linear-gradient(150deg, #2b3a2e 0%, #1a241d 100%);
  transform: rotate(3.7deg);
  /* measured from the reference: a wide, soft shadow thrown down and to the left, none above */
  box-shadow: -1.55vw 1.7vw 5.4vw rgba(20, 19, 17, .42), -.5vw .85vw 9vw rgba(20, 19, 17, .10);
  display: flex;
  align-items: center;
  justify-content: center;
}
.ms-frame-b {
  left: calc(66.8% - 10px);
  top: calc(51.3vw - 178px);
  width: calc(24.8vw + 10px);
  height: calc((24.8vw + 10px) / 1.4244); /* bottom.jpg is 2994x2102, same idea */
  border-radius: 1.3vw;
  background: #2a2a2c;
  transform: rotate(-8deg);
  box-shadow: -1.1vw 1.3vw 3.3vw rgba(20, 19, 17, .45), -.4vw .7vw 6vw rgba(20, 19, 17, .10);
}
/* Picture layer inside each frame. Same hover as the menu's picture frames:
   1.05 zoom over .5s, clipped by the frame. Swap the background for a real image later. */
.ms-img {
  position: absolute;
  inset: 0;
  background-size: cover;
  background-position: center;
}
.ms-img-a { background-image: url('../images/cta/top.jpg'); background-color: #1a241d; }
.ms-img-b { background-image: url('../images/cta/bottom.jpg'); background-color: #2a2a2c; }
.ms-frame-glyph { position: relative; color: rgba(255, 255, 255, .22); }
.ms-frame-glyph svg { width: 56px; height: 56px; }
@media (prefers-reduced-motion: reduce) {
  .ms-img, .ms-frame:hover .ms-img { transition: none; transform: none; }
}

@media (max-width: 900px) {
  .ms-right { display: none; }
  .ms-inner { min-height: 0; }
  .ms-success { inset: 0; }
  .menu-showcase { padding: 80px 0 40px; }
  .ms-left { width: auto; min-width: 0; margin: 0 24px; zoom: 1; }
  .ms-list { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 560px) {
  .ms-list { grid-template-columns: 1fr; grid-auto-flow: row; grid-template-rows: none; }
}

/* ---------- Final CTA (full-width section, no floating card) ---------- */
.final-cta-section { padding: 200px 0 240px; }
.final-cta-inner {
  text-align: center;
  max-width: 680px;
  margin: 0 auto;
}
.final-cta-inner h2 { margin-bottom: 20px; }
.final-cta-inner > p {
  color: var(--muted);
  font-size: 1.125rem;
  max-width: 540px;
  margin: 0 auto 44px;
}
.final-cta-note {
  font-family: var(--font-mono);
  font-size: 0.78125rem;
  color: var(--muted);
  margin: 24px 0 0;
}

/* ---------- Industry cards (Services page) ---------- */
.ind-cards {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 28px;
  margin-top: 72px;
}
.ind-card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 28px;
  padding: 60px 52px;
  transition: box-shadow .3s var(--ease-out), transform .3s var(--ease-out);
}
.ind-card:hover {
  box-shadow: 0 2px 4px rgba(20,19,17,.04), 0 24px 56px rgba(20,19,17,.09);
  transform: translateY(-3px);
}
.ind-card .ind-icon {
  width: 56px; height: 56px;
  display: flex; align-items: center; justify-content: center;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 16px;
  margin-bottom: 32px;
}
.ind-card .ind-icon svg { width: 26px; height: 26px; stroke: var(--ink); }
.ind-card h3 {
  font-size: 1.75rem;
  font-weight: 500;
  letter-spacing: -0.025em;
  margin-bottom: 10px;
}
.ind-card .ind-for {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--muted);
  margin-bottom: 24px;
}
.ind-card p {
  color: var(--muted);
  line-height: 1.75;
}
@media (max-width: 800px) {
  .ind-cards { grid-template-columns: 1fr; }
  .ind-card { padding: 44px 36px; }
}

/* ---------- Footer ---------- */
footer {
  background: #131110;
  color: #979288;
  padding: 120px 0 0;
  margin-top: 0;
  overflow: hidden;
}

/* ── Footer layout: brand left, link columns right ── */
.footer-top {
  display: flex;
  gap: 80px;
  padding-bottom: 48px;
}
.footer-brand {
  flex: 0 0 280px;
}
.footer-logo {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1.375rem;
  color: #fff;
  letter-spacing: -0.02em;
  margin-bottom: 16px;
  display: block;
}
.footer-tagline {
  font-size: 0.9375rem;
  line-height: 1.6;
  color: #97938B;
  margin-bottom: 28px;
  max-width: 260px;
}
.footer-social {
  display: flex;
  gap: 16px;
}
.footer-social a {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  color: #6B6760;
  transition: color .2s;
}
.footer-social a:hover { color: #fff; }
.footer-social svg { width: 18px; height: 18px; }

.footer-links {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 48px;
  flex: 1;
}

.footer-col h4 {
  color: #fff; font-size: 0.75rem; font-family: var(--font-mono); font-weight: 500;
  text-transform: uppercase; letter-spacing: 0.14em; margin-bottom: 22px;
}
.footer-col ul { list-style: none; }
.footer-col li { margin-bottom: 12px; }
.footer-col a, .footer-col span { font-size: 0.9375rem; transition: color .2s; color: #97938B; }
.footer-col a:hover { color: #fff; }

.footer-wordmark {
  font-family: var(--font-display);
  font-weight: 600;
  letter-spacing: -0.03em;
  color: #fff;
  text-align: center;
  line-height: 0.8;
  font-size: clamp(4.5rem, 15vw, 11.5rem);
  margin: 0 -32px;
  user-select: none;
  background: linear-gradient(180deg, #fff 0%, rgba(255,255,255,.35) 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}

.footer-bottom {
  display: flex; justify-content: space-between; align-items: center;
  padding: 36px 0 48px;
  margin-top: 32px;
  border-top: 1px solid rgba(255,255,255,.08);
  font-size: 0.75rem;
  font-family: var(--font-mono);
  color: #6B6760;
}
.footer-legal { display: flex; gap: 24px; align-items: center; }
.footer-legal a { color: #6B6760; transition: color .2s; }
.footer-legal a:hover { color: #A3A099; }
.footer-btt { display: inline-flex; align-items: center; gap: 6px; }
.footer-btt svg { width: 12px; height: 12px; }

/* Footer hills (Home + Services): light footer with dark terrain animation.
   All overrides scoped to .footer-has-hills so dark footer is untouched. */
.footer-has-hills { position: relative; background: var(--bg); color: var(--ink-soft); padding-top: 0; padding-bottom: 0; margin-top: 0; }
#footer-hills {
  position: absolute;
  left: 0; right: 0; top: 0; bottom: -80px;
  width: 100%;
  z-index: 0;
  pointer-events: none;
  /* Drop the terrain 40px so the top text (brand, social, link columns)
     keeps clear air above the rising peaks. The wordmark is unaffected. */
  transform: translateY(40px);
}
.footer-has-hills .container { position: relative; z-index: 1; }
.footer-has-hills .footer-logo { color: var(--ink); }
.footer-has-hills .footer-tagline { color: var(--muted); }
.footer-has-hills .footer-social a { color: var(--muted); }
.footer-has-hills .footer-social a:hover { color: var(--ink); }
.footer-has-hills .footer-col h4 { color: var(--ink); }
.footer-has-hills .footer-col a,
.footer-has-hills .footer-col span { color: var(--ink-soft); }
.footer-has-hills .footer-col a:hover { color: var(--ink); }
.footer-has-hills .footer-wordmark {
  position: relative; z-index: 2;
  color: #3D3A35;
  background: linear-gradient(180deg, #3D3A35 0%, rgba(61,58,53,.18) 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  margin: -8px -32px 0; line-height: 0.8;
}
.footer-has-hills .footer-bottom {
  border-top: 1px solid rgba(20,19,17,.10);
  color: var(--muted);
  padding: 28px 0 30px;
  margin-top: 24px;
}
.footer-has-hills .footer-legal a { color: var(--muted); }
.footer-has-hills .footer-legal a:hover { color: var(--ink); }
.footer-has-hills .footer-btt { color: var(--muted); }
.footer-has-hills .footer-btt:hover { color: var(--ink); }

/* ============================================================
   Cinematic curtain footer — HOME ONLY
   The footer is position:fixed and clipped to .cine-reveal, so as you
   reach the end of the page the content above slides up and off it like
   a curtain, uncovering the footer that was sitting still underneath.
   scripts/footer-cine.js drives the wordmark drift + content fade.
   ============================================================ */
.cine-reveal {
  position: relative;
  z-index: 1;                 /* above the fixed dot field (z:0) */
  /* scroll runway that uncovers the footer. ~1 screen opens the curtain,
     the extra ~1/4 screen lets the angled seam strip travel up and off
     before you hit the very bottom. */
  height: 124vh;
  /* clip-path clips the fixed child to this box WITHOUT making it the
     containing block — so the footer stays pinned to the viewport while
     this window grows. This is what produces the wipe. The angled top
     edge (7vw drop left-to-right ≈ 4°, matching the seam strip's tilt)
     makes the grey→black boundary a diagonal instead of a flat line, and
     trims the strip to clean vertical edges at the screen sides. */
  clip-path: polygon(0 5vw, 100% 0, 100% 100%, 0 100%);
  -webkit-clip-path: polygon(0 5vw, 100% 0, 100% 100%, 0 100%);
}

/* Angled marquee strip — the moving seam of the curtain reveal.
   A normal in-flow child pinned to the top of .cine-reveal, so it rides
   up with the outgoing page as the black footer is uncovered behind it,
   then clips away at the screen edges once you reach the bottom. Charcoal:
   a step down in tone from the grey dotted page toward the black footer. */
.cine-seam {
  position: relative;
  z-index: 3;
  width: 118%;
  margin-left: -9%;
  /* dropped just below the angled clip edge (≈ half the 7vw clip drop),
     so the whole strip — text and all — sits fully visible under the
     diagonal grey→black boundary, none of it clipped. `top` (not margin)
     avoids margin-collapse through .cine-reveal. */
  top: 1.9vw;
  padding: 27px 0 18px;
  overflow: hidden;
  transform: rotate(-3deg);
  background: #201E2C;
  border-top: 3px solid #000;
  border-bottom: 2px solid #F5F2EA;
  box-shadow: 0 26px 44px -14px rgba(0,0,0,.55);
}
.cine-seam-track {
  display: flex;
  align-items: center;
  width: max-content;
  font-family: var(--font-mono);
  font-size: .875rem;
  font-weight: 500;
  line-height: 1;
  letter-spacing: .3em;
  text-transform: uppercase;
  white-space: nowrap;
  color: #F5F2EA;
  will-change: transform;
  animation: cine-seam-scroll 32s linear infinite;
}
.cine-seam-track span { padding: 0 26px; }
.cine-seam-track i {
  font-style: normal;
  font-size: .7em;
  color: rgba(245,242,234,.5);
  transform: translateY(-.06em);
}
@keyframes cine-seam-scroll {
  from { transform: translateX(0); }
  to   { transform: translateX(-25%); }   /* track holds 4 identical copies */
}
.cine-footer {
  position: fixed;
  inset: 0;
  z-index: 1;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  overflow: hidden;
  background: #0E0D0C;
  color: #8B877E;
  isolation: isolate;
}

/* faint square grid, masked to fade top + bottom */
.cine-grid {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-size: 58px 58px;
  background-image:
    linear-gradient(to right, rgba(255,255,255,.035) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(255,255,255,.035) 1px, transparent 1px);
  -webkit-mask-image: linear-gradient(to bottom, transparent, #000 32%, #000 74%, transparent);
  mask-image: linear-gradient(to bottom, transparent, #000 32%, #000 74%, transparent);
}

/* slow breathing glow, brand-tinted, very low intensity */
.cine-glow {
  position: absolute;
  left: 50%;
  top: 44%;
  width: 76vw;
  height: 50vh;
  transform: translate(-50%, -50%);
  z-index: 0;
  pointer-events: none;
  border-radius: 50%;
  filter: blur(90px);
  background: radial-gradient(circle at 50% 50%,
    rgba(255,255,255,.09) 0%, rgba(255,255,255,.03) 42%, transparent 70%);
  animation: cine-breathe 9s ease-in-out infinite alternate;
}
@keyframes cine-breathe {
  from { opacity: .5;  transform: translate(-50%, -50%) scale(1); }
  to   { opacity: 1;   transform: translate(-50%, -50%) scale(1.12); }
}

/* giant background wordmark — JS drifts it up as the curtain opens */
.cine-word {
  position: absolute;
  left: 50%;
  bottom: -0.14em;
  z-index: 1;
  transform: translateX(-50%);
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 25vw;
  line-height: .75;
  letter-spacing: -.045em;
  white-space: nowrap;
  user-select: none;
  pointer-events: none;
  background: linear-gradient(180deg, rgba(255,255,255,.14) 0%, rgba(255,255,255,0) 60%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  -webkit-text-stroke: 1px rgba(255,255,255,.05);
}

.cine-inner {
  position: relative;
  z-index: 2;
  width: 100%;
  max-width: var(--container);
  margin: 0 auto;
  /* 74px bottom = 44 + 30, lifts the whole text block clear of the giant
     VERION wordmark sitting at the base of the footer */
  padding: 0 32px calc(min(26vh, 260px) + 80px);
}

.cine-top {
  display: flex;
  gap: 80px;
  padding-bottom: 40px;
}
.cine-brand { flex: 0 0 300px; }
.cine-footer .cine-logo {
  display: block;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1.375rem;
  letter-spacing: -.02em;
  color: #fff;
  margin-bottom: 16px;
}
.cine-footer .cine-tagline {
  font-size: .9375rem;
  line-height: 1.6;
  color: #8B877E;
  max-width: 270px;
}

.cine-social { display: flex; gap: 12px; margin-top: 26px; }
.cine-social a,
.cine-btt {
  width: 42px;
  height: 42px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 999px;
  color: #A7A399;
  background: linear-gradient(145deg, rgba(255,255,255,.05), rgba(255,255,255,.015));
  border: 1px solid rgba(255,255,255,.08);
  box-shadow: inset 0 1px 1px rgba(255,255,255,.06), 0 10px 30px -12px rgba(0,0,0,.6);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  transition: color .3s var(--ease-out), border-color .3s var(--ease-out),
              background .3s var(--ease-out), transform .4s cubic-bezier(.16,1,.3,1);
}
.cine-social a:hover,
.cine-btt:hover {
  color: #fff;
  border-color: rgba(255,255,255,.22);
  background: linear-gradient(145deg, rgba(255,255,255,.10), rgba(255,255,255,.03));
}
.cine-social svg { width: 17px; height: 17px; }
.cine-btt { cursor: pointer; }
.cine-btt svg { width: 16px; height: 16px; }

.cine-cols {
  flex: 1;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 48px;
}
.cine-col h4 {
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: .75rem;
  text-transform: uppercase;
  letter-spacing: .14em;
  color: #fff;
  margin-bottom: 20px;
}
.cine-col ul { list-style: none; }
.cine-col li { margin-bottom: 12px; }
.cine-col a {
  font-size: .9375rem;
  color: #8B877E;
  transition: color .2s;
}
.cine-col a:hover { color: #fff; }

.cine-bottom {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 20px;
  padding-top: 56px;
  border-top: 1px solid rgba(255,255,255,.08);
  font-family: var(--font-mono);
  font-size: .75rem;
  color: #8B877E;
}
.cine-legal { display: flex; gap: 22px; align-items: center; }
.cine-legal a { color: #8B877E; transition: color .2s; }
.cine-legal a:hover { color: #fff; }

/* current-page indicator in the footer — same slot as the link it replaces,
   just not clickable and dimmed so it reads as "you're already here". */
.cine-self { color: #8B877E; opacity: .5; }
.cine-col .cine-self { font-size: .9375rem; }

/* content fades up once the curtain is mostly open. The hidden start state
   only applies after footer-cine.js has armed it (.cine-armed) and before
   it fires (.is-revealed) — so with no JS the footer just shows normally. */
.cine-fade {
  transition: opacity .8s var(--ease-out), transform .8s var(--ease-out);
}
.cine-footer.cine-armed:not(.is-revealed) .cine-fade {
  opacity: 0;
  transform: translateY(26px);
}

@media (max-width: 860px) {
  .cine-top { flex-direction: column; gap: 44px; }
  .cine-brand { flex: none; }
  .cine-cols { gap: 32px; }
  .cine-word { font-size: 34vw; }
}
@media (max-width: 560px) {
  .cine-cols { grid-template-columns: 1fr 1fr; }
  .cine-bottom { flex-direction: column; align-items: flex-start; gap: 14px; }
  .cine-inner { padding-bottom: 56px; }
  .cine-seam-track { font-size: .6875rem; letter-spacing: .24em; }
  .cine-seam-track span { padding: 0 18px; }
}
/* short viewports: drop the curtain, let the footer sit in normal flow so
   nothing gets clipped off the bottom */
@media (max-height: 640px) {
  .cine-reveal { height: auto; clip-path: none; -webkit-clip-path: none; }
  .cine-footer { position: relative; inset: auto; }
}

@media (prefers-reduced-motion: reduce) {
  .cine-glow { animation: none; }
  .cine-seam-track { animation: none; }
  .cine-fade { opacity: 1; transform: none; transition: none; }
}

/* ---------- Page hero (inner pages) ---------- */
.page-hero { padding: 220px 0 100px; position: relative; overflow: hidden; }
.page-hero .hero-bg { opacity: .8; }
.page-hero h1 { font-size: clamp(2.9rem, 4.4vw, 4rem); margin-bottom: 24px; max-width: 780px; }
.page-hero .lede { font-size: 1.1875rem; color: var(--muted); max-width: 600px; }

/* ---------- Forms ---------- */
.field { margin-bottom: 24px; }
.field label {
  display: block;
  font-size: 0.9375rem; font-weight: 700;
  color: var(--ink);
  margin-bottom: 9px;
  letter-spacing: -0.01em;
}
.field input, .field textarea, .field select {
  width: 100%;
  font-family: var(--font-body);
  font-size: 1rem;
  color: var(--ink);
  padding: 15px 18px;
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-input);
  transition: border-color .2s, box-shadow .2s;
}
.field input:focus, .field textarea:focus, .field select:focus {
  outline: none;
  border-color: var(--brand);
  box-shadow: 0 0 0 4px rgba(20,19,17,.14);
}
.field input::placeholder, .field textarea::placeholder { color: #A6A3BF; }
.field .field-error, .bk-content > .field-error { display: none; font-size: 0.8125rem; color: var(--error); margin-top: 7px; }
.field.invalid input, .field.invalid textarea { border-color: var(--error); }
.field.invalid .field-error { display: block; }

/* ---------- Booking wizard ----------
   Rebuilt full-frame 2026-09-12 (no boxed card - see booking.html's own
   <style> block for the .bk-frame/.bk-stage/.bk-progress-track layout
   that replaced the old .booking-shell/.booking-body card). Only the
   parts still actually used by that markup live here now. */

.bk-step { display: none; flex: 1; flex-direction: column; }
.bk-step.active { display: flex; animation: step-in .55s cubic-bezier(.16, 1, .3, 1); }
.bk-step.active .bk-count { animation: step-child .5s cubic-bezier(.16, 1, .3, 1) .05s both; }
.bk-step.active h2 { animation: step-child .5s cubic-bezier(.16, 1, .3, 1) .12s both; }
.bk-step.active .bk-hint { animation: step-child .5s cubic-bezier(.16, 1, .3, 1) .18s both; }
.bk-step.active .bk-content { animation: step-child .5s cubic-bezier(.16, 1, .3, 1) .24s both; }
@keyframes step-in {
  from { opacity: 0; }
  to { opacity: 1; }
}
@keyframes step-child {
  from { opacity: 0; transform: translateY(20px); filter: blur(3px); }
  to { opacity: 1; transform: none; filter: blur(0); }
}
.bk-count {
  font-family: var(--font-mono);
  font-size: 0.75rem; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 16px;
}
.bk-step h2 { font-size: 1.875rem; margin-bottom: 10px; }
.bk-step .bk-hint { font-size: 0.9875rem; color: var(--muted); margin-bottom: 34px; }
.bk-step .bk-content { flex: 1; }

.choice-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.choice {
  display: flex; align-items: center; gap: 14px;
  padding: 18px 20px;
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: 14px;
  cursor: pointer;
  font-family: var(--font-body);
  font-size: 0.9875rem; font-weight: 500;
  color: var(--ink);
  text-align: left;
  transition: border-color .2s, background-color .2s, box-shadow .25s cubic-bezier(.16,1,.3,1), transform .25s cubic-bezier(.16,1,.3,1);
  width: 100%;
  position: relative;
}
.choice svg { width: 21px; height: 21px; stroke: var(--muted); flex-shrink: 0; transition: stroke .2s; }
.choice:hover {
  border-color: var(--brand);
  box-shadow: 0 2px 8px rgba(20,19,17,.1);
  transform: translateY(-1px);
}
.choice:active { transform: translateY(0); transition-duration: .08s; }
.choice.selected {
  border-color: var(--brand);
  background: var(--brand-ghost);
  box-shadow: 0 0 0 1.5px var(--brand), 0 2px 8px rgba(20,19,17,.08);
  font-weight: 600;
}
.choice.selected svg { stroke: var(--brand); }
/* Check indicator on selected */
.choice.selected::after {
  content: '';
  position: absolute;
  top: 10px; right: 12px;
  width: 18px; height: 18px;
  background: var(--brand);
  border-radius: 50%;
  background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='3' stroke-linecap='round' stroke-linejoin='round' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E");
  background-size: 12px;
  background-position: center;
  background-repeat: no-repeat;
  animation: check-pop .3s cubic-bezier(.16,1,.3,1);
}
@keyframes check-pop {
  from { transform: scale(0); opacity: 0; }
  to { transform: scale(1); opacity: 1; }
}

.bk-nav {
  display: flex; justify-content: space-between; align-items: center;
  margin-top: 44px; padding-top: 28px;
  border-top: 1px solid var(--line);
}
.bk-back {
  display: inline-flex; align-items: center; gap: 8px;
  background: none; border: none;
  font-family: var(--font-body); font-size: 0.9375rem; font-weight: 700;
  color: var(--muted); cursor: pointer;
  padding: 10px 14px; border-radius: var(--r-pill);
  transition: color .2s, background-color .2s;
}
.bk-back:hover { color: var(--ink); background: var(--bg-soft); }
.bk-back svg { width: 15px; height: 15px; }
.bk-key-hint { font-family: var(--font-mono); font-size: 0.71875rem; color: #A6A3BF; }
.bk-key-hint kbd {
  font-family: inherit;
  background: var(--bg-soft);
  border: 1px solid var(--line-strong);
  border-radius: 5px;
  padding: 2px 7px;
}

/* "Other" inline reveal */
.other-reveal { display: none; margin-top: 16px; }
.other-reveal.visible { display: block; animation: step-in .35s var(--ease-out); }
.other-reveal .field { margin-bottom: 0; }

/* Compact chip grid (software step) */
.choice-grid.compact { grid-template-columns: repeat(3, 1fr); gap: 10px; }
.choice-grid.compact .choice { padding: 13px 15px; font-size: 0.9rem; gap: 10px; justify-content: center; text-align: center; }

/* Phone with country code */
.phone-row { display: grid; grid-template-columns: 190px 1fr; gap: 10px; }
.phone-row select {
  font-family: var(--font-body);
  font-size: 0.9375rem;
  color: var(--ink);
  padding: 15px 12px;
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-input);
  cursor: pointer;
  transition: border-color .2s, box-shadow .2s;
}
.phone-row select:focus {
  outline: none;
  border-color: var(--brand);
  box-shadow: 0 0 0 4px rgba(20,19,17,.14);
}

/* Scheduler: month calendar + time panel */
.scheduler { display: grid; grid-template-columns: 1.15fr 0.85fr; gap: 28px; align-items: start; }
.cal {
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 18px;
  padding: 22px;
}
.cal-head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 16px; }
.cal-title { font-weight: 700; color: var(--ink); font-size: 1.0625rem; letter-spacing: -0.015em; }
.cal-nav { display: flex; gap: 6px; }
.cal-nav button {
  width: 36px; height: 36px;
  display: flex; align-items: center; justify-content: center;
  border: 1px solid var(--line-strong);
  background: var(--surface);
  border-radius: 10px;
  cursor: pointer;
  transition: border-color .2s, color .2s, background-color .2s;
}
.cal-nav button svg { width: 15px; height: 15px; stroke: var(--ink-soft); transition: stroke .2s; }
.cal-nav button:hover:not(:disabled) { border-color: var(--brand); }
.cal-nav button:hover:not(:disabled) svg { stroke: var(--brand); }
.cal-nav button:disabled { opacity: .35; cursor: default; }
.cal-dow {
  display: grid; grid-template-columns: repeat(7, 1fr);
  text-align: center;
  font-family: var(--font-mono);
  font-size: 0.625rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--muted);
  margin-bottom: 8px;
}
.cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 4px; }
.cal-day {
  aspect-ratio: 1;
  border: none;
  background: none;
  border-radius: 11px;
  font-family: var(--font-body);
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--ink);
  cursor: pointer;
  transition: background-color .18s, color .18s;
}
.cal-day:hover:not(:disabled):not(.selected) { background: var(--brand-soft); color: var(--brand); }
.cal-day:disabled { color: #C6C3DC; cursor: default; }
.cal-day.today { box-shadow: inset 0 0 0 1px var(--line-strong); }
.cal-day.selected { background: var(--brand); color: #fff; font-weight: 700; }
.cal-day.empty { visibility: hidden; }

.times-panel { min-height: 340px; display: flex; flex-direction: column; }
.times-date {
  font-size: 0.9375rem; font-weight: 700;
  color: var(--ink); letter-spacing: -0.01em;
  margin-bottom: 12px;
}
.times-list {
  display: flex; flex-direction: column; gap: 8px;
  max-height: 300px;
  overflow-y: auto;
  padding-right: 4px;
  animation: step-in .35s var(--ease-out);
}
.times-empty {
  flex: 1;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 12px;
  color: var(--muted);
  font-size: 0.9375rem;
  text-align: center;
  border: 1px dashed var(--line-strong);
  border-radius: 18px;
  padding: 24px;
}
.times-empty svg { width: 26px; height: 26px; stroke: #B4B1CB; }

/* Legacy slot picker (kept for time buttons reuse) */
.slot-times { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; }
.slot-time {
  border: 1px solid var(--line-strong);
  background: var(--surface);
  border-radius: 11px;
  padding: 13px 8px;
  font-family: var(--font-mono);
  font-size: 0.875rem;
  color: var(--ink);
  cursor: pointer;
  text-align: center;
  transition: border-color .2s, background-color .2s;
}
.slot-time:hover { border-color: var(--brand); }
.slot-time.selected { border-color: var(--brand); background: var(--brand); color: #fff; }

/* Booking success */
.bk-success { text-align: center; padding: 24px 0; }
.bk-success .success-icon {
  width: 76px; height: 76px;
  margin: 0 auto 30px;
  display: flex; align-items: center; justify-content: center;
  background: var(--success-soft);
  border-radius: 50%;
}
.bk-success .success-icon svg { width: 36px; height: 36px; stroke: var(--success); }
.bk-success h2 { margin-bottom: 12px; }
.bk-success p { color: var(--muted); max-width: 420px; margin: 0 auto 32px; }
.bk-summary {
  text-align: left;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 16px;
  padding: 26px 30px;
  margin-bottom: 32px;
}
.bk-summary .row {
  display: flex; justify-content: space-between; gap: 24px;
  padding: 9px 0;
  font-size: 0.9375rem;
  border-bottom: 1px solid var(--line);
}
.bk-summary .row:last-child { border-bottom: none; }
.bk-summary .row span { color: var(--muted); }
.bk-summary .row strong { color: var(--ink); text-align: right; }

/* ---------- Reveal on scroll (restrained: headers & panels only) ---------- */
.reveal {
  opacity: 0;
  transform: translateY(32px);
  filter: blur(4px);
  transition:
    opacity .7s cubic-bezier(.16, 1, .3, 1),
    transform .7s cubic-bezier(.16, 1, .3, 1),
    filter  .8s cubic-bezier(.16, 1, .3, 1);
  transition-delay: var(--rd, 0s);
  will-change: opacity, transform;
}
.reveal.in { opacity: 1; transform: none; filter: blur(0); }

/* Reveals inside a scroll-hold section: pure opacity fade, no movement and
   no blur. The whole group fires when the section hits the viewport midpoint,
   then each element cascades via its --rd stagger delay — same approach as
   the services page. Slightly slower (.55s) to match the 7-circles timing. */
.s-pin .reveal,
.s-pin .reveal-soft {
  transform: none;
  filter: none;
  transition: opacity .85s cubic-bezier(.16, 1, .3, 1);
  transition-delay: var(--rd, 0s);
}

/* Homepage hold sections (the-phone/the-laptop/the-automation) only: ported
   1:1 from a 21st.dev reference component's ".reveal-step" (opacity-0
   translate-y-12 transition-all duration-1000 ease-out, [&.active] flips
   both) - only the text content itself is Verion's. main.js toggles
   .th-active as a continuous scroll-progress value crosses each group's
   own checkpoint - see the "Smooth scroll-hold" block. Because it's a
   plain class + CSS transition (not a hand-computed inline style), the
   browser handles direction changes and interruptions on its own:
   scrolling up reverses the exact same transition instead of needing a
   separate hand-built mirror. */
.s-pin .th-step {
  opacity: 0;
  transform: translateY(48px);
  transition: opacity .4s ease-out, transform .4s ease-out;
}
.s-pin .th-step.th-active {
  opacity: 1;
  transform: none;
}

/* ---------- Hero headline: word-by-word rise ---------- */
.split-words .w {
  display: inline-block;
  overflow: hidden;
  vertical-align: bottom;
  /* keep descenders un-clipped inside the mask */
  padding-bottom: .14em;
  margin-bottom: -.14em;
  /* italic serif "punch words" lean past their box — give the clip
     mask side room so the first/last letters aren't shaved off.
     Negative margins keep the layout position unchanged. */
  padding-left: .12em;
  margin-left: -.12em;
  padding-right: .12em;
  margin-right: -.12em;
}
.split-words .w > span {
  display: inline-block;
  transform: translateY(112%);
  transition: transform .85s var(--ease-out);
}
.split-words.in .w > span { transform: none; }

/* ---------- Eyebrow rule draws itself in ---------- */
.eyebrow::before { width: 0; transition: width .7s var(--ease-out) .15s; }
.eyebrow.in::before, .in .eyebrow::before { width: 22px; }
.section-head.center .eyebrow::after { width: 0; transition: width .7s var(--ease-out) .15s; }
.section-head.center.in .eyebrow::after { width: 22px; }

/* ---------- Cursor spotlight on cards ---------- */
.card::after, .step::after, .industry-card::after, .sb-visual::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: radial-gradient(240px circle at var(--mx, 50%) var(--my, 50%), rgba(20,19,17,.09), transparent 68%);
  opacity: 0;
  transition: opacity .35s var(--ease-out);
  pointer-events: none;
}
.card, .step, .sb-visual { position: relative; }
.card:hover::after, .step:hover::after, .industry-card:hover::after, .sb-visual:hover::after { opacity: 1; }

/* ---------- Inertial scroll (Lenis) ---------- */
/* Lenis owns the root className, so target its own class (plus our init hook) */
html.lenis, html.lenis-active { scroll-behavior: auto !important; }
/* cards get a whisper, not a march */
.reveal-soft {
  opacity: 0;
  transform: translateY(18px);
  transition:
    opacity .6s cubic-bezier(.16, 1, .3, 1),
    transform .6s cubic-bezier(.16, 1, .3, 1);
  transition-delay: var(--rd, 0s);
  will-change: opacity, transform;
}
.reveal-soft.in { opacity: 1; transform: none; }

/* ---------- Icon micro-gestures ---------- */
.card .card-icon svg, .step .step-num, .industry-card .card-icon svg {
  transition: transform .25s var(--ease-out);
}
.card:hover .card-icon svg { transform: rotate(-6deg) translateY(-1px); }
.industry-card:hover .card-icon svg { transform: translateY(-2px); }

/* ---------- Section rhythm utilities ---------- */
.s-roomy { padding: 140px 0; }

/* ---------- Scroll-hold pin system ----------
   Wraps a section in an extended-scroll wrapper: the section sticks to the
   viewport for a full screen of extra scroll before it releases and the next
   section arrives. This is the frame a background video will play inside.
   The section itself sits vertically centred inside the sticky, so nothing
   overflows and the composition holds still while the video runs. */
.s-pin {
  position: relative;
  height: 190vh;      /* pin length: ~90vh of dwell after natural entry */
  /* breathing room between pinned sections so one doesn't butt against
     the next - the previous pin releases, then a clear gap, then the
     next section enters. */
  margin-bottom: 120px;
}
.s-pin:last-of-type {
  margin-bottom: 160px;
}
.s-hold {
  position: sticky;
  top: 0;
  height: 100vh;
  display: flex;
  align-items: flex-start;   /* title stays visible at the top of the hold */
  overflow: hidden;
}
.s-hold > section {
  width: 100%;
  padding: 90px 0 0;  /* breathing room from the viewport top */
  margin: 0;
  /* Scroll-driven deceleration: JS continuously updates translateY as the
     section approaches its sticky position, creating a visible slow-down
     instead of an abrupt stop. No CSS transition needed — the scroll
     itself is the animation. */
}
.s-mid   { padding: 160px 0; }
.s-tight { padding: 72px 0; }
.s-flush-top { padding-top: 0; }

/* ---------- Section handoff line ---------- */
.handoff {
  font-family: var(--font-mono);
  font-size: 0.78125rem;
  letter-spacing: 0.08em;
  color: var(--muted);
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: 64px;
}
.handoff::before { content: ''; width: 34px; height: 1px; background: var(--line-strong); }
.handoff svg { width: 14px; height: 14px; stroke: var(--brand); }

/* ---------- Flow line (homepage signature) ---------- */
.flow-wrap { position: relative; }
.flow-svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  z-index: 0;
}
.flow-svg path {
  fill: none;
  stroke: var(--brand);
  stroke-width: 1.5;
  stroke-linecap: round;
  opacity: .3;
}
.flow-wrap > section, .flow-wrap > div { position: relative; z-index: 1; }

/* ---------- Hero tilt ---------- */
.ecosystem { transition: transform .1s linear; will-change: transform; }

/* ---------- Utilities ---------- */
.mt-16 { margin-top: 16px; } .mt-24 { margin-top: 24px; } .mt-40 { margin-top: 40px; }
.mt-64 { margin-top: 64px; } .mt-96 { margin-top: 96px; }
.center { text-align: center; }

/* ---------- Founder (5 static boxes; image boxes + copy are placeholders) ---------- */
.founder { position: relative; padding: 200px 0; font-family: 'Switzer', 'Satoshi', var(--font-body); }

/* Entrance (scripts/founder-reveal.js arms it, so nothing hides if the script fails).
   Opacity + a short rise on the wrapper, strong ease-out so it lands fast and settles
   softly. The boxes cascade 70ms apart within each row. */
.fdr-armed .fdr-rv {
  opacity: 0;
  transform: translate3d(0, 26px, 0);
  transition:
    opacity .55s cubic-bezier(.16, 1, .3, 1),
    transform .8s cubic-bezier(.16, 1, .3, 1);
  transition-delay: var(--fd, 0s);
  will-change: opacity, transform;
}
.fdr-armed .fdr-rv.is-in {
  opacity: 1;
  transform: none;
}
.fdr-armed .lg-cell:nth-child(2), .fdr-armed .lg-cell:nth-child(5) { --fd: .07s; }
.fdr-armed .lg-cell:nth-child(3) { --fd: .14s; }
@media (prefers-reduced-motion: reduce) {
  .fdr-armed .fdr-rv { transform: none; transition: opacity .3s ease; transition-delay: 0s; }
}
.fdr-head { max-width: 640px; margin: 0 auto 96px; text-align: center; }
.fdr-title {
  font-family: inherit;
  font-size: clamp(2rem, 3.4vw, 2.5rem);
  line-height: 1.15;
  font-weight: 500;
  letter-spacing: -0.03em;
  color: var(--ink);
  margin: 0 0 20px;
}
.fdr-sub {
  font-family: inherit;
  font-size: 1rem;
  line-height: 1.55;
  color: var(--muted);
  max-width: 460px;
  margin: 0 auto;
  text-wrap: balance;
}

/* Row 1: 5 / 5 / 10 of 20 cols. Row 2: 14 / 6. */
.lg-grid {
  display: grid;
  grid-template-columns: repeat(20, 1fr);
  grid-auto-rows: clamp(280px, 39vh, 370px);
  gap: 16px;
  max-width: 1160px;
  margin: 0 auto;
}
@media (min-width: 1280px) {
  .lg-grid { max-width: none; margin-left: -40px; margin-right: -40px; }
}
.lg-cell { min-width: 0; grid-column: span 5; }
.lg-span-2 { grid-column: span 10; }
.lg-span-3 { grid-column: span 14; }
.lg-span-4 { grid-column: span 6; }

.lg-card {
  position: relative;
  width: 100%;
  height: 100%;
  overflow: hidden;
  border-radius: 12px;
  box-shadow: 0 1px 2px rgba(20, 19, 17, .065), 0 10px 24px -8px rgba(20, 19, 17, .172);
}

/* Every box has a .lg-bg layer (the picture, or white until one goes in).
   Hover zooms ONLY that layer, same 1.05 / .5s curve as the menu's picture
   frames; the card clips it, and text sits above so it never moves. */
.lg-bg {
  position: absolute;
  inset: 0;
  background-color: #fff;
  background-size: cover;
  background-position: center top;
  transition: transform .5s cubic-bezier(.4, 0, .2, 1);
}
.lg-card:hover .lg-bg { transform: scale(1.05); }
.lg-card > :not(.lg-bg) { position: relative; }

/* Image boxes: grey placeholder until real images go in */
.lg-card-img {
  display: flex;
  align-items: center;
  justify-content: center;
}
.lg-card-img .lg-bg { background-image: linear-gradient(160deg, #DAD6CC 0%, #B3B0A8 100%); }

/* Real pictures (centered; each sits on its own colour so any crop edge blends) */
.lg-bg-1, .lg-bg-3, .lg-bg-4, .lg-bg-5 { background-position: center; background-repeat: no-repeat; }
.lg-card .lg-bg-1 { background-color: #EAE7E3; background-image: url('../images/founder/box-1.jpg'); background-size: auto 82%; }
.lg-card .lg-bg-5 { background-color: #231E1B; background-image: url('../images/founder/box-5.jpg'); background-size: auto 88%; }
.lg-card .lg-bg-3 { background-image: url('../images/founder/top-wide.jpg'); }
.lg-card .lg-bg-4 { background-image: url('../images/founder/bottom-wide.jpg'); }
.lg-card .lg-bg-2 { background-color: #fff; background-image: url('../images/founder/nicola.jpg'); background-size: cover; background-position: center 30%; }

/* Text over a picture: soft shade (part of the zooming layer) + white copy */
.lg-card-onimg .lg-bg::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(0, 0, 0, .42) 0%, rgba(0, 0, 0, 0) 38%, rgba(0, 0, 0, 0) 52%, rgba(0, 0, 0, .52) 100%);
}
.lg-ph-label {
  font-size: 0.8125rem;
  line-height: 1.4;
  text-align: center;
  color: rgba(20, 19, 17, .4);
  letter-spacing: 0.02em;
}

/* Text boxes laid out like the reference: name + role top-left, mark top-right,
   quote bottom-left, all white over the picture. */
.lg-card-text {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding: 24px 28px 28px;
  color: #fff;
}
.lg-top { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; }
.lg-who {
  font-size: 0.875rem;
  line-height: 1.3;
  color: rgba(255, 255, 255, .78);
}
.lg-who strong { font-weight: 600; color: #fff; margin-right: 10px; }
.lg-mark {
  font-size: 1.125rem;
  font-weight: 700;
  letter-spacing: -0.04em;
  line-height: 1;
  color: #fff;
}
.lg-quote {
  max-width: 34rem;
  font-family: var(--font-serif);
  font-size: 1.3rem;
  font-weight: 400;
  line-height: 1.32;
  letter-spacing: -0.005em;
  color: #fff;
  text-wrap: pretty;
}
.lg-quote-wide { max-width: 40rem; }

@media (prefers-reduced-motion: reduce) {
  .lg-bg, .lg-card:hover .lg-bg { transition: none; transform: none; }
}
@media (max-width: 900px) {
  .founder { padding: 120px 0; }
  .fdr-head { margin-bottom: 56px; }
}
@media (max-width: 767px) {
  .lg-card .lg-bg-1 { background-size: cover; }
  .lg-grid { grid-template-columns: 1fr; grid-auto-rows: minmax(240px, auto); }
  .lg-cell, .lg-span-2, .lg-span-3, .lg-span-4 { grid-column: span 1; }
  .lg-card-text { padding: 20px 22px 24px; min-height: 280px; }
  .lg-quote { font-size: 1.25rem; }
}

/* ---------- Hero morph transition (SVG Shape Overlays - GSAP, scroll-scrubbed) ---------- */
.hero-morph-pin {
  position: relative;
  height: 200vh; /* 100vh of scroll drives the morph while the hero stays pinned */
}
.hero-morph-sticky {
  position: sticky;
  top: 0;
  height: 100vh;
  overflow: hidden;
}
.hero-morph-sticky .hero-editorial {
  min-height: 100vh;
}
.shape-overlays {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 6; /* above hero content, below the fixed nav */
  pointer-events: none;
}
@media (prefers-reduced-motion: reduce) {
  .hero-morph-pin { height: auto; }
  .hero-morph-sticky { position: static; height: auto; overflow: visible; }
  .hero-morph-sticky .hero-editorial { min-height: 92vh; }
  .shape-overlays { display: none; }
}

/* ---------- Radial services intro (ported 21st.dev radial-intro) ---------- */
.radial-intro {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 88vh;
  padding: 24px 0;
  margin-top: -10px;
}
/* Tilted-oval stage (reference composition): chips wrap the rim of an ellipse
   whose major axis is tilted ~45°, each depth-scaled by JS. The box just needs
   to give the composition room; overflow is visible so front chips can breathe. */
.radial-stage {
  position: relative;
  width: 560px;
  height: 500px;
  overflow: visible;
}
.orbit-arm {
  position: absolute;
  inset: 0;
  will-change: transform;
}
.orbit-chip {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 96px;
  height: 96px;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--surface);
  border: none;
  box-shadow: var(--shadow-s);
  overflow: hidden;
  opacity: 0;
  /* deliberately NO will-change: transform. It makes the compositor raster this
     layer once and reuse that texture, and since the chips scale from ~0.1 at
     rest up to ~0.8 at the peak, the cached small raster gets stretched and the
     art goes soft. Without it the layer re-rasters at the scale in use, so every
     stage of the animation is drawn from the full-resolution source. */
  user-select: none;
}
.orbit-arm:first-child .orbit-chip { opacity: 1; }
.orbit-chip svg { width: 34px; height: 34px; stroke: var(--muted); }
.orbit-chip img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 50%;
  /* The source art is ~2500px square shown as small as ~65px at rest - a 36x
     downscale. -webkit-optimize-contrast made Chromium sharpen that downsample,
     which reads as crunchy / aliased on the resting circles before they animate.
     Plain high-quality smoothing gives a clean bicubic downscale instead. */
  image-rendering: auto;
  image-rendering: smooth;
  image-rendering: high-quality;
  /* No translateZ here: it pins a GPU texture at the current (tiny) size, so as
     the parent chip scales up the cached raster stretches and goes soft. Letting
     the img re-raster with the chip keeps every frame drawn from full res. */
}

@media (max-width: 1080px) {
  .radial-stage { width: 520px; height: 460px; }
  .orbit-chip { width: 90px; height: 90px; }
  .orbit-chip svg { width: 28px; height: 28px; }
}
@media (max-width: 680px) {
  .radial-intro { min-height: 64vh; }
  .radial-stage { width: min(86vw, 350px); height: min(78vw, 320px); }
  .orbit-chip { width: 62px; height: 62px; }
  .orbit-chip svg { width: 22px; height: 22px; }
}

/* ---------- Radial scroll-scrub showcase ----------
   The pin wrapper's extra height is the scrub distance; the sticky viewport
   holds the composition while main.js drives the cluster from its oval
   resting state into the featured-circle-right layout. Transforms only. */
/* Length carries a genuine dwell at the peak, so the composition holds still
   long enough to use the arrows before the exit begins. The extra 60vh over 430
   is spent entirely on a longer exit - the phase fractions in main.js are set so
   rotation, expansion and dwell keep their exact scroll distances. */
.radial-pin { height: 420vh; }
/* the outer section carries .s-roomy which adds 240px top+bottom; the pin
   already includes the exit runway so the extra bottom padding is dead space
   before the next section arrives */
/* Process section sits between the last pinned left/right section and the
   circles - generous space on both sides so neither neighbour crowds it. */
#how-it-works { margin-top: 80px; margin-bottom: 40px; }
/* Step 3 is the last panel: less empty space under its text before the circles arrive. */
#how-it-works .tpc-panel:last-child .tpc-content { padding-bottom: clamp(100px, 11.5vw, 170px); }
#services-showcase.s-roomy { padding-top: 0; padding-bottom: 0; }
.radial-sticky {
  position: sticky;
  top: 0;
  height: 100vh;
  /* Rests the circles ~70px below centre. The JS entry settle eases that back
     to centre, and because the offset is already present while the section
     scrolls in, the delta at the moment of lock is zero - nothing jumps. */
  padding-top: 40px;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  justify-content: center;
  overflow: hidden;
}
.radial-sticky > .container { flex: 0 0 auto; }
.radial-sticky .radial-intro { min-height: 0; }
/* left/top are written by JS so the arrows sit against the featured circle
   itself rather than the page edges - see rsPlaceArrows in main.js.
   Deliberately quiet: a thin translucent surface with a low-contrast stroke,
   so the featured circle remains the focal point. Hover raises the contrast
   without changing size. */
/* Near-black pill, matches the primary CTA ink. Hover raises to pure ink plus
   a soft brand-tinted glow ring, the same treatment used on other Verion CTAs -
   subtle, premium, no bounce. */
.radial-arrow {
  position: absolute;
  transform: translate(-50%, -50%);
  width: 52px;
  height: 52px;
  border-radius: 50%;
  background: #14110F;
  border: none;
  color: #fff;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  pointer-events: none;
  transition:
    opacity .35s var(--ease-out),
    background .25s var(--ease-out),
    box-shadow .3s var(--ease-out),
    transform .3s var(--ease-out);
  z-index: 30;
  box-shadow: 0 1px 2px rgba(20,19,17,.2), 0 10px 26px rgba(20, 19, 17, 0.16);
}
.radial-arrow svg {
  width: 24px;
  height: 24px;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  fill: none;
  display: block;
  transition: transform .25s var(--ease-out);
}
.radial-arrow.on { opacity: 0.95; pointer-events: auto; }
/* Linear navigation: hide the arrow at the boundary so the user
   sees a clear start (circle 1) and end (circle 7). */
.radial-arrow.on.rs-arrow-hidden { opacity: 0; pointer-events: none; }
/* Hover: same language as the site's primary CTA — darken to black, a
   small lift-in-place (scale, since the button is absolutely centred and
   won't shift layout), a deeper ink shadow, and the chevron nudges in its
   direction of travel. No coloured halo. */
.radial-arrow:hover {
  opacity: 1;
  background: #000;
  transform: translate(-50%, -50%) scale(1.09);
  box-shadow: 0 2px 4px rgba(20,19,17,.22), 0 18px 38px rgba(20, 19, 17, 0.26);
}
.radial-prev:hover svg { transform: translateX(-2px); }
.radial-next:hover svg { transform: translateX(2px); }
.radial-arrow:active {
  transform: translate(-50%, -50%) scale(.97);
  transition-duration: .09s;
}
.radial-arrow:focus-visible {
  outline: none;
  box-shadow: 0 12px 30px rgba(20, 19, 17, 0.24), 0 0 0 3px var(--brand);
}

/* ---------- Radial text panel (service descriptions, left side) ----------
   Uses position:fixed so it is anchored to the viewport left edge while the
   radial composition (which lives inside a sticky box with overflow:hidden)
   drifts right.  Visibility is toggled by JS in sync with the arrows. */
.rs-text-panel {
  position: fixed;
  top: 50%;
  left: 48px;
  transform: translateY(-50%);
  max-width: 420px;
  z-index: 20;
  opacity: 0;
  pointer-events: none;
  transition: opacity .45s cubic-bezier(.16, 1, .3, 1);
}
.rs-text-panel.on {
  opacity: 1;
  pointer-events: auto;
}

/* Each slide stacks in the same position; only .active is visible */
.rs-text-slide {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  opacity: 0;
  transform: translateY(18px);
  filter: blur(3px);
  transition:
    opacity .4s cubic-bezier(.16, 1, .3, 1),
    transform .4s cubic-bezier(.16, 1, .3, 1),
    filter .45s cubic-bezier(.16, 1, .3, 1);
  pointer-events: none;
}
.rs-text-slide.active {
  position: relative;
  opacity: 1;
  transform: none;
  filter: blur(0);
  pointer-events: auto;
}
/* Outgoing slide moves up instead of down */
.rs-text-slide.out {
  transform: translateY(-14px);
}

/* Children stagger in */
.rs-text-slide.active .rs-title {
  animation: rsTextIn .5s cubic-bezier(.16, 1, .3, 1) .04s both;
}
.rs-text-slide.active .rs-body {
  animation: rsTextIn .5s cubic-bezier(.16, 1, .3, 1) .14s both;
}
@keyframes rsTextIn {
  from { opacity: 0; transform: translateY(16px); filter: blur(2px); }
  to   { opacity: 1; transform: none; filter: blur(0); }
}

/* Title */
.rs-title {
  font-size: clamp(2.4rem, 4vw, 3.6rem);
  line-height: 1.08;
  font-weight: 500;
  letter-spacing: -0.028em;
  color: var(--ink);
  margin-bottom: 32px;
}

/* Body paragraph */
.rs-body {
  font-size: 1.1875rem;
  line-height: 1.75;
  color: var(--muted);
  max-width: 440px;
}

/* ── Radial section title ──
   Sits in the empty middle of the resting circle cluster. The wrap does the
   centring; the title itself carries the entrance transform so the two
   transforms don't fight each other. Font size is deliberately restrained
   so a 2-line "Built to Run / Without You." fits the ring's inner gap
   without touching the nearest chips. */
.rs-section-wrap {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: 25;
  pointer-events: none;
  transition: opacity 1s cubic-bezier(.16, 1, .3, 1),
              filter 1.2s cubic-bezier(.16, 1, .3, 1);
}
.rs-section-title {
  text-align: center;
  /* Bumped: the resting ring leaves plenty of empty middle for a punchier
     title. Still sits well inside the inner gap without touching any chip. */
  font-size: clamp(2.2rem, 3.5vw, 3.2rem);
  font-weight: 500;
  letter-spacing: -0.028em;
  line-height: 1.05;
  white-space: nowrap;
  opacity: 0;
  transform: translateY(24px);
  filter: blur(4px);
  transition:
    opacity .7s cubic-bezier(.16, 1, .3, 1),
    transform .7s cubic-bezier(.16, 1, .3, 1),
    filter .8s cubic-bezier(.16, 1, .3, 1);
}
/* the serif second line sits a step below the main line */
.rs-section-title .accent-serif { font-size: .78em; line-height: 1; display: inline-block; margin-top: -.2em; }
.rs-section-wrap.entered .rs-section-title {
  opacity: 1;
  transform: none;
  filter: blur(0);
}
.rs-section-wrap.fade-out {
  opacity: 0;
  filter: blur(6px);
}

/* ── Responsive ── */
@media (max-width: 1080px) {
  .rs-text-panel { max-width: 380px; left: 28px; }
  .rs-title { font-size: clamp(2rem, 3.4vw, 2.8rem); }
  .rs-section-title { font-size: clamp(1.75rem, 2.8vw, 2.4rem); }
}
@media (max-width: 680px) {
  .rs-text-panel { display: none; }
  .rs-section-title { font-size: clamp(1.5rem, 4.5vw, 2rem); }
}

@media (prefers-reduced-motion: reduce) {
  .radial-pin { height: auto; }
  .radial-sticky { position: static; height: auto; overflow: visible; }
  .radial-arrow { display: none; }
  .rs-text-panel { display: none; }
}

/* ---------- Reduced motion ---------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
  .reveal, .reveal-soft { opacity: 1; transform: none; filter: none; }
  .th-step { opacity: 1; transform: none; }
  .svc-text.reveal > * { opacity: 1; transform: none; filter: none; }
  .marquee-track { animation: none; }
  .pulse-dot { display: none; }
  .eco-lines { display: none; }
  .eco-note.n-booked, .eco-note.n-crm { opacity: 1; animation: none; }
  .flow-svg { display: none; }
  .eyebrow::before, .in .eyebrow::before { width: 22px; }
  .card::after, .step::after, .industry-card::after, .sb-visual::after { display: none; }
}

/* ---------- Responsive safety (desktop-first; mobile pass comes later) ---------- */
@media (max-width: 1080px) {
  .hero-grid { grid-template-columns: 1fr; }
  .ecosystem { margin: 40px auto 0; transform: scale(.85); }
  .card-grid, .steps, .metrics { grid-template-columns: 1fr 1fr; }
  .footer-top { flex-direction: column; gap: 48px; }
  .footer-brand { flex: none; }
  .footer-links { grid-template-columns: repeat(3, 1fr); }
  .transform-panel { grid-template-columns: 1fr; }
}
@media (max-width: 680px) {
  .nav-links { display: none; }
  .nav { gap: 14px; } /* links hidden: logo + CTA only */
  .card-grid, .card-grid.two, .steps, .metrics { grid-template-columns: 1fr; }
  .booking-body { padding: 40px 28px; }
  .choice-grid { grid-template-columns: 1fr; }
  .hero-ctas { flex-wrap: wrap; }
  .footer-links { grid-template-columns: 1fr 1fr; gap: 36px; }
  .footer-bottom { flex-direction: column; gap: 16px; align-items: flex-start; }
  .ecosystem { transform: scale(.62); margin: -60px auto -80px; }
  section { padding: 80px 0; }
}

/* ── Curve Swipe page transition (ported from CodePen EaZEQrv) ──
   Full-screen SVG; one dark sheet travels upward across the navigation:
   leading edge covers the old page, trailing edge unveils the new one.
   Brand ink fill instead of the pen's demo gradient. */
.cs-swipe {
  /* Defs-only now: holds the clipPath that shapes .cs-bg. Zero footprint. */
  position: absolute;
  width: 0;
  height: 0;
  overflow: hidden;
}
/* The transition sheet itself - a full-viewport layer clipped by the Curve
   Swipe path (#csClip, scaled to viewport px by main.js). Carries the
   Falling Pattern field below. */
.cs-bg {
  position: fixed;
  inset: 0;
  z-index: 9999;
  pointer-events: none;
  background: #141311;
  clip-path: url(#csClip);
  will-change: opacity;
  transform: translateZ(0); /* own compositor layer - the fade never janks */
  visibility: hidden;
}
html.cs-navout .cs-bg,
html.cs-covered .cs-bg,
.cs-bg.cs-fading { visibility: visible; }
/* ── Falling Pattern (transition background) ──
   Ivory rain streaks drifting down the ink, seen through a halftone dot
   screen. Even edge-to-edge - no center mask. The animation runs from page
   load and is phase-locked to WALL-CLOCK time via a negative
   animation-delay set in main.js: every page shows the identical frame at
   the identical instant, so across a navigation the rain never visibly
   pauses, restarts, or jumps - one continuous canvas. */
/* ACTIVE background: Flickering Grid - a canvas of small ivory squares on
   the ink, each flickering on a wall-clock-deterministic schedule drawn by
   main.js, so the pattern is identical across pages at any instant and the
   page switch is invisible. The Falling Pattern below is KEPT dormant for
   easy restore (swap the canvas back to the rain/dots divs). */
.cs-bg-grid {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}
.cs-bg-dots { position: absolute; inset: 0; }
.cs-bg-rain {
  /* Opaque ink base so the blur mixes streaks into ink at full luminance
     instead of thinning their alpha (the source component blurred an opaque
     backdrop). Overdrawn past the edges so the blur never exposes a rim;
     brightness restores the punch the blur takes away (the source ships
     dark:brightness-600). */
  position: absolute;
  inset: -48px;
  background-color: #141311;
  filter: blur(16px) brightness(2.6);
  background-image:
    radial-gradient(4px 100px at 0px 235px, #F4F3EF, transparent),
    radial-gradient(4px 100px at 300px 235px, #F4F3EF, transparent),
    radial-gradient(1.5px 1.5px at 150px 117.5px, #F4F3EF 100%, transparent 150%),
    radial-gradient(4px 100px at 0px 252px, #F4F3EF, transparent),
    radial-gradient(4px 100px at 300px 252px, #F4F3EF, transparent),
    radial-gradient(1.5px 1.5px at 150px 126px, #F4F3EF 100%, transparent 150%),
    radial-gradient(4px 100px at 0px 150px, #F4F3EF, transparent),
    radial-gradient(4px 100px at 300px 150px, #F4F3EF, transparent),
    radial-gradient(1.5px 1.5px at 150px 75px, #F4F3EF 100%, transparent 150%),
    radial-gradient(4px 100px at 0px 253px, #F4F3EF, transparent),
    radial-gradient(4px 100px at 300px 253px, #F4F3EF, transparent),
    radial-gradient(1.5px 1.5px at 150px 126.5px, #F4F3EF 100%, transparent 150%),
    radial-gradient(4px 100px at 0px 204px, #F4F3EF, transparent),
    radial-gradient(4px 100px at 300px 204px, #F4F3EF, transparent),
    radial-gradient(1.5px 1.5px at 150px 102px, #F4F3EF 100%, transparent 150%),
    radial-gradient(4px 100px at 0px 134px, #F4F3EF, transparent),
    radial-gradient(4px 100px at 300px 134px, #F4F3EF, transparent),
    radial-gradient(1.5px 1.5px at 150px 67px, #F4F3EF 100%, transparent 150%),
    radial-gradient(4px 100px at 0px 179px, #F4F3EF, transparent),
    radial-gradient(4px 100px at 300px 179px, #F4F3EF, transparent),
    radial-gradient(1.5px 1.5px at 150px 89.5px, #F4F3EF 100%, transparent 150%),
    radial-gradient(4px 100px at 0px 299px, #F4F3EF, transparent),
    radial-gradient(4px 100px at 300px 299px, #F4F3EF, transparent),
    radial-gradient(1.5px 1.5px at 150px 149.5px, #F4F3EF 100%, transparent 150%),
    radial-gradient(4px 100px at 0px 215px, #F4F3EF, transparent),
    radial-gradient(4px 100px at 300px 215px, #F4F3EF, transparent),
    radial-gradient(1.5px 1.5px at 150px 107.5px, #F4F3EF 100%, transparent 150%),
    radial-gradient(4px 100px at 0px 281px, #F4F3EF, transparent),
    radial-gradient(4px 100px at 300px 281px, #F4F3EF, transparent),
    radial-gradient(1.5px 1.5px at 150px 140.5px, #F4F3EF 100%, transparent 150%),
    radial-gradient(4px 100px at 0px 158px, #F4F3EF, transparent),
    radial-gradient(4px 100px at 300px 158px, #F4F3EF, transparent),
    radial-gradient(1.5px 1.5px at 150px 79px, #F4F3EF 100%, transparent 150%),
    radial-gradient(4px 100px at 0px 210px, #F4F3EF, transparent),
    radial-gradient(4px 100px at 300px 210px, #F4F3EF, transparent),
    radial-gradient(1.5px 1.5px at 150px 105px, #F4F3EF 100%, transparent 150%);
  background-size:
    300px 235px, 300px 235px, 300px 235px,
    300px 252px, 300px 252px, 300px 252px,
    300px 150px, 300px 150px, 300px 150px,
    300px 253px, 300px 253px, 300px 253px,
    300px 204px, 300px 204px, 300px 204px,
    300px 134px, 300px 134px, 300px 134px,
    300px 179px, 300px 179px, 300px 179px,
    300px 299px, 300px 299px, 300px 299px,
    300px 215px, 300px 215px, 300px 215px,
    300px 281px, 300px 281px, 300px 281px,
    300px 158px, 300px 158px, 300px 158px,
    300px 210px, 300px 210px, 300px 210px;
  animation: cs-rain 150s linear infinite;
}
@keyframes cs-rain {
  from {
    background-position:
      0px 220px, 3px 220px, 151.5px 337.5px, 25px 24px, 28px 24px, 176.5px 150px,
      50px 16px, 53px 16px, 201.5px 91px, 75px 224px, 78px 224px, 226.5px 230.5px,
      100px 19px, 103px 19px, 251.5px 121px, 125px 120px, 128px 120px, 276.5px 187px,
      150px 31px, 153px 31px, 301.5px 120.5px, 175px 235px, 178px 235px, 326.5px 384.5px,
      200px 121px, 203px 121px, 351.5px 228.5px, 225px 224px, 228px 224px, 376.5px 364.5px,
      250px 26px, 253px 26px, 401.5px 105px, 275px 75px, 278px 75px, 426.5px 180px;
  }
  to {
    background-position:
      0px 6800px, 3px 6800px, 151.5px 6917.5px, 25px 13632px, 28px 13632px, 176.5px 13758px,
      50px 5416px, 53px 5416px, 201.5px 5491px, 75px 17175px, 78px 17175px, 226.5px 17301.5px,
      100px 5119px, 103px 5119px, 251.5px 5221px, 125px 8428px, 128px 8428px, 276.5px 8495px,
      150px 9876px, 153px 9876px, 301.5px 9965.5px, 175px 13391px, 178px 13391px, 326.5px 13540.5px,
      200px 14741px, 203px 14741px, 351.5px 14848.5px, 225px 18770px, 228px 18770px, 376.5px 18910.5px,
      250px 5082px, 253px 5082px, 401.5px 5161px, 275px 6375px, 278px 6375px, 426.5px 6480px;
  }
}
/* Halftone screen: opaque ink with a 2px transparent dot grid - the rain is
   only visible through the dots, the component's signature texture. */
.cs-bg-dots {
  background-image: radial-gradient(circle at 50% 50%, transparent 0, transparent 2px, #141311 2px);
  background-size: 8px 8px;
}
@media (prefers-reduced-motion: reduce) {
  .cs-bg-rain { animation: none; }
}

/* Exit cross-dissolve: the page content fades AWAY at the same moment the
   ink sheet fades IN - a seamless handoff, not a black layer creeping over
   an opaque page. A symmetric S-curve keeps the first frames gentle (an
   ease-out here front-loads the darkening and reads as a flash). */
html.cs-navout body > :not(.cs-swipe):not(.cs-bg) {
  opacity: 0;
  transition: opacity .26s cubic-bezier(.45,.05,.55,.95);
}

/* Exit dissolve: the whole sheet (path set to full cover) fades in over
   the old page - long enough to read as a clear, gentle dissolve into the
   transition background, never a flash. Duration and easing match the
   content fade above so page-out and sheet-in move as one motion. The JS
   handoff (main.js) waits for this to nearly complete before navigating,
   so the fade is its own visible phase - not cut off by the Curve Swipe. */
.cs-bg.cs-fading {
  transition: opacity .26s cubic-bezier(.45,.05,.55,.95);
}

/* Header choreography - the whole header rides with the transition:
   slides up and out with the exit dissolve, stays parked above the
   viewport while covered, glides back down once the new page is
   unveiled. */
html.cs-navout .fsn-header {
  opacity: 0;
  transform: translateY(-130%);
  transition: opacity .27s cubic-bezier(.5,0,.75,.4), transform .27s cubic-bezier(.5,0,.75,.4);
}
html.cs-covered .fsn-header {
  opacity: 0;
  transform: translateY(-130%);
}
html.cs-navin .fsn-header {
  opacity: 1;
  transform: translateY(0);
  transition: opacity .55s cubic-bezier(.22,1,.36,1), transform .55s cubic-bezier(.22,1,.36,1);
}
