/* Avelio Marketing — site styles. Split from index.html 2026-07-15. */

:root{
  --ink:#101D3C; --blue:#2563EB; --blue-dark:#1D4ED8; --sky:#EBF1FF;
  --amber:#F59E0B; --muted:#5A6478; --line:#E6EAF2; --white:#FFFFFF;
  --band:#EDF1F8; --band-line:#D7DFEC;
  --radius:24px;
  /* 4pt spacing scale (added 2026-08-08 with the article layout pass). The long-form
     pages previously used three arbitrary values — 15px, 32px, 10px — which is why
     they read as one undifferentiated column: no scale means no rhythm. */
  --sp-1:4px; --sp-2:8px; --sp-3:12px; --sp-4:16px; --sp-5:24px;
  --sp-6:32px; --sp-7:48px; --sp-8:64px;
}
*{box-sizing:border-box; margin:0; padding:0}
[hidden]{display:none!important}
html{scroll-behavior:smooth; -webkit-font-smoothing:antialiased; -moz-osx-font-smoothing:grayscale}
@media (prefers-reduced-motion: reduce){ html{scroll-behavior:auto} }
section[id], #top{scroll-margin-top:86px}
a, button, summary{touch-action:manipulation}
a:focus-visible, button:focus-visible, summary:focus-visible{outline:3px solid var(--blue); outline-offset:3px; border-radius:6px}
.skip{
  position:absolute; left:-9999px; top:0; z-index:100; background:var(--blue); color:#fff;
  font-weight:700; padding:12px 20px; border-radius:0 0 12px 0;
}
.skip:focus{left:0}
.vh{position:absolute; width:1px; height:1px; padding:0; margin:-1px; overflow:hidden; clip-path:inset(50%); white-space:nowrap; border:0}
body{
  font-family:"Plus Jakarta Sans", -apple-system, "Segoe UI", sans-serif;
  color:var(--ink); background:var(--white); line-height:1.6; font-size:17px;
}
img{max-width:100%; display:block}
a{color:inherit; text-decoration:none}
.wrap{max-width:1120px; margin:0 auto; padding:0 24px; padding-inline:max(24px, env(safe-area-inset-left)) max(24px, env(safe-area-inset-right))}

/* buttons */
.btn{
  display:inline-flex; align-items:center; gap:10px; background:var(--blue); color:#fff;
  font-weight:700; font-size:16.5px; padding:15px 30px; border-radius:999px; border:none;
  cursor:pointer; transition:transform .15s ease, background .15s ease, box-shadow .15s ease;
  box-shadow:0 6px 18px -8px rgba(37,99,235,.55);
}
.btn:hover{background:var(--blue-dark); transform:translateY(-1px)}
.btn:active{transform:translateY(0) scale(.97)}
.btn .arr{transition:transform .2s ease}
.btn:hover .arr{transform:translateX(4px)}
.btn.small{padding:11px 22px; font-size:15px}
.btn.ghost{background:transparent; color:var(--ink); box-shadow:none; border:2px solid var(--line)}
.btn.ghost:hover{border-color:var(--blue); color:var(--blue); background:transparent}

