@charset "UTF-8";
/* ===================================================================
   VIKING MEDICAL SERVICES — DESIGN SYSTEM  (alternative direction)
   ===================================================================

   One stylesheet for the whole site. There is no build step: pages are
   hand-written HTML that share this file.

   WHAT THIS VERSION CHANGES, AND WHY
   The previous direction executed restraint as "pick the safest value
   everywhere", which read as a smaller-budget corporate template rather
   than a deliberate alternative to one. This version keeps the sober
   register, the hairlines and the tight radii, and commits harder to a
   smaller number of decisions:

     - one horizontal axis. Section headings sit on the container's left
       gutter, not on a centred spine. Centring survives in one place:
       the closing CTA band.
     - one real type step. H1 is roughly 1.8x H2 at desktop, so page
       level and section level are never mistaken for each other.
     - one accent with a job. The ochre is no longer decoration on a
       10px label; it marks every "this is a label / this is a numbered
       thing / this is the current page" moment on the site.
     - one background. Sections no longer alternate white and grey by
       position. A contrasting band now means something.
     - three buttons. Not four treatments for the same action class.

   HOW TO CHANGE THE COLOURS
   Every colour on the site is a variable in the :root block below.
   Change it there and it changes everywhere. Do not hard-code hex
   values in a page or in a component rule.

   COMPONENT INDEX  (search for the ==== banner to jump to one)
     1.  Tokens ................ :root colour, type, space, motion
     2.  Base .................. resets, typography, links, .wrap
     3.  Header ................ .site-header .brand .main-nav .nav-toggle
     4.  Buttons ............... .btn .btn-primary .btn-secondary
     5.  Hero — home ........... .hero (the aurora, left axis)
     6.  Hero — interior ....... .page-hero .breadcrumbs .eyebrow
     7.  Doors ................. .doors .door (the two-audience split)
     8.  Panels ................ .panel-grid .panel .panel-list
     9.  Cards ................. .card-grid .card
     10. Reasons ............... .reasons .reason (why-choose-us list)
     10b.Arrival ............... .arrival .map-card (find-us block, homepage)
     11. Steps ................. .steps .step (numbered how-it-works)
     12. Prose ................. .prose (guide and policy body copy)
     13. Facts ................. .fact-table .callout .note
     13b.Figures ............... .figures (the one number that goes big)
     14. FAQ ................... details.faq
     15. People ................ .person .person-row .person-photo .badge
     15b.Photography ........... .figure .media-split .media-band .slot
     16. Quote ................. .pullquote
     16b.Claim ................. .claim-block (the type-only set piece)
     17. CTA band .............. .cta
     18. Footer ................ .site-footer
     19. Utilities and motion .. .stack .visually-hidden .reveal
     20. Form .................. .enquiry-form .field .hp
   =================================================================== */


/* ====================================================================
   1. TOKENS
   ==================================================================== */

/* Self-hosted so there is no third-party font request on any page.
   Both are variable fonts, latin subset. Bricolage Grotesque is the
   display face and Instrument Sans the text face; that pairing is
   unchanged from the previous direction because it already does the
   job a display face is meant to do. */
@font-face{
  font-family:'Bricolage Grotesque'; font-style:normal;
  font-weight:200 800; font-stretch:75% 100%; font-display:swap;
  src:url(fonts/bricolage.woff2) format('woff2');
}
@font-face{
  font-family:'Instrument Sans'; font-style:normal;
  font-weight:400 700; font-stretch:75% 100%; font-display:swap;
  src:url(fonts/instrument.woff2) format('woff2');
}

:root{
  /* --- THE PALETTE ------------------------------------------------
     Six tokens carry the whole site, plus three for the dark grounds.
     Every colour below resolves to one of them. Contrast figures are
     measured, not estimated, and are quoted against the ground the
     colour is actually used on.

       --navy      #355069  brand exact, from the logo files
       --ink       #1B2E3D  body copy            13.9:1 on paper
       --ink-soft  #4E6272  secondary copy        5.6:1 on ground
       --link      #2E6B78  brand teal, darkened  5.3:1 on ground
       --accent    #2E6B78  brand teal, darkened  5.3:1 on ground
       --ground    #EEF1F4  the one page ground
       --paper     #FFFFFF  cards, panels, tables
       --line      #D3DCE2  the single hairline value
     Dark grounds:
       --band      #22384A / --band-deep #162836 / --ice #D8DFE2

     Note on brand teal. The logo's exact teal is #71ADB5. It is 2.5:1
     on white and 2.2:1 on the page ground, so it can never carry text
     on a light surface. On the dark bands it reaches 4.8:1, so that is
     where it carries text, as --accent-lift. On light grounds the same
     teal darkened to #2E6B78 does the work.

     There used to be an ochre accent here, #8A5E17. It was the only
     hue on the site that did not come from the logo, which made it a
     fourth voice belonging to nothing else, while the brand's own teal
     was rationed down to a single non-text use. The accent is now teal
     on both grounds, so the whole site resolves to navy, teal and ice. */

  --navy:#355069;
  --teal:#71ADB5;       /* brand exact. Aurora curtains only, see 5. */
  --ice:#D8DFE2;

  /* The aurora, and the only colours on the site darker than
     --band-deep. The homepage hero is the deepest point on the site by
     design, so the page lifts out of it. */
  --aurora-deep:#080F16;
  --aurora-rise:#0C1A26;
  --aurora-mid:#123043;
  --aurora-base:#1B3346;

  --ink:#1B2E3D;
  --ink-soft:#4E6272;
  --link:#2E6B78;       /* brand teal, darkened to clear 4.5:1 on light */
  --link-hover:#1B2E3D;

  /* The accent, committed to rather than tolerated. #B07A28 was 3.3:1
     on the page ground and failed at label sizes; this is 5.0:1. */
  --accent:#2E6B78;   /* brand teal, darkened. 5.3:1 on the ground   */
  --accent-lift:#71ADB5;   /* brand exact. 4.8:1 on the dark bands     */

  --ground:#EEF1F4;
  --paper:#FFFFFF;
  --line:#D3DCE2;
  --line-soft:#E4EAEE;
  --band:#22384A;
  --band-deep:#162836;

  /* --- TYPE SCALE --------------------------------------------------
     Fluid, with a real step between levels. At 1440px this resolves to
     64 / 50 / 36 / 22px, so page level and section level can never be
     confused for one another. */
  --t-h1:clamp(1.75rem, 1.15rem + 3.4vw, 4rem);        /* 31 @375 → 64 */
  --t-h1-page:clamp(1.6rem, 1.15rem + 2.6vw, 3.125rem);/* 28 @375 → 50 */
  --t-h2:clamp(1.65rem, 1.25rem + 1.5vw, 2.25rem);     /* 26.4 → 36  */
  --t-h3:clamp(1.2rem, 1.05rem + 0.5vw, 1.4rem);       /* 19.2 → 22.4*/
  --t-h4:1.09rem;                                      /* 17.5       */
  --t-lede:clamp(1.03rem, 0.98rem + 0.28vw, 1.19rem);  /* 16.5 → 19  */
  --t-figure:clamp(2.5rem, 1.5rem + 4.2vw, 4.25rem);   /* 40 → 68   */
  --t-body:16.5px;
  --t-small:15px;
  --t-label:12px;       /* the floor. Nothing on the site is smaller. */

  /* --- MEASUREMENTS ------------------------------------------------ */
  --wrap:1180px;
  --gutter:32px;
  --radius:3px;         /* deliberately tight. This is an industrial
                           service, not a wellness brand.             */
  --hairline:1px solid var(--line);
  --header-h:72px;
  --header-h-small:60px;

  /* Section rhythm. One token, used everywhere. Reduced from 76px:
     the old padding bought a lot of scroll for very little content. */
  --section-y:58px;
  --section-y-lg:78px;  /* the two bands that carry a whole argument  */
  --head-gap:38px;

  /* --- MOTION ------------------------------------------------------
     Short, and only ever on interaction or on a section arriving. */
  --dur:170ms;
  --ease:cubic-bezier(.2,.6,.3,1);

  --focus:var(--link);  /* overridden on dark grounds, see section 19 */
}


