/* Hallmark · macrostructure: Catalogue · tone: business (professional-premium) · anchor hue: brand blue 256deg
 * genre: modern-minimal · theme: custom (BlueVista brand palette)
 * nav: N12 banner+retract · footer: Ft5 statement · enrichment: photography + hand-built SVG wave
 * paper-band: light · display-style: grotesk-sans (Archivo) · accent-hue: cool (256deg)
 * pre-emit critique: P5 H5 E5 S4 R5 V4
 * ---------------------------------------------------------------------------
 * BlueVista Pools. Shared stylesheet - every page added later reuses this file.
 * Token block sits at the top; a portable copy lives in /tokens.css.
 * ------------------------------------------------------------------------- */

/* ============================ 1 - FONTS ================================== */
@font-face{font-family:"Archivo";font-style:normal;font-weight:600;font-display:swap;
  src:url("../fonts/archivo-latin-600-normal.woff2") format("woff2");
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;}
@font-face{font-family:"Archivo";font-style:normal;font-weight:700;font-display:swap;
  src:url("../fonts/archivo-latin-700-normal.woff2") format("woff2");
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;}
@font-face{font-family:"Source Sans 3";font-style:normal;font-weight:400;font-display:swap;
  src:url("../fonts/source-sans-3-latin-400-normal.woff2") format("woff2");
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;}
@font-face{font-family:"Source Sans 3";font-style:normal;font-weight:600;font-display:swap;
  src:url("../fonts/source-sans-3-latin-600-normal.woff2") format("woff2");
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;}

/* ============================ 2 - TOKENS ================================= */
:root{
  /* brand colour. Hex is authoritative (client brand guide);
     OKLCH equivalent noted alongside for reference. */
  --c-navy:        #00337c;  /* oklch(34.2% .134 259.2)  darkblue 1  */
  --c-blue:        #0060c0;  /* oklch(50.0% .169 255.7)  darkblue 2  - primary accent */
  --c-blue-2:      #0069be;  /* oklch(51.9% .156 252.1)  lightblue 1 */
  --c-cyan:        #00adf0;  /* oklch(70.6% .150 235.3)  lightblue 2 - dark bands only, 2.55:1 on white */

  /* derived states */
  --c-blue-hover:  #004f9e;
  --c-blue-press:  #00427f;
  --c-navy-soft:   #123f89;

  /* surface */
  --c-paper:       #ffffff;
  --c-paper-2:     #f4f7fa;  /* oklch(97.5% .005 247.9) */
  --c-paper-3:     #e8eef5;  /* oklch(94.7% .011 252.1) */
  --c-abyss:       #0a1628;  /* oklch(20.0% .040 258.3) */
  --c-abyss-2:     #0e1e35;

  /* ink */
  --c-ink:         #1c2b3a;  /* 14.4:1 on white */
  --c-ink-2:       #4a5b6e;  /*  6.9:1 on white */
  --c-on-dark:     #e6eef7;
  --c-on-dark-2:   #9fb6cf;  /*  8.7:1 on abyss */

  /* line */
  --c-rule:        #dde6ef;
  --c-rule-dark:   rgba(255,255,255,.14);

  /* action */
  --c-wa:          #0d8038;  /* 5.05:1 on white */
  --c-wa-hover:    #0a6a2f;
  --c-focus:       #0060c0;
  --c-focus-dark:  #00adf0;

  /* type */
  --font-display:"Archivo","Segoe UI",system-ui,-apple-system,sans-serif;
  --font-body:"Source Sans 3",system-ui,-apple-system,"Segoe UI",sans-serif;
  /* code blocks in blog posts; nothing is downloaded for this */
  --font-mono:ui-monospace,SFMono-Regular,"SF Mono",Menlo,Consolas,"Liberation Mono",monospace;

  /* tuned so the longest headline word ("engineering") never exceeds the
     gutter box at any width - see the text-overflow sweep in the build notes */
  --text-display: clamp(1.9rem, 1.05rem + 3.8vw, 4rem);
  --text-h2:      clamp(1.85rem, 1.32rem + 2.1vw, 3rem);
  --text-h3:      clamp(1.2rem, 1.09rem + 0.5vw, 1.45rem);
  --text-lead:    clamp(1.05rem, 1rem + 0.38vw, 1.28rem);
  --text-body:    1.0625rem;
  --text-sm:      0.9375rem;
  --text-xs:      0.8125rem;
  --text-micro:   0.75rem;

  --lh-tight: 1.04;
  --lh-head:  1.14;
  --lh-body:  1.65;
  --track-label: .13em;

  /* 4pt space scale */
  --space-3xs:4px;  --space-2xs:8px;  --space-xs:12px; --space-sm:16px;
  --space-md:24px;  --space-lg:32px;  --space-xl:48px; --space-2xl:64px;
  --space-3xl:96px; --space-4xl:128px;
  /* Tightened from 64-118px. Light sections now share one surface, so the band
     of empty page between two of them reads as dead space rather than rhythm. */
  --section-y: clamp(40px, 4.6vw, 72px);
  /* a section that continues the one above it gets a hairline instead of the
     full gap, so grouped topics stay grouped */
  --section-y-join: clamp(34px, 3.6vw, 56px);
  --gutter:    clamp(20px, 5vw, 56px);
  --wrap:      1200px;
  --wrap-narrow: 740px;
  /* Nav bar height. The brand is a two-line lockup (mark + tagline), so this
     is sized to clear it with a gutter above and below rather than letting the
     tagline sit on the bar's bottom edge. The hero subtracts it, so the two
     stay in step if it is ever retuned. */
  --head-h:           92px;
  --head-h-condensed: 80px;
  --brand-gutter:     11px;

  /* shape */
  --r-sm:3px; --r:6px; --r-lg:10px; --r-pill:999px;
  --rule-hair:1px;

  /* depth */
  --shadow-sm: 0 1px 2px rgba(10,22,40,.06), 0 2px 8px rgba(10,22,40,.05);
  --shadow-md: 0 2px 4px rgba(10,22,40,.06), 0 12px 28px rgba(10,22,40,.09);
  --shadow-lg: 0 4px 10px rgba(10,22,40,.08), 0 22px 48px rgba(10,22,40,.14);

  /* motion */
  --dur-fast:140ms; --dur:240ms; --dur-slow:520ms; --dur-reveal:800ms; --dur-fade:900ms;
  --ease-out:   cubic-bezier(.22,.61,.36,1);
  --ease-in:    cubic-bezier(.55,.06,.68,.19);
  --ease-in-out:cubic-bezier(.65,.05,.36,1);
}

/* ============================ 3 - RESET ================================== */
*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth;overflow-x:clip;scroll-padding-top:96px}
body{
  margin:0;overflow-x:clip;
  /* ONE light surface for the whole page. The page used to alternate white and
     --c-paper-2 between neighbouring sections, which read as an unintended seam
     wherever two light sections met. Contrast now comes from the cards and
     panels sitting on this surface, not from the sections themselves. */
  background:var(--c-paper-2);color:var(--c-ink);
  font-family:var(--font-body);font-size:var(--text-body);line-height:var(--lh-body);
  font-synthesis-weight:none;
  -webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;
}
img,svg,video{display:block;max-width:100%}
img{height:auto}
h1,h2,h3,h4{
  margin:0;font-family:var(--font-display);font-weight:700;font-style:normal;
  line-height:var(--lh-head);letter-spacing:-.022em;
  overflow-wrap:break-word;min-width:0;text-wrap:balance;
}
h1{font-size:var(--text-display);line-height:var(--lh-tight);letter-spacing:-.032em}
h2{font-size:var(--text-h2);letter-spacing:-.026em}
h3{font-size:var(--text-h3);font-weight:600;letter-spacing:-.014em}
p{margin:0;text-wrap:pretty}
ul,ol{margin:0;padding:0;list-style:none}
a{color:inherit;text-decoration:none}
button,input,select,textarea{font:inherit;color:inherit}
:focus-visible{outline:3px solid var(--c-focus);outline-offset:3px;border-radius:var(--r-sm)}
.on-dark :focus-visible,.site-foot :focus-visible{outline-color:var(--c-focus-dark)}
::selection{background:var(--c-cyan);color:var(--c-abyss)}

/* ============================ 4 - PRIMITIVES ============================= */
.wrap{width:100%;max-width:var(--wrap);margin-inline:auto;padding-inline:var(--gutter)}
.wrap--narrow{max-width:var(--wrap-narrow)}
.section{padding-block:var(--section-y)}
/* kept so any page copied from this one still parses; the page has a single
   light surface now, so it is deliberately a no-op */
.section--tint{background:transparent}
/* a section continuing the topic above it: hairline rule, no colour change,
   and a shorter gap than a full section break */
.section--continue{padding-top:0}
.section--continue > .wrap > .s-head,
.section--continue > .wrap > .section__join{
  padding-top:var(--section-y-join);border-top:var(--rule-hair) solid var(--c-rule)}
.skip{
  position:absolute;left:var(--space-sm);top:-100px;z-index:200;
  background:var(--c-navy);color:#fff;padding:12px 20px;border-radius:var(--r);
  font-weight:600;transition:top var(--dur-fast) var(--ease-out);
}
.skip:focus-visible{top:var(--space-sm)}
.sr{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}

/* eyebrow - used sparingly, always stacked directly above its heading */
.eyebrow{
  display:block;margin:0 0 var(--space-sm);
  font-family:var(--font-display);font-size:var(--text-micro);font-weight:600;
  letter-spacing:var(--track-label);text-transform:uppercase;color:var(--c-blue);
}
.on-dark .eyebrow{color:var(--c-cyan)}
.eyebrow--lg{font-size:var(--text-h3)}
.lead{font-size:var(--text-lead);color:var(--c-ink-2);line-height:1.58}
.on-dark .lead{color:var(--c-on-dark-2)}

/* section head - collapses to a single column below 900px */
.s-head{display:grid;gap:var(--space-md);align-items:end;margin-bottom:var(--space-xl)}
@media (min-width:900px){
  .s-head--split{grid-template-columns:minmax(0,1.05fr) minmax(0,.85fr);gap:var(--space-2xl)}
}
.s-head p{max-width:56ch}

/* the logo wave, abstracted to a two-tone bar */
.tick{display:block;width:56px;height:4px;border-radius:2px;margin-bottom:var(--space-md);
  background:linear-gradient(90deg,var(--c-navy) 0%,var(--c-blue) 45%,var(--c-cyan) 100%)}

