/* ===========================================================
   MSM Driving Academy — shared stylesheet
   Built by Topline Studio. Design carried over from the pitch mockup.
   Recoloured to Mark's corporate blue/yellow at his request, 30 Aug 2026.
   =========================================================== */

:root{
  /* Sampled from Mark's own logo, 30 Aug 2026: blue #3232ce, yellow #ffff00,
     red on the wordmark. Pure #ffff00 is 1.07:1 on white and can never carry
     text, so yellow is a SURFACE here and blue does the work. */
  --blue:#3232ce;
  --blue-600:#2727a6;
  --blue-deep:#1a1a6e;
  --navy:#10103a;
  --red:#ff4444;
  --red-deep:#c81e1e;
  --red-deeper:#a81717;  /* hover for .btn.red, now that --red-deep is the resting state */
  --cream:#fdf9e7;
  --cream-2:#f8f1d6;
  --white:#ffffff;
  --ink:#16162b;
  --slate:#545a75;
  --slate-2:#5f6480;   /* the muted body tone; must stay >=4.5:1 on --cream-2. */
  --line:#ede3be;
  --gold:#6e4e08;      /* darkened for the yellow ground: 4.94:1 on --cream-2. Only consumer is .stars. */
  --shadow:0 30px 60px -30px rgba(16,16,58,.5);
  --shadow-sm:0 18px 40px -26px rgba(16,16,58,.5);
  --shadow-card:0 14px 34px -22px rgba(16,16,58,.4);
  --r-lg:26px;
  --r-md:18px;
  --r-sm:12px;
}

*{box-sizing:border-box;}
html{scroll-behavior:smooth;}
body{
  margin:0;
  background:var(--cream);
  color:var(--ink);
  font-family:"Inter",system-ui,sans-serif;
  font-weight:400;
  line-height:1.7;
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
}
img{display:block;max-width:100%;}
/* WebP is served via <picture>. display:contents makes the <img> the effective
   grid/flex child so existing selectors like .gphoto img keep working — without
   it the <picture> becomes the child and the sizing rules miss. */
picture{display:contents;}
a{color:inherit;}
h1,h2,h3{font-family:"Sora",system-ui,sans-serif;font-weight:700;line-height:1.12;letter-spacing:-.02em;margin:0;color:var(--navy);}
.wrap{width:min(1200px,92vw);margin-inline:auto;}
section{position:relative;}

.eyebrow{
  display:inline-flex;align-items:center;gap:.6em;
  font-family:"Sora",sans-serif;
  font-size:.72rem;letter-spacing:.22em;text-transform:uppercase;
  font-weight:600;color:var(--blue);margin:0 0 16px;
}
.eyebrow::before{content:"";width:26px;height:2px;background:var(--red);border-radius:2px;}

/* ---------- buttons ---------- */
.btn{
  display:inline-flex;align-items:center;gap:.55em;
  font-family:"Sora",sans-serif;font-weight:600;font-size:1rem;
  color:var(--white);background:var(--blue);
  padding:15px 28px;border-radius:14px;text-decoration:none;
  box-shadow:0 16px 30px -14px rgba(50,50,206,.65);
  transition:transform .3s cubic-bezier(.2,.7,.2,1), box-shadow .3s, background .25s;
  border:0;cursor:pointer;
}
.btn:hover{transform:translateY(-3px);background:var(--blue-600);box-shadow:0 22px 38px -14px rgba(39,39,166,.8);}
.btn .arr{transition:transform .3s;}
.btn:hover .arr{transform:translateX(4px);}
.btn.red{background:var(--red-deep);color:var(--white);box-shadow:0 16px 30px -14px rgba(200,30,30,.6);}
.btn.red:hover{background:var(--red-deeper);box-shadow:0 22px 38px -14px rgba(168,23,23,.7);}
.btn.ghost{background:transparent;color:var(--navy);border:1.6px solid var(--line);box-shadow:none;}
.btn.ghost:hover{background:var(--cream-2);border-color:var(--blue);color:var(--blue);transform:translateY(-2px);}
.btn.light{background:var(--white);color:var(--blue);box-shadow:0 16px 30px -16px rgba(0,0,0,.35);}
.btn.light:hover{background:var(--cream-2);color:var(--blue-600);}

/* ---------- header ---------- */
/* Skip link. Every page repeats 9-15 nav tab stops before the content, so a
   keyboard or screen-reader user had to tab through the whole header on each
   one. Visible only when focused. */
.skip-link{position:absolute;left:12px;top:-60px;z-index:200;background:var(--blue);color:#fff;
  padding:12px 18px;border-radius:0 0 10px 10px;font-weight:600;text-decoration:none;
  transition:top .18s;}
.skip-link:focus{top:0;outline:3px solid var(--red);outline-offset:2px;}
main:focus{outline:none;}

header{
  position:sticky;top:0;z-index:50;
  background:rgba(253,249,231,.85);
  backdrop-filter:saturate(160%) blur(12px);
  border-bottom:1px solid var(--line);
}
/* The header needs 1309px of natural width (wordmark 348 + nav 583 + cta 338 +
   two 20px gaps) but .wrap caps at min(1200px,92vw) — so it was 109px over at
   EVERY screen size, right up to 1600. The nav links are white-space:nowrap and
   cannot shrink, so all 109px came out of the wordmark and the phone/CTA block:
   the phone broke onto two lines and "Book a lesson" onto three or four. Fixed
   by giving the strapline a deliberate two-line width (saves ~180px), pinning
   the phone/CTA block so it never shrinks, and trimming the nav gap. */
.topbar{display:flex;align-items:center;justify-content:space-between;gap:20px;padding:15px 0;}
.wordmark{display:flex;align-items:center;gap:12px;text-decoration:none;min-width:0;flex:0 1 auto;}
/* Mark's real logo, supplied 14 Aug. It replaced a green "MSM" badge we had
   invented. His yellow/blue is loud against this cream-and-green palette, but
   it is the same yellow/blue that is on the side of both cars — so a learner
   who saw the car recognises the site, which is worth more than a tidy
   palette. It sits in a white rounded plate so it reads as a logo rather than
   a stray bright rectangle.
   The business name is NOT repeated as text beside it: the logo already says
   "MSM DRIVING ACADEMY", and the name is carried in the <img> alt for search
   engines and screen readers. */
.wm-logo{
  flex:none;display:block;background:var(--white);
  border:1px solid var(--line);border-radius:12px;padding:5px 8px;
  box-shadow:0 8px 18px -12px rgba(16,16,58,.5);
  line-height:0;
}
/* 42 -> 64 at Mark's request, 30 Aug. Paid for by dropping the strapline that
   sat beside it; the header still fits nav, phone and CTA at every width from
   320 to 1600. Mobile is already a two-row header, so the bigger mark costs no
   extra height there. */
