/* ==========================================================================
   Spectrum Veterinary Imaging — shared stylesheet
   Display type: Source Serif 4. Body type: IBM Plex Sans. Both self-hosted, both
   variable woff2.
   Palette is sampled from the client-supplied Spectrum Veterinary Imaging logo.
   ========================================================================== */

/* --- Self-hosted faces ---------------------------------------------------- */
/* Variable woff2, one file per style, covering the whole weight range instead of
   three fixed cuts each. 316 KB of fonts against 865 KB of static TTF before.
   The italic is a real file, not a synthesised slant: most headings set their
   second line in <em>, and a browser-obliqued serif looks broken. */
@font-face{font-family:'Source Serif 4';font-style:normal;font-weight:200 900;font-display:swap;src:url(/assets/fonts/display.woff2) format('woff2')}
@font-face{font-family:'Source Serif 4';font-style:italic;font-weight:200 900;font-display:swap;src:url(/assets/fonts/display-italic.woff2) format('woff2')}
@font-face{font-family:'IBM Plex Sans';font-style:normal;font-weight:100 700;font-display:swap;src:url(/assets/fonts/body.woff2) format('woff2')}

/* --- Tokens --------------------------------------------------------------- */
:root{
  --brand:#00a8e4;
  --brand-dark:#0078a8;
  --brand-deep:#005478;
  --navy:#00486c;
  --navy-deep:#062f45;
  --ink:#0f2a38;
  /* Secondary text was #4a6270 — too pale at this size. Darkened for contrast. */
  --ink-soft:#3c5464;
  --line:#cfdce4;
  --line-strong:#aec4d1;
  --line-soft:#e4edf2;
  --bg:#ffffff;
  --bg-tint:#eff6fa;
  --bg-panel:#f8fbfc;
  --bg-deep:#062f45;
  --white:#fff;

  /* David, 18 Sept: "I think it's very white... introduce other further colours
     beyond the blues". A warm sand band alternates with the existing blue tint so
     a long page reads in three background tones rather than two, and a copper
     accent carries the small marks. Copper is the complement of the brand blue
     (hue 196 -> 16), desaturated to sit under it rather than compete. Both are
     held to the same 4.5:1 floor the existing tint already sits at: brand-dark
     on --sand is 4.51, --accent on --sand is 5.25. */
  --sand:#f8f4ee;
  --sand-line:#e6dccd;
  --accent:#9c5228;
  --accent-soft:#c98a5e;

  --display:'Source Serif 4',Georgia,'Times New Roman',serif;
  --body:'IBM Plex Sans',-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif;

  --wrap:1220px;
  --gutter:clamp(20px,5vw,64px);
  --radius:4px;
  /* Vertical rhythm tightened: the old scale left ~250px voids between blocks. */
  --section-y:clamp(46px,5.4vw,84px);
  --shadow:0 1px 2px rgba(6,47,69,.05),0 6px 18px rgba(6,47,69,.07);
  --shadow-lg:0 2px 4px rgba(6,47,69,.06),0 16px 40px rgba(6,47,69,.13);
  /* A visible container edge, used on every panel and card. */
  --edge:1px solid var(--line);
  --edge-strong:1.5px solid var(--line-strong);
}

/* --- Reset ---------------------------------------------------------------- */
*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{
  margin:0;background:var(--bg);color:var(--ink);
  font-family:var(--body);font-size:17px;line-height:1.65;
  font-weight:400;-webkit-font-smoothing:antialiased;
  overflow-x:hidden;
}
img{max-width:100%;height:auto;display:block}
button{font:inherit;color:inherit}
a{color:var(--brand-dark);text-decoration-thickness:1px;text-underline-offset:3px}
/* The resting link colour (--brand-dark, 4.94:1 on white) already passed. Hover
   brightened to --brand, which measures 2.72:1 on a light background and fails.
   --brand-dark stays on hover too: the underline and any component-level hover
   affordance (translateY, border, background) still signal interactivity. Three
   components reuse this brand-on-hover pattern deliberately on dark backgrounds
   where --brand already passes (5.15:1 on navy-deep) -- .contact-card's tel/mail
   links, .footer-brand and .footer-bottom -- and are left as they were. */
a:hover{color:var(--brand-dark)}
:focus-visible{outline:3px solid var(--brand);outline-offset:3px;border-radius:2px}
hr{border:0;border-top:1px solid var(--line)}

h1,h2,h3{
  font-family:var(--display);font-weight:600;
  line-height:1.08;letter-spacing:-.005em;margin:0;
  color:var(--navy-deep);text-wrap:balance;
}
h1{font-size:clamp(2.3rem,5vw,3.7rem)}
h2{font-size:clamp(1.8rem,3.3vw,2.6rem)}
h3{font-size:clamp(1.18rem,1.8vw,1.38rem);line-height:1.2}
h1 em,h2 em,h3 em{font-style:italic;color:var(--brand-dark);font-weight:400}
p{margin:0 0 1.25em}
p:last-child{margin-bottom:0}

/* --- Shared helpers ------------------------------------------------------- */
.lead{font-size:clamp(1.1rem,1.5vw,1.3rem);line-height:1.6;color:var(--ink-soft);max-width:56ch}
.large-text{
  font-family:var(--display);font-size:clamp(1.4rem,2.2vw,1.8rem);line-height:1.3;
  color:var(--navy-deep);font-weight:600;letter-spacing:-.015em;
}
/* The opening answer under each heading. Given a brand rule so the eye lands on
   it first — this is the sentence that carries the page. */
.prose > .large-text{
  border-left:4px solid var(--brand);padding-left:1.1rem;margin-bottom:1.3rem;
}
.small-note{
  font-size:.86rem;color:var(--ink-soft);line-height:1.55;
  background:var(--bg-panel);border:var(--edge);border-radius:var(--radius);
  padding:.7em .9em;
}
.prose{max-width:62ch}
.prose > :last-child{margin-bottom:0}

/* Arrow glyph used inside buttons and text links */
.arrow{display:inline-block;width:1em;height:1em;margin-left:.5em;vertical-align:-.08em;flex:none;position:relative}
.arrow::before{
  content:"";position:absolute;inset:0;
  background:currentColor;
  -webkit-mask:no-repeat center/100% url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M1 8h12M9 4l4 4-4 4' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  mask:no-repeat center/100% url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M1 8h12M9 4l4 4-4 4' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  transition:transform .25s ease;
}
a:hover .arrow::before,button:hover .arrow::before{transform:translateX(3px)}

/* --- Buttons -------------------------------------------------------------- */
.button{
  display:inline-flex;align-items:center;justify-content:center;
  font-family:var(--body);font-weight:600;font-size:.94rem;
  letter-spacing:.01em;padding:.85em 1.5em;border-radius:var(--radius);
  border:1px solid transparent;text-decoration:none;cursor:pointer;
  transition:background .2s ease,color .2s ease,border-color .2s ease,box-shadow .2s ease;
  line-height:1.2;text-align:center;
}
/* Audit, 23 September: white on this blue measures 2.72:1, failing WCAG 1.4.3's
   4.5:1 floor for normal text -- verified independently, matches the report.
   Fill stays the brand colour; text goes to navy-deep instead, which passes at
   5.15:1. The hover state already swaps to a darker fill with white text
   (4.94:1) and was already passing, so it is untouched. */
.button.primary{background:var(--brand);color:var(--navy-deep);border-color:var(--brand)}
.button.primary:hover{background:var(--brand-dark);border-color:var(--brand-dark);color:var(--white)}
.plain{
  background:none;border:0;padding:0;cursor:pointer;
  font-weight:500;font-size:.94rem;color:var(--brand-dark);
  text-decoration:underline;text-underline-offset:3px;
}
.plain:hover{color:var(--brand)}
/* .plain's one light-background use is the "Copy enquiry text" button on the
   contact form; --brand there is 2.72:1 on white and fails WCAG 1.4.3. The
   footer's cookie-information button (line ~792) sits on navy-deep, where
   --brand already passes at 5.15:1, and is untouched. */
