/* ==========================================================================
   Southern View Media. One stylesheet: every token, every class.
   Direction: art-direction-2026-09. Source of truth: concept-home.html.
   Light theme on navy, teal and light teal. Cream ground used lightly.
   House rules: every color goes through a variable. No hex outside :root.
   Class prefix: svm-. Modifiers use --. Elements use __. State uses is-.
   ========================================================================== */


/* --------------------------------------------------------------------------
   1. FONTS
   The three font links live in the HTML <head>, not here:
     https://use.typekit.net/dyi3elm.css          Calluna italic 400/700
     https://api.fontshare.com/v2/css?f[]=general-sans@400,500,600,700
     https://fonts.googleapis.com/css2?family=Figtree...&family=Fraunces...
   Calluna is Adobe licensed and cannot be self hosted. Fraunces is the
   offline fallback and carries the same SOFT axis setting.
   The stacks themselves are declared as tokens in block 2.
   -------------------------------------------------------------------------- */


/* --------------------------------------------------------------------------
   2. TOKENS
   -------------------------------------------------------------------------- */
:root{
  /* -- palette ---------------------------------------------------------- */
  --svm-navy-deep:#0F2436;
  --svm-navy:#1E3A52;
  --svm-navy-light:#2C5270;
  --svm-teal:#8FD4D4;
  --svm-teal-light:#E3F5F5;   /* brand teal at 25% on white. Approved 2026-09-01. */
  --svm-teal-ink:#2C8BA3;
  --svm-teal-deep:#1E647D;
  --svm-cream:#FAF6EE;
  --svm-sand:#EAE3D3;
  --svm-sand-warm:#D9CDB6;
  --svm-coral:#F88379;
  --svm-coral-deep:#D75E52;
  --svm-white:#FFFFFF;

  /* alpha triples. Use rgba(var(--svm-navy-rgb),.16) instead of a raw color. */
  --svm-navy-rgb:30,58,82;
  --svm-navy-deep-rgb:15,36,54;
  --svm-teal-rgb:143,212,212;
  --svm-cream-rgb:250,246,238;
  --svm-white-rgb:255,255,255;

  /* -- theme aliases ----------------------------------------------------- */
  /* Themes swap these six. Component rules never name a palette token. */
  --bg:var(--svm-cream);
  --panel:var(--svm-teal-light);
  --card:var(--svm-white);
  --ink:var(--svm-navy);
  --teal:var(--svm-teal);
  --accent:var(--svm-coral);
  --muted:rgba(var(--svm-navy-rgb),.78);
  --rule:rgba(var(--svm-navy-rgb),.16);

  /* -- type families ----------------------------------------------------- */
  --f-display:"General Sans",system-ui,sans-serif;
  --f-italic:"calluna","Fraunces",Georgia,serif;
  --f-body:"Figtree",system-ui,sans-serif;
  --f-mono:"General Sans",system-ui,sans-serif;   /* the label role, not a mono face */

  /* -- type scale -------------------------------------------------------- */
  --fs-display:clamp(52px,7vw,116px);
  --fs-headline:clamp(36px,4vw,64px);
  --fs-section:clamp(30px,2.8vw,46px);
  --fs-large:21px;
  --fs-body:16px;
  --fs-small:13px;
  --fs-mono:11px;

  /* -- line height ------------------------------------------------------- */
  --lh-tight:.86;
  --lh-display:.96;
  --lh-snug:1.04;
  --lh-body:1.5;

  /* -- letter spacing ---------------------------------------------------- */
  --ls-hero:-6px;
  --ls-display:-.03em;
  --ls-head:-.02em;
  --ls-tight:-.01em;
  --ls-mono:2px;

  /* -- radius ------------------------------------------------------------ */
  --r-sm:4px;
  --r-md:8px;
  --r-nav:18px;
  --r-pill:999px;

  /* -- spacing, 4pt scale ------------------------------------------------ */
  --sp-1:4px;   --sp-2:8px;   --sp-3:12px;  --sp-4:16px;
  --sp-5:20px;  --sp-6:24px;  --sp-7:32px;  --sp-8:40px;
  --sp-9:48px;  --sp-10:64px; --sp-11:96px; --sp-12:120px; --sp-13:140px;

  /* -- container --------------------------------------------------------- */
  --max:1440px;
  --gutter:clamp(20px,4vw,40px);
  --rail-pad:max(var(--gutter), calc((100vw - var(--max)) / 2 + var(--gutter)));
  --sec:clamp(72px,10vw,140px);
  --nav-h:84px;

  /* -- motion ------------------------------------------------------------ */
  --ease-out:cubic-bezier(.22,.61,.36,1);
  --dur-fast:.18s;
  --dur-med:.25s;
  --dur-card:.35s;
  --dur-mock:.55s;
  --dur-slow:.7s;
  --dur-zoom:.8s;

  /* -- seahorse ---------------------------------------------------------- */
  --seahorse-fill:var(--svm-teal);
  --seahorse-alpha:.55;
  --seahorse-edge:var(--svm-white);
  /* the fade that stops the mark before the hero's bottom edge. #000 here is an
     alpha key for the mask, not a palette color. */
  --seahorse-mask:linear-gradient(to bottom,#000 62%,transparent 96%);

  /* -- texture assets ---------------------------------------------------- */
  /* 256px noise tiles drawn at 128px so they stay crisp at 2x. The alpha is
     baked into the pixels. Plain repeating background image. Never a fixed
     layer, never a blend mode.
     Generator, for every tile: alpha = (random ** 2.6) * max_alpha, rounded to
     the nearest step of 6, one flat color, saved as a 256px RGBA PNG.
       grain-navy        navy  30,58,82     max alpha 28   cream and light teal
       grain-navy-light  navy  30,58,82     max alpha 22   white grounds only
       grain-cream       cream 250,246,238  max alpha 19   navy grounds
     grain-cream and grain-navy-light are about 20% lighter than grain-navy.
     Jamie, 2026-09-01. */
  --grain-navy:url("../assets/patterns/grain-navy.png");
  --grain-navy-light:url("../assets/patterns/grain-navy-light.png");
  --grain-cream:url("../assets/patterns/grain-cream.png");
  --grain-size:128px;
  --pattern-coral:url("../assets/patterns/subtle-ocean-corals-teal.svg");
  --pattern-size:1350px;
}


/* --------------------------------------------------------------------------
   3. BASE
   -------------------------------------------------------------------------- */
*{box-sizing:border-box}
html,body{margin:0}
body{
  background:var(--bg) var(--grain-navy) repeat 0 0 / var(--grain-size) var(--grain-size);
  color:var(--ink);
  font-family:var(--f-body);
  font-size:var(--fs-body);
  line-height:var(--lh-body);
  -webkit-font-smoothing:antialiased;
}
a{color:inherit}
/* height:auto is load bearing. An <img> with width and height attributes gets
   them as presentational hints, which sit BELOW author CSS but are still
   specified, so a component that sets width plus aspect-ratio and leaves height
   alone loses: the browser keeps the attribute height and drops the ratio. That
   is what made every post card render at its full pixel height. Any component
   that genuinely wants a fixed height sets one itself and outranks this.
   Jamie, 2026-09-01. */
img{display:block;max-width:100%;height:auto}
.svm-wrap{max-width:var(--max);margin:0 auto;padding-left:var(--gutter);padding-right:var(--gutter)}

/* the focus ring. One rule for every link, button and form control,
   including the navy surfaces (.svm-nav, .svm-menu, .svm-section--dark,
   .svm-footer). The teal token carries enough contrast on both the cream
   ground and the navy grounds, so no separate override is needed there.
   Never remove an outline anywhere on the site. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
[tabindex]:focus-visible{
  outline:2px solid var(--svm-teal);
  outline-offset:3px;
}


/* --------------------------------------------------------------------------
   4. TYPE ROLES
   -------------------------------------------------------------------------- */
.svm-display{font-family:var(--f-display);font-weight:600;font-size:var(--fs-display);line-height:var(--lh-display);letter-spacing:var(--ls-display);margin:0}
.svm-headline{font-family:var(--f-display);font-weight:500;font-size:var(--fs-headline);line-height:var(--lh-snug);letter-spacing:var(--ls-head);margin:0}
.svm-headline strong{font-weight:500}
.svm-section-h{font-family:var(--f-display);font-weight:600;font-size:var(--fs-section);line-height:1.1;letter-spacing:var(--ls-tight);margin:0}
.svm-lead{font-size:var(--fs-large);line-height:1.45;color:var(--muted);max-width:560px;margin:0}

/* the label role. General Sans 600 tracked caps. Never an eyebrow. */
.svm-mono{font-family:var(--f-mono);font-size:var(--fs-mono);letter-spacing:var(--ls-mono);text-transform:uppercase;font-weight:600;margin:0}

/* the italic accent. One word per headline, never body prose. */
.svm-italic{font-family:var(--f-italic);font-style:italic;font-weight:700;color:var(--teal);font-variation-settings:"SOFT" 80;letter-spacing:0}

/* display numbers and years only */
.svm-num{font-family:var(--f-italic);font-style:italic;font-weight:700;color:var(--ink);font-size:44px;line-height:1;letter-spacing:var(--ls-tight);margin:0}

/* the link affordance inside a tile */
.svm-more{font-family:var(--f-mono);font-size:var(--fs-mono);letter-spacing:var(--ls-mono);text-transform:uppercase;font-weight:600;color:var(--ink);text-decoration:none}

/* the phone number */
.svm-tel{font-family:var(--f-mono);font-size:12px;letter-spacing:1.5px;font-weight:600;text-decoration:none;color:inherit}
.svm-tel--display{font-family:var(--f-display);font-size:24px;font-weight:600;letter-spacing:var(--ls-tight);text-decoration:none;color:inherit}


/* --------------------------------------------------------------------------
   5. BUTTONS
   -------------------------------------------------------------------------- */
.svm-btn{
  position:relative;display:inline-flex;align-items:center;gap:10px;
  padding:15px 24px;border-radius:var(--r-sm);text-decoration:none;
  font-family:var(--f-mono);font-size:12px;letter-spacing:var(--ls-mono);
  text-transform:uppercase;font-weight:600;line-height:1;
  transition:transform var(--dur-fast) var(--ease-out),
             box-shadow var(--dur-fast) var(--ease-out),
             background var(--dur-fast),color var(--dur-fast);
}
.svm-btn__arr{font-family:var(--f-body);font-weight:400;font-size:14px;letter-spacing:0}

/* ONE hover for every button. Primary and outline, light ground and navy
   ground, all behave the same: the button lifts 2px up and 2px left, and a
   solid coral block appears behind it 4px down and 4px right. The block is a
   box-shadow, so it never changes the layout box and never causes overflow.
   An outline button keeps its outline and its transparent ground: no fill
   inversion anywhere. Replaced the old corner register marks and the three
   different outline hovers. Jamie, 2026-09-01. */
.svm-btn:hover{transform:translate(-2px,-2px);box-shadow:4px 4px 0 var(--svm-coral)}

.svm-btn--primary{background:var(--svm-teal);color:var(--svm-navy)}

.svm-btn--outline{background:transparent;color:var(--ink);border:1px solid var(--ink)}

/* teal outline. The header CTA on the navy bar. */
.svm-btn--outline-teal{background:transparent;color:var(--svm-teal);border:1px solid var(--svm-teal)}

/* on a navy ground. The coral block reads on navy, so the hover is unchanged. */
.svm-btn--primary.svm-btn--on-dark{background:var(--svm-teal);color:var(--svm-navy-deep)}
.svm-btn--outline.svm-btn--on-dark{color:var(--svm-cream);border-color:var(--svm-cream)}

.svm-cta-row{display:flex;gap:14px;flex-wrap:wrap}


/* --------------------------------------------------------------------------
   6. LAYOUT AND SECTIONS
   -------------------------------------------------------------------------- */
.svm-section{padding:var(--sec) 0}
.svm-section--panel{background:var(--panel) var(--grain-navy) repeat 0 0 / var(--grain-size) var(--grain-size)}
/* white grounds carry the lighter navy tile. Grain reads harder on white than
   it does on cream or on light teal, so white gets grain-navy-light and every
   other light ground keeps grain-navy. */
.svm-section--white{--bg:var(--svm-white);background:var(--svm-white) var(--grain-navy-light) repeat 0 0 / var(--grain-size) var(--grain-size)}
.svm-section--dark{
  background:var(--svm-navy) var(--grain-cream) repeat 0 0 / var(--grain-size) var(--grain-size);
  color:var(--svm-cream);
  --ink:var(--svm-cream);
  --teal:var(--svm-teal);
  --muted:rgba(var(--svm-cream-rgb),.78);
  --rule:rgba(var(--svm-teal-rgb),.3);
}

/* hairlines. A plain 1px rule, never dashed, never dotted. */
.svm-hairline-t,.svm-hairline-b{position:relative}
.svm-hairline-t::before,
.svm-hairline-b::after{content:"";position:absolute;left:0;right:0;height:1px;background:var(--rule);pointer-events:none}
.svm-hairline-b::after{bottom:0}
.svm-hairline-t::before{top:0}
.svm-hairline{height:1px;background:var(--rule)}

/* .svm-grid: the card grid. A card grid always fills its rows, so the builder
   states the card count and the grid spans the cards to match. Twelve columns,
   20px gap, one count modifier. Never leave an orphan card alone on the last
   row. Jamie, 2026-09-01. Replaced the fixed three-column .svm-grid-3.
     --2  6 6
     --3  4 4 4
     --4  3 3 3 3
     --5  4 4 4 / 6 6
     --6  4 4 4 / 4 4 4
     --7  3 3 3 3 / 4 4 4
     --8  3 3 3 3 / 3 3 3 3
   Past eight cards, split the grid or use the rail. */
.svm-grid{display:grid;grid-template-columns:repeat(12,1fr);gap:20px}
.svm-grid > *{grid-column:span 4}
.svm-grid--2 > *{grid-column:span 6}
.svm-grid--3 > *{grid-column:span 4}
.svm-grid--4 > *{grid-column:span 3}
.svm-grid--5 > *{grid-column:span 4}
.svm-grid--5 > :nth-child(n+4){grid-column:span 6}
.svm-grid--6 > *{grid-column:span 4}
.svm-grid--7 > *{grid-column:span 3}
.svm-grid--7 > :nth-child(n+5){grid-column:span 4}
.svm-grid--8 > *{grid-column:span 3}

.svm-sec-head{display:flex;justify-content:space-between;align-items:flex-end;gap:var(--sp-7);margin-bottom:clamp(32px,4vw,56px)}

/* the about band: image left, statement right */
.svm-about > .svm-wrap{display:grid;grid-template-columns:.9fr 1.1fr;gap:clamp(32px,6vw,96px);align-items:center}
/* the about band statement. About 10% under the headline role and a wider
   measure, so the last line carries more than the year at 1440 and 1920.
   Jamie, 2026-09-01. */
.svm-about .svm-headline{font-size:clamp(32px,3.6vw,58px);max-width:18ch}
.svm-about .svm-btn{margin-top:36px}


/* --------------------------------------------------------------------------
   7. HEADER AND MOBILE MENU
   -------------------------------------------------------------------------- */
/* the top bar. A full-bleed strip of deeper navy that the rounded header
   hangs from. It scrolls away; the header below stays sticky. */
.svm-topbar{background:color-mix(in srgb,var(--svm-navy) 78%,#000);color:var(--svm-cream)}
.svm-topbar{overflow:hidden;max-height:36px;transition:max-height .25s var(--ease-out)}
.svm-past-top .svm-topbar{max-height:0}
.svm-topbar__wrap{display:flex;justify-content:space-between;align-items:center;gap:16px;height:36px}
.svm-topbar a{font-family:var(--f-mono);font-size:11px;letter-spacing:1.5px;text-transform:uppercase;font-weight:600;text-decoration:none;color:var(--svm-cream);opacity:.85;display:inline-flex;align-items:center;gap:6px;padding:10px 0;white-space:nowrap}
.svm-topbar a:hover{opacity:1;color:var(--svm-teal)}
.svm-topbar__right{display:flex;gap:26px;align-items:center}
.svm-topbar .svm-nav__ext{font-size:11px;margin:0;opacity:.8}
.svm-nav{position:sticky;top:0;z-index:20;color:var(--svm-cream);--ink:var(--svm-cream)}
.svm-nav__wrap{
  background:var(--svm-navy);border-radius:0 0 var(--r-nav) var(--r-nav);
  display:grid;grid-template-columns:auto 1fr auto;align-items:center;height:var(--nav-h);
}
.svm-logo{height:30px;width:auto;color:var(--ink);display:inline-flex;align-items:center}
/* .svm-wordmark is the inline SVG itself. It carries the class so the rule
   names the component instead of the element, which is what Bricks needs: the
   lockup is a Code element and a bare `svg` selector would also catch the
   seahorse and every icon. */
.svm-logo .svm-wordmark{height:100%;width:auto}
.svm-logo .svm-wordmark *{fill:currentColor!important;opacity:1!important;stroke:none}

/* .svm-logo--duo: the two-color lockup. Teal script, white MEDIA. Dark grounds
   only, which is the nav, the mobile menu panel and the footer. Every other
   use stays single color through currentColor, so one file still serves every
   ground. The two groups inside the inline SVG carry .svm-wordmark__script and
   .svm-wordmark__media; the source file paints the script #91d5de, and this
   uses --svm-teal instead so the palette stays single sourced.
   Jamie, 2026-09-01. */
.svm-logo--duo .svm-wordmark__script path{fill:var(--svm-teal)!important}
.svm-logo--duo .svm-wordmark__media path{fill:var(--svm-white)!important}

.svm-nav__links{display:flex;gap:24px;justify-content:center}
.svm-nav__links > a{text-decoration:none;font-size:14px;white-space:nowrap;font-weight:500;color:var(--svm-cream);opacity:.85}
.svm-nav__links > a:hover{opacity:1;text-decoration:underline;text-decoration-color:var(--svm-teal);text-underline-offset:6px;text-decoration-thickness:2px}
/* 44px tap target. Padding grows the hit and focus box; the matching
   negative margin cancels it back out of the flex layout, so the visible
   text does not move and the header keeps its own height. */
/* direct children only: the mega menu's own links must not inherit the
   nav link box, or the pane buttons lose their padding. */
.svm-nav__links > a{padding:15px 0;margin:-15px 0}

/* -- the Services mega menu ------------------------------------------- */
/* The panel is the full width of the nav bar's container and hangs directly
   under it, so .svm-nav__wrap is the positioned ancestor and .svm-nav__dd
   stays static. A teal hairline is the only seam between the bar and the
   panel. 1024 and down the panel is gone and the mobile accordion is what
   renders. */
.svm-nav__wrap{position:relative}
.svm-nav__dd{position:static;display:flex;align-items:center}
.svm-nav__dd-btn{
  appearance:none;-webkit-appearance:none;background:none;border:0;cursor:pointer;
  font-family:var(--f-body);font-size:14px;font-weight:500;color:var(--svm-cream);opacity:.85;white-space:nowrap;
  display:inline-flex;align-items:center;gap:7px;padding:15px 0;margin:-15px 0;
}
.svm-nav__dd-btn:hover,
.svm-nav__dd-btn[aria-expanded="true"]{opacity:1;text-decoration:underline;text-decoration-color:var(--svm-teal);text-underline-offset:6px;text-decoration-thickness:2px}
/* the caret. A rotated square corner, so there is no icon file. */
.svm-nav__dd-btn i{width:6px;height:6px;border-right:1.5px solid currentColor;border-bottom:1.5px solid currentColor;transform:translateY(-2px) rotate(45deg);transition:transform var(--dur-fast) var(--ease-out)}
.svm-nav__dd-btn[aria-expanded="true"] i{transform:translateY(1px) rotate(-135deg)}

.svm-nav__mm{
  position:absolute;top:100%;left:0;z-index:21;
  width:max-content;max-width:min(960px,calc(100% - 48px));
  background:var(--svm-navy);border-radius:0 0 var(--r-nav) var(--r-nav);
  border-top:1px solid rgba(var(--svm-teal-rgb),.25);
  padding:32px 32px 28px;
  display:grid;gap:24px 40px;
  opacity:0;visibility:hidden;transform:translateY(-6px);
  transition:opacity .2s var(--ease-out),transform .2s var(--ease-out),visibility .2s;
}
/* svm.js sets left so the panel sits under its own button, clamped inside the bar. */
.svm-nav__mm.is-open{opacity:1;visibility:visible;transform:none}

/* one of the three link columns, Build, Advertise, Grow. min-width:0 is load
   bearing: a grid item defaults to min-content, so a long service name would
   push the four-track grid wider than the header. */
.svm-nav__mm-group{min-width:0}
.svm-nav__mm-label{font-family:var(--f-mono);font-size:var(--fs-mono);letter-spacing:var(--ls-mono);text-transform:uppercase;font-weight:600;color:var(--svm-teal);margin:0 0 12px}
.svm-nav__mm-row{display:grid;grid-template-columns:36px minmax(0,1fr);gap:12px;align-items:start;padding:9px 0;text-decoration:none;color:var(--svm-cream)}
.svm-nav__mm-ico{width:36px;height:36px;border-radius:var(--r-sm);background:var(--svm-teal-light);display:grid;place-items:center;transition:background var(--dur-fast) var(--ease-out)}
.svm-nav__mm-ico svg{width:18px;height:18px;display:block;fill:none;stroke:var(--svm-navy);stroke-width:1.75;stroke-linecap:round;stroke-linejoin:round}
.svm-nav__mm-txt{display:flex;flex-direction:column;gap:3px;min-width:0}
.svm-nav__mm-txt b{font-size:15px;font-weight:600;line-height:1.2;transition:color var(--dur-fast) var(--ease-out)}
.svm-nav__mm-txt em{font-style:normal;font-size:13px;line-height:1.35;color:rgba(var(--svm-cream-rgb),.7)}
.svm-nav__mm-row:hover,
.svm-nav__mm-row:focus-visible{text-decoration:none}
.svm-nav__mm-row:hover .svm-nav__mm-txt b,
.svm-nav__mm-row:focus-visible .svm-nav__mm-txt b{color:var(--svm-teal)}
.svm-nav__mm-row:hover .svm-nav__mm-ico,
.svm-nav__mm-row:focus-visible .svm-nav__mm-ico{background:var(--svm-teal)}

/* panel shapes. --2 is two link columns, --3 is the icon-row grid. */
.svm-nav__mm--1{grid-template-columns:minmax(0,1fr)}
.svm-nav__mm--2{grid-template-columns:repeat(2,minmax(0,max-content))}
.svm-nav__mm--3{width:min(960px,calc(100% - 48px));grid-template-columns:repeat(3,minmax(0,1fr));gap:4px 32px}
@media (max-width:1400px){.svm-nav__mm--3{width:min(820px,calc(100% - 48px))}}
/* plain link rows inside a panel */
.svm-nav__mm-link{display:block;padding:7px 0;font-size:15px;font-weight:500;line-height:1.3;color:var(--svm-cream);opacity:.88;text-decoration:none;white-space:nowrap}
.svm-nav__mm-link:hover,
.svm-nav__mm-link:focus-visible{opacity:1;color:var(--svm-teal);text-decoration:none}
.svm-nav__ext{font-size:12px;margin-left:5px;opacity:.7}
/* the All services link sits alone on the last row, right aligned. */
.svm-nav__mm-all{grid-column:1 / -1;justify-self:end;margin-top:12px}

.svm-nav__right{display:flex;justify-content:flex-end;align-items:center;gap:22px}
.svm-nav__right .svm-tel{color:var(--svm-cream)}
/* 44px tap target on the header phone link. Same padding-plus-negative-
   margin technique as the nav links, see the comment above. */
.svm-nav__right .svm-tel{padding:15px 0;margin:-15px 0}

.svm-menu-btn{display:none;width:44px;height:44px;border:0;background:transparent;cursor:pointer;position:relative;margin-left:auto}
.svm-menu-btn i{position:absolute;left:11px;right:11px;height:2px;background:var(--svm-cream);border-radius:2px;transition:transform .3s var(--ease-out),opacity .2s}
.svm-menu-btn i:nth-child(1){top:14px}
.svm-menu-btn i:nth-child(2){top:21px}
.svm-menu-btn i:nth-child(3){top:28px}
body.svm-menu-open .svm-menu-btn i:nth-child(1){transform:translateY(7px) rotate(45deg)}
body.svm-menu-open .svm-menu-btn i:nth-child(2){opacity:0}
body.svm-menu-open .svm-menu-btn i:nth-child(3){transform:translateY(-7px) rotate(-45deg)}

.svm-menu{
  position:fixed;inset:0;z-index:19;background:var(--svm-navy);color:var(--svm-cream);
  padding:96px var(--gutter) max(32px,env(safe-area-inset-bottom));display:flex;flex-direction:column;gap:8px;
  overflow-y:auto;overscroll-behavior:contain;-webkit-overflow-scrolling:touch;
  transform:translateY(-8px);opacity:0;pointer-events:none;
  transition:opacity var(--dur-med) var(--ease-out),transform var(--dur-med) var(--ease-out);
}
body.svm-menu-open .svm-menu{opacity:1;transform:none;pointer-events:auto}
body.svm-menu-open{overflow:hidden}
.svm-menu__link{font-family:var(--f-display);font-weight:600;font-size:34px;letter-spacing:var(--ls-head);color:var(--svm-cream);text-decoration:none;padding:14px 0;border-bottom:1px solid rgba(var(--svm-teal-rgb),.25)}
.svm-menu__foot{margin-top:auto;padding-top:24px;display:flex;flex-direction:column;gap:14px}
/* -- Services as an accordion inside the full-screen menu ------------- */
.svm-menu__group{display:flex;flex-direction:column}
.svm-menu__acc{
  appearance:none;-webkit-appearance:none;background:none;border:0;border-bottom:1px solid rgba(var(--svm-teal-rgb),.25);
  cursor:pointer;text-align:left;width:100%;
  display:flex;align-items:center;justify-content:space-between;gap:16px;
}
/* the plus. Two 2px bars; the upright one folds away and the pair turns 45
   degrees, so the plus becomes an x with no second icon. */
.svm-menu__plus{position:relative;width:22px;height:22px;flex:none;transition:transform var(--dur-med) var(--ease-out)}
.svm-menu__plus::before,
.svm-menu__plus::after{content:"";position:absolute;left:0;right:0;top:10px;height:2px;border-radius:2px;background:var(--svm-teal);transition:transform var(--dur-med) var(--ease-out)}
.svm-menu__plus::after{transform:rotate(90deg)}
.svm-menu__acc[aria-expanded="true"] .svm-menu__plus{transform:rotate(45deg)}
.svm-menu__sub{
  display:grid;grid-template-rows:0fr;
  transition:grid-template-rows var(--dur-med) var(--ease-out);
}
/* two columns, so thirteen services are seven rows instead of thirteen. */
.svm-menu__sub > div{overflow:hidden;display:grid;grid-template-columns:1fr 1fr;column-gap:16px;padding:0 0 0 22px}
.svm-menu__acc[aria-expanded="true"] + .svm-menu__sub > div{padding:12px 0 18px 22px}
.svm-menu__acc[aria-expanded="true"] + .svm-menu__sub{grid-template-rows:1fr}
.svm-menu__sub a{
  font-size:18px;font-weight:500;color:var(--svm-cream);text-decoration:none;opacity:.85;
  padding:10px 0;min-width:0;
}
.svm-menu__sub a:hover{opacity:1;color:var(--teal)}


.svm-menu__foot .svm-tel--display{color:var(--svm-cream)}
.svm-menu .svm-btn--primary{width:100%;justify-content:center}


/* --------------------------------------------------------------------------
   8. HERO
   Type left, the seahorse contour bleeding off the top right.
   -------------------------------------------------------------------------- */
.svm-hero{
  position:relative;overflow:hidden;margin-top:calc(var(--nav-h) * -1);
  background-color:var(--svm-teal-light);
  background-image:
    var(--grain-navy),
    radial-gradient(120% 90% at 85% 10%, rgba(var(--svm-teal-rgb),.55) 0%, rgba(var(--svm-teal-rgb),0) 60%),
    radial-gradient(80% 70% at 0% 100%, rgba(var(--svm-white-rgb),.7) 0%, rgba(var(--svm-white-rgb),0) 55%);
  background-repeat:repeat,no-repeat,no-repeat;
  background-size:var(--grain-size) var(--grain-size),auto,auto;
}
/* the coral tile at 9% */
.svm-hero::before{
  content:"";position:absolute;inset:0;pointer-events:none;z-index:0;opacity:.09;
  background-image:var(--pattern-coral);background-repeat:repeat;
  background-size:var(--pattern-size) var(--pattern-size);background-position:0 0;
}
.svm-hero > .svm-wrap{
  position:relative;z-index:2;max-width:var(--max);
  padding-top:calc(clamp(40px,5vw,72px) + var(--nav-h));
  padding-bottom:clamp(40px,5vw,72px);
}
.svm-hero__copy{position:relative;z-index:2}
.svm-hero__copy > *{animation:svm-rise var(--dur-slow) var(--ease-out) both}
.svm-hero__copy > *:nth-child(2){animation-delay:.08s}
.svm-hero__copy > *:nth-child(3){animation-delay:.16s}
@keyframes svm-rise{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}
.svm-hero .svm-display{max-width:11ch;margin-bottom:28px}
.svm-hero .svm-lead{margin-bottom:36px}

/* the seahorse contour. Once per page.
   The float and the bubbles below are the ONLY looping motion on the site.
   Both stop under prefers-reduced-motion. Nothing else loops. */
.svm-seahorse{
  position:absolute;z-index:1;right:-98px;top:92px;height:108%;width:auto;pointer-events:none;
  -webkit-mask-image:var(--seahorse-mask);
  mask-image:var(--seahorse-mask);
  transform-origin:50% 60%;
  animation:svm-float 6.2s ease-in-out infinite;
}
/* the bob. 0 to -14px with a 0.6deg roll about a point low on the body, so the
   contour rocks like something floating rather than sliding up and down.
   Jamie, 2026-09-01. Off under prefers-reduced-motion, like the bubbles. */
@keyframes svm-float{
  0%,100%{transform:translateY(0) rotate(-0.6deg)}
  50%{transform:translateY(-14px) rotate(0.6deg)}
}

/* -- the bubbles ------------------------------------------------------- */
/* Six circles rising on the seahorse side of the hero. CSS only, no canvas
   and no script. Three sit behind the seahorse, three in front of it. Each one
   rises the full height of the hero, drifts sideways and fades out near the
   top. cqh is the hero's own height, so nothing here carries a magic number.
   Gone under 600px and under reduced motion. */
.svm-bubbles{
  position:absolute;top:0;bottom:0;right:0;width:min(48%,560px);
  overflow:hidden;pointer-events:none;
  container-type:size;
}
.svm-bubbles--back{z-index:0}
.svm-bubbles--front{z-index:1}
.svm-bubbles i{
  position:absolute;bottom:-20px;border-radius:50%;
  /* No border and no fill. The body is two radial gradients: a specular
     highlight about a fifth of the diameter at 30% 30%, and a rim that goes
     from clear to 55% white over the last quarter of the radius. closest-side
     ties both to the circle itself, so one rule covers every size. The inset
     glow lifts the inside edge so the shape reads as glass, not as a ring. */
  background:
    radial-gradient(circle closest-side at 30% 30%,
      rgba(var(--svm-white-rgb),.9) 0%,
      rgba(var(--svm-white-rgb),.5) 20%,
      rgba(var(--svm-white-rgb),0) 34%),
    radial-gradient(circle closest-side at 50% 50%,
      rgba(var(--svm-white-rgb),0) 75%,
      rgba(var(--svm-white-rgb),.55) 100%);
  /* the inset glow lifts the inside edge, and the whisper of a drop shadow is
     what stops a white rim from vanishing on the pale half of the hero. It is
     too soft to read as an outline, which is what the old ring did. */
  box-shadow:inset 0 0 6px rgba(var(--svm-white-rgb),.5),0 1px 3px rgba(var(--svm-navy-rgb),.1);
  opacity:0;
  /* two animations on two different properties, so they compose instead of
     fighting: the rise writes transform, the sway writes translate. */
  animation:svm-bubble 13s linear infinite,svm-bubble-sway 5s ease-in-out infinite;
}
@keyframes svm-bubble{
  0%{transform:translate(0,0);opacity:0}
  9%{opacity:var(--op,.65)}
  50%{transform:translate(var(--dx,10px),calc(-50cqh - 10px))}
  82%{opacity:var(--op,.65)}
  100%{transform:translate(0,calc(-100cqh - 20px));opacity:0}
}
/* the wobble. A few gentle cycles per rise, never enough to read as a path. */
@keyframes svm-bubble-sway{
  0%,100%{translate:0 0}
  25%{translate:var(--sw,8px) 0}
  75%{translate:calc(var(--sw,8px) * -1) 0}
}
/* three behind the contour, three in front of it. The contour covers most of
   this strip, so the back three read as bubbles passing behind the seahorse
   and the front three carry the visible layer. Sizes run 10px to 26px and the
   peak opacity runs .5 to .8, so the big ones carry and the small ones hint. */
.svm-bubbles--back i:nth-child(1){left:10%;width:22px;height:22px;--dx:14px;--sw:8px;--op:.62;animation-duration:14s,5.2s;animation-delay:0s,.4s}
.svm-bubbles--back i:nth-child(2){left:44%;width:13px;height:13px;--dx:-11px;--sw:6px;--op:.5;animation-duration:11s,4.4s;animation-delay:2.4s,1.1s}
.svm-bubbles--back i:nth-child(3){left:76%;width:26px;height:26px;--dx:9px;--sw:10px;--op:.7;animation-duration:16s,6.1s;animation-delay:5.1s,2.2s}
.svm-bubbles--front i:nth-child(1){left:22%;width:16px;height:16px;--dx:12px;--sw:7px;--op:.58;animation-duration:9s,4.8s;animation-delay:1.3s,.7s}
.svm-bubbles--front i:nth-child(2){left:58%;width:20px;height:20px;--dx:-9px;--sw:9px;--op:.8;animation-duration:15s,5.6s;animation-delay:5.8s,1.8s}
.svm-bubbles--front i:nth-child(3){left:88%;width:10px;height:10px;--dx:-13px;--sw:6px;--op:.5;animation-duration:12s,4.1s;animation-delay:9.4s,3.3s}
.svm-seahorse svg{height:100%;width:auto;overflow:visible}
.svm-seahorse svg *{
  fill:var(--seahorse-fill)!important;fill-opacity:var(--seahorse-alpha);
  stroke:var(--seahorse-edge);stroke-width:1px;vector-effect:non-scaling-stroke;
  stroke-opacity:.5;stroke-linejoin:round;
}

/* latest post tile, bottom right of the hero, aligned to the button row */
.svm-hero__widget{
  position:absolute;right:var(--gutter);bottom:clamp(40px,5vw,72px);z-index:3;width:300px;
  background:var(--card);border-radius:var(--r-sm);padding:18px 20px;text-decoration:none;color:var(--ink);
  box-shadow:0 0 0 1px rgba(var(--svm-navy-rgb),.08);
  display:flex;flex-direction:column;gap:8px;
  transition:transform var(--dur-med) var(--ease-out),box-shadow var(--dur-med) var(--ease-out);
  animation:svm-rise var(--dur-slow) var(--ease-out) .32s both;
}
.svm-hero__widget:hover{transform:translateY(-3px);box-shadow:0 0 0 1px rgba(var(--svm-navy-rgb),.08),0 14px 30px -18px rgba(var(--svm-navy-rgb),.45)}
.svm-hero__widget-label{font-family:var(--f-mono);font-size:10px;letter-spacing:var(--ls-mono);text-transform:uppercase;font-weight:600;color:var(--muted);display:flex;align-items:center;gap:10px}
/* the New chip. Coral ground, white text. Small UI is the accent's job. */
.svm-hero__widget-label b{font-family:var(--f-mono);font-size:9px;letter-spacing:1.5px;text-transform:uppercase;font-weight:700;color:var(--svm-white);background:var(--svm-coral);padding:3px 7px;border-radius:2px}
.svm-hero__widget h2{font-family:var(--f-display);font-weight:600;font-size:18px;line-height:1.25;letter-spacing:var(--ls-tight);margin:0}
.svm-hero__widget .svm-more{margin-top:2px}
.svm-hero__widget:hover .svm-more{color:var(--svm-teal-deep)}


/* --------------------------------------------------------------------------
   9. CERTIFICATION BAR
   -------------------------------------------------------------------------- */
.svm-certs > .svm-wrap{padding-top:clamp(18px,2.5vw,28px);padding-bottom:clamp(18px,2.5vw,28px)}
.svm-cert-bar{display:grid;grid-template-columns:auto 1fr;align-items:center;gap:var(--sp-7)}
.svm-cert-bar .svm-mono{color:var(--muted)}
.svm-cert-logos{display:flex;gap:28px;justify-content:flex-end;align-items:center;flex-wrap:wrap}
.svm-cert-logos a{display:block;line-height:0;transition:transform var(--dur-med) var(--ease-out)}
.svm-cert-logos a:hover{transform:translateY(-3px)}
.svm-cert-logos img{height:84px;width:auto}
/* svm.js clones the row once for the phone marquee; the clones stay hidden above 640px. */
.svm-cert-logos .svm-cert-clone{display:none}


/* --------------------------------------------------------------------------
   10. SERVICES RAIL
   Six cards, six CSS mockups. No images, no icon library.
   -------------------------------------------------------------------------- */
.svm-rail-sec{position:relative}
.svm-rail-wrap{position:relative}
.svm-rail{
  --svc-w:300px;--svc-w-hover:390px;
  display:flex;gap:20px;overflow-x:auto;scroll-snap-type:x proximity;scrollbar-width:none;
  padding-top:12px;padding-bottom:20px;
  padding-left:var(--rail-pad);padding-right:var(--rail-pad);
}
.svm-rail::-webkit-scrollbar{display:none}

.svm-svc{
  flex:0 0 var(--svc-w);scroll-snap-align:start;background:var(--card);border-radius:var(--r-sm);
  overflow:hidden;box-shadow:0 0 0 1px rgba(var(--svm-navy-rgb),.1);
  text-decoration:none;color:var(--ink);display:flex;flex-direction:column;
  transition:flex-basis .5s var(--ease-out),transform var(--dur-card) var(--ease-out);
}
.svm-svc:hover{flex-basis:var(--svc-w-hover);transform:translateY(-4px);transition-delay:.09s}
/* the text column never reflows: it holds the base card width while the card grows */
.svm-svc__body{padding:20px 22px 22px;display:flex;flex-direction:column;gap:8px;flex:1;width:var(--svc-w);max-width:var(--svc-w)}
.svm-svc__body h3{font-family:var(--f-display);font-weight:600;font-size:21px;letter-spacing:var(--ls-tight);margin:0;line-height:1.15}
.svm-svc__body p{margin:0;font-size:14px;line-height:1.5;color:var(--muted);max-width:32ch}
.svm-svc .svm-more{margin-top:auto;padding-top:10px}

/* hover-to-scroll strips at each end of the row. No arrow, no fill. */
.svm-edge{position:absolute;top:0;bottom:20px;width:72px;z-index:3;cursor:default;opacity:0}
.svm-edge--l{left:0;width:var(--rail-pad)}
.svm-edge--r{right:0;width:var(--rail-pad)}

/* the paging arrows, in the section header */
.svm-rail-ctl{display:flex;gap:10px;align-items:center}
.svm-rail-ctl button{
  flex:0 0 44px;width:44px;height:44px;border-radius:50%;border:1px solid var(--ink);
  background:transparent;color:var(--ink);font-size:18px;cursor:pointer;display:grid;place-items:center;
  transition:background .2s,color .2s;
}
.svm-rail-ctl button:hover{background:var(--svm-teal);border-color:var(--svm-teal);color:var(--svm-navy)}
.svm-rail-ctl button[disabled]{opacity:.35;cursor:default;background:transparent;color:var(--ink);border-color:var(--ink)}

/* -- the mockup panel -------------------------------------------------- */
.svm-mock{height:200px;position:relative;overflow:hidden;background:var(--svm-teal-light)}
.svm-mock::before{
  content:"";position:absolute;inset:0;z-index:0;pointer-events:none;opacity:.10;
  background-image:var(--pattern-coral);background-repeat:repeat;background-size:520px 520px;
}
.svm-mock *{position:absolute;transition:transform var(--dur-mock) var(--ease-out),opacity .45s var(--ease-out),width var(--dur-mock) var(--ease-out),background .3s}
.svm-mock > *{z-index:1}
.svm-mock__bar{height:6px;border-radius:3px;background:rgba(var(--svm-navy-rgb),.22)}

/* -- websites ---------------------------------------------------------- */
.svm-mock--web .svm-win{left:12%;top:15px;width:76%;height:170px;background:var(--svm-white);border-radius:6px;box-shadow:0 0 0 1px rgba(var(--svm-navy-rgb),.12)}
.svm-mock--web .svm-win-top{left:0;top:0;width:100%;height:18px;background:rgba(var(--svm-navy-rgb),.06);border-radius:6px 6px 0 0}
.svm-mock--web .svm-dot{top:6px;width:6px;height:6px;border-radius:50%;background:rgba(var(--svm-navy-rgb),.3)}
.svm-mock--web .svm-dot--1{left:8px}
.svm-mock--web .svm-dot--2{left:18px}
.svm-mock--web .svm-dot--3{left:28px}
.svm-mock--web .svm-hl{left:14px;top:32px;width:40%;height:9px;background:var(--svm-navy);border-radius:3px}
.svm-mock--web .svm-hl2{left:14px;top:47px;width:30%;height:6px;background:rgba(var(--svm-navy-rgb),.25);border-radius:3px}
/* one coral element per mockup, and only in five of them. The accent is what
   stops the rail reading as an all teal block. Jamie, 2026-09-01. */
.svm-mock--web .svm-cta{left:14px;top:62px;width:44px;height:14px;background:var(--svm-coral);border-radius:3px}
.svm-mock--web .svm-img{right:14px;top:30px;width:30%;height:46px;background:linear-gradient(135deg,var(--svm-navy),var(--svm-teal));border-radius:3px}
.svm-mock--web .svm-g{top:92px;width:26%;height:52px;background:var(--svm-teal-light);border-radius:3px;opacity:.6;transform:translateY(8px)}
.svm-mock--web .svm-g--1{left:14px}
.svm-mock--web .svm-g--2{left:37%}
.svm-mock--web .svm-g--3{right:14px}
:is(:is(.svm-svc:hover,.svm-svc.is-active) .svm-mock--web,.svm-mock--web.is-active) .svm-win{transform:translateY(-10px) rotate(-1.5deg)}
:is(:is(.svm-svc:hover,.svm-svc.is-active) .svm-mock--web,.svm-mock--web.is-active) .svm-g{transform:translateY(0);opacity:1}
:is(:is(.svm-svc:hover,.svm-svc.is-active) .svm-mock--web,.svm-mock--web.is-active) .svm-cta{width:64px}

/* -- paid ads ---------------------------------------------------------- */
.svm-mock--ads .svm-card2{left:12%;top:25px;width:76%;height:150px;background:var(--svm-white);border-radius:6px;box-shadow:0 0 0 1px rgba(var(--svm-navy-rgb),.12)}
.svm-mock--ads .svm-sp{left:14px;top:12px;font-family:var(--f-mono);font-size:8px;letter-spacing:1.5px;text-transform:uppercase;font-weight:600;color:var(--svm-navy);padding:3px 6px;border-radius:2px;background:var(--svm-teal-light)}
.svm-mock--ads .svm-t{left:14px;top:38px;width:62%;height:9px;background:var(--svm-navy);border-radius:3px}
.svm-mock--ads .svm-l1{left:14px;top:55px;width:80%}
.svm-mock--ads .svm-l2{left:14px;top:67px;width:64%}
.svm-mock--ads .svm-ctab{left:14px;top:92px;width:70px;height:20px;background:var(--svm-teal);border-radius:3px}
/* .svm-ring is the cursor: an arrow pointer that slides onto the button and clicks it. */
.svm-mock--ads .svm-ring{left:72px;top:98px;width:16px;height:16px;opacity:0;background:var(--svm-coral);transform:translate(22px,18px);-webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M4.037 4.688a.495.495 0 0 1 .651-.651l16 6.5a.5.5 0 0 1-.063.947l-6.124 1.58a2 2 0 0 0-1.438 1.435l-1.579 6.126a.5.5 0 0 1-.947.063z'/%3E%3C/svg%3E") center/contain no-repeat;mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M4.037 4.688a.495.495 0 0 1 .651-.651l16 6.5a.5.5 0 0 1-.063.947l-6.124 1.58a2 2 0 0 0-1.438 1.435l-1.579 6.126a.5.5 0 0 1-.947.063z'/%3E%3C/svg%3E") center/contain no-repeat;filter:drop-shadow(0 1px 1px rgba(var(--svm-navy-rgb),.25))}
.svm-mock--ads .svm-badge{right:-6px;top:118px;background:var(--svm-navy);color:var(--svm-cream);font-family:var(--f-mono);font-size:9px;letter-spacing:1.5px;text-transform:uppercase;font-weight:600;padding:6px 10px;border-radius:3px;transform:translateY(24px);opacity:0}
:is(:is(.svm-svc:hover,.svm-svc.is-active) .svm-mock--ads,.svm-mock--ads.is-active) .svm-ring{animation:svm-click .9s var(--ease-out) forwards}
:is(:is(.svm-svc:hover,.svm-svc.is-active) .svm-mock--ads,.svm-mock--ads.is-active) .svm-ctab{animation:svm-press .9s var(--ease-out) forwards}
@keyframes svm-click{0%{opacity:0;transform:translate(22px,18px)}40%{opacity:1;transform:translate(0,0) scale(1)}55%{transform:translate(0,0) scale(.78)}70%{transform:translate(0,0) scale(1)}100%{opacity:1;transform:translate(0,0)}}
@keyframes svm-press{0%,45%{filter:brightness(1);transform:scale(1)}55%{filter:brightness(.82);transform:scale(.96)}70%,100%{filter:brightness(1);transform:scale(1)}}
:is(:is(.svm-svc:hover,.svm-svc.is-active) .svm-mock--ads,.svm-mock--ads.is-active) .svm-badge{transform:translateY(0) translateX(-16px);opacity:1}
:is(:is(.svm-svc:hover,.svm-svc.is-active) .svm-mock--ads,.svm-mock--ads.is-active) .svm-card2{transform:translateY(-6px)}

/* -- seo --------------------------------------------------------------- */
.svm-mock--seo .svm-q{left:10%;top:18px;width:80%;height:32px;background:var(--svm-white);border-radius:16px;box-shadow:0 0 0 1px rgba(var(--svm-navy-rgb),.12)}
.svm-mock--seo .svm-mag{left:12px;top:10px;width:9px;height:9px;border:2px solid var(--svm-navy);border-radius:50%}
.svm-mock--seo .svm-mag::after{content:"";position:absolute;width:2px;height:6px;background:var(--svm-navy);right:-4px;bottom:-5px;transform:rotate(-45deg);border-radius:1px}
.svm-mock--seo .svm-qt{left:32px;top:9px;font-family:var(--f-mono);font-size:9px;letter-spacing:.6px;text-transform:uppercase;font-weight:600;color:var(--svm-navy);white-space:nowrap}
.svm-mock--seo .svm-r{left:10%;width:80%;height:36px;background:var(--svm-white);border-radius:var(--r-sm);box-shadow:0 0 0 1px rgba(var(--svm-navy-rgb),.08)}
.svm-mock--seo .svm-r .svm-fav{left:10px;top:11px;width:12px;height:12px;border-radius:50%;background:var(--svm-teal-light);box-shadow:0 0 0 1px rgba(var(--svm-navy-rgb),.15)}
.svm-mock--seo .svm-r .svm-t{left:30px;top:9px;width:50%;height:7px;background:var(--svm-navy);opacity:.7;border-radius:3px}
.svm-mock--seo .svm-r .svm-u{left:30px;top:22px;width:36%;height:4px;background:rgba(var(--svm-navy-rgb),.25);border-radius:2px}
.svm-mock--seo .svm-r1{top:64px}
.svm-mock--seo .svm-r2{top:108px}
.svm-mock--seo .svm-r3{top:152px}
.svm-mock--seo .svm-r1 .svm-fav{background:var(--svm-teal)}
.svm-mock--seo .svm-r1 .svm-t{opacity:1}
.svm-mock--seo .svm-rank{right:10px;top:9px;height:18px;padding:0 7px;border-radius:9px;background:var(--svm-coral);color:var(--svm-white);font-family:var(--f-mono);font-size:9px;letter-spacing:1px;font-weight:700;display:grid;place-items:center;transform:scale(0)}
:is(:is(.svm-svc:hover,.svm-svc.is-active) .svm-mock--seo,.svm-mock--seo.is-active) .svm-r1{transform:translateY(-6px) scale(1.04)}
:is(:is(.svm-svc:hover,.svm-svc.is-active) .svm-mock--seo,.svm-mock--seo.is-active) .svm-r2,
:is(:is(.svm-svc:hover,.svm-svc.is-active) .svm-mock--seo,.svm-mock--seo.is-active) .svm-r3{transform:translateY(8px);opacity:.6}
:is(:is(.svm-svc:hover,.svm-svc.is-active) .svm-mock--seo,.svm-mock--seo.is-active) .svm-rank{transform:scale(1)}
:is(:is(.svm-svc:hover,.svm-svc.is-active) .svm-mock--seo,.svm-mock--seo.is-active) .svm-mag{transform:scale(1.15)}

/* -- social ------------------------------------------------------------ */
.svm-mock--social .svm-ph{left:50%;top:26px;width:108px;height:200px;margin-left:-54px;background:var(--svm-white);border-radius:14px;box-shadow:0 0 0 1px rgba(var(--svm-navy-rgb),.12)}
.svm-mock--social .svm-av{left:12px;top:14px;width:16px;height:16px;border-radius:50%;background:var(--svm-teal)}
.svm-mock--social .svm-nm{left:34px;top:16px;width:40px;height:6px}
.svm-mock--social .svm-nm2{left:34px;top:25px;width:28px;height:4px}
.svm-mock--social .svm-pic{left:0;top:42px;width:100%;height:78px;background:linear-gradient(135deg,var(--svm-navy),var(--svm-teal))}
.svm-mock--social .svm-act{left:12px;top:132px;width:60px;height:6px}
.svm-mock--social .svm-fl{font-size:14px;color:var(--svm-teal);opacity:0;transform:translateY(20px);width:14px;height:14px}
.svm-mock--social .svm-f1{left:18%;top:58%}
.svm-mock--social .svm-f2{left:72%;top:64%;font-size:11px}
.svm-mock--social .svm-f3{left:78%;top:36%}
.svm-mock--social .svm-f4{left:12%;top:30%;font-size:10px}
.svm-mock--social .svm-f5{left:22%;top:78%}
.svm-mock--social .svm-hb{position:absolute;left:1px;top:3px;width:10px;height:10px;background:var(--svm-teal);transform:rotate(45deg)}
.svm-mock--social .svm-hb::before,
.svm-mock--social .svm-hb::after{content:"";position:absolute;width:10px;height:10px;border-radius:50%;background:var(--svm-teal)}
.svm-mock--social .svm-hb::before{left:-5px;top:0}
.svm-mock--social .svm-hb::after{left:0;top:-5px}
/* the first heart only. f2 is a sparkle glyph and f3 stays navy. */
.svm-mock--social .svm-f1 .svm-hb,
.svm-mock--social .svm-f1 .svm-hb::before,
.svm-mock--social .svm-f1 .svm-hb::after{background:var(--svm-coral)}
.svm-mock--social .svm-f3 .svm-hb{width:14px;height:14px;background:var(--svm-navy)}
.svm-mock--social .svm-f3 .svm-hb::before,
.svm-mock--social .svm-f3 .svm-hb::after{width:14px;height:14px;background:var(--svm-navy)}
.svm-mock--social .svm-f3 .svm-hb::before{left:-7px}
.svm-mock--social .svm-f3 .svm-hb::after{top:-7px}
:is(:is(.svm-svc:hover,.svm-svc.is-active) .svm-mock--social,.svm-mock--social.is-active) .svm-ph{transform:translateY(-8px) rotate(2deg)}
:is(:is(.svm-svc:hover,.svm-svc.is-active) .svm-mock--social,.svm-mock--social.is-active) .svm-fl{opacity:1;transform:translateY(-14px)}
:is(:is(.svm-svc:hover,.svm-svc.is-active) .svm-mock--social,.svm-mock--social.is-active) .svm-f2{transition-delay:.08s}
:is(:is(.svm-svc:hover,.svm-svc.is-active) .svm-mock--social,.svm-mock--social.is-active) .svm-f3{transition-delay:.15s}
:is(:is(.svm-svc:hover,.svm-svc.is-active) .svm-mock--social,.svm-mock--social.is-active) .svm-f4{transition-delay:.22s}
:is(:is(.svm-svc:hover,.svm-svc.is-active) .svm-mock--social,.svm-mock--social.is-active) .svm-f5{transition-delay:.3s}

/* -- logo design ------------------------------------------------------- */
.svm-mock--logo .svm-cv{left:50%;top:22px;width:130px;height:130px;margin-left:-65px;background:var(--svm-white);border-radius:6px;box-shadow:0 0 0 1px rgba(var(--svm-navy-rgb),.12)}
.svm-mock--logo .svm-circ{left:50%;top:50%;width:92px;height:92px;margin:-46px 0 0 -46px;border-radius:50%;border:1px solid var(--svm-teal);transform:scale(.85);opacity:.6}
.svm-mock--logo .svm-vh{left:50%;top:10px;bottom:10px;width:1px;background:var(--svm-teal);opacity:.5}
.svm-mock--logo .svm-hz{top:50%;left:10px;right:10px;height:1px;background:var(--svm-teal);opacity:.5}
.svm-mock--logo .svm-mk{left:50%;top:50%;width:34px;height:auto;margin-left:-17px;transform:translateY(-50%)}
.svm-mock--logo .svm-mk *{fill:var(--svm-navy)!important;position:static}
.svm-mock--logo .svm-sw{top:166px;width:18px;height:18px;border-radius:50%;left:50%;margin-left:-9px}
.svm-mock--logo .svm-s1{background:var(--svm-navy)}
.svm-mock--logo .svm-s2{background:var(--svm-teal)}
.svm-mock--logo .svm-s3{background:var(--svm-coral);box-shadow:none}
:is(:is(.svm-svc:hover,.svm-svc.is-active) .svm-mock--logo,.svm-mock--logo.is-active) .svm-circ{transform:scale(1) rotate(90deg);opacity:1}
:is(:is(.svm-svc:hover,.svm-svc.is-active) .svm-mock--logo,.svm-mock--logo.is-active) .svm-s1{transform:translateX(-30px)}
:is(:is(.svm-svc:hover,.svm-svc.is-active) .svm-mock--logo,.svm-mock--logo.is-active) .svm-s3{transform:translateX(30px)}
:is(:is(.svm-svc:hover,.svm-svc.is-active) .svm-mock--logo,.svm-mock--logo.is-active) .svm-mk{transform:translateY(-50%) scale(1.12)}

/* -- video ------------------------------------------------------------- */
.svm-mock--video .svm-fr{left:10%;top:30px;width:80%;height:120px;background:var(--svm-navy);border-radius:6px;overflow:hidden}
.svm-mock--video .svm-sheen{left:-40%;top:0;width:60%;height:100%;background:linear-gradient(100deg,transparent,rgba(var(--svm-teal-rgb),.35),transparent);transform:translateX(0)}
.svm-mock--video .svm-play{left:50%;top:50%;width:0;height:0;margin:-12px 0 0 -8px;border-left:22px solid var(--svm-cream);border-top:12px solid transparent;border-bottom:12px solid transparent}
.svm-mock--video .svm-sb{left:10%;top:164px;width:80%;height:4px;background:rgba(var(--svm-navy-rgb),.2);border-radius:2px}
.svm-mock--video .svm-pg{left:0;top:0;height:100%;width:18%;background:var(--svm-teal);border-radius:2px}
.svm-mock--video .svm-pg::after{content:"";position:absolute;right:-3px;top:-2px;width:8px;height:8px;border-radius:50%;background:var(--svm-coral)}
.svm-mock--video .svm-tm{left:10%;top:176px;width:26px;height:5px}
:is(:is(.svm-svc:hover,.svm-svc.is-active) .svm-mock--video,.svm-mock--video.is-active) .svm-pg{width:72%}
:is(:is(.svm-svc:hover,.svm-svc.is-active) .svm-mock--video,.svm-mock--video.is-active) .svm-play{transform:scale(1.25)}
:is(:is(.svm-svc:hover,.svm-svc.is-active) .svm-mock--video,.svm-mock--video.is-active) .svm-sheen{transform:translateX(240%)}
:is(:is(.svm-svc:hover,.svm-svc.is-active) .svm-mock--video,.svm-mock--video.is-active) .svm-fr{transform:scale(1.03)}


/* mock 7: content and copy writing. A page types itself. -------------- */
.svm-mock--copy .svm-doc{left:13%;top:16px;width:74%;height:168px;background:var(--svm-white);border-radius:6px;box-shadow:0 0 0 1px rgba(var(--svm-navy-rgb),.12)}
.svm-mock--copy .svm-tbar{left:0;top:0;width:100%;height:24px;background:var(--svm-navy);border-radius:6px 6px 0 0}
.svm-mock--copy .svm-ln{left:16px;height:7px;border-radius:3px;background:rgba(var(--svm-navy-rgb),.22);width:0}
.svm-mock--copy .svm-ln--1{top:46px}
.svm-mock--copy .svm-ln--2{top:66px}
.svm-mock--copy .svm-ln--hl{top:86px;background:var(--svm-teal)}
.svm-mock--copy .svm-ln--3{top:106px}
.svm-mock--copy .svm-ln--4{top:126px}
.svm-mock--copy .svm-cur{right:-6px;top:-4px;width:2px;height:15px;background:var(--svm-navy);border-radius:1px}
:is(:is(.svm-svc:hover,.svm-svc.is-active) .svm-mock--copy,.svm-mock--copy.is-active) .svm-ln--1{width:74%}
:is(:is(.svm-svc:hover,.svm-svc.is-active) .svm-mock--copy,.svm-mock--copy.is-active) .svm-ln--2{width:62%;transition-delay:.1s}
:is(:is(.svm-svc:hover,.svm-svc.is-active) .svm-mock--copy,.svm-mock--copy.is-active) .svm-ln--hl{width:80%;transition-delay:.2s}
:is(:is(.svm-svc:hover,.svm-svc.is-active) .svm-mock--copy,.svm-mock--copy.is-active) .svm-ln--3{width:68%;transition-delay:.3s}
:is(:is(.svm-svc:hover,.svm-svc.is-active) .svm-mock--copy,.svm-mock--copy.is-active) .svm-ln--4{width:46%;transition-delay:.4s}
/* two blinks, then the cursor rests visible. Never a loop. */
:is(:is(.svm-svc:hover,.svm-svc.is-active) .svm-mock--copy,.svm-mock--copy.is-active) .svm-cur{animation:svm-blink .5s steps(1,end) .95s 2 both}
@keyframes svm-blink{0%{opacity:1}50%{opacity:0}100%{opacity:1}}

/* mock 8: strategy and consulting. Bars grow, the trend line draws. ---- */
.svm-mock--strategy .svm-dash{left:12%;top:20px;width:76%;height:160px;background:var(--svm-white);border-radius:6px;box-shadow:0 0 0 1px rgba(var(--svm-navy-rgb),.12)}
.svm-mock--strategy .svm-chip{right:12px;top:12px;font-family:var(--f-mono);font-size:8px;letter-spacing:1.5px;text-transform:uppercase;font-weight:700;color:var(--svm-cream);background:var(--svm-navy);padding:4px 8px;border-radius:2px}
.svm-mock--strategy .svm-line{left:14px;top:38px;width:calc(100% - 28px);height:48px;overflow:visible}
.svm-mock--strategy .svm-line polyline{position:static;fill:none;stroke:var(--svm-teal-ink);stroke-width:2.2;stroke-linecap:round;stroke-linejoin:round;vector-effect:non-scaling-stroke;stroke-dasharray:220;stroke-dashoffset:220;transition:stroke-dashoffset .8s var(--ease-out)}
.svm-mock--strategy .svm-base{left:14px;right:14px;bottom:22px;width:auto;height:1px;background:rgba(var(--svm-navy-rgb),.18)}
.svm-mock--strategy .svm-bar{bottom:23px;width:18%;border-radius:3px 3px 0 0;transform:scaleY(.06);transform-origin:bottom center}
.svm-mock--strategy .svm-bar--1{left:18%;height:34px;background:var(--svm-navy)}
.svm-mock--strategy .svm-bar--2{left:41%;height:56px;background:var(--svm-teal)}
.svm-mock--strategy .svm-bar--3{left:64%;height:80px;background:var(--svm-teal-light);box-shadow:inset 0 0 0 1px rgba(var(--svm-navy-rgb),.14)}
:is(:is(.svm-svc:hover,.svm-svc.is-active) .svm-mock--strategy,.svm-mock--strategy.is-active) .svm-bar{transform:none}
:is(:is(.svm-svc:hover,.svm-svc.is-active) .svm-mock--strategy,.svm-mock--strategy.is-active) .svm-bar--2{transition-delay:.09s}
:is(:is(.svm-svc:hover,.svm-svc.is-active) .svm-mock--strategy,.svm-mock--strategy.is-active) .svm-bar--3{transition-delay:.18s}
:is(:is(.svm-svc:hover,.svm-svc.is-active) .svm-mock--strategy,.svm-mock--strategy.is-active) .svm-line polyline{stroke-dashoffset:0;transition-delay:.24s}

/* mock 9: government services. A checklist clears, then a stamp. ------- */
.svm-mock--gov .svm-doc2{left:13%;top:14px;width:70%;height:172px;background:var(--svm-white);border-radius:6px;box-shadow:0 0 0 1px rgba(var(--svm-navy-rgb),.12)}
.svm-mock--gov .svm-band{left:0;top:0;width:100%;height:26px;background:var(--svm-navy);border-radius:6px 6px 0 0}
.svm-mock--gov .svm-row{left:16px;right:16px;width:auto;height:14px}
.svm-mock--gov .svm-row--1{top:48px}
.svm-mock--gov .svm-row--2{top:76px}
.svm-mock--gov .svm-row--3{top:104px}
.svm-mock--gov .svm-row--4{top:132px}
.svm-mock--gov .svm-box{left:0;top:0;width:14px;height:14px;border-radius:3px;background:transparent;box-shadow:inset 0 0 0 1px rgba(var(--svm-navy-rgb),.38)}
.svm-mock--gov .svm-txt{left:24px;top:4px;right:0;width:auto;height:6px;border-radius:3px;background:rgba(var(--svm-navy-rgb),.22)}
.svm-mock--gov .svm-stamp{right:4px;bottom:16px;width:58px;height:58px;border-radius:50%;background:var(--svm-teal);color:var(--svm-navy);display:grid;place-items:center;text-align:center;font-family:var(--f-mono);font-size:8px;letter-spacing:1.2px;text-transform:uppercase;font-weight:700;opacity:0;transform:scale(1.4) rotate(-16deg)}
:is(:is(.svm-svc:hover,.svm-svc.is-active) .svm-mock--gov,.svm-mock--gov.is-active) .svm-box{background:var(--svm-teal);box-shadow:inset 0 0 0 1px var(--svm-teal)}
:is(:is(.svm-svc:hover,.svm-svc.is-active) .svm-mock--gov,.svm-mock--gov.is-active) .svm-row--2 .svm-box{transition-delay:.1s}
:is(:is(.svm-svc:hover,.svm-svc.is-active) .svm-mock--gov,.svm-mock--gov.is-active) .svm-row--3 .svm-box{transition-delay:.2s}
:is(:is(.svm-svc:hover,.svm-svc.is-active) .svm-mock--gov,.svm-mock--gov.is-active) .svm-row--4 .svm-box{transition-delay:.3s}
:is(:is(.svm-svc:hover,.svm-svc.is-active) .svm-mock--gov,.svm-mock--gov.is-active) .svm-stamp{opacity:1;transform:scale(1) rotate(-8deg);transition-delay:.4s}


/* mock 10: and more. Nine white tiles in a 3 by 3 grid, the last one teal
   with a navy plus. At rest the tiles sit fanned out from the center and
   dimmed. Active, they fan in to the grid 45ms apart and the plus turns 90
   degrees. The card it belongs to is the last card in the rail and it points
   at the services overview page. Jamie, 2026-09-01. */
.svm-mock--more .svm-tile{
  width:24%;height:44px;background:var(--svm-white);border-radius:var(--r-sm);
  box-shadow:0 0 0 1px rgba(var(--svm-navy-rgb),.12);opacity:.55;
}
.svm-mock--more .svm-ln{left:11px;top:19px;width:56%;height:6px;border-radius:3px;background:var(--svm-navy);opacity:.75}
.svm-mock--more .svm-c1{left:12%}
.svm-mock--more .svm-c2{left:38%}
.svm-mock--more .svm-c3{left:64%}
.svm-mock--more .svm-r1{top:22px}
.svm-mock--more .svm-r2{top:78px}
.svm-mock--more .svm-r3{top:134px}
/* the fan. Each tile pushes away from the center of the grid at rest. */
.svm-mock--more .svm-r1.svm-c1{transform:translate(-14px,-12px) rotate(-5deg)}
.svm-mock--more .svm-r1.svm-c2{transform:translateY(-16px)}
.svm-mock--more .svm-r1.svm-c3{transform:translate(14px,-12px) rotate(5deg)}
.svm-mock--more .svm-r2.svm-c1{transform:translateX(-18px) rotate(-3deg)}
.svm-mock--more .svm-r2.svm-c3{transform:translateX(18px) rotate(3deg)}
.svm-mock--more .svm-r3.svm-c1{transform:translate(-14px,12px) rotate(4deg)}
.svm-mock--more .svm-r3.svm-c2{transform:translateY(16px)}
.svm-mock--more .svm-r3.svm-c3{transform:translate(14px,12px) rotate(-4deg)}
/* the ninth tile. Teal ground, a navy plus built from two bars. */
.svm-mock--more .svm-tile--plus{background:var(--svm-teal);box-shadow:0 0 0 1px rgba(var(--svm-navy-rgb),.12)}
.svm-mock--more .svm-plus{left:50%;top:50%;width:18px;height:18px;margin:-9px 0 0 -9px}
.svm-mock--more .svm-plus::before,
.svm-mock--more .svm-plus::after{content:"";position:absolute;left:0;right:0;top:8px;height:2px;border-radius:2px;background:var(--svm-navy)}
.svm-mock--more .svm-plus::after{transform:rotate(90deg)}
:is(:is(.svm-svc:hover,.svm-svc.is-active) .svm-mock--more,.svm-mock--more.is-active) .svm-tile{transform:none;opacity:1}
:is(:is(.svm-svc:hover,.svm-svc.is-active) .svm-mock--more,.svm-mock--more.is-active) .svm-r1.svm-c2{transition-delay:.045s}
:is(:is(.svm-svc:hover,.svm-svc.is-active) .svm-mock--more,.svm-mock--more.is-active) .svm-r1.svm-c3{transition-delay:.09s}
:is(:is(.svm-svc:hover,.svm-svc.is-active) .svm-mock--more,.svm-mock--more.is-active) .svm-r2.svm-c1{transition-delay:.135s}
:is(:is(.svm-svc:hover,.svm-svc.is-active) .svm-mock--more,.svm-mock--more.is-active) .svm-r2.svm-c2{transition-delay:.18s}
:is(:is(.svm-svc:hover,.svm-svc.is-active) .svm-mock--more,.svm-mock--more.is-active) .svm-r2.svm-c3{transition-delay:.225s}
:is(:is(.svm-svc:hover,.svm-svc.is-active) .svm-mock--more,.svm-mock--more.is-active) .svm-r3.svm-c1{transition-delay:.27s}
:is(:is(.svm-svc:hover,.svm-svc.is-active) .svm-mock--more,.svm-mock--more.is-active) .svm-r3.svm-c2{transition-delay:.315s}
:is(:is(.svm-svc:hover,.svm-svc.is-active) .svm-mock--more,.svm-mock--more.is-active) .svm-r3.svm-c3{transition-delay:.36s}
:is(:is(.svm-svc:hover,.svm-svc.is-active) .svm-mock--more,.svm-mock--more.is-active) .svm-plus{transform:rotate(90deg);transition-delay:.36s}


/* --------------------------------------------------------------------------
   11. CARDS
   Tiles are white on cream or on light teal. 4px radius, no outline, no rule.
   -------------------------------------------------------------------------- */
.svm-card{background:var(--card);padding:34px 30px 28px;display:flex;flex-direction:column;gap:14px;min-height:260px;border-radius:var(--r-sm);transition:transform var(--dur-med) var(--ease-out)}
.svm-card h3{font-family:var(--f-display);font-weight:600;font-size:22px;letter-spacing:var(--ls-tight);margin:0;line-height:1.15}
/* A card title may be the link itself. It inherits the ink and drops the
   browser underline, then earns a teal underline on hover, so the card still
   reads as one object rather than a heading with a blue link inside it.
   The whole card is not a link, so the title has to be one. */
:is(.svm-card,.svm-post) h3 a{color:inherit;text-decoration:none}
:is(.svm-card,.svm-post) h3 a:hover{text-decoration:underline;text-decoration-color:var(--teal);text-decoration-thickness:2px;text-underline-offset:3px}
.svm-card p{margin:0;font-size:15px;line-height:1.55;color:var(--muted);flex:1}
.svm-card .svm-more:hover{color:var(--svm-teal-deep)}
.svm-card:hover{transform:translateY(-2px)}
.svm-card.svm-hairline-t::before{display:none}

/* post card */
.svm-post{display:flex;flex-direction:column;background:var(--card);text-decoration:none;overflow:hidden;border-radius:var(--r-sm);transition:transform var(--dur-med) var(--ease-out)}
.svm-post:hover{transform:translateY(-2px)}
.svm-post__pic{overflow:hidden}
/* every post card image is the SVM blog image ratio, 1200 by 628. One ratio for
   the archive grid, the featured split and the related strip, so a post reads
   the same everywhere. Jamie, 2026-09-01. Replaced 16:10. */
.svm-post img{aspect-ratio:1200/628;object-fit:cover;width:100%;transition:transform var(--dur-zoom) var(--ease-out)}
.svm-post:hover img{transform:scale(1.03)}
.svm-post__img--right{object-position:72% 50%}
.svm-post__body{padding:22px 24px 24px;display:flex;flex-direction:column;gap:12px;flex:1}
.svm-post__body h3{font-family:var(--f-display);font-weight:600;font-size:20px;letter-spacing:var(--ls-tight);margin:0;line-height:1.2}
.svm-post .svm-more{margin-top:auto}

/* review card, with the big Calluna quotation mark behind it */
.svm-quote{position:relative;padding:34px 32px 30px;display:flex;flex-direction:column;gap:22px;background:var(--card);border-radius:var(--r-sm);margin:0}
.svm-quote::after{content:"\201C";position:absolute;right:22px;top:-18px;font-family:var(--f-italic);font-style:italic;font-weight:700;font-size:180px;line-height:1;color:var(--svm-teal);opacity:.22;pointer-events:none}
.svm-quote > *{position:relative}
.svm-quote.svm-hairline-t::before{display:none}
.svm-quote p{margin:0;font-family:var(--f-italic);font-style:italic;font-weight:400;font-size:21px;line-height:1.4;font-variation-settings:"SOFT" 80}
.svm-quote__who{display:flex;flex-direction:column;gap:4px}
.svm-quote__who b{font-family:var(--f-mono);font-size:12px;letter-spacing:var(--ls-mono);text-transform:uppercase;font-weight:600}
.svm-quote__who span{font-family:var(--f-mono);font-size:10px;letter-spacing:var(--ls-mono);text-transform:uppercase;font-weight:600;color:var(--muted)}
/* review stars. Coral, and big enough to register as the rating. */
.svm-stars{font-family:var(--f-body);letter-spacing:4px;color:var(--svm-coral);font-size:20px}

/* the duotone image with the solid teal offset block behind it */
.svm-duo-wrap{position:relative}
.svm-duo-wrap::before{content:"";position:absolute;inset:0;background:var(--svm-teal);border-radius:var(--r-sm);transform:translate(16px,16px);z-index:0}
.svm-duo{position:relative;z-index:1;overflow:hidden;border-radius:var(--r-sm)}
.svm-duo img{width:100%;aspect-ratio:3/2;max-height:380px;object-fit:cover;object-position:15% 50%;transition:transform var(--dur-zoom) var(--ease-out)}
.svm-duo:hover img{transform:scale(1.03)}


/* --------------------------------------------------------------------------
   12. TEXTURE
   One texture, the coral tile, in four places: the hero at 9%, every mockup
   panel at 10%, the blog panel at 7% and the navy closing band at 3%.
   -------------------------------------------------------------------------- */
.svm-textured{position:relative;overflow:hidden}
.svm-textured > .svm-wrap{position:relative;z-index:2}
.svm-textured::before{
  content:"";position:absolute;inset:0;pointer-events:none;z-index:0;opacity:.07;
  background-image:var(--pattern-coral);background-repeat:repeat;
  background-size:var(--pattern-size) var(--pattern-size);
}

/* the closing CTA. The one dark band. It flows into the footer. */
.svm-cta-band.svm-textured::before{opacity:.03}
.svm-cta-band > .svm-wrap{display:grid;grid-template-columns:1.2fr .8fr;gap:var(--sp-9);align-items:end}
.svm-cta-band .svm-display{font-size:clamp(48px,6.5vw,104px);max-width:10ch}
.svm-cta-band__cities{margin:40px 0 0;padding-top:22px;font-size:17px;line-height:1.5;color:var(--muted);max-width:44ch}
.svm-cta-band__side{display:flex;flex-direction:column;gap:18px}
.svm-cta-band__sub{font-size:var(--fs-large);line-height:1.4;max-width:34ch;color:var(--muted);margin:0 0 var(--sp-5)}
.svm-cta-band__side .svm-tel--display{font-size:28px}


/* --------------------------------------------------------------------------
   13. FOOTER
   -------------------------------------------------------------------------- */
.svm-footer{
  background:var(--svm-navy-deep) var(--grain-cream) repeat 0 0 / var(--grain-size) var(--grain-size);
  color:var(--svm-cream);
  --ink:var(--svm-cream);
  --teal:var(--svm-teal);
  --muted:rgba(var(--svm-cream-rgb),.62);
  --rule:rgba(var(--svm-teal-rgb),.3);
}
.svm-footer > .svm-wrap{padding-top:clamp(48px,6vw,80px);padding-bottom:40px}
/* Services gets the widest column: its two-up list has to hold "OTT & Connected TV" on one line. */
.svm-footer__grid{display:grid;grid-template-columns:1.25fr .8fr 1.45fr 1.1fr;gap:40px;padding-top:clamp(40px,5vw,64px);padding-bottom:56px}
.svm-footer__head{font-family:var(--f-mono);font-size:var(--fs-mono);letter-spacing:var(--ls-mono);text-transform:uppercase;font-weight:600;color:var(--teal);margin:0 0 18px}
.svm-footer__list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:9px;font-size:14px}
.svm-footer__list--two{display:grid;grid-template-columns:1fr 1fr;column-gap:24px}
.svm-footer__list a{text-decoration:none;color:var(--svm-cream);opacity:.85}
.svm-footer__list a:hover{opacity:1;color:var(--teal)}
/* 44px tap target. Same padding-plus-negative-margin technique as the
   header nav links (see section 7): the text does not move and the
   column height does not change. */
.svm-footer__list a{padding:15px 0;margin:-15px 0}
.svm-footer__brand .svm-logo{height:40px;color:var(--svm-cream);margin-bottom:22px;max-width:100%}
.svm-footer__brand .svm-logo svg{max-width:100%}
.svm-footer__brand p{max-width:34ch;color:var(--muted);font-size:14px;margin:0 0 22px}
/* the footer phone is coral, and teal on hover. The header phone stays cream:
   it sits next to the nav links and must not read as a second accent. */
.svm-footer__brand .svm-tel--display{font-size:22px;color:var(--svm-coral)}
.svm-footer__brand .svm-tel--display:hover{color:var(--svm-teal)}
/* the Google Partner badge links to the agency's Partners profile. */
.svm-footer__partner{display:block;width:92px;margin-top:22px;line-height:0;transition:transform var(--dur-med) var(--ease-out)}
.svm-footer__partner:hover{transform:translateY(-3px)}
.svm-footer__partner img{width:100%;height:auto;border-radius:6px}
.svm-footer__bottom{display:flex;justify-content:space-between;align-items:center;gap:24px;padding-top:24px;font-family:var(--f-mono);font-size:10px;letter-spacing:1.8px;text-transform:uppercase;font-weight:600;color:var(--muted);flex-wrap:wrap}
.svm-footer__bottom--tight{padding-top:12px}
.svm-footer__bottom a{text-decoration:none;color:inherit}
.svm-footer__bottom a:hover{color:var(--teal)}
/* 44px tap target, covers the legal links and the social links (both are
   inside .svm-footer__bottom). Same technique as section 7. */
.svm-footer__bottom a{padding:15px 0;margin:-15px 0}
.svm-footer__socials,
.svm-footer__legal{display:flex;gap:18px;flex-wrap:wrap}
.svm-footer__legal{gap:22px}
/* socials are teal glyphs, 40px tap targets, no words. */
.svm-footer__socials{gap:6px;align-items:center}
.svm-footer__bottom .svm-footer__socials a{display:inline-flex;width:40px;height:40px;align-items:center;justify-content:center;padding:0;margin:0;color:var(--teal);border-radius:50%;transition:color var(--dur-fast) var(--ease-out),background var(--dur-fast) var(--ease-out)}
.svm-footer__bottom .svm-footer__socials a:hover{color:var(--svm-cream);background:rgba(255,255,255,.07)}
.svm-footer__socials svg{width:18px;height:18px;fill:currentColor;display:block}
.svm-footer__disclaimer{font-family:var(--f-body);font-size:12px;letter-spacing:0;text-transform:none;font-weight:400;color:var(--muted);margin-top:14px}


/* --------------------------------------------------------------------------
   14. REVEAL
   A 16px fade and lift as a block enters. Staggered by 80ms.
   The opacity only drops once svm.js has confirmed it is running, so the page
   is readable if the script never loads.
   -------------------------------------------------------------------------- */
.svm-js .svm-rv{opacity:0;transform:translateY(16px);transition:opacity var(--dur-slow) var(--ease-out),transform var(--dur-slow) var(--ease-out)}
.svm-js .svm-rv.is-in{opacity:1;transform:none}
.svm-js .svm-svc.svm-rv.is-in{transition:flex-basis .5s var(--ease-out),transform var(--dur-card) var(--ease-out),opacity var(--dur-slow) var(--ease-out)}
.svm-js .svm-post.svm-rv.is-in,
.svm-js .svm-quote.svm-rv.is-in{transition:transform var(--dur-med) var(--ease-out),opacity var(--dur-slow) var(--ease-out)}
/* the stagger. One step is 80ms. .svm-rv-1 is the explicit no-delay first
   position, so a builder can number a whole row from 1 and read it back. The
   family runs to 9 because the homepage rail carries nine service cards. */
.svm-rv-1{transition-delay:0s}
.svm-rv-2{transition-delay:.08s}
.svm-rv-3{transition-delay:.16s}
.svm-rv-4{transition-delay:.24s}
.svm-rv-5{transition-delay:.32s}
.svm-rv-6{transition-delay:.4s}
.svm-rv-7{transition-delay:.48s}
.svm-rv-8{transition-delay:.56s}
.svm-rv-9{transition-delay:.64s}


/* --------------------------------------------------------------------------
   15. RESPONSIVE
   Breakpoints in order: 1024, 860, 600. Then reduced motion, then pointer.
   -------------------------------------------------------------------------- */

/* -- 1024: the mobile nav starts here, so tablets get it too ------------ */
@media (max-width:1024px){
  :root{--seahorse-alpha:.72;--nav-h:64px}
  /* two columns. An odd count would leave an orphan, so its last card spans
     both. --2, --4, --6 and --8 divide evenly and need nothing.
     The per-child span rules from block 6 have to be reset by name: a bare
     .svm-grid > * does not outrank .svm-grid--5 > :nth-child(n+4), and a
     leftover span 6 in a two column grid builds implicit columns. */
  .svm-grid{grid-template-columns:repeat(2,1fr)}
  .svm-grid > *,
  .svm-grid--5 > :nth-child(n+4),
  .svm-grid--7 > :nth-child(n+5){grid-column:auto}
  .svm-grid--3 > :last-child,
  .svm-grid--5 > :last-child,
  .svm-grid--7 > :last-child{grid-column:1 / -1}
  .svm-footer__grid{grid-template-columns:1fr 1fr}
  .svm-seahorse{right:-70px;top:92px;height:104%}
  .svm-nav__wrap{height:var(--nav-h)}
  .svm-rail-ctl button{display:none}
  .svm-hero__widget{position:static;width:100%;max-width:420px;margin-top:28px}
}

/* the bar carries seven items. The phone number is the first thing to go,
   then the type compacts, then at 1200 the hamburger takes over. */
@media (max-width:1300px){.svm-nav__links{gap:16px}.svm-nav__links > a,.svm-nav__dd-btn{font-size:13px}.svm-nav .svm-logo{height:26px}}
/* the Bricks shortcode wrapper around the bar links is a grid cell of its own. */
.svm-nav__slot{min-width:0}
.svm-menu__slot{display:contents}
@media (max-width:1200px){
  .svm-nav__wrap{grid-template-columns:auto 1fr;border-radius:0 0 14px 14px}
  .svm-nav__slot{display:none}
  .svm-nav .svm-logo{height:30px}
  .svm-nav__links{display:none}
  .svm-nav__mm{display:none}
  .svm-nav__right .svm-btn{display:none}
  .svm-menu-btn{display:block}
}

/* -- 860 ---------------------------------------------------------------- */
@media (max-width:860px){
  .svm-rail{--svc-w:270px;--svc-w-hover:270px;scroll-padding-left:var(--rail-pad)}
  .svm-about .svm-duo-wrap{margin-right:16px}
  .svm-hero .svm-display{max-width:none}
  .svm-seahorse{right:-12vw;top:72px;height:92%}
  .svm-seahorse svg *{fill-opacity:calc(var(--seahorse-alpha) - .12)}
  .svm-edge{display:none}
  .svm-cert-bar{grid-template-columns:minmax(0,1fr);gap:18px;min-width:0}
  .svm-cert-logos{min-width:0}
  .svm-cert-logos img{min-width:0}
  /* phone: an auto-moving marquee, about four badges in view. The row is
     duplicated by svm.js, so a -50% shift lands on an identical frame. */
  .svm-cert-bar{overflow:hidden}
  .svm-cert-logos{justify-content:flex-start;gap:22px;flex-wrap:nowrap;width:max-content;animation:svm-marquee 22s linear infinite}
  .svm-cert-logos:hover{animation-play-state:paused}
  .svm-cert-logos .svm-cert-clone{display:block}
  .svm-cert-logos a,.svm-cert-logos img{flex:0 0 auto}
  .svm-cert-logos img{height:62px;width:auto}
  @keyframes svm-marquee{from{transform:translateX(0)}to{transform:translateX(calc(-50% - 11px))}}
  .svm-cert-bar .svm-mono{font-size:10px}
  .svm-about > .svm-wrap{grid-template-columns:1fr}
  .svm-sec-head{flex-direction:column;align-items:flex-start}
  .svm-cta-band > .svm-wrap{grid-template-columns:1fr}
}

/* -- 600 ---------------------------------------------------------------- */
@media (max-width:600px){
  :root{--sec:clamp(56px,14vw,72px)}
  .svm-grid{grid-template-columns:1fr}
  .svm-grid > *,
  .svm-grid--5 > :nth-child(n+4),
  .svm-grid--7 > :nth-child(n+5),
  .svm-grid--3 > :last-child,
  .svm-grid--5 > :last-child,
  .svm-grid--7 > :last-child{grid-column:auto}
  .svm-footer__grid{grid-template-columns:1fr 1fr;gap:28px 20px}
  .svm-footer__brand{grid-column:1 / -1}
  .svm-footer__grid > div:not(:last-child) .svm-footer__list--two{grid-template-columns:1fr}
  .svm-footer__grid > div:last-child{grid-column:1 / -1}
  .svm-footer__grid > div:last-child .svm-footer__list{display:grid;grid-template-columns:1fr 1fr;column-gap:20px}
  .svm-footer__bottom{flex-direction:column;gap:14px}
  .svm-footer__brand .svm-logo{height:32px}
  .svm-btn{width:100%;justify-content:center}
  .svm-lead{font-size:19px}
  .svm-headline{font-size:clamp(32px,9vw,40px)}
  .svm-display{font-size:clamp(44px,12.5vw,52px)}
  .svm-quote::after{font-size:140px;right:14px;top:-14px}
  .svm-seahorse{right:-10vw;top:64px;bottom:auto;height:60%}
  .svm-hero::before{background-size:800px 800px;opacity:.075}
  /* the hero is short on a phone and the type sits over it, so the bubbles go. */
  .svm-bubbles{display:none}
}

/* -- reduced motion ----------------------------------------------------- */
@media (prefers-reduced-motion:reduce){
  .svm-cert-logos{animation:none}
  .svm-hero__copy > *,
  .svm-hero__widget{animation:none!important}
  .svm-js .svm-rv{opacity:1;transform:none;transition:none}
  /* the two looping animations, both off. */
  .svm-seahorse{animation:none}
  .svm-bubbles{display:none}
}

/* -- pointer ------------------------------------------------------------ */
/* Scroll snap fought both the edge scrolling and the card growth on a mouse. */
@media (hover:hover){
  .svm-rail{scroll-snap-type:none}
}
/* On touch nothing expands. The observer in svm.js plays the same animation. */
@media (hover:none){
  .svm-svc:hover{flex-basis:var(--svc-w);transform:none}
}


/* --------------------------------------------------------------------------
   16. SERVICE PAGE ADDITIONS
   Added 2026-09-01 for the SEO service page (brief 01). A breadcrumb strip,
   a text-left/image-right content split, numbered service-point cards and a
   sub-page hero that sits in normal document flow below a breadcrumb
   instead of overlapping the sticky header the way the homepage hero does.
   -------------------------------------------------------------------------- */

/* the breadcrumb trail. Label role, always inside .svm-drawer on an interior
   page. A crumb is an <a> when the level has a page, a plain <span> when it
   does not (Areas has no index page yet), and the last crumb carries
   aria-current. The flat strip form was dropped on 2026-09-02: every page uses
   the drawer. */
.svm-breadcrumb__nav{display:flex;align-items:center;gap:10px;font-family:var(--f-mono);font-size:var(--fs-mono);letter-spacing:var(--ls-mono);text-transform:uppercase;font-weight:600}
.svm-breadcrumb__nav a{color:var(--muted);text-decoration:none}
.svm-breadcrumb__nav a:hover{color:var(--ink);text-decoration:underline;text-decoration-color:var(--teal);text-underline-offset:4px}
.svm-breadcrumb__nav span:not([aria-hidden]):not([aria-current]){color:var(--muted)}
.svm-breadcrumb__nav span[aria-hidden]{color:var(--rule)}
.svm-breadcrumb__nav span[aria-current]{color:var(--ink)}

/* an interior-page hero. Same look as .svm-hero, but it follows a
   breadcrumb in normal flow rather than pulling up under the sticky header. */
/* Interior hero: the breadcrumb hangs under the nav bar as a white drawer, rounded like the bar. */
.svm-hero--sub{--drawer-h:46px}
/* compact contact cards inside the sub hero: icon and title on one row. */
.svm-hero__ways{margin-top:36px}
.svm-card--compact{min-height:0;padding:20px 22px 18px;gap:10px;background:var(--svm-white)}
.svm-card__head{display:flex;align-items:center;gap:12px}
.svm-card__head .svm-card__icon{width:36px;height:36px}
.svm-card__head .svm-card__icon svg{width:18px;height:18px}
.svm-card__head h3{font-size:19px}
.svm-card--compact p{font-size:14px;line-height:1.5;flex:none}
.svm-card--compact .svm-more{margin-top:2px}
.svm-hero--sub > .svm-wrap{padding-top:calc(clamp(40px,5vw,72px) + var(--nav-h) + var(--drawer-h))}
.svm-drawer{position:absolute;top:var(--nav-h);left:20px;right:20px;z-index:3;height:var(--drawer-h);padding:0 24px;background:var(--svm-cream);border-radius:0 0 14px 14px;display:flex;align-items:center;gap:10px}
@media (max-width:1024px){.svm-drawer{left:12px;right:12px;padding:0 16px}}

/* the content split: headline and intro left, one duo image right.
   Mirrors .svm-about but keeps text first for an interior page. */
.svm-split{display:grid;grid-template-columns:1.1fr .9fr;gap:clamp(32px,6vw,96px);align-items:center;margin-bottom:clamp(56px,7vw,96px)}
.svm-split :is(.svm-headline,.svm-display,.svm-section-h){margin-bottom:20px}
/* the last split in a section does not add a gap on top of the section padding */
.svm-split:last-child{margin-bottom:0}
.svm-split p{margin:0 0 16px;color:var(--muted);font-size:16px;line-height:1.6;max-width:60ch}
.svm-split p:last-child{margin-bottom:0}

/* a 4:3 crop of the duotone treatment, for a support image beside body copy */
.svm-duo--4x3 img{aspect-ratio:4/3}

/* the card icon tile. One inline Lucide glyph at 22px, navy at 1.75 stroke,
   on a 44px light teal square. Cards are never numbered: a card grid is a
   set, not a sequence. Numbers belong to .svm-process. Jamie, 2026-09-01.
   flex:none is required, or the tile inherits flex:1 from .svm-card p and
   every card in the row lands its heading at a different height. */
.svm-card__icon{width:44px;height:44px;flex:none;border-radius:var(--r-sm);background:var(--svm-teal-light);display:grid;place-items:center}
.svm-card__icon svg{width:22px;height:22px;display:block;fill:none;stroke:var(--svm-navy);stroke-width:1.75;stroke-linecap:round;stroke-linejoin:round}

@media (max-width:860px){
  .svm-split{grid-template-columns:1fr}
  .svm-split .svm-duo-wrap{margin-right:16px}
}


/* --------------------------------------------------------------------------
   18. HERO ART
   Added 2026-09-01. An interior service hero carries the same CSS mockup its
   card uses on the homepage rail, at rest in its animated end state, on the
   right of the hero. No image, no icon library, nothing new to draw.
   -------------------------------------------------------------------------- */

/* the frame. Absolute inside .svm-hero > .svm-wrap, so it inherits that box.
   padding-top and padding-bottom are inherited on purpose: they cancel the
   hero's header offset, which centers the art on the copy and not on the
   whole wrap. z-index 1 puts it over the coral pattern and under both the
   hero copy (2) and the breadcrumb drawer (3). */
.svm-hero__art{
  position:absolute;top:0;bottom:0;right:var(--gutter);
  padding-top:inherit;padding-bottom:inherit;
  width:clamp(320px,32vw,460px);
  display:flex;align-items:center;justify-content:center;
  z-index:1;pointer-events:none;
}
/* two thirds of the frame, scaled by 1.5, so the drawn art is exactly the
   frame width and nothing is clipped by the hero's overflow:hidden. */
.svm-hero__art .svm-mock{width:66.667%;flex:none}

/* .svm-mock--bare: the rail mockup with its own ground removed. No light teal
   panel, no coral tile, no clipping, and scaled up for hero use. Only the
   mockup pieces sit on the hero. Use it nowhere else. */
.svm-mock--bare{background:none;overflow:visible;transform:scale(1.5);transform-origin:center center}
.svm-mock--bare::before{content:none}
.svm-hero__art .svm-mock--bare{animation:svm-art-rise var(--dur-slow) var(--ease-out) .24s both}
@keyframes svm-art-rise{from{opacity:0;transform:scale(1.42) translateY(10px)}to{opacity:1;transform:scale(1.5)}}

/* the headline must never run under the art. */
@media (min-width:1025px){
  .svm-hero:has(.svm-hero__art) .svm-hero__copy{max-width:calc(100% - clamp(360px,35vw,510px))}
}
/* the city map stays in the hero down to 860, 260px further than the generic
   service art, so the copy needs the same narrowing over that whole range. */
@media (min-width:861px) and (max-width:1024px){
  .svm-hero--city:has(.svm-hero__map) .svm-hero__copy{max-width:calc(100% - clamp(360px,35vw,510px))}
}
/* tablets and phones: the interior hero is text only, except the city map,
   which stays visible and switches layout in its own rules below. */
@media (max-width:1024px){
  .svm-hero__art:not(.svm-hero__map):not(.svm-post-hero__thumb){display:none}
}
@media (prefers-reduced-motion:reduce){
  .svm-hero__art .svm-mock--bare{animation:none}
}


/* --------------------------------------------------------------------------
   19. PROCESS WINDOW AND CREDENTIALS
   .svm-steps was removed 2026-09-01 and replaced by .svm-process. The old
   stepper put nodes on a track with a box under them, which read as a generic
   wizard. The window speaks the language the homepage mockups already speak.
   -------------------------------------------------------------------------- */

/* .svm-process: the one component for "here is how we work". Never a row of
   cards, never a bare <ol>, never a track with nodes on it.

   It is one white window on the section ground, drawn with the same chrome as
   .svm-mock--web but at real scale: a top bar with three dots on the left and
   a short progress track on the right whose teal fill equals the active step's
   position. Inside, a light teal sidebar of step rows and a white content pane.

   861 and up: sidebar left at 300px, pane right.
   860 and down: the sidebar becomes a scrolling row of pills above the pane.
   The pane swaps at both widths, so the script never stands down.

   Tabs semantics: the sidebar list is the tablist, each row is a tab, and the
   pane is one tabpanel whose aria-labelledby follows the active tab.

   Works for three to six steps. Past six, split the process. */
.svm-process{
  position:relative;background:var(--card);border-radius:var(--r-sm);overflow:hidden;
  box-shadow:0 0 0 1px rgba(var(--svm-navy-rgb),.12);
}

/* -- the chrome bar ---------------------------------------------------- */
.svm-process__bar{
  display:flex;align-items:center;justify-content:space-between;gap:20px;
  height:44px;padding:0 18px;
  background:rgba(var(--svm-navy-rgb),.06);
  border-bottom:1px solid rgba(var(--svm-navy-rgb),.10);
}
.svm-process__dots{display:flex;align-items:center;gap:8px}
.svm-process__dots i{width:10px;height:10px;border-radius:50%;background:rgba(var(--svm-navy-rgb),.3)}
/* the progress track. 120px, and the fill is set by the script, so the width
   is the active step over the step count. */
.svm-process__track{width:120px;height:4px;flex:none;border-radius:var(--r-pill);background:rgba(var(--svm-navy-rgb),.14);overflow:hidden}
.svm-process__fill{display:block;width:0;height:100%;border-radius:var(--r-pill);background:var(--teal);transition:width .4s var(--ease-out)}

/* -- the two columns ---------------------------------------------------- */
.svm-process__body{display:grid;grid-template-columns:300px minmax(0,1fr);align-items:stretch}
.svm-process__list{
  background:var(--svm-teal-light);
  border-right:1px solid rgba(var(--svm-navy-rgb),.10);
  padding:10px 0;
}

/* -- a sidebar row ------------------------------------------------------ */
.svm-process__step{
  appearance:none;-webkit-appearance:none;font:inherit;color:var(--ink);cursor:pointer;
  display:grid;grid-template-columns:22px minmax(0,1fr) 32px;align-items:center;gap:12px;
  width:100%;min-height:56px;margin:0;padding:10px 14px;text-align:left;
  background:transparent;border:0;border-left:3px solid transparent;
  transition:background var(--dur-fast) var(--ease-out),border-color var(--dur-fast) var(--ease-out);
}
.svm-process__num{font-family:var(--f-italic);font-style:italic;font-weight:700;font-size:15px;line-height:1;color:var(--svm-navy);font-variation-settings:"SOFT" 80;text-align:center}
.svm-process__label{font-family:var(--f-display);font-weight:600;font-size:15px;line-height:1.25;letter-spacing:var(--ls-tight);color:var(--ink)}
.svm-process__tile{width:32px;height:32px;flex:none;border-radius:var(--r-sm);background:var(--svm-teal-light);display:grid;place-items:center;transition:background var(--dur-fast) var(--ease-out)}
.svm-process__tile svg{width:18px;height:18px;display:block;fill:none;stroke:var(--svm-navy);stroke-width:1.75;stroke-linecap:round;stroke-linejoin:round}

.svm-process__step:hover{background:rgba(var(--svm-white-rgb),.55)}
.svm-process__step:focus-visible{outline:2px solid var(--svm-teal-ink);outline-offset:-2px}
.svm-process__step[aria-selected="true"]{background:var(--card);border-left-color:var(--teal)}
.svm-process__step[aria-selected="true"] .svm-process__tile{background:var(--teal)}

/* -- the content pane --------------------------------------------------- */
.svm-process__pane{background:var(--card);padding:40px}
.svm-process__item{min-height:170px}
.svm-process__icon{width:56px;height:56px;border-radius:var(--r-sm);background:var(--svm-teal-light);display:grid;place-items:center;margin-bottom:20px}
.svm-process__icon svg{width:28px;height:28px;display:block;fill:none;stroke:var(--svm-navy);stroke-width:1.75;stroke-linecap:round;stroke-linejoin:round}
.svm-process__title{font-family:var(--f-display);font-weight:500;font-size:28px;line-height:1.1;letter-spacing:var(--ls-head);color:var(--ink);margin:0 0 14px}
.svm-process__text{margin:0 0 20px;font-size:17px;line-height:1.6;color:var(--muted);max-width:62ch}
.svm-process__count{font-family:var(--f-mono);font-size:var(--fs-mono);letter-spacing:var(--ls-mono);text-transform:uppercase;font-weight:600;color:var(--muted);margin:0}

/* without the script every step stays visible, so the process still reads. */
.svm-js .svm-process__item{display:none}
.svm-js .svm-process__item.is-on{display:block}
.svm-process__item + .svm-process__item{margin-top:34px}

/* -- motion ------------------------------------------------------------- */
/* The window rises and fades, then the rows stagger in from the left 60ms
   apart. It rides the .svm-rv observer: put .svm-rv on the .svm-process root
   and the reveal in svm.js adds .is-in. No second observer, no loop. */
.svm-js .svm-process{opacity:0;transform:translateY(16px);transition:opacity var(--dur-slow) var(--ease-out),transform var(--dur-slow) var(--ease-out)}
.svm-js .svm-process.is-in{opacity:1;transform:none}
.svm-js .svm-process .svm-process__step{opacity:0}
.svm-js .svm-process.is-in .svm-process__step{animation:svm-process-row .4s var(--ease-out) .22s both}
.svm-js .svm-process.is-in .svm-process__step:nth-child(2){animation-delay:.28s}
.svm-js .svm-process.is-in .svm-process__step:nth-child(3){animation-delay:.34s}
.svm-js .svm-process.is-in .svm-process__step:nth-child(4){animation-delay:.40s}
.svm-js .svm-process.is-in .svm-process__step:nth-child(5){animation-delay:.46s}
.svm-js .svm-process.is-in .svm-process__step:nth-child(6){animation-delay:.52s}
@keyframes svm-process-row{from{opacity:0;transform:translateX(-14px)}to{opacity:1;transform:none}}

/* the swap. The pane content crossfades and slides 6px up. An item goes from
   display:none to display:block, which restarts the animation on its own. */
.svm-js .svm-process__item.is-on{animation:svm-process-swap .25s var(--ease-out) both}
@keyframes svm-process-swap{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}

/* .svm-facts and .svm-fact were removed 2026-09-01. A credentials row is a
   card grid: .svm-grid plus a count modifier, of .svm-card, each with a
   .svm-card__icon. There is
   no second tile component. */

@media (max-width:1024px){
  .svm-process__body{grid-template-columns:260px minmax(0,1fr)}
  .svm-process__pane{padding:32px}
}

/* -- tablet and phone: the sidebar becomes an accordion ------------------ */
/* Every step stays in view as a full-width row, and the selected step's
   content opens directly under it. The list and the pane drop their own
   boxes (display:contents) so steps and items become siblings of one column,
   and `order` interleaves them: step n, item n. Same tab script, no DOM moves.
   Jamie, 2026-09-02: no more scrolling pills. */
@media (max-width:860px){
  .svm-process__body{display:flex;flex-direction:column}
  .svm-process__list,
  .svm-process__pane{display:contents}
  .svm-process__step:nth-child(1){order:1}  .svm-process__item:nth-child(1){order:2}
  .svm-process__step:nth-child(2){order:3}  .svm-process__item:nth-child(2){order:4}
  .svm-process__step:nth-child(3){order:5}  .svm-process__item:nth-child(3){order:6}
  .svm-process__step:nth-child(4){order:7}  .svm-process__item:nth-child(4){order:8}
  .svm-process__step:nth-child(5){order:9}  .svm-process__item:nth-child(5){order:10}
  .svm-process__step:nth-child(6){order:11} .svm-process__item:nth-child(6){order:12}
  .svm-process__step:nth-child(7){order:13} .svm-process__item:nth-child(7){order:14}
  .svm-process__step:nth-child(8){order:15} .svm-process__item:nth-child(8){order:16}
  .svm-process__step{
    min-height:60px;padding:12px 16px;gap:14px;
    background:var(--svm-teal-light);border-bottom:1px solid rgba(var(--svm-navy-rgb),.10);
  }
  .svm-process__step:hover{background:var(--svm-teal-light)}
  .svm-process__step[aria-selected="true"]{background:var(--card);border-left-color:var(--teal);border-bottom-color:transparent}
  .svm-process__step[aria-selected="true"] .svm-process__tile{background:var(--teal)}
  .svm-process__item{min-height:0;background:var(--card);padding:6px 18px 24px 55px;border-left:3px solid var(--teal);border-bottom:1px solid rgba(var(--svm-navy-rgb),.10)}
  .svm-process__item + .svm-process__item{margin-top:0}
  .svm-process__icon{display:none}
  .svm-process__title{font-size:22px;margin-bottom:10px}
  .svm-process__text{font-size:16px;margin-bottom:12px}
  .svm-process__count{margin:0}
  .svm-js .svm-process.is-in .svm-process__step{animation-name:svm-process-row}
}

@media (max-width:600px){
  .svm-process__item{padding-left:16px}
}

@media (prefers-reduced-motion:reduce){
  .svm-js .svm-process,
  .svm-js .svm-process.is-in{opacity:1;transform:none;transition:none}
  .svm-js .svm-process .svm-process__step,
  .svm-js .svm-process.is-in .svm-process__step{opacity:1;animation:none}
  .svm-js .svm-process__item.is-on{animation:none}
  .svm-process__fill{transition:none}
}


/* --------------------------------------------------------------------------
   20. MAPS
   Added 2026-09-01 for the city pages. Every path in img/maps/*.svg is
   generated by tools/make-maps.py from the us-atlas 1:10m TopoJSON of the US
   states, projected with an Albers conic equal area fitted to each selection.
   No boundary is drawn by hand and no SVG file carries a color: the files
   hold geometry and class names only, and every fill and stroke comes from
   this block. That is why a map is inlined into the page rather than loaded
   through an <img>, which would cut it off from these tokens.
   -------------------------------------------------------------------------- */
/* The viewBox does the cropping, so overflow must stay hidden. */
.svm-map{display:block;width:100%;height:auto}

/* the states. The city's own state carries --here.
   --map-state is a local theme alias, the same trick the page grounds use: the
   neighbouring states default to light teal, which reads on a white or cream
   ground. On the light teal hero and the light teal "Also serving" panel that
   fill is the ground's own color and the map disappears, so those two places
   set --map-state to white and lift the borders to 45%. */
.svm-map{--map-state:var(--svm-teal-light);--map-rule:.35}
.svm-map__state{
  fill:var(--map-state);
  stroke:var(--svm-navy);stroke-opacity:var(--map-rule);stroke-width:1;
  vector-effect:non-scaling-stroke;stroke-linejoin:round;
}
.svm-map__state--here{fill:var(--svm-teal);fill-opacity:.55}

/* the city point. A teal dot in a white ring, with the seahorse standing on it. */
.svm-map__dot{fill:var(--svm-teal);stroke:var(--svm-white);stroke-width:2.5}
.svm-map__mark{fill:var(--svm-navy)}
/* the label role, in SVG. font-size and letter-spacing here are viewBox units,
   not screen pixels: a 600-unit map drawn at 440px scales by .733, so 15 units
   land on the 11px of the label role. Change one and change the other. */
.svm-map__label{
  font-family:var(--f-mono);font-size:var(--map-label,15px);font-weight:600;
  letter-spacing:2.7px;text-transform:uppercase;
  fill:var(--svm-navy);
}

/* the leader line: drawn only when a label would collide with the state's own
   edge and has to be nudged clear of it. See tools/make-maps.py. */
.svm-map__leader{stroke:var(--svm-navy);stroke-opacity:.5;stroke-width:1;vector-effect:non-scaling-stroke}


/* --------------------------------------------------------------------------
   21. CITY PAGE
   .svm-hero--city, .svm-hero__map and .svm-prose. Added 2026-09-01.
   -------------------------------------------------------------------------- */

/* the city H1. Smaller and wider than the service H1, so a two-part city name
   breaks into two lines at 1440 instead of four. */
.svm-hero.svm-hero--city .svm-display{font-size:clamp(40px,5vw,72px);max-width:18ch}

/* .svm-hero__map: the .svm-hero__art frame carrying the city's regional map.
   Use it with .svm-hero__art, never on its own. Unlike the service art it is
   never hidden, because on a city page the map IS the page's point: under
   860 it leaves the absolute frame and drops below the buttons.
   Down to 860 it stays absolute inside the hero, bottom anchored with 40px of
   clearance above the hero's own bottom edge. padding-top:0 lets a tall
   state's top run up under the breadcrumb drawer and the nav bar, both of
   which sit above it (z-index 3 and 20 against this frame's inherited 1), so
   the map is simply covered there rather than overflowing the hero, which
   stays overflow:hidden. max-height on the SVG itself is what keeps a tall
   state like Alabama or Mississippi inside that space at 1440 and 1024
   instead of running past the hero's top. A wide state like Louisiana or
   Florida is short enough that it never reaches the cap, so .svm-map--wide
   reverts to the original vertical centering instead of bottom anchoring,
   which would otherwise strand it low in the frame. */
.svm-hero__art.svm-hero__map{
  width:clamp(340px,31vw,440px);
  align-items:flex-end;
  padding-top:0;padding-bottom:40px;
  animation:svm-rise var(--dur-slow) var(--ease-out) .24s both;
}
.svm-hero__art.svm-hero__map:has(.svm-map--wide){
  align-items:center;padding-top:inherit;padding-bottom:inherit;
}
.svm-hero__map .svm-map{
  display:block;width:auto;height:auto;max-width:100%;max-height:100%;
  --map-state:var(--svm-white);--map-rule:.45;
}

@media (max-width:860px){
  .svm-hero__art.svm-hero__map{
    display:block;position:static;width:100%;max-width:420px;
    padding-top:0;padding-bottom:0;margin-top:var(--sp-8);
    align-items:center;
  }
  .svm-hero__map .svm-map{width:100%;height:auto;max-width:100%;max-height:none}
}
@media (prefers-reduced-motion:reduce){
  .svm-hero__art.svm-hero__map{animation:none}
}

/* .svm-prose: one column of running body copy at a 68ch measure, left aligned
   in the container. Section heads take the section-head role, paragraphs sit
   on the 4pt scale. Use it on the white ground, never in a two-column split:
   a long article set in two columns makes the reader jump the page. */
/* the layout. Prose column on the left at a 68ch measure, the at-a-glance rail
   on the right, 48px between them. The rail is sticky so it stays beside the
   copy while a long article scrolls. */
.svm-prose-wrap{display:grid;grid-template-columns:minmax(0,1fr) 300px;gap:48px;align-items:start}
.svm-prose{max-width:68ch;min-width:0}

/* run heads. A 2px teal rule above each one is what breaks the column into
   runs, so a long article reads as sections instead of one chunk. */
.svm-prose .svm-section-h{margin:0 0 var(--sp-4)}
.svm-prose * + .svm-section-h{margin-top:var(--sp-8);padding-top:var(--sp-8);border-top:2px solid var(--teal)}
.svm-prose p{margin:0 0 var(--sp-6);color:var(--muted);font-size:16px;line-height:1.6}
/* the opening paragraph carries the lead role, so the column opens at 21px */
.svm-prose > p:first-of-type{font-size:var(--fs-large);line-height:1.45;margin-bottom:var(--sp-7)}
.svm-prose > :last-child{margin-bottom:0}

/* .svm-prose__pull: one pull quote per article, a sentence lifted verbatim from
   the copy. Cream tile, Calluna italic at 26px, and the same oversized
   quotation mark the review cards use. Never a new sentence, never a stat. */
.svm-prose__pull{
  position:relative;overflow:hidden;
  margin:var(--sp-8) 0 var(--sp-9);padding:32px 34px 30px;
  background:var(--svm-cream);border-radius:var(--r-sm);
}
.svm-prose__pull::after{
  content:"\201C";position:absolute;right:22px;top:-18px;
  font-family:var(--f-italic);font-style:italic;font-weight:700;font-size:180px;
  line-height:1;color:var(--svm-teal);opacity:.22;pointer-events:none;
}
.svm-prose__pull + .svm-section-h{margin-top:var(--sp-6)}
.svm-prose__pull p{
  position:relative;margin:0;color:var(--ink);
  font-family:var(--f-italic);font-style:italic;font-weight:400;
  font-size:26px;line-height:1.35;font-variation-settings:"SOFT" 80;
}

/* .svm-prose__aside: the at-a-glance rail. Every fact in it is already in the
   page's own copy. Never put a number here that the article does not say. */
.svm-prose__aside{
  position:sticky;top:120px;
  background:var(--card);border-radius:var(--r-sm);padding:26px 24px;
  box-shadow:0 0 0 1px rgba(var(--svm-navy-rgb),.1);
}
.svm-prose__aside .svm-mono{color:var(--muted);margin:0 0 var(--sp-5)}
.svm-prose__fact{display:flex;align-items:flex-start;gap:14px}
.svm-prose__fact + .svm-prose__fact{margin-top:var(--sp-5)}
.svm-prose__fact p{margin:0;font-size:15px;line-height:1.45;color:var(--ink)}
.svm-prose__fact .svm-card__icon{width:36px;height:36px}
.svm-prose__fact .svm-card__icon svg{width:18px;height:18px}

@media (max-width:1024px){
  /* the rail moves above the copy and stops being sticky */
  .svm-prose-wrap{grid-template-columns:minmax(0,1fr)}
  .svm-prose__aside{position:static;top:auto;order:-1;margin-bottom:var(--sp-8)}
  .svm-prose{max-width:68ch}
}
@media (max-width:600px){
  .svm-prose__pull{padding:26px 24px 24px}
  .svm-prose__pull p{font-size:22px}
  .svm-prose__pull::after{font-size:140px;right:14px;top:-14px}
}

/* top aligned columns, for a split whose two sides are different heights */
.svm-split--top{align-items:start}
/* a long form: full container width, in one card. A compact card beside the
   hero copy carries what to have ready. */
.svm-display--compact{font-size:clamp(38px,4.8vw,62px)}
.svm-hero__row{display:grid;grid-template-columns:minmax(0,1.15fr) minmax(0,.85fr);gap:clamp(24px,4vw,64px);align-items:end}
.svm-hero__aside{gap:8px}
.svm-hero__aside .svm-section-h{margin:0 0 4px}
.svm-hero__aside p{margin:0;font-size:14px;line-height:1.5;color:var(--muted);flex:none}
.svm-hero__aside .svm-mono{margin-top:8px;color:var(--ink)}
.svm-hero__aside .svm-toc{padding-left:18px;gap:6px;font-size:14px;color:var(--muted)}
.svm-card--form{padding:clamp(24px,3vw,44px);min-height:0}
/* the form card overlaps the hero's bottom edge, so the form starts one
   screen sooner. The hero keeps extra room under its copy for the overlap. */
.svm-hero--form > .svm-wrap{padding-bottom:calc(clamp(40px,5vw,72px) + 72px)}
.svm-section--pull{padding-top:0}
.svm-section--pull .svm-card--form{position:relative;z-index:2;margin-top:-72px;box-shadow:0 18px 48px -24px rgba(var(--svm-navy-rgb),.25)}
@media (max-width:860px){.svm-hero__row{grid-template-columns:minmax(0,1fr)}}
/* Gravity Forms sections read as chapters inside the card */
.gform_wrapper .gfield--type-section{margin-top:16px}
.gform_wrapper .gfield--type-section:first-child{margin-top:0}
.gform_wrapper .gfield--type-section .gsection_description{font-size:14px;color:var(--muted);margin:8px 0 0}
/* GF wraps name, address and consent in a fieldset. A legend paints outside
   a fieldset's background by default, so float it inside like any label. */
.gform_wrapper fieldset.gfield{min-inline-size:0;display:block}
.gform_wrapper fieldset.gfield > legend{float:left;width:100%;padding:0}
.gform_wrapper fieldset.gfield > legend + *{clear:both}
.gform_wrapper .gfield.gfield--type-consent{background:rgba(var(--svm-teal-rgb),.14);border:1px solid rgba(var(--svm-teal-rgb),.55);border-radius:var(--r-sm);padding:16px 18px 18px}
.gform_wrapper .gfield--type-consent .gfield_label{margin-bottom:10px;color:var(--ink)}
.gform_wrapper .gfield--type-consent .gfield_consent_description{max-height:none;overflow:visible;margin:0 0 14px;font-size:14px;line-height:1.55;color:var(--ink)}
.gform_wrapper .gfield--type-consent .ginput_container_consent{display:flex;gap:12px;align-items:center}
.gform_wrapper .gfield--type-consent .gfield_consent_label{font-size:15px;font-weight:600;color:var(--ink);line-height:1.4}

/* A phone renders the hero map at about 350px, so a 15 unit label lands under
   9px. The label grows in viewBox units to hold the label role's 11px. */
@media (max-width:600px){
  .svm-hero__map .svm-map{--map-label:20px}
}


/* --------------------------------------------------------------------------
   22. BLOG TEMPLATE AND SHARED PATTERNS
   Added 2026-09-01 (brief 09). blog.html and post.html were built while the
   stylesheet was locked, so they carried inline styles. Everything they needed
   is a class here now, and several of these classes are shared with the company
   pages and the case study template.

   NAMING NOTE. The sticky side column is .svm-siderail, NOT .svm-rail.
   .svm-rail is already the homepage services carousel in block 10, and
   js/svm.js binds to it by name, so reusing that name would break the
   homepage. Any brief that says ".svm-rail" for a sticky column means this.
   -------------------------------------------------------------------------- */

/* -- links in running prose --------------------------------------------- */
/* Ink text, no rest underline, a 2px teal underline on hover. The focus ring
   is the system ring from block 3 and is never removed. */
.svm-prose a{color:var(--ink);text-decoration:underline;text-decoration-color:var(--svm-teal);text-decoration-thickness:2px;text-underline-offset:3px}
.svm-prose a:hover{text-decoration-color:var(--svm-navy)}

/* a headline or a section head that is itself a link. Same behavior as the
   card title rule in block 11, so a linked title reads as one object. */
:is(.svm-headline,.svm-section-h) a{color:inherit;text-decoration:none}
:is(.svm-headline,.svm-section-h) a:hover{text-decoration:underline;text-decoration-color:var(--teal);text-decoration-thickness:2px;text-underline-offset:3px}

/* -- the hero label and meta stack ---------------------------------------- */
/* A post hero is label, title, meta line. Sibling rules, so no new class and
   no inline margin. */
.svm-hero__copy .svm-mono + .svm-display{margin-top:var(--sp-4)}
.svm-hero__copy .svm-display + .svm-mono{margin-top:var(--sp-5)}

/* -- .svm-prose--wide ---------------------------------------------------- */
/* The post body drops the 68ch measure and fills the grid column, so the copy
   runs all the way to the 300px rail with the 48px gap. Two columns only:
   below 1025 there is no rail beside the copy, so the 68ch measure returns.
   Everywhere else .svm-prose keeps 68ch. */
@media (min-width:1025px){
  .svm-prose--wide{max-width:none}
}

/* -- .svm-siderail ------------------------------------------------------- */
/* The sticky right column of .svm-prose-wrap. It holds cards, it is not a card
   itself. 300px comes from the grid track. Above the copy and static below
   1024, the same move .svm-prose__aside makes. */
.svm-siderail{position:sticky;top:120px;display:flex;flex-direction:column;gap:var(--sp-6)}
@media (max-width:1024px){
  .svm-siderail{position:static;top:auto;order:-1;max-width:420px;margin-bottom:var(--sp-8)}
}

/* -- .svm-toc ------------------------------------------------------------ */
/* the in-page contents list inside a .svm-card in the side rail */
.svm-toc{margin:0;padding-left:18px;list-style:disc;display:flex;flex-direction:column;gap:10px;font-size:14px;line-height:1.4}
.svm-toc a{color:inherit;text-decoration:none}
.svm-toc a:hover{text-decoration:underline;text-decoration-color:var(--teal);text-decoration-thickness:2px;text-underline-offset:3px}

/* -- .svm-table ---------------------------------------------------------- */
/* A plain table. Hairline rows, a label-role header over a 2px teal rule, 15px
   body. Always wrap it in .svm-table-wrap, which turns into a horizontal
   scroller under 600 so a table never widens the document. */
.svm-table-wrap{max-width:100%}
.svm-table{width:100%;border-collapse:collapse;margin:0 0 var(--sp-6);font-size:15px}
.svm-table th{
  text-align:left;padding:10px 14px 10px 0;border-bottom:2px solid var(--teal);
  font-family:var(--f-mono);font-size:12px;letter-spacing:var(--ls-mono);
  text-transform:uppercase;font-weight:600;color:var(--ink);
}
.svm-table td{padding:12px 14px 12px 0;border-bottom:1px solid var(--rule);vertical-align:top;color:var(--muted);line-height:1.5}
.svm-table :is(th,td) + :is(th,td){padding-left:14px}
.svm-table :is(th,td):last-child{padding-right:0}
.svm-table td:first-child{font-weight:600;color:var(--ink)}
.svm-table tbody tr:last-child td{border-bottom:0}
@media (max-width:600px){
  .svm-table-wrap{overflow-x:auto;-webkit-overflow-scrolling:touch}
  .svm-table{min-width:520px}
}

/* -- .svm-thumb ---------------------------------------------------------- */
/* One image class for the SVM blog image ratio, 1200 by 628. 4px radius, cover
   crop, full color. Use it on the <img> itself. */
.svm-thumb{display:block;width:100%;aspect-ratio:1200/628;object-fit:cover;border-radius:var(--r-sm)}

/* -- .svm-post-hero__thumb ----------------------------------------------- */
/* The featured image in the post hero. It is a variant of .svm-hero__art and
   always carries both classes, the same way .svm-hero__map does, so the hero
   copy is capped opposite it and the image centers vertically on the copy.
   About 480px at 1440. Unlike the service art it is never hidden: under 1024 it
   leaves the absolute frame and drops below the meta line at full width. */
.svm-hero__art.svm-post-hero__thumb{width:clamp(320px,34vw,480px)}
@media (max-width:1024px){
  .svm-hero__art.svm-post-hero__thumb{
    display:block;position:static;width:100%;max-width:520px;
    padding-top:0;padding-bottom:0;margin-top:var(--sp-7);
  }
}

/* -- .svm-hero--message --------------------------------------------------- */
/* A hero that IS the page: 404 and thank you carry a hero, the closing band and
   nothing else. It holds a minimum height so the seahorse contour reads whole
   instead of being cropped to a fin, which is what a short hero does to it. */
.svm-hero--message{min-height:clamp(460px,52vw,760px);display:flex;align-items:center}
.svm-hero--message > .svm-wrap{width:100%}

/* -- .svm-section--compact ------------------------------------------------ */
/* A band that carries one short row. 48px top and bottom instead of --sec. */
.svm-section--compact{padding-top:var(--sp-9);padding-bottom:var(--sp-9)}

/* -- .svm-split--feature -------------------------------------------------- */
/* The newest post on the blog archive. A 520px thumbnail at the blog ratio, the
   copy centered beside it: label, title at the section-head role, a two line
   excerpt and the read link. Under 380px tall at 1440. */
.svm-split--feature{grid-template-columns:520px minmax(0,1fr);gap:clamp(28px,4vw,56px);margin-bottom:0}
.svm-split--feature > div{display:flex;flex-direction:column;gap:12px;align-items:flex-start}
.svm-split--feature p{margin:0;max-width:64ch}
/* the excerpt stops at two lines, so the row keeps its height whatever the
   post's opening paragraph says. */
.svm-split__excerpt{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
@media (max-width:860px){
  .svm-split--feature{grid-template-columns:minmax(0,1fr)}
}

/* a grid followed by another section head, which is how a long card set is
   broken into labelled groups: the awards page runs one grid per year. */
.svm-grid + .svm-sec-head{margin-top:clamp(40px,5vw,64px)}

/* a photo band: three or four photos in a card grid. .svm-duo without its
   .svm-duo-wrap offset block is the plain photo frame, and in a grid each one
   is center cropped instead of taking the split treatment's left bias. */
.svm-grid > .svm-duo img{object-position:50% 50%;max-height:none}

/* -- .svm-chip-row -------------------------------------------------------- */
/* A row of outline buttons used as jump links or filters, under a lead or a
   section head. Buttons, not a new pill: one button component on the site. */
.svm-chip-row{display:flex;flex-wrap:wrap;gap:12px;margin:0 0 clamp(32px,4vw,48px)}
/* the archive filter: the chosen chip fills, the grid narrows to that service. */
.svm-chip-row .svm-btn--outline.is-on{background:var(--ink);color:var(--svm-cream);border-color:var(--ink)}
.svm-cs-empty{grid-column:1 / -1;font-family:var(--f-mono);font-size:var(--fs-mono);letter-spacing:var(--ls-mono);text-transform:uppercase;font-weight:600;color:var(--muted);margin:0;padding:24px 0}

/* a button row centered under a grid, for a Load more or a single closing link */
.svm-cta-row--center{justify-content:center;margin-top:clamp(40px,5vw,56px)}

/* -- .svm-faq ------------------------------------------------------------- */
/* Native details and summary. No script: the browser owns the open state.
   The question is General Sans 600 at 18px with a Lucide chevron-down that
   rotates 180 degrees when the item opens. Put .svm-faq on a .svm-prose column
   so the answers take the prose paragraph role. */
/* the questions span the whole grid track, so the rules run to the side rail.
   The answers keep a 68ch measure of their own. */
.svm-faq{max-width:none}
.svm-faq > details{border-top:1px solid var(--rule)}
.svm-faq > details:last-of-type{border-bottom:1px solid var(--rule)}
.svm-faq summary{
  list-style:none;cursor:pointer;
  display:grid;grid-template-columns:minmax(0,1fr) 24px;align-items:center;gap:16px;
  padding:20px 0;
  font-family:var(--f-display);font-weight:600;font-size:18px;line-height:1.35;
  letter-spacing:var(--ls-tight);color:var(--ink);
  transition:color var(--dur-fast) var(--ease-out);
}
.svm-faq summary::-webkit-details-marker{display:none}
.svm-faq summary::marker{content:""}
.svm-faq summary:hover{color:var(--svm-teal-deep)}
.svm-faq__chev{
  width:24px;height:24px;display:block;fill:none;stroke:var(--svm-navy);
  stroke-width:1.75;stroke-linecap:round;stroke-linejoin:round;
  transition:transform var(--dur-med) var(--ease-out);
}
.svm-faq details[open] .svm-faq__chev{transform:rotate(180deg)}
.svm-faq details > p{margin:0 0 var(--sp-6);max-width:68ch}
@media (prefers-reduced-motion:reduce){
  .svm-faq__chev{transition:none}
}

/* -- .svm-form ------------------------------------------------------------ */
/* Native inputs, no framework. Label role above each field, white ground,
   hairline border that goes teal-ink on hover, 4px radius. The system focus
   ring from block 3 is what marks focus, so no border color change there. */
.svm-form{display:flex;flex-direction:column;gap:var(--sp-4)}
.svm-form__row{display:grid;grid-template-columns:1fr 1fr;gap:var(--sp-4)}
.svm-form label{
  display:block;margin-bottom:8px;
  font-family:var(--f-mono);font-size:var(--fs-mono);letter-spacing:var(--ls-mono);
  text-transform:uppercase;font-weight:600;color:var(--muted);
}
.svm-form :is(input,textarea){
  width:100%;display:block;
  font-family:var(--f-body);font-size:16px;line-height:1.4;color:var(--ink);
  background:var(--svm-white);border:1px solid var(--rule);border-radius:var(--r-sm);
  padding:13px 14px;
  transition:border-color var(--dur-fast) var(--ease-out);
}
.svm-form :is(input,textarea):hover{border-color:var(--svm-teal-ink)}
.svm-form ::placeholder{color:rgba(var(--svm-navy-rgb),.45);opacity:1}
.svm-form textarea{resize:vertical;min-height:132px}
.svm-form button.svm-btn{appearance:none;-webkit-appearance:none;border:0;cursor:pointer;align-self:flex-start}
@media (max-width:600px){
  .svm-form__row{grid-template-columns:1fr}
  .svm-form button.svm-btn{align-self:stretch}
}

/* -- Gravity Forms ------------------------------------------------------- */
/* GF outputs no CSS of its own on this site (rg_gforms_disable_css). These rules
   give its markup the .svm-form look. A GF embed sits in a .svm-form shell in
   Bricks (shortcode element), so the two share one recipe. */
.gform_wrapper{width:100%;min-width:0}
.gform_wrapper .gform_heading{margin:0 0 12px}
.gform_wrapper .gform_required_legend{font-family:var(--f-mono);font-size:11px;letter-spacing:1px;color:var(--muted);margin:0}
.gform_wrapper .gform_fields{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));gap:var(--sp-4) 16px;margin:0;padding:0;list-style:none}
.gform_wrapper .gfield{grid-column:span 12;min-width:0;margin:0;padding:0;border:0}
.gform_wrapper .gfield--width-half{grid-column:span 6}
.gform_wrapper .gfield--width-third{grid-column:span 4}
.gform_wrapper .gfield--width-two-thirds{grid-column:span 8}
.gform_wrapper .gfield--width-quarter{grid-column:span 3}
.gform_wrapper .gfield--type-honeypot,
.gform_wrapper .gform_validation_container,
.gform_wrapper .gfield_visibility_hidden{display:none!important}
.gform_wrapper .gfield_label,
.gform_wrapper legend.gfield_label{display:block;margin-bottom:8px;
  font-family:var(--f-mono);font-size:var(--fs-mono);letter-spacing:var(--ls-mono);
  text-transform:uppercase;font-weight:600;color:var(--muted);padding:0;width:auto}
.gform_wrapper .gfield_required{color:var(--svm-coral);margin-left:3px}
.gform_wrapper .gfield--type-section .gsection_title{font-family:var(--f-display);font-size:20px;font-weight:600;margin:12px 0 0;padding-bottom:10px;border-bottom:1px solid var(--rule)}
.gform_wrapper :is(input[type=text],input[type=email],input[type=tel],input[type=number],input[type=url],input[type=date],input[type=file],select,textarea){width:100%;display:block;
  font-family:var(--f-body);font-size:16px;line-height:1.4;color:var(--ink);
  background:var(--svm-white);border:1px solid var(--rule);border-radius:var(--r-sm);
  padding:13px 14px;
  transition:border-color var(--dur-fast) var(--ease-out)}
.gform_wrapper :is(input,select,textarea):hover{border-color:var(--svm-teal-ink)}
.gform_wrapper :is(input,select,textarea):focus-visible{outline:2px solid var(--svm-teal);outline-offset:1px}
.gform_wrapper ::placeholder{color:rgba(var(--svm-navy-rgb),.45);opacity:1}
.gform_wrapper textarea{min-height:132px;resize:vertical}
.gform_wrapper select{appearance:none;-webkit-appearance:none;padding-right:40px;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23023C5B' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 14px center;background-size:16px}
.gform_wrapper input[type=file]{padding:10px 14px;font-size:14px}
/* first/last, city/state: two columns, sublabel under the box */
.gform_wrapper .ginput_complex{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px 16px}
.gform_wrapper .ginput_complex > span{display:flex;flex-direction:column;gap:6px;min-width:0}
.gform_wrapper .ginput_complex > span.ginput_full{grid-column:span 2}
.gform_wrapper .gform-field-label--type-sub{font-family:var(--f-mono);font-size:10px;letter-spacing:1.2px;text-transform:uppercase;font-weight:600;color:var(--muted);margin:0}
.gform_wrapper .gfield_description{font-size:13px;line-height:1.5;color:var(--muted);margin-top:6px}
/* choices */
.gform_wrapper :is(.gfield_checkbox,.gfield_radio){display:flex;flex-direction:column;gap:8px;margin:0;padding:0;list-style:none}
.gform_wrapper :is(.gchoice,.ginput_container_consent){display:flex;gap:10px;align-items:flex-start;font-size:15px;color:var(--ink)}
/* choice labels are sentence case body type, not the mono field label */
.gform_wrapper .gchoice{padding:5px 0;align-items:center;gap:12px}
.gform_wrapper .gchoice label,
.gform_wrapper .gfield_consent_label,
.svm-form .gform_wrapper .gchoice label,
.svm-form .gform_wrapper .gfield_consent_label{font-family:var(--f-body);font-size:16px;line-height:1.4;letter-spacing:0;text-transform:none;font-weight:500;color:var(--ink);margin:0;display:block}
.gform_wrapper :is(input[type=checkbox],input[type=radio]){width:20px;height:20px;flex:none;margin:0;accent-color:var(--svm-teal-ink)}
.gform_wrapper :is(.gfield_checkbox,.gfield_radio){gap:2px}
/* submit */
.gform_wrapper .gform_footer{margin:var(--sp-4) 0 0;padding:0;display:flex;align-items:center;gap:12px}
.gform_wrapper .gform_button{position:relative;display:inline-flex;align-items:center;gap:10px;
  padding:15px 24px;border-radius:var(--r-sm);text-decoration:none;
  font-family:var(--f-mono);font-size:12px;letter-spacing:var(--ls-mono);
  text-transform:uppercase;font-weight:600;line-height:1;
  transition:transform var(--dur-fast) var(--ease-out),
             box-shadow var(--dur-fast) var(--ease-out),
             background var(--dur-fast),color var(--dur-fast);background:var(--svm-teal);color:var(--svm-navy);appearance:none;-webkit-appearance:none;border:0;cursor:pointer}
.gform_wrapper .gform_button:hover{filter:brightness(.95)}
.gform_wrapper .gform_ajax_spinner{width:20px;height:20px}
/* validation and confirmation */
.gform_wrapper .gform_validation_errors{grid-column:span 12;background:rgba(var(--svm-coral-rgb,240,128,112),.12);border:1px solid var(--svm-coral);border-radius:var(--r-sm);padding:14px 16px;margin:0 0 var(--sp-4)}
.gform_wrapper .gform_submission_error{font-family:var(--f-body);font-size:15px;font-weight:600;margin:0;color:var(--ink)}
.gform_wrapper .gform_validation_errors ol{margin:8px 0 0 18px;padding:0;font-size:14px}
.gform_wrapper .gfield_error :is(input,select,textarea){border-color:var(--svm-coral)}
.gform_wrapper .validation_message{font-size:13px;color:var(--svm-coral);margin-top:6px}
.gform_confirmation_wrapper .gform_confirmation_message{font-size:18px;line-height:1.5}
@media (max-width:600px){
  .gform_wrapper :is(.gfield--width-half,.gfield--width-third,.gfield--width-two-thirds,.gfield--width-quarter){grid-column:span 12}
  .gform_wrapper .ginput_complex{grid-template-columns:1fr}
  .gform_wrapper .ginput_complex > span.ginput_full{grid-column:auto}
  .gform_wrapper .gform_button{width:100%;justify-content:center}
}

/* -- .svm-card--tile ------------------------------------------------------- */
/* A card that centers one piece of artwork or one short message instead of the
   usual heading-and-paragraph stack: a logo, a map, an embed stand-in. Still a
   .svm-card, so there is no second tile component. */
.svm-card--tile{align-items:center;justify-content:center;text-align:center;gap:18px}
.svm-card--tile img{width:auto;max-width:100%;max-height:110px;object-fit:contain}
.svm-card--tile .svm-map{width:auto;height:auto;max-width:min(340px,100%);max-height:320px}
.svm-card--tile p{flex:none}

/* .svm-card--embed: a tile standing in for a third-party embed the static build
   cannot render. Always with .svm-card--tile. */
.svm-card--embed{min-height:640px}

@media (max-width:600px){
  .svm-card--tile .svm-map{max-height:260px}
}


/* --------------------------------------------------------------------------
   23. CASE STUDY TEMPLATE
   Added 2026-09-02 (brief 10). Model: SVM's own one-page case study PDF,
   Coastal Stone, December 2024.

   A case study single is NOT a fixed story. It is an ordered set of OPTIONAL
   blocks, and any study may use any subset of them in any count. Every block
   renders only when its data exists. In Bricks each block carries a condition
   on its own field, so an empty field removes the block instead of leaving a
   heading over nothing. The block list and the field model are in
   CASE-STUDY-FIELDS.md.

     .svm-cs-hero      chip, logo, client name, meta row, collage
     .svm-cs-headline  the headline metric, its sub-lines and an optional donut
     .svm-cs-tiles     stat tiles, one to six, plus the --stack column variant
     .svm-cs-chart     a standalone bar or donut chart
     .svm-cs-table     a data table
     .svm-cs-story     label-left, copy-right rows, any count
     .svm-cs-quote     a client quote
     .svm-cs-gallery   an image grid

   CHART RULES. One hue family only, teal through light teal, no second hue and
   no gradient. Every chart is inline SVG with role="img" and a title plus a
   description, so it reads without color. The dataviz validator was run on the
   segment pair on 2026-09-02: as a CATEGORICAL palette #8FD4D4 and #E3F5F5 fail
   the normal-vision separation floor at delta E 14.2 and warn on contrast. They
   are used here as a two step SEQUENTIAL ramp, which is monotonic in lightness
   and in scope, and the required relief is built in: a navy hairline on every
   segment edge, a gap between segments, and a direct label on every value in
   the dotted sub-lines. Never use this pair as a categorical palette.
   -------------------------------------------------------------------------- */

/* -- .svm-grid--1 --------------------------------------------------------- */
/* The count modifier for a set of one. A card grid always fills its rows, so a
   set of one fills the row across all twelve columns: no orphan, no empty cell.
   It completes the family in block 6. A tile row or a gallery of one uses it. */
.svm-grid--1 > *{grid-column:span 12}

/* -- .svm-cs-hero --------------------------------------------------------- */
/* Copy left, the creative collage right. Everything except the client name is
   optional: no logo, no meta line, no services and no collage still leaves a
   correct hero. */
.svm-cs-hero{--cs-gap:clamp(20px,2.5vw,40px);position:relative;display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.25fr);gap:var(--cs-gap);align-items:end}
.svm-cs-hero > .svm-hero__copy{align-self:center}
/* The client's own logo, never cropped and never recolored. Above 860 it is
   lifted out of the copy column to the top right corner of the hero, level with
   the "Case study" chip, so the h1 sits directly under the chip. It stays in
   the copy in the DOM, so under 860 it drops back into flow under the chip at
   the left with no duplicate markup. */
.svm-cs-hero__logo{width:auto;max-width:180px;max-height:64px;object-fit:contain}
@media (min-width:861px){
  /* .svm-hero__copy is itself positioned, so it is the containing block. The
     right column is 1.25 times the copy column, so pushing the logo right by
     125% of the copy plus the grid gap lands its right edge exactly on the
     hero's right edge. No magic number, and it tracks the column ratio. */
  .svm-cs-hero__logo{position:absolute;top:0;right:calc(-125% - var(--cs-gap));z-index:3;margin:0}
}
@media (max-width:860px){
  .svm-cs-hero__logo{max-width:140px;margin:0 0 var(--sp-5)}
}
/* the "Case study" chip. Coral ground, white text: the same treatment the New
   chip on the homepage widget carries, because small UI is the accent's job.
   The PDF's light teal pill has nothing to sit against once the ground is light
   teal. Jamie, 2026-09-02. */
.svm-cs-chip{display:inline-block;background:var(--svm-coral);color:var(--svm-white);padding:8px 14px;border-radius:var(--r-sm)}
.svm-hero__copy > .svm-cs-chip{margin-bottom:var(--sp-5)}
.svm-hero__copy .svm-mono + .svm-chip-row{margin-top:var(--sp-5)}
.svm-hero__copy > .svm-chip-row:last-child{margin-bottom:0}

/* -- .svm-cs-hero__collage ------------------------------------------------ */
/* ONE image. The collage is composed in design and delivered as a single
   pre-fanned asset, so the page places one <img> and nothing else: no per-image
   markup, no CSS fan, no tilt. Right column, bottom anchored, about 620px wide
   at 1440. The wrap's own bottom padding is cancelled and the image is pulled
   further, so its lower part runs under the section edge; .svm-hero clips it,
   which is why the collage can never widen the document. Jamie, 2026-09-02. */
.svm-cs-hero__collage{
  align-self:end;justify-self:end;min-width:0;
  margin-bottom:calc(-1 * (clamp(40px,5vw,72px) + clamp(14px,3.4vw,50px)));
}
.svm-cs-hero__collage img{width:clamp(280px,43vw,620px);height:auto}

/* -- .svm-cs-headline ----------------------------------------------------- */
/* The headline metric. Donut left when there is one, the value and its label in
   the middle, the two-tile stack right when there is one. Any of the three may
   be absent: the grid is declared by what is present. */
.svm-cs-headline{display:grid;grid-template-columns:minmax(0,1fr);gap:clamp(28px,4vw,56px);align-items:center}
.svm-cs-headline:has(.svm-cs-donut){grid-template-columns:auto minmax(0,1fr)}
.svm-cs-headline:has(.svm-cs-tiles--stack){grid-template-columns:minmax(0,1fr) minmax(240px,.6fr)}
.svm-cs-headline:has(.svm-cs-donut):has(.svm-cs-tiles--stack){grid-template-columns:auto minmax(0,1fr) minmax(240px,.6fr)}
.svm-cs-headline__body{display:flex;flex-direction:column;gap:var(--sp-2);min-width:0}
/* the value takes .svm-num, the site's display-number role. Calluna italic is
   correct here because these are VALUES, not counts: the "cards never count"
   rule bans a numbered card grid and this is not one. */
.svm-cs-headline .svm-num{font-size:clamp(56px,7vw,96px);line-height:.92}
.svm-cs-headline .svm-section-h{margin:0}

/* -- .svm-cs-subs --------------------------------------------------------- */
/* Up to four sub-lines under the headline value. Each is a dot plus an italic
   note, and each is the direct label for a donut segment when a donut is
   present, so identity is never carried by color alone. */
.svm-cs-subs{list-style:none;margin:var(--sp-4) 0 0;padding:0;display:flex;flex-direction:column;gap:10px}
.svm-cs-sub{
  display:flex;align-items:center;gap:12px;
  font-family:var(--f-italic);font-style:italic;font-weight:400;
  font-size:19px;line-height:1.3;color:var(--ink);font-variation-settings:"SOFT" 80;
}
.svm-cs-sub::before{content:"";width:15px;height:15px;flex:none;border-radius:var(--r-pill);background:var(--svm-teal);border:1px solid var(--svm-navy)}
.svm-cs-sub--light::before{background:var(--svm-teal-light)}
.svm-cs-sub--navy::before{background:var(--svm-navy)}
/* A white segment, for a donut drawn on a light teal band, where light teal on
   light teal would have no edge. On the cream band the pair is teal and light
   teal, as the PDF draws it. */
.svm-cs-sub--white::before{background:var(--svm-white)}

/* -- .svm-cs-donut -------------------------------------------------------- */
/* Inline SVG, drawn from the sub-line values. Teal and light teal segments on a
   navy hairline, no legend box: the dotted sub-lines beside it are the legend.
   No gradient, no drop shadow, no third dimension. */
.svm-cs-donut{width:clamp(148px,15vw,208px);height:auto;display:block;flex:none}

/* -- .svm-cs-tiles and .svm-cs-tile --------------------------------------- */
/* A stat tile: label, value, note. The row form is .svm-grid plus the count
   modifier, one to six. The stack form is the same tile in a single column,
   for the position beside the headline metric. */
.svm-cs-tiles{align-items:stretch}
.svm-cs-tiles--stack{display:grid;grid-template-columns:minmax(0,1fr);gap:20px;align-content:center}
/* Every tile is white. The whole metrics band is light teal, so a tile always
   has an edge without needing a rule or a shadow. */
.svm-cs-tile{background:var(--card);border-radius:var(--r-sm);padding:26px 24px;display:flex;flex-direction:column;gap:6px;transition:transform var(--dur-med) var(--ease-out)}
.svm-cs-tile:hover{transform:translateY(-2px)}
.svm-cs-tile__label{font-family:var(--f-display);font-weight:600;font-size:16px;line-height:1.25;letter-spacing:var(--ls-tight);color:var(--ink);margin:0}
.svm-cs-tile__value{font-family:var(--f-italic);font-style:italic;font-weight:700;font-size:40px;line-height:1;letter-spacing:var(--ls-tight);color:var(--ink);margin:0}
.svm-cs-tile__note{font-family:var(--f-italic);font-style:italic;font-weight:400;font-size:16px;line-height:1.35;color:var(--muted);margin:0;font-variation-settings:"SOFT" 80}

/* the metric blocks stack inside one band with a single rhythm, so a study may
   run a headline, a tile row and a chart together without a wrapper class. */
:is(.svm-cs-headline,.svm-cs-tiles,.svm-cs-chart) + :is(.svm-cs-headline,.svm-cs-tiles,.svm-cs-chart){margin-top:clamp(36px,4.5vw,64px)}

/* -- .svm-cs-chart -------------------------------------------------------- */
/* A standalone chart: a title in the section-head role and one inline SVG.
   A bar is a solid teal fill with a 4px radius and NO stroke. There is no axis,
   no baseline, no grid and no legend. The label sits above each bar in the
   label role and the value sits at the bar's end in Calluna italic, so every
   value is read directly off the mark.
   .svm-cs-chart__note is an OPTIONAL source note and is empty by default.
   Never write an explanatory or apologetic note into page copy: a caveat about
   the data belongs in the build report, not on the page. Jamie, 2026-09-02. */
.svm-cs-chart{display:flex;flex-direction:column;gap:var(--sp-5);max-width:820px}
.svm-cs-chart svg{width:100%;height:auto;display:block}
.svm-cs-chart__note{font-size:13px;line-height:1.5;color:var(--muted);margin:0}

/* -- .svm-cs-table -------------------------------------------------------- */
/* An optional data table. It is .svm-table inside .svm-table-wrap, which is
   already the site's table; this only holds the block's measure and its title. */
.svm-cs-table{max-width:820px}
.svm-cs-table > .svm-mono{color:var(--muted);margin:0 0 var(--sp-5)}

/* -- .svm-cs-story -------------------------------------------------------- */
/* The narrative. A repeater of rows: the label on the left, the copy on the
   right. The labels are the study's own, usually Objectives, Solutions and
   Results, and a study may run any number of rows under any labels. Native
   bullets, because the copy is a list when the study writes a list. */
.svm-cs-story{display:flex;flex-direction:column}
.svm-cs-story__row{display:grid;grid-template-columns:200px minmax(0,1fr);gap:clamp(24px,4vw,56px);padding:clamp(28px,4vw,44px) 0;border-top:1px solid var(--rule)}
.svm-cs-story__row:first-child{border-top:0;padding-top:0}
.svm-cs-story__row:last-child{padding-bottom:0}
.svm-cs-story__label{font-family:var(--f-mono);font-size:14px;letter-spacing:var(--ls-mono);text-transform:uppercase;font-weight:600;color:var(--svm-navy);margin:0}
.svm-cs-story__body{min-width:0}
.svm-cs-story__body :is(p,ul,ol){margin:0 0 var(--sp-5);color:var(--muted);font-size:16px;line-height:1.6;max-width:68ch}
.svm-cs-story__body :is(ul,ol){padding-left:22px}
.svm-cs-story__body li{margin-bottom:10px}
.svm-cs-story__body > :last-child{margin-bottom:0}
@media (max-width:768px){
  .svm-cs-story__row{grid-template-columns:minmax(0,1fr);gap:var(--sp-4)}
}

/* -- .svm-cs-quote -------------------------------------------------------- */
/* The client quote. It is .svm-quote, the site's review card, on cream instead
   of white, so there is no second quote component. Never put it on a cream
   band: a cream tile on a cream ground has no edge. */
.svm-cs-quote{background:var(--svm-cream)}

/* -- .svm-cs-gallery ------------------------------------------------------ */
/* A count-aware image grid of plain <img> elements. .svm-grid > img already
   gives each one its track and the 4px radius, with no crop, because a case
   study asset is usually a composite a cover crop would cut into. The hairline
   is what keeps a white-backed asset from bleeding into a light ground. */
.svm-cs-gallery > img{box-shadow:0 0 0 1px rgba(var(--svm-navy-rgb),.1)}

/* -- responsive ----------------------------------------------------------- */
@media (max-width:1024px){
  .svm-cs-headline,
  .svm-cs-headline:has(.svm-cs-donut),
  .svm-cs-headline:has(.svm-cs-tiles--stack),
  .svm-cs-headline:has(.svm-cs-donut):has(.svm-cs-tiles--stack){grid-template-columns:minmax(0,1fr);justify-items:start}
  .svm-cs-tiles--stack{grid-template-columns:repeat(2,minmax(0,1fr));width:100%}
}
@media (max-width:860px){
  .svm-cs-hero{grid-template-columns:minmax(0,1fr)}
  .svm-cs-hero__collage{justify-self:center;margin-bottom:calc(-1 * (clamp(40px,5vw,72px) + clamp(12px,3vw,34px)))}
  .svm-cs-hero__collage img{width:min(100%,520px)}
}
@media (max-width:600px){
  .svm-cs-tiles--stack{grid-template-columns:minmax(0,1fr)}
  .svm-cs-sub{font-size:17px}
}
@media (prefers-reduced-motion:reduce){
  .svm-cs-tile{transition:none}
}

/* -- the label role inside a card ----------------------------------------- */
/* BUILD FIX, 2026-09-02. .svm-card p sets 15px for a card's body copy and
   outranks .svm-mono, so every label inside a card was silently rendering at
   15px tracked caps instead of the label role's 11px. The label role has one
   size and a card is not an exception. Font size only: the flex behaviour of a
   card's children is left alone so no card's vertical rhythm moves.
   Also affects post.html, awards.html and schedule-a-meeting.html, all
   re-checked in the same pass. */
.svm-card .svm-mono{font-size:var(--fs-mono);line-height:1.4}

/* -- a post card that carries a description ------------------------------- */
/* .svm-post__body already styles the label role and the title. A case study
   card adds one line of the study's own copy between them and the read link.
   Same paragraph role .svm-card p uses, so a description reads the same in
   either card. Put .svm-split__excerpt on it to hold the card to two lines. */
.svm-post__body > p:not(.svm-mono){margin:0;font-size:15px;line-height:1.55;color:var(--muted)}

/* -- a gallery image ------------------------------------------------------ */
/* A plain <img> as a direct child of .svm-grid keeps its own ratio, fills its
   track and takes the 4px radius. Unlike .svm-duo and .svm-post there is no
   crop. */
.svm-grid > img{width:100%;border-radius:var(--r-sm)}


/* --------------------------------------------------------------------------
   24. PAGINATION
   Added 2026-09-02. Replaces the Load more button on the blog archive. In
   Bricks this is the query loop's pagination element.
   -------------------------------------------------------------------------- */

/* A centered row under a card grid. Previous and Next are the site's outline
   button at the ends. The page numbers between them are the same button in a
   44px round form, which is the one place a button is not a rectangle: a page
   number is a single glyph and a rectangle around it reads as a chip.
   The current page is filled teal with navy text, the same pairing
   .svm-btn--primary uses, and carries aria-current="page".
   Every item is a real anchor. Nothing here needs script. */
.svm-pagination{
  display:flex;align-items:center;justify-content:center;flex-wrap:wrap;
  gap:10px;margin-top:clamp(40px,5vw,56px);
}
.svm-pagination__pages{display:flex;align-items:center;gap:10px}
/* Previous and Next take the number row's 44px height, so the ends of the row
   line up with the round buttons between them. */
.svm-pagination > .svm-btn{height:44px;padding-top:0;padding-bottom:0}
.svm-pagination__num{
  width:44px;height:44px;padding:0;justify-content:center;border-radius:var(--r-pill);
}
.svm-pagination__num[aria-current="page"]{background:var(--svm-teal);color:var(--svm-navy);border-color:var(--svm-teal)}
/* the gap where pages are skipped. Not a link and not focusable. */
.svm-pagination__gap{
  width:44px;text-align:center;color:var(--muted);
  font-family:var(--f-mono);font-size:var(--fs-mono);letter-spacing:var(--ls-mono);font-weight:600;
}
/* Under 600 the row keeps Previous, Next, the current page and its two
   neighbours. Everything else in the number list is hidden, so a long archive
   never pushes the row onto three lines or past the gutter. */
@media (max-width:600px){
  .svm-pagination{gap:8px}
  .svm-pagination__pages > *{display:none}
  .svm-pagination__pages > [aria-current="page"],
  .svm-pagination__pages > [aria-current="page"] + *,
  .svm-pagination__pages > :has(+ [aria-current="page"]){display:flex}
  .svm-pagination__pages > .svm-pagination__gap{display:none}
}

/* -- the cursor ------------------------------------------------------------ */
/* A coral arrow with a white outline, so it reads on every ground including
   coral. Links and buttons get the same arrow with a small ring at the tail.
   Mouse devices only; touch and pen never see a cursor. Text fields keep the
   I-beam. Hotspot 6 6 is the arrow tip. Jamie, 2026-09-02. */
@media (hover:hover) and (pointer:fine){
  html,body{
    cursor:url(../img/cursor/arrow.png) 6 6,auto;
    cursor:image-set(url(../img/cursor/arrow.png) 1x,url(../img/cursor/arrow@2x.png) 2x) 6 6,auto;
  }
  a,button,[role="button"],label,select,summary,
  .svm-btn,.svm-nav__dd-btn,.svm-menu__acc,.svm-menu-btn,.svm-process__step,.svm-chip-row a,.svm-post,.svm-svc{
    cursor:url(../img/cursor/pointer.png) 6 6,pointer;
    cursor:image-set(url(../img/cursor/pointer.png) 1x,url(../img/cursor/pointer@2x.png) 2x) 6 6,pointer;
  }
  input:not([type="submit"]):not([type="button"]):not([type="checkbox"]):not([type="radio"]):not([type="file"]),textarea,[contenteditable]{cursor:text}
  input[type="checkbox"],input[type="radio"],input[type="submit"],input[type="button"],.gform_wrapper .gform_button{
    cursor:url(../img/cursor/pointer.png) 6 6,pointer;
    cursor:image-set(url(../img/cursor/pointer.png) 1x,url(../img/cursor/pointer@2x.png) 2x) 6 6,pointer;
  }
}

/* -- text selection --------------------------------------------------------- */
/* Teal highlight with navy text on the light grounds; the navy surfaces flip
   it so selected text stays legible on the header, the menu sheet, the band
   and the footer. Jamie, 2026-09-02. */
::selection{background:var(--svm-teal);color:var(--svm-navy)}
::-moz-selection{background:var(--svm-teal);color:var(--svm-navy)}
:is(.svm-nav,.svm-menu,.svm-topbar,.svm-section--dark,.svm-footer) ::selection{background:var(--svm-teal);color:var(--svm-navy)}
img::selection{background:rgba(var(--svm-teal-rgb),.4)}