.wm-logo img{height:64px;width:auto;display:block;}
@media (max-width:640px){.wm-logo img{height:52px;}}
.wm-text{line-height:1.05;}
.wm-text .role{display:block;font-size:.66rem;letter-spacing:.12em;text-transform:uppercase;color:var(--slate-2);font-weight:600;
  white-space:normal;max-width:18ch;line-height:1.32;}  /* 18ch is the narrowest value that still gives exactly two lines — 16ch spills to three */

.nav-links{display:flex;align-items:center;gap:18px;}
.nav-links a{font-size:.92rem;font-weight:500;color:var(--slate);text-decoration:none;transition:color .2s;white-space:nowrap;}
.nav-links a:hover,.nav-links a.active{color:var(--blue);}
.nav-links a.active{font-weight:600;}
.nav-cta{display:flex;align-items:center;gap:16px;flex:0 0 auto;}  /* never absorb the shortfall — see .topbar note */
.nav-phone{font-family:"Sora",sans-serif;font-weight:600;color:var(--navy);text-decoration:none;font-size:.95rem;display:inline-flex;align-items:center;gap:.4em;white-space:nowrap;}
.nav-cta .btn{white-space:nowrap;}

/* dropdown for lesson pages */
.has-sub{position:relative;}
.has-sub > a::after{content:"▾";font-size:.7em;margin-left:.35em;opacity:.6;}
.subnav{
  position:absolute;left:-14px;top:100%;min-width:250px;
  background:var(--white);border:1px solid var(--line);border-radius:var(--r-md);
  box-shadow:var(--shadow);padding:10px;margin-top:10px;
  opacity:0;visibility:hidden;transform:translateY(8px);
  transition:opacity .22s ease, transform .22s ease, visibility .22s;
}
.has-sub:hover .subnav,.has-sub:focus-within .subnav{opacity:1;visibility:visible;transform:none;}
.subnav a{display:block;padding:9px 14px;border-radius:10px;font-size:.92rem;color:var(--slate);}
.subnav a:hover{background:var(--cream-2);color:var(--blue);}

/* mobile nav */
.nav-toggle{
  display:none;background:var(--white);border:1.5px solid var(--line);border-radius:12px;
  width:46px;height:46px;cursor:pointer;color:var(--navy);
  align-items:center;justify-content:center;flex:none;
}
/* Breakpoint raised 980 -> 1279. The desktop header needs ~1157px of natural
   width and .wrap only offers 92vw capped at 1200 — so between 981 and 1279 the
   wordmark was being squeezed below its own text and the strapline overlapped
   the nav links. There is no shaving that fixes 1024; the honest answer is to
   show the burger until there is genuinely room. Verified: 1280 fits with 21px
   to spare, 1279 and below get the (now tidy) drawer. */
@media (max-width:1279px){
  .nav-links{
    display:none;position:absolute;left:0;right:0;top:100%;
    flex-direction:column;align-items:stretch;gap:0;
    border-bottom:1px solid var(--line);
    box-shadow:var(--shadow-sm);padding:10px 4vw 18px;
    /* Scroll affordance. The panel scrolls internally (see max-height below)
       but macOS/iOS hide overlay scrollbars, so there was nothing to say more
       items existed below the fold. Two cover gradients scroll WITH the content
       (background-attachment:local) and sit on top of two fixed shadow
       gradients — so the shadow only shows on the edge you can still scroll
       towards, and disappears once you reach it. Pure CSS, self-hiding, no JS. */
    background-color:var(--white);
    background-image:
      linear-gradient(var(--white) 30%, rgba(255,255,255,0)),
      linear-gradient(rgba(255,255,255,0), var(--white) 70%),
      radial-gradient(farthest-side at 50% 0, rgba(16,16,58,.22), rgba(16,16,58,0)),
      radial-gradient(farthest-side at 50% 100%, rgba(16,16,58,.22), rgba(16,16,58,0));
    background-position:0 0, 0 100%, 0 0, 0 100%;
    background-repeat:no-repeat;
    background-size:100% 34px, 100% 34px, 100% 13px, 100% 13px;
    background-attachment:local, local, scroll, scroll;
    /* and show a real scrollbar where the platform allows one */
    scrollbar-width:thin;
    scrollbar-color:var(--blue) transparent;
    /* The panel is taller than a phone viewport and the header is sticky, so
       page scrolling could not reach its last items — and the fixed .callbar
       covered the ones above those. On a 390x734 iPhone that put "Contact"
       off-screen entirely with no way to get to it. Cap the height, scroll
       inside the panel, and reserve room for the call bar. */
    max-height:calc(100dvh - 100% - 92px);
    overflow-y:auto;
    -webkit-overflow-scrolling:touch;
    overscroll-behavior:contain;
  }
  .nav-links.open{display:flex;}
  .nav-links a{padding:13px 8px;border-bottom:1px solid var(--line);font-size:1rem;}
  /* On desktop .subnav is position:absolute, which blockifies it. Going static
     on mobile let it fall back to display:inline — an inline box wrapping
     block-level <a> children, which is what produced the ragged, part-width
     divider lines. Blockify both it and its inline .has-sub parent, drop the
     14px indent so the lesson pages line up with Home / The app, and square off
     the border-radius the desktop rule leaves on the links (it was rounding the
     ends of every divider). */
  .has-sub{display:block;}
  /* the parent link is inline, so its border-bottom only spanned its own text
     width (84px) and read as another ragged divider */
  .has-sub > a{display:block;}
  .subnav{display:block;position:static;opacity:1;visibility:visible;transform:none;box-shadow:none;border:0;margin:0;padding:0;min-width:0;}
  .subnav a{border-radius:0;padding:13px 8px;font-size:1rem;}
  .subnav a:hover{background:none;}
  .has-sub > a::after{content:"";}
  .nav-toggle{display:inline-flex;}
  .nav-links::-webkit-scrollbar{width:8px;}
  .nav-links::-webkit-scrollbar-track{background:transparent;}
  .nav-links::-webkit-scrollbar-thumb{background:var(--blue);border-radius:4px;}
}
@media (max-width:760px){
  /* Mark photographed this on his Android on 3 Sept: the "Book a lesson" label
     was overflowing its own button. Measured at 360/384/393px, and at 412px too
     once Android's display size is set above 1.0 — the label needs 137px of text
     inside a 114px box. It is not Android-only; the same widths fail on iPhone.

     The real problem was duplication. The fixed .callbar below carries BOTH
     "Call Mark" and "Book a lesson" on every page at this exact breakpoint, so
     the header was squeezing itself to repeat two actions that are already
     permanently on screen. Drop them from the header here and the topbar is
     just the logo and the burger — it no longer needs to wrap to a second row
     at all, so the squeeze cannot come back at any width or font scale. */
  .nav-cta .nav-phone, .nav-cta .btn{display:none;}
  .nav-cta{flex:0 0 auto;gap:0;}
}
@media (max-width:640px){
  .topbar{padding:13px 0;}
  .wordmark{flex:1 1 auto;}
}
@media (max-width:860px){.nav-phone-label{display:none;}}
/* The header strapline was removed outright on 30 Aug to make room for a
   bigger logo, so the old <380px rule that hid it is gone with it. */