.enquiry-card .plain:hover{color:var(--brand-dark)}
.text-link{
  display:inline-flex;align-items:center;font-weight:600;font-size:.94rem;
  color:var(--brand-dark);text-decoration:none;
  border-bottom:1px solid rgba(0,168,228,.35);padding-bottom:2px;
}
.text-link:hover{color:var(--brand-dark);border-bottom-color:var(--brand-dark)}
/* .text-link's one dark-background use, inside .contact-card, already passed
   (--brand on navy-deep is 5.15:1) and keeps its original hover colour. */
.contact-card .text-link:hover{color:var(--brand);border-bottom-color:var(--brand)}

/* --- Skip link ------------------------------------------------------------ */
.skip{
  position:absolute;left:-9999px;top:0;z-index:200;
  background:var(--navy-deep);color:var(--white);padding:.8em 1.2em;
  text-decoration:none;font-weight:600;
}
.skip:focus{left:8px;top:8px}
.skip:hover{color:var(--white)}

/* --- Header / nav --------------------------------------------------------- */
.site-header{
  position:sticky;top:0;z-index:100;background:var(--white);
  border-bottom:1px solid var(--line);
  display:flex;align-items:center;justify-content:space-between;gap:1.5rem;
  padding:.9rem var(--gutter);
}
.brand{display:inline-flex;align-items:center;flex:none}
/* Stacked lockup: the wordmark sits under the mark, so it needs real height to
   stay legible. "VETERINARY" and "IMAGING" are only 6.5% of the artwork's height,
   so at 76px they rendered under 5px tall and closed up. 86px puts them at 5.6px,
   which is the floor for a 1x display. Taken back 20% from 108px on 19 September:
   108 read as heavy once the top bar was gone. Phones go the other way, below. */
.brand img{width:auto;height:86px}
.site-footer .brand img{height:93px}

.menu-toggle{
  display:none;align-items:center;gap:.55rem;background:none;border:1px solid var(--line);
  border-radius:var(--radius);padding:.6em 1em;font-weight:600;font-size:.9rem;cursor:pointer;
  color:var(--navy-deep);
}
.plus{position:relative;display:inline-block;width:12px;height:12px;flex:none}
.plus::before,.plus::after{
  content:"";position:absolute;background:currentColor;border-radius:1px;transition:transform .25s ease,opacity .25s ease;
}
.plus::before{inset:5px 0 5px 0;height:2px}
.plus::after{inset:0 5px 0 5px;width:2px}
.menu-toggle[aria-expanded="true"] .plus::after{transform:rotate(90deg);opacity:0}

#main-nav{display:flex;align-items:center;gap:clamp(.6rem,1.6vw,1.9rem)}
/* :not(.button) matters here too — #main-nav's ID gives this more specificity
   than .button.primary's own color rules, so without the exclusion it pins the
   CTA to navy-deep text through hover, when the button's own :hover swaps to a
   darker fill that needs white text to stay readable. */
#main-nav > a:not(.button),.nav-dropdown > summary{
  font-weight:500;font-size:.96rem;color:var(--navy-deep);text-decoration:none;
  white-space:nowrap;padding:.4em 0;border-bottom:2px solid transparent;
}
#main-nav > a:not(.button):hover,.nav-dropdown > summary:hover{color:var(--brand-dark)}
/* :not(.button) matters — the "Refer a patient" CTA is also a nav link, and on
   /referrals/ it picks up aria-current. Without this it loses its white text. */
#main-nav > a:not(.button)[aria-current="page"]{color:var(--brand-dark);border-bottom-color:var(--brand)}
#main-nav > .button{white-space:nowrap;padding:.7em 1.25em;border-bottom:1px solid transparent}
#main-nav > .button[aria-current="page"]{box-shadow:inset 0 -3px 0 rgba(6,47,69,.35)}

.nav-dropdown{position:relative}
.nav-dropdown > summary{
  display:inline-flex;align-items:center;gap:.4rem;cursor:pointer;list-style:none;
}
.nav-dropdown > summary::-webkit-details-marker{display:none}
.chevron{
  width:9px;height:9px;border-right:1.8px solid currentColor;border-bottom:1.8px solid currentColor;
  transform:rotate(45deg) translate(-2px,-2px);transition:transform .25s ease;flex:none;
}
.nav-dropdown[open] > summary .chevron{transform:rotate(-135deg) translate(-2px,-2px)}
.nav-menu{
  position:absolute;top:calc(100% + 14px);left:50%;transform:translateX(-50%);
  min-width:280px;background:var(--white);border:1px solid var(--line);
  border-radius:var(--radius);box-shadow:var(--shadow-lg);padding:.5rem;
  display:flex;flex-direction:column;
}
.nav-menu a{
  padding:.7em .9em;border-radius:var(--radius);text-decoration:none;
  color:var(--navy-deep);font-size:.94rem;font-weight:500;
}
.nav-menu a:hover{background:var(--bg-tint);color:var(--brand-dark)}

/* --- Section scaffolding -------------------------------------------------- */
main{display:block}
.content-section{
  max-width:var(--wrap);margin-inline:auto;
  padding-block:var(--section-y);padding-inline:var(--gutter);
}
.content-section.two-col{
  display:grid;grid-template-columns:minmax(0,.72fr) minmax(0,1.28fr);
  gap:clamp(1.5rem,3vw,3rem);align-items:start;
}
/* The heading column used to run out halfway down, leaving a tall void beside
   the prose. Sticking it holds the pairing together while the prose scrolls. */
@media (min-width:861px){
  .content-section.two-col > div:first-child{position:sticky;top:130px}
}
/* Prose sits in a bordered panel so the section reads as a contained block
   rather than text floating on white. */
.content-section.two-col .prose{
  background:var(--bg-panel);border:var(--edge);border-radius:var(--radius);
  padding:clamp(1.4rem,2.5vw,2.1rem);max-width:none;box-shadow:var(--shadow);
}
.content-section.tinted,section.tinted{
  background:var(--bg-tint);max-width:none;
  border-block:1px solid var(--line-soft);
}
.content-section.tinted > *,section.tinted > *{max-width:var(--wrap);margin-inline:auto}
.section-heading{
  display:grid;grid-template-columns:minmax(0,1.15fr) minmax(0,.85fr);
  gap:clamp(1.5rem,4vw,4rem);align-items:end;margin-bottom:clamp(2rem,4vw,3.5rem);
}
.section-heading p{color:var(--ink-soft);margin:0;max-width:44ch}

/* --- Home hero ------------------------------------------------------------ */
.home-hero{
  max-width:var(--wrap);margin-inline:auto;
  padding-block:clamp(2rem,4vw,3.4rem) clamp(1.8rem,3vw,2.6rem);padding-inline:var(--gutter);
  display:grid;grid-template-columns:minmax(0,1.02fr) minmax(0,.98fr);
  gap:clamp(2rem,5vw,4.5rem);align-items:center;
}
.home-copy h1{margin-bottom:1.1rem}
.home-copy .lead{margin-bottom:2rem}
.actions{display:flex;flex-wrap:wrap;align-items:center;gap:1.1rem 1.6rem;margin-bottom:2.6rem}
.hero-note{
  display:grid;grid-template-columns:auto 1fr;gap:1.4rem;align-items:center;
  background:var(--bg-tint);border:var(--edge);border-left:4px solid var(--brand);
  border-radius:var(--radius);padding:1.35rem 1.5rem;
}
.hero-note span{
  font-size:.72rem;font-weight:700;letter-spacing:.13em;text-transform:uppercase;
  color:var(--brand-dark);line-height:1.6;
}
.hero-note p{font-size:.93rem;color:var(--ink-soft);margin:0;max-width:64ch}

.home-visual{position:relative}
/* The 18 September lead photograph is a 2.4:1 banner, not the 4:3.4 portrait the
   console close-up was. Cropping it back to that frame would cut off the people
   at both ends, who are the point of the picture, so the frame takes the shape
   of the photograph instead. */