/* ====================================================================
   2. BASE
   ==================================================================== */

*{box-sizing:border-box; margin:0; padding:0;}
html{scroll-behavior:smooth;}
[id]{scroll-margin-top:96px;}   /* anchors clear the sticky header */

body{
  background:var(--ground);
  color:var(--ink);
  font-family:'Instrument Sans',-apple-system,"Helvetica Neue",Arial,sans-serif;
  font-size:var(--t-body);
  line-height:1.62;
  -webkit-font-smoothing:antialiased;
}

h1,h2,h3,h4,h5{
  font-family:'Bricolage Grotesque',-apple-system,"Helvetica Neue",Arial,sans-serif;
  font-weight:600;
  letter-spacing:-0.018em;
  line-height:1.14;
  color:var(--navy);
  text-wrap:balance;    /* kills most single-word orphans on its own */
}
h1{font-size:var(--t-h1-page); line-height:1.05;}
h2{font-size:var(--t-h2);}
h3{font-size:var(--t-h3);}

a{color:inherit; text-decoration:none;}
img,svg{max-width:100%;}

.wrap{max-width:var(--wrap); margin:0 auto; padding:0 var(--gutter);}
@media(max-width:640px){ :root{--gutter:20px;} }

/* A section is the standard vertical rhythm unit. There is no
   alternating light/dark modifier: see section 8 of the notes at the
   top of this file, and .band-quote in component 16. */
.section{padding:var(--section-y) 0;}
.section-lg{padding:var(--section-y-lg) 0;}

/* Section heading. Left-aligned on the container gutter. Where an
   intro paragraph exists it sits beside the heading on a 5/7 split at
   desktop rather than centred beneath it, which uses the width the
   container already has and gives the eye a second column to track. */
.section-head{margin:0 0 var(--head-gap);}
.section-head h2{max-width:20ch;}
/* The measure exists to stop long headings running the full wrap. A
   heading written to sit on one line opts out of it. */
.section-head h2.oneline{max-width:none;}
.section-head p{color:var(--ink-soft); font-size:var(--t-lede); max-width:64ch; margin-top:13px;}
@media(min-width:900px){
  .section-head:has(p){
    display:grid; grid-template-columns:5fr 7fr; gap:0 52px; align-items:end;
  }
  .section-head:has(p) h2{max-width:16ch;}
  .section-head:has(p) p{margin-top:0; padding-bottom:4px;}
}
/* A rule under a section head, where a section needs a harder edge
   than spacing alone gives it. */
.section-head.ruled{padding-bottom:20px; border-bottom:var(--hairline);}

.skip-link{
  position:absolute; left:-9999px; top:0; z-index:100;
  background:var(--ink); color:var(--paper);
  padding:12px 22px; font-size:14px; font-weight:500;
}
.skip-link:focus{left:0;}

/* Visible focus ring for keyboard users, on every interactive thing.
   --focus is redefined on the dark grounds so the ring always clears
   3:1 against what is actually behind it. */
a:focus-visible, button:focus-visible, summary:focus-visible, details:focus-visible{
  outline:2px solid var(--focus); outline-offset:3px; border-radius:1px;
}


/* ====================================================================
   3. HEADER
   Single row, 72px at rest and 60px once scrolled. Logo hard left
   against the container gutter, navigation and the booking button
   grouped hard right. Fully opaque: the previous header was a 0.88
   alpha wash with a 10px blur, and section headings ghosted through it
   at every scroll position, which reads as a rendering fault rather
   than as an effect.
   ==================================================================== */