/* ---------- sticky mobile call bar ---------- */
.callbar{
  position:fixed;left:0;right:0;bottom:0;z-index:60;display:none;
  gap:10px;padding:10px 14px calc(10px + env(safe-area-inset-bottom));
  background:rgba(255,255,255,.94);backdrop-filter:blur(10px);
  border-top:1px solid var(--line);box-shadow:0 -10px 30px -18px rgba(16,16,58,.5);
}
.callbar a{flex:1 1 0;justify-content:center;padding:14px 10px;font-size:.98rem;}
@media (max-width:760px){
  .callbar{display:flex;}
  body{padding-bottom:78px;}
}

/* ---------- reveal ---------- */
/* Gated on .js, which site.js sets on <html> before it registers the observer.
   Previously .reveal was opacity:0 by default and ONLY JavaScript ever cleared
   it — so if site.js 404'd, was blocked, or threw, every one of the 42 .reveal
   blocks stayed invisible and the page rendered as an empty rectangle. Now the
   content is visible by default and only hides when the script that un-hides it
   is known to be running. */
.js .reveal{opacity:0;transform:translateY(26px);transition:opacity .8s ease, transform .8s cubic-bezier(.2,.7,.2,1);}
.js .reveal.in{opacity:1;transform:none;}
.reveal.d1{transition-delay:.08s;}
.reveal.d2{transition-delay:.16s;}
.reveal.d3{transition-delay:.24s;}
@media (prefers-reduced-motion:reduce){
  .js .reveal{opacity:1!important;transform:none!important;}
  html{scroll-behavior:auto;}
}

/* ---------- hero (home) ---------- */
.hero{padding:70px 0 40px;position:relative;}
.hero::before{
  content:"";position:absolute;inset:0;z-index:-1;
  background:
    radial-gradient(600px 340px at 88% -8%, rgba(50,50,206,.10), transparent 70%),
    radial-gradient(520px 300px at 4% 108%, rgba(255,68,68,.10), transparent 70%);
}
.hero-grid{display:grid;grid-template-columns:1.05fr .95fr;gap:52px;align-items:center;}
.hero-tag{
  display:inline-flex;align-items:center;gap:.6em;
  background:var(--white);border:1px solid var(--line);
  padding:7px 15px;border-radius:999px;
  font-size:.78rem;font-weight:600;color:var(--blue-600);
  box-shadow:var(--shadow-card);margin-bottom:22px;
}
.hero-tag .dot{width:8px;height:8px;border-radius:50%;background:var(--red);box-shadow:0 0 0 4px rgba(255,68,68,.18);}
.hero h1{font-size:clamp(2.3rem,4.6vw,3.6rem);}
.hero h1 .hl{color:var(--blue);}
.hero-lead{font-size:1.13rem;color:var(--slate);margin:22px 0 8px;max-width:33ch;}
.hero-cta{display:flex;flex-wrap:wrap;gap:14px;margin-top:26px;}
.hero-chips{display:flex;flex-wrap:wrap;gap:10px;margin-top:28px;}
.chip{
  display:inline-flex;align-items:center;gap:.5em;
  background:var(--white);border:1px solid var(--line);
  padding:8px 14px;border-radius:12px;font-size:.85rem;font-weight:600;color:var(--slate);
  box-shadow:var(--shadow-card);
}
.chip svg{color:var(--blue);}
.hero-media{position:relative;}
.hero-photo{border-radius:var(--r-lg);overflow:hidden;aspect-ratio:4/4.4;box-shadow:var(--shadow);border:6px solid var(--white);}
.hero-photo img{width:100%;height:100%;object-fit:cover;transition:transform 1.2s ease;}
.hero-photo:hover img{transform:scale(1.05);}
.hero-float{
  position:absolute;left:-24px;bottom:26px;
  background:var(--white);border-radius:18px;padding:16px 20px;
  box-shadow:var(--shadow);border:1px solid var(--line);
  display:flex;align-items:center;gap:14px;max-width:250px;
}
.hero-float .big{font-family:"Sora",sans-serif;font-weight:800;font-size:1.7rem;color:var(--blue);line-height:1;}
.hero-float .lbl{font-size:.78rem;color:var(--slate);line-height:1.3;}
.hero-badge{
  /* Overhangs the hero photo by design. Pulled flush at 360px so it does not
     hang outside the viewport on the narrowest phones — see .stamp above. */
  position:absolute;right:-14px;top:26px;
  background:var(--red-deep);color:var(--white);
  font-family:"Sora",sans-serif;font-weight:700;font-size:.82rem;
  padding:10px 16px;border-radius:14px;transform:rotate(4deg);
  box-shadow:0 18px 34px -16px rgba(200,30,30,.8);
}
@media (max-width:900px){
  .hero-grid{grid-template-columns:1fr;gap:34px;}
  .hero-media{max-width:460px;margin-inline:auto;}
  .hero-lead{max-width:none;}
  .hero-float{left:-8px;}
}

/* ---------- page hero (inner pages) ---------- */
.phero{padding:56px 0 40px;position:relative;}
.phero::before{
  content:"";position:absolute;inset:0;z-index:-1;
  background:radial-gradient(700px 380px at 82% -20%, rgba(50,50,206,.10), transparent 70%);
}
.phero-grid{display:grid;grid-template-columns:1.1fr .9fr;gap:48px;align-items:center;}
.phero h1{font-size:clamp(2rem,3.9vw,3rem);}
.phero h1 .hl{color:var(--blue);}
.phero-lead{font-size:1.08rem;color:var(--slate);margin:20px 0 0;}
.phero-cta{display:flex;flex-wrap:wrap;gap:14px;margin-top:26px;}
.phero-photo{border-radius:var(--r-lg);overflow:hidden;aspect-ratio:4/3.1;box-shadow:var(--shadow);border:6px solid var(--white);}
/* Every other page heroes a landscape car photo, but Louise's page heroes a
   PORTRAIT headshot — and 4/3.1 cut roughly the top quarter off her, head
   included. The class is applied by measuring the real file, so it can never
   disagree with the photo that is actually there. */
.phero-photo.portrait{aspect-ratio:3/4;max-width:420px;margin-left:auto;}
.phero-photo img{width:100%;height:100%;object-fit:cover;}
@media (max-width:900px){.phero-grid{grid-template-columns:1fr;gap:32px;}}

/* ---------- breadcrumbs ---------- */
.crumbs{padding:16px 0 0;font-size:.82rem;color:var(--slate-2);}
.crumbs a{text-decoration:none;color:var(--slate-2);}
.crumbs a:hover{color:var(--blue);}
.crumbs span{margin:0 .45em;opacity:.5;}