.hero-photo{
  width:100%;border-radius:var(--radius);box-shadow:var(--shadow-lg);
  aspect-ratio:4/3.4;object-fit:cover;
}
/* The 18 September lead photograph is a 2.4:1 banner. Held in the half-width
   portrait frame the console shot used, it renders as a 504x210 letterbox
   stranded beside 575px of copy, and the corner tag lands across people's
   faces. Cropping it back to that frame would cut off the figures at both ends,
   who are the point of the picture. So on the home page the hero stacks: copy,
   then the photograph across the full width. Every other hero is untouched. */
.home-hero.stacked{grid-template-columns:minmax(0,1fr)}
/* Headline and lead keep a readable measure; the note runs the full width so
   its right edge lines up with the photograph below it rather than stopping
   short of it. */
.home-hero.stacked .home-copy h1,
.home-hero.stacked .home-copy .lead{max-width:58ch}
.home-visual.wide{grid-column:1/-1}
.home-visual.wide .hero-photo{aspect-ratio:var(--img-ar,2/1);height:auto}
/* Tag moves off the faces and onto the bottom edge of the wide frame. */
.home-visual.wide .photo-tag{top:auto;bottom:-14px;left:18px}
@media (max-width:860px){
  .home-visual.wide .photo-tag{left:0;bottom:-12px}
}
.photo-tag{
  position:absolute;left:-10px;top:22px;background:var(--brand);color:var(--navy-deep);
  font-size:.75rem;font-weight:600;letter-spacing:.14em;text-transform:uppercase;
  padding:.55em .9em;border-radius:2px;box-shadow:var(--shadow);
}

/* --- List resets for the semantic card grids ------------------------------ */
/* These grids are real lists (enumerable content), so the markup is <ul>/<li>.
   The bullets and indent are stripped here rather than in the markup. */
.info-grid,.service-cards,.audience-links,.related ul,.legal-layout aside ul{
  list-style:none;margin:0;padding:0;
}
.service-cards > li,.audience-links > li{display:flex}
.service-cards > li > a,.audience-links > li > a{width:100%}

/* --- Audience links ------------------------------------------------------- */
.audience-links{
  max-width:var(--wrap);margin-inline:auto;padding-inline:var(--gutter);
  display:grid;grid-template-columns:1fr 1fr;gap:1.6rem;margin-top:0;
}
.audience-links a{
  display:grid;grid-template-columns:1fr auto;align-items:center;
  gap:.2rem 1rem;text-decoration:none;
  border:var(--edge-strong);border-left:4px solid var(--brand);
  border-radius:var(--radius);padding:1.85rem 2rem;background:var(--white);
  transition:border-color .2s ease,box-shadow .2s ease,transform .2s ease,background .2s ease;
}
.audience-links a:hover{
  box-shadow:var(--shadow-lg);transform:translateY(-3px);background:var(--bg-panel);
}
.audience-links span{
  grid-column:1;font-size:.74rem;font-weight:700;letter-spacing:.13em;
  text-transform:uppercase;color:var(--brand-dark);
}
.audience-links strong{
  grid-column:1;font-family:var(--display);font-size:clamp(1.5rem,2.2vw,1.85rem);
  font-weight:600;color:var(--navy-deep);line-height:1.1;
}
/* Arrow pinned to the right of both rows rather than dropping onto its own line. */
.audience-links .arrow{
  grid-column:2;grid-row:1 / span 2;align-self:center;margin:0;
  width:2.4rem;height:2.4rem;border-radius:50%;
  background:var(--bg-tint);color:var(--brand-dark);
}
.audience-links .arrow::before{inset:.6rem}
.audience-links a:hover .arrow{background:var(--brand);color:var(--white)}

/* --- Service cards -------------------------------------------------------- */
.service-cards{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:1.6rem}
.service-card{
  position:relative;display:flex;flex-direction:column;gap:.55rem;text-decoration:none;
  background:var(--white);border:var(--edge-strong);border-radius:var(--radius);
  padding:2.15rem 1.9rem 1.7rem;overflow:hidden;
  transition:border-color .2s ease,box-shadow .2s ease,transform .2s ease;
}
/* Brand bar across the top of every service card: the strongest, cheapest
   repetition of the palette across the whole site. */
.service-card::before{
  content:"";position:absolute;inset:0 0 auto 0;height:4px;
  background:linear-gradient(90deg,var(--brand),var(--brand-deep));
  transform:scaleX(0);transform-origin:left;transition:transform .28s ease;
}
.service-card:hover{border-color:var(--brand);box-shadow:var(--shadow-lg);transform:translateY(-3px)}
.service-card:hover::before{transform:scaleX(1)}
.service-card h3{color:var(--navy-deep);font-weight:600}
.service-card p{color:var(--ink-soft);font-size:.96rem;line-height:1.6;margin:0;flex:1}
.card-action{
  display:inline-flex;align-items:center;font-size:.78rem;font-weight:700;
  letter-spacing:.1em;text-transform:uppercase;color:var(--brand-dark);
  margin-top:1.1rem;padding-top:1.05rem;border-top:1px solid var(--line-soft);
}

/* --- Info cards ----------------------------------------------------------- */
.info-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:1.6rem}
.info-card{
  position:relative;background:var(--white);border:var(--edge-strong);
  border-radius:var(--radius);padding:2.15rem 1.9rem;
  border-top:3px solid var(--brand);
}
/* The step number is a real badge, not a floating numeral. */
.info-card .index{
  display:inline-flex;align-items:center;justify-content:center;
  width:2.1rem;height:2.1rem;border-radius:50%;
  background:var(--bg-tint);border:1px solid var(--line);
  font-family:var(--body);font-size:.8rem;font-weight:700;letter-spacing:.02em;
  color:var(--brand-dark);margin-bottom:.9rem;line-height:1;
}
.info-card h3{margin-bottom:.65rem;font-weight:600}
.info-card p{color:var(--ink-soft);font-size:.96rem;line-height:1.6;margin:0}

/* --- Page hero ------------------------------------------------------------ */
/* The page hero sits on a tinted band with a hard bottom edge, so the top of
   every inner page has a defined masthead rather than text on blank white. */
/* The page hero sits on a tinted, full-bleed band with a hard bottom edge, so
   the top of every inner page has a defined masthead instead of text on blank
   white. The padding trick keeps the content on the --wrap grid while the
   background runs edge to edge. */
.page-hero{
  max-width:none;
  padding-inline:max(var(--gutter),calc((100% - var(--wrap)) / 2));
  padding-block:clamp(2rem,4vw,3.2rem) clamp(2.4rem,4vw,3.4rem);
  background:linear-gradient(180deg,var(--bg-tint),var(--bg));
  border-bottom:var(--edge-strong);margin-bottom:clamp(2rem,4vw,3rem);
}
.page-hero.text-only{max-width:none}
.page-hero.with-image{
  display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,.95fr);
  gap:clamp(2rem,5vw,4.5rem);align-items:center;
}
.page-hero.text-only{max-width:min(var(--wrap),980px)}
/* A text-only hero already ends in whitespace; without this the next section's
   own top padding stacks on it and opens a dead band roughly 170px tall. */
.page-hero.text-only + .content-section,
.page-hero.text-only + section.tinted{padding-top:clamp(1rem,2.5vw,2.2rem)}
.page-hero h1{margin-bottom:1rem}
.page-hero-image img{
  width:100%;border-radius:var(--radius);box-shadow:var(--shadow-lg);
  aspect-ratio:4/3.2;object-fit:cover;
}
.breadcrumb{
  display:flex;flex-wrap:wrap;align-items:center;gap:.55rem;
  font-size:.8rem;color:var(--ink-soft);margin:0 0 1.4rem;
}
.breadcrumb a{color:var(--ink-soft);text-decoration:none}
.breadcrumb a:hover{color:var(--brand-dark)}
.breadcrumb span{color:var(--line);}