/* nav — fixed bar; transparent over the hero (nav.overlay), solid white past it */
nav{
  position:fixed; top:0; left:0; right:0; z-index:50;
  transition:box-shadow .7s ease;
}
nav::before{
  content:""; position:absolute; inset:0;
  background:rgba(255,255,255,.92); border-bottom:1px solid var(--line);
  -webkit-backdrop-filter:blur(10px); backdrop-filter:blur(10px);
  opacity:1; transition:opacity .7s ease;
}
.js nav.overlay::after{
  content:""; position:absolute; inset:0; z-index:-1;
  background:linear-gradient(180deg, rgba(16,29,60,.5) 0%, rgba(16,29,60,0) 100%);
  opacity:1; transition:opacity .7s ease;
}
.js nav.overlay.scrolled::after{opacity:0}
.nav-inner{position:relative}
nav.scrolled{box-shadow:0 8px 24px -16px rgba(16,29,60,.18)}
.js nav.overlay:not(.scrolled)::before{opacity:0}
.js nav.overlay:not(.scrolled) .nav-links a{color:#fff; text-shadow:0 1px 12px rgba(16,29,60,.45)}
.js nav.overlay:not(.scrolled) .nav-links a:hover{color:#8AB4FF}
.logo-nav path, .logo-nav circle{transition:fill .7s ease}
.js nav.overlay:not(.scrolled) .logo-nav :is(path,circle){fill:#fff}
.logo-nav circle{transform-box:fill-box; transform-origin:center}
.nav-logo:hover .logo-nav circle{animation:dotHop .5s ease}
@keyframes dotHop{0%,100%{transform:translateY(0)}40%{transform:translateY(-14%)}}
.nav-inner{display:flex; align-items:center; gap:30px; height:74px}
.nav-logo svg{height:44px; width:auto; aspect-ratio:454.5/133.4; display:block}
.nav-links{display:flex; gap:26px; font-weight:600; font-size:15.5px; color:var(--muted); margin-left:auto}
.nav-links a{padding:10px 2px; transition:color .7s ease, text-shadow .7s ease}
.nav-links a:hover{color:var(--blue); transition:color .15s ease}
.nav-cta{margin-left:8px}
@media (max-width:820px){ .nav-links{display:none} .nav-cta{margin-left:auto} }

/* ============ HERO — full-bleed photograph under the blue fade ============ */
.hero{
  position:relative; overflow:hidden; display:flex; align-items:center;
  min-height:100vh; min-height:100svh; /* exactly one screen on open; svh = fits with mobile toolbars showing */
  background:linear-gradient(180deg, var(--sky) 0%, #FFFFFF 100%);
}
.hero-bg{position:absolute; inset:0; z-index:0}
.hero-scrim{
  position:absolute; inset:0; z-index:1;
  background:linear-gradient(94deg, rgba(16,29,60,.66) 0%, rgba(16,29,60,.34) 46%, rgba(16,29,60,.06) 70%, transparent 100%);
}
@media (max-width:760px){
  .hero-scrim{background:linear-gradient(180deg, rgba(16,29,60,.62) 0%, rgba(16,29,60,.3) 100%)}
}
/* one looping clip, filling the hero at every size and centred on both axes —
   cover (not contain) so phones/tablets never show empty bands beside the video. */
.hero-bg video{
  position:absolute; inset:0; width:100%; height:100%;
  object-fit:cover; object-position:center center;
}
/* hero chat: glass feed rising from the bottom (audited from the Sierra source clone) */
.hero-grid2{display:grid; grid-template-columns:1.05fr .95fr; gap:48px; align-items:center}
@media (max-width:940px){ .hero-grid2{grid-template-columns:1fr} .hero .hero-chat{display:none} }
.hero-chat{
  position:absolute; right:max(24px, calc(50% - 536px)); bottom:16px; z-index:2; width:418px;
  display:flex; flex-direction:column; justify-content:flex-end; align-items:flex-end; gap:16px;
  height:360px; overflow:hidden; padding:0 6px;
  -webkit-mask-image:linear-gradient(180deg, transparent 0%, #000 26%, #000 100%);
  mask-image:linear-gradient(180deg, transparent 0%, #000 26%, #000 100%);
}
.bubble{
  max-width:330px; border-radius:20px; padding:13px 16px;
  font-size:15px; line-height:1.5; font-weight:600; color:#fff;
  background:rgba(255,255,255,.2);
  border:1px solid rgba(255,255,255,.16);
  -webkit-backdrop-filter:blur(20px) saturate(1.15); backdrop-filter:blur(20px) saturate(1.15);
  box-shadow:0 10px 30px -18px rgba(16,29,60,.35);
  will-change:transform, opacity;
  transition:opacity .55s ease;
}
.hero-chat .bubble:nth-last-child(1){opacity:1}
.hero-chat .bubble:nth-last-child(2){opacity:.7}
.hero-chat .bubble:nth-last-child(3){opacity:.4}
.hero-chat .bubble:nth-last-child(n+4){opacity:0}
.bubble .who{display:flex; align-items:center; gap:8px; font-size:13px; font-weight:600; color:rgba(255,255,255,.72); margin-bottom:6px}
.bubble .ava{
  width:18px; height:18px; border-radius:50%; flex:none;
  background:rgba(255,255,255,.3);
  display:inline-flex; align-items:center; justify-content:center;
  font-size:10px; font-weight:800; color:#fff;
}
.bubble.q{align-self:flex-start}
.bubble.a{align-self:flex-end}
.js .bubble.pop{animation:bubbleUp .55s cubic-bezier(.33,1,.68,1) backwards}
@keyframes bubbleUp{from{transform:translateY(calc(100% + 16px))} to{transform:none}}
.bubble.shift{transition:transform .55s cubic-bezier(.33,1,.68,1), opacity .55s ease}
.hero .wrap{position:relative; z-index:2; padding-top:96px; padding-bottom:96px; width:100%}
.hero-content{max-width:640px}
h1{font-size:clamp(40px,5.4vw,62px); font-weight:800; letter-spacing:-.025em; line-height:1.07; text-wrap:balance}
.hero h1{color:#fff; text-shadow:0 2px 22px rgba(16,29,60,.45)}
.checks{display:flex; flex-direction:column; gap:12px; margin:30px 0 34px; font-weight:600; font-size:17px; color:#fff; text-shadow:0 1px 12px rgba(16,29,60,.5)}
.checks li{list-style:none; display:flex; gap:12px; align-items:center}
.checks svg{flex:none}
.cta-row{display:flex; align-items:center; gap:18px; flex-wrap:wrap}
.hero-loc{display:block; margin-top:20px; font-size:14px; font-weight:600; color:rgba(255,255,255,.82); text-shadow:0 1px 10px rgba(16,29,60,.5)}
@keyframes fadeUp{from{opacity:0; transform:translateY(18px)} to{opacity:1; transform:none}}
.hero h1{animation:fadeUp .7s ease .15s both}
.hero .checks{animation:fadeUp .7s ease .3s both}
.hero .cta-row{animation:fadeUp .7s ease .43s both}
.hero .hero-loc{animation:fadeUp .7s ease .55s both}
@media (max-width:760px){
  .hero-loc{font-size:12.5px; margin-top:14px}
}

/* scroll story — hero pins while the next section slides over it; content fades + zooms out,
   then a white veil takes the background to 100% white (veil runs hp .5→.85) */
.hero{position:sticky; top:0; z-index:0}
main > section{position:relative; z-index:1}
.hero-content, .hero-chat{will-change:transform, opacity}
.js .hero-content, .js .hero-chat{
  opacity:calc(1 - var(--hp, 0) * 1.4);
  transform:scale(calc(1 - .1 * var(--hp, 0)));
}
.js .hero::after{
  content:""; position:absolute; inset:0; z-index:1; background:#fff;
  opacity:calc((var(--hp, 0) - .5) * 2.857); pointer-events:none;
}
.hero.covered .hero-content, .hero.covered .hero-chat{pointer-events:none}
@media (prefers-reduced-motion: reduce){
  .hero{position:static}
  .js .hero-content, .js .hero-chat{opacity:1; transform:none}
  .js .hero::after{content:none}
}

/* fit the fold — compact on short screens, grand on TVs/widescreens */
@media (max-height:700px){
  .hero .wrap{padding-top:84px; padding-bottom:40px}
  .checks{margin:22px 0 26px; gap:9px}
  .hero-loc{margin-top:14px}
}
@media (max-height:520px){
  .hero h1{font-size:34px}
  .checks{font-size:15px; gap:7px; margin:14px 0 18px}
  .checks svg{width:18px; height:18px}
  .cta-row .btn{padding:12px 24px; font-size:15px}
  .hero .wrap{padding-top:70px; padding-bottom:16px}
  .hero-loc{margin-top:10px; font-size:12.5px}
  .hero .hero-chat{display:none}
}
@media (min-width:1600px){
  .wrap{max-width:1280px}
  .hero h1{font-size:clamp(62px, 18.7px + 2.71vw, 88px)}
  .checks{font-size:19px; gap:14px}
  .btn{font-size:18px; padding:17px 34px}
  .btn.small{font-size:16px; padding:12px 26px}
  .hero-loc{font-size:15px}
  .hero-chat{width:460px; bottom:20px; right:max(24px, calc(50% - 616px))}
  .bubble{max-width:360px; font-size:16px}
}

/* sections */
section{padding:88px 0}
.sec-head{text-align:center; max-width:680px; margin:0 auto 56px}
h2{font-size:clamp(30px,3.8vw,42px); font-weight:800; letter-spacing:-.02em; line-height:1.15; text-wrap:balance}
.sec-sub{font-size:18px; color:var(--muted); margin-top:16px}

/* ============ THE TANGLE — the online-first problem, one organic thread ============ */
.problem{background:var(--white); padding-top:72px}
.tangle{position:relative; height:clamp(250px, 30vw, 330px); margin-bottom:64px}
.tangle > svg{position:absolute; inset:0; width:100%; height:100%}
.tangle .svg-m{display:none} /* vertical thread — phones only (≤640 swaps svg-d → svg-m) */
.tangle .strand{stroke:#D5DFF3; stroke-opacity:.85; stroke-width:9; stroke-linecap:round; stroke-linejoin:round; fill:none}
.js .tangle.reveal .strand{stroke-dasharray:1; stroke-dashoffset:1; transition:stroke-dashoffset 1.8s cubic-bezier(.4,0,.2,1) .15s}
.js .tangle.reveal.in .strand{stroke-dashoffset:0}
.mini-print{
  position:absolute; left:var(--x); top:var(--y); width:clamp(112px, 13vw, 150px);
  transform:rotate(var(--r)); background:#fff; border:1px solid var(--line); border-radius:8px;
  padding:7px 7px 26px; box-shadow:0 14px 28px -18px rgba(16,29,60,.4);
  transition:transform .25s ease;
}
.mini-print:hover{transform:rotate(0deg) translateY(-5px); z-index:3}
.mini-print img{width:100%; height:auto; aspect-ratio:4/3; object-fit:cover; border-radius:4px}
.mini-print figcaption{position:absolute; bottom:7px; left:0; right:0; text-align:center; font-size:12.5px; font-weight:700; color:var(--muted)}
.chipf{ /* chips scale WITH the viewport (prints do too) so tablets keep the prints-first hierarchy; em padding tracks the font */
  position:absolute; left:var(--x); top:var(--y); transform:rotate(var(--r, 0deg));
  display:inline-flex; align-items:center; gap:.5em; white-space:nowrap;
  background:#fff; border:1px solid var(--line); border-radius:999px; padding:.56em 1em;
  font-size:clamp(11.5px, 0.6vw + 6.9px, 13.5px); font-weight:700; color:var(--ink);
  box-shadow:0 10px 22px -14px rgba(16,29,60,.35);
}
.chipf svg{flex:none; width:1.05em; height:1.05em}
.chipf .mut{color:var(--muted); font-weight:600}
.pcols{display:grid; grid-template-columns:repeat(3,1fr); gap:40px; max-width:1020px; margin:0 auto}
.pcol{position:relative; padding:16px 0 0 22px}
.pcol::before{content:""; position:absolute; left:0; top:-34px; width:44px; height:92px; border-left:2px solid var(--line); border-top:2px solid var(--line); border-top-left-radius:18px}
.pcol h3{font-size:20px; font-weight:800; margin-bottom:8px}
.pcol p{font-size:15.5px; color:var(--muted)}
.pcol p b{color:var(--ink)}
@media (max-width:820px){ .pcols{grid-template-columns:1fr; gap:30px; max-width:520px} .pcol::before{top:-6px; height:56px} }
@media (max-width:719px){
  /* phones + narrow tablets (below 720px no collage arrangement stays collision-free):
     the WHOLE collage — thread, five prints, five chips — restacks as a
     centered vertical story. The svg-m thread draws top→bottom (same .strand
     animation); prints zigzag around it, each chip riding the opposite shoulder. */
  .tangle{height:auto; margin-bottom:44px; display:flex; flex-direction:column; align-items:center; gap:12px}
  .tangle .svg-d{display:none}
  .tangle .svg-m{display:block}
  .mini-print{position:static; width:min(150px, 44vw); padding:6px 6px 24px}
  .mini-print figcaption{font-size:11.5px}
  .chipf{position:static; font-size:12px; padding:6px 11px}
  /* zigzag via margins (layout-level, transform-safe): margin-right pushes an item
     left of the thread, margin-left pushes it right; chips oppose their print */
  .mini-print:nth-of-type(1){order:1; margin-right:60px}
  .chipf:nth-of-type(1){order:2; margin-left:84px; transform:rotate(-2deg)}      /* Mike’s Barbershop */
  .mini-print:nth-of-type(2){order:3; margin-left:60px}
  .chipf:nth-of-type(2){order:4; margin-right:84px; transform:rotate(2deg)}      /* 4.9 · 132 reviews */
  .mini-print:nth-of-type(3){order:5; margin-right:60px}
  .chipf:nth-of-type(4){order:6; margin-left:84px; transform:rotate(-2deg)}      /* $2,500 quoted */
  .mini-print:nth-of-type(4){order:7; margin-left:60px}
  .chipf:nth-of-type(3){order:8; margin-right:84px; transform:rotate(2deg)}      /* “Call for a quote…” */
  .mini-print:nth-of-type(5){order:9; margin-right:60px}
  .chipf:nth-of-type(5){order:10; margin-left:84px; transform:rotate(-2deg)}     /* shot at your shop */
}
@media (max-width:640px){
  /* heading vs body balance on phones: h2 up, section subs down */
  h2{font-size:32px}
  .sec-sub{font-size:16px; line-height:1.55}
}
@media (min-width:720px) and (max-width:1090px){
  /* tablet collage squeeze: same art, measured clean slots — the chips reflow off the
     prints (!important is needed to beat the inline --x/--y the desktop layout uses) */
  .mini-print:nth-of-type(5){--x:80% !important}                /* Boutiques inside the right edge */
  .chipf:nth-of-type(1){--x:21.5% !important}                   /* Mike's — off Barbers' corner at the 720 floor */
  .chipf:nth-of-type(2){--x:32% !important; --y:82% !important} /* 4.9 reviews → open center-left, off Salons */
  .chipf:nth-of-type(3){--x:32% !important}                     /* "Call for a quote…" stacks above it */
  .chipf:nth-of-type(4){--x:60% !important; --y:54% !important} /* $2,500 → the free mid-right band */
  .chipf:nth-of-type(5){--x:55% !important}                     /* shot at your business, clear of Boutiques */
}

/* pricing — Boardroom Slate band (decided 2026-07-15): cool slate with crisp rules */
/* position:relative is required by the gradient canvas AND fixes the confetti:
   .confetti is `position:absolute; inset:0` and main.js computes its size and
   burst origin relative to this section, but with no positioned ancestor it was
   resolving against the document instead (2026-08-08). */
/* DARK band (Swash 2026-08-08: "white is great, but can we try the black one" —
   same gradient as #work). position:relative is required by the gradient canvas
   AND fixes the confetti: .confetti is `position:absolute; inset:0` and main.js
   computes its size and burst origin relative to this section, but with no
   positioned ancestor it was resolving against the document.
   Borders dropped to match .work — a light hairline framed the dark band. */
.pricing{position:relative; background:#0B1430; border-top:0; border-bottom:0}
.pricing > .wrap{position:relative; z-index:1}
/* Same scrim shape as .work-scrim, and doing the same job: the shader alone
   only reaches 4.23:1 against white at its brightest, which fails AA for the
   15px .pricing-foot. With this it clears 6:1. NOT decorative. Painted as a
   pseudo-element (no markup to add) — it shares z-index 0 with the canvas but
   comes later in paint order, so it lands between canvas and .wrap. */
.pricing::after{
  content:""; position:absolute; inset:0; z-index:0; pointer-events:none;
  background:linear-gradient(180deg, rgba(0,0,0,.5) 0%, rgba(0,0,0,.2) 26%, rgba(0,0,0,.2) 74%, rgba(0,0,0,.5) 100%);
}
.pricing.gbg-fallback{
  background:
    radial-gradient(80% 62% at 22% 26%, rgba(46,111,208,.55), transparent 62%),
    radial-gradient(72% 66% at 78% 36%, rgba(107,79,168,.5), transparent 66%),
    radial-gradient(95% 72% at 50% 104%, rgba(5,10,24,.92), transparent 70%),
    #0B1430;
}
/* Text flipped for the dark ground. Scoped to .pricing so the shared .sec-sub /
   .pricing-foot rules are untouched everywhere else, exactly as .work does it.
   The white .card keeps its own `color:var(--ink)` pin, so card interiors are
   unaffected — that pin was added in 2026-08-04 for precisely this case. */
.pricing h2{color:#fff; text-shadow:0 2px 18px rgba(16,29,60,.5)}
.pricing .sec-sub{color:#fff}
.pricing .pricing-foot{color:rgba(255,255,255,.82)}
/* "See detailed pricing" is --blue #2563EB, which measures 2.93:1 on this band
   at its real position — invisible. #8AB4FF is what .work already uses for the
   same link on the same ground; measured 7.25:1 here. */
.pricing .see-all{color:#8AB4FF}
.pricing .see-all:hover{color:#fff}
.founding{
  display:inline-flex; align-items:center; gap:8px; background:#FFF4DE; color:#7A4D00;
  font-weight:700; font-size:14.5px; border-radius:999px; padding:9px 18px; margin-top:18px;
}
.cards{display:grid; grid-template-columns:repeat(3,1fr); gap:22px; align-items:stretch}
@media (max-width:900px){ .cards{grid-template-columns:1fr; max-width:440px; margin:0 auto} }
.card{
  background:#fff; border-radius:var(--radius); padding:36px 32px; border:1px solid var(--line);
  display:flex; flex-direction:column; position:relative;
  transition:transform .2s ease, box-shadow .2s ease;
  /* The card is ALWAYS a white surface, so pin its text to ink instead of
     inheriting the page colour. Without this, any dark treatment of the section
     makes .price and .feat inherit white and vanish (Swash 2026-08-04). */
  color:var(--ink);
}
.card:hover{transform:translateY(-6px); box-shadow:0 22px 40px -24px rgba(16,29,60,.28)}
.js .card.reveal.in:hover{transform:translateY(-6px)} /* outranks .js .reveal.in's transform:none */
.card.hot{border:2px solid var(--blue); box-shadow:0 24px 48px -24px rgba(37,99,235,.35)}
.badge{
  position:absolute; top:-15px; left:50%; transform:translateX(-50%);
  background:var(--amber); color:#3D2A00; font-size:12.5px; font-weight:800; letter-spacing:.04em;
  padding:6px 16px; border-radius:999px; white-space:nowrap;
}
.tier{font-size:14px; letter-spacing:.12em; text-transform:uppercase; font-weight:800; color:var(--blue); margin-bottom:14px}
.price-old{color:var(--muted); text-decoration:line-through; font-weight:600; font-size:19px; font-variant-numeric:tabular-nums}
.price{font-size:46px; font-weight:800; letter-spacing:-.02em; line-height:1; margin:2px 0 4px; font-variant-numeric:tabular-nums}
.price-note{font-size:14px; color:var(--muted); margin-bottom:22px}
.feat{display:flex; flex-direction:column; gap:11px; margin-bottom:30px; font-size:16px}
.feat li{list-style:none; display:flex; gap:10px; align-items:flex-start}
.feat svg{flex:none; margin-top:4px}
.card .btn{margin-top:auto; justify-content:center}
.pricing-foot{text-align:center; color:var(--muted); font-size:15px; margin:30px auto 0; max-width:58ch; padding:0 8px}
.confetti{position:absolute; inset:0; width:100%; height:100%; pointer-events:none; z-index:5}

/* ============ SHOOT MAP — the Lower Mainland we drive to (replaces the film band) ============ */
.shootmap{background:var(--white); padding-bottom:0}
.map-band{position:relative; width:100%; overflow:hidden; background:#fff}
.map-stage{position:relative; width:100%; aspect-ratio:2560/1280}
.map-stage::before{
  content:""; position:absolute; top:0; left:0; right:0; height:120px; z-index:1; pointer-events:none;
  background:linear-gradient(180deg, #fff, rgba(255,255,255,0));
}
.map-stage img{position:absolute; inset:0; width:100%; height:100%; display:block; object-fit:cover}
.map-credit{ /* ODbL requires OSM attribution near the map — kept as a quiet caption instead of the on-map chip */
  text-align:center; font-size:11px; font-weight:600; color:var(--muted);
  padding:9px 24px 11px; margin:0;
}
.map-pin{position:absolute; left:var(--x); top:var(--y); transform:translate(-50%,-50%); z-index:2; --pin-gap:clamp(6px, .9vw, 10px)}
.map-pin::before{ /* sonar ring — idle it sweeps the cities, on hover it pings fast */
  content:""; position:absolute; left:50%; top:50%; width:48px; height:48px;
  margin:-24px 0 0 -24px; border-radius:50%; background:rgba(37,99,235,.28);
  transform:scale(.2); opacity:0; z-index:-1; pointer-events:none;
}
.js .map-band.reveal .map-pin{opacity:0}
.js .map-band.reveal.in .map-pin{animation:pinDrop .6s cubic-bezier(.22,1,.36,1) both; animation-delay:calc(.2s + var(--d, 0s))}
.js .map-band.reveal.in .map-pin::before{animation:pinPing 6.3s linear infinite; animation-delay:calc(1.2s + var(--d, 0s) * 10)}
.map-pin:hover::before, .js .map-band.reveal.in .map-pin:hover::before{animation:pinPingFast 1.8s cubic-bezier(.25,1,.5,1) infinite; animation-delay:0s}
.pin-ico{
  /* fluid: phone 30×33 → desktop 36×39, so tablets get a proportional map instead of desktop-size pins */
  display:block; width:clamp(30px, 2.1vw + 12px, 36px); height:clamp(33px, 2.1vw + 15px, 39px); color:var(--blue);
  filter:drop-shadow(0 5px 9px rgba(16,29,60,.35));
  transform-origin:50% 100%;
}
.map-pin:hover .pin-ico{animation:pinHop .9s cubic-bezier(.22,1,.36,1)}
.pin-card{
  position:absolute; bottom:calc(100% + var(--pin-gap)); left:50%; transform:translateX(-50%);
  background:#fff; border:1px solid var(--line); border-radius:10px;
  padding:clamp(4px, .62vw, 7px) clamp(10px, 1.16vw, 13px);
  font-size:clamp(13px, 1.12vw + 4.4px, 16px); font-weight:800; color:var(--ink); white-space:nowrap;
  box-shadow:0 12px 26px -12px rgba(16,29,60,.35);
  transition:transform .5s cubic-bezier(.22,1,.36,1), box-shadow .5s ease;
}
.map-pin:hover .pin-card{transform:translateX(-50%) translateY(-7px) scale(1.06); box-shadow:0 18px 34px -12px rgba(16,29,60,.45)}
@keyframes pinDrop{
  0%{opacity:0; transform:translate(-50%,-50%) translateY(-36px)}
  62%{opacity:1; transform:translate(-50%,-50%) translateY(2px)}
  100%{opacity:1; transform:translate(-50%,-50%)}
}
@keyframes pinPing{
  0%{transform:scale(.2); opacity:0}
  2%{opacity:.5}
  14%{transform:scale(2); opacity:0}
  100%{transform:scale(2); opacity:0}
}
@keyframes pinPingFast{
  0%{transform:scale(.2); opacity:.5}
  80%{transform:scale(2.2); opacity:0}
  100%{transform:scale(2.2); opacity:0}
}
@keyframes pinHop{ /* one slow rise and settle — no overshoot, reads calm not springy */
  0%{transform:translateY(0)}
  50%{transform:translateY(-9px) scale(1.1)}
  100%{transform:translateY(0)}
}
.pin-card::after{
  content:""; position:absolute; top:100%; left:50%; transform:translateX(-50%);
  border:5px solid transparent; border-top-color:#fff;
}
.map-pin.alt .pin-card{bottom:auto; top:calc(100% + var(--pin-gap))}
.map-pin.alt .pin-card::after{top:auto; bottom:100%; border-top-color:transparent; border-bottom-color:#fff}
@media (max-width:640px){
  .map-stage::before{height:40px}
  .map-stage{width:123.5%; margin-left:-11.7%} /* crop-zoom: sea east+west trimmed so the pin cluster fills the phone width; pins are % of stage so geography scales with it (margin, NOT transform — a transformed stage stacks above the pin layer, the old shipped bug) */
  .pin-card{line-height:1.3; border-radius:8px} /* size + offsets come from the fluid clamps (floor = this phone spec) */
  .map-pin.alt .pin-card, .map-pin.mflip .pin-card{bottom:auto; top:calc(100% + var(--pin-gap))}
  .map-pin.mflip .pin-card::after{top:auto; bottom:100%; border-top-color:transparent; border-bottom-color:#fff}
  .map-pin.msink .pin-card{top:calc(100% + var(--pin-gap) + 9px)} /* Surrey: sinks below Burnaby's card — the two below-bands collide at shared offset */
  .map-pin.mup .pin-card{bottom:calc(100% + var(--pin-gap)); top:auto; transform:translateX(-57%)} /* Abbotsford: flips above on phones (below clips the stage bottom); card nudged left so it clears the band's right edge */
  .map-pin.mup .pin-card::after{top:100%; bottom:auto; border-top-color:#fff; border-bottom-color:transparent; left:57%}
  .map-pin.mup:hover .pin-card{transform:translateX(-57%) translateY(-7px) scale(1.06)}
  .map-credit{font-size:11.5px; padding:7px 20px 9px}
}
@keyframes recPulse{0%,100%{opacity:1}50%{opacity:.35}} /* used by the steps-tile REC dot */

/* how it works — feature lattice: the four steps in the middle,
   everything that comes included around them, edges fading out */
.featgrid{
  display:grid; grid-template-columns:repeat(8,1fr);
  grid-template-rows:52px repeat(6,122px) 52px;
  gap:1px; background:var(--line); padding:1px;
  width:min(1340px, 100%); margin:0 auto;
  -webkit-mask-image:linear-gradient(to right, transparent, #000 9%, #000 91%, transparent);
  mask-image:linear-gradient(to right, transparent, #000 9%, #000 91%, transparent);
}
.featgrid > *{background:#fff; min-width:0}
.fg-sp{display:block; grid-column:var(--c); grid-row:var(--r)}
.fcell{
  grid-column:var(--c); grid-row:var(--r);
  display:flex; flex-direction:column; align-items:center; justify-content:center; gap:9px;
  padding:12px 10px; text-align:center; color:#8792A8;
  transition:background .18s ease, color .18s ease;
}
.fcell svg{width:25px; height:25px; fill:none; stroke:currentColor; stroke-width:1.7; stroke-linecap:round; flex:none}
.fcell span{font-size:13px; font-weight:700; line-height:1.3; color:var(--muted); max-width:16ch; transition:color .18s ease}
.fcell:hover{background:#F7FAFF; color:var(--blue)}
.fcell:hover span{color:var(--ink)}
.tile{
  position:relative; overflow:hidden;
  display:flex; flex-direction:column; padding:20px 18px;
  background:#fff radial-gradient(120% 88% at var(--wx,50%) 0%, #E2ECFF 0%, rgba(235,241,255,.3) 55%, rgba(255,255,255,0) 80%);
  transition:transform .22s ease, box-shadow .22s ease, border-radius .22s ease;
}
.t1{grid-column:3/5; grid-row:3/5}
.t2{grid-column:5/7; grid-row:3/5}
.t3{grid-column:3/5; grid-row:5/7}
.t4{grid-column:5/7; grid-row:5/7}
.tile:hover{
  transform:translateY(-6px); z-index:2; border-radius:14px;
  box-shadow:0 24px 44px -20px rgba(16,29,60,.28), 0 0 0 1px #BFD3FC;
}
.js .tile.reveal.in:hover{transform:translateY(-6px)}
.featgrid .t2{transition-delay:.07s}
.featgrid .t3{transition-delay:.14s}
.featgrid .t4{transition-delay:.21s}
.tile-art{position:relative; flex:1; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:10px; min-height:0}
.art-cap{display:inline-flex; align-items:center; gap:6px; font-size:11.5px; font-weight:700; color:var(--muted); white-space:nowrap}
.tile-name{display:flex; align-items:center; justify-content:center; gap:10px; margin-top:12px}
.tile-n{
  width:28px; height:28px; border-radius:9px; background:var(--blue); color:#fff; flex:none;
  display:grid; place-items:center; font-size:14.5px; font-weight:800;
  box-shadow:inset 0 -3px 0 rgba(16,29,60,.3);
}
.tile-name h3{font-size:clamp(18px, 1.6vw, 21px); font-weight:800; letter-spacing:-.01em}
/* tile art: booking pills */
.cal-pills{display:flex; gap:8px}
.pill{
  display:inline-flex; align-items:center; gap:6px; white-space:nowrap;
  border:1px solid var(--line); background:#fff; border-radius:999px;
  padding:7px 13px; font-size:12.5px; font-weight:700; color:var(--muted);
  box-shadow:0 8px 18px -12px rgba(16,29,60,.3);
}
.pill.on{background:var(--blue); border-color:var(--blue); color:#fff}
/* tile art: viewfinder */
.vf{position:relative; width:min(200px, 92%); height:104px; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:7px}
.vfc{position:absolute; width:15px; height:15px; border:2.5px solid #9FB4D8}
.vfc.tl{top:0; left:0; border-right:0; border-bottom:0; border-top-left-radius:4px}
.vfc.tr{top:0; right:0; border-left:0; border-bottom:0; border-top-right-radius:4px}
.vfc.bl{bottom:0; left:0; border-right:0; border-top:0; border-bottom-left-radius:4px}
.vfc.br{bottom:0; right:0; border-left:0; border-top:0; border-bottom-right-radius:4px}
.vf-rec{position:absolute; top:2px; right:10px; display:inline-flex; align-items:center; gap:5px; font-size:10px; font-weight:800; letter-spacing:.08em; color:#B42334}
.vf-rec i{width:7px; height:7px; border-radius:50%; background:#FF5A5A; animation:recPulse 1.6s ease infinite}
.vf-cam{width:30px; height:30px; fill:none; stroke:var(--ink); stroke-width:1.7; stroke-linecap:round}
.vf-cap{font-size:11px; font-weight:700; color:var(--muted); white-space:nowrap}
/* tile art: browser build */
.brw{position:relative; width:min(190px, 88%); border:1px solid var(--line); border-radius:10px; background:#fff; box-shadow:0 12px 26px -18px rgba(16,29,60,.35)}
.brw-top{display:flex; gap:4px; padding:8px 10px; border-bottom:1px solid var(--line)}
.brw-top i{width:6px; height:6px; border-radius:50%; background:#D8DFEC}
.brw-body{display:flex; flex-direction:column; gap:6px; padding:11px 12px 13px}
.sk{display:block; border-radius:4px; background:var(--sky)}
.sk.h{width:58%; height:9px; background:#C9D8F6}
.sk.l{width:92%; height:6px}
.sk.l.s{width:70%}
.sk.cta{width:46px; height:12px; border-radius:999px; background:var(--blue); margin-top:3px}
.brw-tag{
  position:absolute; top:-10px; right:-12px; transform:rotate(4deg);
  background:#FFF4DE; color:#7A4D00; border-radius:999px; padding:4px 10px;
  font-size:10.5px; font-weight:800; letter-spacing:.03em; white-space:nowrap;
}
/* tile art: launch & own */
.urlbar{
  display:inline-flex; align-items:center; gap:7px; white-space:nowrap;
  border:1px solid var(--line); border-radius:999px; background:#fff;
  padding:8px 15px; font-size:13px; font-weight:700; color:var(--ink);
  box-shadow:0 10px 22px -14px rgba(16,29,60,.35);
}
.urlbar svg{flex:none}
.cf{position:absolute; left:var(--x); top:var(--y); width:7px; height:10px; border-radius:2px; transform:rotate(var(--r)); opacity:.9}
@media (max-width:900px){
  /* the icon lattice is desktop-only ambience (Swash 2026-07-29): on phones/tablets
     it collapsed into a meaningless icon list, so the 4 step tiles carry the section */
  .featgrid{grid-template-columns:repeat(6,1fr); grid-template-rows:none; -webkit-mask-image:none; mask-image:none}
  .fg-sp, .fcell{display:none}
  .tile{grid-row:auto; grid-column:span 3; min-height:230px}
}
@media (max-width:560px){
  .tile{grid-column:span 6}
}

/* work → verified reviews (2026-07-15): feature rows left, browser review panel right */
.work{background:var(--band); border-top:1px solid var(--band-line); border-bottom:1px solid var(--band-line)}
.rev-grid{display:grid; grid-template-columns:1.04fr .96fr; gap:56px; align-items:center; margin-bottom:46px}
.rf{display:flex; gap:16px; margin-bottom:26px}
.rf-ico{
  flex:none; width:44px; height:44px; border-radius:13px; background:var(--blue);
  display:grid; place-items:center; box-shadow:0 10px 20px -10px rgba(37,99,235,.55);
}
.rf-ico svg{width:22px; height:22px; fill:none; stroke:#fff; stroke-width:1.8; stroke-linecap:round; stroke-linejoin:round}
.rf b{font-size:17px; display:block; margin:2px 0 5px}
.rf p{font-size:14.5px; color:var(--muted); max-width:46ch}
.rev-note{
  display:flex; gap:11px; align-items:flex-start; background:#fff; border:1px solid var(--line);
  border-radius:14px; padding:15px 18px; margin-top:6px;
}
.rev-note svg{flex:none; width:17px; height:17px; fill:none; stroke:var(--muted); stroke-width:1.8; stroke-linecap:round; margin-top:2px}
.rev-note p{font-size:13.5px; color:var(--muted)}
.rev-note b{color:var(--ink)}
/* white panel on a dark photo band — pin its text to ink so it can't inherit
   the section's light colour and disappear (same trap as .card) */
.rev-panel{position:relative; background:#fff; color:var(--ink); border:1px solid var(--line); border-radius:16px; box-shadow:0 24px 48px -28px rgba(16,29,60,.35)}
.rev-top{display:flex; align-items:center; gap:5px; padding:12px 16px; border-bottom:1px solid var(--line)}
.rev-top i{width:8px; height:8px; border-radius:50%; background:#E2E7F0}
.rev-top i:first-child{background:var(--blue)}
.rev-url{font-size:11.5px; color:var(--muted); font-weight:600; margin-left:10px}
.rev-head{display:flex; align-items:center; gap:13px; padding:18px 20px 4px}
.rev-mark{flex:none; width:46px; height:46px; border-radius:12px; background:var(--sky); display:grid; place-items:center}
.rev-mark img{width:26px; height:auto; display:block}
.rev-head b{font-size:16.5px; display:block}
.rev-sub{display:flex; align-items:center; gap:7px; font-size:13px; color:var(--muted); margin-top:2px}
.rev-sub b{font-size:13px}
.rev-stars{color:var(--amber); letter-spacing:2px; font-size:13px}
.rev-card{margin:14px 20px 0; border:1px solid var(--line); border-radius:13px; padding:16px 18px}
.rev-who{display:flex; align-items:center; gap:10px}
.rev-ava{
  flex:none; width:26px; height:26px; border-radius:50%; background:linear-gradient(135deg,#6A5A9C,#3D6FB5);
  color:#fff; font-size:12px; font-weight:800; display:grid; place-items:center;
}
.rev-who b{font-size:14.5px}
.rev-who a:hover{color:var(--blue)} /* the client name links to their live site */
.rev-ver{
  margin-left:auto; display:inline-flex; align-items:center; gap:5px;
  background:#DCFCE7; color:#15803D; font-size:11px; font-weight:800;
  border-radius:999px; padding:4px 10px; white-space:nowrap;
}
.rev-card .rev-stars{display:block; font-size:15px; letter-spacing:3px; margin:10px 0 8px}
.rev-card p{font-size:14.5px; color:var(--ink); text-wrap:pretty}
.rev-meta{display:block; font-size:12px; color:var(--muted); margin-top:12px}
.rev-foot{text-align:center; font-size:12px; color:var(--muted); padding:16px 0 18px}
.rev-badge{
  position:absolute; left:-16px; bottom:-22px; background:#fff; border:1px solid var(--line);
  border-radius:13px; padding:10px 16px 11px; box-shadow:0 16px 30px -16px rgba(16,29,60,.4);
}
.rev-badge .rev-stars{font-size:12px; letter-spacing:2px}
.rev-badge b{font-size:13px; margin-left:6px}
.rev-badge .cap{display:block; font-size:11px; color:var(--muted); margin-top:3px}
.rev-cta{text-align:center}
.see-all{display:inline-flex; align-items:center; gap:9px; color:var(--blue); font-weight:800; font-size:16.5px}
/* The arrow SVG carries stroke="#2563EB" as an inline presentation attribute, so
   it stayed brand blue on every dark band even after the label was lightened —
   including .work, whose label has been #8AB4FF since 2026-08-04. Presentation
   attributes lose to any CSS rule, so binding to currentColor fixes all of them.
   Light sections are unchanged: .see-all is already var(--blue) there. */
.see-all .arr path{stroke:currentColor}
.see-all .arr{transition:transform .2s ease}
.see-all:hover .arr{transform:translateX(4px)}
@media (max-width:900px){
  .rev-grid{grid-template-columns:1fr; gap:40px; margin-bottom:42px}
  .rev-badge{position:static; display:inline-block; margin:-4px 0 16px 16px; box-shadow:0 10px 20px -12px rgba(16,29,60,.35)}
}

/* about — a word from the founder: centered quote over a round portrait */
.about{background:var(--white)}
.about-quote{max-width:780px; margin:0 auto; text-align:center}
.about-quote::before{
  content:"\201D"; display:block; font-size:clamp(76px, 9vw, 100px); font-weight:800;
  line-height:.62; height:.6em; color:#C9D8F6;
}
.quote-k{
  font-size:12.5px; letter-spacing:.14em; line-height:1.4; text-transform:uppercase;
  font-weight:800; color:var(--blue); margin:14px 0 22px;
}
.quote-text{margin:0}
.quote-text p{
  font-size:clamp(19px, 2.2vw, 26px); font-weight:600; letter-spacing:-.01em;
  line-height:1.5; color:var(--ink); text-wrap:balance;
}
/* .long = the full founder story on the about page: smaller type, tighter column, real paragraphs */
.quote-text.long{max-width:660px; margin:0 auto}
.quote-text.long p{
  font-size:clamp(16.5px, 1.55vw, 19px); letter-spacing:-.005em;
  line-height:1.62; text-wrap:pretty;
}
.quote-text.long p + p{margin-top:15px}
.quote-who{margin-top:38px}
.quote-who img{
  width:104px; height:104px; border-radius:50%; object-fit:cover; object-position:top;
  display:block; margin:0 auto; border:4px solid #fff;
  box-shadow:0 0 0 1px var(--line), 0 16px 32px -18px rgba(16,29,60,.35);
}
.quote-who b{display:block; font-size:17px; margin-top:16px}
.quote-who span{display:block; font-size:14px; color:var(--muted); margin-top:3px}

/* FAQ — Boardroom Slate band */
/* Swash 2026-08-08: white, not the #f2f2f2 grey and not dark. Both hairlines
   existed to frame a grey band; with the band gone the top one just drew a line
   between two white sections (.about above is also white), so Swash removed it.
   The bottom rule is kept for now — see note, it meets the dark contact band. */
.faq{background:var(--white); border-bottom:1px solid var(--band-line)}
.faq-list{max-width:760px; margin:0 auto; display:flex; flex-direction:column; gap:14px}
details{
  background:#fff; border:1px solid var(--line); border-radius:18px; padding:22px 26px;
  overflow:hidden;
  transition:background-color .24s ease, border-color .24s ease;
}
details:not([open]):hover{border-color:#BFD3FC}
details[open]{background:var(--ink); border-color:var(--ink)}
summary{
  cursor:pointer; font-weight:700; font-size:17.5px; list-style:none; color:var(--ink);
  display:flex; justify-content:space-between; align-items:center; gap:16px;
  transition:color .24s ease;
}
details[open] summary{color:#fff}
summary::-webkit-details-marker{display:none}
summary::after{
  content:""; width:19px; height:19px; flex:none; background:currentColor;
  -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E") center/contain no-repeat;
  mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E") center/contain no-repeat;
  transition:transform .3s cubic-bezier(.22,1,.36,1);
}
details[open] summary::after{transform:rotate(180deg)}
details p{
  color:#C9D3E8; margin-top:12px; font-size:16px;
  opacity:0; transform:translateY(4px);
  transition:opacity .25s ease .08s, transform .25s ease .08s;
}
details[open] p{opacity:1; transform:none}
details.closing{background:#fff; border-color:var(--line)}
details.closing summary{color:var(--ink)}
details.closing summary::after{transform:none}
details.closing p{opacity:0; transform:translateY(4px); transition-delay:0s}
.sec-sub, .pcol p, details p, .feat li, .final-box p{text-wrap:pretty}

/* final CTA — interior pages show an ink box on white; the home #book section
   opts into the dark treatment with .final.contact (booking + contact cards). */
.final{background:var(--white); text-align:center}
.final.contact{background:var(--ink)}
.final-box{background:var(--ink); border-radius:32px; padding:72px 30px; color:#fff}
.final-box h2{color:#fff; max-width:600px; margin:0 auto}
.final-box p{color:#B9C3D8; font-size:18px; margin:18px auto 34px; max-width:480px}
.final-box .btn{box-shadow:none}

/* footer — 4-column layout (Aspire-style reference, 2026-07-15) */
/* the glow flows out of .final.contact: its centre sits 100px ABOVE the footer's top
   edge, exactly matching that section's `calc(100% - 100px)` anchor, so the ellipse
   carries on across the join with no seam. */
footer{
  background:
    radial-gradient(900px 520px at 10% -100px, rgba(37,99,235,.14), transparent 62%),
    var(--ink);
  color:#B9C3D8; padding:64px 0 26px; margin-top:-1px;
}
.foot-grid{display:grid; grid-template-columns:minmax(260px, 350px) repeat(3, max-content); justify-content:space-between; gap:40px; align-items:start}
@media (max-width:980px){ .foot-grid{grid-template-columns:1fr 1fr; gap:36px} }
@media (max-width:560px){ .foot-grid{grid-template-columns:1fr} }
.foot-logo svg{height:56px; width:auto; aspect-ratio:454.5/133.4; display:block; margin-bottom:18px}
.foot-desc{font-size:14.5px; line-height:1.75; max-width:36ch}
.foot-desc b{color:#fff}
.foot-meta{list-style:none; margin-top:18px; display:flex; flex-direction:column; gap:11px; font-size:14.5px}
.foot-meta li{position:relative; padding-left:27px; line-height:1.45}
.foot-meta svg{
  position:absolute; left:0; top:50%; transform:translateY(-50%);
  width:16px; height:16px; fill:none; stroke:#8AB4FF; stroke-width:1.8; stroke-linecap:round; stroke-linejoin:round;
}
.foot-meta a:hover{color:#fff}
.foot-col b{color:#8AB4FF; display:block; margin-bottom:14px; font-size:15.5px}
.foot-col{font-size:14.5px; line-height:2.15}
.foot-col a{display:block}
.foot-col a:hover{color:#fff}
.foot-book{color:#fff; font-weight:800; font-size:15.5px; margin-bottom:16px}
.foot-book:hover{color:#8AB4FF}
.foot-social{display:flex; gap:10px}
.foot-social a{
  width:36px; height:36px; border-radius:50%; background:#fff;
  display:grid; place-items:center;
  transition:transform .15s ease, background .15s ease;
}
.foot-social a:hover{background:var(--sky); transform:translateY(-2px)}
.foot-bottom{
  border-top:1px solid rgba(255,255,255,.12); margin-top:50px;
  padding:22px 54px 0; position:relative; text-align:center;
  font-size:13.5px; color:#8E9AB5;
}
.foot-bottom a{color:#B9C3D8}
.foot-bottom a:hover{color:#fff}
.to-top{
  position:absolute; right:0; top:14px; width:38px; height:38px; border-radius:10px;
  background:var(--blue); display:grid; place-items:center;
  transition:transform .15s ease, background .15s ease;
}
.to-top:hover{background:var(--blue-dark); transform:translateY(-3px)}
.to-top svg{width:16px; height:16px; fill:none; stroke:#fff; stroke-width:2.4; stroke-linecap:round; stroke-linejoin:round}

/* scroll reveal — staggered within groups; no-JS ships fully visible */
.js .reveal{opacity:0; transform:translateY(22px); transition:opacity .6s ease, transform .6s ease}
.js .reveal.in{opacity:1; transform:none}
.pcols > .reveal:nth-child(2), .cards > .reveal:nth-child(2){transition-delay:.07s}
.pcols > .reveal:nth-child(3), .cards > .reveal:nth-child(3){transition-delay:.14s}

@media (prefers-reduced-motion: reduce){
  .hero h1, .hero .checks, .hero .cta-row, .hero .hero-loc,
  .nav-logo:hover .logo-nav circle, .hero-bg, .vf-rec i{animation:none}
  .reveal{opacity:1 !important; transform:none !important}
  .js .tangle.reveal .strand{stroke-dashoffset:0; transition:none}
  .map-pin, .map-pin::before, .pin-ico{animation:none !important}
  .js .map-band.reveal .map-pin{opacity:1}
  .map-pin:hover .pin-card{transform:translateX(-50%)}
}

/* ============ section → detail-page links & interior pages ============ */
/* .sec-cta: the "see details" link at the bottom of a home section (reuses .see-all).
   Interior pages (pricing / how-it-works / portfolio / about / blog / privacy / 404) are
   plain static HTML — the nav renders solid because it has no .overlay class. */
.sec-cta{text-align:center; margin-top:46px}

.page-hero{padding:128px 0 14px; text-align:center; background:linear-gradient(180deg, var(--sky), #fff)}
.page-hero h1{font-size:clamp(32px, 4.4vw, 52px); letter-spacing:-.025em; line-height:1.09}
.page-hero .lead{font-size:18px; color:var(--muted); max-width:620px; margin:16px auto 0; text-wrap:pretty}
/* Interior page entrance (2026-08-08): the heading and lead rise once on load.
   Keyframe-from pattern — the BASE state is fully visible, and only the running
   animation supplies the hidden from-state, so nothing can ever ship blank
   (no class gate, no JS; `backwards` covers the lead's delay). Home is untouched
   (.page-hero exists only on interior pages). */
@keyframes pageHeroIn{from{opacity:0; transform:translateY(14px)}}
.page-hero h1{animation:pageHeroIn .55s cubic-bezier(.22,1,.36,1) backwards}
.page-hero .lead{animation:pageHeroIn .55s cubic-bezier(.22,1,.36,1) .08s backwards}
@media (prefers-reduced-motion: reduce){
  .page-hero h1, .page-hero .lead{animation:none}
}
.page-sec{padding:56px 0}
.band{background:var(--band); border-top:1px solid var(--band-line); border-bottom:1px solid var(--band-line)}

/* readable prose — privacy policy + longer copy */
.prose{max-width:720px; margin:0 auto}
.prose > p{color:var(--muted); font-size:16px; line-height:1.7; margin-bottom:15px; text-wrap:pretty}
.prose > p b{color:var(--ink)}
.prose h2{font-size:21px; font-weight:800; margin:32px 0 10px; letter-spacing:-.01em; color:var(--ink)}
.prose ul{margin:0 0 15px 22px; color:var(--muted); font-size:16px; line-height:1.7}
.prose li{margin-bottom:6px}
.prose a{
  color:var(--blue); font-weight:700;
  /* hover affordance (2026-08-08): the underline fades in rather than grows —
     text-decoration-color is wrap-safe on multi-line links where a background-
     image underline would only paint the last fragment */
  text-decoration:underline; text-decoration-color:transparent;
  text-decoration-thickness:1.5px; text-underline-offset:3px;
  transition:text-decoration-color .18s ease, color .15s ease;
}
.prose a:hover{color:var(--blue-dark); text-decoration-color:currentColor}
@media (prefers-reduced-motion: reduce){
  .prose a{transition:none}
}
/* comparison table inside .prose — first used by the 2026-08-08 price guide.
   .tablewrap keeps a wide table scrolling inside its own box so the page body
   never scrolls sideways on a phone. */
.tablewrap{overflow-x:auto; margin:0 0 18px; -webkit-overflow-scrolling:touch}
.prose table{border-collapse:collapse; width:100%; min-width:460px; font-size:15.5px}
.prose th, .prose td{text-align:left; padding:11px 14px; border-bottom:1px solid var(--line); color:var(--muted)}
.prose th{color:var(--ink); font-weight:800; font-size:14px; background:var(--band); white-space:nowrap}
.prose td:first-child{color:var(--ink); font-weight:600}

/* ============ LONG-FORM ARTICLE (2026-08-08 layout pass) ============
   Scoped with .article so /privacy and /terms, which also use .prose, keep the
   flatter treatment that suits a legal document.
   Rhythm is the point: generous ABOVE each heading, tight below it, so a heading
   binds to the text it introduces instead of floating between two equal gaps. */
.prose.article > p{font-size:16.5px; line-height:1.75; margin-bottom:var(--sp-4)}
/* 26px against 16.5px body is a 1.58 ratio, which reads as weak hierarchy. Pushed
   to 30px (1.82) — combined with weight 800 vs 400 and 48px of space above, that
   is three dimensions doing the work, not one. */
.prose.article h2{font-size:clamp(22px, 2.5vw, 30px); margin:var(--sp-7) 0 var(--sp-3); text-wrap:balance}
.prose.article > *:first-child{margin-top:0}
.prose.article ul{margin:0 0 var(--sp-5) 20px; line-height:1.75}
.prose.article li{margin-bottom:var(--sp-2)}

/* The short answer: the most-read 55 words on the page and the block answer
   engines lift, so it stops looking like body copy. */
.answer{
  background:var(--sky); border:1px solid #D3E1FF; border-radius:18px;
  padding:clamp(18px, 3.2vw, 28px); margin:0 0 var(--sp-6);
}
.prose.article .answer p{font-size:18px; line-height:1.65; color:var(--ink); margin:0}
.prose.article .answer p + p{margin-top:var(--sp-3)}

/* Column comparison: options are COLUMNS, attributes are ROWS (Swash 2026-08-08 —
   the first version had options as rows, which reads as a list, not a comparison).
   Avelio's column is tinted so the eye lands on it first. On a phone the table
   scrolls sideways inside its own box AND the row labels stay pinned to the left,
   so you never lose track of which line you are reading. */
.cmp{
  overflow-x:auto; -webkit-overflow-scrolling:touch;
  margin:0 0 var(--sp-6); border:1px solid var(--line); border-radius:16px;
}
/* Deliberate grid-break: the comparison is the single most useful thing on the
   page, and inside the 720px reading column it still had to scroll on a desktop.
   Breaking it out of the measure lets all five columns be seen at once, which is
   the whole point of a comparison. Below 900px it returns to the column and
   scrolls sideways with the row labels pinned. */
@media (min-width:900px){
  .cmp{width:min(960px, calc(100vw - 64px)); margin-left:50%; transform:translateX(-50%)}
}
.cmp table{border-collapse:collapse; width:100%; min-width:660px; font-size:15px}
.cmp th, .cmp td{padding:14px 16px; text-align:left; vertical-align:top; border-bottom:1px solid var(--line)}
.cmp thead th{font-size:13.5px; font-weight:800; color:var(--ink); background:var(--band); white-space:nowrap}
.cmp tbody th{
  position:sticky; left:0; z-index:1;
  background:#fff; color:var(--ink); font-weight:700; font-size:14px; min-width:158px;
}
.cmp td{color:var(--muted)}
.cmp td b{display:block; color:var(--ink); font-weight:800; font-size:16px}
.cmp td span{display:block; font-size:13px; margin-top:3px}
.cmp .us{background:var(--sky)}
.cmp thead .us{background:var(--blue); color:#fff}
.cmp td.us{color:var(--ink)}
.cmp tbody tr:last-child th, .cmp tbody tr:last-child td{border-bottom:0}

/* Numbered checklist. Numbers earn their place here because this genuinely IS a
   sequence the reader works through, not section scaffolding. */
.asklist{list-style:none; margin:0 0 var(--sp-6); padding:0; counter-reset:ask}
.prose.article .asklist li{
  counter-increment:ask; display:grid; grid-template-columns:30px 1fr; gap:var(--sp-4);
  padding:var(--sp-4) 0; margin:0; border-bottom:1px solid var(--line);
}
.asklist li:last-child{border-bottom:0}
.asklist li::before{
  content:counter(ask); display:grid; place-items:center;
  width:30px; height:30px; border-radius:50%;
  background:var(--sky); color:var(--blue-dark); font-size:14px; font-weight:800;
}
.asklist b{display:block; color:var(--ink); margin-bottom:2px}

/* Question and answer pairs, visible rather than collapsed: an answer engine can
   only quote what it can read. */
.qa{margin:0 0 var(--sp-6)}
.qa-item{padding:var(--sp-4) 0; border-bottom:1px solid var(--line)}
.qa-item:last-child{border-bottom:0}
.qa-item b{display:block; color:var(--ink); font-size:16.5px; margin-bottom:var(--sp-1)}
.prose.article .qa-item p{margin:0}
.prose .stamp{font-size:13.5px; color:var(--muted); margin-bottom:26px}

/* how-it-works detail — numbered step list */
.stepline{max-width:720px; margin:0 auto; display:flex; flex-direction:column; gap:16px}
.stepitem{display:flex; gap:18px; align-items:flex-start; background:#fff; border:1px solid var(--line); border-radius:16px; padding:22px 24px}
.stepitem .n{flex:none; width:38px; height:38px; border-radius:11px; background:var(--blue); color:#fff; display:grid; place-items:center; font-weight:800; font-size:16px; box-shadow:inset 0 -3px 0 rgba(16,29,60,.3)}
.stepitem h2{font-size:18px; font-weight:800}
.stepitem p{color:var(--muted); font-size:15px; margin-top:4px; text-wrap:pretty}

/* empty state — portfolio + blog before real content exists */
.empty{max-width:600px; margin:0 auto; text-align:center; background:#fff; border:1px solid var(--line); border-radius:20px; padding:46px 32px; box-shadow:0 20px 44px -30px rgba(16,29,60,.3)}
.empty-ico{width:56px; height:56px; border-radius:16px; background:var(--sky); display:grid; place-items:center; margin:0 auto 18px}
.empty-ico svg{width:28px; height:28px; fill:none; stroke:var(--blue); stroke-width:1.8; stroke-linecap:round; stroke-linejoin:round}
.empty h2{font-size:22px; font-weight:800}
.empty p{color:var(--muted); margin-top:8px; font-size:15.5px; text-wrap:pretty}
/* portfolio tease: the first project's real full-page screenshot under an ink shade.
   Hover = the card lifts and the site slowly auto-scrolls through the frame;
   leaving glides it back to the top. Pure CSS (interior pages ship no JS). */
.empty.tease{
  max-width:760px; position:relative; overflow:hidden; border-color:rgba(16,29,60,.35);
  padding:92px 40px; background:var(--ink);
  box-shadow:0 32px 64px -32px rgba(16,29,60,.6);
  transition:transform .45s cubic-bezier(.22,1,.36,1), box-shadow .45s ease;
}
.empty.tease:hover{transform:translateY(-8px) scale(1.012); box-shadow:0 24px 44px -26px rgba(16,29,60,.42)}
.tease-media{position:absolute; inset:0; z-index:0; overflow:hidden}
.tease-media img{
  width:100%; height:100%; object-fit:cover; object-position:center top;
  transition:object-position 1.6s cubic-bezier(.22,1,.36,1); /* the glide back up */
}
.empty.tease:hover .tease-media img{
  object-position:center bottom;
  transition:object-position 28s cubic-bezier(.2,.2,.7,.9); /* starts moving right away, cruises, lands soft */
}
.empty.tease::before{
  content:""; position:absolute; inset:0; z-index:1;
  background:linear-gradient(180deg, rgba(16,29,60,.72) 0%, rgba(16,29,60,.88) 100%);
  transition:opacity .6s ease;
}
.empty.tease:hover::before{opacity:.72} /* shade thins so the site shows through while it scrolls */
.empty.tease > h2, .empty.tease > p{position:relative; z-index:2}
.empty.tease h2{color:#fff}
.empty.tease p{color:#C9D3E8}
.empty.tease a{color:#8AB4FF; font-weight:700}
.empty.tease a:hover{color:#fff}
@media (prefers-reduced-motion: reduce){
  .empty.tease, .tease-media img, .empty.tease::before{transition:none !important}
  .empty.tease:hover{transform:none}
  .empty.tease:hover .tease-media img{object-position:center top}
}

/* 404 */
.nf{min-height:66vh; display:grid; place-items:center; text-align:center; padding:130px 24px 70px}
.nf-code{font-size:clamp(90px, 17vw, 160px); font-weight:800; line-height:.9; letter-spacing:-.04em; color:#DCE6FB}
.nf h1{font-size:clamp(26px, 4vw, 36px); margin-top:4px}
.nf p{color:var(--muted); font-size:18px; margin:14px auto 28px; max-width:440px}

/* booking — two-column card: our pitch panel (ink) + the Calendly calendar.
   Still only Calendly; the calendar renders on our page. NOTE: the calendar's own
   colours (dark theme) are a Calendly PAID feature — on the free plan it stays light,
   so we frame it in a white panel beside the ink pitch. Upgrade → set background_color
   on the data-url + make .book-cal ink to go fully dark like the reference. */
.book-grid{
  display:grid; grid-template-columns:0.72fr 1fr; align-items:stretch; text-align:left;
  background:#16223F; border:1px solid rgba(255,255,255,.08); border-radius:28px; overflow:hidden;
  box-shadow:0 44px 90px -44px rgba(0,0,0,.55);
}
.book-pitch{display:flex; flex-direction:column; justify-content:center; padding:44px 42px; color:#fff}
.book-face{
  width:78px; height:78px; border-radius:20px; object-fit:cover; object-position:top;
  border:1px solid rgba(255,255,255,.18); margin-bottom:22px;
}
.book-eyebrow{
  font-size:12.5px; letter-spacing:.16em; text-transform:uppercase; font-weight:800;
  color:#8AB4FF; margin-bottom:14px;
}
.book-pitch h2{color:#fff; font-size:clamp(28px,3vw,38px); line-height:1.12; letter-spacing:-.02em}
.book-pitch > p{color:#B9C3D8; font-size:16px; margin:14px 0 24px; max-width:42ch; text-wrap:pretty}
.book-checks{list-style:none; display:flex; flex-direction:column; gap:13px; margin-bottom:28px}
.book-checks li{display:flex; gap:12px; align-items:center; font-weight:600; font-size:15.5px; color:#EAF0FA}
.book-checks svg{flex:none}
.book-social{display:flex; gap:10px}
.book-social a{
  width:40px; height:40px; border-radius:50%; background:#fff; display:grid; place-items:center;
  transition:transform .15s ease, background .15s ease;
}
.book-social a:hover{background:var(--sky); transform:translateY(-2px)}
.book-cal{background:#fff}
.book-cal .calendly-inline-widget{width:100%; height:700px} /* Calendly's own default embed height — fits the month view; data-resize auto-height was tried 2026-08-04 and collapsed the iframe in real browsers */
@media (max-width:860px){
  .book-grid{grid-template-columns:1fr}
  .book-pitch{padding:38px 28px 30px; justify-content:flex-start}
  .book-cal .calendly-inline-widget{height:760px}
}
@media (max-width:480px){ .book-pitch{padding:32px 22px 26px} }

/* contact — "Let's get started" header + info cards, on the dark #book section (reference-style) */
.contact-head{max-width:640px; margin:0 auto}
.contact-badge{
  display:inline-flex; align-items:center; gap:8px; margin-bottom:22px;
  background-color:var(--ink); background-image:linear-gradient(rgba(37,99,235,.14), rgba(37,99,235,.14)); border:1px solid rgba(37,99,235,.42);
  color:#8AB4FF; font-size:12.5px; font-weight:800; letter-spacing:.13em; text-transform:uppercase;
  padding:9px 20px; border-radius:999px;
}
.contact-head h2{color:#fff; font-size:clamp(34px,4.6vw,52px); letter-spacing:-.02em; line-height:1.08}
.contact-head p{color:#B9C3D8; font-size:17.5px; margin-top:18px; text-wrap:pretty}
.contact-cards{display:grid; grid-template-columns:repeat(3,1fr); gap:18px; margin:46px auto 58px; max-width:940px}
.cinfo{
  /* same white tint as before, composited onto solid ink: identical look, but opaque so the
     section's dot texture never shows through the card (longhands: var() breaks bg shorthand layers) */
  background-color:var(--ink);
  background-image:linear-gradient(rgba(255,255,255,.035), rgba(255,255,255,.035));
  border:1px solid rgba(255,255,255,.09); border-radius:20px;
  padding:32px 20px 28px; text-align:center;
  transition:transform .18s ease, border-color .18s ease, background .18s ease;
}
.cinfo:hover{transform:translateY(-4px); border-color:rgba(138,180,255,.45); background-image:linear-gradient(rgba(255,255,255,.06), rgba(255,255,255,.06))}
.cinfo-ico{
  width:56px; height:56px; border-radius:15px; margin:0 auto 18px;
  background:linear-gradient(145deg,#3B82F6,#2563EB); display:grid; place-items:center;
  box-shadow:0 12px 26px -10px rgba(37,99,235,.7);
}
.cinfo-ico svg{width:25px; height:25px; fill:none; stroke:#fff; stroke-width:1.9; stroke-linecap:round; stroke-linejoin:round}
.cinfo b{display:block; font-size:13px; letter-spacing:.11em; text-transform:uppercase; color:#fff; font-weight:800; margin-bottom:9px}
.cinfo a, .cinfo span{color:#9DB4D8; font-size:15px; font-weight:600; word-break:break-word}
.cinfo a{transition:color .15s ease}
.cinfo a:hover{color:#8AB4FF}
@media (max-width:640px){ .contact-cards{grid-template-columns:1fr; gap:14px; margin:38px auto 44px; max-width:400px} }

/* ============ mobile nav: burger + ink drawer (≤820px) ============ */
/* CSS-only (checkbox) so it works on the no-JS interior pages too; main.js adds link-tap + Esc close on home */
.nav-check{position:absolute; width:1px; height:1px; opacity:0; margin:0}
.nav-burger, .nav-backdrop, .nav-drawer{display:none}
@media (max-width:820px){
  .nav-burger{
    display:flex; flex-direction:column; justify-content:center; align-items:center; gap:5px;
    width:44px; height:44px; margin-right:-8px; flex:none; cursor:pointer; color:var(--ink);
  }
  .nav-burger span{display:block; width:22px; height:2.5px; border-radius:2px; background:currentColor; transition:background .7s ease}
  .js nav.overlay:not(.scrolled) .nav-burger{color:#fff; filter:drop-shadow(0 1px 6px rgba(16,29,60,.45))}
  .nav-check:focus-visible ~ .nav-burger{outline:3px solid var(--blue); outline-offset:2px; border-radius:8px}

  .nav-backdrop{
    display:block; position:fixed; inset:0; z-index:60; background:rgba(16,29,60,.55);
    opacity:0; pointer-events:none; transition:opacity .35s ease; cursor:pointer;
  }
  .nav-drawer{
    display:flex; flex-direction:column; position:fixed; top:0; bottom:0; left:0; z-index:61;
    width:min(320px, 84vw); background:var(--ink);
    padding:20px 24px calc(26px + env(safe-area-inset-bottom));
    overflow-y:auto; overscroll-behavior:contain;
    transform:translateX(-103%); transition:transform .38s cubic-bezier(.22,1,.36,1);
    box-shadow:0 0 60px rgba(16,29,60,.55);
  }
  .nav-check:checked ~ .nav-backdrop{opacity:1; pointer-events:auto}
  .nav-check:checked ~ .nav-drawer{transform:none}
  body:has(.nav-check:checked){overflow:hidden}

  .drawer-head{display:flex; align-items:center; justify-content:space-between; gap:16px; margin-bottom:22px}
  .drawer-logo{height:36px; width:auto}
  .drawer-x{
    display:flex; align-items:center; justify-content:center; flex:none;
    width:36px; height:36px; border-radius:10px; background:var(--blue); cursor:pointer;
    transition:background .15s ease, transform .15s ease;
  }
  .drawer-x:hover{background:var(--blue-dark)}
  .drawer-x:active{transform:scale(.92)}

  .drawer-links{display:flex; flex-direction:column}
  .drawer-links a{padding:14px 2px; font-weight:600; font-size:17px; color:#fff; transition:color .15s ease}
  .drawer-links a:hover, .drawer-links a:active{color:#8AB4FF}
  .drawer-cta{margin-top:16px; justify-content:center}
}
@media (max-width:480px){
  .nav-inner{gap:16px}
  .nav-logo svg{height:38px}
  .nav-cta{padding:10px 17px; font-size:14px}
}
@media (prefers-reduced-motion: reduce){
  .nav-drawer, .nav-backdrop{transition:none}
}

/* ===== on-site booking picker — replaces the Calendly iframe when a slot feed is available ===== */
@keyframes avpCellIn{from{opacity:0; transform:scale(.55)} to{opacity:1; transform:none}}
@keyframes avpGridNext{from{opacity:0; transform:translateX(16px)} to{opacity:1; transform:none}}
@keyframes avpGridPrev{from{opacity:0; transform:translateX(-16px)} to{opacity:1; transform:none}}
@keyframes avpRowIn{from{opacity:0; transform:translateY(10px)} to{opacity:1; transform:none}}
@keyframes avpPop{from{transform:scale(.72)} to{transform:none}}
@keyframes avpNextIn{from{opacity:0; transform:translateX(-8px)} to{opacity:1; transform:none}}
@keyframes avpFadeDown{from{opacity:0; transform:translateY(-8px)} to{opacity:1; transform:none}}
.avp{padding:26px 20px 22px}
.avp h3{font-size:18px; font-weight:800; text-align:center; letter-spacing:-.01em; margin:0 0 14px; color:var(--ink)}
.avp-cols{display:flex; justify-content:center; gap:4px}
.avp-cal{width:100%; max-width:340px; flex:none}
.avp-nav{display:flex; align-items:center; justify-content:center; gap:22px; margin-bottom:12px}
.avp-nav b{font-size:15px; font-weight:700; color:var(--blue)}
.avp-nav button{font-family:inherit; width:32px; height:32px; border-radius:50%; border:none; background:transparent; color:var(--blue); font-size:18px; font-weight:700; cursor:pointer; line-height:1}
.avp-nav button:hover{background:var(--sky)}
.avp-nav button:disabled{color:#B9C3D8; cursor:default; background:transparent}
.avp-dow, .avp-grid{display:grid; grid-template-columns:repeat(7,1fr); justify-items:center}
.avp-dow{margin-bottom:6px}
.avp-dow span{font-size:11.5px; font-weight:600; color:var(--muted)}
.avp-grid{row-gap:4px}
.avp-grid.boot .avp-d{animation:avpCellIn .38s cubic-bezier(.22,1,.36,1) both; animation-delay:calc(var(--i, 0) * 9ms)}
.avp-grid.mnext{animation:avpGridNext .26s cubic-bezier(.22,1,.36,1) both}
.avp-grid.mprev{animation:avpGridPrev .26s cubic-bezier(.22,1,.36,1) both}
.avp-d{
  width:40px; height:40px; border-radius:50%; border:none; background:transparent;
  font-family:inherit; font-size:14px; font-weight:600; color:#9AA4B8; position:relative;
  display:flex; align-items:center; justify-content:center; transition:background-color .15s ease;
}
.avp-d.avail{background:var(--sky); color:var(--blue); font-weight:800; cursor:pointer}
.avp-d.avail:hover{background:#D8E5FF}
.avp-d.sel{background:var(--blue); color:#fff; animation:avpPop .3s cubic-bezier(.22,1,.36,1)}
.avp-d.today::after{content:""; position:absolute; bottom:4px; left:50%; transform:translateX(-50%); width:4px; height:4px; border-radius:50%; background:currentColor}
.avp-tz{margin-top:14px}
.avp-tz b{display:block; font-size:13px; font-weight:800; margin-bottom:4px; color:var(--ink)}
.avp-tz > span{font-size:12.5px; color:var(--muted); font-weight:600; display:inline-flex; align-items:center; gap:6px}
.avp-times{width:0; opacity:0; overflow:hidden; flex:none; transition:width .45s cubic-bezier(.22,1,.36,1), opacity .3s ease .1s}
.avp.open .avp-times{width:212px; opacity:1}
.avp-times h4{font-size:13.5px; font-weight:600; color:var(--ink); margin:4px 0 12px; white-space:nowrap; animation:avpFadeDown .3s cubic-bezier(.22,1,.36,1) both}
.avp-list{display:flex; flex-direction:column; gap:9px; max-height:380px; overflow-y:auto; padding:2px 10px 2px 2px; scrollbar-width:thin}
.avp-row{display:flex; gap:7px; flex:none; animation:avpRowIn .34s cubic-bezier(.22,1,.36,1) both; animation-delay:calc(var(--i, 0) * 26ms)}
.avp-t{
  font-family:inherit; flex:1; padding:11px 4px; text-align:center; cursor:pointer;
  border:1px solid #BFD3FC; border-radius:8px; background:#fff; font-size:14px; font-weight:800; color:var(--blue);
  transition:border-color .15s ease, background-color .18s ease, color .18s ease;
}
.avp-t:hover{border-color:var(--blue)}
.avp-row.picked .avp-t{background:var(--muted); border-color:var(--muted); color:#fff; cursor:default}
.avp-next{font-family:inherit; flex:1; display:none; padding:11px 4px; text-align:center; cursor:pointer; border:none; border-radius:8px; background:var(--blue); color:#fff; font-size:14px; font-weight:800}
.avp-next:hover{background:var(--blue-dark)}
.avp-row.picked .avp-next{display:block; animation:avpNextIn .2s cubic-bezier(.22,1,.36,1) both}
@media (max-width:640px){
  .avp-cols{flex-direction:column; align-items:center}
  .avp.open .avp-times{width:100%; max-width:340px}
  .avp-times h4{text-align:center}
  .avp-list{max-height:280px}
}
/* desktop (two-column booking card): the picker owns the whole white panel —
   fills its height, centers vertically, and scales up to the panel's width */
@media (min-width:861px){
  .book-cal{display:flex}
  .avp{flex:1; display:flex; flex-direction:column; justify-content:center; padding:34px 24px}
  .avp h3{font-size:21px; margin-bottom:20px}
  .avp-cols{gap:16px}
  .avp-cal{max-width:340px} /* 340 + 16 + 218 = 574 = panel inner width; cal never resizes on open */
  .avp-nav b{font-size:16.5px}
  .avp-nav button{width:36px; height:36px; font-size:20px}
  .avp-dow span{font-size:12.5px}
  .avp-grid{row-gap:7px}
  .avp-d{width:47px; height:47px; font-size:15.5px}
  .avp.open .avp-times{width:218px}
  .avp-times h4{font-size:15px; margin:6px 0 14px}
  .avp-list{max-height:440px; gap:10px}
  .avp-t, .avp-next{font-size:15px; padding:13px 6px}
  .avp-tz{margin-top:20px}
  .avp-tz b{font-size:14px}
  .avp-tz > span{font-size:13.5px}
}
@media (prefers-reduced-motion: reduce){
  .avp, .avp *{animation:none !important; transition:none !important}
}

/* ---- pricing detail: value breakdown (pricing.html) ---- */
.value-head{text-align:center; max-width:640px; margin:0 auto 40px}
.value-head h2{font-size:clamp(24px,3.4vw,32px); font-weight:800; letter-spacing:-.02em; color:var(--ink); margin-bottom:10px; text-wrap:balance}
.value-head p{color:var(--muted); font-size:16.5px; line-height:1.6; text-wrap:pretty}
.value-grid{display:grid; grid-template-columns:repeat(3,1fr); gap:36px; max-width:1080px; margin:0 auto}
.vcol{min-width:0}
.vcol h3{font-size:17px; font-weight:800; color:var(--ink); letter-spacing:-.01em; margin-bottom:14px}
.vcol .feat{margin-bottom:0; font-size:15.5px}
@media (max-width:900px){
  .value-grid{grid-template-columns:1fr; gap:32px; max-width:560px}
}
/* pricing: scope note ("what's not included"). Deliberately quiet — a hairline-ruled block in
   muted body copy, NOT a warning box: the point is to set expectations before a call, not to
   make the page feel defensive. Matches .vcol h3 sizing so it reads as part of the same section. */
.scope-note{
  max-width:1080px; margin:52px auto 0; padding-top:30px;
  border-top:1px solid var(--line);
}
.scope-note h3{font-size:17px; font-weight:800; color:var(--ink); letter-spacing:-.01em; margin-bottom:12px}
.scope-note p{color:var(--muted); font-size:15.5px; line-height:1.7; max-width:70ch; text-wrap:pretty}
.scope-note p + p{margin-top:12px}

/* ---- reviews section: café photo under an ink scrim (replaces the slate band) ---- */
.work{position:relative; overflow:hidden; background:#0B1430; border-top:0; border-bottom:0}

/* ---- animated gradient behind this band (js/gradient-bg.js) ----
   Replaced the café photo 2026-08-08. The canvas is inserted as the section's
   FIRST child, so .work-scrim still paints over it and white copy stays legible. */
.gbg-canvas{position:absolute; inset:0; width:100%; height:100%; display:block; pointer-events:none; z-index:0}
/* Still approximation of the shader, shown when WebGL is missing or the context
   is lost — so the band never degrades to flat navy. */
.work.gbg-fallback{
  background:
    radial-gradient(80% 62% at 22% 26%, rgba(46,111,208,.55), transparent 62%),
    radial-gradient(72% 66% at 78% 36%, rgba(107,79,168,.5), transparent 66%),
    radial-gradient(95% 72% at 50% 104%, rgba(5,10,24,.92), transparent 70%),
    #0B1430;
}
.work-scrim{
  position:absolute; inset:0;
  /* neutral black, not ink — the blue tint fought the photo (Swash 2026-08-04).
     Lightened 2026-08-08: the old .84/.7 was sized to tame a bright photo and
     would have flattened the gradient. Edges stay darker for text safety. */
  background:linear-gradient(180deg, rgba(0,0,0,.5) 0%, rgba(0,0,0,.2) 26%, rgba(0,0,0,.2) 74%, rgba(0,0,0,.5) 100%);
}
.work > .wrap{position:relative; z-index:1}
.work h2{color:#fff; text-shadow:0 2px 18px rgba(16,29,60,.5)}
/* Swash 2026-08-04: body copy in THIS section only is pure white, not the
   blue-grey tint. Scoped to .work so the rest of the site is untouched. */
.work .sec-sub{color:#fff}
.work .rf b{color:#fff}
.work .rf p{color:#fff}
.work .rev-note{background:#16223F; border-color:rgba(255,255,255,.1)}
.work .rev-note svg{stroke:#8AB4FF}
.work .rev-note p{color:#fff}
.work .rev-note b{color:#fff}
.work .see-all{color:#8AB4FF}
.work .see-all:hover{color:#fff}

/* ---- contact section texture: dot grid fading toward the footer ----
   The glow is anchored a fixed 100px above this section's BOTTOM edge rather than at
   92% (which drifted with section height, so it could never line up on mobile). That
   lets `footer` continue the identical ellipse from `at 10% -100px`, making the two
   dark surfaces one uninterrupted gradient instead of meeting at a visible line. */
.final.contact{
  position:relative;
  background:
    radial-gradient(900px 520px at 10% calc(100% - 100px), rgba(37,99,235,.14), transparent 62%),
    var(--ink);
}
.final.contact::before{
  content:""; position:absolute; inset:0; z-index:2; pointer-events:none;
  background-image:
    radial-gradient(circle, rgba(138,180,255,.17) 1px, transparent 1.6px),
    radial-gradient(circle, rgba(255,255,255,.09) 1px, transparent 1.6px);
  background-size:22px 22px, 44px 44px;
  background-position:0 0, 11px 11px;
  -webkit-mask-image:linear-gradient(180deg, transparent 0, #000 9%, #000 52%, transparent 94%);
  mask-image:linear-gradient(180deg, transparent 0, #000 9%, #000 52%, transparent 94%);
}
.final.contact > .wrap{position:relative; z-index:3}

/* ---- animated gradient behind the contact band (Swash 2026-08-08) ----
   The canvas is MASKED to fade out over the lower third. That is deliberate:
   the rule above anchors this section's glow 100px above its BOTTOM edge so
   `footer` can continue the identical ellipse from `at 10% -100px`. The canvas
   is opaque, so covering that area would bury the glow and reinstate exactly
   the seam fixed on 2026-08-04. Fading it out lets the ink + glow show through
   at the bottom, and the footer needs no change at all.
   Explicit stack, since three layers now share this section:
   canvas 0 · scrim 1 · dot texture 2 · content 3. */
.final.contact .gbg-canvas{
  -webkit-mask-image:linear-gradient(180deg, #000 0%, #000 52%, transparent 82%);
  mask-image:linear-gradient(180deg, #000 0%, #000 52%, transparent 82%);
}
/* Scrim fades out on the same curve as the canvas mask, so it never darkens the
   glow region below it. */
.final.contact::after{
  content:""; position:absolute; inset:0; z-index:1; pointer-events:none;
  background:linear-gradient(180deg, rgba(0,0,0,.5) 0%, rgba(0,0,0,.2) 26%, rgba(0,0,0,.2) 62%, rgba(0,0,0,0) 82%);
}
.final.contact.gbg-fallback{
  background:
    radial-gradient(80% 52% at 22% 20%, rgba(46,111,208,.5), transparent 62%),
    radial-gradient(72% 50% at 78% 30%, rgba(107,79,168,.45), transparent 66%),
    radial-gradient(900px 520px at 10% calc(100% - 100px), rgba(37,99,235,.14), transparent 62%),
    var(--ink);
}

/* same dot texture inside the interior pages' bottom-CTA box (pricing, how-it-works,
   portfolio, about, blog) so every dark surface on the site reads as one material */
.final-box{position:relative; overflow:hidden}
.final-box::before{
  content:""; position:absolute; inset:0; z-index:2; pointer-events:none;
  background-image:
    radial-gradient(circle, rgba(138,180,255,.17) 1px, transparent 1.6px),
    radial-gradient(circle, rgba(255,255,255,.09) 1px, transparent 1.6px);
  background-size:22px 22px, 44px 44px;
  background-position:0 0, 11px 11px;
  -webkit-mask-image:linear-gradient(180deg, transparent 0, #000 9%, #000 52%, transparent 94%);
  mask-image:linear-gradient(180deg, transparent 0, #000 9%, #000 52%, transparent 94%);
}
.final-box > *{position:relative; z-index:3}

/* ---- animated gradient inside the interior-page CTA box (Swash 2026-08-08) ----
   Same stack as .final.contact: canvas 0 · scrim 1 · dot texture 2 · content 3.
   The canvas MUST be pulled back out of `.final-box > *`, which matches the
   injected canvas too and — being declared later at equal specificity (0,1,0) —
   beat BOTH of `.gbg-canvas`'s own declarations. It overrode `position:absolute`
   with `position:relative`, dropping the canvas into the flow where `height:100%`
   inflated this box from ~350px to 1516px, and it overrode `z-index:0` with 3,
   putting the canvas on top of the copy. `.final-box .gbg-canvas` is (0,2,0), so
   it wins back both. `overflow:hidden` + `border-radius:32px` on the parent clip
   the canvas to the rounded card, so no extra masking is needed here. */
.final-box .gbg-canvas{position:absolute; z-index:0}
.final-box::after{
  content:""; position:absolute; inset:0; z-index:1; pointer-events:none;
  background:linear-gradient(180deg, rgba(0,0,0,.45) 0%, rgba(0,0,0,.2) 30%, rgba(0,0,0,.2) 70%, rgba(0,0,0,.45) 100%);
}
.final-box.gbg-fallback{
  background:
    radial-gradient(85% 70% at 22% 24%, rgba(46,111,208,.55), transparent 62%),
    radial-gradient(75% 72% at 78% 38%, rgba(107,79,168,.5), transparent 66%),
    #0B1430;
}

/* ============ Cross-page transitions (2026-08-08 animate pass) ============
   Cross-document view transitions: navigating between pages crossfades instead
   of flashing white. Pure CSS progressive enhancement — a browser without
   support (or with the CSS unloaded) just navigates normally, so the interior
   pages' no-JS guarantee is untouched. The fixed nav carries its own
   view-transition-name: paired separately, an identical bar holds perfectly
   still while the content fades under it (and interior-solid ↔ home-overlay
   crossfades within the pair instead of double-fading with the page).
   Exit faster than entrance per the site's motion convention. */
@view-transition{navigation:auto}
nav{view-transition-name:site-nav}
::view-transition-old(root),
::view-transition-old(site-nav){animation-duration:.18s; animation-timing-function:cubic-bezier(.22,1,.36,1)}
::view-transition-new(root),
::view-transition-new(site-nav){animation-duration:.26s; animation-timing-function:cubic-bezier(.22,1,.36,1)}
@media (prefers-reduced-motion: reduce){
  ::view-transition-group(*),
  ::view-transition-image-pair(*),
  ::view-transition-old(*),
  ::view-transition-new(*){animation:none !important}
}
