/* ==========================================================================
   Altus Digital — shared site stylesheet
   Used by every public page: /, /web-design/, /local-seo/,
   /google-business-profile/, /portfolio/, /about/, /contact/, /grader/.

   css/styles.css is deliberately left alone — /onboarding/ and
   /admin/onboarding/ still depend on its dark theme.

   Adding a page? Copy the header/footer/CTA blocks verbatim from any
   existing page. Every asset path here and in that chrome is root-absolute
   (/assets/…, /css/…) so the markup is identical at any folder depth.
   ========================================================================== */

/* ===== Fonts (same files as the rest of the site — already cached) ===== */
@font-face{ font-family:'Clash Display'; src:url('/assets/fonts/clash-display-500.woff2') format('woff2'); font-weight:500; font-style:normal; font-display:swap; }
@font-face{ font-family:'Clash Display'; src:url('/assets/fonts/clash-display-600.woff2') format('woff2'); font-weight:600; font-style:normal; font-display:swap; }
@font-face{ font-family:'Clash Display'; src:url('/assets/fonts/clash-display-700.woff2') format('woff2'); font-weight:700; font-style:normal; font-display:swap; }
@font-face{ font-family:'Satoshi'; src:url('/assets/fonts/satoshi-400.woff2') format('woff2'); font-weight:400; font-style:normal; font-display:swap; }
@font-face{ font-family:'Satoshi'; src:url('/assets/fonts/satoshi-500.woff2') format('woff2'); font-weight:500; font-style:normal; font-display:swap; }
@font-face{ font-family:'Satoshi'; src:url('/assets/fonts/satoshi-700.woff2') format('woff2'); font-weight:700; font-style:normal; font-display:swap; }
@font-face{ font-family:'JetBrains Mono'; src:url('/assets/fonts/jetbrains-mono-500.woff2') format('woff2'); font-weight:500; font-style:normal; font-display:swap; }

/* ===== Tokens =====
   Altus is dark-first: near-black ground, layered graphite surfaces, one
   electric blue. The legacy names (--paper, --ink, --slate, --line) are kept
   and remapped rather than renamed, so every page and component that already
   speaks them inverts with the system instead of needing a rewrite. */
:root{
  /* Ground — four steps of near-black, used to separate sections without
     drawing a single border. Never pure #000: it reads as a hole on OLED. */
  --bg-deep:#05070A;         /* hero, final CTA — the darkest moment */
  --bg:#090C12;              /* page base */
  --bg-graphite:#0D1117;     /* alternate band */
  --bg-char:#0B0F15;         /* charcoal band, between base and graphite */

  /* Elevated surfaces — cards, mockups, nav, forms */
  --surface:#11161E;
  --surface-2:#161C26;
  --surface-3:#1D2531;

  /* Legacy ground names, remapped */
  --paper:var(--bg);
  --paper-soft:var(--bg-graphite);

  /* Type ramp. Measured against --bg: 17.9:1 / 11.6:1 / 6.6:1. */
  --ink:#F2F5F9;             /* primary   — near-white */
  --ink-soft:#C6CEDA;        /* secondary — cool light gray */
  --slate:#8E98A8;           /* tertiary  — muted, still AA at 16px */
  --on-blue:#FFFFFF;

  /* Altus electric blue. --blue is a FILL (white on it is 5.2:1);
     --blue-bright is the TEXT/LINK value (5.9:1 on --bg). Using --blue for
     small text would land at 3.7:1, which is why the two are separate. */
  --blue:#0A5CFF;
  --blue-hover:#2B77FF;
  --blue-bright:#3D8BFF;
  --blue-deep:#0038A8;
  --tint:rgba(10,92,255,.12);
  --glow:rgba(10,92,255,.40);
  --glow-soft:rgba(10,92,255,.16);

  /* Hairlines — alpha, so they sit correctly on any of the grounds */
  --line:rgba(255,255,255,.075);
  --line-strong:rgba(255,255,255,.16);

  --font-display:'Clash Display','Satoshi',sans-serif;
  --font-body:'Satoshi',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;
  --font-mono:'JetBrains Mono',ui-monospace,SFMono-Regular,monospace;

  --wrap:1180px;
  --ease:cubic-bezier(.4,0,.2,1);
  /* On a dark ground a grey shadow is invisible; depth comes from a black
     drop plus a 1px light rim on the surface itself. */
  --shadow-card:0 1px 0 rgba(255,255,255,.04) inset, 0 18px 40px -24px rgba(0,0,0,.9);
  --shadow-card-hover:0 1px 0 rgba(255,255,255,.06) inset, 0 28px 60px -28px rgba(0,0,0,1);
  --shadow-lift:0 40px 90px -40px rgba(0,0,0,1);
}

*,*::before,*::after{ box-sizing:border-box; }

/* scroll-padding keeps anchor targets clear of the 70px sticky header —
   without it every in-page nav link lands with its heading behind the bar */
html{ scroll-behavior:smooth; scroll-padding-top:90px; -webkit-text-size-adjust:100%; }
body{
  margin:0;
  background:var(--paper);
  color:var(--ink);
  font-family:var(--font-body);
  font-size:17px;
  line-height:1.6;
  -webkit-font-smoothing:antialiased;
  -moz-osx-font-smoothing:grayscale;
}
img{ max-width:100%; height:auto; display:block; }
a{ color:inherit; text-decoration:none; }
ul{ margin:0; padding:0; list-style:none; }
h1,h2,h3,h4{ font-family:var(--font-display); font-weight:600; margin:0; letter-spacing:-.03em; line-height:1.1; }
p{ margin:0; }
button{ font-family:inherit; }

:focus-visible{
  outline:2px solid var(--blue-bright);
  outline-offset:3px;
  border-radius:4px;
}

.wrap{ max-width:var(--wrap); margin:0 auto; padding:0 2rem; }

.sr-only{
  position:absolute; width:1px; height:1px; padding:0; margin:-1px;
  overflow:hidden; clip:rect(0,0,0,0); white-space:nowrap; border:0;
}
.skip-link{
  position:absolute; left:1rem; top:-4rem;
  background:var(--blue); color:#fff;
  padding:.7rem 1.1rem; border-radius:8px; z-index:200;
  font-size:.9rem; transition:top .2s var(--ease);
}
.skip-link:focus{ top:1rem; }

/* ===== Reveal on scroll — opacity + a few px, nothing more ===== */
.reveal{
  opacity:0;
  transform:translateY(14px);
  transition:opacity .6s var(--ease), transform .6s var(--ease);
}
.reveal.is-visible{ opacity:1; transform:none; }
@media (prefers-reduced-motion: reduce){
  html{ scroll-behavior:auto; }
  .reveal{ opacity:1; transform:none; transition:none; }
}

/* ===== Buttons: exactly two styles, used everywhere ===== */
.btn{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  gap:.5rem;
  padding:.9rem 1.5rem;
  border-radius:10px;
  border:1px solid transparent;
  font-family:var(--font-body);
  font-size:.98rem;
  font-weight:700;
  letter-spacing:-.01em;
  line-height:1.2;
  cursor:pointer;
  white-space:nowrap;
  transition:background .18s var(--ease), border-color .18s var(--ease),
             color .18s var(--ease), transform .18s var(--ease);
}
/* "Book Your Free Growth Assessment" is wider than a 320px screen's content
   box, and nowrap made it push the page into horizontal scroll. Only the
   smallest phones need the label to break. */