/* --- Feature split -------------------------------------------------------- */
.feature-split{
  max-width:var(--wrap);margin-inline:auto;padding-inline:var(--gutter);
  padding-block:var(--section-y);
  display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);
  gap:clamp(2rem,5vw,4.5rem);align-items:center;
}
.feature-split h2{margin-bottom:1rem}
.feature-split p{color:var(--ink-soft);margin-bottom:1.8rem;max-width:52ch}
.feature-photo img{
  width:100%;border-radius:var(--radius);box-shadow:var(--shadow-lg);
  aspect-ratio:5/4;object-fit:cover;border:var(--edge-strong);
}

/* --- Image story ---------------------------------------------------------- */
.image-story{
  display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);
  gap:clamp(2rem,5vw,4.5rem);align-items:center;
}
.scan-frame,.scan-stack{background:var(--navy-deep);border-radius:var(--radius);padding:16px 16px 18px;box-shadow:var(--shadow-lg)}
/* Diagnostic images are never cropped. The orientation marker, the study label
   and the measurement legend sit at the edges of the frame, and those are the
   parts a referring vet actually reads — so no aspect-ratio, no object-fit. */
.scan-frame img,.scan-stack img{border-radius:2px;width:100%;height:auto}
/* Two studies stacked in one frame — the second reads as a companion view
   rather than a separate section. */
.scan-stack img + img{margin-top:10px}
.scan-frame span,.scan-stack span{
  display:block;margin-top:.9rem;font-size:.72rem;font-weight:600;
  letter-spacing:.14em;text-transform:uppercase;color:rgba(255,255,255,.7);
}
.image-story h2{margin-bottom:1rem}
.image-story p{color:var(--ink-soft)}

/* --- Figures and captions ------------------------------------------------- */
figure{margin:0}
figcaption{
  font-size:.85rem;line-height:1.5;color:var(--ink-soft);
  padding-top:.7rem;border-top:1px solid var(--line);margin-top:.8rem;
}
.page-hero-image figcaption,.feature-photo figcaption{margin-top:.9rem}

/* --- Clinical image carousel ---------------------------------------------- */
/* Scroll-snapped strip, requested by the client for the Abdominal Ultrasound and
   Echocardiography pages. CSS only: no script, no new visual language — the
   slides reuse the existing dark scan-frame treatment. */
.scan-carousel{
  list-style:none;margin:0 0 1rem;padding:0 0 .8rem;
  display:grid;grid-auto-flow:column;grid-auto-columns:min(78%,420px);gap:1rem;
  overflow-x:auto;scroll-snap-type:x mandatory;overscroll-behavior-x:contain;
  scrollbar-width:thin;
}
.scan-slide{
  scroll-snap-align:start;
  background:var(--navy-deep);border-radius:var(--radius);
  padding:12px 12px 14px;box-shadow:var(--shadow);
  display:flex;flex-direction:column;
}
.scan-slide img{width:100%;height:auto;border-radius:2px}
.scan-slide span{
  display:block;margin-top:.7rem;font-size:.78rem;line-height:1.45;
  color:rgba(255,255,255,.75);
}

/* --- Wave band ------------------------------------------------------------ */
.wave-band{
  position:relative;overflow:hidden;background:var(--bg-deep);color:var(--white);
  padding-block:clamp(4rem,9vw,7.5rem);padding-inline:var(--gutter);
  display:flex;justify-content:center;text-align:center;
}
.wave-band.compact{padding-block:clamp(3rem,6vw,5rem)}
.wave-band canvas{position:absolute;inset:0;width:100%;height:100%;display:block;opacity:.55}
.wave-band > div{position:relative;z-index:1;max-width:720px}
.wave-band h2{color:var(--white);margin-bottom:2rem}
.wave-band h2 em{color:var(--brand)}

/* --- Partner strip / panel ------------------------------------------------ */
.partner-strip{
  display:grid;grid-template-columns:minmax(0,.8fr) minmax(0,1.2fr);
  gap:clamp(1.5rem,4vw,3rem);align-items:center;
  background:var(--bg-panel);border:var(--edge-strong);
  border-left:4px solid var(--brand);border-radius:var(--radius);
  max-width:var(--wrap);margin-inline:auto;
  padding:clamp(1.8rem,3vw,2.6rem)!important;
  margin-bottom:clamp(2rem,4vw,3rem);
}
.partner-strip p{color:var(--ink-soft);margin-bottom:1rem}
.partner-panel{
  display:grid;grid-template-columns:minmax(0,.8fr) minmax(0,1.2fr);
  gap:clamp(1.5rem,4vw,4rem);align-items:start;
  background:var(--bg-tint);border:1px solid var(--line-soft);border-radius:var(--radius);
  max-width:var(--wrap);margin-inline:auto;
  padding:clamp(2rem,4vw,3.4rem);
}
.partner-panel p{color:var(--ink-soft)}
.partner-panel .button{margin-block:.6rem 1rem}

/* --- Lists: checklist and FAQ --------------------------------------------- */
/* Checklist rows are bordered so a list of four items reads as a block of
   content rather than four short lines adrift in whitespace. */
.checklist{list-style:none;margin:0 0 1.5rem;padding:0;display:grid;gap:.65rem}
.checklist li{
  position:relative;padding:.95em 1.1em .95em 2.7rem;color:var(--ink);
  background:var(--white);border:var(--edge);border-radius:var(--radius);
  font-weight:500;
}
.checklist li::before{
  content:"";position:absolute;left:1.05rem;top:1.35em;width:11px;height:7px;
  border-left:2.5px solid var(--brand);border-bottom:2.5px solid var(--brand);
  transform:rotate(-45deg);
}
.prose .checklist li{background:var(--white)}
.faq{border-top:1px solid var(--line)}
.faq details{border-bottom:1px solid var(--line)}
.faq summary{
  display:flex;align-items:center;justify-content:space-between;gap:1.5rem;
  padding:1.15rem 0;cursor:pointer;list-style:none;
  font-family:var(--display);font-size:1.22rem;font-weight:600;color:var(--navy-deep);
  line-height:1.2;
}
.faq summary::-webkit-details-marker{display:none}
.faq summary:hover{color:var(--brand-dark)}
.faq .plus{color:var(--brand);flex:none}
.faq details[open] summary .plus::after{transform:rotate(90deg);opacity:0}
.faq p{padding:0 0 1.35rem;margin:0;color:var(--ink-soft);max-width:70ch}

/* --- Next step CTA -------------------------------------------------------- */
/* The conversion block. Previously a hairline rule and a small button, which is
   the least emphasis on the page for the thing the page is for. */
.nextstep{
  position:relative;overflow:hidden;
  max-width:var(--wrap);margin:0 auto clamp(2.5rem,5vw,4rem);
  padding:clamp(2.2rem,4vw,3.4rem) clamp(1.6rem,3.5vw,3rem);
  display:grid;grid-template-columns:minmax(0,1fr) auto;
  gap:clamp(1.5rem,4vw,3rem);align-items:center;
  background:var(--navy-deep);color:var(--white);border-radius:var(--radius);
  box-shadow:var(--shadow-lg);
}
/* Wave motif from the logo, as a watermark. */
.nextstep::after{
  content:"";position:absolute;right:-40px;top:50%;translate:0 -50%;
  width:320px;height:320px;pointer-events:none;opacity:.16;
  background:no-repeat center/contain url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 120 90'%3E%3Cg fill='none' stroke='%2300a8e4' stroke-width='7' stroke-linecap='round'%3E%3Cpath d='M20 78a40 40 0 0 1 80 0'/%3E%3Cpath d='M34 60a26 26 0 0 1 52 0'/%3E%3Cpath d='M48 42a12 12 0 0 1 24 0'/%3E%3C/g%3E%3C/svg%3E");
}
.nextstep > *{position:relative;z-index:1}
.nextstep h2{margin-bottom:.7rem;color:var(--white)}
.nextstep h2 em{color:var(--brand)}
.nextstep p{color:rgba(255,255,255,.78);margin:0;max-width:52ch}
.nextstep .button.primary{
  background:var(--brand);border-color:var(--brand);font-size:1rem;padding:1em 1.8em;
}
.nextstep .button.primary:hover{background:var(--white);border-color:var(--white);color:var(--navy-deep)}
/* The phone and email moved into this panel when the duplicate contact strip
   below it was dropped, so the panel has to carry a button and two routes
   without turning into a second block of its own. */