/* ---------- trust strip ---------- */
.strip{padding:8px 0 6px;}
.strip-inner{
  display:grid;grid-template-columns:repeat(4,1fr);gap:20px;
  background:var(--navy);border-radius:var(--r-lg);padding:30px 34px;
  box-shadow:var(--shadow);
}
/* Centred, not left-aligned. Four stats in four equal columns read as a badge
   row when they are centred and as ragged text when they are not — and the two
   longer labels wrap, which made the whole strip look left-heavy. */
.strip-item{text-align:center;}
/* Keeps "Lesson types, from beginner to Pass Plus" from breaking one word onto
   its own line. Falls back harmlessly where it is unsupported. */
.strip-item .t{text-wrap:balance;}
.strip-item .n{font-family:"Sora",sans-serif;font-weight:800;font-size:1.65rem;color:var(--white);line-height:1;}
.strip-item .n span{color:var(--red);}
.strip-item .t{color:#c3c9e8;font-size:.9rem;margin-top:8px;}
@media (max-width:760px){.strip-inner{grid-template-columns:repeat(2,1fr);row-gap:26px;}}

/* ---------- about ---------- */
.about{padding:88px 0 78px;}
.about-grid{display:grid;grid-template-columns:.9fr 1.1fr;gap:56px;align-items:center;}
.about-photo{position:relative;}
.about-photo .frame{border-radius:var(--r-lg);overflow:hidden;aspect-ratio:4/4.6;box-shadow:var(--shadow);border:6px solid var(--white);}
/* Mark's photo is 835x1500 (0.56) and this frame is 4/4.6 (0.87), so cover
   crops top and bottom hard and the centre default was cutting his forehead
   off. Biasing the crop upward keeps his whole head in frame. Only used on the
   homepage's meet-your-instructor block, so nothing else is affected. */
.about-photo .frame img{width:100%;height:100%;object-fit:cover;object-position:50% 18%;transition:transform 1.1s ease;}
.about-photo:hover .frame img{transform:scale(1.04);}
.about-photo .stamp{
  position:absolute;right:-18px;bottom:28px;width:118px;height:118px;border-radius:50%;
  background:var(--white);box-shadow:var(--shadow);display:grid;place-items:center;text-align:center;
  border:1px solid var(--line);
}
/* The stamp deliberately overhangs the photo by 18px. On desktop that reads as
   a design flourish; on mobile the photo is full-bleed, so the overhang lands
   outside the viewport and drags a 2px horizontal scroll onto the homepage.
   Tuck it back inside below 640px — the effect still reads. */
@media (max-width:640px){.about-photo .stamp{right:6px;}}
.about-photo .stamp b{font-family:"Sora",sans-serif;color:var(--blue);font-size:1.5rem;display:block;line-height:1;}
.about-photo .stamp span{font-size:.66rem;color:var(--slate);text-transform:uppercase;letter-spacing:.12em;margin-top:4px;display:block;}
.about h2{font-size:clamp(1.8rem,3vw,2.5rem);margin-bottom:18px;}
.about p{color:var(--slate);margin:0 0 16px;}
.about .sign{font-family:"Sora",sans-serif;font-weight:700;color:var(--navy);margin-top:6px;}
.about .sign span{display:block;font-family:"Inter";font-weight:500;font-size:.85rem;color:var(--slate-2);}
.creds{display:flex;flex-wrap:wrap;gap:10px;margin:22px 0 4px;}
.cred{display:inline-flex;align-items:center;gap:.5em;background:var(--cream-2);border:1px solid var(--line);border-radius:10px;padding:8px 13px;font-size:.85rem;font-weight:600;color:var(--blue-deep);}
@media (max-width:900px){.about-grid{grid-template-columns:1fr;gap:38px;}.about-photo{max-width:420px;margin-inline:auto;}}

/* ---------- services / cards ---------- */
.services{padding:80px 0;background:var(--white);border-top:1px solid var(--line);border-bottom:1px solid var(--line);}
.sec-head{text-align:center;max-width:640px;margin:0 auto 46px;}
.sec-head h2{font-size:clamp(1.9rem,3.2vw,2.6rem);}
.sec-head p{color:var(--slate);margin-top:14px;}
.cards{display:grid;grid-template-columns:repeat(3,1fr);gap:22px;}
.card{
  position:relative;background:var(--cream);border:1px solid var(--line);border-radius:var(--r-md);
  padding:30px 26px;overflow:hidden;text-decoration:none;display:block;
  transition:transform .4s cubic-bezier(.2,.7,.2,1), box-shadow .4s, border-color .3s;
}
.card::before{content:"";position:absolute;left:0;top:0;height:4px;width:100%;background:linear-gradient(90deg,var(--blue),var(--red));transform:scaleX(0);transform-origin:left;transition:transform .45s ease;}
.card:hover{transform:translateY(-8px);box-shadow:var(--shadow);border-color:#cdd0ee;}
.card:hover::before{transform:scaleX(1);}
.card .ic{width:52px;height:52px;border-radius:14px;background:linear-gradient(150deg,rgba(50,50,206,.14),rgba(255,68,68,.14));display:grid;place-items:center;color:var(--blue);margin-bottom:18px;}
.card h3{font-size:1.16rem;margin-bottom:9px;}
.card p{color:var(--slate);font-size:.95rem;margin:0;}
.card .more{display:inline-flex;align-items:center;gap:.4em;margin-top:14px;font-family:"Sora",sans-serif;font-weight:600;font-size:.88rem;color:var(--blue);}
.card:hover .more .arr{transform:translateX(4px);}
.card .more .arr{transition:transform .3s;}
@media (max-width:900px){.cards{grid-template-columns:repeat(2,1fr);}}
@media (max-width:600px){.cards{grid-template-columns:1fr;}}

/* ---------- prose / content sections ---------- */
.prose{padding:70px 0;}
.prose-grid{display:grid;grid-template-columns:1.25fr .75fr;gap:56px;align-items:start;}
.prose-body h2{font-size:clamp(1.6rem,2.7vw,2.15rem);margin:0 0 16px;}
.prose-body h3{font-size:1.18rem;margin:34px 0 10px;}
.prose-body p{color:var(--slate);margin:0 0 16px;}
.prose-body ul{color:var(--slate);margin:0 0 20px;padding-left:0;list-style:none;display:grid;gap:11px;}
/* The tick used to be a flex item and the li a flex container. That quietly
   broke every bullet containing an inline tag: in a flex container each run of
   text becomes its own anonymous flex item and a <b> or <a> becomes another, so
   "valid for <b>12 months</b> from the day..." laid out as three columns rather
   than one sentence. It affected 33 bullets across 7 pages, including all five
   lesson pages. Absolute positioning keeps the text in normal inline flow, so
   inline elements behave like inline elements. */
.prose-body ul li{position:relative;padding-left:31px;}
.prose-body ul li::before{
  content:"";position:absolute;left:0;top:3px;width:20px;height:20px;border-radius:50%;
  background:rgba(50,50,206,.12) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%233232ce' stroke-width='3.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E") center/12px no-repeat;
}
.aside{position:sticky;top:98px;display:grid;gap:18px;}
.aside-card{background:var(--white);border:1px solid var(--line);border-radius:var(--r-md);padding:26px 24px;box-shadow:var(--shadow-card);}
.aside-card h3{font-size:1.08rem;margin-bottom:12px;}
.aside-card p{color:var(--slate);font-size:.93rem;margin:0 0 16px;}
.aside-card .btn{width:100%;justify-content:center;}
.aside-card.dark{background:linear-gradient(160deg,var(--blue-deep),var(--navy));border-color:transparent;}
.aside-card.dark h3{color:#fff;}
.aside-card.dark p{color:#c3c9e8;}
.aside-list{list-style:none;padding:0;margin:0;display:grid;gap:11px;}
.aside-list li{display:flex;justify-content:space-between;gap:12px;font-size:.93rem;color:var(--slate);padding-bottom:10px;border-bottom:1px solid var(--line);}
.aside-list li:last-child{border-bottom:0;padding-bottom:0;}
/* `white-space:nowrap` was safe while every value was a short token like
   "£42/hr". The app and instructor pages put phrases in here ("Debit or credit
   card, in the app"), which then could not wrap and pushed the whole aside
   past the viewport on a 360px phone. Wrapping, right-aligned: short values
   still sit on one line because they are short, long ones now fold. */
.aside-list li b{color:var(--navy);font-family:"Sora",sans-serif;text-align:right;min-width:0;}
@media (max-width:900px){.prose-grid{grid-template-columns:1fr;gap:36px;}.aside{position:static;}}
/* Grid items default to min-width:auto, so one unbreakable string sets the
   column's minimum width. "msmdrivingacademy@gmail.com" is 26 characters with
   nowhere to break, which pushed .prose-body past a 360px viewport on contact,
   the app page and the instructor page. min-width:0 lets the column shrink;
   break-word lets the address itself wrap rather than being clipped. */
.prose-grid > *{min-width:0;}
.prose-body{overflow-wrap:break-word;}
/* The li is no longer a flex container (see above), so the min-width:auto trap
   no longer applies to its children. `anywhere` (not `break-word`) is still
   needed on links: the email address has no natural break opportunity at all
   and would otherwise push the column wider than the page on a phone. */
.prose-body a{overflow-wrap:anywhere;}

/* ---------- instructor photos (about page) ---------- */
.team{display:grid;grid-template-columns:repeat(2,1fr);gap:18px;margin:22px 0 26px;}
.tmember{margin:0;background:var(--white);border:1px solid var(--line);border-radius:var(--r-md);overflow:hidden;box-shadow:var(--shadow-card);display:flex;flex-direction:column;}
/* No height:100% here — the grid stretches the figure to match its taller
   sibling, and an image filling that height pushes the caption out of the
   overflow:hidden box. Fixed aspect + auto height keeps both visible. */
/* 3/4, because that is the shape BOTH headshots actually are (1125x1500 and
   900x1200). A frame that matches its source crops nothing, which is the only
   way this stops needing a hand-tuned object-position every time a photo is
   replaced. Mark, 30 Aug: his was "a bit too cropped in", Louise's head was
   clipped. Her master has ~4% headroom, so any vertical crop cut her hair.
   object-position is a fallback for a future photo of another shape. */
.tmember img{width:100%;height:auto;aspect-ratio:3/4;object-fit:cover;object-position:50% 12%;display:block;}
.tmember figcaption{padding:14px 16px 16px;}
.tmember figcaption b{display:block;font-family:"Sora",sans-serif;font-weight:700;color:var(--navy);font-size:1rem;}
.tmember figcaption span{display:block;margin-top:3px;color:var(--slate);font-size:.82rem;}
/* Academic qualifications, supplied by Mark 30 Aug. Set smaller and lighter than
   the role: the ADI line is the one a customer actually checks for, and letters
   after a name should not outshout it. */
.tmember figcaption .quals{margin-top:5px;font-size:.74rem;letter-spacing:.03em;color:var(--slate-2);}
@media (max-width:520px){.team{gap:12px;}.tmember figcaption{padding:11px 12px 13px;}.tmember figcaption b{font-size:.9rem;}.tmember figcaption span{font-size:.75rem;}}

/* ---------- price table ---------- */
.ptable{background:var(--white);border:1px solid var(--line);border-radius:var(--r-md);overflow:hidden;box-shadow:var(--shadow-card);}
.ptable table{width:100%;border-collapse:collapse;}
.ptable th{
  text-align:left;font-family:"Sora",sans-serif;font-size:.74rem;letter-spacing:.14em;text-transform:uppercase;
  color:var(--slate-2);font-weight:700;padding:16px 24px;background:var(--cream-2);border-bottom:1px solid var(--line);
}
.ptable th.r,.ptable td.r{text-align:right;}
.ptable td{padding:20px 24px;border-bottom:1px solid var(--line);vertical-align:top;color:var(--slate);font-size:.95rem;}
.ptable tr:last-child td{border-bottom:0;}
.ptable td .nm{font-family:"Sora",sans-serif;font-weight:700;color:var(--navy);font-size:1rem;display:block;margin-bottom:3px;}
.ptable td.r{font-family:"Sora",sans-serif;font-weight:700;color:var(--blue);font-size:1.05rem;white-space:nowrap;}
/* Secondary line under a table value — the real 2-hour total under an hourly
   rate, or an instructor's availability under what they teach. */
.ptable td .sub2{
  display:block;margin-top:4px;font-family:"Inter",sans-serif;font-weight:500;
  color:var(--slate);font-size:.8rem;white-space:normal;
}
/* Standing caveat under a table, e.g. out-of-hours availability. */
.note{
  margin:14px 0 0;color:var(--slate);font-size:.88rem;line-height:1.6;
  padding-left:14px;border-left:2px solid var(--line);
}
@media (max-width:620px){
  .ptable th{padding:12px 16px;}
  .ptable td{padding:16px 16px;font-size:.9rem;}
}

/* The form got long once Mark added address, theory and test fields — these
   group headings stop it reading as an intimidating wall of inputs. */
.book-form .fgroup{
  font-family:"Sora",sans-serif;font-size:.72rem;font-weight:700;letter-spacing:.13em;
  text-transform:uppercase;color:var(--blue);margin:26px 0 -2px;
  padding-bottom:8px;border-bottom:1px solid var(--line);
}
.book-form .fgroup:first-of-type{margin-top:18px;}
.book-form .opt{font-weight:400;color:var(--slate-2);}  /* was a hardcoded #6f7592 that bypassed the token, so it kept failing at 4.42 */
/* Hint under a single input (not the checkbox, which nests its own). */
.book-form .field > .hint{
  display:block;margin-top:6px;font-size:.8rem;line-height:1.5;color:var(--slate);
}

/* Booking form: request-a-female-instructor checkbox. The hint carries the
   availability caveat, so nobody ticks it expecting a free choice of car. */
.book-form .check{
  display:flex;gap:12px;align-items:flex-start;cursor:pointer;
  background:var(--cream);border:1px solid var(--line);border-radius:var(--r-sm);
  padding:14px 16px;margin:0;
}
.book-form .check input[type="checkbox"]{
  width:20px;height:20px;margin:2px 0 0;flex:0 0 auto;accent-color:var(--blue);cursor:pointer;
}
.book-form .check b{display:block;font-size:.95rem;color:var(--navy);margin-bottom:3px;}
.book-form .check .hint{display:block;font-size:.82rem;line-height:1.5;color:var(--slate);}
.book-form .check:hover{border-color:var(--blue);}
.book-form .check:focus-within{outline:2px solid var(--blue);outline-offset:2px;}

/* ---------- PASS GALLERY ---------- */
/* Pass photos are the most persuasive thing a driving school can show — proof
   the product works, produced weekly for free. Grid keeps its shape whether
   there are 6 or 60. */
.passgrid{
  display:grid;grid-template-columns:repeat(auto-fill,minmax(230px,1fr));
  gap:18px;margin-top:26px;
  /* Only some passes carry a date — we publish one only where it is actually
     known. Without this, grid items stretch to the tallest in the row and an
     undated card grows an empty white strip where its caption would be. */
  align-items:start;
}
.passgrid figure.pass{margin:0;background:var(--white);border:1px solid var(--line);
  border-radius:var(--r-md);overflow:hidden;box-shadow:var(--shadow-card);}
/* height:auto is load-bearing. Every <img> carries width/height attributes for CLS,
   and the HTML height attribute is a presentational hint that still applies once
   width is overridden — so without height:auto the box renders at the file's own
   pixel height (a 1000px-tall card in a 292px column) and aspect-ratio is ignored.
   .tmember img above gets this right; this rule did not, and it never showed
   because passes.html had no photos to build with until 19 Aug 2026. */
.passgrid figure.pass img{width:100%;height:auto;aspect-ratio:4/5;object-fit:cover;display:block;}
.passgrid figure.pass figcaption{
  padding:12px 14px;font-family:"Sora",sans-serif;font-weight:600;
  font-size:.88rem;color:var(--navy);
}
.passgrid figure.pass figcaption time{color:var(--blue);}
@media (max-width:520px){
  .passgrid{grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:12px;}
}

/* The review ask — gallery page only, never on pages whose job is enquiries. */
.reviewask{
  background:var(--white);border:1px solid var(--line);border-radius:var(--r-md);
  padding:28px 30px;text-align:center;box-shadow:var(--shadow-card);margin-top:34px;
}
.reviewask h3{font-family:"Sora",sans-serif;color:var(--navy);margin:0 0 8px;font-size:1.15rem;}
.reviewask p{max-width:52ch;margin:0 auto 18px;color:var(--slate);font-size:.95rem;}

/* Priced case-by-case on purpose — an answer, not a gap. Must not look like a TBC. */
.byarr{
  font-family:"Inter",sans-serif;font-weight:500;color:var(--slate);
  font-size:.9rem;white-space:normal;
}

/* price / detail still to confirm with Mark — visible on purpose so it can't ship by accident */
.tbc{
  display:inline-block;background:#fbe3a6;border:1px dashed #b98a12;color:#6e4e08;
  font-family:"Space Mono",ui-monospace,Menlo,monospace;font-size:.82em;font-weight:700;
  padding:1px 8px;border-radius:6px;letter-spacing:.02em;white-space:nowrap;
}

/* ---------- FAQ ---------- */
.faq{padding:76px 0;background:var(--white);border-top:1px solid var(--line);}
.faq-list{max-width:820px;margin:0 auto;display:grid;gap:12px;}
.faq-item{background:var(--cream);border:1px solid var(--line);border-radius:var(--r-md);overflow:hidden;}
.faq-item summary{
  cursor:pointer;list-style:none;padding:20px 24px;
  font-family:"Sora",sans-serif;font-weight:600;font-size:1.02rem;color:var(--navy);
  display:flex;justify-content:space-between;align-items:center;gap:16px;
}
.faq-item summary::-webkit-details-marker{display:none;}
.faq-item summary::after{
  content:"+";flex:none;width:28px;height:28px;border-radius:50%;
  background:rgba(50,50,206,.12);color:var(--blue);
  display:grid;place-items:center;font-size:1.2rem;font-weight:700;transition:transform .3s;
}
.faq-item[open] summary::after{content:"−";transform:rotate(180deg);}
.faq-item .a{padding:0 24px 22px;color:var(--slate);font-size:.96rem;}
.faq-item .a p{margin:0 0 12px;}
.faq-item .a p:last-child{margin:0;}

/* ---------- gallery ---------- */
.gallery{padding:80px 0 40px;}
/* `dense` lets the small cells backfill the gaps a `tall` or `wide` cell leaves
   behind, so the grid stays solid at both column counts. It only works because
   GALLERY_PHOTOS is sized to fill whole rows — see the note in build.py. */
/* Row height sets every cell's shape, and every cell crops with
   object-fit:cover — so a row height that disagrees with the photos throws
   the difference away. At 180px the cells were 1.57 (normal) and 3.23 (wide)
   while most of Mark's photos are 0.75 portrait or 1.33 landscape, and the
   grid was quietly binning 50-67% of eight of them. 200px makes the normal
   cell 1.41 and the tall cell 0.68, which is close to what the photos
   actually are. build.py now picks each cell FROM the file's real dimensions
   (see gallery_cell) instead of hand-assigning, so this stays true when Mark
   sends new photos. */
.ggrid{display:grid;grid-template-columns:repeat(4,1fr);grid-auto-rows:200px;gap:16px;grid-auto-flow:dense;}
.gphoto{border-radius:var(--r-md);overflow:hidden;box-shadow:var(--shadow-card);}
.gphoto img{width:100%;height:100%;object-fit:cover;transition:transform 1s ease;}
.gphoto:hover img{transform:scale(1.07);}
.gphoto.tall{grid-row:span 2;}
.gphoto.wide{grid-column:span 2;}
/* 2x2. The old set had no cell for an ordinary landscape photo that deserves
   size: `wide` is a 2.9 letterbox and anything squarer lost half its frame. */
.gphoto.big{grid-column:span 2;grid-row:span 2;}
/* Where a photo's subject is not in the middle, say so rather than letting the
   centre crop decide. The two-cars shot carries its L-plate roof sign at the
   very top and nothing but tarmac at the bottom, so a centred crop trims the
   one part that says "driving school". */
.gphoto.focus-top img{object-position:50% 28%;}
.gphoto.focus-bottom img{object-position:50% 72%;}
/* A three-photo block. Three wider columns need taller rows to keep the cell
   shape near the photos' 1.3-1.6, otherwise widening the column re-creates
   the same letterbox problem. */
.ggrid.trio{grid-template-columns:repeat(3,1fr);grid-auto-rows:260px;}
@media (max-width:760px){
  /* Two columns are much narrower, so the row must come down with them or the
     cells go square and crop the landscape shots. 112px keeps them at ~1.4. */
  .ggrid,.ggrid.trio{grid-template-columns:repeat(2,1fr);grid-auto-rows:112px;}
  .gphoto.wide{grid-column:span 2;}
}

/* ---------- embedded video (Total Drive app page) ---------- */
.videowrap{
  position:relative;width:100%;aspect-ratio:16/9;margin:22px 0 6px;
  border-radius:var(--r-md);overflow:hidden;box-shadow:var(--shadow-card);
  background:var(--navy);
}
.videowrap iframe{position:absolute;inset:0;width:100%;height:100%;border:0;}

/* ---------- car spec strip (under the gallery) ---------- */
/* Cars used to be three lines of text beside the feature list, which told you
   the models but not which car turns up on your driveway. Each car now carries
   its own photo and says whose it is — the one thing a learner actually wants
   to match up. That needs the full width, so cars sit on top and the features
   run underneath rather than the two sharing a row. */
.carspec{
  margin-top:28px;padding:26px 28px;background:var(--white);
  border:1px solid var(--line);border-radius:var(--r-md);box-shadow:var(--shadow-card);
}
.carspec-cars{display:grid;grid-template-columns:repeat(3,1fr);gap:18px;}
.carspec-car{margin:0;}
.carspec-shot{margin:0;}
.carspec-car img{
  width:100%;height:auto;aspect-ratio:4/3;object-fit:cover;display:block;
  border-radius:var(--r-sm);background:var(--cream-2);
}
.carspec-car figcaption{padding-top:10px;}
.carspec-car b{display:block;font-size:1.02rem;color:var(--ink);}
.carspec-car span{font-size:.86rem;color:var(--slate-2);}
/* One disclosure per car. <details> is used rather than a scripted panel so it
   still opens with JavaScript off and announces itself properly to a screen
   reader. The marker is replaced with our own chevron because the native
   triangle sits at a different size and colour in every browser. */
.carmore{margin-top:10px;}
.carmore > summary{
  display:inline-flex;align-items:center;gap:.45em;cursor:pointer;
  font-family:"Sora",sans-serif;font-weight:600;font-size:.85rem;
  color:var(--blue);padding:7px 12px;border:1px solid var(--line);
  border-radius:999px;background:var(--cream-2);
  transition:background .25s, border-color .25s;
  list-style:none;               /* Firefox */
}
.carmore > summary::-webkit-details-marker{display:none;}
.carmore > summary::after{
  content:"";width:.42em;height:.42em;border-right:2px solid currentColor;
  border-bottom:2px solid currentColor;transform:rotate(45deg) translate(-1px,-1px);
  transition:transform .25s;
}
.carmore[open] > summary::after{transform:rotate(-135deg) translate(-1px,-1px);}
.carmore > summary:hover{background:var(--white);border-color:var(--blue);}
.carmore > summary:focus-visible{outline:2px solid var(--blue);outline-offset:2px;}
.carmore-grid{
  display:grid;grid-template-columns:repeat(2,1fr);gap:10px;margin-top:12px;
}
.carmore-shot{margin:0;}
.carmore-shot img{
  width:100%;height:auto;aspect-ratio:4/3;object-fit:cover;display:block;
  border-radius:var(--r-sm);background:var(--cream-2);
}
.carspec-note{
  margin:18px 0 0;padding-top:18px;border-top:1px solid var(--line);
  font-size:.9rem;color:var(--slate);line-height:1.5;
}
.carspec-feats{
  list-style:none;margin:18px 0 0;padding-top:18px;border-top:1px solid var(--line);
  display:grid;grid-template-columns:repeat(4,1fr);gap:12px 24px;
}
.carspec-feats li{font-size:.88rem;color:var(--slate);line-height:1.45;}
.carspec-feats b{display:block;color:var(--ink);font-size:.92rem;}
@media (max-width:900px){
  .carspec-feats{grid-template-columns:1fr 1fr;}
}
@media (max-width:640px){
  .carspec{padding:22px;}
  .carmore-grid{gap:8px;}
  /* Three cars side by side on a phone are too small to tell apart, which
     defeats the point of showing them. One per row instead. */
  .carspec-cars{grid-template-columns:1fr;gap:22px;}
  .carspec-feats{grid-template-columns:1fr;}
}

/* ---------- booking ---------- */
.book{padding:80px 0;}
.book-panel{
  display:grid;grid-template-columns:.95fr 1.05fr;gap:0;
  border-radius:var(--r-lg);overflow:hidden;box-shadow:var(--shadow);border:1px solid var(--line);
  background:var(--white);
}
.book-side{background:linear-gradient(160deg,var(--blue-deep),var(--navy));color:var(--white);padding:46px 40px;}
.book-side .eyebrow{color:#c2cbff;}
.book-side .eyebrow::before{background:var(--red);}
.book-side h2{color:var(--white);font-size:clamp(1.7rem,2.6vw,2.2rem);}
.book-side p{color:#c3c9e8;margin:16px 0 26px;}
.book-side ul{list-style:none;padding:0;margin:0;display:grid;gap:14px;}
.book-side li{display:flex;gap:12px;align-items:flex-start;font-size:.96rem;color:#e3e6f5;}
.book-side li svg{flex:none;color:#8fa3ff;margin-top:2px;}
.book-form{padding:42px 40px;}
.book-form h3{font-size:1.3rem;margin-bottom:6px;}
.book-form .muted{color:var(--slate-2);font-size:.9rem;margin:0 0 22px;}
.field{margin-bottom:16px;}
.field label{display:block;font-size:.82rem;font-weight:600;color:var(--navy);margin-bottom:6px;}
.field input,.field select,.field textarea{
  width:100%;padding:12px 14px;border:1.5px solid var(--line);border-radius:12px;
  font-family:"Inter",sans-serif;font-size:max(16px,.95rem);color:var(--ink);background:var(--cream);
  transition:border-color .2s, box-shadow .2s;
}
.field input:focus,.field select:focus,.field textarea:focus{outline:0;border-color:var(--blue);box-shadow:0 0 0 4px rgba(50,50,206,.12);background:var(--white);}
.field textarea{resize:vertical;min-height:82px;}
.frow{display:grid;grid-template-columns:1fr 1fr;gap:14px;}
.book-form .btn{width:100%;justify-content:center;margin-top:6px;}
.book-note{font-size:.78rem;color:var(--slate-2);text-align:center;margin:14px 0 0;}
@media (max-width:900px){.book-panel{grid-template-columns:1fr;}.frow{grid-template-columns:1fr;}}

/* ---------- reviews ---------- */
.reviews{padding:70px 0 80px;background:var(--white);border-top:1px solid var(--line);}
.rgrid{display:grid;grid-template-columns:repeat(3,1fr);gap:22px;margin-top:44px;}
.rcard{background:var(--cream);border:1px solid var(--line);border-radius:var(--r-md);padding:28px 26px;box-shadow:var(--shadow-card);}
.stars{color:var(--gold);letter-spacing:2px;font-size:1rem;margin-bottom:12px;}
.rcard p{color:var(--slate);font-size:.96rem;margin:0 0 18px;font-style:italic;}
.rwho{display:flex;align-items:center;gap:12px;}
.rwho .av{width:42px;height:42px;border-radius:50%;background:linear-gradient(150deg,var(--blue),var(--red-deep));color:#fff;display:grid;place-items:center;font-family:"Sora",sans-serif;font-weight:700;font-size:.95rem;flex:none;}
.rwho .nm{font-family:"Sora",sans-serif;font-weight:600;color:var(--navy);font-size:.95rem;}
.rwho .mt{font-size:.78rem;color:var(--slate-2);}
@media (max-width:900px){.rgrid{grid-template-columns:1fr;}}

/* ---------- cta ---------- */
.cta{padding:20px 0 90px;}
.cta-inner{
  background:linear-gradient(155deg,var(--blue) 0%,var(--blue-deep) 100%);
  border-radius:var(--r-lg);padding:60px 40px;text-align:center;color:var(--white);
  box-shadow:var(--shadow);position:relative;overflow:hidden;
}
.cta-inner::after{content:"";position:absolute;right:-60px;bottom:-60px;width:260px;height:260px;border-radius:50%;background:rgba(255,68,68,.25);}
.cta-inner .eyebrow{color:#c2cbff;position:relative;}
.cta-inner h2{color:var(--white);font-size:clamp(1.9rem,3.4vw,2.7rem);position:relative;}
.cta-inner p{color:#d3d8f0;max-width:52ch;margin:16px auto 28px;position:relative;}
.cta-actions{display:flex;gap:14px;justify-content:center;flex-wrap:wrap;position:relative;}

/* ---------- footer ---------- */
footer{background:var(--navy);color:#c3c9e8;padding:60px 0 30px;}
.foot-top{display:grid;grid-template-columns:1.4fr 1fr 1fr 1fr;gap:36px;padding-bottom:36px;border-bottom:1px solid rgba(255,255,255,.1);}
.foot-brand p{margin:16px 0 0;font-size:.92rem;max-width:34ch;}
.foot-brand .wm-text .role{color:#9aa3d0;}
.foot-col h3,.foot-col h4{font-family:"Sora",sans-serif;color:#fff;font-size:.95rem;margin:0 0 16px;}
.foot-col a,.foot-col span{display:block;color:#adb4dc;text-decoration:none;font-size:.92rem;margin-bottom:10px;transition:color .2s;}
.foot-col a:hover{color:var(--red);}
/* NAP block — must match the Google Business Profile word for word */
.nap{margin-top:4px;font-style:normal;color:#adb4dc;font-size:.92rem;line-height:1.9;}
.nap b{display:block;color:#fff;font-family:"Sora",sans-serif;font-weight:600;margin-bottom:2px;}
.nap a{color:#adb4dc;text-decoration:none;}
.nap a:hover{color:var(--red);}
.foot-bottom{display:flex;justify-content:space-between;gap:16px;flex-wrap:wrap;padding-top:24px;font-size:.82rem;color:#9aa3d0;}
.disclaimer{max-width:640px;}
.disclaimer a{color:#c2cbff;font-weight:600;text-decoration:none;}
.disclaimer a:hover{text-decoration:underline;}
@media (max-width:980px){.foot-top{grid-template-columns:1fr 1fr;gap:30px;}.foot-brand{grid-column:1/-1;}}
@media (max-width:560px){.foot-top{grid-template-columns:1fr;}}

@media (max-width:380px){.hero-badge{right:0;}}

/* ---- booking form: honeypot, status line, success state ----
   Added 16 Aug 2026 with the switch from a mailto: handoff to a real POST. */

/* Hidden from people, not from bots. Deliberately NOT display:none — some
   spam bots skip those fields, and a honeypot nothing fills catches nothing. */
.hp{position:absolute;left:-9999px;top:auto;width:1px;height:1px;overflow:hidden;}

.book-status{
  margin:12px 0 0;padding:11px 14px;border-radius:var(--r-sm);
  font-size:.95rem;line-height:1.45;border:1px solid var(--line);
  background:var(--cream-2);color:var(--slate);
}
.book-status.is-busy{background:var(--cream-2);color:var(--slate);}
/* Success stays green and error stays red: these are status conventions, not
   the brand. --blue-600 is blue now, so this needs a green of its own. */
.book-status.is-ok{background:#e8f4ed;border-color:#bcdcc9;color:#1b6b41;}
.book-status.is-error{background:#fdebeb;border-color:#f5c2c2;color:#b01a1a;}
/* #b01a1a, not --red-deep: the token is 4.16:1 on this tint, just under the
   4.5 minimum, and this is error text — the one message that must be readable. */

.book-done{
  padding:26px 24px;border:1px solid var(--line);border-radius:var(--r-md);
  background:var(--cream-2);
}
.book-done h3{margin:0 0 10px;color:var(--navy);}
.book-done p{margin:0 0 10px;color:var(--slate);}
.book-done p:last-child{margin-bottom:0;}
.book-done a{color:var(--blue);font-weight:600;}

/* A disabled Send button must not look clickable. */
.btn[disabled]{opacity:.55;cursor:not-allowed;}

/* The [hidden] attribute only sets display:none via the UA stylesheet, so ANY
   author display rule beats it. .voucher-extras is display:grid and .cards is
   display:grid, so `el.hidden = true` silently did nothing on both — the
   optional fields stayed on screen after the page went into ring-Mark mode,
   and the voucher cards would have stayed up behind the success message.
   One reset, applied once, rather than remembering it per component. */
[hidden]{display:none !important;}

/* In-page jumps land under the sticky header without this, so the thing you
   clicked to see is hidden behind it. Honoured by #book on contact.html and
   index.html, and by the skip link's #main target. */
:target{scroll-margin-top:96px;}
#book,#main{scroll-margin-top:96px;}
/* Smooth only for people who have not asked for less motion. */
@media (prefers-reduced-motion:no-preference){html{scroll-behavior:smooth;}}

/* ---------- gift vouchers ---------- */
/* The two optional fields sit under the three voucher cards and are read at
   checkout time, so they are deliberately NOT a <form> — there is nothing to
   submit, and a form here would give Enter somewhere pointless to go. */
.voucher-extras{max-width:620px;margin:36px auto 0;display:grid;grid-template-columns:1fr 1fr;gap:14px;}
.voucher-extras .book-note{grid-column:1/-1;margin:0;}
@media (max-width:640px){.voucher-extras{grid-template-columns:1fr;}}
#voucher-notice{max-width:620px;margin:0 auto 28px;text-align:center;}
#voucher-notice a{color:inherit;font-weight:600;text-decoration:underline;}
.card .vbuy{margin-top:18px;width:100%;justify-content:center;}
.card .vbuy[disabled]{opacity:.55;cursor:not-allowed;transform:none;box-shadow:none;}