@media (max-width:400px){
  .btn{ white-space:normal; padding-left:1.1rem; padding-right:1.1rem; }
}
.btn-primary{ background:var(--blue); color:#fff; }
.btn-primary:hover{ background:var(--blue-hover); transform:translateY(-1px); }
.btn-primary:active{ transform:translateY(0); }

.btn-secondary{ background:transparent; color:var(--ink); border-color:var(--line-strong); }
.btn-secondary:hover{ background:rgba(255,255,255,.07); border-color:var(--ink-soft); transform:translateY(-1px); }
.btn-secondary:active{ transform:translateY(0); }

.btn-sm{ padding:.65rem 1.1rem; font-size:.9rem; border-radius:9px; }
.btn-block{ width:100%; }

/* ===== Header ===== */
.h-header{
  position:sticky;
  top:0;
  z-index:100;
  background:rgba(255,255,255,.82);
  backdrop-filter:saturate(180%) blur(18px);
  -webkit-backdrop-filter:saturate(180%) blur(18px);
  border-bottom:1px solid transparent;
  transition:border-color .25s var(--ease), box-shadow .25s var(--ease);
}
.h-header.is-scrolled{
  border-bottom-color:var(--line);
  box-shadow:0 1px 20px -8px rgba(0,0,0,.14);
}
.h-header-inner{
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:2rem;
  height:70px;
}
.h-brand{
  display:inline-flex;
  align-items:center;
  gap:.6rem;
  font-family:var(--font-display);
  font-weight:600;
  font-size:1.08rem;
  letter-spacing:-.02em;
  color:var(--ink);
  flex:0 0 auto;
}
.h-brand em{ font-style:normal; color:var(--blue); }
.h-brand img{ height:26px; width:auto; }

.h-nav{ display:flex; align-items:center; gap:2.25rem; margin-left:auto; }
.h-nav-cta{ display:none; }
.h-nav > a, .h-menu-btn{
  font-family:var(--font-body);
  font-size:.95rem;
  font-weight:500;
  color:var(--slate);
  transition:color .18s var(--ease);
}
.h-nav > a:hover, .h-nav > a.is-active{ color:var(--ink); }

/* ===== Services dropdown ===== */
.h-menu{ position:relative; }
.h-menu-btn{
  display:inline-flex;
  align-items:center;
  gap:.4rem;
  padding:0;
  background:none;
  border:0;
  cursor:pointer;
}
.h-menu-btn:hover, .h-menu-btn[aria-expanded="true"], .h-menu.is-current .h-menu-btn{ color:var(--ink); }
.h-menu-btn svg{
  width:11px; height:11px;
  transition:transform .2s var(--ease);
}
.h-menu-btn[aria-expanded="true"] svg{ transform:rotate(180deg); }

.h-menu-list{
  position:absolute;
  top:calc(100% + 1.15rem);
  left:50%;
  transform:translateX(-50%) translateY(-6px);
  min-width:270px;
  padding:.5rem;
  background:var(--surface);
  border:1px solid var(--line);
  border-radius:14px;
  box-shadow:0 1px 2px rgba(0,0,0,.04), 0 20px 44px -16px rgba(0,0,0,.22);
  opacity:0;
  visibility:hidden;
  transition:opacity .18s var(--ease), transform .18s var(--ease), visibility .18s;
}
.h-menu-btn[aria-expanded="true"] + .h-menu-list{
  opacity:1;
  visibility:visible;
  transform:translateX(-50%) translateY(0);
}
.h-menu-list a{
  display:block;
  padding:.75rem .85rem;
  border-radius:9px;
  color:var(--ink);
  font-size:.94rem;
  font-weight:500;
  transition:background .15s var(--ease);
}
.h-menu-list a span{
  display:block;
  margin-top:.15rem;
  font-size:.82rem;
  font-weight:400;
  color:var(--slate);
}
.h-menu-list a:hover{ background:var(--paper-soft); }
.h-menu-list a.is-active{ background:var(--tint); color:var(--blue); }
.h-menu-list a.is-active span{ color:var(--blue); opacity:.75; }

.h-actions{ display:flex; align-items:center; gap:.75rem; flex:0 0 auto; }

.h-toggle{
  display:none;
  flex-direction:column;
  justify-content:center;
  gap:5px;
  width:40px; height:40px;
  padding:0;
  background:transparent;
  border:1px solid var(--line-strong);
  border-radius:9px;
  cursor:pointer;
}
.h-toggle span{
  display:block; height:1.5px; margin:0 9px;
  background:var(--ink);
  transition:transform .22s var(--ease), opacity .22s var(--ease);
}
.h-toggle[aria-expanded="true"] span:nth-child(1){ transform:translateY(6.5px) rotate(45deg); }
.h-toggle[aria-expanded="true"] span:nth-child(2){ opacity:0; }
.h-toggle[aria-expanded="true"] span:nth-child(3){ transform:translateY(-6.5px) rotate(-45deg); }

/* ===== Sections ===== */
.section{ padding:5.75rem 0; }
.section-soft{ background:var(--paper-soft); }
.section-line{ border-top:1px solid var(--line); }

.eyebrow{
  font-family:var(--font-mono);
  font-size:.68rem;
  font-weight:500;
  letter-spacing:.18em;
  text-transform:uppercase;
  color:var(--blue);
  margin-bottom:1.35rem;
}
.section-head{ max-width:44rem; margin-bottom:3rem; }
.section-head-center{ margin-left:auto; margin-right:auto; text-align:center; }
.section-title{
  font-size:clamp(2.1rem,4.5vw,3.15rem);
  letter-spacing:-.035em;
  text-wrap:balance;
}
.section-lede{
  margin-top:1.25rem;
  font-size:1.1rem;
  line-height:1.6;
  color:var(--slate);
  max-width:52ch;
}
.section-head-center .section-lede{ margin-left:auto; margin-right:auto; }

/* ===== Hero ===== */
.hero{ padding:5rem 0 4rem; }
.hero-inner{ max-width:56rem; }
.hero-title{
  font-size:clamp(2.5rem,5.6vw,4.15rem);
  line-height:1.04;
  letter-spacing:-.04em;
  max-width:20ch; /* the headline is a full sentence — 16ch turned it into a column */
}
.hero-sub{
  margin-top:1.9rem;
  font-size:1.2rem;
  line-height:1.6;
  color:var(--slate);
  max-width:50ch;
}
.hero-ctas{ margin-top:2.75rem; display:flex; gap:.9rem; flex-wrap:wrap; }

/* ===== Card grid ===== */
/* Grid and flex children default to min-width:auto, so one wide child — the
   a wide demo screenshot is the usual offender — can force its track wider than the
   viewport and push the whole page into horizontal scroll on phones.
   Pinning min-width:0 lets the single-column mobile layouts actually fit. */
.grid > *,
.split > *,
.annotated > *,

.grid{ display:grid; gap:1.5rem; }
.grid-3{ grid-template-columns:repeat(3,1fr); }
.grid-2{ grid-template-columns:repeat(2,1fr); }

.card{
  background:var(--surface);
  border:1px solid var(--line);
  border-radius:16px;
  padding:2.25rem 2rem;
  box-shadow:var(--shadow-card);
  transition:box-shadow .25s var(--ease), transform .25s var(--ease), border-color .25s var(--ease);
}
.card:hover{
  box-shadow:var(--shadow-card-hover);
  transform:translateY(-3px);
  border-color:var(--line-strong);
}
.card-icon{
  width:40px; height:40px;
  margin-bottom:1.5rem;
  color:var(--blue);
}
.card-icon svg{ width:100%; height:100%; display:block; }

/* ===== Compact problem card (Why it matters) =====
   Deliberately lighter than the service card below it: a small ringed icon,
   tighter type, no artwork — so the two sections never read as the same block. */
.card-compact{ padding:1.9rem 1.75rem; }
.icon-ring{
  width:46px; height:46px;
  margin-bottom:1.35rem;
  border-radius:50%;
  border:1px solid var(--line-strong);
  background:var(--tint);
  color:var(--blue);
  display:flex;
  align-items:center;
  justify-content:center;
}
.icon-ring svg{ width:20px; height:20px; display:block; }
.card-compact h3{ font-size:1.05rem; }
.card-compact > p{ font-size:.94rem; }

/* ===== Service card with artwork (What we do) =====
   The illustration panel is what makes this section visually distinct. */
.card-feature{ padding:0; overflow:hidden; }
.feature-art{
  height:132px;
  display:flex;
  align-items:center;
  justify-content:center;
  background:var(--paper-soft);
  border-bottom:1px solid var(--line);
}
.feature-art svg{ width:76%; max-width:210px; height:auto; display:block; }
/* Painted through classes, not presentation attributes — var() is unreliable
   as an attribute value but perfectly safe in a stylesheet. */
.art-line{ stroke:var(--line-strong); }
.art-accent{ stroke:var(--blue); }
.art-fill{ fill:var(--blue); }
.art-dot{ fill:var(--line-strong); }
.card-feature-body{ padding:1.85rem 1.75rem 2rem; }
.card-feature h3{ font-size:1.15rem; margin-bottom:.6rem; }
.card-feature p{ color:var(--slate); font-size:.96rem; }
.card-feature .card-list{ margin-top:1.4rem; }
.card h3{ font-size:1.2rem; margin-bottom:.7rem; }
.card > p{ color:var(--slate); font-size:.98rem; }
.card-list{ margin-top:1.5rem; display:flex; flex-direction:column; gap:.6rem; }
.card-list li{
  position:relative;
  padding-left:1.5rem;
  font-size:.93rem;
  color:var(--ink-soft);
}
.card-list li::before{
  content:"";
  position:absolute;
  left:0; top:.55em;
  width:6px; height:6px;
  border-radius:50%;
  background:var(--blue);
}

/* ===== Service card: inline "Learn more" =====
   Same 0fr -> 1fr grid technique as .faq-a, so nothing measures heights in JS. */
.card-toggle{
  margin-top:.85rem;
  padding:0;
  min-height:44px; /* comfortable tap target — the text alone is only 21px tall */
  background:none;
  border:0;
  font-family:var(--font-body);
  font-size:.94rem;
  font-weight:600;
  color:var(--blue);
  cursor:pointer;
  display:inline-flex;
  align-items:center;
  gap:.45rem;
}
.card-toggle-icon{
  position:relative;
  width:9px; height:9px;
  flex:none;
}
.card-toggle-icon::before,
.card-toggle-icon::after{
  content:"";
  position:absolute;
  left:50%; top:50%;
  width:9px; height:1.6px;
  background:currentColor;
  border-radius:1px;
  transform:translate(-50%,-50%);
  transition:transform .25s var(--ease), opacity .25s var(--ease);
}
.card-toggle-icon::after{ transform:translate(-50%,-50%) rotate(90deg); }
.card-toggle[aria-expanded="true"] .card-toggle-icon::after{
  transform:translate(-50%,-50%) rotate(0deg);
  opacity:0;
}
.card-more{
  display:grid;
  grid-template-rows:0fr;
  transition:grid-template-rows .3s var(--ease);
}
.card-more > div{ overflow:hidden; min-height:0; }
.card-toggle[aria-expanded="true"] + .card-more{ grid-template-rows:1fr; }
/* .card-list carries a 1.5rem top margin by default; the open panel wants less */
.card-more .card-list{ margin-top:1.1rem; }

/* ===== "View all" link under a section grid ===== */
.section-more{ margin-top:2rem; }

/* ===== Roadmap: the process as a path you move through =====
   The cursor's vertical position over the stage drives the traveller along the
   SVG path and opens the nearest step. Click and keyboard focus do the same
   thing, so it works without a pointer. */
.roadmap{
  display:grid;
  grid-template-columns:88px 1fr;
  gap:1.75rem;
  align-items:stretch;
  margin-top:4rem;
  min-height:380px;
}
.roadmap-svg{ width:100%; height:100%; display:block; }
.roadmap-track{ stroke:var(--line-strong); }
.roadmap-fill{
  stroke:var(--blue);
  stroke-linecap:round;
  stroke-dasharray:var(--path-len,900);
  stroke-dashoffset:var(--path-len,900);
}
.roadmap-dot{ fill:var(--blue); stroke:#fff; stroke-width:3; }

.roadmap-steps{
  display:flex;
  flex-direction:column;
  justify-content:center;
  gap:.35rem;
}
.roadmap-step{
  all:unset;
  box-sizing:border-box;
  display:block;
  width:100%;
  padding:1.1rem 1.35rem;
  border:1px solid transparent;
  border-radius:12px;
  cursor:pointer;
  transition:background .25s var(--ease), border-color .25s var(--ease), box-shadow .25s var(--ease);
}
.roadmap-step:hover{ background:var(--surface); }
.roadmap-step:focus-visible{
  outline:2px solid var(--blue-bright);
  outline-offset:2px;
}
.roadmap-step.is-active{
  background:var(--surface);
  border-color:var(--line);
  box-shadow:var(--shadow-card);
}
.roadmap-step-head{ display:flex; align-items:baseline; gap:1rem; }
.roadmap-step h3{
  font-family:var(--font-display);
  font-weight:600;
  font-size:1.15rem;
  letter-spacing:-.02em;
  margin:0;
  color:var(--slate);
  transition:color .25s var(--ease);
}
.roadmap-step.is-active h3{ color:var(--ink); }
.step-num{
  font-family:var(--font-mono);
  font-size:.7rem;
  letter-spacing:.14em;
  color:var(--line-strong);
  transition:color .25s var(--ease);
}
.roadmap-step.is-active .step-num{ color:var(--blue); }

.roadmap-step-body{
  display:grid;
  grid-template-rows:0fr;
  transition:grid-template-rows .35s var(--ease);
}
.roadmap-step-body p{
  overflow:hidden;
  min-height:0;
  color:var(--slate);
  font-size:.95rem;
  max-width:58ch;
}
.roadmap-step.is-active .roadmap-step-body{ grid-template-rows:1fr; }
.roadmap-step.is-active .roadmap-step-body p{ padding-top:.6rem; }

@media (prefers-reduced-motion: reduce){
  .roadmap-step, .roadmap-step h3, .step-num, .roadmap-step-body{ transition:none; }
}

/* ===== Who we help ===== */
.who{ display:grid; grid-template-columns:1fr 1.1fr; gap:4.5rem; align-items:start; }
.who-copy p{ color:var(--slate); font-size:1.05rem; }
.who-copy p + p{ margin-top:1.25rem; }
.tags{ display:flex; flex-wrap:wrap; gap:.6rem; margin-top:2rem; }
/* direct children only — a chip that links wraps an arrow in its own span */
.tags > span,
.tags > a{
  font-size:.88rem;
  color:var(--ink-soft);
  border:1px solid var(--line-strong);
  border-radius:999px;
  padding:.45rem 1rem;
  background:var(--surface);
  transition:border-color .18s var(--ease), background .18s var(--ease), color .18s var(--ease);
}
/* Only the industries we have a live demo for are links. The plain chips lost
   their hover state along with this — it promised somewhere to go and there
   wasn't one. */
.tags > a{
  display:inline-flex;
  align-items:center;
  gap:.4rem;
  font-weight:600;
  color:var(--blue);
  border-color:var(--blue);
  background:var(--tint);
}
.tags > a:hover{ background:var(--blue); border-color:var(--blue); color:#fff; }
.tags .tag-go{ transition:transform .18s var(--ease); }
.tags > a:hover .tag-go{ transform:translateX(2px); }

/* ===== Demos ===== */
.demo-card{
  display:flex;
  flex-direction:column;
  background:var(--surface);
  border:1px solid var(--line);
  border-radius:16px;
  overflow:hidden;
  box-shadow:var(--shadow-card);
  transition:box-shadow .25s var(--ease), transform .25s var(--ease), border-color .25s var(--ease);
}
.demo-card:hover{
  box-shadow:var(--shadow-card-hover);
  transform:translateY(-3px);
  border-color:var(--line-strong);
}
.demo-shot{ display:block; background:var(--paper-soft); border-bottom:1px solid var(--line); }
.demo-shot img{
  width:100%;
  height:210px;
  object-fit:cover;
  object-position:center top;
}
.demo-body{ padding:1.6rem 1.75rem 1.85rem; display:flex; flex-direction:column; flex:1 1 auto; }
.demo-tag{
  font-family:var(--font-mono);
  font-size:.64rem;
  letter-spacing:.14em;
  text-transform:uppercase;
  color:var(--slate);
  margin-bottom:.65rem;
}
.demo-card h3{ font-size:1.15rem; margin-bottom:.55rem; }
.demo-card p{ font-size:.95rem; color:var(--slate); margin-bottom:1.4rem; }
.demo-link{
  margin-top:auto;
  align-self:flex-start;
  font-size:.94rem;
  font-weight:600;
  color:var(--blue);
  display:inline-flex;
  align-items:center;
  gap:.4rem;
  transition:gap .18s var(--ease);
}
.demo-link:hover{ gap:.65rem; }

/* ===== Portfolio filtering ===== */
.filters{
  display:flex;
  gap:.6rem;
  flex-wrap:wrap;
  margin-bottom:2.75rem;
}
.filter{
  padding:.6rem 1.15rem;
  border:1px solid var(--line-strong);
  border-radius:999px;
  background:var(--surface);
  font-family:var(--font-body);
  font-size:.93rem;
  font-weight:500;
  color:var(--slate);
  cursor:pointer;
  transition:border-color .18s var(--ease), color .18s var(--ease),
             background .18s var(--ease), transform .18s var(--ease);
}
.filter:hover{ border-color:var(--blue); color:var(--blue); }
.filter.is-active{
  background:var(--blue);
  border-color:var(--blue);
  color:#fff;
}
.filter-count{
  margin-left:.45rem;
  font-family:var(--font-mono);
  font-size:.72em;
  opacity:.65;
}

/* Larger imagery on the portfolio grid than the homepage teaser */
.grid-work .demo-shot img{ height:270px; }
.demo-card{ transition:box-shadow .25s var(--ease), transform .25s var(--ease),
                       border-color .25s var(--ease), opacity .3s var(--ease); }
.demo-card.is-hidden{ display:none; }

.filter-empty{
  padding:3rem 0;
  color:var(--slate);
  font-size:1rem;
}

@media (max-width:640px){
  .grid-work .demo-shot img{ height:200px; }
  .filters{ gap:.45rem; margin-bottom:2rem; }
  .filter{ padding:.5rem .9rem; font-size:.88rem; }
}

/* ===== Pricing ===== */
/* stretch, not start: tiers carry different amounts of copy, and letting each
   card size to its own content leaves them visibly uneven.
   .price-card .btn already has margin-top:auto, so every CTA stays bottom-aligned.
   .pricing-3 is declared here (not after the 960px query) so that query can
   still collapse it to a single column on phones. */

@media (max-width:960px){

}

/* --- Four build tiers -------------------------------------------------
   A quarter of the 1140px measure is tight, so this variant tightens the
   card's padding and type rather than shrinking the wrap. The responsive
   steps (4 -> 2 -> 1) live further down, past the 960px block. */

/* Steering line under the four tiers. */

/* ===== Plan comparison table =====
   The cards sell; this is where someone checks exactly what they get. Wrapped
   in its own overflow-x container so a 4-column table can scroll sideways on a
   phone without ever making the page itself scroll horizontally. */

/* 720px, not 900px: below this the 660px table actually starts to scroll.
   Above it the hint would be telling people to swipe a table that fits. */
@media (max-width:720px){

}
@media (max-width:640px){

}

/* ===== "What's included" detail =====
   Reuses the FAQ accordion. .faq-a was written for a single <p>; allowing a
   <div> lets the panel hold a labelled list without changing the mechanics. */

.price-sub{ margin-top:.5rem; color:var(--slate); font-size:.96rem; }
.price-amount{ margin:1.85rem 0 0; display:flex; align-items:baseline; gap:.5rem; flex-wrap:wrap; }
.price-label{
  font-family:var(--font-mono);
  font-size:.64rem;
  letter-spacing:.12em;
  text-transform:uppercase;
  color:var(--slate);
}
.price-value{
  font-family:var(--font-display);
  font-size:2.5rem;
  font-weight:600;
  letter-spacing:-.03em;
  color:var(--ink);
}
.price-suffix{ font-family:var(--font-body); font-size:1rem; font-weight:500; color:var(--slate); }
.price-note{ font-size:.85rem; color:var(--slate); margin-top:.45rem; }
.price-desc{ margin-top:1.35rem; color:var(--slate); font-size:.96rem; }

.price-features{ margin:1.6rem 0 2rem; display:flex; flex-direction:column; gap:.72rem; }
.price-features li{
  position:relative;
  padding-left:1.65rem;
  font-size:.94rem;
  line-height:1.5;
  color:var(--ink-soft);
}
/* "Everything in Care/Growth" — the hinge that makes the value jump obvious,
   so it gets a + instead of a tick and a heavier weight. */
.price-features li.price-inherit{ font-weight:600; color:var(--ink); }
/* needs to outrank `.price-features li::before`, which draws the tick */
.price-features li.price-inherit::before{
  content:"+";
  border:0;
  transform:none;
  width:auto; height:auto;
  top:-.05em;
  color:var(--blue);
  font-size:1.05rem;
  font-weight:700;
  line-height:1.4;
}
.price-features li::before{
  content:"";
  position:absolute;
  left:0; top:.42em;
  width:11px; height:6px;
  border-left:2px solid var(--blue);
  border-bottom:2px solid var(--blue);
  transform:rotate(-45deg);
}
/* Scope note under the feature list — separated by a hairline and set small
   and grey so it reads as a caveat, not as another benefit. */
.price-more{
  margin:-.6rem 0 1.9rem;
  padding-top:1.1rem;
  border-top:1px solid var(--line);
  font-size:.83rem;
  line-height:1.6;
  color:var(--slate);
}

/* ===== FAQ ===== */
.faq{ max-width:46rem; margin-left:auto; margin-right:auto; }
.faq-item{ border-bottom:1px solid var(--line); }
.faq-q{
  width:100%;
  display:flex;
  align-items:flex-start;
  justify-content:space-between;
  gap:2rem;
  padding:1.6rem 0;
  background:none;
  border:0;
  text-align:left;
  font-family:var(--font-body);
  font-size:1.05rem;
  font-weight:600;
  letter-spacing:-.01em;
  color:var(--ink);
  cursor:pointer;
}
.faq-icon{ position:relative; width:18px; height:18px; flex:0 0 auto; margin-top:.35rem; }
.faq-icon::before, .faq-icon::after{
  content:"";
  position:absolute; top:50%; left:50%;
  background:var(--blue);
  transform:translate(-50%,-50%);
  transition:transform .25s var(--ease), opacity .25s var(--ease);
}
.faq-icon::before{ width:13px; height:1.8px; }
.faq-icon::after{ width:1.8px; height:13px; }
.faq-q[aria-expanded="true"] .faq-icon::after{ transform:translate(-50%,-50%) rotate(90deg); opacity:0; }

/* The 0fr -> 1fr grid technique reads nicely but does not actually interpolate
   in current Chrome — the row stays pinned near 0 and the answer never opens.
   Measured here at 26px against ~120px of copy. max-height animates reliably;
   26rem clears the longest answer without making the close feel laggy. */
.faq-a{
  overflow:hidden;
  max-height:0;
  transition:max-height .32s var(--ease);
}
.faq-a > p{
  color:var(--slate);
  font-size:1rem;
  max-width:62ch;
  padding-bottom:1.6rem;
}
/* --faq-h is measured per panel by js/site.js. The fallback has to be
   larger than any real panel: without JS this is what the visitor gets,
   and clipped legal or pricing copy is worse than a fast transition. */
.faq-q[aria-expanded="true"] + .faq-a{ max-height:var(--faq-h, 200rem); }
/* Reduced motion gets an instant open rather than an animated one. This is the
   correct behaviour for the preference, and it also removes a real failure mode:
   a max-height transition that never completes leaves the answer permanently
   unreadable. Verified — with the transition active the panel measured 0px, with
   it disabled it resolves to the full 416px. */
@media (prefers-reduced-motion: reduce){
  .faq-a{ transition:none; }
}

/* ==========================================================================
   Interior page components
   Shared by the service, portfolio, about, and contact pages — and by any
   industry / location / blog page added later.
   ========================================================================== */

/* ===== Page hero (compact — the homepage keeps the tall .hero) ===== */
.page-hero{
  padding:4.5rem 0 4rem;
  background:var(--paper-soft);
  border-bottom:1px solid var(--line);
}
.page-hero-inner{ max-width:50rem; }
.page-hero h1{
  font-size:clamp(2.2rem,5vw,3.4rem);
  line-height:1.05;
  letter-spacing:-.04em;
  max-width:18ch;
}
.page-hero p{
  margin-top:1.5rem;
  max-width:52ch;
  font-size:1.15rem;
  line-height:1.6;
  color:var(--slate);
}
.page-hero .btn{ margin-top:2.25rem; }

.breadcrumb{
  display:flex;
  align-items:center;
  flex-wrap:wrap;
  gap:.5rem;
  margin-bottom:1.5rem;
  font-family:var(--font-mono);
  font-size:.68rem;
  letter-spacing:.13em;
  text-transform:uppercase;
  color:var(--slate);
}
.breadcrumb a{ color:var(--slate); transition:color .18s var(--ease); }
.breadcrumb a:hover{ color:var(--blue); }
.breadcrumb span[aria-hidden]{ opacity:.45; }
.breadcrumb [aria-current]{ color:var(--ink); }

/* ===== Two-column content block ===== */
.split{ display:grid; grid-template-columns:1fr 1.15fr; gap:4.5rem; align-items:start; }
.split-sticky{ position:sticky; top:110px; }
.prose p{ color:var(--slate); font-size:1.05rem; line-height:1.7; }
.prose p + p{ margin-top:1.25rem; }
.prose h3{ font-size:1.3rem; margin:2.5rem 0 .85rem; }
.prose h3:first-child{ margin-top:0; }

/* ===== Check list ===== */
.check-list{ display:flex; flex-direction:column; gap:.9rem; }
.check-list li{
  position:relative;
  padding-left:1.85rem;
  font-size:1rem;
  line-height:1.55;
  color:var(--ink-soft);
}
.check-list li::before{
  content:"";
  position:absolute;
  left:0; top:.45em;
  width:12px; height:7px;
  border-left:2px solid var(--blue);
  border-bottom:2px solid var(--blue);
  transform:rotate(-45deg);
}
.check-list strong{ color:var(--ink); font-weight:600; }

/* ===== Deliverables / feature grid ===== */
.feature-grid{ display:grid; grid-template-columns:repeat(2,1fr); gap:2.5rem 3rem; }
.feature h3{ font-size:1.1rem; margin-bottom:.6rem; }
.feature p{ font-size:.96rem; color:var(--slate); }
.feature-num{
  display:block;
  font-family:var(--font-mono);
  font-size:.68rem;
  letter-spacing:.14em;
  color:var(--blue);
  margin-bottom:.85rem;
}

/* ===== Testimonial =====
   Styled and ready, but intentionally not placed on any live page yet —
   Altus has no client quotes to show, and placeholder praise would be
   fabricated proof. Drop a .testimonial-grid into any page once real
   quotes exist. */
.testimonial-grid{ display:grid; grid-template-columns:repeat(2,1fr); gap:1.5rem; }
.testimonial{
  display:flex;
  flex-direction:column;
  background:var(--surface);
  border:1px solid var(--line);
  border-radius:16px;
  padding:2.25rem 2rem;
  box-shadow:var(--shadow-card);
}
.testimonial blockquote{
  margin:0;
  font-size:1.08rem;
  line-height:1.6;
  color:var(--ink);
  letter-spacing:-.01em;
}
.testimonial blockquote::before{ content:"\201C"; }
.testimonial blockquote::after{ content:"\201D"; }
.testimonial figcaption{
  margin-top:1.5rem;
  padding-top:1.25rem;
  border-top:1px solid var(--line);
  font-size:.92rem;
  color:var(--slate);
}
.testimonial figcaption strong{ display:block; color:var(--ink); font-weight:600; }

/* ===== Contact detail rows ===== */
.contact-rows{
  border:1px solid var(--line);
  border-radius:16px;
  background:var(--surface);
  overflow:hidden;
  box-shadow:var(--shadow-card);
}
.contact-row{
  display:flex;
  align-items:baseline;
  justify-content:space-between;
  gap:2rem;
  padding:1.35rem 1.75rem;
  border-bottom:1px solid var(--line);
}
.contact-row:last-child{ border-bottom:0; }
.contact-row dt{
  font-family:var(--font-mono);
  font-size:.66rem;
  letter-spacing:.14em;
  text-transform:uppercase;
  color:var(--slate);
  flex:0 0 auto;
}
.contact-row dd{
  margin:0;
  font-size:1rem;
  color:var(--ink);
  text-align:right;
}
.contact-row dd a:hover{ color:var(--blue); }

/* ==========================================================================
   Page-specific signature components
   Each service page gets its own structural device so the pages don't read as
   one template with the words swapped. All mock UI below is illustrative and
   labelled as an example — it never depicts a real client or a real ranking.
   ========================================================================== */

/* ===== Browser frame (web design page) ===== */
.browser{
  border:1px solid var(--line-strong);
  border-radius:14px;
  overflow:hidden;
  background:var(--surface);
  box-shadow:var(--shadow-card);
}
.browser-bar{
  display:flex;
  align-items:center;
  gap:6px;
  padding:.7rem .9rem;
  background:var(--paper-soft);
  border-bottom:1px solid var(--line);
}
.browser-bar i{ width:8px; height:8px; border-radius:50%; background:var(--line-strong); }
.browser-url{
  margin-left:.6rem;
  flex:1;
  font-family:var(--font-mono);
  font-size:.66rem;
  color:var(--slate);
  background:var(--surface);
  border:1px solid var(--line);
  border-radius:6px;
  padding:.25rem .6rem;
}
.browser-body{ padding:1.25rem; display:flex; flex-direction:column; gap:.7rem; }

/* Wireframe blocks — a diagram, not a screenshot */
.wf{ border-radius:7px; background:var(--paper-soft); border:1px solid var(--line); }
.wf-row{ display:flex; gap:.7rem; }
.wf-nav{ height:34px; display:flex; align-items:center; justify-content:space-between; padding:0 .7rem; }
.wf-dot{ width:44px; height:9px; border-radius:3px; background:var(--line-strong); }
.wf-pill{ width:78px; height:20px; border-radius:6px; background:var(--blue); }
.wf-hero{ height:74px; padding:.85rem; display:flex; flex-direction:column; gap:.5rem; justify-content:center; }
.wf-line{ height:11px; border-radius:3px; background:var(--line-strong); }
.wf-line.sm{ height:7px; opacity:.65; }
.wf-line.w70{ width:70%; } .wf-line.w45{ width:45%; } .wf-line.w85{ width:85%; }
.wf-tile{ flex:1; height:52px; }
.wf-band{ height:40px; background:var(--tint); border-color:rgba(0,70,214,.18); }

/* Numbered callouts alongside a visual */
.annotated{ display:grid; grid-template-columns:1.05fr .95fr; gap:3.5rem; align-items:center; }
.anno-list{ display:flex; flex-direction:column; gap:1.6rem; }
.anno{ display:flex; gap:1.1rem; }
.anno-num{
  flex:0 0 auto;
  width:26px; height:26px;
  border-radius:50%;
  background:var(--blue);
  color:#fff;
  font-family:var(--font-mono);
  font-size:.7rem;
  display:flex; align-items:center; justify-content:center;
}
.anno h3{ font-size:1.05rem; margin-bottom:.35rem; }
.anno p{ font-size:.94rem; color:var(--slate); }

/* ===== Local search mock (local SEO page) ===== */
.serp{
  border:1px solid var(--line-strong);
  border-radius:14px;
  background:var(--surface);
  overflow:hidden;
  box-shadow:var(--shadow-card);
}
.serp-search{
  display:flex; align-items:center; gap:.6rem;
  padding:.9rem 1.1rem;
  border-bottom:1px solid var(--line);
}
.serp-search span{
  font-family:var(--font-mono);
  font-size:.78rem;
  color:var(--ink);
}
.serp-search svg{ width:15px; height:15px; color:var(--slate); flex:0 0 auto; }
.serp-label{
  padding:.6rem 1.1rem;
  font-family:var(--font-mono);
  font-size:.6rem;
  letter-spacing:.14em;
  text-transform:uppercase;
  color:var(--slate);
  background:var(--paper-soft);
  border-bottom:1px solid var(--line);
}
.serp-item{
  display:flex; align-items:flex-start; gap:.85rem;
  padding:.95rem 1.1rem;
  border-bottom:1px solid var(--line);
}
.serp-item:last-child{ border-bottom:0; }
.serp-rank{
  flex:0 0 auto;
  width:20px; height:20px;
  border-radius:5px;
  background:var(--paper-soft);
  border:1px solid var(--line);
  font-family:var(--font-mono);
  font-size:.62rem;
  color:var(--slate);
  display:flex; align-items:center; justify-content:center;
}
.serp-item strong{ display:block; font-size:.94rem; font-weight:600; }
.serp-item p{ font-size:.8rem; color:var(--slate); margin-top:.15rem; }
.serp-stars{ color:#B26A00; font-size:.78rem; letter-spacing:.05em; }
.serp-item.is-you{ background:var(--tint); }
.serp-item.is-you .serp-rank{ background:var(--blue); border-color:var(--blue); color:#fff; }

/* ===== What we control (local SEO page) ===== */
.control-grid{ display:grid; grid-template-columns:repeat(3,1fr); gap:1.5rem; }
.control-col{
  border-top:2px solid var(--line-strong);
  padding-top:1.5rem;
}
.control-col.is-own{ border-top-color:var(--blue); }
.control-col h3{
  font-family:var(--font-mono);
  font-size:.68rem;
  font-weight:500;
  letter-spacing:.14em;
  text-transform:uppercase;
  color:var(--slate);
  margin-bottom:1.1rem;
}
.control-col.is-own h3{ color:var(--blue); }
.control-col ul{ display:flex; flex-direction:column; gap:.7rem; }
.control-col li{ font-size:.94rem; color:var(--ink-soft); }
.control-col.is-none li{ color:var(--slate); }

/* ===== Timeline (local SEO page) ===== */
.timeline{ display:grid; grid-template-columns:repeat(3,1fr); gap:0; }
.tl-step{ padding:0 1.75rem 0 0; position:relative; }
.tl-step::before{
  content:"";
  display:block;
  height:3px;
  border-radius:3px;
  background:var(--blue);
  margin-bottom:1.5rem;
  opacity:calc(.35 + (var(--i,0) * .32));
}
.tl-when{
  display:block;
  font-family:var(--font-mono);
  font-size:.68rem;
  letter-spacing:.14em;
  text-transform:uppercase;
  color:var(--blue);
  margin-bottom:.7rem;
}
.tl-step h3{ font-size:1.1rem; margin-bottom:.6rem; }
.tl-step p{ font-size:.94rem; color:var(--slate); }

/* ===== Google Business Profile mock ===== */
.gbp{
  border:1px solid var(--line-strong);
  border-radius:14px;
  background:var(--surface);
  overflow:hidden;
  box-shadow:var(--shadow-card);
}
.gbp-head{ padding:1.35rem 1.5rem 1.1rem; border-bottom:1px solid var(--line); }
.gbp-head h3{ font-size:1.25rem; margin-bottom:.35rem; }
.gbp-meta{ font-size:.85rem; color:var(--slate); }
.gbp-rating{ color:#B26A00; font-size:.85rem; }
.gbp-actions{ display:flex; gap:.6rem; padding:1rem 1.5rem; border-bottom:1px solid var(--line); flex-wrap:wrap; }
.gbp-action{
  flex:1;
  min-width:88px;
  text-align:center;
  padding:.55rem .5rem;
  border:1px solid var(--line-strong);
  border-radius:8px;
  font-size:.8rem;
  color:var(--blue);
  font-weight:500;
}
.gbp-row{
  display:flex; justify-content:space-between; gap:1rem;
  padding:.8rem 1.5rem;
  border-bottom:1px solid var(--line);
  font-size:.88rem;
}
.gbp-row:last-child{ border-bottom:0; }
.gbp-row dt{ color:var(--slate); }
.gbp-row dd{ margin:0; color:var(--ink); text-align:right; }
.gbp-photos{ display:flex; gap:.5rem; padding:1rem 1.5rem; border-bottom:1px solid var(--line); }
.gbp-photos i{
  flex:1; height:52px; border-radius:7px;
  border:1px solid var(--line);
  background-color:var(--paper-soft);
  background-size:cover;
  background-position:center;
}
.gbp-photos i:nth-child(1){ background-image:url('/assets/photos/storefront.webp'); }
.gbp-photos i:nth-child(2){ background-image:url('/assets/photos/van.webp'); }
.gbp-photos i:nth-child(3){ background-image:url('/assets/photos/plumber.webp'); }
.gbp-photos i:nth-child(4){ background-image:url('/assets/photos/plumber-blue.webp'); }

/* ===== Self-audit checklist (GBP page) ===== */
.audit{
  border:1px solid var(--line);
  border-radius:16px;
  background:var(--surface);
  box-shadow:var(--shadow-card);
  overflow:hidden;
}
.audit-item{
  display:flex;
  align-items:flex-start;
  gap:.9rem;
  padding:1.05rem 1.5rem;
  border-bottom:1px solid var(--line);
  cursor:pointer;
  transition:background .15s var(--ease);
}
.audit-item:hover{ background:var(--paper-soft); }
.audit-item input{
  appearance:none; -webkit-appearance:none;
  width:20px; height:20px;
  margin:.1rem 0 0;
  flex:0 0 auto;
  border:1.5px solid var(--line-strong);
  border-radius:6px;
  background:var(--surface);
  position:relative;
  cursor:pointer;
  transition:background .15s var(--ease), border-color .15s var(--ease);
}
.audit-item input:checked{ background:var(--blue); border-color:var(--blue); }
.audit-item input:checked::after{
  content:"";
  position:absolute; left:6px; top:2.5px;
  width:5px; height:10px;
  border:solid #fff; border-width:0 2px 2px 0;
  transform:rotate(45deg);
}
.audit-item input:focus-visible{ outline:none; box-shadow:0 0 0 3.5px rgba(47,139,255,.22); }
.audit-item span{ font-size:.98rem; color:var(--ink); line-height:1.5; }
.audit-score{
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:1rem;
  padding:1.35rem 1.5rem;
  background:var(--paper-soft);
}
.audit-score-label{ font-size:.92rem; color:var(--slate); }
.audit-score-value{
  font-family:var(--font-display);
  font-size:1.6rem;
  font-weight:600;
  letter-spacing:-.02em;
  color:var(--ink);
}
.audit-score-value span{ font-family:var(--font-mono); font-size:.85rem; font-weight:400; color:var(--slate); }

/* ===== Editorial (about page) ===== */
/* ===== Photo figure (shared) ===== */
.figure{ margin:0; }
.figure img{
  display:block;
  width:100%;
  height:auto;
  border-radius:14px;
  border:1px solid var(--line);
  box-shadow:var(--shadow-card);
}
.figure figcaption{
  margin-top:.9rem;
  font-size:.9rem;
  line-height:1.55;
  color:var(--slate);
}
.figure-crop img{ height:340px; object-fit:cover; }
.split-sticky .figure{ margin-top:2.25rem; }
.figure-spaced{ margin-top:2.25rem; }
.editorial .figure{ margin:3.25rem 0; }

/* ===== Legal documents (privacy, terms) ===== */
.legal{ max-width:44rem; }
.legal h2{
  font-size:1.35rem;
  margin:3rem 0 1rem;
  letter-spacing:-.015em;
}
.legal h2:first-child{ margin-top:0; }
.legal h3{ font-size:1.05rem; margin:2rem 0 .7rem; }
.legal p, .legal li{ color:var(--ink-soft); font-size:1.02rem; line-height:1.7; }
.legal p + p{ margin-top:1rem; }
.legal ul{ margin:1rem 0 0; display:flex; flex-direction:column; gap:.65rem; }
.legal li{ position:relative; padding-left:1.4rem; }
.legal li::before{
  content:"";
  position:absolute;
  left:0; top:.65em;
  width:5px; height:5px;
  border-radius:50%;
  background:var(--line-strong);
}
.legal a{ color:var(--blue); text-decoration:underline; text-underline-offset:2px; }
.legal-updated{
  font-family:var(--font-mono);
  font-size:.7rem;
  letter-spacing:.09em;
  text-transform:uppercase;
  color:var(--slate);
  margin-bottom:2.5rem;
}

/* ===== About: editorial ===== */
.editorial{ max-width:38rem; }
.editorial p{ font-size:1.15rem; line-height:1.75; color:var(--ink-soft); }
.editorial p + p{ margin-top:1.5rem; }
.editorial p.lead{ font-size:1.35rem; line-height:1.6; color:var(--ink); }
.pull-quote{
  margin:4rem 0;
  padding:0 0 0 2rem;
  border-left:3px solid var(--blue);
}
.pull-quote p{
  font-family:var(--font-display);
  font-weight:600;
  font-size:clamp(1.5rem,3.4vw,2.1rem);
  line-height:1.25;
  letter-spacing:-.03em;
  color:var(--ink);
}
.principles{ counter-reset:principle; display:flex; flex-direction:column; }
.principle{
  counter-increment:principle;
  display:grid;
  grid-template-columns:auto 1fr;
  gap:2rem;
  padding:2.25rem 0;
  border-top:1px solid var(--line);
}
.principle:last-child{ border-bottom:1px solid var(--line); }
.principle::before{
  content:counter(principle,decimal-leading-zero);
  font-family:var(--font-mono);
  font-size:.72rem;
  letter-spacing:.14em;
  color:var(--blue);
  padding-top:.4rem;
}
.principle h3{ font-size:1.3rem; margin-bottom:.7rem; }
.principle p{ font-size:1rem; color:var(--slate); max-width:52ch; }

@media (max-width:960px){
  .annotated, .control-grid, .timeline{ grid-template-columns:1fr; }
  .annotated{ gap:2.5rem; }
  .timeline{ gap:2rem; }
  .tl-step{ padding:0; }
  .principle{ grid-template-columns:1fr; gap:.5rem; }
  .pull-quote{ margin:2.5rem 0; padding-left:1.35rem; }
}

/* ===== Closing CTA band ===== */
.cta-band{ padding:7rem 0; border-top:1px solid var(--line); text-align:center; }
.cta-band h2{ font-size:clamp(2.1rem,4.4vw,3.1rem); letter-spacing:-.035em; max-width:20ch; margin:0 auto; }
.cta-band p{
  margin:1.35rem auto 0;
  max-width:48ch;
  font-size:1.1rem;
  color:var(--slate);
}
.cta-band .btn{ margin-top:2.5rem; }
.cta-contact{
  margin-top:3.5rem;
  display:flex;
  justify-content:center;
  flex-wrap:wrap;
  gap:0;
  border:1px solid var(--line);
  border-radius:14px;
  overflow:hidden;
  max-width:44rem;
  margin-left:auto;
  margin-right:auto;
  background:var(--surface);
}
.cta-contact > *{
  flex:1 1 33%;
  min-width:180px;
  padding:1.35rem 1.5rem;
  border-right:1px solid var(--line);
  text-align:center;
}
.cta-contact > *:last-child{ border-right:0; }
.cta-contact a:hover{ background:var(--paper-soft); }
.cta-contact span{
  display:block;
  font-family:var(--font-mono);
  font-size:.62rem;
  letter-spacing:.14em;
  text-transform:uppercase;
  color:var(--slate);
  margin-bottom:.4rem;
}
.cta-contact strong{ font-weight:500; font-size:.98rem; color:var(--ink); }

/* ===== Footer ===== */
.footer{ border-top:1px solid var(--line); padding:4rem 0 2.5rem; background:var(--paper-soft); }
.footer-inner{ display:grid; grid-template-columns:1.5fr 1fr 1fr; gap:3rem; }
.footer-brand p{ margin-top:1rem; color:var(--slate); font-size:.92rem; max-width:32ch; }
.footer h4{
  font-family:var(--font-mono);
  font-size:.64rem;
  font-weight:500;
  letter-spacing:.14em;
  text-transform:uppercase;
  color:var(--slate);
  margin-bottom:1.1rem;
}
.footer-inner{ grid-template-columns:1.5fr 1fr 1fr 1fr; }
.footer-col{ display:flex; flex-direction:column; gap:.8rem; font-size:.94rem; color:var(--slate); }
.footer-col a{ transition:color .18s var(--ease); }
.footer-col a:hover{ color:var(--blue); }

/* ===== Footer =============================================================
   Three bands, each doing one job: identity + the single action, then the
   links and contact on one line, then legal. The previous version fed four
   children into a three-column grid, which wrapped the fourth underneath the
   brand and left a large hole in the middle of the footer.
   ========================================================================== */
.footer-top{
  display:flex; align-items:center; justify-content:space-between;
  gap:2rem; flex-wrap:wrap;
  padding-bottom:2.5rem;
}
.footer-tagline{
  margin-top:.9rem;
  font-family:var(--font-display);
  font-weight:600;
  font-size:1.05rem;
  color:var(--ink);
  letter-spacing:-.01em;
}
.footer-bar{
  display:flex; align-items:center; justify-content:space-between;
  gap:1.5rem 2.5rem; flex-wrap:wrap;
  padding:1.6rem 0;
  border-top:1px solid var(--line);
  border-bottom:1px solid var(--line);
}
.footer-links{ display:flex; flex-wrap:wrap; gap:1.75rem; }
.footer-links a{
  font-size:.94rem; color:var(--ink-soft);
  transition:color .18s var(--ease);
}
.footer-links a:hover{ color:var(--blue); }
.footer-meta{ display:flex; flex-wrap:wrap; gap:1.5rem; font-size:.94rem; color:var(--slate); }
.footer-meta a{ transition:color .18s var(--ease); }
.footer-meta a:hover{ color:var(--blue); }

.footer-legal{
  display:flex; align-items:center; justify-content:space-between;
  gap:1rem 1.75rem; flex-wrap:wrap;
  padding-top:1.6rem;
  font-size:.85rem; color:var(--slate);
}
.footer-legal nav{ display:flex; gap:1.5rem; }
.footer-legal a:hover{ color:var(--blue); }

/* ===== Responsive ===== */
/* The path is decorative; below tablet the steps stand on their own. */
@media (max-width:820px){
  .roadmap{ grid-template-columns:1fr; min-height:0; margin-top:3rem; }
  .roadmap-svg{ display:none; }
  .roadmap-steps{ gap:.15rem; }
  .roadmap-step{ padding:1rem 1.15rem; }
}

@media (max-width:960px){
  .h-nav{
    display:none;
    position:absolute;
    top:70px; left:0; right:0;
    flex-direction:column;
    align-items:stretch;
    gap:0;
    background:var(--surface);
    border-bottom:1px solid var(--line);
    box-shadow:0 20px 40px -24px rgba(0,0,0,.25);
    padding:.5rem 2rem 1.25rem;
  }
  .h-nav.is-open{ display:flex; }
  .h-nav > a{ padding:.9rem 0; border-bottom:1px solid var(--line); font-size:1rem; }
  .h-toggle{ display:flex; }

  /* The header CTA used to vanish entirely on mobile, leaving the menu with no
     way to convert. Move it inside the open panel instead of hiding it. */
  .h-actions .btn{ display:none; }
  .h-nav.is-open::after{ content:none; }
  .h-nav-cta{ display:block; padding:1.1rem 0 .25rem; }
  .h-nav-cta .btn{ width:100%; justify-content:center; }

  /* Dropdown flattens into an inline expanding group on touch */
  .h-menu{ border-bottom:1px solid var(--line); }
  .h-menu-btn{ width:100%; justify-content:space-between; padding:.9rem 0; font-size:1rem; }
  .h-menu-list{
    position:static;
    transform:none;
    min-width:0;
    padding:0 0 .75rem;
    border:0;
    border-radius:0;
    box-shadow:none;
    display:none;
  }
  .h-menu-btn[aria-expanded="true"] + .h-menu-list{
    display:block;
    opacity:1;
    visibility:visible;
    transform:none;
  }
  .h-menu-list a{ padding:.7rem .9rem; }

  .grid-3, .grid-2, .pricing, .who,
  .split, .feature-grid, .testimonial-grid,
  .launch-card, .addon{ grid-template-columns:1fr; }
  .who, .split{ gap:2.5rem; }
  .split-sticky{ position:static; }
  .footer-inner{ grid-template-columns:1fr 1fr; gap:2.5rem; }
}

@media (max-width:640px){
  body{ font-size:16px; }
  .wrap{ padding:0 1.25rem; }
  .section{ padding:4.5rem 0; }
  .hero{ padding:4.5rem 0 4rem; }
  .section-head{ margin-bottom:2.5rem; }
  .hero-ctas{ flex-direction:column; align-items:stretch; }
  .hero-ctas .btn{ width:100%; }
  .card{ padding:1.85rem 1.6rem; }
  .cta-band{ padding:4.5rem 0; }
  .page-hero{ padding:3rem 0 2.75rem; }
  .contact-row{ flex-direction:column; gap:.35rem; }
  .contact-row dd{ text-align:left; }
  .footer-inner{ grid-template-columns:1fr; }
  .cta-contact > *{ flex:1 1 100%; border-right:0; border-bottom:1px solid var(--line); }
  .cta-contact > *:last-child{ border-bottom:0; }
  .demo-shot img{ height:180px; }
}

/* ===== Four build tiers: responsive steps =====
   Declared after the 960px block (and scoped `.pricing.pricing-4` so it
   outranks the shared `.pricing` collapse) — otherwise the row would drop
   straight from four columns to one. 4 -> 2 -> 1. */
@media (max-width:1080px){

}
@media (max-width:680px){

}

/* ============================================================
   TWO-OFFER RESTRUCTURE
   Premium Website Launch  +  Google Presence & Reviews
   Reuses existing tokens and card styling — no new brand colours.
   ============================================================ */

/* --- Review flow: 4 plain steps --- */

/* --- Offer card CTA: pin to the bottom so both cards' buttons line up --- */
#services .card-feature{ display:flex; flex-direction:column; }
#services .card-feature-body{ display:flex; flex-direction:column; flex:1; }
#services .card-feature-body .card-list{ margin-bottom:1.5rem; }
#services .card-feature-body .btn{ margin-top:auto; align-self:flex-start; }

@media (max-width:960px){

}
@media (max-width:640px){
  .care-strip{ grid-template-columns:1fr; gap:1rem; }
}
@media (max-width:520px){

}

/* ==========================================================================
   BRAND HOMEPAGE — the website is the product
   Short sections, big type, few words. Everything here is tuned for the
   phone first: on mobile the whole page should be a handful of thumb swipes,
   so vertical rhythm is deliberately tighter than the site default.
   ========================================================================== */

.hero-brand{ padding:5.5rem 0 4.25rem; text-align:center; }
.hero-brand .hero-inner{ display:grid; justify-items:center; }
.hero-brand .hero-title{ max-width:16ch; }
.hero-brand .hero-sub{ max-width:30ch; font-size:clamp(1.05rem,2vw,1.3rem); }
.hero-brand .hero-ctas{ justify-content:center; }
.hero-price{
  margin-top:1.75rem;
  font-family:var(--font-mono);
  font-size:.72rem;
  letter-spacing:.16em;
  text-transform:uppercase;
  color:var(--slate);
}
.hero-price strong{ color:var(--ink); font-size:1.05rem; letter-spacing:0; }

/* --- The four proof points ------------------------------------------------ */
.offer-grid{
  display:grid;
  grid-template-columns:repeat(4,1fr);
  gap:1.25rem;
  margin-bottom:3rem;
}
.offer-point{ padding:1.75rem 1.5rem; border:1px solid var(--line); border-radius:16px; background:var(--surface); }
.offer-point > *{ min-width:0; }
.offer-num{
  display:block;
  margin-bottom:1.1rem;
  font-family:var(--font-mono);
  font-size:.68rem;
  letter-spacing:.14em;
  color:var(--blue);
}
.offer-point h3{ font-size:1.08rem; margin-bottom:.35rem; letter-spacing:-.01em; }
.offer-point p{ font-size:.95rem; color:var(--slate); margin:0; }

/* --- QR review kit -------------------------------------------------------- */
.offer-extra{
  display:grid;
  grid-template-columns:auto 1fr;
  align-items:center;
  gap:2rem;
  padding:2.25rem 2.25rem;
  border:1px solid var(--line);
  border-radius:20px;
  background:var(--paper-soft);
}
.offer-extra-art{ color:var(--blue); line-height:0; }
.offer-extra h3{ font-size:clamp(1.25rem,2.4vw,1.65rem); margin:.3rem 0 .5rem; letter-spacing:-.02em; }
.offer-extra p{ margin:0; color:var(--slate); max-width:46ch; }

/* --- Price + CTA ---------------------------------------------------------- */
.offer-cta{ margin-top:3rem; text-align:center; }
.offer-price{ font-family:var(--font-display); font-size:1.15rem; color:var(--slate); margin:0 0 .35rem; }
.offer-price strong{ font-size:clamp(2.6rem,6vw,3.6rem); color:var(--ink); letter-spacing:-.03em; display:block; }
.offer-note{ font-size:.9rem; color:var(--slate); margin:0 0 1.75rem; }

/* --- Mobile: fewer, shorter swipes --------------------------------------- */
@media (max-width:900px){
  .offer-grid{ grid-template-columns:repeat(2,1fr); gap:1rem; }
  .offer-extra{ grid-template-columns:1fr; gap:1.25rem; padding:1.75rem 1.5rem; text-align:left; }
  .offer-extra-art svg{ width:64px; height:64px; }
}
@media (max-width:640px){
  .hero-brand{ padding:4.5rem 0 3.5rem; }
  .section{ padding:5rem 0; }
  .section-head{ margin-bottom:2.5rem; }
  .offer-point{ padding:1.35rem 1.25rem; }
  .offer-num{ margin-bottom:.75rem; }
  .offer-cta{ margin-top:2.25rem; }
}
/* Two-up survives down to ~340px because each card is three or four words. */
@media (max-width:339px){
  .offer-grid{ grid-template-columns:1fr; }
}

/* The line that turns the free QR code into the $299 upgrade. */
.offer-extra-next{
  margin:.9rem 0 0 !important;
  font-size:.92rem;
  color:var(--ink);
}
.offer-extra-next a{ color:var(--blue); text-decoration:underline; text-underline-offset:2px; font-weight:600; }
/* Review automation is the reason to choose this tier, so it reads louder
   than the rows around it. */
.price-features li.is-hero{ font-weight:600; color:var(--ink); }

/* ==========================================================================
   DIGITAL GROWTH & AUTOMATION POSITIONING
   ========================================================================== */

.hero-note{
  margin-top:1.6rem;
  font-family:var(--font-mono);
  font-size:.68rem;
  letter-spacing:.14em;
  text-transform:uppercase;
  color:var(--slate);
}

/* --- the hover behaviour -------------------------------------------------
   Everything below is progressive enhancement. Without :has() support the
   cards render exactly as they do now, just connected. */
@supports selector(:has(*)){
  /* dim the whole route while any step is active... */
  .chain:has(.chain-step:hover) .chain-step,

  /* ...then relight everything from 01 up to the one being pointed at */
  .chain:has(.chain-step:nth-child(1):is(:hover,:focus-within)) .chain-step:nth-child(-n+1),
  .chain:has(.chain-step:nth-child(2):is(:hover,:focus-within)) .chain-step:nth-child(-n+2),
  .chain:has(.chain-step:nth-child(3):is(:hover,:focus-within)) .chain-step:nth-child(-n+3),
  .chain:has(.chain-step:nth-child(4):is(:hover,:focus-within)) .chain-step:nth-child(-n+4),
  .chain:has(.chain-step:nth-child(5):is(:hover,:focus-within)) .chain-step:nth-child(-n+5),

  /* the legs already travelled turn blue — one fewer than the lit steps */
  .chain:has(.chain-step:nth-child(2):is(:hover,:focus-within)) .chain-step:nth-child(-n+1)::after,
  .chain:has(.chain-step:nth-child(3):is(:hover,:focus-within)) .chain-step:nth-child(-n+2)::after,
  .chain:has(.chain-step:nth-child(4):is(:hover,:focus-within)) .chain-step:nth-child(-n+3)::after,
  .chain:has(.chain-step:nth-child(5):is(:hover,:focus-within)) .chain-step:nth-child(-n+4)::after,

  .chain:has(.chain-step:nth-child(2):is(:hover,:focus-within)) .chain-step:nth-child(-n+1)::before,
  .chain:has(.chain-step:nth-child(3):is(:hover,:focus-within)) .chain-step:nth-child(-n+2)::before,
  .chain:has(.chain-step:nth-child(4):is(:hover,:focus-within)) .chain-step:nth-child(-n+3)::before,
  .chain:has(.chain-step:nth-child(5):is(:hover,:focus-within)) .chain-step:nth-child(-n+4)::before,

}

/* the step under the cursor gets the emphasis, with or without :has() */
.chain-step:hover,

/* --- Diagnostic cards ----------------------------------------------------- */

.diag-note{
  margin:2.5rem auto 0;
  max-width:44rem;
  text-align:center;
  font-size:.95rem;
  color:var(--slate);
}

.tags-center{ justify-content:center; }

/* ===== Industries: hover-linked preview gallery ==============================
   Five demo screenshots sitting above the industry chips. Pointing at a chip
   lifts the matching shot and dims the others; pointing at a shot highlights
   its chip in return, so the mapping is obvious from either direction.

   All of it is :has() inside @supports — no JavaScript, and without :has()
   support the section degrades to a plain row of screenshots that still link
   to the demos. Touch devices get the same static row, which is correct:
   there is no hover to respond to.
   ========================================================================== */
.ind-gallery{
  display:grid;
  /* Three across, two rows. Six in a single row squeezed each screenshot to
     ~136px at 960px, which is too small to read as a website preview; three
     gives ~349px at desktop and the two-row block sits better under the
     heading anyway. */
  grid-template-columns:repeat(3,1fr);
  gap:.85rem;
  margin:0 0 2.25rem;
}
.ind-gallery .shot{
  position:relative;
  display:block;
  border-radius:12px;
  overflow:hidden;
  border:1px solid var(--line);
  background:var(--paper-soft);
  aspect-ratio:16/10;
  transition:transform .3s var(--ease), box-shadow .3s var(--ease),
             border-color .3s var(--ease), opacity .3s var(--ease);
}
.ind-gallery .shot img{
  width:100%; height:100%; object-fit:cover; object-position:top center;
  transition:transform .45s var(--ease);
}
.shot-cap{
  position:absolute; left:0; right:0; bottom:0;
  padding:1.5rem .7rem .55rem;
  background:linear-gradient(transparent, rgba(0,0,0,.86) 58%);
  color:#fff;
  opacity:0; transform:translateY(6px);
  transition:opacity .3s var(--ease), transform .3s var(--ease);
}
.shot-cap b{ display:block; font-size:.82rem; font-weight:600; letter-spacing:-.01em; line-height:1.2; }
.shot-cap i{
  display:block; font-style:normal; margin-top:.1rem;
  font-family:var(--font-mono); font-size:.6rem; letter-spacing:.12em;
  text-transform:uppercase; color:rgba(255,255,255,.72);
}

/* the active shot — used by both hover directions below */
.ind-gallery .shot:hover,
.ind-gallery .shot:focus-visible{
  border-color:var(--blue);
  box-shadow:0 1px 2px rgba(0,70,214,.06), 0 22px 44px -24px rgba(0,70,214,.5);
  transform:translateY(-5px);
  z-index:1;
}
.ind-gallery .shot:hover img,
.ind-gallery .shot:focus-visible img{ transform:scale(1.06); }
.ind-gallery .shot:hover .shot-cap,
.ind-gallery .shot:focus-visible .shot-cap{ opacity:1; transform:none; }

@supports selector(:has(*)){
  /* --- chip hovered -> light its shot, dim the rest --- */
  #industries:has(.tags > a:is(:hover,:focus-visible)) .ind-gallery .shot{ opacity:.32; }

  #industries:has(.tags > a[data-ind="hvac"]:is(:hover,:focus-visible))     .shot[data-ind="hvac"],
  #industries:has(.tags > a[data-ind="medspa"]:is(:hover,:focus-visible))   .shot[data-ind="medspa"],
  #industries:has(.tags > a[data-ind="skin"]:is(:hover,:focus-visible))     .shot[data-ind="skin"],
  #industries:has(.tags > a[data-ind="plumbing"]:is(:hover,:focus-visible)) .shot[data-ind="plumbing"],
  #industries:has(.tags > a[data-ind="hair"]:is(:hover,:focus-visible))     .shot[data-ind="hair"],
#industries:has(.tags > a[data-ind="roofing"]:is(:hover,:focus-visible))  .shot[data-ind="roofing"]{
    opacity:1;
    border-color:var(--blue);
    box-shadow:0 1px 2px rgba(0,70,214,.06), 0 22px 44px -24px rgba(0,70,214,.5);
    transform:translateY(-5px);
    z-index:1;
  }
  #industries:has(.tags > a[data-ind="hvac"]:is(:hover,:focus-visible))     .shot[data-ind="hvac"] .shot-cap,
  #industries:has(.tags > a[data-ind="medspa"]:is(:hover,:focus-visible))   .shot[data-ind="medspa"] .shot-cap,
  #industries:has(.tags > a[data-ind="skin"]:is(:hover,:focus-visible))     .shot[data-ind="skin"] .shot-cap,
  #industries:has(.tags > a[data-ind="plumbing"]:is(:hover,:focus-visible)) .shot[data-ind="plumbing"] .shot-cap,
  #industries:has(.tags > a[data-ind="hair"]:is(:hover,:focus-visible))     .shot[data-ind="hair"] .shot-cap,
#industries:has(.tags > a[data-ind="roofing"]:is(:hover,:focus-visible))  .shot[data-ind="roofing"] .shot-cap{
    opacity:1; transform:none;
  }
  #industries:has(.tags > a[data-ind="hvac"]:is(:hover,:focus-visible))     .shot[data-ind="hvac"] img,
  #industries:has(.tags > a[data-ind="medspa"]:is(:hover,:focus-visible))   .shot[data-ind="medspa"] img,
  #industries:has(.tags > a[data-ind="skin"]:is(:hover,:focus-visible))     .shot[data-ind="skin"] img,
  #industries:has(.tags > a[data-ind="plumbing"]:is(:hover,:focus-visible)) .shot[data-ind="plumbing"] img,
  #industries:has(.tags > a[data-ind="hair"]:is(:hover,:focus-visible))     .shot[data-ind="hair"] img,
#industries:has(.tags > a[data-ind="roofing"]:is(:hover,:focus-visible))  .shot[data-ind="roofing"] img{
    transform:scale(1.06);
  }

  /* --- shot hovered -> dim the other shots, and light its chip back --- */
  .ind-gallery:has(.shot:is(:hover,:focus-visible)) .shot{ opacity:.32; }
  .ind-gallery:has(.shot:is(:hover,:focus-visible)) .shot:is(:hover,:focus-visible){ opacity:1; }

  #industries:has(.shot[data-ind="hvac"]:is(:hover,:focus-visible))     .tags > a[data-ind="hvac"],
  #industries:has(.shot[data-ind="medspa"]:is(:hover,:focus-visible))   .tags > a[data-ind="medspa"],
  #industries:has(.shot[data-ind="skin"]:is(:hover,:focus-visible))     .tags > a[data-ind="skin"],
  #industries:has(.shot[data-ind="plumbing"]:is(:hover,:focus-visible)) .tags > a[data-ind="plumbing"],
  #industries:has(.shot[data-ind="hair"]:is(:hover,:focus-visible))     .tags > a[data-ind="hair"],
#industries:has(.shot[data-ind="roofing"]:is(:hover,:focus-visible))  .tags > a[data-ind="roofing"]{
    background:var(--blue); border-color:var(--blue); color:#fff;
  }
}

@media (prefers-reduced-motion:reduce){
  .ind-gallery .shot,.ind-gallery .shot img,.shot-cap{ transition:none; }
  .ind-gallery .shot:hover,.ind-gallery .shot:focus-visible{ transform:none; }
  .ind-gallery .shot:hover img,.ind-gallery .shot:focus-visible img{ transform:none; }
}

@media (max-width:900px){
  /* five 16:10 frames get too small to read below this — go to a scroll strip */
  .ind-gallery{
    display:flex; gap:.7rem; margin-bottom:1.75rem;
    overflow-x:auto; scroll-snap-type:x mandatory;
    -webkit-overflow-scrolling:touch;
    padding-bottom:.35rem;
  }
  .ind-gallery .shot{ flex:0 0 min(74%,300px); scroll-snap-align:center; }
  .shot-cap{ opacity:1; transform:none; }   /* no hover here, so always show it */
}

/* --- Responsive ----------------------------------------------------------- */
@media (max-width:900px){
  /* Two columns: the serpentine placement and its connectors no longer line
     up, so drop back to a plain grid. */

}
@media (max-width:640px){
  /* Two-up, not one-up: each card is a two-word heading and one short line, so
     stacking them singly doubled the scroll without helping anyone read. */

}
/* Below ~340px there genuinely isn't room for two columns. */
@media (max-width:339px){

}

/* ==========================================================================
   ALTUS 2026 — OFFER SYSTEM
   Four public offers: NFC Review Stands, Website Design, Google Growth and
   optional Website Care. Everything below is built from the existing tokens —
   no new brand colours, no new type families.
   ========================================================================== */

/* --- Dark section: used once, for the product moment ---------------------- */
.section-dark{ background:var(--bg-deep); color:var(--ink); }
.section-dark .section-title{ color:#fff; }
.section-dark .section-lede{ color:rgba(255,255,255,.72); }
.section-dark .eyebrow{ color:var(--blue-bright); }

.btn-invert{ background:var(--ink); color:#05070A; }
.btn-invert:hover{ background:var(--blue); color:#fff; transform:translateY(-1px); }
.btn-invert:active{ transform:translateY(0); }

/* --- Services overview: four scannable offers ----------------------------- */
.offers{ display:grid; grid-template-columns:repeat(4,minmax(0,1fr)); gap:1rem; }
.offer{
  display:flex; flex-direction:column;
  padding:1.9rem 1.6rem 1.7rem;
  background:var(--surface); border:1px solid var(--line); border-radius:16px;
  transition:border-color .25s var(--ease), transform .25s var(--ease),
             box-shadow .25s var(--ease);
}
.offer:hover{ border-color:var(--blue); transform:translateY(-4px); box-shadow:var(--shadow-card-hover); }
.offer-name{
  font-family:var(--font-display); font-size:1.08rem; font-weight:600;
  letter-spacing:-.02em; color:var(--ink);
}
.offer-name em{
  font-style:normal; margin-left:.45rem; padding:.15rem .45rem;
  border:1px solid var(--line-strong); border-radius:999px;
  font-family:var(--font-mono); font-size:.56rem; letter-spacing:.12em;
  text-transform:uppercase; color:var(--slate); vertical-align:middle;
}
.offer-price{ margin-top:1.1rem; display:flex; align-items:baseline; gap:.35rem; flex-wrap:wrap; }
.offer-from{
  flex-basis:100%; font-family:var(--font-mono); font-size:.6rem;
  letter-spacing:.14em; text-transform:uppercase; color:var(--slate); margin-bottom:.15rem;
}
.offer-price strong{
  font-family:var(--font-display); font-size:2rem; font-weight:600;
  letter-spacing:-.03em; color:var(--ink);
}
.offer-per{ font-size:.95rem; color:var(--slate); }
.offer-line{ margin-top:.9rem; font-size:.93rem; line-height:1.6; color:var(--slate); }
.offer-go{
  margin-top:auto; padding-top:1.3rem;
  font-family:var(--font-mono); font-size:.62rem; letter-spacing:.13em;
  text-transform:uppercase; color:var(--blue);
}

/* --- The product: copy beside a rendering --------------------------------- */
.product{ display:grid; grid-template-columns:1fr .85fr; gap:4rem; align-items:center; }
.taps{ list-style:none; margin:2.25rem 0 0; padding:0; display:flex; flex-direction:column; gap:.85rem; }
.taps li{ display:flex; align-items:center; gap:.85rem; font-size:1rem; color:rgba(255,255,255,.9); }
.taps span{
  flex:none; width:26px; height:26px; border-radius:50%;
  display:grid; place-items:center;
  background:rgba(255,255,255,.1); color:#fff;
  font-family:var(--font-mono); font-size:.7rem;
}
.ticks{ list-style:none; margin:2rem 0 0; padding:0; display:flex; flex-direction:column; gap:.7rem; }
.ticks li{ position:relative; padding-left:1.6rem; font-size:.95rem; line-height:1.55; }
.ticks li::before{
  content:""; position:absolute; left:0; top:.45em;
  width:10px; height:6px; transform:rotate(-45deg);
  border-left:2px solid var(--blue-bright); border-bottom:2px solid var(--blue-bright);
}
.section-dark .ticks li{ color:rgba(255,255,255,.82); }
.ticks-off li::before{
  transform:none; width:10px; height:2px; top:.72em;
  border-left:0; border-bottom:2px solid var(--line-strong);
}

/* grid children of .product — named so the layout intent is readable */
.product-copy{ min-width:0; }
.product-visual{ min-width:0; display:flex; justify-content:center; }

/* the product photograph, presented on a white card because the shot has a
   white background and this section is dark */
.plate{ margin:0; }
.plate img{
  width:100%; max-width:330px; height:auto; margin:0 auto; display:block;
  background:var(--surface); border-radius:20px; padding:.5rem;
  box-shadow:0 26px 60px -26px rgba(0,0,0,.65);
}
.plate figcaption{
  margin-top:1.5rem; text-align:center;
  font-family:var(--font-mono); font-size:.58rem; letter-spacing:.1em;
  text-transform:uppercase; color:rgba(255,255,255,.45);
}

/* --- Plate pricing -------------------------------------------------------- */
.packs{ display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:1rem; margin-top:4.5rem; }
.pack{
  position:relative; padding:1.75rem 1.5rem; text-align:center;
  border:1px solid rgba(255,255,255,.14); border-radius:16px;
}
.pack.is-value{ border-color:var(--blue-bright); background:rgba(47,139,255,.07); }
.pack-flag{
  position:absolute; top:-10px; left:50%; transform:translateX(-50%);
  background:var(--blue-bright); color:var(--ink);
  font-family:var(--font-mono); font-size:.56rem; letter-spacing:.12em;
  text-transform:uppercase; padding:.3rem .7rem; border-radius:999px; white-space:nowrap;
}
.pack-qty{ font-size:.9rem; color:rgba(255,255,255,.72); }
.pack-price{
  margin-top:.5rem; font-family:var(--font-display); font-size:2.4rem;
  font-weight:600; letter-spacing:-.03em; color:#fff;
}
.pack-each{ margin-top:.2rem; font-family:var(--font-mono); font-size:.62rem; letter-spacing:.1em; text-transform:uppercase; color:rgba(255,255,255,.55); }
.packs-note{ margin-top:1.5rem; text-align:center; font-size:.92rem; color:rgba(255,255,255,.7); }
.packs-cta{ margin-top:1.75rem; text-align:center; }
.fitline{
  margin:3.5rem auto 0; max-width:60ch; text-align:center;
  font-size:.9rem; line-height:1.7; color:rgba(255,255,255,.55);
}

/* --- Feature block: copy + list ------------------------------------------- */
.feature{ display:grid; grid-template-columns:1fr .9fr; gap:4rem; align-items:center; }
.feature-flip .feature-copy{ order:2; }
.feature-price{ margin-top:1.75rem; display:flex; align-items:baseline; gap:.4rem; flex-wrap:wrap; }
.feature-price span{
  font-family:var(--font-mono); font-size:.62rem; letter-spacing:.14em;
  text-transform:uppercase; color:var(--slate);
}
.feature-price strong{
  font-family:var(--font-display); font-size:2.6rem; font-weight:600;
  letter-spacing:-.035em; color:var(--ink);
}
.section-dark .feature-price strong{ color:#fff; }
.feature-note{ margin-top:1rem; max-width:46ch; font-size:.88rem; line-height:1.65; color:var(--slate); }
.feature-copy .btn{ margin-top:2rem; }
.feature-list{ list-style:none; margin:0; padding:0; display:flex; flex-direction:column; }
.feature-list li{
  padding:1rem 0; border-bottom:1px solid var(--line);
  font-size:1rem; color:var(--ink-soft);
}
.feature-list li:first-child{ padding-top:0; }
.feature-list li:last-child{ border-bottom:0; }
.aside{
  margin-top:2rem; padding:1.35rem 1.5rem;
  background:var(--tint); border-radius:12px;
  font-size:.93rem; line-height:1.65; color:var(--ink-soft);
}
.aside strong{ color:var(--ink); }

/* --- Website Care --------------------------------------------------------- */
.care{ border:1px solid var(--line); border-radius:20px; padding:3rem 2.75rem; background:var(--surface); }
.care-head{ max-width:46rem; }
.care-head .btn{ margin-top:1.75rem; }
.care-cols{ display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:3rem; margin-top:3rem; padding-top:2.5rem; border-top:1px solid var(--line); }
/* Left as real headings in the display face. Styling the page's only two h3s
   as tiny mono labels put them at 9.92px against the system's 19.89px and broke
   the heading scale. */
/* no font-size override — h3 takes the system's heading size, same as before */
.care-cols h3{ margin-bottom:1.1rem; }
.care-cols .ticks{ margin-top:0; }
.care-foot{ margin-top:1.25rem; font-size:.86rem; color:var(--slate); }
.care-own{
  margin-top:2.5rem; padding-top:1.75rem; border-top:1px solid var(--line);
  font-size:.93rem; color:var(--slate);
}
.care-own strong{ color:var(--ink); }

/* --- About ---------------------------------------------------------------- */
.about{ max-width:46rem; }
.about-lede{ margin-top:1.35rem; font-size:1.08rem; line-height:1.7; color:var(--ink-soft); }

/* --- Responsive ----------------------------------------------------------- */
@media (max-width:1020px){
  .offers{ grid-template-columns:repeat(2,minmax(0,1fr)); }
  .product,.feature{ grid-template-columns:minmax(0,1fr); gap:3rem; }
  .feature-flip .feature-copy{ order:0; }
  .care{ padding:2.5rem 2rem; }
}
@media (max-width:760px){
  .packs{ grid-template-columns:minmax(0,1fr); gap:.85rem; }
  .pack.is-value{ order:-1; }
  .care-cols{ grid-template-columns:minmax(0,1fr); gap:2.25rem; }
}
@media (max-width:640px){
  .offers{ grid-template-columns:minmax(0,1fr); }
  .offer{ padding:1.6rem 1.4rem 1.5rem; }
  .care{ padding:2rem 1.4rem; border-radius:16px; }
  .plate img{ max-width:250px; }
  .taps li{ font-size:.95rem; }
  .feature-price strong{ font-size:2.2rem; }
  .fitline{ margin-top:2.5rem; font-size:.86rem; }
}

@media (max-width:720px){
  .footer-top{ flex-direction:column; align-items:flex-start; gap:1.5rem; }
  .footer-top .btn{ width:100%; }
  .footer-bar{ flex-direction:column; align-items:flex-start; gap:1.25rem; }
  .footer-links{ gap:1.25rem; }
  .footer-meta{ flex-direction:column; gap:.6rem; }
}


/* ==========================================================================
   THE ALTUS TRAJECTORY  —  the site's one signature device
   --------------------------------------------------------------------------
   The logo is an A with an upward sweep. That sweep becomes a single blue
   line that carries the whole business model in the hero: build the site,
   get found, make the action easy, grow. Four waypoints sit ON the path at
   different heights, so it reads as a rising trajectory rather than a row of
   evenly spaced boxes.

   The path draws itself once, on load. Without JS or under reduced motion it
   is simply already drawn — the stroke-dash animation is additive.
   ========================================================================== */
.traj{ position:relative; margin-top:4rem; }
.traj-svg{ display:block; width:100%; height:auto; overflow:visible; }

.traj-line{
  fill:none;
  stroke:var(--blue);
  stroke-width:2.5;
  stroke-linecap:round;
}
/* draw-on: only when JS has confirmed motion is welcome */
.js-motion .traj-line{
  stroke-dasharray:var(--len,1200);
  stroke-dashoffset:var(--len,1200);
}
.js-motion .traj.in .traj-line{
  animation:traj-draw 1.6s var(--ease) forwards;
}
@keyframes traj-draw{ to{ stroke-dashoffset:0; } }

.traj-node{ fill:#fff; stroke:var(--blue); stroke-width:2.5; }
.traj-node-core{ fill:var(--blue); }
.js-motion .traj-dot{ opacity:0; }
.js-motion .traj.in .traj-dot{ animation:traj-pop .5s var(--ease) forwards; }
.js-motion .traj.in .traj-dot:nth-of-type(1){ animation-delay:.35s; }
.js-motion .traj.in .traj-dot:nth-of-type(2){ animation-delay:.70s; }
.js-motion .traj.in .traj-dot:nth-of-type(3){ animation-delay:1.05s; }
.js-motion .traj.in .traj-dot:nth-of-type(4){ animation-delay:1.40s; }
@keyframes traj-pop{ from{ opacity:0; transform:scale(.4);} to{ opacity:1; transform:none;} }
.traj-dot{ transform-box:fill-box; transform-origin:center; }

/* the labels ride under the path, aligned to each node */
.traj-labels{
  display:grid; grid-template-columns:repeat(4,1fr);
  gap:1rem; margin-top:1.5rem;
}
.traj-label{ text-align:center; }
.traj-label b{
  display:block; font-family:var(--font-display); font-weight:600;
  font-size:1.02rem; letter-spacing:-.02em; color:var(--ink);
}
.traj-label span{
  display:block; margin-top:.3rem;
  font-family:var(--font-mono); font-size:.62rem; letter-spacing:.14em;
  text-transform:uppercase; color:var(--slate);
}
/* the last waypoint is the payoff — it gets the blue */
.traj-label:last-child b{ color:var(--blue); }

/* ==========================================================================
   BROWSER COMPOSITION  —  websites section
   Real demo screenshot in a restrained chrome, with a phone overlapping and
   short labels tied to parts of the interface. Shows the work before the copy.
   ========================================================================== */
.compose{ position:relative; }
.browser{
  border:1px solid var(--line);
  border-radius:12px;
  overflow:hidden;
  background:var(--surface);
  box-shadow:0 30px 70px -40px rgba(0,0,0,.4);
}
.browser-bar{
  display:flex; align-items:center; gap:.4rem;
  padding:.7rem .9rem;
  background:var(--paper-soft);
  border-bottom:1px solid var(--line);
}
.browser-dot{ width:8px; height:8px; border-radius:50%; background:var(--line-strong); }
.browser-url{
  margin-left:.6rem; flex:1;
  font-family:var(--font-mono); font-size:.6rem; letter-spacing:.06em;
  color:var(--slate);
  background:var(--surface); border:1px solid var(--line);
  border-radius:5px; padding:.28rem .6rem;
  overflow:hidden; white-space:nowrap; text-overflow:ellipsis;
}
.browser img{ width:100%; display:block; }

/* the phone sits over the lower-left corner of the browser */
.compose-phone{
  position:absolute; left:-1.5rem; bottom:-2rem;
  width:23%; min-width:120px; max-width:190px;
  border:1px solid var(--line);
  border-radius:16px;
  overflow:hidden;
  background:var(--surface);
  box-shadow:0 24px 50px -22px rgba(0,0,0,.45);
}
.compose-phone::before{
  content:""; display:block; height:16px;
  background:var(--paper-soft); border-bottom:1px solid var(--line);
}
.compose-phone img{ width:100%; display:block; }

/* short labels, tied to the visual rather than stacked as a list */
.compose-tags{
  display:flex; flex-wrap:wrap; gap:.5rem;
  margin-top:2.75rem;
}
.compose-tags span{
  font-family:var(--font-mono); font-size:.62rem; letter-spacing:.12em;
  text-transform:uppercase; color:var(--ink-soft);
  border:1px solid var(--line-strong);
  border-radius:999px; padding:.42rem .85rem;
  background:var(--surface);
}

/* ==========================================================================
   GOOGLE PRESENCE  —  an incomplete profile completing itself, and reviews
   arriving. Original composition: no Google chrome, no invented numbers.
   ========================================================================== */
.gp{ display:grid; gap:1rem; }
.gp-card{
  border:1px solid var(--line); border-radius:14px; background:var(--surface);
  padding:1.4rem 1.5rem; box-shadow:var(--shadow-card);
}
.gp-head{ display:flex; align-items:center; gap:.8rem; }
.gp-avatar{
  width:38px; height:38px; border-radius:10px; flex:none;
  background:var(--tint); color:var(--blue);
  display:grid; place-items:center;
  font-family:var(--font-display); font-weight:600; font-size:.95rem;
}
/* Scoped to .gp-meta, not `.gp-head span` — that bare descendant selector was
   (0,2,0) and outranked .gp-avatar (0,1,0), forcing the avatar to display:block
   at 0.6rem so its letter fell out of the box. */
.gp-meta b{ display:block; font-size:.98rem; letter-spacing:-.01em; color:var(--ink); }
.gp-meta span{
  display:block; margin-top:.1rem;
  font-family:var(--font-mono); font-size:.6rem; letter-spacing:.12em;
  text-transform:uppercase; color:var(--slate);
}
/* the completing fields */
.gp-fields{ margin-top:1.1rem; display:flex; flex-direction:column; gap:.55rem; }
.gp-field{ display:flex; align-items:center; gap:.6rem; font-size:.86rem; color:var(--ink-soft); }
.gp-field i{
  width:15px; height:15px; border-radius:50%; flex:none;
  border:1.5px solid var(--line-strong);
  display:grid; place-items:center;
}
.gp-field.is-done i{ background:var(--blue); border-color:var(--blue); }
.gp-field.is-done i::after{
  content:""; width:6px; height:3px;
  border-left:1.5px solid #fff; border-bottom:1.5px solid #fff;
  transform:rotate(-45deg) translate(0,-1px);
}
.gp-field.is-pending{ color:var(--slate); }

/* review chips entering a stream */
.gp-stream{ display:flex; flex-direction:column; gap:.6rem; }
.gp-review{
  display:flex; align-items:center; gap:.7rem;
  border:1px solid var(--line); border-radius:12px; background:var(--surface);
  padding:.7rem .9rem;
}
.gp-stars{ display:flex; gap:1px; flex:none; }
.gp-stars svg{ width:11px; height:11px; fill:#E5A50A; }
.gp-review span{ font-size:.82rem; color:var(--ink-soft); }
.gp-review b{ margin-left:auto; flex:none; font-family:var(--font-mono); font-size:.58rem;
  letter-spacing:.1em; text-transform:uppercase; color:var(--slate); }
.js-motion .gp-review{ opacity:0; transform:translateY(8px); }
.js-motion .gp.in .gp-review{ animation:gp-in .55s var(--ease) forwards; }
.js-motion .gp.in .gp-review:nth-child(1){ animation-delay:.15s; }
.js-motion .gp.in .gp-review:nth-child(2){ animation-delay:.45s; }
.js-motion .gp.in .gp-review:nth-child(3){ animation-delay:.75s; }
@keyframes gp-in{ to{ opacity:1; transform:none; } }

/* ==========================================================================
   CARE STATUS  —  four calm tiles, not two columns of contract language
   ========================================================================== */
.care-grid{ display:grid; grid-template-columns:repeat(4,1fr); gap:1px; background:var(--line);
  border:1px solid var(--line); border-radius:14px; overflow:hidden; }
.care-tile{ background:var(--surface); padding:1.6rem 1.35rem; }
.care-dot{
  width:9px; height:9px; border-radius:50%; background:#1BA35C;
  box-shadow:0 0 0 4px rgba(27,163,92,.14);
  margin-bottom:1rem;
}
.care-tile b{ display:block; font-family:var(--font-display); font-weight:600;
  font-size:1.02rem; letter-spacing:-.015em; color:var(--ink); }
.care-tile span{ display:block; margin-top:.3rem; font-size:.85rem; color:var(--slate); }

/* ==========================================================================
   PLATE TAP SEQUENCE  —  three frames: tap, open, review
   ========================================================================== */
.tap{ display:grid; grid-template-columns:repeat(3,1fr); gap:1.25rem; }
.tap-step{ text-align:left; }
.tap-num{
  font-family:var(--font-mono); font-size:.6rem; letter-spacing:.16em;
  color:var(--blue-bright); display:block; margin-bottom:.7rem;
}
.tap-step b{ display:block; font-family:var(--font-display); font-weight:600;
  font-size:1.05rem; letter-spacing:-.015em; color:#fff; }
.tap-step span{ display:block; margin-top:.3rem; font-size:.88rem; color:rgba(255,255,255,.62); }

/* the contactless pulse on the product image */
.plate-wrap{ position:relative; }
.plate-pulse{
  position:absolute; left:50%; top:62%;
  width:54px; height:54px; margin:-27px 0 0 -27px;
  border:2px solid var(--blue-bright); border-radius:50%;
  opacity:0; pointer-events:none;
}
.js-motion .plate-wrap.in .plate-pulse{ animation:pulse 2.6s var(--ease) infinite; }
.js-motion .plate-wrap.in .plate-pulse:nth-of-type(2){ animation-delay:.9s; }
@keyframes pulse{
  0%{ opacity:.75; transform:scale(.5); }
  70%{ opacity:0; transform:scale(2.4); }
  100%{ opacity:0; transform:scale(2.4); }
}

/* ==========================================================================
   RESPONSIVE
   ========================================================================== */
@media (max-width:900px){
  .traj-labels{ grid-template-columns:repeat(2,1fr); gap:1.5rem 1rem; }
  .care-grid{ grid-template-columns:repeat(2,1fr); }
  .tap{ grid-template-columns:1fr; gap:1.5rem; }
  .compose-phone{ left:auto; right:-.5rem; bottom:-1.5rem; width:28%; }
}
@media (max-width:640px){
  .traj{ margin-top:2.5rem; }
  .traj-labels{ grid-template-columns:repeat(2,1fr); }
  .care-grid{ grid-template-columns:1fr; }
  .compose-tags{ margin-top:2rem; }
  .compose-phone{ position:static; width:46%; margin:1rem 0 0 auto; }
  .gp-card{ padding:1.15rem 1.15rem; }
}

@media (prefers-reduced-motion:reduce){
  .traj-line{ stroke-dashoffset:0 !important; animation:none !important; }
  .traj-dot,.gp-review{ opacity:1 !important; transform:none !important; animation:none !important; }
  .plate-pulse{ display:none; }
}


/* ==========================================================================
   VISUAL QA PASS
   Fixes found by rendering the page and looking at it.
   ========================================================================== */

/* --- Trajectory ----------------------------------------------------------
   First pass read as a small stock sparkline: too narrow, too shallow, and
   the labels sat on an even grid while the nodes did not. Now it breaks out
   of the hero's 56rem measure to the full wrap, climbs much harder, and the
   nodes are evenly spaced so the label grid lines up with them exactly. */
/* Sits in its own .wrap now. The previous version used 100vw to break out of
   the hero's narrow measure, and 100vw includes the scrollbar — that was the
   8px of horizontal overflow showing up at 1024 and below. */
.traj{ margin-top:3.25rem; }
/* uniform scale — a forced height turned the circular nodes into ovals */
.traj-svg{ height:auto; }
.traj-line{ stroke-width:3; }
.traj-node{ stroke-width:3; }
/* the payoff node carries a soft halo so the eye lands there */
.traj-node-end{ filter:drop-shadow(0 0 10px rgba(0,70,214,.45)); }
.traj-labels{ margin-top:1.1rem; }
.traj-label b{ font-size:1.08rem; }

/* --- NFC pack prices -----------------------------------------------------
   On the near-black section these were rendering as dark grey on dark: the
   loudest thing in the block was invisible. */
.section-dark .pack{
  background:rgba(255,255,255,.05);
  border-color:rgba(255,255,255,.16);
}
.section-dark .pack-qty{
  color:rgba(255,255,255,.68);
  font-family:var(--font-mono); font-size:.62rem;
  letter-spacing:.14em; text-transform:uppercase;
}
.section-dark .pack-price{
  color:#fff;
  font-family:var(--font-display); font-weight:600;
  font-size:1.9rem; letter-spacing:-.03em;
}
.section-dark .pack.is-best{
  background:rgba(47,139,255,.12);
  border-color:var(--blue-bright);
}
.section-dark .pack-note{ color:rgba(255,255,255,.6); }

/* --- Websites composition ------------------------------------------------
   The phone was clipping off the bottom-left corner and reading as a mistake
   rather than a deliberate overlap. Pull it inside the composition. */
.compose{ padding-bottom:2.5rem; }
.compose-phone{ left:2%; bottom:0; width:24%; min-width:126px; max-width:178px; }

/* --- Google profile avatar ----------------------------------------------- */
.gp-avatar{
  background:var(--blue); color:#fff;
  font-size:1.05rem; line-height:1;
}

/* --- Spacing ------------------------------------------------------------
   A lone accordion sitting in the middle of a section had a large hole
   around it; tighten it against the block it belongs to. */
#google-growth .faq{ margin-top:2.5rem !important; }
#care .care-grid{ margin-top:.5rem; }

@media (max-width:900px){
  .traj-labels{ grid-template-columns:repeat(4,1fr); gap:.5rem; }
  .traj-label b{ font-size:.86rem; }
  .traj-label span{ font-size:.55rem; letter-spacing:.1em; }
}
@media (max-width:640px){
  .traj{ margin-top:2.25rem; }
  .traj-label b{ font-size:.78rem; line-height:1.15; }
  .traj-label span{ display:none; }
  .section-dark .pack-price{ font-size:1.5rem; }
}


/* ==========================================================================
   INTERACTIVE TRAJECTORY
   The four waypoints are real buttons. Hover, tap, click or arrow-key through
   them and the path lights up to that stage while a one-line panel explains it.
   Without JS all four labels and the first line are still there — the
   interaction adds detail, it never gates it.
   ========================================================================== */
.traj-lit{
  fill:none; stroke:var(--blue-bright); stroke-width:4; stroke-linecap:round;
  stroke-dasharray:var(--len,1200);
  stroke-dashoffset:var(--len,1200);
  transition:stroke-dashoffset .55s var(--ease);
  pointer-events:none;
}
.traj-dot{ cursor:pointer; }
.traj-dot .traj-node{ transition:r .25s var(--ease), stroke .25s var(--ease); }
.traj-dot.is-on .traj-node{ stroke:var(--blue-bright); }
.traj-dot.is-on .traj-node-core{ fill:var(--blue-bright); }

/* labels become buttons */
.traj-label{
  display:block; width:100%;
  padding:.7rem .4rem;
  border:0; border-top:2px solid transparent;
  background:none; cursor:pointer; text-align:center;
  font:inherit; color:inherit;
  transition:border-color .25s var(--ease), opacity .25s var(--ease);
}
.traj-label b{ pointer-events:none; }
.traj-label span{ pointer-events:none; }
.traj-label:hover b{ color:var(--blue); }
.traj-label.is-on{ border-top-color:var(--blue); }
.traj-label.is-on b{ color:var(--blue); }
.js-motion .traj-labels:hover .traj-label:not(:hover){ opacity:.55; }
.traj-label:focus-visible{ outline:2px solid var(--blue-bright); outline-offset:2px; border-radius:6px; }

.traj-panel{
  margin-top:.4rem; min-height:3.2em;
  text-align:center;
}
.traj-panel p{
  margin:0; font-size:1rem; color:var(--slate);
  max-width:46ch; margin-inline:auto;
}
/* JS turns this into a single swapping line; without JS the first line shows
   and the rest are simply additional sentences, which still reads fine. */
.js .traj-panel p{ display:none; }
.js .traj-panel p.is-on{ display:block; }

/* ==========================================================================
   RATES  —  the four offers and their prices, one scannable block
   ========================================================================== */
.rates{
  list-style:none; margin:0; padding:0;
  border-top:1px solid var(--line);
  max-width:52rem; margin-inline:auto;
}
.rate{ border-bottom:1px solid var(--line); }
.rate a{
  display:grid;
  grid-template-columns:1fr auto;
  grid-template-areas:"name price" "desc price";
  gap:.15rem 2rem;
  align-items:center;
  padding:1.35rem .25rem;
  transition:background .2s var(--ease), padding-left .2s var(--ease);
}
.rate a:hover{ background:var(--paper-soft); padding-left:1rem; }
.rate-name{
  grid-area:name;
  font-family:var(--font-display); font-weight:600; font-size:1.14rem;
  letter-spacing:-.02em; color:var(--ink);
}
.rate-name em{
  font-style:normal; margin-left:.5rem;
  font-family:var(--font-mono); font-size:.56rem; letter-spacing:.14em;
  text-transform:uppercase; color:var(--slate);
  border:1px solid var(--line-strong); border-radius:999px; padding:.18rem .5rem;
  vertical-align:middle;
}
.rate-desc{ grid-area:desc; font-size:.93rem; color:var(--slate); }
.rate-price{
  grid-area:price; justify-self:end; white-space:nowrap;
  font-family:var(--font-display); font-weight:600; font-size:1.35rem;
  letter-spacing:-.03em; color:var(--ink);
}
.rate-price i{ font-style:normal; font-size:.8rem; color:var(--slate); margin-left:.1rem; }
.rate a:hover .rate-price{ color:var(--blue); }
.rates-note{
  max-width:52rem; margin:1.5rem auto 0;
  font-size:.86rem; color:var(--slate); text-align:center;
}

@media (max-width:640px){
  .traj-label{ padding:.55rem .2rem; }
  .traj-panel{ min-height:4.4em; }
  .traj-panel p{ font-size:.92rem; }
  .rate a{
    grid-template-columns:1fr;
    grid-template-areas:"name" "desc" "price";
    gap:.3rem; padding:1.15rem .25rem;
  }
  .rate-price{ justify-self:start; font-size:1.2rem; }
  .rate a:hover{ padding-left:.25rem; }
}
@media (prefers-reduced-motion:reduce){
  .traj-lit{ transition:none; }
}


/* ==========================================================================
   ALTUS DARK SYSTEM
   ==========================================================================
   The sheet above was authored against a white page; the token block now
   points at near-black, and this layer rebuilds the pieces a token flip
   alone cannot invert — chrome, section rhythm, lighting — plus the
   components that only exist in the dark design.

   Ordering note: these rules are appended deliberately. They match the
   specificity of the originals and win on source order, so nothing above
   needed deleting.
   ========================================================================== */

body{ background:var(--bg); color:var(--ink); }
::selection{ background:var(--blue); color:#fff; }
html{ color-scheme:dark; scrollbar-color:var(--surface-3) var(--bg); }

/* ---------- Section rhythm --------------------------------------------
   Depth comes from four near-blacks, not from borders. The eye reads a
   change of ground as a new chapter without ever seeing a dividing line. */
.sec-deep{ background:var(--bg-deep); }
.sec-base{ background:var(--bg); }
.sec-char{ background:var(--bg-char); }
.sec-graphite{ background:var(--bg-graphite); }
.section-soft{ background:var(--bg-graphite); }
.section-line{ border-top:1px solid var(--line); }

.section{ padding:6.5rem 0; }
.section-title{ color:var(--ink); }
.section-lede{ color:var(--ink-soft); }
.eyebrow{ color:var(--blue-bright); }
.section-dark .section-lede{ color:var(--ink-soft); }
.section-dark .eyebrow{ color:var(--blue-bright); }

/* ---------- Header ---------------------------------------------------- */
.h-header{
  background:rgba(5,7,10,.72);
  -webkit-backdrop-filter:saturate(150%) blur(16px);
  backdrop-filter:saturate(150%) blur(16px);
  border-bottom:1px solid transparent;
  transition:background .3s var(--ease), border-color .3s var(--ease);
}
/* JS stamps .is-scrolled past the top: the bar gains a ground and a hairline
   only once there is content behind it to separate from. */
.h-header.is-scrolled{ background:rgba(5,7,10,.9); border-bottom-color:var(--line); }
.h-brand span{ color:var(--ink); }
.h-brand em{ color:var(--blue-bright); }
.h-nav a{ color:var(--ink-soft); }
.h-nav a:hover{ color:var(--ink); }
.h-toggle{ border-color:var(--line-strong); }
.h-toggle span{ background:var(--ink); }
.h-menu, .h-menu-list{ background:var(--surface); border-color:var(--line-strong); }
.h-menu-list a:hover{ background:var(--surface-2); }

/* ---------- Buttons --------------------------------------------------- */
.btn-primary{
  background:var(--blue); color:#fff;
  box-shadow:0 0 0 1px rgba(255,255,255,.09) inset, 0 10px 30px -12px var(--glow);
}
.btn-primary:hover{ background:var(--blue-hover); box-shadow:0 0 0 1px rgba(255,255,255,.12) inset, 0 14px 38px -12px var(--glow); }
.btn-invert{ background:var(--ink); color:var(--bg-deep); }
.btn-invert:hover{ background:#fff; }

/* ---------- Cards ----------------------------------------------------- */
.card, .offer, .care-tile, .faq-item, .browser, .gp-card{
  background:var(--surface); border-color:var(--line);
}
.card:hover, .offer:hover{ border-color:var(--line-strong); background:var(--surface-2); }

/* ==========================================================================
   HERO
   A product photographed in a dark studio: the composition is lit from
   behind and below, everything else stays dark, and the contrast is what
   makes it read as expensive.
   ========================================================================== */
.hero-lead{
  position:relative; background:var(--bg-deep);
  padding:5.5rem 0 6rem; overflow:hidden; isolation:isolate;
}
/* The environmental light. Two very wide, very soft radials — one low and
   behind the device, one wash at the horizon. Not a gradient blob: it has a
   source and a falloff. */
.hero-amb{
  position:absolute; inset:0; z-index:-1; pointer-events:none;
  background:
    radial-gradient(48% 42% at 72% 58%, rgba(10,92,255,.30) 0%, rgba(10,92,255,.10) 40%, transparent 70%),
    radial-gradient(90% 55% at 50% 108%, rgba(10,92,255,.18) 0%, transparent 62%);
}
.hero-amb::after{
  content:""; position:absolute; left:0; right:0; bottom:0; height:1px;
  background:linear-gradient(90deg, transparent, rgba(61,139,255,.45) 45%, rgba(61,139,255,.15) 75%, transparent);
}

.hero-split{
  display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1.12fr);
  gap:4.5rem; align-items:center;
}
.hero-lead .hero-title{
  font-size:clamp(2.9rem,6.4vw,5rem);
  letter-spacing:-.045em; line-height:1.02; color:var(--ink);
}
.hero-lead .hero-title .grow{
  background:linear-gradient(96deg,var(--blue-bright) 0%,#0A5CFF 62%);
  -webkit-background-clip:text; background-clip:text; color:transparent;
}
/* Without background-clip:text the gradient would paint a block over the
   word, so fall back to a flat, still-accessible blue. */
@supports not ((-webkit-background-clip:text) or (background-clip:text)){
  .hero-lead .hero-title .grow{ background:none; color:var(--blue-bright); }
}
.hero-lead .hero-sub{
  margin-top:1.6rem; max-width:34ch;
  font-size:clamp(1.02rem,1.5vw,1.16rem); color:var(--ink-soft);
}
.hero-lead .hero-ctas{ margin-top:2.4rem; }

/* Understated value row under the CTAs — statements of fact, nothing claimed. */
.hero-facts{
  display:flex; flex-wrap:wrap; gap:.55rem 1.9rem;
  margin-top:2.6rem; padding-top:1.7rem;
  border-top:1px solid var(--line); list-style:none;
}
.hero-facts li{ display:flex; align-items:center; gap:.5rem; font-size:.83rem; color:var(--slate); white-space:nowrap; }
.hero-facts svg{ width:14px; height:14px; flex:none; fill:var(--blue-bright); }

/* ---------- The device stage ------------------------------------------ */
.stage{ position:relative; perspective:1800px; }
.stage-glow{
  position:absolute; left:-14%; right:-10%; top:-16%; bottom:-22%;
  z-index:0; pointer-events:none;
  background:radial-gradient(52% 46% at 50% 55%, var(--glow) 0%, var(--glow-soft) 38%, transparent 70%);
  filter:blur(18px);
}
.stage-tilt{
  position:relative; z-index:1; transform-style:preserve-3d;
  /* --tx/--ty are nudged by the pointer; the resting pose is the default. */
  transform:rotateY(calc(-10deg + var(--tx,0deg))) rotateX(calc(3.5deg + var(--ty,0deg)));
  transition:transform .45s var(--ease); will-change:transform;
}
.stage .browser{
  position:relative; border-radius:14px;
  border:1px solid rgba(255,255,255,.14); background:var(--surface);
  box-shadow:
    0 0 0 1px rgba(10,92,255,.14),
    0 0 60px -14px var(--glow),
    0 70px 120px -50px #000;
}
/* Edge light: a thin bright rim along the top-left, as though the blue
   source sits behind and to the left of the panel. */
.stage .browser::before{
  content:""; position:absolute; inset:0; border-radius:14px; pointer-events:none; z-index:2;
  background:linear-gradient(150deg, rgba(255,255,255,.16), transparent 34%);
  mix-blend-mode:screen;
}
.stage .browser img{ width:100%; display:block; }

/* The reflected pool of light the device appears to stand in. */
.stage-floor{
  position:absolute; left:8%; right:8%; bottom:-8%; height:70px; z-index:0;
  background:radial-gradient(50% 50% at 50% 50%, rgba(61,139,255,.34), transparent 72%);
  filter:blur(20px); pointer-events:none;
}
.stage-chip{
  position:absolute; z-index:2; right:-2%; bottom:6%;
  display:flex; align-items:center; gap:.6rem; padding:.7rem .95rem;
  background:rgba(13,17,23,.92);
  -webkit-backdrop-filter:blur(10px); backdrop-filter:blur(10px);
  border:1px solid var(--line-strong); border-radius:12px;
  box-shadow:0 20px 44px -22px #000;
  font-size:.78rem; color:var(--ink-soft); white-space:nowrap;
}
.stage-chip b{ color:var(--ink); font-weight:600; }
.stage-chip .dot{
  width:7px; height:7px; border-radius:50%; background:#31D07A; flex:none;
  box-shadow:0 0 0 3px rgba(49,208,122,.18);
}

/* ==========================================================================
   INDUSTRY STRIP
   Stands where a client-logo row normally goes. These are the industries
   Altus builds for and can show work in — no invented company marks.
   ========================================================================== */
.strip{ background:var(--bg-deep); border-top:1px solid var(--line); padding:2.6rem 0; }
.strip-label{
  text-align:center; font-family:var(--font-mono);
  font-size:.63rem; letter-spacing:.22em; text-transform:uppercase; color:var(--slate);
}
.strip-list{
  display:flex; flex-wrap:wrap; justify-content:center;
  gap:.7rem 2.4rem; margin-top:1.4rem; list-style:none;
}
.strip-list li{
  font-family:var(--font-display); font-weight:600;
  font-size:clamp(.92rem,1.5vw,1.08rem); letter-spacing:-.02em;
  color:var(--slate); transition:color .2s var(--ease);
}
.strip-list li:hover{ color:var(--ink-soft); }

/* ==========================================================================
   GOOGLE BUSINESS PROFILE — illustration
   A recognisable profile rendered in the Altus environment, so a prospect
   can see the thing being managed rather than a map pin. The business is
   fictional and captioned as such.
   ========================================================================== */
.gbp{
  position:relative; background:var(--surface);
  border:1px solid var(--line-strong); border-radius:18px; overflow:hidden;
  box-shadow:0 0 60px -26px var(--glow), var(--shadow-lift);
}
.gbp-photos{
  display:grid;
  grid-template-columns:1.7fr 1fr 1fr;
  grid-template-rows:repeat(2,minmax(0,1fr));
  gap:5px; padding:5px; aspect-ratio:1000/300;
}
/* No display here: `.gbp-photos img` is (0,1,1) and would outrank the
   (0,1,0) `.gbp-ph-2 { display:none }` hides in the phone breakpoints no
   matter where they sit in the file. The global `img { display:block }`
   is (0,0,1) and already covers it. */
.gbp-photos img{ width:100%; height:100%; object-fit:cover; border-radius:3px; }
.gbp-ph-lead{ grid-row:1 / span 2; }
.gbp-ph-last{ position:relative; }
.gbp-ph-last span{
  position:absolute; inset:0; display:grid; place-items:center;
  background:rgba(5,7,10,.55); border-radius:3px;
  font-size:.86rem; font-weight:600; color:#fff;
}

.gbp-body{ display:grid; grid-template-columns:minmax(0,1.5fr) minmax(0,1fr); }
.gbp-main{ padding:1.6rem 1.7rem 1.4rem; }
.gbp-side{ padding:1.6rem 1.7rem 1.4rem; border-left:1px solid var(--line); }

.gbp-name{ font-size:1.5rem; letter-spacing:-.03em; color:var(--ink); }
.gbp-rating{ display:flex; align-items:center; gap:.45rem; margin-top:.5rem; font-size:.92rem; color:var(--ink-soft); }
.gbp-rating b{ color:var(--ink); font-weight:600; }
.gbp-stars{ display:inline-flex; gap:1px; }
.gbp-stars svg{ width:14px; height:14px; fill:#F5B70A; }
.gbp-cat{ margin-top:.5rem; font-size:.9rem; color:var(--slate); }
.gbp-owner{ display:flex; align-items:center; gap:.45rem; margin-top:.7rem; font-size:.86rem; color:var(--ink-soft); }
.gbp-owner svg{ width:15px; height:15px; fill:var(--blue-bright); flex:none; }

.gbp-actions{
  display:flex; gap:1.9rem; margin:1.3rem 0; padding:1.1rem 0;
  border-top:1px solid var(--line); border-bottom:1px solid var(--line);
}
.gbp-act{ display:flex; flex-direction:column; align-items:center; gap:.4rem; font-size:.74rem; color:var(--blue-bright); }
.gbp-act i{ display:grid; place-items:center; width:36px; height:36px; border:1px solid rgba(61,139,255,.4); border-radius:50%; }
.gbp-act svg{ width:16px; height:16px; fill:var(--blue-bright); }

.gbp-facts{ display:grid; gap:.75rem; list-style:none; }
.gbp-facts li{ display:flex; align-items:center; gap:.75rem; font-size:.88rem; color:var(--ink-soft); }
.gbp-facts svg{ width:15px; height:15px; fill:var(--slate); flex:none; }
.gbp-open{ color:#31D07A; font-weight:600; }
.gbp-link{ color:var(--blue-bright); }
.gbp-all{
  display:block; width:100%; margin-top:1.3rem; padding:.7rem;
  background:var(--surface-2); border:1px solid var(--line);
  border-radius:8px; text-align:center; font-size:.86rem; color:var(--ink-soft);
}

.gbp-side h4{ font-size:1rem; letter-spacing:-.02em; color:var(--ink); font-weight:600; }
.gbp-side h4 + h4{ margin-top:1.5rem; }
.gbp-post{ margin-top:.9rem; padding:.95rem 1rem; background:var(--surface-2); border:1px solid var(--line); border-radius:10px; }
.gbp-post-brand{ display:flex; align-items:center; gap:.55rem; }
.gbp-post-brand svg{ width:22px; height:22px; flex:none; }
.gbp-post-brand b{ font-family:var(--font-display); font-size:.86rem; letter-spacing:-.02em; color:var(--ink); }
.gbp-post-brand i{ display:block; font-style:normal; font-family:var(--font-mono); font-size:.5rem; letter-spacing:.14em; text-transform:uppercase; color:var(--slate); }
.gbp-post p{ margin-top:.7rem; font-size:.85rem; line-height:1.5; color:var(--ink-soft); }
.gbp-post-foot{ display:flex; justify-content:space-between; margin-top:.8rem; font-size:.76rem; color:var(--slate); }
.gbp-post-foot span:last-child{ color:var(--blue-bright); }

.gbp-score{ display:flex; align-items:center; gap:.5rem; margin-top:.9rem; }
.gbp-score b{ font-family:var(--font-display); font-size:1.75rem; letter-spacing:-.03em; color:var(--ink); }
.gbp-score .gbp-stars svg{ width:16px; height:16px; }
.gbp-count{ margin-top:.35rem; font-size:.84rem; color:var(--blue-bright); }
.gbp-verified{ display:flex; align-items:center; gap:.35rem; margin-top:.25rem; font-size:.8rem; color:var(--slate); }
.gbp-bars{ display:grid; gap:.3rem; margin-top:.9rem; }
.gbp-bar{ display:grid; grid-template-columns:auto 1fr auto; align-items:center; gap:.6rem; font-size:.74rem; color:var(--slate); }
.gbp-bar i{ display:block; height:8px; border-radius:4px; background:var(--surface-3); overflow:hidden; }
.gbp-bar i b{ display:block; height:100%; border-radius:4px; background:#F5B70A; }
.gbp-caption{ margin-top:1rem; font-size:.78rem; color:var(--slate); text-align:center; }

/* ==========================================================================
   AUTOMATION FLOW
   Four steps, blue connectors. Legible to a roofer in three seconds.
   ========================================================================== */
.flow{ display:grid; grid-template-columns:repeat(4,minmax(0,1fr)); gap:0; margin-top:2.5rem; }
.flow-step{ position:relative; padding:1.2rem 1rem; text-align:center; }
/* Drawn between steps, never after the last one. */
.flow-step + .flow-step::before{
  content:""; position:absolute; left:-50%; top:34px; width:100%; height:1px;
  background:linear-gradient(90deg, rgba(61,139,255,.15), rgba(61,139,255,.55), rgba(61,139,255,.15));
}
.flow-icon{
  position:relative; z-index:1;
  display:grid; place-items:center; width:52px; height:52px; margin:0 auto;
  background:var(--surface); border:1px solid rgba(61,139,255,.35); border-radius:14px;
  box-shadow:0 0 26px -10px var(--glow);
}
.flow-icon svg{ width:20px; height:20px; fill:var(--blue-bright); }
.flow-step b{ display:block; margin-top:.85rem; font-size:.94rem; color:var(--ink); }
/* :not(.flow-icon) matters: the icon tile is also a <span>, and a bare
   `.flow-step span` is (0,1,1) - it outranks `.flow-icon` at (0,1,0) and
   was overriding its display:grid with display:block, which knocked every
   icon to the top of its tile and shrank it to caption size. */
.flow-step span:not(.flow-icon){ display:block; margin-top:.25rem; font-size:.8rem; color:var(--slate); }

/* ==========================================================================
   REVIEW PLATE
   The product is photographed on white; the studio ground has been keyed out
   (assets/product/nfc-review-plate-cut.webp) so the plate sits in the Altus
   environment rather than inside a white box.
   ========================================================================== */
.plate{ position:relative; margin:0; display:grid; place-items:center; }
.plate img{
  position:relative; z-index:1;
  width:100%; max-width:370px; height:auto; margin:0 auto; display:block;
  background:none; padding:0; border-radius:0;
  filter:drop-shadow(0 40px 60px rgba(0,0,0,.85)) drop-shadow(0 0 40px rgba(10,92,255,.25));
}
.plate::before{
  content:""; position:absolute; z-index:0; width:78%; aspect-ratio:1; top:6%;
  background:radial-gradient(50% 50% at 50% 50%, var(--glow) 0%, var(--glow-soft) 42%, transparent 70%);
  filter:blur(24px);
}
.plate-pulse{
  position:absolute; z-index:0; top:50%; left:50%;
  width:62%; aspect-ratio:1; margin:-31% 0 0 -31%;
  border:1px solid rgba(61,139,255,.4); border-radius:24px; opacity:0;
}
.js-motion .plate-pulse{ animation:plate-ping 3.6s var(--ease) infinite; }
.js-motion .plate-pulse:nth-of-type(2){ animation-delay:1.8s; }
@keyframes plate-ping{
  0%{ transform:scale(.86); opacity:0; }
  22%{ opacity:.7; }
  100%{ transform:scale(1.32); opacity:0; }
}

/* ==========================================================================
   FINAL CTA — the other memorable moment: deepest black, one wave of light.
   ========================================================================== */
.cta-band{
  position:relative; overflow:hidden; isolation:isolate;
  background:var(--bg-deep); border-top:1px solid var(--line);
  padding:8rem 0 8.5rem;
}
.cta-wave{ position:absolute; left:0; right:0; bottom:0; z-index:-1; pointer-events:none; }
.cta-wave svg{ display:block; width:100%; height:auto; }
.cta-band::before{
  content:""; position:absolute; inset:auto 0 0 0; height:70%; z-index:-1;
  background:radial-gradient(60% 100% at 50% 130%, rgba(10,92,255,.35) 0%, rgba(10,92,255,.08) 45%, transparent 72%);
}
.cta-band h2{ color:var(--ink); }
.cta-band p{ color:var(--ink-soft); }
.cta-micro{
  display:flex; flex-wrap:wrap; justify-content:center; gap:.6rem 2rem;
  margin-top:2rem; list-style:none; font-size:.84rem; color:var(--slate);
}
.cta-micro li{ display:flex; align-items:center; gap:.45rem; }
.cta-micro svg{ width:14px; height:14px; fill:var(--blue-bright); flex:none; }
.cta-contact a, .cta-contact div{ background:var(--surface); border-color:var(--line); }
.cta-contact a:hover{ background:var(--surface-2); border-color:var(--line-strong); }
.cta-contact span{ color:var(--slate); }
.cta-contact strong{ color:var(--ink); }

/* ---------- Footer ---------------------------------------------------- */
.footer{ background:var(--bg-deep); border-top:1px solid var(--line); }
.footer-tagline{ color:var(--slate); }
.footer-links a, .footer-meta, .footer-legal{ color:var(--slate); }
.footer-links a:hover, .footer-meta a:hover, .footer-legal a:hover{ color:var(--blue-bright); }
.footer-bar, .footer-legal{ border-color:var(--line); }

/* ---------- Trajectory, re-lit ---------------------------------------- */
.traj-line{ stroke:rgba(255,255,255,.13); }
.traj-node{ fill:var(--bg-graphite); stroke:rgba(255,255,255,.22); }
.traj-node-core{ fill:rgba(255,255,255,.28); }
.traj-dot.is-on .traj-node{ stroke:var(--blue-bright); fill:var(--bg-graphite); }
.traj-dot.is-on .traj-node-core{ fill:var(--blue-bright); }
.traj-node-end{ filter:drop-shadow(0 0 14px var(--glow)); }
.traj-label b{ color:var(--ink-soft); }
.traj-label span{ color:var(--slate); }
.traj-label:hover b, .traj-label.is-on b{ color:var(--blue-bright); }
.traj-label.is-on{ border-top-color:var(--blue-bright); }
.traj-panel p{ color:var(--ink-soft); }

/* ---------- Work gallery, rates, FAQ, chrome details ------------------- */
.shot{ background:var(--surface); border-color:var(--line); }
.shot:hover{ border-color:var(--line-strong); }
.shot-cap b{ color:var(--ink); }
.shot-cap i{ color:var(--slate); }
.rate a:hover{ background:var(--surface); }
.rate-name{ color:var(--ink); }
.rate-price{ color:var(--ink); }
.rate a:hover .rate-price{ color:var(--blue-bright); }
.faq-q{ color:var(--ink); }
.faq-a p{ color:var(--ink-soft); }
.browser-bar{ background:var(--surface-2); border-bottom:1px solid var(--line); }
.browser-dot{ background:var(--surface-3); }
.browser-url{ color:var(--slate); }
.tap-num{ color:var(--slate); }
.tap-step b{ color:var(--ink); }
.tap-step span{ color:var(--slate); }
.pack{ background:var(--surface); border-color:var(--line); }
.pack-qty{ color:var(--slate); }
.pack-price{ color:var(--ink); }
.pack.is-best{ background:rgba(10,92,255,.14); border-color:var(--blue-bright); }
.pack-note{ color:var(--slate); }
.care-tile b{ color:var(--ink); }
.care-tile span{ color:var(--slate); }
.feature-price strong{ color:var(--ink); }
.feature-price span, .feature-note{ color:var(--slate); }
.compose-tags span{ background:var(--surface); border-color:var(--line); color:var(--ink-soft); }

/* ==========================================================================
   RESPONSIVE
   The dark composition is redesigned for the phone, not stacked. Order is
   headline -> visual -> explanation -> CTA, so proof arrives early.
   ========================================================================== */
@media (max-width:1040px){
  .hero-split{ grid-template-columns:1fr; gap:3.25rem; }
  .stage-tilt{ transform:none; }
  .stage-chip{ right:0; bottom:-14px; }
  .gbp-body{ grid-template-columns:1fr; }
  .gbp-side{ border-left:0; border-top:1px solid var(--line); }
}
@media (max-width:760px){
  .section{ padding:4.75rem 0; }
  .hero-lead{ padding:3.25rem 0 4rem; }
  .hero-lead .hero-sub{ max-width:none; }
  .hero-facts{ gap:.5rem 1.4rem; }
  .gbp-photos{ aspect-ratio:1000/420; grid-template-columns:1.4fr 1fr; }
  .gbp-ph-3{ display:none; }
  .gbp-actions{ gap:0; justify-content:space-between; }
  .flow{ grid-template-columns:1fr 1fr; gap:.5rem 0; }
  .flow-step:nth-child(3)::before{ display:none; }
  .cta-band{ padding:5.5rem 0 6rem; }
}
@media (max-width:520px){
  .gbp-photos{ aspect-ratio:1000/560; grid-template-columns:1fr; grid-template-rows:1fr; }
  .gbp-ph-lead{ grid-row:auto; }
  .gbp-ph-2,.gbp-ph-4,.gbp-ph-last{ display:none; }
  .gbp-main,.gbp-side{ padding:1.25rem 1.15rem; }
  .flow{ grid-template-columns:1fr; }
  .flow-step + .flow-step::before{ display:none; }
  .flow-step{ display:grid; grid-template-columns:52px 1fr; gap:0 1rem; text-align:left; align-items:center; padding:.6rem 0; }
  .flow-step b{ margin-top:0; }
  .flow-icon{ margin:0; }
}
@media (prefers-reduced-motion:reduce){
  .stage-tilt{ transition:none; }
  .plate-pulse{ animation:none!important; opacity:0; }
}

/* ==========================================================================
   REVIEW PLATE LAYOUT
   Source order is the phone order the brief asks for — headline, product,
   explanation, price. On desktop the grid re-places those three blocks into
   two columns with the product spanning both rows, so neither viewport is a
   compromise and nothing is duplicated.
   ========================================================================== */
.plate-layout{
  display:grid;
  grid-template-columns:minmax(0,1fr) minmax(0,.92fr);
  grid-template-areas:"head fig" "rest fig";
  grid-template-rows:auto 1fr;
  gap:1.5rem 4.5rem;
  align-items:start;
}
.plate-head{ grid-area:head; }
.plate{ grid-area:fig; align-self:center; }
.plate-rest{ grid-area:rest; }
.plate-rest .tap,
.plate-rest .packs{ margin-top:2.4rem; }
.plate-rest .btn{ margin-top:1.6rem; }

@media (max-width:900px){
  .plate-layout{
    grid-template-columns:1fr;
    grid-template-areas:"head" "fig" "rest";
    gap:2rem;
  }
  .plate img{ max-width:290px; }
}

/* ==========================================================================
   FIXES — first dark render pass
   ========================================================================== */

/* --- Word spacing --------------------------------------------------------
   Clash Display at -.03/-.045em letter-spacing was eating the word gaps as
   well as the letter gaps: "A proven process" rendered as "Aproven process".
   Letter-spacing is applied to the space character too, so it has to be paid
   back explicitly. */
h1,h2,h3,h4{ word-spacing:.09em; }
.hero-lead .hero-title{ word-spacing:.12em; }

/* --- Trajectory ----------------------------------------------------------
   The base line at 13% white vanished on near-black, and .traj-label:last-child
   painted "You grow" blue permanently — which read as a second selected tab
   next to the real one. */
.traj-line{ stroke:rgba(255,255,255,.2); stroke-width:2.5; }
.traj-label:last-child b{ color:var(--ink-soft); }
.traj-label:last-child:hover b,
.traj-label:last-child.is-on b{ color:var(--blue-bright); }
.traj-lit{ filter:drop-shadow(0 0 6px rgba(61,139,255,.55)); }
.traj{ margin-top:1.5rem; }
.traj-svg{ height:clamp(140px,15vw,215px); }

/* --- Google Growth, full width ------------------------------------------ */
.gg-head{
  display:grid; grid-template-columns:minmax(0,1fr) auto;
  gap:1.75rem 3.5rem; align-items:end; margin-bottom:2.75rem;
}
.gg-head .section-lede{ margin-top:1rem; max-width:46ch; }
.gg-buy{ display:flex; flex-direction:column; align-items:flex-start; gap:1rem; }
.gg-buy .feature-price{ margin:0; }
.gg-note{ max-width:52ch; margin:1.5rem auto 0; text-align:center; }
@media (max-width:860px){
  .gg-head{ grid-template-columns:1fr; align-items:start; }
}

/* --- Flow connectors -----------------------------------------------------
   The line was drawn at 34px, which crossed the icons near their top edge
   rather than through their centre (padding 1.2rem + half of a 52px icon). */
.flow-step + .flow-step::before{ top:45px; }

/* --- Websites composition ------------------------------------------------
   The inset phone was small enough to read as a stray rectangle. Give it a
   real device frame and enough size to be recognisable as a phone. */
.compose-phone{
  left:1%; bottom:-1.5rem; width:23%; min-width:118px; max-width:172px;
  border-radius:14px; overflow:hidden;
  border:1px solid rgba(255,255,255,.16);
  background:var(--surface);
  box-shadow:0 30px 60px -26px #000, 0 0 34px -14px var(--glow);
}
.compose-phone img{ border-radius:0; }

/* --- Hero device ---------------------------------------------------------
   A touch more perspective so it reads as an object, and the live-site chip
   clear of the site's own buttons. */
.stage-tilt{ transform:rotateY(calc(-12deg + var(--tx,0deg))) rotateX(calc(4deg + var(--ty,0deg))); }
.stage-chip{ right:-3%; bottom:-1.25rem; }
.hero-lead{ padding-bottom:4.5rem; }

/* --- Plate column ------------------------------------------------------- */
.plate-layout{ gap:1.5rem 3.5rem; }
.plate img{ max-width:335px; }

/* --- Trajectory geometry -------------------------------------------------
   The SVG had width:100% and a clamped HEIGHT. With the default
   preserveAspectRatio ("meet") the drawing scales to fit whichever axis is
   smaller — the height — so at 215px tall the 1000x300 viewBox rendered only
   ~716px wide and sat centred, leaving the nodes floating well inside their
   labels. Giving the box the viewBox's own aspect ratio makes "meet" an exact
   fit: the path spans the full measure and each node lands dead centre under
   its label, with the circles still circular (which is what
   preserveAspectRatio:none broke last time). */
.traj{
  width:auto; max-width:none;
  margin:1.75rem 0 0;      /* no viewport maths — it lives inside .wrap now */
}
.traj-svg{ width:100%; height:auto; aspect-ratio:1000/300; }
@media (max-width:900px){ .traj-svg{ aspect-ratio:1000/340; } }
@media (max-width:640px){ .traj-svg{ aspect-ratio:1000/420; } }

/* --- Hero facts ----------------------------------------------------------
   Four items in a ~500px column wrapped 3 + 1, which reads as a mistake.
   A deliberate two-by-two reads as a designed block. */
.hero-facts{
  display:grid; grid-template-columns:auto auto;
  justify-content:start; gap:.75rem 2.25rem;
}
@media (max-width:420px){ .hero-facts{ grid-template-columns:1fr; } }

/* ==========================================================================
   FIXES — second dark render pass
   ========================================================================== */

/* The "Reviews" heading sat directly on the business-update card: the
   h4 + h4 rule never matched because the card is between them. */
.gbp-post + h4{ margin-top:1.6rem; }

/* The base trajectory line was still ghosting out against graphite. */
.traj-line{ stroke:rgba(255,255,255,.26); }
.traj-node{ stroke:rgba(255,255,255,.3); }

/* The product is the dominant moment of its section and was reading small
   inside a lot of empty ground. */
.plate img{ max-width:430px; }
.plate::before{ width:88%; }
.plate-layout{ grid-template-columns:minmax(0,1fr) minmax(0,1.02fr); }

/* The inset "phone" was a 16:9 screenshot in a small box, which reads as a
   stray rectangle rather than a device. Crop it to a phone's aspect and show
   the top of the page, which is what a phone would actually be showing. */
.compose-phone{
  width:20%; min-width:112px; max-width:150px;
  aspect-ratio:9/19; border-radius:18px;
}
.compose-phone img{
  width:100%; height:100%;
  object-fit:cover; object-position:top center;
}

/* ==========================================================================
   AUDIT FIXES — contrast, overflow, tap targets
   ========================================================================== */

/* --- Grid overflow -------------------------------------------------------
   `1fr` is `minmax(auto,1fr)`: the auto floor is the item's min-content size,
   and a 1280px-wide screenshot has a large one. Below ~1000px the gallery was
   pushing ~190px past the viewport and being clipped, so two demo cards were
   simply unreachable on a phone. minmax(0,1fr) lets the tracks actually
   shrink; the same trap applied to the hero's single-column fallback.
   (Below 900px the gallery is already a horizontal scroll strip, so only the
   900-1024 band needed this.) */
.ind-gallery{ grid-template-columns:repeat(3,minmax(0,1fr)); }
@media (max-width:1040px){ .hero-split{ grid-template-columns:minmax(0,1fr); } }

/* Keep the hero's ambient light inside the viewport. It is already clipped by
   the section's overflow:hidden, but there is no reason to paint outside. */
.stage-glow{ left:-7%; right:-5%; }

/* --- Contrast ------------------------------------------------------------
   --blue is the FILL value; as text on near-black it lands at 3.7:1, which
   fails for anything under 24px. --blue-bright is the text value (5.9:1). */
.demo-link{ color:var(--blue-bright); }

/* "Best value" was near-white on --blue-bright: 3.0:1 at 9px. Flipping to the
   deeper fill with white on it gives 5.2:1. */
.pack-flag{ background:var(--blue); color:#fff; }

/* --- Tap targets ---------------------------------------------------------
   44px minimum. The footer links were 22-24px tall; padding gives them a real
   hit area without changing how the row looks. */
.h-toggle{ width:44px; height:44px; }
.footer-links a, .footer-legal a, .footer-meta a{
  display:inline-flex; align-items:center; min-height:44px;
}
.footer-links{ gap:1.75rem; margin:-.6rem 0; }
.footer-legal nav{ align-items:center; }

/* The header nav links were 24px tall. */
.h-nav a{ display:inline-flex; align-items:center; min-height:44px; }

/* The inset phone was sitting on top of the displayed site's headline. The
   cause was height, not position: at 9/19 the phone stood 316px tall against
   a ~292px browser, so anchoring it to the bottom still reached the top of
   the page behind it. A 9/16 crop of the same screenshot is shorter than the
   browser, so it layers over the bottom-left corner only — a device
   composition rather than an occlusion. */
.compose{ padding-left:0; padding-bottom:0; }
.compose-phone{
  left:-2%; bottom:-2rem;
  width:19%; min-width:96px; max-width:132px;
  aspect-ratio:9/16;
}
@media (max-width:640px){
  .compose-phone{ left:0; bottom:-1.25rem; min-width:78px; }
}

/* Bottom-LEFT was still wrong: that corner of the displayed site is where its
   headline sits, so the phone covered the one line the mockup exists to show.
   The bottom-right of that screenshot is photography, which the phone can
   safely overlap. */
.compose-phone{ left:auto; right:-4%; bottom:-2rem; aspect-ratio:9/15; }
@media (max-width:640px){ .compose-phone{ right:0; left:auto; } }

/* Cropping a 16:9 desktop screenshot to a phone's portrait means taking a
   narrow vertical slice; centred, that slice lands on the middle of the
   layout and reads as noise. Biased left it catches the hero copy, which is
   what a phone would actually be showing. */
.compose-phone img{ object-position:18% top; }

/* ==========================================================================
   MOBILE HERO ORDER
   The brief's phone order is headline -> visual -> explanation -> CTA, so the
   proof arrives before the argument. The copy block is flattened with
   display:contents at this width, which promotes its children to grid items
   so they can be ordered around the device without duplicating any markup.
   ========================================================================== */
@media (max-width:1040px){
  .hero-copy{ display:contents; }
  .hero-split{ gap:0; }
  .hero-lead .eyebrow{ order:1; }
  .hero-lead .hero-title{ order:2; margin-top:1rem; }
  .hero-lead .stage{ order:3; margin:2.5rem 0 .5rem; }
  .hero-lead .hero-sub{ order:4; margin-top:2rem; }
  .hero-lead .hero-ctas{ order:5; }
  .hero-lead .hero-facts{ order:6; }
}

/* The two-column plate grid was re-declared later in this sheet without a
   media query, which silently overrode the <=900px stack and squeezed the
   whole section into a ~150px column on a phone. Re-assert the stack after
   it. (Same class of bug as the .traj rules: an unscoped tweak appended
   after a breakpoint wins on source order at every width.) */
@media (max-width:900px){
  .plate-layout{
    grid-template-columns:minmax(0,1fr);
    grid-template-areas:"head" "fig" "rest";
    gap:2rem;
  }
  .plate img{ max-width:300px; }
}

/* Once .feature stacks, .compose spans the full wrap and a negative right
   offset pushes the phone past the viewport — 1px of real document scroll
   at 900px. Pull it back inside the composition at that point. */
@media (max-width:1040px){ .compose-phone{ right:0; } }

/* Inline links in running text were painted with --blue, the FILL value,
   which measures 3.7:1 on the dark ground and fails AA below 24px. Anything
   that is a link inside prose uses the text-weight blue instead. */
.legal a:not(.skip-link), .ag-body a:not(.btn):not(.skip-link),
.prose a, p a:not(.btn):not(.skip-link), li a:not(.btn):not(.skip-link){
  color:var(--blue-bright);
}
.demo-link, .card a:not(.btn){ color:var(--blue-bright); }
/* The skip link is white on the blue fill and must stay that way: the rule
   above matched it as "a link inside .ag-body" and left blue on blue. */
.skip-link{ color:#fff; }

/* Breadcrumb links are 32x17 of inline text. Giving them a 44px min-height
   would blow the crumb row apart, so the hit area is expanded with an
   absolutely positioned pseudo-element instead: the touch target grows, the
   layout does not move. */
.breadcrumb a{ position:relative; }
.breadcrumb a::after{ content:""; position:absolute; inset:-14px -8px; }

/* ==========================================================================
   FLOW ICONS — redrawn
   The first pass used 20px solid glyphs inside a 52px tile: they read as
   small dots rather than icons, and the "tap" glyph was an unreadable blob.
   These are drawn as strokes on a 24 grid at 26px, which fills the tile and
   matches the hairline language used everywhere else on the page.
   ========================================================================== */
.flow-icon{
  width:58px; height:58px; border-radius:17px;
  background:linear-gradient(160deg, rgba(61,139,255,.14), rgba(10,92,255,.05));
  border:1px solid rgba(61,139,255,.32);
  box-shadow:0 0 30px -12px var(--glow), inset 0 1px 0 rgba(255,255,255,.07);
}
.flow-icon svg{
  width:27px; height:27px;
  fill:none;
  stroke:var(--blue-bright);
  stroke-width:1.6;
  stroke-linecap:round;
  stroke-linejoin:round;
}
/* the connector has to meet the tile's centre, which moved with its height */
.flow-step + .flow-step::before{ top:48px; }
.flow-step{ padding:1.2rem .75rem; }
.flow-step b{ margin-top:1rem; font-size:.97rem; }

/* The inset phone is now a genuine 390x780 render rather than a desktop
   screenshot cropped to a phone shape, so it can use its own aspect and stop
   pretending. */
.compose-phone{ aspect-ratio:390/780; }
.compose-phone img{ object-position:top center; }

@media (max-width:520px){
  .flow-icon{ width:52px; height:52px; }
  .flow-icon svg{ width:24px; height:24px; }
}

/* background: <gradient> is shorthand — it reset background-color to
   transparent, so the connector line was visible straight through each tile.
   Set the colour and the image separately. */
.flow-icon{
  background-color:var(--bg-graphite);
  background-image:linear-gradient(160deg, rgba(61,139,255,.16), rgba(10,92,255,.04));
}
/* the connector meets the tile's true centre: 23px offset + half of 58px */
.flow-step + .flow-step::before{ top:52px; }

/* The phone was small enough that the site inside it was unreadable — it read
   as a shape rather than a screen. */
.compose-phone{ width:22%; min-width:110px; max-width:154px; }

/* .footer-meta was the one footer row left at align-items:normal (i.e.
   stretch). Its two links are inline-flex with a 44px min-height for touch,
   so their text centres; the plain "West Palm Beach, FL" span stretched to
   the same height with its text at the top, riding ~9px high. Centring the
   row lines all three up on one midline. */
.footer-meta{ align-items:center; }

/* The hero mockup is an <a> now, so it needs a block box — an anchor defaults
   to inline and the composition collapses without this. */
.browser{ display:block; }
.stage .browser:focus-visible{ outline:2px solid var(--blue-bright); outline-offset:4px; }
.stage .browser:hover{ box-shadow:0 0 0 1px rgba(10,92,255,.22), 0 0 74px -12px var(--glow), 0 70px 120px -50px #000; }

/* ==========================================================================
   WORD SPACING, THE REST OF IT
   The h1-h4 fix only covered headings. Clash Display is used on a number of
   non-heading elements too, all of them with negative letter-spacing, and
   letter-spacing shrinks the word gap along with the letter gaps — the footer
   tagline was rendering as "WeBuild.YouGrow." Anything wearing the display
   face pays the spacing back.
   ========================================================================== */
.footer-tagline,
.h-brand,
.traj-label b,
.rate-name, .rate-desc,
.care-tile b, .tap-step b,
.strip-list li,
.offer-name, .pull-quote p,
.gbp-name, .gbp-post-brand b{
  word-spacing:.08em;
}
/* Numerals and single words don't need it, and it looks wrong on a price. */
.rate-price, .pack-price, .feature-price strong, .gbp-score b{ word-spacing:normal; }

/* ==========================================================================
   PORTFOLIO THUMBNAILS
   The cards fixed the image to 270px tall and let width fill the column. At
   three across that is roughly 355x270 - a 1.31 box holding a 1.78 screenshot
   - so object-fit:cover cropped the sides off every site, cutting headlines
   in half. A portfolio thumbnail exists to show the whole page, so the box
   takes the screenshot's own aspect ratio instead of a fixed height.
   ========================================================================== */
.grid-work .demo-shot img{ height:auto; aspect-ratio:16/9; object-position:center top; }


/* ==========================================================================
   MOBILE PASS
   ==========================================================================
   Earlier breakpoints were bolted on one at a time and started fighting each
   other. This block is the single authority for phone layout on the sections
   below; it sets every property it depends on rather than inheriting from
   whichever rule happened to win.
   ========================================================================== */

/* Hover states are gated behind an actual hover-capable pointer. On a
   touchscreen :hover latches after a tap, which is why a price row stayed
   highlighted after being pressed. */
@media (hover:none){
  .rate a:hover, .shot:hover, .card:hover, .offer:hover, .demo-card:hover{
    background:inherit; transform:none;
  }
  .rate a:hover{ padding-left:.25rem; }
}

/* ---------- Website Design composition ---------------------------------
   The phone was position:static below 900px (an old rule), so the absolute
   offsets every later rule set were inert and it dropped 16px clear of the
   browser as a stray rectangle. Rather than re-assert absolute positioning in
   a space too narrow to overlap cleanly, the phone becomes a real sibling:
   two devices standing side by side, bottom-aligned, which is what the
   section is claiming anyway — one site, both screens. */
@media (max-width:760px){
  .compose{
    display:flex; align-items:flex-end; gap:.85rem;
    padding:0; margin:0;
  }
  .compose .browser{ flex:1 1 auto; min-width:0; }
  .compose-phone{
    position:static;
    flex:0 0 27%; width:auto; min-width:0; max-width:124px;
    margin:0; aspect-ratio:390/780;
    border-radius:14px;
  }
}

/* ---------- Review flow ------------------------------------------------
   Was a two-column icon/text row, and the step numeral pushed the title into
   the icon's 52px column. Centred pairs instead: numeral, icon, title, line.
   Four across on desktop, two-by-two on a phone. */
.flow-num{
  display:block;
  font-family:var(--font-mono); font-size:.62rem; letter-spacing:.2em;
  color:var(--blue-bright); font-style:normal;
  margin-bottom:.55rem;
}
.flow-step{
  display:flex; flex-direction:column; align-items:center; text-align:center;
}
.flow-num{ order:-1; }
.flow-step b{ margin-top:.9rem; }

@media (max-width:760px){
  .flow{ grid-template-columns:1fr 1fr; gap:2.25rem 1rem; margin-top:2rem; }
  .flow-step{ padding:0; }
  .flow-step + .flow-step::before{ display:none; }
  .flow-step b{ margin-top:.8rem; font-size:.95rem; }
  .flow-step span:not(.flow-icon){ margin-top:.3rem; font-size:.82rem; max-width:19ch; }
  .flow-icon{ margin:0; }
}
@media (max-width:340px){
  .flow{ grid-template-columns:1fr; gap:1.75rem; }
}

/* ---------- Prices ------------------------------------------------------
   A flat list of four rows carried no weight, and on a phone the price sat
   under the description as a third line of text. Desktop keeps the list but
   gains a chevron and a heavier price; a phone gets four real cards with the
   price held on the right where the eye lands. */
.rate a{
  grid-template-columns:1fr auto auto;
  grid-template-areas:"name price go" "desc price go";
}
.rate a::after{
  grid-area:go; content:""; align-self:center;
  width:8px; height:8px; margin-left:1.25rem;
  border-right:1.5px solid var(--slate); border-top:1.5px solid var(--slate);
  transform:rotate(45deg);
  transition:border-color .2s var(--ease), transform .2s var(--ease);
}
.rate-price{ font-size:1.5rem; }
@media (hover:hover){
  .rate a:hover::after{ border-color:var(--blue-bright); transform:rotate(45deg) translate(2px,-2px); }
}

@media (max-width:640px){
  .rates{
    border-top:0; display:grid; gap:.7rem;
    max-width:26rem;
  }
  .rate{ border:1px solid var(--line); border-radius:14px; background:var(--surface); }
  .rate a{
    grid-template-columns:1fr auto;
    grid-template-areas:"name price" "desc price";
    align-items:center; gap:.2rem 1rem;
    padding:1.15rem 1.15rem;
  }
  .rate a:hover{ padding-left:1.15rem; }
  .rate a::after{ display:none; }
  .rate-name{ font-size:1.02rem; }
  .rate-desc{ font-size:.86rem; }
  .rate-price{
    grid-area:price; justify-self:end; text-align:right;
    font-size:1.45rem; color:var(--ink); line-height:1;
  }
  .rate-price i{ display:block; font-size:.68rem; margin:.2rem 0 0; }
  /* the accent that the hover state provides on desktop */
  .rate::before{
    content:""; display:block; height:2px; width:38px; margin:1.15rem 0 -.35rem 1.15rem;
    background:linear-gradient(90deg,var(--blue-bright),transparent);
    border-radius:2px;
  }
  .rates-note{ margin-top:1.25rem; font-size:.82rem; }
}

/* ---------- Footer ------------------------------------------------------
   Centred on a phone: three rows of left-aligned links against a full-width
   button read as a broken column. */
@media (max-width:760px){
  .footer-top{ align-items:center; text-align:center; gap:1.75rem; }
  .footer-top > div{ display:flex; flex-direction:column; align-items:center; }
  .footer-bar{ flex-direction:column; align-items:center; gap:1rem; padding:1.4rem 0; }
  .footer-links{ justify-content:center; gap:1.5rem; margin:0; }
  .footer-meta{
    flex-direction:column; align-items:center; justify-content:center;
    gap:.15rem; text-align:center;
  }
  .footer-legal{
    flex-direction:column; align-items:center; gap:.35rem;
    text-align:center; padding-top:1.4rem;
  }
  .footer-legal nav{ justify-content:center; }
}

/* ---------- General phone polish --------------------------------------- */
@media (max-width:760px){
  .section{ padding:4.25rem 0; }
  .wrap{ padding:0 1.35rem; }
  .h-brand img{ width:28px; height:auto; }
  .h-brand span{ font-size:1.02rem; }
  .section-head{ margin-bottom:2.25rem; }
  .hero-lead .hero-ctas .btn{ width:100%; }
  .cta-band .btn{ width:100%; max-width:22rem; }
}

/* ---------- Review plate section, phone --------------------------------
   Both of these stacked to one column below 900px, which turned five short
   items into a very long scroll for almost no information. They are short
   enough to sit across the width: three tap steps in a row, three price
   packs in a row. */
@media (max-width:760px){
  .tap{
    grid-template-columns:repeat(3,minmax(0,1fr));
    gap:.75rem; text-align:center;
  }
  .tap-step{ text-align:center; }
  .tap-num{ margin-bottom:.45rem; }
  .tap-step b{ font-size:.95rem; }
  .tap-step span{ font-size:.76rem; margin-top:.2rem; }

  .packs{
    grid-template-columns:repeat(3,minmax(0,1fr));
    gap:.5rem; margin-top:2.25rem;
  }
  .pack{ padding:1.15rem .45rem 1rem; border-radius:13px; }
  .pack-qty{ font-size:.62rem; letter-spacing:.1em; }
  .section-dark .pack-price{ font-size:1.4rem; margin-top:.3rem; }
  .pack-flag{ font-size:.46rem; padding:.24rem .45rem; top:-8px; }
  .pack-note{ margin-top:1rem; font-size:.82rem; }
  .plate-rest .btn{ width:100%; }
}
/* Below this the three packs stop fitting legibly side by side. */
@media (max-width:360px){
  .tap{ grid-template-columns:repeat(3,minmax(0,1fr)); gap:.5rem; }
  .tap-step span{ display:none; }
  .packs{ gap:.4rem; }
  .section-dark .pack-price{ font-size:1.2rem; }
}

/* "from" is a qualifier, not part of the figure — set it above the number in
   the same mono treatment as "/mo" so the amount is what the eye lands on. */
.rate-price em{
  display:block; font-style:normal;
  font-family:var(--font-mono); font-size:.58rem; letter-spacing:.14em;
  text-transform:uppercase; color:var(--slate);
  margin-bottom:.15rem; line-height:1;
}

/* The step numeral sits above the icon, which pushed the tiles 21px further
   down the step; the connector was still drawn at the old 52px and clipped
   their top edge. Measured centre is now 73px. */
.flow-step + .flow-step::before{ top:73px; }

/* ==========================================================================
   BUNDLE — Google Growth + Review Automation
   Emphasis comes from an accent panel, not from shrinking the services either
   side of it. Sits inside a .sec-char section, so it reads against dark.
   ========================================================================== */
.bundle{
  position:relative;
  margin-top:3rem;
  display:grid;
  grid-template-columns:1fr auto;
  gap:2.5rem;
  align-items:center;
  padding:2.4rem 2.4rem;
  border:1px solid var(--blue);
  border-radius:20px;
  background:
    radial-gradient(120% 160% at 0% 0%, rgba(47,139,255,.16), transparent 60%),
    rgba(255,255,255,.03);
  box-shadow:0 30px 80px -40px rgba(47,139,255,.55);
}
.bundle-flag{
  display:inline-block;
  margin:0 0 .9rem;
  padding:.24rem .7rem;
  border-radius:100px;
  background:var(--blue);
  color:#fff;
  font-family:var(--font-mono);
  font-size:.58rem;
  letter-spacing:.14em;
  text-transform:uppercase;
}
.bundle-title{
  margin:0 0 .7rem;
  font-family:var(--font-display);
  font-size:clamp(1.3rem,2.6vw,1.85rem);
  line-height:1.15;
  letter-spacing:-.02em;
}
.bundle-copy{ margin:0; max-width:46ch; opacity:.78; font-size:.98rem; line-height:1.6; }

.bundle-buy{ text-align:right; display:grid; justify-items:end; gap:.15rem; }
.bundle-was{
  margin:0;
  font-size:.9rem;
  opacity:.55;
  text-decoration:line-through;
}
.bundle-was span{ text-decoration:none; display:inline-block; margin-left:.3rem; }
.bundle-price{ margin:0 0 .9rem; display:flex; align-items:baseline; gap:.3rem; }
.bundle-price strong{ font-size:2.6rem; line-height:1; letter-spacing:-.03em; }
.bundle-price span{ font-size:.9rem; opacity:.7; }
.bundle-save{
  margin:.7rem 0 0;
  font-family:var(--font-mono);
  font-size:.6rem;
  letter-spacing:.12em;
  text-transform:uppercase;
  opacity:.7;
}

/* The bundle row in the price list gets the accent border and flag, so the
   list and the panel above agree on which option is being recommended. */
.rate.is-best{ border-color:var(--blue); }
.rate.is-best .rate-name em{
  background:var(--blue);
  color:#fff;
  opacity:1;
}
.rate.is-best .rate-price{ color:var(--blue-bright, #2F8BFF); }

@media (max-width:820px){
  .bundle{
    grid-template-columns:1fr;
    gap:1.5rem;
    padding:1.9rem 1.6rem;
  }
  .bundle-buy{ justify-items:start; text-align:left; }
  .bundle-copy{ max-width:none; }
}
@media (max-width:520px){
  .bundle{ padding:1.6rem 1.35rem; }
  .bundle-price strong{ font-size:2.2rem; }
}

/* --- Add-ons line -----------------------------------------------------------
   The plates and Care still have full sections; here they are a footnote, so
   the eye reads three services and a bundle rather than a six-item menu. */
.addons{
  display:flex;
  flex-wrap:wrap;
  align-items:baseline;
  justify-content:center;
  gap:.5rem 1.4rem;
  margin:1.75rem 0 0;
  font-size:.92rem;
}
.addons > span{
  font-family:var(--font-mono);
  font-size:.6rem;
  letter-spacing:.14em;
  text-transform:uppercase;
  opacity:.55;
}
.addons a{
  opacity:.72;
  text-decoration:none;
  border-bottom:1px solid transparent;
  transition:opacity .18s var(--ease), border-color .18s var(--ease);
}
.addons a:hover,
.addons a:focus-visible{ opacity:1; border-bottom-color:currentColor; }

@media (max-width:520px){
  .addons{ flex-direction:column; align-items:center; gap:.55rem; text-align:center; }
}

/* --- Build tiers, inside the websites drawer -------------------------------- */
.tiers-mini{
  list-style:none;
  margin:1.1rem 0 0;
  padding:0;
  border-top:1px solid var(--line);
}
.tiers-mini li{
  display:flex;
  align-items:baseline;
  justify-content:space-between;
  gap:1rem;
  padding:.7rem 0;
  border-bottom:1px solid var(--line);
  font-size:.94rem;
}
.tiers-mini span{ opacity:.8; }
.tiers-mini b{ white-space:nowrap; font-weight:600; }

@media (max-width:420px){
  .tiers-mini li{ font-size:.88rem; gap:.75rem; }
}