.nextstep-lines{
  list-style:none;margin:0;padding:0;display:grid;gap:.5rem;min-width:min(100%,286px);
}
.nextstep-go{margin-bottom:.25rem}
.nextstep-go .button{width:100%}
.nextstep-lines li:not(.nextstep-go) a{
  display:flex;align-items:baseline;gap:.6rem;text-decoration:none;
  border:1px solid rgba(255,255,255,.22);border-radius:var(--radius);
  padding:.6rem .95rem;min-height:2.75rem;
  transition:border-color .2s ease;
}
/* No background wash on hover -- even a faint white overlay lightens this
   dark panel enough to drop the CALL/EMAIL label span below 4.5:1 (5.15:1
   at rest, ~4.18:1 once lightened). The border-color swap is affordance
   enough on its own. */
.nextstep-lines li:not(.nextstep-go) a:hover{border-color:var(--brand)}
.nextstep-lines li:not(.nextstep-go) a:focus-visible{outline:2px solid var(--brand);outline-offset:2px}
.nextstep-lines li:not(.nextstep-go) span{
  font-size:.72rem;font-weight:700;letter-spacing:.14em;color:var(--brand);flex:none;
}
.nextstep-lines li:not(.nextstep-go) strong{
  font-family:var(--display);font-size:1.05rem;font-weight:600;color:var(--white);
  line-height:1.2;word-break:break-word;
}

/* --- Related -------------------------------------------------------------- */
.related{
  max-width:var(--wrap);margin:0 auto clamp(2rem,4vw,3rem);
  padding:clamp(1.7rem,2.8vw,2.3rem);
  background:var(--bg-tint);border:var(--edge);border-radius:var(--radius);
}
.related ul{display:flex;flex-wrap:wrap;gap:.7rem}
.related a{
  display:inline-flex;align-items:center;text-decoration:none;background:var(--white);
  border:var(--edge-strong);border-radius:var(--radius);
  padding:.8em 1.3em;font-size:.94rem;font-weight:600;color:var(--navy-deep);
  transition:border-color .2s ease,color .2s ease,background .2s ease,transform .2s ease;
}
.related a:hover{border-color:var(--brand);color:var(--brand-dark);transform:translateY(-2px)}

/* --- Availability block --------------------------------------------------- */
.availability{text-align:center;max-width:640px;margin-inline:auto}
.availability p{color:var(--ink-soft);margin-bottom:1.8rem}

/* --- Contact / enquiry ---------------------------------------------------- */
.contact-layout{
  display:grid;grid-template-columns:minmax(0,.85fr) minmax(0,1.15fr);
  gap:clamp(2rem,4vw,3.5rem);align-items:start;
}
.contact-card{
  background:var(--navy-deep);color:var(--white);border-radius:var(--radius);
  padding:clamp(2rem,3.5vw,2.8rem);position:sticky;top:120px;
}
.contact-card h2{color:var(--white);margin-bottom:1.4rem}
.contact-card h2 em{color:var(--brand)}
.contact-card > a[href^="tel"],.contact-card > a[href^="mailto"]{
  display:block;color:var(--white);font-family:var(--display);font-size:1.4rem;
  font-weight:500;text-decoration:none;margin-bottom:.45rem;word-break:break-word;
}
.contact-card > a[href^="tel"]:hover,.contact-card > a[href^="mailto"]:hover{color:var(--brand)}
.contact-card p{color:rgba(255,255,255,.75);font-size:.93rem;margin:1.4rem 0 1.2rem}
.contact-card .text-link{color:var(--brand);border-bottom-color:rgba(0,168,228,.5)}
.contact-card .text-link:hover{color:var(--white);border-bottom-color:var(--white)}

.enquiry-card{
  background:var(--white);border:1px solid var(--line);border-radius:var(--radius);
  padding:clamp(2rem,3.5vw,2.8rem);box-shadow:var(--shadow);
}
.enquiry-card h2{margin-bottom:.9rem}
.enquiry-card > p{color:var(--ink-soft);font-size:.95rem;margin-bottom:1.8rem}
#enquiry-form{display:grid;gap:1.1rem}
.form-grid{display:grid;grid-template-columns:1fr 1fr;gap:1.1rem}
#enquiry-form label{
  display:grid;gap:.45rem;font-size:.82rem;font-weight:600;
  letter-spacing:.04em;text-transform:uppercase;color:var(--navy-deep);
}
#enquiry-form input,#enquiry-form select{
  font-family:var(--body);font-size:1rem;font-weight:400;letter-spacing:normal;
  text-transform:none;color:var(--ink);
  padding:.8em .9em;border:1px solid var(--line);border-radius:var(--radius);
  background:var(--white);width:100%;transition:border-color .2s ease,box-shadow .2s ease;
}
#enquiry-form input:focus,#enquiry-form select:focus{
  outline:none;border-color:var(--brand);box-shadow:0 0 0 3px rgba(0,168,228,.15);
}
#enquiry-form select{appearance:none;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M2 4.5 6 8.5l4-4' fill='none' stroke='%2314303f' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right .9em center;background-size:12px;padding-right:2.6em;
}
.form-actions{display:flex;flex-wrap:wrap;align-items:center;gap:1rem 1.5rem;margin-top:.4rem}
#enquiry-status:empty{display:none}
#enquiry-status{
  margin:0;padding:.8em 1em;background:var(--bg-tint);
  border-left:3px solid var(--brand);border-radius:2px;
}