.site-header{
  position:sticky; top:0; z-index:50;
  background:var(--paper);
  border-bottom:var(--hairline);
  transition:height var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.site-header.is-scrolled{box-shadow:0 1px 12px rgba(27,46,61,0.07);}

.header-inner{
  display:flex; align-items:center; justify-content:space-between; gap:20px;
  height:var(--header-h);
  transition:height var(--dur) var(--ease);
}
.site-header.is-scrolled .header-inner{height:var(--header-h-small);}

/* Horizontal lockup: mark left of the wordmark, so the wordmark can be
   sized properly inside a 72px bar. The stacked lockup put "MEDICAL
   SERVICES" at roughly 5px here, which is noise rather than branding;
   it now appears only in the footer, at a size where it can be read. */
.brand{display:block; line-height:0; flex:none;}
.brand img{height:38px; width:auto; display:block; transition:height var(--dur) var(--ease);}
.site-header.is-scrolled .brand img{height:32px;}

.header-right{display:flex; align-items:center; gap:34px;}

.main-nav{display:flex; align-items:center; gap:28px;}
.main-nav a{
  font-size:var(--t-small); color:var(--ink);
  display:inline-flex; align-items:center; min-height:44px;
  border-bottom:2px solid transparent;
  transition:color var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.main-nav a:hover{color:var(--link); border-bottom-color:var(--line);}
/* Active page. There was no active state at all before. */
.main-nav a[aria-current]{
  color:var(--ink); font-weight:600; border-bottom-color:var(--accent);
}

.nav-toggle{
  display:none; flex-direction:column; justify-content:center; gap:5px;
  width:44px; height:44px; padding:10px; flex:none;
  background:transparent; border:var(--hairline);
  border-radius:var(--radius); cursor:pointer;
  transition:border-color var(--dur) var(--ease), background var(--dur) var(--ease);
}
.nav-toggle:hover{border-color:var(--navy);}
.nav-toggle span{display:block; height:2px; background:var(--ink); transition:transform var(--dur) var(--ease), opacity var(--dur) var(--ease);}
.nav-toggle[aria-expanded="true"] span:nth-child(1){transform:translateY(7px) rotate(45deg);}
.nav-toggle[aria-expanded="true"] span:nth-child(2){opacity:0;}
.nav-toggle[aria-expanded="true"] span:nth-child(3){transform:translateY(-7px) rotate(-45deg);}

@media(max-width:900px){
  :root{--header-h:64px; --header-h-small:56px;}
  .brand img{height:32px;}
  .site-header.is-scrolled .brand img{height:30px;}
  .header-right{gap:12px;}
  .main-nav{display:none;}
  .nav-toggle{display:flex; order:2;}
  /* The booking button stays in the collapsed bar rather than being
     buried inside the menu. */
  .header-actions{order:1;}
  .main-nav.open{
    display:flex; flex-direction:column; align-items:stretch; gap:0;
    position:absolute; top:100%; left:0; right:0;
    background:var(--paper); border-bottom:var(--hairline);
    box-shadow:0 12px 24px rgba(27,46,61,0.09);
    padding:4px 0 8px;
  }
  .main-nav.open a{
    padding:0 var(--gutter); min-height:52px; font-size:16.5px;
    border-top:1px solid var(--line-soft); border-bottom:none;
  }
  .main-nav.open a:first-child{border-top:none;}
  .main-nav.open a[aria-current]{box-shadow:inset 3px 0 0 var(--accent);}
}
/* The label shortening lives with the button, in component 4. Height,
   padding, weight and type size never change. */


/* ====================================================================
   4. BUTTONS
   Exactly three variants, defined once. One height, one horizontal
   padding, one type size, one weight. Every variant has :hover,
   :focus-visible and :active.

     .btn-primary    the single most important action in a section
     .btn-secondary  the alternative action
     .link-arrow     inline tertiary — "View all", "Read the guide"

   On the dark grounds the first two invert, which is handled once at
   the foot of this component rather than per-section. The previous
   direction had four treatments, and inside the closing navy band the
   hierarchy was inverted: the pale teal "primary" sat weaker against
   the navy than the ghost secondary beside it.
   ==================================================================== */

.btn{
  display:inline-flex; align-items:center; justify-content:center; gap:8px;
  min-height:44px; padding:11px 24px; border-radius:var(--radius);
  font-size:var(--t-small); font-weight:600; line-height:1.3; text-align:center;
  border:1px solid transparent; cursor:pointer;
  transition:background var(--dur) var(--ease), color var(--dur) var(--ease),
             border-color var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.btn:active{transform:translateY(1px);}

.btn-primary{background:var(--navy); color:var(--paper); border-color:var(--navy);}
.btn-primary:hover{background:var(--ink); border-color:var(--ink);}

.btn-secondary{background:transparent; color:var(--navy); border-color:var(--navy);}
.btn-secondary:hover{background:var(--navy); color:var(--paper);}

/* .btn-book carries no colour of its own. It is a .btn-primary that
   also knows how to shorten its label on a narrow phone.

   Each label state is a single text node rather than "Book" plus a
   toggled " online" span. The old markup put the two halves either side
   of the flex gap, so the word space and the 8px gap both rendered and
   the button read "Book  online". That is where the double space in the
   header CTA actually came from: the markup was correct all along. */
.btn-book, .btn-header{flex:none; white-space:nowrap;}

/* The employer-facing pages swap the header action rather than sharing
   the booking button. Ollie's point on the 25 August call: an employer
   making a health surveillance enquiry, which is the big-ticket work,
   should not be funnelled into the £100-300 individual appointment
   booker. Those pages carry .btn-header pointing at contact instead. */
.btn-label-short{display:none;}
@media(max-width:420px){
  .btn-book .btn-label-full{display:none;}
  .btn-book .btn-label-short{display:inline;}
}

.btn-row{display:flex; gap:14px; flex-wrap:wrap;}
.btn-row.centred{justify-content:center;}

/* Tertiary. Text plus an arrow; the arrow is the accent, the text is
   the link colour, so it still reads as a link. */
.link-arrow{
  font-size:var(--t-small); font-weight:600; color:var(--link);
  display:inline-flex; align-items:center; gap:8px;
  transition:color var(--dur) var(--ease);
}
.link-arrow::after{
  content:"\2192"; color:var(--accent);
  transition:transform var(--dur) var(--ease);
}
.link-arrow:hover{color:var(--link-hover); text-decoration:underline; text-underline-offset:3px;}
.link-arrow:hover::after{transform:translateX(4px);}

/* --- on dark grounds ------------------------------------------------ */
.on-dark .btn-primary,
.cta .btn-primary{background:var(--paper); color:var(--navy); border-color:var(--paper);}
.on-dark .btn-primary:hover,
.cta .btn-primary:hover{background:var(--ice); border-color:var(--ice); color:var(--navy);}
.on-dark .btn-secondary,
.cta .btn-secondary{background:rgba(255,255,255,0.10); color:var(--paper); border-color:rgba(255,255,255,0.72);}
.on-dark .btn-secondary:hover,
.cta .btn-secondary:hover{background:rgba(255,255,255,0.12); color:var(--paper); border-color:var(--paper);}
.on-dark .link-arrow,
.cta .link-arrow{color:var(--ice);}
.on-dark .link-arrow::after,
.cta .link-arrow::after{color:var(--accent-lift);}
.on-dark .link-arrow:hover,
.cta .link-arrow:hover{color:var(--paper);}


/* ====================================================================
   5. HERO — HOME
   Flat deep navy, and typography does the work.

   Why the seascape went. The old hero ran the H1 across the band where
   the image passed from mid-blue to near-white, so line one was low
   contrast on blue-grey while line four was dark on near-white.
   Contrast varying line by line inside a single heading is an
   accessibility failure and it looks accidental. A photograph with a
   scrim would have fixed it, but there is no Viking photograph that
   could carry a hero, and inventing one is out: on a doctor-led
   medical site an imagined clinic misdirects the patients who navigate
   by it. A flat ground makes the contrast provably identical on every
   line, and removes a WebGL canvas from the critical path.
   ==================================================================== */

.hero{
  position:relative; isolation:isolate; overflow:hidden;
  color:var(--ice);
  padding:clamp(64px,8vw,104px) 0 clamp(52px,6vw,76px);
  border-bottom:1px solid var(--band);
  /* Night sky over the firth, carried over from concept/aurora.css.
     Curtains ramp through brand teal, the harbour glow at the waterline
     is the accent, and the band settles to --aurora-base at the bottom
     so the seam with the light page below is a flat colour rather than
     noisy sky. */
  background-color:var(--aurora-deep);
  background-image:
    radial-gradient(80% 54% at 72% 70%, rgba(113,173,181,0.38), transparent 66%),
    radial-gradient(62% 44% at 46% 82%, rgba(46,107,120,0.34), transparent 70%),
    radial-gradient(96% 34% at 52% 102%, rgba(160,104,44,0.20), transparent 72%),
    linear-gradient(var(--aurora-deep) 0%, var(--aurora-rise) 42%, var(--aurora-mid) 62%, var(--aurora-base) 100%);
}

/* The legibility scrim, and the reason this can carry type at all.

   It is FLAT across the whole column the copy occupies, then falls away
   to the right where the curtains read at full strength. That is the
   difference between this and the seascape hero it replaces: there, the
   H1 ran across the band where the image passed from mid-blue to
   near-white, so line one was low contrast and line four was dark on
   near-white. Here every line of the H1 sits on the same 0.88 scrim, so
   the sky underneath is damped to 12% and the measured contrast varies
   by a fraction of a ratio point from the first line to the last.

   90deg, not the concept's 100deg: a tilted axis would mean the flat
   zone is not a true vertical band, and the top and bottom lines of the
   heading would sit on slightly different scrim values. */
.hero::before{
  content:""; position:absolute; inset:0; z-index:-1; pointer-events:none;
  /* The flat zone runs to 66%. The H1 measures 63.6% of the hero width
     at 1440, so the whole heading sits inside it with a margin, and the
     falloff begins past the longest line rather than under it. */
  background:linear-gradient(90deg,
    rgba(8,15,22,0.88) 0%,
    rgba(8,15,22,0.88) 66%,
    rgba(8,15,22,0.42) 79%,
    rgba(8,15,22,0.10) 91%,
    rgba(8,15,22,0) 100%);
}
@media(max-width:900px){
  /* Below the desktop breakpoint the copy fills the width, so there is
     no clear half to fall away to. A flat scrim across the whole band
     keeps the contrast uniform and still lets the sky through at 15%. */
  .hero::before{background:rgba(8,15,22,0.85);}
}
.hero .eyebrow{color:var(--accent-lift); margin-bottom:22px;}
.hero h1{
  font-size:var(--t-h1); color:var(--paper);
  max-width:19ch;         /* sets in 2–3 lines, not 4 */
  margin-bottom:22px;
}
.hero .lede{
  font-size:var(--t-lede); color:rgba(216,223,226,0.88);
  max-width:58ch; margin-bottom:32px;
}
.hero .btn-row{margin-bottom:40px;}

/* Credential row. This is the strongest trust element above the fold,
   so it is set as bordered chips rather than as 10px text separated by
   bullets with uneven spacing either side. */
/* One mark, not three. These carried a dot, small caps and a border for
   a single job, and floated unattached below the buttons. The rule above
   anchors them to the hero; the dot is the only decoration left. */
.trust-strip{
  display:flex; flex-wrap:wrap; gap:10px 26px; list-style:none;
  border-top:1px solid rgba(216,223,226,0.22); padding-top:18px;
}
.trust-strip li{
  display:inline-flex; align-items:center; gap:9px;
  font-size:var(--t-label); letter-spacing:0.09em; text-transform:uppercase;
  font-weight:600; color:var(--ice);
}
.trust-strip li::before{
  content:""; flex:none; width:6px; height:6px; border-radius:50%;
  background:var(--accent-lift);
}


/* ====================================================================
   6. HERO — INTERIOR
   Every page below the homepage. Carries the breadcrumb, the eyebrow,
   the single H1 and the lede.
   ==================================================================== */

.page-hero{
  position:relative;
  padding:34px 0 46px;
  border-bottom:var(--hairline);
  background:var(--paper);
}
.page-hero h1{font-size:var(--t-h1-page); max-width:18ch; margin-bottom:16px;}
.page-hero .lede{font-size:var(--t-lede); color:var(--ink-soft); max-width:62ch;}
.page-hero .btn-row{margin-top:28px;}

.breadcrumbs{font-size:13.5px; color:var(--ink-soft); margin-bottom:20px;}
.breadcrumbs a{color:var(--link);}
.breadcrumbs a:hover{text-decoration:underline; text-underline-offset:3px;}
.breadcrumbs span{margin:0 7px; opacity:0.5;}

/* The label mark. */
.eyebrow{
  display:inline-flex; align-items:center; gap:10px;
  font-size:var(--t-label); letter-spacing:0.10em; text-transform:uppercase;
  color:var(--accent); font-weight:700; margin-bottom:14px;
}


/* ====================================================================
   7. DOORS
   The two-audience split from the live homepage: the employer who buys
   a programme, and the individual who books and pays for their own
   medical. Two equal doors, no hierarchy between them.
   ==================================================================== */

.doors{display:grid; grid-template-columns:1fr 1fr; gap:1px; background:var(--line); border:var(--hairline);}
@media(max-width:760px){ .doors{grid-template-columns:1fr;} }
.door{
  background:var(--paper); padding:38px 34px;
  display:flex; flex-direction:column;
  transition:background var(--dur) var(--ease);
}
.door .tag{
  font-size:var(--t-label); letter-spacing:0.10em; text-transform:uppercase;
  color:var(--accent); font-weight:700; margin-bottom:14px; display:block;
}
/* h2 or h3 depending on where the block sits in the page outline. */
.door h2, .door h3{font-size:var(--t-h3); margin-bottom:12px;}
.door p{color:var(--ink-soft); margin-bottom:24px;}
.door p:last-child{margin-bottom:0; margin-top:auto; padding-top:6px;}
/* A door can close on a button rather than an arrow link. margin-top
   auto pins it to the foot so two doors of unequal copy still line
   their actions up; align-self stops the column stretch making it full
   width. */
/* A door pins its action to the bottom so the two cards align whatever the
   copy length. Where a door offers two routes they sit in a .btn-row, so the
   row is pinned rather than each button, or the second one drops to a line of
   its own with no gap. */
.door > .btn, .door > .btn-row{margin-top:auto; align-self:flex-start;}


/* ====================================================================
   8. PANELS
   A panel is a bordered block holding a heading and a list of what is
   included — the "Health Surveillance / Statutory Medicals" pattern.
   ==================================================================== */

.panel-grid{display:grid; grid-template-columns:1fr 1fr; gap:24px;}
@media(max-width:760px){ .panel-grid{grid-template-columns:1fr;} }
.panel{
  background:var(--paper); border:var(--hairline); border-radius:var(--radius);
  padding:32px; display:flex; flex-direction:column;
}
.panel h2, .panel h3{font-size:var(--t-h3); margin-bottom:8px;}
.panel .desc{color:var(--ink-soft); font-size:15.5px; margin-bottom:20px;}
/* The two panels hold different numbers of rows. Left to size themselves the
   links land on different lines, which is loud in a rule-based layout; padded
   to a common height the shorter one shows an empty slot. The compromise is a
   floor: the list gets a minimum depth so both cards reach the same line with
   their rows still evenly spaced, and the ruled footer closes each one. */
.panel .panel-list{min-height:16.5em;}
.panel .link-arrow{
  margin-top:auto; padding-top:18px; width:100%;
  border-top:1px solid var(--line);
}

/* Service rows. A two-column grid with a fixed ratio, not
   space-between: on a wide row the descriptor used to drift so far
   from its link that the relationship between them broke. */
.panel-list{list-style:none;}
.panel-list li{
  display:flex; align-items:baseline; gap:10px;
  padding:12px 0; border-top:1px solid var(--line-soft); font-size:15.5px;
}
.panel-list li::before{
  content:""; order:2; flex:1 1 auto; align-self:center;
  height:1px; background:var(--line); margin:0 2px;
}
.panel-list li a{order:1; flex:0 1 auto;}
.panel-list li .meta{order:3; flex:0 0 auto;}
.panel-list li:first-child{border-top:none;}
.panel-list li a{color:var(--link); font-weight:500;}
.panel-list li a:hover{text-decoration:underline; text-underline-offset:3px;}
.panel-list li .meta{color:var(--ink-soft); font-size:13.5px; text-align:right;}
@media(max-width:400px){
  .panel-list li{flex-wrap:wrap; gap:2px;}
  .panel-list li::before{display:none;}
  .panel-list li .meta{flex-basis:100%; text-align:left;}
}


/* ====================================================================
   9. CARDS
   Used for the services hub and the guides hub. A whole card is a link.
   One hover idea, applied consistently: the border goes navy, an accent
   rule appears along the top edge, and the card lifts 2px.
   ==================================================================== */

.card-grid{display:grid; grid-template-columns:repeat(3,1fr); gap:22px;}
.card-grid-2{grid-template-columns:repeat(2,1fr);}
@media(max-width:900px){ .card-grid{grid-template-columns:1fr 1fr;} }
@media(max-width:620px){ .card-grid, .card-grid-2{grid-template-columns:1fr;} }

.card{
  position:relative;
  background:var(--paper); border:var(--hairline); border-radius:var(--radius);
  padding:30px; display:flex; flex-direction:column;
  transition:border-color var(--dur) var(--ease), transform var(--dur) var(--ease),
             box-shadow var(--dur) var(--ease);
}
.card::before{
  content:""; position:absolute; left:-1px; right:-1px; top:-1px; height:2px;
  background:var(--accent); transform:scaleX(0); transform-origin:left;
  transition:transform var(--dur) var(--ease);
}
.card:hover{border-color:var(--navy); transform:translateY(-2px); box-shadow:0 6px 18px rgba(27,46,61,0.07);}
.card:hover::before{transform:scaleX(1);}
.card .tag{
  font-size:var(--t-label); letter-spacing:0.10em; text-transform:uppercase;
  color:var(--accent); font-weight:700; margin-bottom:12px; display:block;
}
.card h2, .card h3{font-size:var(--t-h4); margin-bottom:10px;}
.card p{color:var(--ink-soft); font-size:var(--t-small); margin-bottom:20px;}
/* The CTA pins to the bottom of the card, so on a short card the slack
   sits inside the padding rather than as a dead tail below the link. */
.card .link-arrow{margin-top:auto;}


/* ====================================================================
   10. REASONS
   The "why employers choose us" list, and the densest block on the
   homepage. Numbered so six near-identical text blocks can be scanned,
   with the accent rule running the full column width above each one.
   ==================================================================== */

/* Five across on one row, matching the reference Ollie compared against.
   Five is the count, so it is the column number: three-up left a widowed
   row of two, which reads as an afterthought rather than a set. At the
   wrap this is about 196px a column, so the copy under each heading has
   to stay to a line or two. Keep it that way if you edit them. */
.reasons{display:grid; grid-template-columns:repeat(5,1fr); gap:30px 26px; counter-reset:reason;}
@media(max-width:1080px){ .reasons{grid-template-columns:repeat(3,1fr); gap:30px 34px;} }
@media(max-width:760px){ .reasons{grid-template-columns:1fr 1fr;} }
@media(max-width:520px){ .reasons{grid-template-columns:1fr;} }
.reason{border-top:2px solid var(--accent); padding-top:16px;}
.reason::before{
  counter-increment:reason; content:"0" counter(reason);
  display:block; margin-bottom:8px;
  font-family:'Bricolage Grotesque',sans-serif; font-weight:600;
  font-size:var(--t-label); letter-spacing:0.08em; color:var(--accent);
}
.reason h2, .reason h3, .reason h4{font-size:var(--t-h4); margin-bottom:8px;}
.reason p{font-size:var(--t-small); color:var(--ink-soft);}


/* --- arrival: the compact Find the clinic row on the homepage --------
   Three ways to get here, one line each. It borrows the .reason rule
   and type but deliberately not its counter: these are alternatives,
   not a ranked or sequenced list, and numbering them would imply an
   order that does not exist. The full version lives on contact.html. */
.arrival{display:grid; gap:0; margin-top:26px;}
.arrival > div{
  display:grid; grid-template-columns:112px 1fr; gap:20px;
  padding:16px 0; border-top:1px solid var(--line);
}
.arrival > div:last-child{border-bottom:1px solid var(--line);}
.arrival h3{
  font-size:var(--t-label); letter-spacing:0.10em; text-transform:uppercase;
  color:var(--accent); font-weight:700; margin:2px 0 0;
}
.arrival p{font-size:var(--t-small); color:var(--ink-soft);}
@media(max-width:520px){
  .arrival > div{grid-template-columns:1fr; gap:6px;}
}

/* The map card. Structure borrowed from the version Ollie compared us
   against: a coordinates bar over an embedded map, which does the same
   job as a caption while reading as an instrument panel rather than a
   label. The saturation knock keeps Google's greens and blues from
   being the loudest thing on a page built out of navy and ice. */
.map-card{
  border:var(--hairline); border-radius:var(--radius);
  overflow:hidden; background:var(--paper);
}
.map-card .bar{
  display:flex; justify-content:space-between; align-items:baseline; gap:14px;
  padding:13px 16px; border-bottom:var(--hairline);
  font-size:var(--t-label); letter-spacing:0.10em; text-transform:uppercase;
  color:var(--ink); font-weight:700;
}
.map-card .bar span:last-child{color:var(--ink-soft); font-weight:500; letter-spacing:0.06em;}
.map-card iframe{
  display:block; width:100%; height:360px; border:0;
  filter:saturate(0.85);
}
@media(max-width:820px){ .map-card iframe{height:300px;} }


/* ====================================================================
   11. STEPS
   Numbered how-it-works sequence. Numbers come from CSS, so adding a
   step means adding a list item and nothing else.
   ==================================================================== */

.steps{counter-reset:step; max-width:820px;}
.steps.wide{max-width:none;}
.step{
  display:grid; grid-template-columns:54px 1fr; gap:22px;
  padding:20px 0; border-bottom:var(--hairline);
}
.step:last-child{border-bottom:none;}
.step::before{
  counter-increment:step; content:"0" counter(step);
  font-family:'Bricolage Grotesque',sans-serif; font-weight:600;
  font-size:var(--t-small); color:var(--accent); padding-top:3px;
}
.step h3{font-size:var(--t-h4); margin-bottom:6px;}
.step p{font-size:15.5px; color:var(--ink-soft);}


/* ====================================================================
   12. PROSE
   Body copy for guides and policy pages. Constrained to a readable
   measure and sitting on the left gutter like everything else.
   ==================================================================== */

.prose{max-width:72ch;}
.prose h2{font-size:var(--t-h2); margin:44px 0 16px; max-width:20ch;}
.prose h2:first-child{margin-top:0;}
.prose h3{font-size:var(--t-h3); margin:30px 0 10px;}
.prose p{margin-bottom:17px;}
.prose ul, .prose ol{margin:0 0 20px 24px;}
.prose li{margin-bottom:9px;}
.prose strong{font-weight:600; color:var(--ink);}
.prose a{color:var(--link); text-decoration:underline; text-underline-offset:3px;}
.prose a:hover{color:var(--link-hover);}
.prose>:last-child{margin-bottom:0;}


/* ====================================================================
   13. FACTS — tables, callouts, notes
   Regulation names, intervals and frequencies. These carry the
   clinical detail, so they are styled to be scanned rather than read.
   ==================================================================== */

.fact-table{
  width:100%; border-collapse:collapse; font-size:var(--t-small);
  margin:22px 0 28px; background:var(--paper); border:var(--hairline);
}
.fact-table th{
  text-align:left; font-family:'Bricolage Grotesque',sans-serif;
  font-weight:600; font-size:13.5px; letter-spacing:0.03em;
  color:var(--navy); background:var(--ground);
}
.fact-table th, .fact-table td{padding:13px 16px; border-bottom:1px solid var(--line); vertical-align:top;}
/* The header row closes with a full-weight rule. On a compliance site the
   table is the artefact people came for, so it gets the firmest treatment
   on the page rather than the meekest. */
.fact-table tr:first-child th{border-bottom:2px solid var(--navy);}
.fact-table tr:last-child td{border-bottom:none;}
/* Wide tables scroll inside their own box rather than the page. The
   min-width matters: without it a comparison table crushes itself into
   unreadable columns on a phone instead of scrolling. */
.table-scroll{overflow-x:auto; -webkit-overflow-scrolling:touch; margin:22px 0 28px;}
.table-scroll .fact-table{margin:0; min-width:560px;}
@media(min-width:1000px){
  .prose .table-scroll, .prose>.fact-table{width:94ch; max-width:none;}
}

/* The callout is a labelled aside, so it takes the accent bar rather
   than the teal one. */
.callout{
  background:var(--paper); border:var(--hairline);
  border-left:3px solid var(--accent); border-radius:var(--radius);
  padding:22px 26px; margin:26px 0;
}
.callout h3{font-size:var(--t-h4); margin-bottom:8px;}
.callout p:last-child{margin-bottom:0;}

.note{font-size:14.5px; color:var(--ink-soft); margin:18px 0;}
.review-note{
  font-size:14px; color:var(--ink-soft); margin-top:40px;
  padding-top:20px; border-top:var(--hairline);
}


/* ====================================================================
   13b. FIGURES
   One moment per page where a number is allowed to be the largest thing
   on it. Regulation values were being carried as bold runs inside body
   copy, three to a paragraph, which makes the paragraph spotty and
   still leaves the value hard to find. A duty holder scanning for the
   number they have to comply with should hit it without reading.

   Deliberately not a card: hairline separators and open ground, so it
   reads as a specification, not a promo tile. Two or three at most. A
   fourth turns the moment back into a grid.
   ==================================================================== */

.figures{
  display:grid; grid-template-columns:repeat(auto-fit, minmax(210px,1fr));
  gap:0; margin:0; border-top:2px solid var(--navy);
  /* Held well inside the wrap. Across the full 1180 the two columns strand
     their qualifiers in open ground and the block reads as unfinished
     rather than spacious. */
  max-width:840px;
}
/* The rule is drawn on the cell rather than the row, so it stops where the
   shorter column's content stops instead of dangling into air. */
.figures>div{padding:22px 26px 20px 0; position:relative;}
.figures>div+div{padding-left:30px;}
.figures>div+div::before{
  content:""; position:absolute; left:0; top:18px; bottom:4px;
  width:1px; background:var(--line);
}
.figures .label{
  font-size:var(--t-label); letter-spacing:0.10em; text-transform:uppercase;
  font-weight:700; color:var(--accent); display:block; margin-bottom:10px;
}
.figures .value{
  font-family:'Bricolage Grotesque',sans-serif; font-weight:600;
  font-size:var(--t-figure); line-height:0.98; color:var(--navy);
  letter-spacing:-0.02em; display:block;
}
.figures .value{display:flex; align-items:baseline; gap:5px;}
.figures .value .unit{font-size:0.28em; font-weight:600; letter-spacing:0.01em; color:var(--ink-soft);}
.figures p{
  font-size:14.5px; color:var(--ink-soft); margin:12px 0 0; max-width:30ch;
  min-height:4.2em;   /* two captions of different length still sit level */
}
@media(max-width:620px){
  .figures>div{border-right:none; border-bottom:1px solid var(--line); padding-right:0;}
  .figures>div:last-child{border-bottom:none;}
}


/* A section that continues the one above rather than starting a new
   thought, so it drops the top padding instead of stacking two. */
.section-flush{padding-top:0;}


/* ====================================================================
   14. FAQ
   Native <details>. Mark the same questions up as FAQPage JSON-LD.
   ==================================================================== */

.faq-wrap{max-width:820px;}
details.faq{
  background:var(--paper); border:var(--hairline);
  border-radius:var(--radius); margin-bottom:10px;
  transition:border-color var(--dur) var(--ease);
}
details.faq:hover{border-color:var(--navy);}
details.faq summary{
  cursor:pointer; padding:16px 22px; list-style:none; min-height:44px;
  font-family:'Bricolage Grotesque',sans-serif; font-weight:600; font-size:16px;
  color:var(--navy);
  display:flex; justify-content:space-between; align-items:center; gap:16px;
}
details.faq summary::-webkit-details-marker{display:none;}
details.faq summary::after{content:"+"; color:var(--accent); font-size:20px; flex:none;}
details.faq[open] summary::after{content:"\2013";}
details.faq[open] summary{border-bottom:1px solid var(--line-soft);}
details.faq .faq-body{padding:17px 22px; font-size:15.5px; color:var(--ink-soft);}
details.faq .faq-body p{margin-bottom:11px;}
details.faq .faq-body p:last-child{margin-bottom:0;}
details.faq .faq-body a{color:var(--link); text-decoration:underline; text-underline-offset:3px;}


/* ====================================================================
   15. PEOPLE
   One .person block per profile, taking a photograph at the portrait
   slot ratio in component 15b. There is no initials avatar: on a site
   whose whole proposition is a named doctor, a two-letter box reads as
   an unfinished page rather than as a placeholder.
   ==================================================================== */

.person{
  display:grid; grid-template-columns:260px 1fr; gap:38px;
  background:var(--paper); border:var(--hairline); border-radius:var(--radius);
  padding:34px; align-items:start; margin-bottom:22px;
}
@media(max-width:680px){ .person{grid-template-columns:1fr; gap:24px;} }

/* height:auto is required: the width/height attributes on the <img> are
   a presentational hint that otherwise beats aspect-ratio and leaves
   the portrait uncropped. object-position sits high because these are
   head-and-shoulders portraits, and is a variable so it can be tuned
   per image when a new photograph lands. */
.person-photo{
  width:100%; height:auto; aspect-ratio:4/5;
  object-fit:cover; object-position:var(--pos, 50% 18%);
  border-radius:var(--radius); display:block; background:var(--band-deep);
}
@media(max-width:680px){ .person-photo, .person .slot{max-width:240px;} }

.person h2, .person h3{font-size:var(--t-h3); margin-bottom:4px;}
.person .role{font-size:14.5px; color:var(--ink-soft); font-weight:700; margin-bottom:4px;}
.person .cred{font-size:14.5px; color:var(--ink-soft); margin-bottom:16px;}
.person p{font-size:15.5px; color:var(--ink-soft); margin-bottom:13px;}
.person p:last-child{margin-bottom:0;}

.badge-row{display:flex; gap:8px; flex-wrap:wrap; margin-top:18px;}
.badge{
  font-size:var(--t-label); letter-spacing:0.03em; font-weight:500;
  padding:6px 12px; border:var(--hairline); border-radius:20px;
  color:var(--ink-soft); background:var(--ground);
}

/* A personal profile link on a team card. Icon inherits the link colour
   rather than LinkedIn's own blue, so it stays inside the site palette. */
.person .social-link{
  display:inline-flex; align-items:center; gap:6px;
  font-size:var(--t-small); font-weight:600; color:var(--link);
  margin-bottom:13px;
}
.person .social-link:hover{color:var(--link-hover); text-decoration:underline; text-underline-offset:3px;}
.person .social-link svg{width:16px; height:16px; flex:none;}


/* --- person row: the three-up on the homepage -------------------------
   The homepage sells reachability rather than biography, so all three
   people carry equal weight and the copy stays to a line. Full profiles
   are on team.html. The photograph is squared here rather than taking
   the 4/5 portrait of the full profile: three portraits at column width
   would run to 450px each and swallow the section. */
.person-row{display:grid; grid-template-columns:repeat(3,1fr); gap:22px;}
@media(max-width:860px){ .person-row{grid-template-columns:1fr;} }
/* align-content:start stops the photo and name row from stretching to fill
   the card: .person-row makes all three cards match the tallest one
   (Gillian's, with the most text), and without this the extra height was
   absorbed as empty space between the photo and the name on the shorter
   two, pushing Iona's and Ollie's names down out of line with Gillian's. */
.person-row .person{grid-template-columns:1fr; gap:20px; margin-bottom:0; align-content:start;}
.person-row .person-photo{aspect-ratio:1; max-width:none;}


/* ====================================================================
   15b. PHOTOGRAPHY
   Why this exists: on the old site the photographs were dropped in
   full-bleed at full saturation, so a hi-vis yellow or a bright blue
   sky punched straight through a muted navy/ochre/ice page. Everything
   here exists to stop that happening again.

   Three rules:
     1. Every photograph is GRADED. .figure desaturates slightly and
        lays a navy wash over the top, so an image joins the palette
        instead of competing with it. Never use a bare <img>.
     2. Every photograph has a JOB. It illustrates the hazard or the
        work the surrounding copy is about. Decoration gets cut.
     3. One image per section, at a fixed aspect ratio, so a photograph
        can never grow to dominate the page.

   The portrait is the exception to rule 1: it carries no wash and no
   duotone, because it has to read as a straight professional
   photograph of a named doctor.

   To dial the grading up or down, change --photo-wash and --photo-sat.
   Both are in this block and nowhere else.
   ==================================================================== */

:root{
  --photo-sat:1.06;
  --photo-bright:1.04;                        /* 1 = untouched            */
  --photo-wash:rgba(53,80,105,0.06);       /* brand navy, low alpha    */
}

/* The ground colour, not the dark band: a lazy image that has not
   painted yet should read as an empty frame the same weight as the
   page, not as a black slab that then swaps to a photograph. */
.figure{
  position:relative; overflow:hidden;
  border-radius:var(--radius); background:var(--line-soft);
  line-height:0;
}
.figure img{
  width:100%; height:auto; display:block;
  object-fit:cover; object-position:var(--pos, 50% 50%);
  filter:saturate(var(--photo-sat)) brightness(var(--photo-bright)) contrast(1.03);
}
/* The wash. A flat navy veil rather than a blend mode, so it renders
   identically everywhere instead of shifting between browsers. */
.figure::after{
  content:""; position:absolute; inset:0; pointer-events:none;
  background:var(--photo-wash);
}
.figure figcaption{
  position:absolute; left:0; right:0; bottom:0; z-index:2;
  padding:26px 24px 16px; line-height:1.45;
  font-size:13px; color:var(--ice);
  background:linear-gradient(to top, rgba(22,40,54,0.88), rgba(22,40,54,0));
}

/* --- .slot: an image that has been specified but not shot ------------
   A labelled empty frame, deliberately unfinished-looking: flat pale
   ground, a navy hairline, and a centred small-caps label naming the
   slot and its reference in PHOTO-BRIEF.md. It is not a gradient, a
   stock image or an initials block, because a placeholder that looks
   finished ships by accident.

   It occupies exactly the space the real photograph will, so dropping
   the asset in later is a file swap plus an --pos tweak. To replace
   one: delete the <div class="slot"> and put an <img> in its place.

   check-site.py warns while any of these are still on the site. */
.slot{
  display:flex; flex-direction:column; align-items:center; justify-content:center;
  gap:8px; text-align:center; padding:24px;
  background:var(--ground); border:1px solid var(--navy);
  border-radius:var(--radius); line-height:1.5; width:100%;
}
.slot .ref{
  font-size:var(--t-label); font-weight:700; letter-spacing:0.14em;
  text-transform:uppercase; color:var(--navy);
}
.slot p{
  font-family:'Instrument Sans',sans-serif; font-size:13px;
  color:var(--ink-soft); margin:0; max-width:34ch;
}
.slot-portrait{aspect-ratio:4/5;}
.slot-3-2{aspect-ratio:3/2;}
.slot-16-9{aspect-ratio:16/9;}

/* --- panel media: a banner across the top of a .panel -----------------
   The treatment Ollie liked in the August comparison: the two homepage
   panels lead with a photograph rather than a heading. It is full bleed,
   so it cancels the panel's 32px padding with a negative margin and
   pulls the radius back to the panel's own corners.

   2:1 rather than the 16:9 used elsewhere. At the panel's width that is
   about 270px, close to the reference, and it is the shallowest crop
   these two photographs survive: any tighter and the ear defenders in
   one and the helmet in the other start leaving the frame, which are
   the two things the images exist to show. --pos is tuned per image for
   the same reason. */
.panel-media{
  margin:-32px -32px 24px;
  border-radius:var(--radius) var(--radius) 0 0;
  aspect-ratio:2/1;
}
.panel-media img{height:100%;}
@media(max-width:520px){
  /* The panel loses its side padding before this breakpoint, and a 2:1
     band at phone width is only about 150px tall, which is too little
     to read three faces. Squarer crop, more subject. */
  .panel-media{aspect-ratio:3/2;}
}

/* --- media split: photograph beside copy ------------------------------
   The default. The image supports an argument being made in words next
   to it, which is why it never appears without adjacent copy. */
.media-split{
  display:grid; grid-template-columns:1fr 1fr; gap:44px; align-items:center;
}
.media-split.flip .figure, .media-split.flip .slot{order:2;}
.media-split .figure{aspect-ratio:3/2;}
.media-split .figure img{height:100%;}
.media-split h2{margin-bottom:14px;}
.media-split p{color:var(--ink-soft); margin-bottom:14px;}
.media-split p:last-child{margin-bottom:0;}
@media(max-width:820px){
  .media-split{grid-template-columns:1fr; gap:26px;}
  .media-split.flip .figure, .media-split.flip .slot{order:0;}
  .media-split .figure{aspect-ratio:16/9;}
}

/* --- media band: one full-width image per page, maximum --------------
   Used as a section divider. Deliberately short so it reads as a band
   rather than a hero, and always carries the scrim because copy sits
   on top of it. Use only for a bright image: a dark photograph under
   this scrim reads as a flat dark block. */
.media-band{
  position:relative; overflow:hidden;
  height:clamp(220px,30vw,320px); background:var(--band-deep);
}
.media-band img{
  position:absolute; inset:0; width:100%; height:100%;
  object-fit:cover; object-position:var(--pos, 50% 50%); display:block;
  filter:saturate(var(--photo-sat)) brightness(var(--photo-bright)) contrast(1.03);
}
.media-band::after{
  content:""; position:absolute; inset:0;
  background:
    linear-gradient(100deg, rgba(22,40,54,0.90) 0%, rgba(22,40,54,0.66) 34%, rgba(22,40,54,0.24) 62%, rgba(22,40,54,0.06) 100%),
    var(--photo-wash);
}
@media(max-width:700px){
  /* No room for a text-free half on a phone, so the scrim goes even. */
  .media-band::after{
    background:linear-gradient(rgba(22,40,54,0.66), rgba(22,40,54,0.82)), var(--photo-wash);
  }
}
.media-band .wrap{position:relative; z-index:2; height:100%; display:flex; flex-direction:column; justify-content:center;}
.media-band p{
  color:var(--paper); font-size:clamp(17px,2.1vw,23px); max-width:30ch;
  font-family:'Bricolage Grotesque',sans-serif; font-weight:500; line-height:1.32;
}
.media-band .attrib{
  font-family:'Instrument Sans',sans-serif; font-weight:700;
  font-size:var(--t-label); letter-spacing:0.12em; text-transform:uppercase;
  color:var(--accent-lift); margin-bottom:12px;
}


/* ====================================================================
   16. QUOTE
   The positioning statement. This is one of the two places on a page
   allowed a background of its own, because the band is encoding
   something rather than alternating by position.
   ==================================================================== */

.band-quote{
  background:var(--paper);
  border-top:var(--hairline); border-bottom:var(--hairline);
}
.pullquote{
  max-width:900px;
  border-left:3px solid var(--accent); padding-left:30px;
}
.pullquote blockquote{
  font-family:'Bricolage Grotesque',sans-serif; font-weight:500;
  font-size:clamp(21px,2.9vw,30px); line-height:1.35; color:var(--navy);
}
/* The closing clause carries the whole positioning claim, so the
   emphasis is a defined style rather than an unexplained switch to
   italic: same weight, the accent colour. */
.pullquote blockquote em{font-style:normal; color:var(--accent);}
.pullquote cite{
  display:block; margin-top:20px; font-style:normal; font-size:var(--t-label);
  letter-spacing:0.10em; text-transform:uppercase; color:var(--ink-soft); font-weight:600;
}
@media(max-width:640px){ .pullquote{padding-left:20px;} }


/* ====================================================================
   16b. CLAIM
   The one section on a page where type carries everything and there is
   no image at all. It exists because the HSE Appointed Doctor claim is
   the strongest commercial line on the site and it was being set at the
   same weight as a paragraph about pricing.

   Deliberately on the light ground rather than a fifth dark band: the
   dark treatment already closes every page, and another one would read
   as the same section again rather than as a change of pace.
   ==================================================================== */

.claim-block{
  border-top:2px solid var(--navy); padding-top:30px;
  display:grid; grid-template-columns:minmax(0,1.05fr) minmax(0,0.95fr);
  gap:0 56px; align-items:start;
}
@media(max-width:900px){ .claim-block{grid-template-columns:1fr; gap:0;} }
.claim-block .label{grid-column:1 / -1;

  font-size:var(--t-label); letter-spacing:0.10em; text-transform:uppercase;
  font-weight:700; color:var(--accent); display:block; margin-bottom:20px;
}
.claim-block .statement{
  font-family:'Bricolage Grotesque',sans-serif; font-weight:500;
  font-size:clamp(1.85rem, 1.15rem + 2.6vw, 3rem); line-height:1.14;
  letter-spacing:-0.015em; color:var(--navy); max-width:24ch; margin:0;
}
/* Stacked beside the statement rather than strung in a thin band beneath
   it, so the right half carries weight instead of air. Rules separate rows
   and stop with the list; they never run past their content. */
.claim-list{
  list-style:none; margin:6px 0 0; grid-row:span 2;
  border-top:1px solid var(--line);
}
.claim-list li{
  display:grid; grid-template-columns:8.5rem minmax(0,1fr); gap:18px;
  align-items:baseline; padding:15px 0; border-bottom:1px solid var(--line);
}
.claim-list li:last-child{border-bottom:none;}
.claim-list .reg{
  font-size:var(--t-label); letter-spacing:0.08em;
  text-transform:uppercase; font-weight:700; color:var(--accent);
}
.claim-list .what{display:block; font-size:16px; color:var(--ink); line-height:1.45;}
.claim-foot{margin:30px 0 0; color:var(--ink-soft); max-width:46ch; align-self:end;}
@media(max-width:900px){
  .claim-list{margin-top:34px;}
  .claim-foot{max-width:60ch;}
}


/* ====================================================================
   17. CTA BAND
   The dark band that closes every page, and the one place on the site
   where centring survives.
   ==================================================================== */

/* The band sits one step lighter than the footer beneath it. Both on
   --band-deep merged into a single 400px slab of navy with no visible
   edge between the closing call to action and the site furniture. */
.cta{
  padding:var(--section-y-lg) 0; color:var(--ice); text-align:center;
  background:var(--band);
  --focus:var(--accent-lift);
}
.cta h2{color:var(--paper); font-size:var(--t-h2); max-width:20ch; margin:0 auto 18px;}
.cta p{color:rgba(216,223,226,0.85); max-width:58ch; margin:0 auto 30px; font-size:var(--t-lede);}


/* ====================================================================
   18. FOOTER
   The best-executed block on the previous version; the structure is
   unchanged. The one fix is the logo strapline, which rode along inside
   the stacked lockup at roughly 3px. It is now a separate asset set at
   a size where it can actually be read.
   ==================================================================== */

.site-footer{
  background:var(--band-deep); color:var(--ice);
  padding:56px 0 32px; font-size:var(--t-small);
  --focus:var(--accent-lift);
}
.foot-grid{
  display:grid; grid-template-columns:1.5fr 1fr 1fr 1fr; gap:34px;
  padding-bottom:32px; border-bottom:1px solid rgba(216,223,226,0.16); margin-bottom:24px;
}
@media(max-width:820px){ .foot-grid{grid-template-columns:1fr 1fr;} }
@media(max-width:520px){ .foot-grid{grid-template-columns:1fr;} }
.foot-brand .foot-lockup{height:34px; width:auto; display:block; margin-bottom:11px;}
/* 225px sets the cap height at roughly 10px, about a 14px type size.
   Inside the stacked lockup this rendered at about 3px. */
.foot-brand .foot-strapline{width:225px; height:auto; display:block; margin-bottom:20px;}
.foot-col h2{
  font-family:'Instrument Sans',sans-serif;
  font-size:var(--t-label); letter-spacing:0.12em; text-transform:uppercase;
  color:var(--accent-lift); margin-bottom:14px; font-weight:700;
}
.foot-col p, .foot-col a{display:block; color:rgba(216,223,226,0.82); margin-bottom:9px;}
.foot-col a{transition:color var(--dur) var(--ease);}
.foot-col a:hover{color:var(--paper); text-decoration:underline; text-underline-offset:3px;}
.foot-bottom{
  display:flex; justify-content:space-between; gap:12px; flex-wrap:wrap;
  font-size:13.5px; color:rgba(216,223,226,0.62);
}
.foot-bottom a:hover{color:var(--paper); text-decoration:underline; text-underline-offset:3px;}


/* ====================================================================
   19. UTILITIES AND MOTION
   ==================================================================== */

.centred{text-align:center;}
.stack>*+*{margin-top:18px;}
.visually-hidden{
  position:absolute; width:1px; height:1px; padding:0; margin:-1px;
  overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; border:0;
}
/* Dark grounds get their own focus colour so the ring always clears 3:1
   against what is behind it, and their own link colour. */
.on-dark{--focus:var(--accent-lift);}

/* One scroll-reveal treatment, applied to section blocks only: a short
   fade and a 10px rise, once. No stagger, no cascade, nothing on
   individual list items, and nothing that loops or parallaxes.
   site.js adds .reveal only when motion is allowed and IntersectionObserver
   exists, so with JS off or reduced motion on, content is simply there. */
.reveal{opacity:0; transform:translateY(10px);}
.reveal.is-in{
  opacity:1; transform:none;
  transition:opacity 480ms var(--ease), transform 480ms var(--ease);
}

@media (prefers-reduced-motion: reduce){
  html{scroll-behavior:auto;}
  *{transition-duration:0.01ms !important; animation-duration:0.01ms !important;}
  .reveal{opacity:1; transform:none;}
}

@media print{
  .reveal{opacity:1 !important; transform:none !important;}
  .site-header{position:static;}
  .cta, .nav-toggle, .header-actions{display:none;}
}


/* ====================================================================
   20. FORM
   One form on the site: the employer enquiry on contact.html. It is a
   Netlify form, so there is no backend and no JavaScript: the markup is
   parsed at deploy time and submissions land in the Netlify dashboard
   and in email.

   Spam is handled by a honeypot rather than a CAPTCHA. A CAPTCHA would
   mean a third-party script and a cookie-consent obligation on a site
   that self-hosts its fonts precisely to avoid third-party requests,
   and it taxes the legitimate user to stop the illegitimate one.
   ==================================================================== */

.enquiry-form{
  background:var(--paper); border:var(--hairline); border-radius:var(--radius);
  padding:34px;
}
@media(max-width:560px){ .enquiry-form{padding:26px 20px;} }

/* Short fields pair up on a wide screen; anything that needs room takes
   the full width by declaring .field-wide. */
.field-grid{display:grid; grid-template-columns:1fr 1fr; gap:20px 22px;}
@media(max-width:640px){ .field-grid{grid-template-columns:1fr;} }
.field-wide{grid-column:1 / -1;}

.field label{
  display:block; margin-bottom:6px;
  font-size:var(--t-small); font-weight:600; color:var(--ink);
}
.field .opt{font-weight:400; color:var(--ink-soft);}
.field input, .field select, .field textarea{
  width:100%; padding:11px 13px;
  font-family:inherit; font-size:16px;   /* 16px stops iOS zooming on focus */
  color:var(--ink); background:var(--ground);
  border:1px solid var(--line); border-radius:var(--radius);
  transition:border-color var(--dur) var(--ease);
}
.field textarea{min-height:132px; resize:vertical;}
.field input:hover, .field select:hover, .field textarea:hover{border-color:var(--ink-soft);}
.field input:focus-visible, .field select:focus-visible, .field textarea:focus-visible{
  outline:2px solid var(--focus); outline-offset:2px; border-color:var(--focus);
}
.field .hint{margin-top:6px; font-size:13.5px; color:var(--ink-soft);}

/* The note above the submit. It carries the do-not-send-health-data
   warning, which on an occupational health site is the one piece of
   form copy that genuinely matters. */
.form-note{
  margin:22px 0 0; font-size:13.5px; color:var(--ink-soft); max-width:62ch;
}
.form-note strong{color:var(--ink);}
.enquiry-form .btn{margin-top:20px;}

/* The honeypot. Hidden from sight and from assistive technology, but
   still submitted, so a bot that fills every field gives itself away.
   Not display:none, which some bots skip. */
.hp{position:absolute; left:-9999px; width:1px; height:1px; overflow:hidden;}