/* ---- buttons ---- */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:10px;
  padding:14px 26px;border:1px solid transparent;border-radius:var(--r);
  font-family:var(--font-display);font-size:var(--text-sm);font-weight:600;
  letter-spacing:.005em;white-space:nowrap;cursor:pointer;
  transition:background-color var(--dur-fast) var(--ease-out),
             border-color var(--dur-fast) var(--ease-out),
             color var(--dur-fast) var(--ease-out),
             transform var(--dur-fast) var(--ease-out);
}
.btn svg{width:18px;height:18px;flex:none}
.btn--primary{background:var(--c-blue);color:#fff}
.btn--primary:hover{background:var(--c-blue-hover)}
.btn--primary:active{background:var(--c-blue-press);transform:translateY(1px)}
.btn--ghost{background:transparent;color:var(--c-ink);border-color:var(--c-rule)}
.btn--ghost:hover{border-color:var(--c-blue);color:var(--c-blue)}
.btn--ghost:active{transform:translateY(1px)}
.btn--onphoto{background:rgba(255,255,255,.12);color:#fff;border-color:rgba(255,255,255,.5)}
.btn--onphoto:hover{background:#fff;color:var(--c-navy);border-color:#fff}
.btn--onphoto:active{transform:translateY(1px)}
.btn--light{background:#fff;color:var(--c-navy);border-color:#fff}
.btn--light:hover{background:var(--c-cyan);border-color:var(--c-cyan);color:var(--c-abyss)}
.btn--light:active{transform:translateY(1px)}
.btn--wa{background:var(--c-wa);color:#fff}
.btn--wa:hover{background:var(--c-wa-hover)}
.btn--wa:active{transform:translateY(1px)}
.btn[disabled],.btn[aria-disabled="true"]{opacity:.5;cursor:not-allowed;transform:none}
.btn-row{display:flex;flex-wrap:wrap;gap:var(--space-xs)}

/* ---- link with a drawn underline ---- */
.ulink{
  display:inline-flex;align-items:center;gap:8px;white-space:nowrap;
  font-family:var(--font-display);font-weight:600;font-size:var(--text-sm);color:var(--c-blue);
  border-bottom:2px solid var(--c-paper-3);padding-bottom:3px;
  transition:border-color var(--dur-fast) var(--ease-out),color var(--dur-fast) var(--ease-out);
}
.ulink:hover{border-color:var(--c-blue)}
.ulink svg{width:15px;height:15px;transition:transform var(--dur-fast) var(--ease-out)}
.ulink:hover svg{transform:translateX(3px)}

/* ---- wave separator ----------------------------------------------------
   The wordmark wave, reused as the top edge of every dark block: the CTA band,
   the brochure band, the photo band and the footer. It is filled with the
   colour of whatever sits ABOVE it, so it reads as the light page spilling
   down into the band rather than as a shape drawn on top of one. Set
   --wave-fill on the block if the thing above is not the page surface. */
.wave-top{
  position:absolute;left:0;right:0;top:0;z-index:3;
  width:100%;height:clamp(18px,2.4vw,36px);
  color:var(--wave-fill,var(--c-paper-2));
  transform:scaleY(-1);
  pointer-events:none;
}

/* Seam fix. The block's background and the wave share an edge, and when that
   edge lands on a fractional pixel mid-scroll both are anti-aliased into the
   same pixel row, so a dark hairline flickers along the wave. Painting a 1px
   page-coloured strip into the block's OWN background layer makes that row
   light, and the photo layers stop 1px short so they cannot bleed into it. */
.band:has(> .wave-top),.broch-band:has(> .wave-top),.on-dark:has(> .wave-top),
.site-foot:has(> .wave-top){
  background-image:linear-gradient(var(--wave-fill,var(--c-paper-2)) 0 1px,transparent 1px);
}
.cta-band:has(> .wave-top){
  background-image:linear-gradient(var(--wave-fill,var(--c-paper-2)) 0 1px,transparent 1px),
    linear-gradient(112deg,#0a4694 0%,#0c4d9e 48%,#1054ac 100%);
}
.band:has(> .wave-top) > .band__media,
.broch-band:has(> .wave-top) > .broch-band__media{top:1px}
/* the same seam on the hero and page-banner bottoms, where the wave sits last */
.hero:has(> .wave),.phero:has(> .wave){
  background-image:linear-gradient(to top,var(--c-paper-2) 0 1px,transparent 1px);
}
.hero:has(> .wave) > .hero__media,.phero:has(> .wave) > .phero__media{bottom:1px}

/* ============================ 5 - HEADER (N12) =========================== */
.site-head{position:sticky;top:0;z-index:100;background:var(--c-paper);
  border-bottom:var(--rule-hair) solid var(--c-rule)}
.utility{
  background:var(--c-navy);color:var(--c-on-dark);font-size:var(--text-xs);
  height:38px;overflow:hidden;
  transition:height var(--dur) var(--ease-out),opacity var(--dur) var(--ease-out);
}
.utility__in{display:flex;align-items:center;justify-content:space-between;gap:var(--space-md);height:38px}
.utility p{margin:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.utility__contact{display:flex;align-items:center;gap:10px;flex:none}
.utility__contact a{border-bottom:1px solid transparent;transition:border-color var(--dur-fast) var(--ease-out)}
.utility__contact a:hover{border-bottom-color:var(--c-cyan)}
.utility__sep{color:var(--c-on-dark-2)}
.is-condensed .utility{height:0;opacity:0}

/* min-height, not height: the brand carries its own padding, so the bar can
   never crush the lockup against its edges even if the type metrics shift. */
.nav-bar__in{display:flex;align-items:center;gap:var(--space-md);
  min-height:var(--head-h);transition:min-height var(--dur) var(--ease-out)}
.is-condensed .nav-bar__in{min-height:var(--head-h-condensed)}
/* The mark and its tagline are one lockup, so the brand is a column and the
   tagline is centred under the wordmark exactly as it sits in the logo file.
   The logo art itself carries no tagline; it is live text here so it stays
   crisp at every size and is read out with the link. */
.brand{flex:none;display:flex;flex-direction:column;align-items:center;gap:3px;
  padding-block:var(--brand-gutter)}
/* 2.49:1 - the 2026 mark is squarer than the one it replaced. Width came
   down rather than height going up, so --head-h and the hero calc that
   subtracts it are both untouched. */
.brand img{width:142px;height:57px;object-fit:contain;
  transition:width var(--dur) var(--ease-out),height var(--dur) var(--ease-out)}
/* --c-cyan is the logo's tagline colour but fails contrast on white, so the
   light band uses --c-blue-2 from the same brand ramp (5.69:1 on --c-paper-2) */
.brand__tagline{font-family:var(--font-display);font-weight:700;font-size:.6875rem;
  line-height:1;letter-spacing:.005em;color:var(--c-blue-2);white-space:nowrap}
.is-condensed .brand{padding-block:8px}
.is-condensed .brand img{width:132px;height:53px}

.nav{margin-left:auto}
.nav ul{display:flex;align-items:center;gap:clamp(14px,1.9vw,30px)}
.nav a{
  position:relative;display:block;padding:8px 0;white-space:nowrap;
  font-family:var(--font-display);font-size:var(--text-sm);font-weight:600;color:var(--c-ink);
  transition:color var(--dur-fast) var(--ease-out);
}
.nav a::after{
  content:"";position:absolute;left:0;right:0;bottom:0;height:2px;
  background:var(--c-blue);transform:scaleX(0);transform-origin:left;
  transition:transform var(--dur-fast) var(--ease-out);
}
.nav a:hover{color:var(--c-blue)}
.nav a:hover::after,.nav a[aria-current="page"]::after{transform:scaleX(1)}
.nav-cta{flex:none;padding:12px 22px}
.nav-toggle{
  display:none;flex:none;width:46px;height:46px;margin-left:auto;
  background:transparent;border:1px solid var(--c-rule);border-radius:var(--r);
  cursor:pointer;align-items:center;justify-content:center;
  transition:border-color var(--dur-fast) var(--ease-out)}
.nav-toggle:hover{border-color:var(--c-blue)}
.nav-toggle span{display:block;width:20px;height:2px;background:var(--c-ink);position:relative}
.nav-toggle span::before,.nav-toggle span::after{content:"";position:absolute;left:0;width:20px;height:2px;background:var(--c-ink);
  transition:transform var(--dur-fast) var(--ease-out),opacity var(--dur-fast) var(--ease-out)}
.nav-toggle span::before{top:-6px}
.nav-toggle span::after{top:6px}
.nav-toggle[aria-expanded="true"] span{background:transparent}
.nav-toggle[aria-expanded="true"] span::before{transform:translateY(6px) rotate(45deg)}
.nav-toggle[aria-expanded="true"] span::after{transform:translateY(-6px) rotate(-45deg)}

/* ============================ 6 - HERO =================================== */
/* short laptop viewports: trim the hero further so the slider controls stay
   above the fold rather than being the first thing the user has to scroll to */
@media (max-height:720px){
  .hero__in{padding-block:clamp(24px,3vw,40px)}
  .hero__ctl{margin-top:var(--space-md)}
  .hero .btn-row{margin-top:var(--space-md)}
}
/* Sized to the first screen: the header sits in flow above this, so the hero
   takes what is left of --head-h. svh keeps mobile browser chrome from
   pushing the controls out of sight. Content is centred in whatever height
   that works out to, so the hero never needs to be scrolled past. */
.hero{
  position:relative;background:var(--c-abyss);color:#fff;isolation:isolate;
  display:flex;flex-direction:column;
  min-height:calc(100vh - var(--head-h));
  min-height:calc(100svh - var(--head-h));
}
.hero > .wrap{flex:1;display:flex;align-items:center}
.hero__media{position:absolute;inset:0;z-index:-2;overflow:hidden}
.hero__media img{width:100%;height:100%;object-fit:cover;object-position:50% 58%}

/* --- hero slider: cross-fade, so nothing reflows between slides --- */
.hero__slide{position:absolute;inset:0;opacity:0;
  transition:opacity var(--dur-fade) var(--ease-in-out)}
.hero__slide picture,.hero__slide img{display:block;width:100%;height:100%}
/* The showreel layers on top of slide 1s image. The image underneath is the
   first paint, the buffering state, and the fallback when the video is blocked
   or motion is reduced, so it is never removed. */
.hero__video{
  position:absolute;inset:0;width:100%;height:100%;
  object-fit:cover;object-position:50% 58%;
  opacity:0;transition:opacity var(--dur-fade) var(--ease-in-out);
}
/* main.js adds this once the video is actually playing, so the image is never
   swapped out for a black rectangle */
.hero__video.is-playing{opacity:1}
/* nothing starts it without scripting, so take it out of the box tree entirely
   rather than leave an empty element over the photo */
html:not(.js) .hero__video{display:none}
.hero__slide.is-active{opacity:1}
/* with JS off only the first slide is painted, so the hero still looks right */
html:not(.js) .hero__slide:not(.is-active){display:none}

.hero__ctl{display:flex;align-items:center;gap:var(--space-xs);margin-top:var(--space-lg)}
.hero__ctl[hidden]{display:none}
.hbtn{
  flex:none;width:42px;height:42px;display:grid;place-items:center;cursor:pointer;
  background:rgba(255,255,255,.1);color:#fff;
  border:1px solid rgba(255,255,255,.45);border-radius:var(--r-pill);
  transition:background-color var(--dur-fast) var(--ease-out),
             color var(--dur-fast) var(--ease-out),
             border-color var(--dur-fast) var(--ease-out);
}
.hbtn svg{width:17px;height:17px}
.hbtn--prev svg{transform:rotate(180deg)}
.hbtn:hover{background:#fff;color:var(--c-navy);border-color:#fff}
.hbtn:active{transform:translateY(1px)}
.hero__dots{display:flex;gap:7px;margin-left:var(--space-2xs)}
.hdot{
  width:26px;height:4px;padding:0;border:0;border-radius:var(--r-pill);cursor:pointer;
  background:rgba(255,255,255,.34);
  transition:background-color var(--dur-fast) var(--ease-out),width var(--dur) var(--ease-out);
}
.hdot:hover{background:rgba(255,255,255,.6)}
.hdot[aria-selected="true"]{background:var(--c-cyan);width:38px}
/* Scrim is a left-to-right ramp so the water stays visible on the right while
   the headline column keeps AA contrast. Lightened twice from the original
   .93/.86/.62/.18 ramp, at the client's request.

   The shape changed as well as the numbers. The dark shelf now holds flat to
   56%, which is just past the right edge of the longest line of text, and then
   falls off far more steeply than it used to. That is what makes the water
   read brighter: the old ramp was still at .24 over at 75%, this one is at .09.
   The left-hand shelf cannot go much below .64 without the lead paragraph
   dropping under 4.5:1 on the brightest slide, so that is where it sits. See
   the contrast note at the bottom of tokens.css. */
.hero__media::after{
  content:"";position:absolute;inset:0;
  background:
    linear-gradient(90deg,rgba(1,18,44,.38) 0%,rgba(1,18,44,.30) 38%,
                          rgba(1,18,44,.12) 58%,rgba(1,18,44,0) 74%);
}
@media (max-width:760px){
  /* The phone layout runs text across the full width, so there is no bright
     side to open up: the scrim can only be lightened where no text sits. The
     stops track the text down the block - loose at the top and bottom, tight
     through the middle where the lead paragraph is. */
  .hero__media::after{
    background:linear-gradient(180deg,rgba(1,18,44,.22) 0%,rgba(1,18,44,.28) 28%,
                                      rgba(1,18,44,.34) 50%,rgba(2,14,34,.40) 100%);
  }
}
.hero__in{position:relative;width:100%;max-width:850px;
  padding-block:clamp(36px,5vw,72px) clamp(40px,5.4vw,80px)}
.hero h1{color:#fff}
/* light overlay, so a soft shadow keeps the text readable on bright frames */
.hero__in{text-shadow:0 1px 14px rgba(1,18,44,.5)}
.hero h1 .accent{color:var(--c-cyan)}
.hero__lead{margin-top:var(--space-sm);max-width:60ch;font-size:var(--text-lead);color:#e8f1fb;line-height:1.55}
.hero .btn-row{margin-top:var(--space-lg)}
.hero__note{margin-top:var(--space-sm);font-size:var(--text-sm);color:#d8e6f5}

/* hand-built wave, echoing the wordmark */
.wave{display:block;width:100%;height:clamp(28px,4vw,56px);position:relative;z-index:1;
  margin-bottom:-1px;color:var(--c-paper-2)}

/* ---- credential strip ----
   Four tiles rather than four table cells: each one is a white card on the page
   surface, with the numeral as the hero and a watermark copy of it behind. */
.creds{padding-block:var(--space-xl) var(--space-lg)}
.creds__grid{display:grid;gap:var(--space-sm);grid-template-columns:repeat(2,minmax(0,1fr))}
@media (min-width:860px){.creds__grid{grid-template-columns:repeat(4,minmax(0,1fr));gap:var(--space-md)}}

.creds__item{
  position:relative;min-width:0;overflow:hidden;isolation:isolate;
  padding:var(--space-md) var(--space-md) var(--space-md);
  background:var(--c-paper);border:var(--rule-hair) solid var(--c-rule);
  border-radius:var(--r-lg);box-shadow:var(--shadow-sm);
  transition:transform var(--dur) var(--ease-out),
             box-shadow var(--dur) var(--ease-out),
             border-color var(--dur) var(--ease-out);
}
@media (min-width:860px){.creds__item{padding:var(--space-lg)}}
/* the brand wave, cropped to a 3px cap on each tile */
.creds__item::before{
  content:"";position:absolute;left:0;right:0;top:0;height:3px;
  background:linear-gradient(90deg,var(--c-navy) 0%,var(--c-blue) 45%,var(--c-cyan) 100%);
  transform:scaleX(0);transform-origin:left;
  transition:transform var(--dur-slow) var(--ease-out);
}
.creds__item:hover{transform:translateY(-4px);box-shadow:var(--shadow-md);border-color:#c8d8e8}
.creds__item:hover::before{transform:scaleX(1)}

.creds__ic{
  width:38px;height:38px;display:grid;place-items:center;border-radius:var(--r);
  background:var(--c-paper-2);color:var(--c-blue);margin-bottom:var(--space-sm);
  transition:background-color var(--dur) var(--ease-out),color var(--dur) var(--ease-out);
}
.creds__ic svg{width:20px;height:20px}
.creds__item:hover .creds__ic{background:var(--c-navy);color:#fff}

.creds b{
  display:block;width:fit-content;font-family:var(--font-display);font-weight:700;
  font-size:clamp(2.6rem,1.9rem + 2.6vw,4.1rem);
  line-height:.94;letter-spacing:-.045em;
  background:linear-gradient(125deg,var(--c-navy) 0%,var(--c-blue) 48%,var(--c-cyan) 104%);
  -webkit-background-clip:text;background-clip:text;color:transparent;
}
/* the gradient fill needs a fallback wherever background-clip:text is not
   honoured, or the numbers would render invisible */
@supports not ((-webkit-background-clip:text) or (background-clip:text)){
  .creds b{background:none;color:var(--c-navy)}
}
.creds__label{
  display:block;margin-top:var(--space-2xs);max-width:24ch;
  font-size:var(--text-sm);line-height:1.45;color:var(--c-ink-2);
}

/* ============================ 7 - CRAFT ================================== */
.craft{display:grid;gap:var(--space-2xl);align-items:center}
@media (min-width:940px){
  .craft{grid-template-columns:minmax(0,.95fr) minmax(0,1fr);gap:clamp(48px,6vw,96px);
    align-items:stretch}
}
.craft__media{position:relative;min-width:0}
.craft__media img{width:100%;border-radius:var(--r-lg)}
.craft__media .a{aspect-ratio:4/5;object-fit:cover;box-shadow:var(--shadow-md)}
/* Two columns of equal height: the text column sets the row height and the
   photo fills it, cropping rather than stretching. Only above the two-column
   breakpoint - stacked, the photo keeps its own 4:5 proportion. */
@media (min-width:940px){
  .craft__media{display:flex}
  .craft__media .a{height:100%;aspect-ratio:auto;min-height:0}
}
.craft__media .b{
  position:absolute;right:0;bottom:-10%;width:47%;aspect-ratio:1/1;object-fit:cover;
  border:7px solid var(--c-paper);box-shadow:var(--shadow-lg);
}
/* the inset only breaks the column edge once the two-column layout gives it
   gutter room to land in - below that it would push past the viewport */
@media (min-width:940px){.craft__media .b{right:-6%}}
@media (max-width:560px){.craft__media .b{bottom:-8%;width:44%;border-width:5px}}
.craft__body h2 .accent{color:var(--c-blue)}
.craft__body p + p{margin-top:var(--space-md)}
.craft__body .lead{margin-top:var(--space-md)}
.craft__more{margin-top:var(--space-xl)}
.craft__more .btn svg{width:15px;height:15px;transition:transform var(--dur-fast) var(--ease-out)}
.craft__more .btn:hover svg{transform:translateX(3px)}

/* ============================ 8 - SERVICES (catalogue) =================== */
.cat{display:grid;gap:1px;background:var(--c-rule);border:var(--rule-hair) solid var(--c-rule);border-radius:var(--r-lg);overflow:hidden}
@media (min-width:660px){.cat{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (min-width:1000px){.cat{grid-template-columns:repeat(3,minmax(0,1fr))}}
.cat__item{
  background:var(--c-paper);padding:var(--space-xl) var(--space-lg);
  display:flex;flex-direction:column;gap:var(--space-xs);min-width:0;
  transition:background-color var(--dur) var(--ease-out);
}
.cat__item:hover{background:var(--c-paper-2)}
.cat__ic{width:58px;height:58px;display:grid;place-items:center;border-radius:var(--r);
  background:var(--c-paper-3);color:var(--c-navy);margin-bottom:var(--space-sm);
  transition:background-color var(--dur) var(--ease-out),color var(--dur) var(--ease-out)}
.cat__item:hover .cat__ic{background:var(--c-navy);color:#fff}
.cat__ic svg{width:30px;height:30px}
/* two-line floor keeps the card descriptions on a shared baseline across the row */
@media (min-width:660px){.cat__item h3{min-height:calc(2 * var(--lh-head) * 1em)}}
.cat__item h3{color:var(--c-ink)}
.cat__item p{color:var(--c-ink-2);font-size:var(--text-sm)}
/* ---- free consultation: full-bleed CTA band ----
   Full width so it reads as a page-level break, not a card inside the services
   section. Navy gradient rather than photography, so it stays distinct from
   .band further down, which is the photo treatment. */
/* Lightened at the client's request: the ramp used to start on --c-navy
   (#00337c) and finish on #0a4694. It now starts where it used to finish.
   No photograph behind this one, so the contrast is exact rather than
   worst-case: #c3d8ef body copy on the lightest stop is 4.99:1. Taking the
   end stop any brighter than #1054ac drops it under AA. */
.cta-band{
  position:relative;isolation:isolate;overflow:hidden;
  background:#0a4694;color:#fff;
  background-image:linear-gradient(112deg,#0a4694 0%,#0c4d9e 48%,#1054ac 100%);
}
/* the wave separator is shared; see section 4b */
.cta-band__glow{
  position:absolute;z-index:-1;pointer-events:none;
  right:-8%;top:-40%;width:min(620px,70vw);aspect-ratio:1;border-radius:50%;
  background:radial-gradient(circle,rgba(0,173,240,.26) 0%,rgba(0,173,240,.09) 45%,transparent 70%);
}

.cta-band__in{
  position:relative;
  display:grid;gap:var(--space-lg);align-items:center;
  padding-block:clamp(56px,6.4vw,92px) clamp(40px,5vw,72px);
}
@media (min-width:900px){
  .cta-band__in{grid-template-columns:minmax(0,1fr) auto;gap:clamp(32px,4.4vw,72px)}
}

.cta-band__body{display:flex;gap:var(--space-md);align-items:flex-start;min-width:0}
.cta-band__ic{
  flex:none;width:52px;height:52px;display:grid;place-items:center;border-radius:var(--r);
  background:rgba(255,255,255,.12);color:var(--c-cyan);
}
.cta-band__ic svg{width:26px;height:26px}
@media (max-width:560px){.cta-band__ic{display:none}}

.cta-band__eyebrow{
  font-family:var(--font-display);font-size:var(--text-micro);font-weight:600;
  letter-spacing:var(--track-label);text-transform:uppercase;color:#8ddbf9;
  margin-bottom:var(--space-2xs);
}
.cta-band h2{color:#fff;font-size:clamp(1.5rem,1.2rem + 1.4vw,2.35rem)}
.cta-band__lead{margin-top:var(--space-xs);color:#dbe8f8;font-size:var(--text-sm);max-width:56ch}

.cta-band__act{display:flex;flex-wrap:wrap;gap:var(--space-xs);align-items:center}
@media (min-width:900px){.cta-band__act{flex-direction:column;align-items:stretch;flex:none;width:272px}}
/* two nowrap buttons do not fit side by side on a phone, and relying on
   flex-wrap leaves a ragged row; stack them instead */
@media (max-width:680px){
  .cta-band__act{flex-direction:column;align-items:stretch}
  .cta-band__act .btn{width:100%}
}
.cta-band__act .btn{justify-content:center}

/* ============================ 9 - PROCESS (flow) =========================
 * A drawn timeline rather than five headings in a row. Each step has a numbered
 * node and a card; the connector between nodes draws itself left to right (top
 * to bottom on narrow screens) as the block scrolls in. Everything keys off the
 * .is-in class that the page's shared IntersectionObserver already adds, and
 * --i on each <li> staggers the sequence, so this costs no extra JS.
 * ---------------------------------------------------------------------- */
.flow{--flow-node:52px;--flow-beat:150ms;display:grid;gap:var(--space-lg)}
@media (min-width:860px){
  .flow{grid-template-columns:repeat(5,minmax(0,1fr));gap:var(--space-md);align-items:start}
}
.flow__step{position:relative;isolation:isolate;min-width:0;display:grid;gap:var(--space-sm)}
@media (min-width:860px){.flow__step{gap:var(--space-md)}}

/* --- node --- */
.flow__mark{
  position:relative;z-index:2;flex:none;
  width:var(--flow-node);height:var(--flow-node);display:grid;place-items:center;
  border-radius:var(--r-pill);
  background:var(--c-navy);border:2px solid var(--c-navy);color:#fff;
  box-shadow:0 6px 18px rgba(0,51,124,.28);
  transition:background-color 420ms var(--ease-out),border-color 420ms var(--ease-out),
             color 420ms var(--ease-out),box-shadow 420ms var(--ease-out),
             transform 420ms var(--ease-out);
  transition-delay:calc(var(--i) * var(--flow-beat));
}
.flow__num{font-family:var(--font-display);font-size:var(--text-sm);font-weight:700;
  letter-spacing:.02em;font-variant-numeric:tabular-nums}

/* the ring that pulses out once as the node lights up */
.flow__mark::after{
  content:"";position:absolute;inset:-2px;border-radius:inherit;
  border:2px solid var(--c-blue);opacity:0;transform:scale(1);
}

/* --- connector --- */
.flow__step:not(:last-child)::before{
  content:"";position:absolute;z-index:1;background:var(--c-blue);
  transform-origin:left;
  transition:transform 520ms var(--ease-out);
  transition-delay:calc(var(--i) * var(--flow-beat) + 200ms);
}
/* the unfilled rail the connector draws along */
.flow__step:not(:last-child)::after{
  content:"";position:absolute;z-index:0;background:var(--c-paper-3);
}
@media (min-width:860px){
  .flow__step:not(:last-child)::before,
  .flow__step:not(:last-child)::after{
    left:calc(var(--flow-node) + 8px);
    right:calc(8px - var(--space-md));
    top:calc(var(--flow-node) / 2 - 1px);height:2px;
  }
}
@media (max-width:859px){
  .flow{gap:0}
  .flow__step{grid-template-columns:var(--flow-node) minmax(0,1fr);
    align-items:start;gap:var(--space-md);padding-bottom:var(--space-lg)}
  .flow__step:not(:last-child)::before,
  .flow__step:not(:last-child)::after{
    left:calc(var(--flow-node) / 2 - 1px);width:2px;
    top:calc(var(--flow-node) + 8px);bottom:8px;
  }
  .flow__step:last-child{padding-bottom:0}
}

/* --- card --- */
.flow__card{
  min-width:0;padding:var(--space-md);
  background:var(--c-paper);border:var(--rule-hair) solid var(--c-rule);
  border-radius:var(--r-lg);
  transition:opacity 520ms var(--ease-out),transform 520ms var(--ease-out),
             box-shadow var(--dur) var(--ease-out),border-color var(--dur) var(--ease-out);
  transition-delay:calc(var(--i) * var(--flow-beat) + 90ms);
}
@media (min-width:860px){.flow__card{padding:var(--space-md) var(--space-sm) var(--space-lg) 0;
  background:transparent;border:0;border-radius:0;padding-right:var(--space-md)}}
.flow__card h3{margin-bottom:var(--space-2xs);color:var(--c-ink)}
.flow__card p{font-size:var(--text-sm);color:var(--c-ink-2)}

/* --- start state ---
   Scoped to .js, because .is-in is the only thing that undoes it and only JS
   ever adds .is-in. With scripting off the rules above stand on their own and
   render a finished timeline rather than five invisible cards. */
.js .flow__mark{background:var(--c-paper);border-color:var(--c-rule);
  color:var(--c-ink-2);box-shadow:none}
.js .flow__step:not(:last-child)::before{transform:scaleX(0)}
.js .flow__card{opacity:0;transform:translateY(14px)}
/* narrow screens draw the rail downward instead of rightward */
@media (max-width:859px){
  .js .flow__step:not(:last-child)::before{transform:scaleY(0);transform-origin:top}
}

/* --- the scrolled-into-view state --- */
.js .flow.is-in .flow__mark{
  background:var(--c-navy);border-color:var(--c-navy);color:#fff;
  box-shadow:0 6px 18px rgba(0,51,124,.28);
}
.js .flow.is-in .flow__mark::after{
  animation:flow-ring 900ms var(--ease-out) forwards;
  animation-delay:calc(var(--i) * var(--flow-beat));
}
.js .flow.is-in .flow__step:not(:last-child)::before{transform:scale(1)}
.js .flow.is-in .flow__card{opacity:1;transform:none}

@keyframes flow-ring{
  0%  {opacity:.55;transform:scale(1)}
  100%{opacity:0;transform:scale(1.55)}
}

/* the reveal wrapper would otherwise fade the whole block in a second time,
   on top of the per-step choreography */
.js .flow.reveal{opacity:1;transform:none;transition:none}

/* ============================ 9b - MEDIA HOVER (.mfx) ===================
 * Replaces the plain scale() zoom that every photo on the page used to share.
 * Instead: the frame holds a constant slight overscale so there is room to
 * move, and on hover the photo drifts upward like water pulling back from an
 * edge while a caustic-style sheen sweeps across it and the colour lifts.
 * Nothing changes size, so the effect reads as light and motion, not as zoom.
 * ---------------------------------------------------------------------- */
.mfx{position:relative;overflow:hidden}
.mfx img{
  /* the constant 1.045 is headroom for the drift, NOT a hover zoom:
     it never changes, so no edge gap can appear as the photo moves */
  transform:scale(1.045);
  filter:saturate(.93) brightness(.98);
  transition:transform 760ms var(--ease-out),filter 620ms var(--ease-out);
}
/* the sheen. ::before sits above the static <img> but below any positioned
   child that comes later in the DOM (the sector scrim, the gallery caption) */
.mfx::before{
  content:"";position:absolute;inset:-12% -35%;pointer-events:none;
  background:linear-gradient(104deg,
    transparent 40%,
    rgba(255,255,255,.30) 47%,
    rgba(186,234,255,.20) 52%,
    rgba(255,255,255,.12) 57%,
    transparent 66%);
  opacity:0;transform:translateX(-115%);
  /* snaps back invisibly when the pointer leaves, so it only ever sweeps
     in one direction */
  transition:opacity 180ms linear,transform 0s linear 180ms;
}

.mfx:hover img,
.mfx:focus-within img,
.scard:hover .mfx img,
.post:hover .mfx img{
  transform:scale(1.045) translateY(-2.6%);
  filter:saturate(1.1) brightness(1.05) contrast(1.02);
}
.mfx:hover::before,
.mfx:focus-within::before,
.scard:hover .mfx::before,
.post:hover .mfx::before{
  opacity:1;transform:translateX(115%);
  transition:opacity 220ms linear,transform 1000ms var(--ease-out);
}

/* ============================ 10 - SECTORS =============================== */
.sectors{display:grid;gap:var(--space-md)}
@media (min-width:820px){.sectors{grid-template-columns:repeat(3,minmax(0,1fr))}}
.sector{
  position:relative;min-width:0;overflow:hidden;border-radius:var(--r-lg);
  background:var(--c-abyss);isolation:isolate;
  transition:transform var(--dur) var(--ease-out),box-shadow var(--dur) var(--ease-out);
}
.sector:hover{transform:translateY(-3px);box-shadow:var(--shadow-lg)}
.sector img{width:100%;aspect-ratio:3/4;object-fit:cover}
@media (min-width:820px){.sector img{aspect-ratio:3/4.2}}
.sector__scrim{position:absolute;inset:0;
  background:linear-gradient(180deg,rgba(0,22,56,.04) 30%,rgba(0,22,56,.48) 66%,rgba(2,14,32,.78) 100%)}
.sector__txt{position:absolute;left:0;right:0;bottom:0;padding:var(--space-lg);color:#fff}
.sector__txt h3{color:#fff;margin-bottom:6px}
.sector__txt p{font-size:var(--text-sm);color:#cddef0}

/* ============================ 11 - BAND (photo CTA) ====================== */
.band{position:relative;background:var(--c-abyss);color:#fff;isolation:isolate;overflow:hidden}
.band__media{position:absolute;inset:0;z-index:-2}
.band__media img{width:100%;height:100%;object-fit:cover}
/* No dark scrim: the photograph shows at full brightness. The text carries
   its own soft shadow instead so it stays readable on a daytime image. */
.band__in{text-shadow:0 1px 3px rgba(1,18,44,.55),0 2px 18px rgba(1,18,44,.55)}
.band__in{padding-block:clamp(64px,8vw,110px);max-width:640px}
.band h2{color:#fff}
.band p{margin-top:var(--space-md);color:#fff;font-size:var(--text-lead)}
.band .btn-row{margin-top:var(--space-xl)}

/* ============================ 12 - WHY (dark) ============================ */
.on-dark{background:var(--c-abyss);color:var(--c-on-dark)}
.on-dark h2,.on-dark h3{color:#fff}
.reasons{display:grid;gap:1px;background:var(--c-rule-dark);
  border:1px solid var(--c-rule-dark);border-radius:var(--r-lg);overflow:hidden}
@media (min-width:680px){.reasons{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (min-width:1000px){.reasons{grid-template-columns:repeat(3,minmax(0,1fr))}}
.reasons li{background:var(--c-abyss);padding:var(--space-lg);min-width:0;
  transition:background-color var(--dur) var(--ease-out)}
.reasons li:hover{background:var(--c-abyss-2)}
.reasons h3{font-size:1.0625rem;margin-bottom:6px;display:flex;gap:10px;align-items:baseline}
.reasons h3 svg{width:16px;height:16px;flex:none;color:var(--c-cyan);transform:translateY(2px)}
.reasons p{font-size:var(--text-sm);color:var(--c-on-dark-2)}

/* vision / mission / values */
.vmv{margin-top:var(--space-2xl);display:grid;gap:var(--space-xl)}
@media (min-width:860px){.vmv{grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--space-2xl)}}
.vmv h3{font-size:var(--text-micro);letter-spacing:var(--track-label);text-transform:uppercase;
  color:var(--c-cyan);font-weight:600;margin-bottom:var(--space-sm)}
.vmv p{color:var(--c-on-dark);font-size:var(--text-sm);line-height:1.62}
.vmv ul{display:flex;flex-wrap:wrap;gap:8px;margin-top:var(--space-sm)}
.vmv li{font-family:var(--font-display);font-size:var(--text-xs);font-weight:600;
  padding:5px 12px;border:1px solid var(--c-rule-dark);border-radius:var(--r-pill);color:var(--c-on-dark)}

/* ============================ 13 - GALLERY =============================== */
.gal{display:grid;gap:var(--space-sm);grid-template-columns:repeat(2,minmax(0,1fr))}
@media (min-width:900px){.gal{grid-template-columns:repeat(4,minmax(0,1fr));gap:var(--space-md)}}
.gal figure{position:relative;margin:0;min-width:0;overflow:hidden;border-radius:var(--r);background:var(--c-paper-3)}
.gal img{width:100%;height:100%;object-fit:cover;aspect-ratio:1/1}
@media (min-width:900px){
  .gal .w2{grid-column:span 2}
  .gal .w2 img{aspect-ratio:2/1}
}
.gal figcaption{
  position:absolute;left:0;right:0;bottom:0;padding:var(--space-md) var(--space-sm) var(--space-sm);
  font-family:var(--font-display);font-size:var(--text-xs);font-weight:600;color:#fff;
  background:linear-gradient(180deg,rgba(0,20,52,0) 0%,rgba(0,20,52,.66) 100%);
}

/* ============================ 14 - GUIDES ================================ */
.posts{display:grid;gap:var(--space-xl)}
@media (min-width:760px){.posts{grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--space-md)}}
.post{min-width:0;display:flex;flex-direction:column;
  transition:transform var(--dur) var(--ease-out)}
.post:hover{transform:translateY(-3px)}
.post__img{border-radius:var(--r);background:var(--c-paper-3);margin-bottom:var(--space-md)}
.post__img img{width:100%;aspect-ratio:16/10;object-fit:cover}
.post__tag{font-family:var(--font-display);font-size:var(--text-micro);font-weight:600;
  letter-spacing:var(--track-label);text-transform:uppercase;color:var(--c-blue);margin-bottom:var(--space-2xs)}
.post h3{margin-bottom:var(--space-2xs)}
.post p{font-size:var(--text-sm);color:var(--c-ink-2)}
.post .ulink{margin-top:var(--space-md);align-self:flex-start}

/* ============================ 15 - CONTACT =============================== */
/* a form standing on its own, with no companion column beside it */
.form-solo{max-width:760px;margin-inline:auto}

/* ---- .contact / .contact__side ------------------------------------------
   No page uses these at the moment: contact.html used to pair the enquiry
   form with a column of steps and office hours, and that column was cut. Kept
   because it is self-contained and a form-plus-sidebar layout is the likeliest
   thing an inner page will want. Markup is a .contact wrapper holding a
   .contact__side (h3 + dl of .row > dt/dd, optional .sub spans) and the form. */
.contact{display:grid;gap:var(--space-2xl)}
.contact > *{min-width:0}
@media (min-width:940px){.contact{grid-template-columns:minmax(0,.85fr) minmax(0,1.15fr);gap:clamp(48px,6vw,88px)}}
.contact__side dl{margin:var(--space-xl) 0 0}
.contact__side .row{padding:var(--space-md) 0;border-top:var(--rule-hair) solid var(--c-rule)}
.contact__side dt{font-family:var(--font-display);font-size:var(--text-micro);font-weight:600;
  letter-spacing:var(--track-label);text-transform:uppercase;color:var(--c-ink-2);margin-bottom:6px}
/* `anywhere` (not `break-word`) so the email address does not set a
   min-content floor that pushes the grid track past the 320px gutter box */
.contact__side dd{margin:0;font-family:var(--font-display);font-weight:600;font-size:1.0625rem;
  overflow-wrap:anywhere}
.contact__side dd a{color:var(--c-navy);border-bottom:2px solid var(--c-paper-3);
  transition:border-color var(--dur-fast) var(--ease-out)}
.contact__side dd a:hover{border-bottom-color:var(--c-blue)}
.contact__side .sub{display:block;font-family:var(--font-body);font-weight:400;font-size:var(--text-sm);
  color:var(--c-ink-2);margin-top:4px}

.form{background:var(--c-paper);border:var(--rule-hair) solid var(--c-rule);
  border-radius:var(--r-lg);padding:clamp(20px,3.6vw,40px);box-shadow:var(--shadow-sm)}
.form__grid{display:grid;gap:var(--space-md)}
@media (min-width:600px){.form__grid{grid-template-columns:repeat(2,minmax(0,1fr))}.field--wide{grid-column:1/-1}}
.field{display:flex;flex-direction:column;gap:6px;min-width:0}
.field label{font-family:var(--font-display);font-size:var(--text-xs);font-weight:600;
  letter-spacing:.04em;text-transform:uppercase;color:var(--c-ink-2)}
.field .req{color:var(--c-blue)}
.field input,.field select,.field textarea{
  width:100%;padding:5px;background:var(--c-paper);
  border:1px solid var(--c-rule);border-radius:var(--r);
  font-size:var(--text-body);color:var(--c-ink);
  transition:border-color var(--dur-fast) var(--ease-out),box-shadow var(--dur-fast) var(--ease-out);
}
.field textarea{resize:vertical;min-height:118px}
.field select{appearance:none;cursor:pointer;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5l5-5' fill='none' stroke='%234a5b6e' stroke-width='1.6' stroke-linecap='round'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right 8px center;background-size:12px;padding-right:26px}
.field input:hover,.field select:hover,.field textarea:hover{border-color:#c3d2e2}
.field input:focus,.field select:focus,.field textarea:focus{
  outline:none;border-color:var(--c-blue);box-shadow:0 0 0 3px rgba(0,96,192,.16)}
.field input:focus-visible,.field select:focus-visible,.field textarea:focus-visible{outline:none}
.field input[disabled],.field textarea[disabled]{background:var(--c-paper-2);cursor:not-allowed}
.field .err{font-size:var(--text-xs);color:#b3261e;min-height:0}
.field[data-invalid="true"] input,.field[data-invalid="true"] select,.field[data-invalid="true"] textarea{
  border-color:#b3261e;box-shadow:0 0 0 3px rgba(179,38,30,.13)}
.form__foot{margin-top:var(--space-lg);display:flex;flex-wrap:wrap;align-items:center;gap:var(--space-md)}
.form__foot .btn{flex:none}
.form__hint{font-size:var(--text-sm);color:var(--c-ink-2);max-width:40ch}
.form__status{margin-top:var(--space-md);font-size:var(--text-sm);font-weight:600;color:var(--c-wa)}
.form__status:empty{display:none}
.hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}

/* ============================ 16 - FOOTER (Ft5) ========================== */
.site-foot{position:relative;background:var(--c-navy);color:var(--c-on-dark);
  padding-block:var(--space-3xl) var(--space-xl)}
.foot__top{display:grid;gap:var(--space-2xl);padding-bottom:var(--space-2xl);
  border-bottom:1px solid var(--c-rule-dark)}
.foot__top > *{min-width:0}
/* four columns: brand / services / pages / contact. Two-up in the middle so
   the lists do not sit as one very long ribbon on a tablet. */
@media (min-width:620px){.foot__top{grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--space-xl)}}
@media (min-width:1000px){
  .foot__top{grid-template-columns:minmax(0,1.25fr) minmax(0,.85fr) minmax(0,.6fr) minmax(0,.95fr);
    gap:var(--space-xl)}
}
.foot__brand img{width:190px;height:76px;object-fit:contain;object-position:left}
/* On navy, --c-cyan is the logo's own tagline colour and clears AA (4.67:1),
   so the footer keeps it. Centred under the logo, matching the lockup. */
.foot__tagline{width:190px;text-align:center;margin-top:6px;font-family:var(--font-display);font-weight:700;
  font-size:.8125rem;line-height:1;letter-spacing:.005em;color:var(--c-cyan)}
.foot__statement{margin-top:var(--space-md);font-family:var(--font-display);font-weight:600;
  font-size:1rem;line-height:1.5;letter-spacing:0;color:#fff;max-width:34ch}
.foot h2{font-family:var(--font-display);font-size:var(--text-micro);font-weight:600;
  letter-spacing:var(--track-label);text-transform:uppercase;color:#7fb4e8;margin:0 0 var(--space-md)}
.foot__list li{font-size:var(--text-sm);color:var(--c-on-dark-2);padding:4px 0}
/* the rows are links now. No underline, so hover shifts them to cyan instead,
   matching the contact column directly beside them. */
.foot__list a{display:inline-block;transition:color var(--dur-fast) var(--ease-out)}
.foot__list a:hover{color:var(--c-cyan)}
.foot__list a[aria-current="page"]{color:#fff;font-weight:600}
.foot__contact li{display:flex;gap:10px;align-items:flex-start;padding:7px 0;font-size:var(--text-sm)}
.foot__contact li svg{width:16px;height:16px;flex:none;color:var(--c-cyan);margin-top:3px}
/* No underline. These are still links, so hover shifts them to cyan rather
   than leaving no affordance at all; keyboard users get the global focus ring. */
.foot__contact a{color:#fff;font-family:var(--font-display);font-weight:600;overflow-wrap:anywhere;
  transition:color var(--dur-fast) var(--ease-out)}
.foot__contact a:hover{color:var(--c-cyan)}

/* social row */
.foot__social{display:flex;flex-wrap:wrap;gap:10px;margin-top:var(--space-md)}
.foot__social a{
  width:40px;height:40px;display:grid;place-items:center;border-radius:var(--r-pill);
  background:rgba(255,255,255,.09);color:#fff;
  border:1px solid var(--c-rule-dark);
  transition:background-color var(--dur-fast) var(--ease-out),
             color var(--dur-fast) var(--ease-out),
             border-color var(--dur-fast) var(--ease-out),
             transform var(--dur-fast) var(--ease-out);
}
.foot__social svg{width:19px;height:19px}
.foot__social a:hover{background:var(--c-cyan);color:var(--c-abyss);border-color:var(--c-cyan);transform:translateY(-2px)}
.foot__social a:active{transform:translateY(0)}
/* <address> is only a semantic wrapper here; the rows style themselves */
.site-foot address{font-style:normal}
.foot__bar{display:flex;flex-wrap:wrap;gap:var(--space-sm) var(--space-md);
  justify-content:space-between;align-items:center;padding-top:var(--space-lg);
  font-size:var(--text-xs);color:var(--c-on-dark-2)}
.foot__credit a{
  color:#fff;font-family:var(--font-display);font-weight:600;
  border-bottom:1px solid rgba(255,255,255,.3);
  transition:color var(--dur-fast) var(--ease-out),border-color var(--dur-fast) var(--ease-out);
}
.foot__credit a:hover{color:var(--c-cyan);border-bottom-color:var(--c-cyan)}
/* on narrow screens the credit gets its own line under the other two */
@media (max-width:760px){
  .foot__bar{flex-direction:column;align-items:flex-start;gap:var(--space-2xs)}
  .foot__credit{margin-top:var(--space-2xs)}
}

/* ============================ 17 - STICKY ACTIONS ======================== */
.rail{position:fixed;right:20px;bottom:24px;z-index:90;display:none;flex-direction:column;gap:12px}
@media (min-width:641px){.rail{display:flex}}
.rail a{
  position:relative;width:54px;height:54px;border-radius:var(--r-pill);
  display:grid;place-items:center;color:#fff;box-shadow:var(--shadow-md);
  transition:transform var(--dur-fast) var(--ease-out),background-color var(--dur-fast) var(--ease-out);
}
.rail a:hover{transform:translateY(-3px)}
.rail a:active{transform:translateY(0)}
.rail svg{width:26px;height:26px}
.rail .r-wa{background:var(--c-wa)}
.rail .r-wa:hover{background:var(--c-wa-hover)}
.rail .r-call{background:var(--c-blue)}
.rail .r-call:hover{background:var(--c-blue-hover)}
.rail .tip{
  position:absolute;right:calc(100% + 12px);top:50%;transform:translateY(-50%) translateX(6px);
  background:var(--c-abyss);color:#fff;font-family:var(--font-display);font-size:var(--text-xs);
  font-weight:600;white-space:nowrap;padding:7px 12px;border-radius:var(--r);
  opacity:0;pointer-events:none;
  transition:opacity var(--dur-fast) var(--ease-out),transform var(--dur-fast) var(--ease-out);
}
.rail a:hover .tip,.rail a:focus-visible .tip{opacity:1;transform:translateY(-50%) translateX(0)}

.dock{
  position:fixed;left:0;right:0;bottom:0;z-index:90;display:grid;grid-template-columns:1fr 1fr;
  box-shadow:0 -2px 14px rgba(10,22,40,.16);
}
@media (min-width:641px){.dock{display:none}}
.dock a{
  display:flex;align-items:center;justify-content:center;gap:9px;
  padding:15px 8px;color:#fff;font-family:var(--font-display);font-weight:600;font-size:var(--text-sm);
  white-space:nowrap;
}
.dock svg{width:19px;height:19px;flex:none}
.dock .d-call{background:var(--c-blue)}
.dock .d-call:active{background:var(--c-blue-press)}
.dock .d-wa{background:var(--c-wa)}
.dock .d-wa:active{background:var(--c-wa-hover)}
@media (max-width:640px){body{padding-bottom:56px}}

/* ============================ 18 - REVEAL ================================ */
/* fade-in-up / fade-in-down, in the spirit of WOW.js + animate.css but built
   on the page's own IntersectionObserver - no library, no extra request. */
.js .reveal{
  opacity:0;transform:translateY(30px);
  transition:opacity var(--dur-reveal) var(--ease-out),
             transform var(--dur-reveal) var(--ease-out);
  will-change:opacity,transform;
}
.js .reveal[data-anim="down"]{transform:translateY(-30px)}
.js .reveal[data-anim="left"]{transform:translateX(30px)}
.js .reveal.is-in{opacity:1;transform:none;will-change:auto}
.js .reveal[data-d="1"]{transition-delay:90ms}
.js .reveal[data-d="2"]{transition-delay:180ms}
.js .reveal[data-d="3"]{transition-delay:270ms}
.js .reveal[data-d="4"]{transition-delay:360ms}
.js .reveal[data-d="5"]{transition-delay:450ms}
.js .reveal[data-d="6"]{transition-delay:540ms}

/* ============================ 18b - COUNTER ============================== */
.creds b{font-variant-numeric:tabular-nums}

/* ============================ 18c - CAROUSEL ============================= */
.carousel{position:relative}
/* The viewport bleeds into the page gutter so cards can scroll off-screen
   edge to edge. scroll-padding-inline is what makes a snapped card line up
   with the page's content column instead of the bled edge - without it every
   snap lands one gutter-width too far left. */
.carousel__viewport{
  overflow-x:auto;overflow-y:hidden;scroll-snap-type:x mandatory;
  scroll-behavior:smooth;scrollbar-width:none;-ms-overflow-style:none;
  margin-inline:calc(var(--gutter) * -1);padding-inline:var(--gutter);
  scroll-padding-inline:var(--gutter);
}
.carousel__viewport::-webkit-scrollbar{display:none}
.carousel__viewport:focus-visible{outline:3px solid var(--c-focus);outline-offset:-3px;border-radius:var(--r-lg)}
.carousel__track{display:flex;gap:var(--space-md);align-items:stretch}
.carousel__track > li{
  flex:0 0 calc((100% - var(--space-md) * 2) / 3);
  min-width:0;scroll-snap-align:start;
}
@media (max-width:900px){
  .carousel__track > li{flex-basis:calc((100% - var(--space-md)) / 2)}
}
@media (max-width:600px){
  .carousel__track > li{flex-basis:100%}
}

/* service card */
.scard{
  display:flex;flex-direction:column;height:100%;
  background:var(--c-paper);border:var(--rule-hair) solid var(--c-rule);
  border-radius:var(--r-lg);overflow:hidden;
  transition:transform var(--dur) var(--ease-out),box-shadow var(--dur) var(--ease-out),
             border-color var(--dur) var(--ease-out);
}
.scard:hover{transform:translateY(-4px);box-shadow:var(--shadow-md);border-color:#c8d8e8}
/* .scard__img must NOT clip: the icon badge hangs half out of its bottom
   edge. The clipping moved down to .scard__shot, which wraps only the photo,
   so the hover effect is still contained but the badge is not cut in half. */
.scard__img{position:relative;background:var(--c-paper-3);overflow:visible}
.scard__shot{display:block;border-radius:0}
.scard__img img{width:100%;aspect-ratio:3/2;object-fit:cover}
.scard__ic{
  position:absolute;z-index:2;left:var(--space-md);bottom:0;transform:translateY(50%);
  width:52px;height:52px;display:grid;place-items:center;border-radius:var(--r);
  background:var(--c-navy);color:#fff;box-shadow:var(--shadow-md);
}
.scard__ic svg{width:26px;height:26px}
.scard__body{padding:calc(var(--space-lg) + 10px) var(--space-md) var(--space-lg);
  display:flex;flex-direction:column;gap:var(--space-2xs);flex:1}
.scard__body h3{color:var(--c-ink)}
.scard__body p{color:var(--c-ink-2);font-size:var(--text-sm)}

/* controls */
.carousel__ctl{display:flex;align-items:center;gap:var(--space-sm);margin-top:var(--space-lg)}
.cbtn{
  flex:none;width:46px;height:46px;display:grid;place-items:center;cursor:pointer;
  background:var(--c-paper);color:var(--c-navy);
  border:1px solid var(--c-rule);border-radius:var(--r-pill);
  transition:background-color var(--dur-fast) var(--ease-out),
             color var(--dur-fast) var(--ease-out),
             border-color var(--dur-fast) var(--ease-out);
}
.cbtn svg{width:19px;height:19px}
.cbtn:hover:not([disabled]){background:var(--c-navy);color:#fff;border-color:var(--c-navy)}
.cbtn:active:not([disabled]){transform:translateY(1px)}
.cbtn[disabled]{opacity:.38;cursor:not-allowed}
.cbtn--prev svg{transform:rotate(180deg)}
.carousel__dots{display:flex;gap:8px;margin-inline:auto}
.cdot{
  width:28px;height:5px;padding:0;cursor:pointer;border:0;border-radius:var(--r-pill);
  background:var(--c-paper-3);
  transition:background-color var(--dur-fast) var(--ease-out),width var(--dur) var(--ease-out);
}
.cdot:hover{background:#c2d4e6}
.cdot[aria-selected="true"]{background:var(--c-blue);width:40px}
.carousel__live{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0)}

/* ============================ 18d - BROCHURE BAND ======================= *
 * Full-bleed, with photography behind a heavy navy duotone scrim. The scrim
 * does the work: it keeps the block reading as the navy brochure block it was,
 * so it does not turn into a second version of .band further down the page.
 * ---------------------------------------------------------------------- */
.broch-band{
  position:relative;isolation:isolate;overflow:hidden;
  background:var(--c-navy);color:#fff;
}
.broch-band__media{position:absolute;inset:0;z-index:-2}
.broch-band__media img{width:100%;height:100%;object-fit:cover}
/* Lightened from .96/.90/.82. This one cannot open up as far as the others:
   the copy runs almost the full width of the band, so there is no stretch of
   photograph without text over it. */
.broch-band__media::after{
  content:"";position:absolute;inset:0;
  background:
    linear-gradient(104deg,rgba(0,45,110,.80) 0%,rgba(0,51,124,.72) 48%,rgba(10,70,148,.62) 100%),
    linear-gradient(180deg,rgba(0,26,64,.10) 0%,rgba(0,26,64,0) 40%);
}

.broch-band__in{
  position:relative;display:grid;gap:var(--space-lg);align-items:center;
  padding-block:clamp(48px,5.6vw,80px);
}
@media (min-width:860px){
  .broch-band__in{grid-template-columns:minmax(0,1fr) auto;gap:clamp(32px,4.4vw,72px)}
}

.broch-band__body{display:flex;gap:var(--space-md);align-items:flex-start;min-width:0}
.broch__ic{
  flex:none;width:54px;height:54px;display:grid;place-items:center;border-radius:var(--r);
  background:rgba(255,255,255,.12);color:var(--c-cyan);
}
.broch__ic svg{width:28px;height:28px}
@media (max-width:560px){.broch__ic{display:none}}

.broch-band h2{color:#fff;font-size:clamp(1.5rem,1.2rem + 1.4vw,2.1rem)}
.broch-band p{margin-top:var(--space-xs);color:#dceafa;max-width:58ch;font-size:var(--text-sm)}

.broch-band__act{display:flex;flex-direction:column;align-items:flex-start;gap:var(--space-2xs)}
@media (min-width:860px){.broch-band__act{flex:none;align-items:stretch;width:272px}}
@media (max-width:680px){.broch-band__act .btn{width:100%}}
.broch-band__act .btn{justify-content:center}
.broch__meta{display:block;font-size:var(--text-xs);color:#eaf1f9;text-align:center;width:100%}

/* ============================ 18e - MODAL ================================ */
.modal[hidden]{display:none}
.modal{position:fixed;inset:0;z-index:120;display:grid;place-items:center;padding:var(--space-sm)}
.modal__backdrop{position:absolute;inset:0;background:rgba(4,16,36,.62);
  opacity:0;transition:opacity var(--dur) var(--ease-out)}
.modal__panel{
  position:relative;width:min(100%,520px);max-height:calc(100dvh - 32px);overflow-y:auto;
  background:var(--c-paper);border-radius:var(--r-lg);box-shadow:var(--shadow-lg);
  padding:clamp(22px,3.4vw,38px);
  opacity:0;transform:translateY(16px) scale(.985);
  transition:opacity var(--dur) var(--ease-out),transform var(--dur) var(--ease-out);
}
.modal.is-open .modal__backdrop{opacity:1}
.modal.is-open .modal__panel{opacity:1;transform:none}
.modal__x{
  position:absolute;top:12px;right:12px;width:38px;height:38px;cursor:pointer;
  display:grid;place-items:center;background:transparent;border:0;border-radius:var(--r);
  color:var(--c-ink-2);transition:background-color var(--dur-fast) var(--ease-out),color var(--dur-fast) var(--ease-out);
}
.modal__x:hover{background:var(--c-paper-2);color:var(--c-ink)}
.modal__x svg{width:18px;height:18px}
.modal h2{font-size:clamp(1.35rem,1.15rem + .8vw,1.7rem);padding-right:34px}
.modal__intro{margin-top:var(--space-2xs);color:var(--c-ink-2);font-size:var(--text-sm)}
.modal form{margin-top:var(--space-lg)}
.modal .field + .field{margin-top:var(--space-md)}
.modal .btn{width:100%;margin-top:var(--space-lg)}
.modal__note{margin-top:var(--space-sm);font-size:var(--text-xs);color:var(--c-ink-2);text-align:center}
.modal__status{margin-top:var(--space-md);font-size:var(--text-sm);font-weight:600;
  color:var(--c-wa);text-align:center}
.modal__status:empty{display:none}
body.is-locked{overflow:hidden}

/* ========================================================================= *
 *  18f-18l  INNER PAGES
 *  Everything below here was added for about / services / gallery / contact.
 *  index.html does not use any of it, so nothing in this block may restyle a
 *  class the homepage already relies on.
 * ========================================================================= */

/* ============================ 18f - PAGE HERO ============================ *
 * The short banner at the top of every page that is not the homepage. Same
 * ingredients as .hero (photo, navy ramp, wordmark wave on the bottom edge)
 * but sized to its content rather than to the viewport, so the first section
 * of the page is always partly visible on load.
 * ------------------------------------------------------------------------ */
.phero{position:relative;isolation:isolate;overflow:hidden;
  background:var(--c-abyss);color:#fff;display:flex;flex-direction:column}
.phero__media{position:absolute;inset:0;z-index:-2}
.phero__media img{width:100%;height:100%;object-fit:cover;object-position:50% 56%}
/* Gallery and blog banners: the pool sits in the lower half of the photo, so crop low. */
.phero__media--pool img{object-position:50% 72%}
/* Same shape as the homepage ramp and lightened the same way: flat over the
   text column, then a steep falloff so the photograph carries the right-hand
   side of the banner. */
.phero__media::after{
  content:"";position:absolute;inset:0;
  background:
    linear-gradient(100deg,rgba(1,18,44,.40) 0%,rgba(1,18,44,.32) 40%,
                           rgba(1,18,44,.12) 62%,rgba(1,18,44,0) 80%);
}
@media (max-width:760px){
  .phero__media::after{
    background:linear-gradient(180deg,rgba(1,18,44,.22) 0%,rgba(1,18,44,.30) 45%,rgba(2,14,34,.40) 100%);
  }
}
.phero__in{position:relative;max-width:840px;
  padding-block:clamp(34px,4.4vw,66px) clamp(44px,5.4vw,82px)}
.phero h1{color:#fff}
/* the overlay is light now, so a soft shadow keeps the text readable on bright photos */
.phero__in{text-shadow:0 1px 14px rgba(1,18,44,.45)}
.phero h1 .accent{color:var(--c-cyan)}
.phero__lead{margin-top:var(--space-sm);max-width:62ch;
  font-size:var(--text-lead);color:#e8f1fb;line-height:1.55}
.phero .btn-row{margin-top:var(--space-lg)}
.phero__note{margin-top:var(--space-sm);font-size:var(--text-sm);color:#d8e6f5}

/* breadcrumb trail, only ever on a dark banner */
/* #cfe0f2 rather than the #9dbbdd used on flat navy: this is 12px text sitting
   on a photograph, and the lighter scrim does not leave room for a dimmer grey */
.crumbs{display:flex;flex-wrap:wrap;align-items:center;gap:9px;margin-bottom:var(--space-md);
  font-family:var(--font-display);font-size:var(--text-micro);font-weight:600;
  letter-spacing:var(--track-label);text-transform:uppercase;color:#cfe0f2}
.crumbs li{display:flex;align-items:center;gap:9px}
.crumbs a{border-bottom:1px solid transparent;
  transition:color var(--dur-fast) var(--ease-out),border-color var(--dur-fast) var(--ease-out)}
.crumbs a:hover{color:#fff;border-bottom-color:var(--c-cyan)}
.crumbs [aria-current="page"]{color:var(--c-cyan)}
.crumbs svg{width:12px;height:12px;flex:none;opacity:.6}

/* ============================ 18g - SERVICE GRID ========================= *
 * The services page shows the same .scard the homepage carousel uses, laid
 * out as a static grid instead. .scard itself is untouched; this only adds
 * the container and the spec list inside the card body.
 * ------------------------------------------------------------------------ */
.scards{display:grid;gap:var(--space-md);grid-template-columns:minmax(0,1fr)}
@media (min-width:640px){.scards{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (min-width:1020px){.scards{grid-template-columns:repeat(3,minmax(0,1fr))}}
/* deep links (services.html#infinity-edge) must clear the sticky header */
.scards > li{scroll-margin-top:120px}
.scard__list{margin-top:var(--space-2xs);display:flex;flex-direction:column;gap:7px}
.scard__list li{position:relative;padding-left:19px;font-size:var(--text-sm);color:var(--c-ink-2)}
.scard__list li::before{
  content:"";position:absolute;left:0;top:.62em;width:7px;height:7px;border-radius:50%;
  background:var(--c-blue);box-shadow:0 0 0 3px rgba(0,96,192,.14);
}
/* the "01 / 13" marker in the card's top corner */
.scard__no{
  position:absolute;z-index:2;top:var(--space-xs);right:var(--space-xs);
  padding:5px 11px;border-radius:var(--r-pill);
  background:rgba(4,16,36,.62);color:#fff;
  font-family:var(--font-display);font-size:var(--text-micro);font-weight:700;
  letter-spacing:var(--track-label);
}

/* a jump list of every service, sat under the services page intro */
.jump{display:flex;flex-wrap:wrap;gap:var(--space-2xs)}
.jump a{
  display:inline-flex;align-items:center;gap:8px;padding:8px 15px;border-radius:var(--r-pill);
  background:var(--c-paper);border:var(--rule-hair) solid var(--c-rule);
  font-family:var(--font-display);font-size:var(--text-xs);font-weight:600;color:var(--c-ink-2);
  transition:color var(--dur-fast) var(--ease-out),border-color var(--dur-fast) var(--ease-out),
             background-color var(--dur-fast) var(--ease-out);
}
.jump a svg{width:15px;height:15px;color:var(--c-blue);flex:none}
.jump a:hover{color:var(--c-navy);border-color:var(--c-blue);background:#fff}

/* ============================ 18h - FILTER CHIPS ========================= */
.chips{display:flex;flex-wrap:wrap;gap:var(--space-2xs);margin-bottom:var(--space-lg)}
.chip{
  cursor:pointer;padding:9px 18px;border-radius:var(--r-pill);
  background:var(--c-paper);border:var(--rule-hair) solid var(--c-rule);color:var(--c-ink-2);
  font-family:var(--font-display);font-size:var(--text-sm);font-weight:600;
  transition:color var(--dur-fast) var(--ease-out),border-color var(--dur-fast) var(--ease-out),
             background-color var(--dur-fast) var(--ease-out);
}
.chip:hover{color:var(--c-blue);border-color:var(--c-blue)}
.chip[aria-pressed="true"]{background:var(--c-navy);border-color:var(--c-navy);color:#fff}
.chip[aria-pressed="true"]:hover{background:var(--c-navy-soft);border-color:var(--c-navy-soft);color:#fff}
/* filtering is a JS enhancement: with scripting off every tile stays visible */
.gal figure[hidden]{display:none}
/* A gallery tile that opens the lightbox wraps its photo in a button. The
   <figcaption> stays a direct child of the <figure> (it has to be), which
   means it lies over the button, so it must not swallow the click. */
.gal .gbtn{display:block;width:100%;height:100%;padding:0;border:0;background:none;
  cursor:zoom-in;color:inherit;text-align:left}
.gal .gbtn:focus-visible{outline-offset:-3px}
.gal figcaption{pointer-events:none}
.gal__empty{padding:var(--space-xl) 0;color:var(--c-ink-2);text-align:center}
.gal__empty[hidden]{display:none}

/* ============================ 18i - LIGHTBOX ============================= */
.lbx[hidden]{display:none}
.lbx{position:fixed;inset:0;z-index:130;display:grid;place-items:center;
  padding:clamp(12px,3vw,44px)}
.lbx__backdrop{position:absolute;inset:0;background:rgba(3,12,28,.90);
  opacity:0;transition:opacity var(--dur) var(--ease-out)}
.lbx__fig{position:relative;margin:0;max-width:min(1120px,100%);
  opacity:0;transform:scale(.985);
  transition:opacity var(--dur) var(--ease-out),transform var(--dur) var(--ease-out)}
.lbx.is-open .lbx__backdrop{opacity:1}
.lbx.is-open .lbx__fig{opacity:1;transform:none}
.lbx__fig img{width:auto;margin-inline:auto;max-width:100%;
  max-height:calc(100dvh - 190px);border-radius:var(--r-lg);box-shadow:var(--shadow-lg)}
.lbx__cap{margin-top:var(--space-sm);text-align:center;
  font-family:var(--font-display);font-weight:600;font-size:var(--text-sm);color:#fff}
.lbx__cap span{display:block;margin-top:5px;
  font-family:var(--font-body);font-weight:400;font-size:var(--text-xs);color:#9dbbdd}
.lbx__x{position:absolute;top:calc(var(--space-sm) * -1 - 30px);right:0}
@media (max-width:640px){.lbx__x{top:calc(var(--space-sm) * -1 - 26px)}}
.lbx__ctl{display:flex;align-items:center;justify-content:center;
  gap:var(--space-xs);margin-top:var(--space-md)}
.lbx__count{font-family:var(--font-display);font-size:var(--text-xs);font-weight:600;
  letter-spacing:var(--track-label);color:#9dbbdd;min-width:66px;text-align:center}

/* ============================ 18j - CONTACT PAGE ========================= */
.cinfo{display:grid;gap:var(--space-md);grid-template-columns:minmax(0,1fr)}
@media (min-width:640px){.cinfo{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (min-width:1020px){.cinfo{grid-template-columns:repeat(4,minmax(0,1fr))}}
.cinfo__item{
  display:flex;flex-direction:column;gap:var(--space-2xs);min-width:0;
  background:var(--c-paper);border:var(--rule-hair) solid var(--c-rule);
  border-radius:var(--r-lg);padding:var(--space-lg);
  transition:transform var(--dur) var(--ease-out),box-shadow var(--dur) var(--ease-out),
             border-color var(--dur) var(--ease-out);
}
.cinfo__item:hover{transform:translateY(-4px);box-shadow:var(--shadow-md);border-color:#c8d8e8}
.cinfo__ic{
  width:46px;height:46px;display:grid;place-items:center;border-radius:var(--r);
  background:var(--c-paper-2);color:var(--c-blue);margin-bottom:var(--space-2xs);
  transition:background-color var(--dur) var(--ease-out),color var(--dur) var(--ease-out);
}
.cinfo__ic svg{width:22px;height:22px}
.cinfo__item:hover .cinfo__ic{background:var(--c-navy);color:#fff}
.cinfo__item h3{font-size:var(--text-micro);font-weight:600;letter-spacing:var(--track-label);
  text-transform:uppercase;color:var(--c-ink-2)}
.cinfo__item .val{font-family:var(--font-display);font-weight:700;font-size:1.0625rem;
  color:var(--c-navy);line-height:1.34;overflow-wrap:anywhere}
.cinfo__item .val a{border-bottom:2px solid var(--c-paper-3);
  transition:border-color var(--dur-fast) var(--ease-out)}
.cinfo__item .val a:hover{border-bottom-color:var(--c-blue)}
.cinfo__item .sub{font-size:var(--text-sm);color:var(--c-ink-2);margin-top:auto;padding-top:var(--space-2xs)}

/* ---- map ----------------------------------------------------------------
   Google's embed is a third-party request, and the rest of the site makes
   none, so it is not in the markup. The panel below is the whole map area
   until someone presses the button; main.js then swaps in the iframe. The
   "Open in Google Maps" link works either way, scripting or not. */
.map{position:relative;border-radius:var(--r-lg);overflow:hidden;
  border:var(--rule-hair) solid var(--c-rule);background:var(--c-paper);box-shadow:var(--shadow-sm)}
.map__ph{display:grid;place-items:center;gap:var(--space-sm);text-align:center;
  min-height:clamp(280px,34vw,420px);padding:var(--space-xl) var(--space-md);
  background:
    radial-gradient(circle at 26% 30%,rgba(0,173,240,.13),transparent 58%),
    radial-gradient(circle at 74% 72%,rgba(0,96,192,.13),transparent 58%),
    var(--c-paper-2);
}
.map__ph > div{display:grid;justify-items:center;gap:var(--space-2xs)}
.map__ic{width:52px;height:52px;display:grid;place-items:center;border-radius:var(--r);
  background:var(--c-navy);color:#fff}
.map__ic svg{width:26px;height:26px}
.map__addr{font-family:var(--font-display);font-weight:700;font-size:1.0625rem;color:var(--c-navy)}
.map__note{font-size:var(--text-sm);color:var(--c-ink-2);max-width:44ch}
.map__acts{display:flex;flex-wrap:wrap;gap:var(--space-2xs);justify-content:center;margin-top:var(--space-2xs)}
.map iframe{display:block;width:100%;height:clamp(280px,34vw,420px);border:0}

/* ---- hours ---- */
/* ---- opening hours list -------------------------------------------------
   Also unused now: it sat in the contact page's side column. The hours
   themselves still appear on the "Call the office" card, so nothing was lost
   from the page. Markup is a <ul class="hours"> of li > .day + .time. */
.hours{margin-top:var(--space-md)}
.hours li{display:flex;justify-content:space-between;gap:var(--space-md);
  padding:10px 0;border-top:var(--rule-hair) solid var(--c-rule);font-size:var(--text-sm)}
.hours li:first-child{border-top:0}
.hours dt,.hours .day{color:var(--c-ink-2)}
.hours .time{font-family:var(--font-display);font-weight:600;color:var(--c-ink);white-space:nowrap}

/* ---- FAQ ----------------------------------------------------------------
   No page uses this at the moment: it was built for contact.html and the
   section was cut. Kept because it is self-contained and an FAQ block is the
   likeliest thing the next page will want. Markup is a .faq wrapper holding
   <details> elements, each a <summary> plus a <p class="faq__a">. */
.faq{display:grid;gap:var(--space-2xs)}
.faq details{background:var(--c-paper);border:var(--rule-hair) solid var(--c-rule);
  border-radius:var(--r);overflow:hidden}
.faq details[open]{border-color:#c8d8e8;box-shadow:var(--shadow-sm)}
.faq summary{cursor:pointer;list-style:none;display:flex;align-items:center;
  justify-content:space-between;gap:var(--space-sm);padding:var(--space-md);
  font-family:var(--font-display);font-weight:600;color:var(--c-ink)}
.faq summary::-webkit-details-marker{display:none}
.faq summary::after{content:"";flex:none;width:9px;height:9px;
  border-right:2px solid var(--c-blue);border-bottom:2px solid var(--c-blue);
  transform:rotate(45deg) translate(-2px,-2px);
  transition:transform var(--dur) var(--ease-out)}
.faq details[open] summary::after{transform:rotate(-135deg) translate(-2px,-2px)}
.faq summary:hover{color:var(--c-blue)}
.faq .faq__a{padding:0 var(--space-md) var(--space-md);color:var(--c-ink-2);font-size:var(--text-sm)}

/* ============================ 18k - ABOUT PAGE =========================== */
/* .on-dark carries a wave on the inner pages, which needs a containing block */
.section.on-dark{position:relative;isolation:isolate}
/* the wave sits over the section's own padding, so push the content clear */
.section.on-dark > .wrap{position:relative;z-index:1}

.pullq{max-width:900px;margin-inline:auto;text-align:center}
.pullq .tick{margin-inline:auto}
.pullq blockquote{margin:0;font-family:var(--font-display);font-weight:600;
  font-size:clamp(1.3rem,1.02rem + 1.2vw,1.95rem);line-height:1.32;letter-spacing:-.022em;
  color:var(--c-navy);text-wrap:balance}
.pullq cite{display:block;margin-top:var(--space-md);font-style:normal;
  font-family:var(--font-display);font-weight:600;font-size:var(--text-micro);
  letter-spacing:var(--track-label);text-transform:uppercase;color:var(--c-ink-2)}

/* a two-up photo strip, used once on the about page */
.duo{display:grid;gap:var(--space-md)}
@media (min-width:760px){.duo{grid-template-columns:repeat(2,minmax(0,1fr))}}
.duo figure{margin:0;min-width:0;border-radius:var(--r-lg);overflow:hidden;background:var(--c-paper-3)}
.duo img{width:100%;aspect-ratio:16/10;object-fit:cover}

/* ============================ 18l - SHARED BITS ========================== */
/* a centred section head, for pages that do not use the split layout */
.s-head--center{justify-items:center;text-align:center}
.s-head--center p{margin-inline:auto}
.s-head--center .tick{margin-inline:auto}
@media (min-width:900px){.s-head--center{grid-template-columns:minmax(0,1fr)}}
/* the current page in the primary nav */
.nav a[aria-current="page"]{color:var(--c-blue)}
/* a centred "see all of it" button closing off a preview section */
.more-row{margin-top:var(--space-xl);display:flex;justify-content:center}
.more-row .btn svg{transition:transform var(--dur-fast) var(--ease-out)}
.more-row .btn:hover svg{transform:translateX(3px)}

/* ============================ 18m - BLOG ================================= *
 * blogs.php and blog.php. The listing reuses .posts / .post unchanged; only
 * the pager, the article body and the prev/next pair are new.
 * ------------------------------------------------------------------------ */

/* the whole card is the link on the listing, so the hover moves as one */
.post__link{display:flex;flex-direction:column;height:100%;color:inherit}
.post__link h3{transition:color var(--dur-fast) var(--ease-out)}
.post:hover .post__link h3{color:var(--c-blue)}
.post__link:focus-visible{outline-offset:6px}

/* ---- pager ---- */
.pager{margin-top:var(--space-2xl);display:flex;flex-wrap:wrap;align-items:center;
  justify-content:center;gap:var(--space-sm)}
.pager__step{display:inline-flex;align-items:center;gap:8px;padding:10px 16px;
  border-radius:var(--r-pill);border:var(--rule-hair) solid var(--c-rule);
  background:var(--c-paper);color:var(--c-ink);
  font-family:var(--font-display);font-weight:600;font-size:var(--text-sm);
  transition:border-color var(--dur-fast) var(--ease-out),color var(--dur-fast) var(--ease-out)}
.pager__step svg{width:16px;height:16px}
.pager__step--prev svg{transform:rotate(180deg)}
.pager__step:hover{border-color:var(--c-blue);color:var(--c-blue)}
.pager__step[aria-disabled="true"]{opacity:.4;pointer-events:none}
.pager__nums{display:flex;flex-wrap:wrap;gap:6px;align-items:center}
.pager__n{display:grid;place-items:center;min-width:40px;height:40px;padding:0 10px;
  border-radius:var(--r-pill);border:var(--rule-hair) solid var(--c-rule);
  background:var(--c-paper);color:var(--c-ink-2);
  font-family:var(--font-display);font-weight:600;font-size:var(--text-sm);
  transition:border-color var(--dur-fast) var(--ease-out),color var(--dur-fast) var(--ease-out),
             background-color var(--dur-fast) var(--ease-out)}
.pager__n:hover{border-color:var(--c-blue);color:var(--c-blue)}
.pager__n[aria-current="page"]{background:var(--c-navy);border-color:var(--c-navy);color:#fff}
@media (max-width:520px){
  .pager__step span{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0)}
  .pager__step{padding:10px 13px}
}

/* ---- single article ---- */
.article__head{margin-top:var(--space-md)}
.article__meta{font-family:var(--font-display);font-size:var(--text-micro);font-weight:600;
  letter-spacing:var(--track-label);text-transform:uppercase;color:var(--c-ink-2);
  display:flex;flex-wrap:wrap;gap:8px;align-items:center;margin-bottom:var(--space-sm)}
.article h1{font-size:clamp(1.9rem,1.4rem + 2.2vw,3.1rem)}
.article__hero{margin:var(--space-xl) 0 0;border-radius:var(--r-lg);overflow:hidden;
  background:var(--c-paper-3)}
.article__hero img{width:100%;aspect-ratio:16/8.5;object-fit:cover}

/* breadcrumbs on a light page rather than a photo */
.crumbs--ink{color:var(--c-ink-2)}
.crumbs--ink a:hover{color:var(--c-blue);border-bottom-color:var(--c-blue)}
.crumbs--ink [aria-current="page"]{color:var(--c-ink);
  display:block;max-width:34ch;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* the body measure. 68ch inside the 740px narrow wrap reads at about 72
   characters a line, which is where long-form comfort sits. */
.prose{margin-top:var(--space-2xl);max-width:68ch}
.prose p{font-size:1.09rem;line-height:1.72;color:var(--c-ink)}
.prose p + p{margin-top:var(--space-md)}
.prose a{color:var(--c-blue);border-bottom:1px solid var(--c-paper-3)}
.prose a:hover{border-bottom-color:var(--c-blue)}

/* The admin editor can emit headings, lists, quotes and code, so the article
   body has to style more than paragraphs. Without these an <h2> would inherit
   the page-level heading size and land at 3rem mid-article. */
.prose h2{font-size:clamp(1.4rem,1.2rem + .7vw,1.75rem);line-height:1.22;
  margin:var(--space-2xl) 0 var(--space-sm)}
.prose h3{font-size:clamp(1.15rem,1.05rem + .4vw,1.35rem);line-height:1.3;font-weight:600;
  margin:var(--space-xl) 0 var(--space-xs)}
.prose > :first-child{margin-top:0}
.prose ul,.prose ol{margin:var(--space-md) 0;padding-left:1.35em;
  font-size:1.09rem;line-height:1.72;color:var(--c-ink)}
.prose ul{list-style:disc}
.prose ol{list-style:decimal}
.prose li{margin-bottom:var(--space-2xs);padding-left:.2em}
.prose li::marker{color:var(--c-blue)}
.prose blockquote{margin:var(--space-lg) 0;padding:var(--space-2xs) 0 var(--space-2xs) var(--space-md);
  border-left:3px solid var(--c-cyan);color:var(--c-ink-2);
  font-size:1.12rem;line-height:1.68}
.prose blockquote p{color:inherit;font-size:inherit}
.prose strong{font-weight:700}
.prose pre{margin:var(--space-lg) 0;padding:var(--space-md);overflow-x:auto;
  background:var(--c-paper-2);border:var(--rule-hair) solid var(--c-rule);border-radius:var(--r);
  font-family:var(--font-mono);font-size:.92rem;line-height:1.6;color:var(--c-ink)}
.prose code{font-family:var(--font-mono);font-size:.92em;
  background:var(--c-paper-2);border:var(--rule-hair) solid var(--c-rule);
  border-radius:var(--r-sm);padding:.1em .35em}
.prose pre code{background:none;border:0;padding:0;font-size:inherit}

.article__foot{margin-top:var(--space-2xl);padding-top:var(--space-lg);
  border-top:var(--rule-hair) solid var(--c-rule);
  display:flex;flex-wrap:wrap;gap:var(--space-md);align-items:center;
  justify-content:space-between}
.article__sig{font-family:var(--font-display);line-height:1.4}
.article__sig strong{display:block;color:var(--c-navy);font-size:1.0625rem}
.article__sig span{font-size:var(--text-sm);font-weight:600;color:var(--c-blue)}

/* ---- prev / next ---- */
.adjacent{margin-top:var(--space-2xl);display:grid;gap:var(--space-sm)}
@media (min-width:700px){.adjacent{grid-template-columns:repeat(2,minmax(0,1fr))}}
.adjacent__item{display:flex;flex-direction:column;gap:6px;min-width:0;
  padding:var(--space-md);border-radius:var(--r-lg);
  background:var(--c-paper);border:var(--rule-hair) solid var(--c-rule);
  transition:transform var(--dur) var(--ease-out),box-shadow var(--dur) var(--ease-out),
             border-color var(--dur) var(--ease-out)}
.adjacent__item:hover{transform:translateY(-3px);box-shadow:var(--shadow-md);border-color:#c8d8e8}
/* when there is only a next, keep it in the right-hand column */
.adjacent__item--next:only-child{grid-column:2}
@media (max-width:699px){.adjacent__item--next:only-child{grid-column:1}}
.adjacent__dir{display:flex;align-items:center;gap:7px;
  font-family:var(--font-display);font-size:var(--text-micro);font-weight:600;
  letter-spacing:var(--track-label);text-transform:uppercase;color:var(--c-ink-2)}
.adjacent__dir svg{width:14px;height:14px;color:var(--c-blue)}
.adjacent__item--prev .adjacent__dir svg{transform:rotate(180deg)}
.adjacent__item--next{text-align:right}
.adjacent__item--next .adjacent__dir{justify-content:flex-end}
.adjacent__title{font-family:var(--font-display);font-weight:600;font-size:1.0625rem;
  color:var(--c-ink);overflow-wrap:anywhere}
.adjacent__item:hover .adjacent__title{color:var(--c-blue)}

/* ---- homepage strip, filled from api/latest.php ---- */
/* Hidden until the fetch resolves, so a failed request leaves no empty
   section rather than three broken cards. */
.js .posts[data-latest-posts]:empty{display:none}
.posts[data-latest-posts]:empty + .more-row{display:none}

/* ============================ 19 - MOBILE NAV ============================ */
@media (max-width:1000px){
  .nav-toggle{display:flex}
  /* a transform/opacity panel, not a 0fr->1fr grid: `fr` resolves to 0 inside
     an absolutely positioned container, and `visibility` keeps the links out
     of the tab order while the menu is closed */
  .nav{
    position:absolute;left:0;right:0;top:100%;margin:0;
    background:var(--c-paper);border-bottom:var(--rule-hair) solid var(--c-rule);
    box-shadow:var(--shadow-md);
    opacity:0;visibility:hidden;transform:translateY(-10px);
    transition:opacity var(--dur) var(--ease-out),
               transform var(--dur) var(--ease-out),
               visibility 0s linear var(--dur);
  }
  .nav[data-open="true"]{
    opacity:1;visibility:visible;transform:none;
    transition:opacity var(--dur) var(--ease-out),
               transform var(--dur) var(--ease-out),
               visibility 0s;
  }
  .nav > ul{flex-direction:column;align-items:stretch;gap:0;
    padding-inline:var(--gutter);padding-block:var(--space-2xs) var(--space-sm)}
  .nav li{border-top:var(--rule-hair) solid var(--c-rule)}
  .nav li:first-child{border-top:0}
  .nav a{padding:15px 0;font-size:1.0625rem}
  .nav a::after{display:none}
  .nav-cta{display:none}
}
/* drop the tagline before it is narrow enough to truncate mid-sentence */
@media (max-width:820px){
  .utility p:first-child{display:none}
  .utility__in{justify-content:center}
}
@media (max-width:420px){
  .utility__contact .u-mail,.utility__sep{display:none}
  /* keep the lockup clear of the menu button on the narrowest phones */
  .brand img,.is-condensed .brand img{width:126px;height:50px}
  .brand__tagline{font-size:.625rem}
}

/* ============================ 20 - REDUCED MOTION ======================== */
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{
    animation-duration:1ms !important;animation-iteration-count:1 !important;
    transition-duration:120ms !important;
  }
  .js .reveal{opacity:1;transform:none;transition:opacity 120ms linear}
  .sector:hover{transform:none}
  .post:hover,.rail a:hover{transform:none}
  /* the media hover keeps only the colour lift; no drift, no sheen sweep */
  .mfx img{transform:none;filter:none}
  .mfx:hover img,.mfx:focus-within img,
  .scard:hover .mfx img,.post:hover .mfx img{transform:none;filter:saturate(1.06)}
  .mfx::before,.mfx:hover::before,.mfx:focus-within::before,
  .scard:hover .mfx::before,.post:hover .mfx::before{display:none}
  /* the process timeline draws itself instantly */
  .flow__mark,.flow__card,.flow__step::before{transition-delay:0s !important}
  .flow__card{opacity:1;transform:none}
  .flow.is-in .flow__mark::after{animation:none}
  .creds__item:hover{transform:none}
  /* the carousel stops auto-advancing in JS; this kills the smooth-scroll jump */
  .carousel__viewport{scroll-behavior:auto}
  .scard:hover{transform:none}
  .modal__panel{transform:none}
  .hero__video{display:none}
}

/* ============================ 21 - PRINT ================================= */
@media print{
  .site-head,.rail,.dock,.band,.hero__media,.wave-top{display:none}
  body{color:#000;background:#fff}
  .section{padding-block:18px}
}

/* values mosaic (about) */
.vals{display:grid;gap:var(--space-sm);grid-template-columns:minmax(0,1fr)}
@media (min-width:660px){.vals{grid-template-columns:repeat(2,minmax(0,1fr))}.vals__item--lead{grid-column:span 2}}
@media (min-width:1000px){.vals{grid-template-columns:repeat(4,minmax(0,1fr));grid-auto-rows:minmax(260px,auto)}
  .vals__item--lead{grid-column:span 2;grid-row:span 2}.vals__item--wide{grid-column:span 2}}
.vals__item{position:relative;overflow:hidden;border-radius:var(--r-lg);min-height:280px;
  display:flex;align-items:flex-end;background:var(--c-abyss);isolation:isolate}
.vals__item img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;z-index:-2;
  transition:transform var(--dur-slow) var(--ease-out)}
/* Illustrations that must be seen whole: show the full image on the right
   instead of cropping it, and let the card's dark ground fill the rest. */
.vals__item--fit img{object-fit:contain;object-position:right center}
.vals__item::before{content:"";position:absolute;inset:0;z-index:-1;
  background:linear-gradient(to top,color-mix(in oklab,var(--c-abyss) 92%,transparent) 0%,color-mix(in oklab,var(--c-abyss) 55%,transparent) 45%,transparent 80%)}
.vals__item:hover img{transform:scale(1.04)}
.vals__body{padding:var(--space-lg);color:var(--c-on-dark)}
.vals__body h3{color:var(--c-on-dark);margin:0 0 var(--space-2xs)}
.vals__body p{color:var(--c-on-dark-2);margin:0;max-width:40ch;font-size:var(--text-sm)}
.vals__item--lead .vals__body h3{font-size:var(--text-h2)}
.vals__item--lead .vals__body p{font-size:var(--text-body)}
@media (prefers-reduced-motion:reduce){.vals__item img{transition:none}.vals__item:hover img{transform:none}}
.craft__media .a{object-position:62% center}