/* --- Legal pages ---------------------------------------------------------- */
.legal-layout{
  max-width:var(--wrap);margin-inline:auto;padding-inline:var(--gutter);
  padding-block:0 var(--section-y);
  display:grid;grid-template-columns:minmax(0,.32fr) minmax(0,.68fr);
  gap:clamp(2rem,5vw,4rem);align-items:start;
}
.legal-layout aside{position:sticky;top:120px}
.legal-layout aside ul{display:flex;flex-direction:column;gap:.15rem}
.legal-layout aside a{
  font-size:.91rem;color:var(--ink-soft);text-decoration:none;
  padding:.5em .8em;border-left:2px solid var(--line);
}
.legal-layout aside a:hover{color:var(--brand-dark);border-left-color:var(--brand);background:var(--bg-tint)}
.legal-copy{max-width:68ch}
.legal-copy section{padding-block:1.6rem}
.legal-copy section + section{border-top:1px solid var(--line-soft)}
.legal-copy h2{font-size:clamp(1.35rem,2.2vw,1.75rem);margin-bottom:.8rem}
.legal-copy p{color:var(--ink-soft)}
.review-note{
  background:#fff8e8;border:1px solid #f0dcb0;border-left:3px solid #d99b28;
  border-radius:var(--radius);padding:1.1rem 1.3rem;margin-bottom:1rem;
  font-size:.93rem;color:#6b4f15;
}
.review-note strong{color:#4a3608}

/* --- Contact strip -------------------------------------------------------- */
/* Phone and email repeated above the footer on every page. */
.contact-strip{
  max-width:none;
  padding-inline:max(var(--gutter),calc((100% - var(--wrap)) / 2));
  padding-block:clamp(2.2rem,4vw,3.2rem);
  background:var(--bg-tint);border-block:var(--edge-strong);
  display:grid;grid-template-columns:minmax(0,.85fr) minmax(0,1.15fr);
  gap:clamp(1.5rem,4vw,3rem);align-items:center;
}
.contact-strip h2{font-size:clamp(1.6rem,2.8vw,2.3rem)}
.contact-strip-actions{
  display:flex;flex-wrap:nowrap;gap:.9rem;justify-content:flex-end;
  list-style:none;margin:0;padding:0;
}
.contact-strip-actions > li{display:flex;flex:1 1 0;min-width:0}
.contact-strip-note{color:var(--ink-soft);font-size:.95rem;margin:.8rem 0 0;max-width:46ch}
.contact-line{
  display:flex;flex-direction:column;gap:.15rem;text-decoration:none;
  background:var(--white);border:var(--edge-strong);border-left:4px solid var(--brand);
  border-radius:var(--radius);padding:.9rem 1.3rem;min-width:0;width:100%;
  transition:border-color .2s ease,box-shadow .2s ease,transform .2s ease;
}
.contact-line:hover{box-shadow:var(--shadow-lg);transform:translateY(-2px)}
.contact-line span{
  font-size:.72rem;font-weight:700;letter-spacing:.14em;color:var(--brand-dark);
}
.contact-line strong{
  font-family:var(--display);font-size:1.3rem;font-weight:600;color:var(--navy-deep);
  line-height:1.15;word-break:break-word;
}

/* --- Sticky mobile action bar --------------------------------------------- */
.mobile-cta{display:none}
@media (max-width:700px){
  .mobile-cta{
    display:grid;grid-template-columns:1fr 1fr;gap:1px;
    position:fixed;inset:auto 0 0 0;z-index:120;
    background:var(--line-strong);border-top:var(--edge-strong);
    box-shadow:0 -4px 18px rgba(6,47,69,.14);
  }
  .mobile-cta a{
    text-align:center;padding:1em .6em;font-size:.92rem;font-weight:700;
    text-decoration:none;
  }
  .mobile-call{background:var(--white);color:var(--navy-deep)}
  .mobile-refer{background:var(--brand);color:var(--white)}
  /* Clear the bar so it never covers the last line of the footer. */
  body{padding-bottom:3.6rem}
}

/* --- Footer --------------------------------------------------------------- */
.site-footer{background:var(--navy-deep);color:rgba(255,255,255,.72);margin-top:0}
.footer-top{
  max-width:var(--wrap);margin-inline:auto;padding-inline:var(--gutter);
  padding-block:clamp(3rem,6vw,4.5rem);
  display:grid;grid-template-columns:minmax(0,1.5fr) repeat(3,minmax(0,1fr));
  gap:clamp(2rem,4vw,3.5rem);
}
.footer-brand .brand{margin-bottom:1.2rem}
.footer-brand img{filter:brightness(0) invert(1);opacity:.95}
.footer-brand p{font-size:.93rem;color:rgba(255,255,255,.66);margin-bottom:1.1rem}
.footer-brand a{display:block;color:var(--white);text-decoration:none;font-weight:500;font-size:.95rem;margin-bottom:.3rem;word-break:break-word}
.footer-brand a:hover{color:var(--brand)}
.footer-top h3{
  font-family:var(--body);font-size:.72rem;font-weight:600;letter-spacing:.14em;
  text-transform:uppercase;color:var(--brand);margin-bottom:1.1rem;
}
.footer-top > div > a{
  display:block;color:rgba(255,255,255,.72);text-decoration:none;
  font-size:.93rem;padding-block:.32rem;
}
.footer-top > div > a:hover{color:var(--white)}
.footer-bottom{
  max-width:var(--wrap);margin-inline:auto;padding-inline:var(--gutter);
  padding-block:1.4rem;border-top:1px solid rgba(255,255,255,.14);
  display:flex;flex-wrap:wrap;justify-content:space-between;align-items:center;gap:.8rem 1.5rem;
  font-size:.83rem;color:rgba(255,255,255,.6);
}
.footer-bottom .plain{color:rgba(255,255,255,.72);font-size:.83rem}
.footer-bottom .plain:hover{color:var(--brand)}

/* --- Cookie dialog -------------------------------------------------------- */
#cookie-dialog{
  border:0;border-radius:var(--radius);padding:clamp(1.8rem,3vw,2.6rem);
  max-width:min(92vw,520px);box-shadow:var(--shadow-lg);color:var(--ink);
  position:fixed;margin:auto;
}
#cookie-dialog::backdrop{background:rgba(6,47,69,.55)}
#cookie-dialog h2{margin-bottom:1rem;font-size:clamp(1.5rem,3vw,2rem)}
#cookie-dialog p{font-size:.94rem;color:var(--ink-soft)}
.dialog-close{
  position:absolute;top:.9rem;right:1rem;background:none;border:0;cursor:pointer;
  font-size:.82rem;font-weight:600;color:var(--ink-soft);text-transform:uppercase;letter-spacing:.08em;
}
.dialog-close:hover{color:var(--brand-dark)}

/* --- Responsive ----------------------------------------------------------- */
@media (max-width:1000px){
  .service-cards,.info-grid{grid-template-columns:repeat(2,minmax(0,1fr))}
  .footer-top{grid-template-columns:repeat(2,minmax(0,1fr))}
  .legal-layout{grid-template-columns:1fr}
  .legal-layout aside{position:static}
  .legal-layout aside ul{flex-direction:row;flex-wrap:wrap;gap:.4rem}
  .legal-layout aside a{border-left:0;border:1px solid var(--line);border-radius:var(--radius)}
  .contact-card{position:static}
}

@media (max-width:1239px){
  .site-header{flex-wrap:wrap}
  .menu-toggle{display:inline-flex}
  #main-nav{
    display:none;width:100%;flex-direction:column;align-items:stretch;
    gap:.2rem;padding-top:1rem;margin-top:.9rem;border-top:1px solid var(--line);
  }
  #main-nav.open{display:flex}
  #main-nav > a,.nav-dropdown > summary{padding:.75em 0;border-bottom:1px solid var(--line-soft)}
  #main-nav > .button{margin-top:.8rem;width:100%}
  .nav-dropdown > summary{justify-content:space-between}
  .nav-menu{
    position:static;transform:none;min-width:0;border:0;box-shadow:none;
    padding:.2rem 0 .6rem 1rem;border-left:2px solid var(--line);margin:.4rem 0 .6rem;
  }
}

@media (max-width:860px){
  .home-hero,.page-hero.with-image,.feature-split,.image-story,
  .content-section.two-col,.section-heading,.partner-strip,.partner-panel,
  .contact-layout,.nextstep,.contact-strip{grid-template-columns:1fr}
  .section-heading{align-items:start}
  .nextstep{justify-items:start}
  .nextstep-lines{width:100%}
  .home-visual{margin-bottom:2.5rem}
  .photo-tag{left:0}
  .audience-links{grid-template-columns:1fr}
  /* .contact-strip was missing from the list above, so its 2-column grid never
     stacked: on a 375px phone the actions column was squeezed to 179px, split
     nowrap into two ~82px sub-columns. "info@spectrumultrasound.ca" cannot wrap
     at a word boundary in 82px, so word-break:break-word fell back to breaking
     every character onto its own line -- a 291px-tall vertical letter-stack
     instead of a button. Stacking the actions list too, full width, fixes it
     the same way .nextstep-lines already works: one full-width tappable row per
     contact method instead of two competing for a sliver each. */
  .contact-strip-actions{flex-direction:column;justify-content:flex-start}
  .contact-strip-actions > li{width:100%}
  }

@media (max-width:560px){
  body{font-size:16px}
  .service-cards,.info-grid,.form-grid{grid-template-columns:1fr}
  .footer-top{grid-template-columns:1fr}
    /* Phones go up 20% rather than down: at 58px the lockup was the one thing on a
     small screen that was too small to read. The header keeps its height because
     the padding comes in to pay for it. */
  .brand img{height:70px}
  .site-header{padding-block:.5rem}
  .actions{gap:.9rem}
  .actions .button{width:100%}
  .form-actions .button{width:100%}
}

/* --- Touch and small-screen refinements ----------------------------------- */
/* Desktop sizing is unchanged. These rules only raise legibility and tap-target
   size where a finger is the pointer or the screen is small, which is where the
   audit found sub-12px labels and sub-40px targets. */
@media (pointer:coarse){
  /* Apple asks for 44px, Android for 48dp. These bring the small links up to
     roughly 44px without moving anything on a mouse-driven screen. */
    .text-link{padding-block:.55em}
  .footer-top > div > a{padding-block:.62rem}
  .footer-bottom .plain{padding-block:.5em}
  .legal-layout aside a{padding-block:.7em}
  .related a{padding-block:.9em}
  .nav-menu a{padding-block:.85em}
  /* Breadcrumb links and the form's secondary button were 21px and 25px tall. */
  .breadcrumb a{padding-block:.5em}
  .form-actions .plain{padding-block:.6em}
}
@media (max-width:860px){
  /* Decorative photo labels were 9.6–9.9px on a phone, below the ~12px floor
     where uppercase tracked text stops being readable at arm's length. */
  .photo-tag{font-size:.74rem;letter-spacing:.1em}
    .contact-line span{font-size:.76rem}
  .footer-top h3{font-size:.8rem}
  .audience-links span{font-size:.8rem}
  /* Two columns leave the note's prose about 45% of a phone screen, which wrapped
     it into a ten-line ribbon beside its own label. It stacks below 560px. */
  .hero-note{grid-template-columns:1fr;gap:.5rem}
  .hero-note span{font-size:.76rem}
  .card-action{font-size:.8rem}
}
@media (max-width:380px){
  /* Long service names wrap awkwardly in the tightest phones. */
  h1{font-size:clamp(2.1rem,10vw,2.6rem)}
  h2{font-size:clamp(1.7rem,8vw,2rem)}
  .scan-carousel{grid-auto-columns:88%}
}

/* --- Motion / print ------------------------------------------------------- */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important;scroll-behavior:auto!important}
}
@media print{
  .site-header,.site-footer,#cookie-dialog,.wave-band canvas,.related,.nextstep{display:none!important}
  body{font-size:11pt;color:#000}
  a{color:#000;text-decoration:underline}
}

/* ==========================================================================
   Client revision, 18 September 2026
   --------------------------------------------------------------------------
   David: "It is a little bit boring though. I think it's very white. Are you
   able to introduce other further colours beyond the blues and [white] ... it
   can be settled in the background with watermarks or even the rotation of
   pictures ... Or even fade in or fade outs."

   Everything below is additive. No layout, type scale or spacing rule above is
   changed; deleting this block and the four tokens it adds returns the site to
   the version David signed off on.
   ========================================================================== */

/* --- Warm band ------------------------------------------------------------ */
/* A third background tone. Mirrors .tinted exactly so the two are
   interchangeable: a section becomes warm by swapping one class name. */
.content-section.warm,section.warm{
  background:var(--sand);max-width:none;
  border-block:1px solid var(--sand-line);
}
.content-section.warm > *,section.warm > *{max-width:var(--wrap);margin-inline:auto}
/* Cards sit on white inside the warm band, so only their edges need retuning. */
.warm .info-card,.warm .service-card,.warm .checklist li{border-color:var(--sand-line)}
.warm .info-card .index{background:var(--sand);border-color:var(--sand-line);color:var(--accent)}

/* --- Background watermark ------------------------------------------------- */
/* The wave motif from the logo, sized large and held at a low enough opacity
   that it reads as paper texture rather than as a graphic. It sits behind the
   content and never over it. No .tinted or .warm section is also .two-col, so
   the clipping here cannot trap a position:sticky heading. */
.content-section.tinted,section.tinted,
.content-section.warm,section.warm{position:relative;overflow:hidden}
.content-section.tinted::before,section.tinted::before,
.content-section.warm::before,section.warm::before{
  content:"";position:absolute;pointer-events:none;z-index:0;
  right:clamp(-160px,-6vw,-60px);bottom:-22%;
  width:min(620px,58vw);aspect-ratio:4/3;
  background:no-repeat center/contain url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 120 90'%3E%3Cg fill='none' stroke='%23000' stroke-width='7' stroke-linecap='round'%3E%3Cpath d='M20 78a40 40 0 0 1 80 0'/%3E%3Cpath d='M34 60a26 26 0 0 1 52 0'/%3E%3Cpath d='M48 42a12 12 0 0 1 24 0'/%3E%3C/g%3E%3C/svg%3E");
}
.content-section.tinted::before,section.tinted::before{opacity:.05}
.content-section.warm::before,section.warm::before{opacity:.045}
/* Content clears the watermark. */
.content-section.tinted > *,section.tinted > *,
.content-section.warm > *,section.warm > *{position:relative;z-index:1}
/* On phones the mark is too close to the text column to stay decorative. */
@media (max-width:700px){
  .content-section.tinted::before,section.tinted::before,
  .content-section.warm::before,section.warm::before{opacity:.03;width:76vw}
}

/* --- Reveal on scroll ----------------------------------------------------- */
/* Opt-in: the hiding rule only applies once app.js has marked the document, so
   with JS off or broken every section renders normally. Elements already in
   view on load are marked immediately and never animate, which keeps the first
   screen free of movement. */
.js-reveal [data-reveal]{opacity:0;transform:translateY(16px)}
.js-reveal [data-reveal].revealed{
  opacity:1;transform:none;
  transition:opacity .75s cubic-bezier(.22,.61,.36,1),transform .75s cubic-bezier(.22,.61,.36,1);
}
.js-reveal [data-reveal].revealed-instant{opacity:1;transform:none}
@media (prefers-reduced-motion:reduce){
  .js-reveal [data-reveal]{opacity:1;transform:none}
}
/* Nothing may stay hidden in a medium that cannot scroll. Printing, or saving to
   PDF, otherwise produces pages that are blank below the first screen. */
@media print{
  .js-reveal [data-reveal]{opacity:1!important;transform:none!important}
}

/* --- Rotating clinical strip ---------------------------------------------- */
/* With JS off this stays the manual scroll-snap strip it already was. JS adds
   the controls and switches it into rotator mode.

   Rotation is a crossfade, not a scroll. The strip shows two to three slides at
   once and can only scroll 72px at 1440px wide against a 436px slide step, so
   scrolling cannot advance it past the second image at any viewport width.
   Stacking the slides in one grid cell also sizes the frame to the tallest
   slide on its own, with no height measurement to keep in sync on resize, and
   gives each scan the full column width instead of a third of it. */
/* One scan at full column width is 862px tall at 1280px wide, which is more
   screen than a supporting image should take. The whole block — kicker,
   controls, frame and note — is held to one narrower centred column instead.
   This rule has to outrank .content-section.warm > *, so it carries the same
   two-class weight and sits later in the file. */
.content-section.scan-section > *{max-width:min(100%,780px);margin-inline:auto}
.scan-carousel.rotator{
  display:grid;grid-template-areas:"slide";
  grid-auto-flow:row;grid-auto-columns:auto;
  overflow:visible;scroll-snap-type:none;padding-bottom:0;
}
.rotator .scan-slide{
  grid-area:slide;scroll-snap-align:none;
  opacity:0;transition:opacity .8s ease;
}
.rotator .scan-slide[data-on]{opacity:1}
/* Inactive slides keep their text in the document and in the accessibility tree
   on purpose: a crawler or a screen reader still gets every caption. */
@media (prefers-reduced-motion:reduce){
  .rotator .scan-slide{transition:none}
}
/* Print cannot crossfade, so the stack unpacks back into a list. */
@media print{
  .scan-carousel.rotator{display:block}
  .rotator .scan-slide{opacity:1!important;margin-bottom:1rem}
}

/* --- Rotator controls ----------------------------------------------------- */
.scan-controls{
  display:flex;align-items:center;gap:.9rem;margin:-.2rem 0 1rem;flex-wrap:wrap;
}
.scan-dots{display:flex;gap:.5rem;list-style:none;margin:0;padding:0}
.scan-dots button{
  /* 2.75rem, not the 2.4rem the dot appears to need: the target is the button,
     and it has to clear the 44px minimum on a touch screen. */
  width:2.75rem;height:2.75rem;padding:0;border:0;background:none;cursor:pointer;
  display:grid;place-items:center;border-radius:50%;
}
.scan-dots button::before{
  content:"";width:9px;height:9px;border-radius:50%;
  background:var(--line-strong);transition:background .3s ease,transform .3s ease;
}
.scan-dots button[aria-current="true"]::before{background:var(--accent);transform:scale(1.35)}
.scan-dots button:hover::before{background:var(--brand-dark)}
.scan-dots button:focus-visible{outline:2px solid var(--brand-dark);outline-offset:2px}
.scan-pause{
  margin-left:auto;background:none;border:1px solid var(--line);border-radius:var(--radius);
  font:inherit;font-size:.82rem;font-weight:600;color:var(--ink-soft);
  padding:.55em 1em;cursor:pointer;min-height:2.75rem;
}
.scan-pause:hover{border-color:var(--brand-dark);color:var(--brand-dark)}
.scan-pause:focus-visible{outline:2px solid var(--brand-dark);outline-offset:2px}
@media print{.scan-controls{display:none}}

/* ==========================================================================
   Phone density pass, 19 September
   --------------------------------------------------------------------------
   Client: the desktop layout is right, but on a phone the site read "bulky,
   too big and outdated". It was. Every type size is a clamp whose lower bound
   never releases on a small screen: 6vw only overtakes the 2.6rem floor at
   693px, so an h1 sat at 41.6px on a 390px phone and an h2 at 32px. Desktop
   proportions were being shown at phone width, which is exactly what a 2015
   responsive retrofit looks like.

   Nothing here touches the desktop or tablet layout, and body copy stays at
   16px: below that iOS zooms the page on focus, and the text is not what was
   too big. Only the display scale, the leading and the padding come in.
   ========================================================================== */
@media (max-width:700px){
  body{line-height:1.55}
  h1{font-size:1.85rem;line-height:1.12}
  h2{font-size:1.5rem;line-height:1.14}
  h3{font-size:1.08rem}
  .lead{font-size:1.02rem;line-height:1.5}
  .large-text{font-size:1.22rem;line-height:1.34}
  .prose > .large-text{padding-left:.85rem;margin-bottom:1rem}

  /* Vertical rhythm: 40px bands between every section is desktop spacing. */
  :root{--section-y:34px}
  .section-heading{margin-bottom:1.4rem}
  .content-section.two-col{gap:1.1rem}
  .home-copy .lead{margin-bottom:1.4rem}
  .actions{gap:.8rem 1rem;margin-bottom:1.8rem}

  /* Cards carried 1.9rem of padding on a 350px-wide column. */
  .info-card{padding:1.35rem 1.2rem}
  .info-card .index{width:1.8rem;height:1.8rem;font-size:.72rem;margin-bottom:.6rem}
  .service-card{padding:1.35rem 1.2rem 1.15rem}
  .audience-links a{padding:1.2rem 1.25rem}
  .info-grid,.service-cards,.audience-links{gap:1rem}
  .checklist li{padding-block:.85rem}
  .prose{max-width:none}

  /* The strip tag wrapped onto two lines and became a slab. */
  .photo-tag{font-size:.74rem;letter-spacing:.02em;padding:.45em .7em}
  .nextstep{padding:1.6rem 1.2rem}
  .related{padding:1.2rem}
  .contact-strip{padding-block:1.8rem}
}

/* The equipment range shot is a 16:9 product line-up, so it sits on the wrap
   grid at its own aspect rather than being cropped into a card. */
.range-figure{margin:0}
.range-figure img{width:100%;height:auto;border-radius:var(--radius);box-shadow:var(--shadow)}
.range-figure figcaption{
  margin-top:.8rem;font-size:.86rem;color:var(--ink-soft);line-height:1.5;
}

/* A headshot is a portrait. The service heroes crop their image to 4/3.2, which
   on a 0.84:1 frame takes the top of the subject's head off, so this one keeps
   its own shape and sits at a size a face reads at rather than filling the
   column. */
.page-david-stasiuk .page-hero-image img{
  aspect-ratio:var(--img-ar,3/4);max-width:340px;margin-inline:auto;
}

/* --- Cine loops ------------------------------------------------------------ */
/* Video sits on the same warm band as the clinical strip. Two loops go side by
   side on a wide screen and stack below 860px; one loop centres on its own. */
.clip-section > h2{max-width:min(100%,780px);margin-inline:auto;margin-bottom:1.4rem}
.clip-grid{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,340px),1fr));
  gap:1.6rem;max-width:min(100%,1060px);margin-inline:auto;
}
.clip-grid:has(> :only-child){max-width:min(100%,780px)}
.clip{margin:0}
.clip video{
  width:100%;height:auto;display:block;
  background:var(--navy-deep);border-radius:var(--radius);box-shadow:var(--shadow);
}
.clip figcaption{
  margin-top:.8rem;font-size:.86rem;color:var(--ink-soft);line-height:1.5;
}
.clip-section > .small-note{max-width:min(100%,1060px);margin-inline:auto;margin-top:1.4rem}

/* ==========================================================================
   Navigation feel, 21 September
   --------------------------------------------------------------------------
   Measured first. On a local connection the home page is done in 116ms, so
   there is nothing to cover there. On Slow 3G the text paints at 4.4s but the
   hero photograph does not arrive until 21.2s. The gap people actually see on
   this site is images, not HTML, so that is where the skeleton goes.
   ========================================================================== */

/* --- Media skeleton -------------------------------------------------------- */
/* Carried in the image's own background, so it needs no wrapper: the picture
   paints over it the instant it decodes. Every image already ships width and
   height, so the box is the right size before anything loads and nothing
   shifts. On a fast connection this is never seen; on a slow one it is the
   whole point. */
.skel,.clip video{
  background-color:var(--bg-tint);
  background-image:linear-gradient(100deg,
    rgba(255,255,255,0) 20%,rgba(255,255,255,.7) 42%,rgba(255,255,255,0) 64%);
  background-size:220% 100%;
  background-repeat:no-repeat;
  animation:skel-sweep 1.5s linear infinite;
}
.clip video{background-color:var(--navy-deep)}
@keyframes skel-sweep{from{background-position:170% 0}to{background-position:-70% 0}}
/* app.js drops this the moment the image fires load, so the sweep does not keep
   running behind a picture nobody can see it through. */
.skel-done{background-image:none;animation:none}
@media (prefers-reduced-motion:reduce){
  .skel,.clip video{animation:none;background-image:none}
}

/* --- Cross-document view transitions --------------------------------------- */
/* Both pages have to opt in, which every page here does. Chrome, Edge and
   Safari 18.2 run it; Firefox ignores the at-rule and navigates normally, which
   is exactly the old behaviour. 180ms because the default 250ms reads as a
   wait rather than a transition on pages this small. */
@view-transition{navigation:auto}
::view-transition-old(root){animation:vt-fade-out .12s ease-in both}
::view-transition-new(root){animation:vt-fade-in .18s ease-out both}
@keyframes vt-fade-out{to{opacity:0}}
@keyframes vt-fade-in{from{opacity:0}}
/* The masthead is identical on every page, so it is named and held still while
   the content beneath it changes. Without this it cross-fades with everything
   else and the logo appears to flicker on every click. */
.site-header{view-transition-name:site-header}
@media (prefers-reduced-motion:reduce){
  ::view-transition-group(*),::view-transition-old(*),::view-transition-new(*){
    animation:none!important;
  }
}

/* --- Navigation progress --------------------------------------------------- */
/* For the slow case only. app.js shows it 150ms after a click on an internal
   link, so a prerendered or cached navigation never flashes it. */
.nav-progress{
  position:fixed;left:0;top:0;height:3px;width:100%;z-index:300;
  transform:scaleX(0);transform-origin:0 50%;
  background:linear-gradient(90deg,var(--brand),var(--brand-dark));
  opacity:0;pointer-events:none;
  transition:transform .45s cubic-bezier(.22,.61,.36,1),opacity .2s ease;
}
.nav-progress.on{opacity:1}
@media (prefers-reduced-motion:reduce){.nav-progress{transition:opacity .2s ease}}

/* The portal page offers both routes at once: sign in, or ask for a login. */
.portal-actions{
  max-width:var(--wrap);margin-inline:auto;
  display:flex;flex-wrap:wrap;align-items:center;gap:1rem 1.4rem;
}
.portal-actions .small-note{flex:1 1 22rem;margin:0}
