/* v5 SITE: tokens, base type, header, footer, accessibility toolbar and its
   fonts, and the shared components (shell, intro, eyebrow, buttons, booking
   row, cards, tables, rich text, two-column info blocks, placeholders). Every
   v5-family page loads it; v5-home.css adds the homepage after it. */
/* HEADER: hides on scroll down, returns on scroll up (v5-site.js); sizes from the page tokens (--hdr-h). */
body.v5-site .top-bar{
  display:none;
}
/* Skip link (Justin, 2026-10-13): the first stop for Tab (first in
   <body>). Off-screen until it has keyboard focus (:focus-visible), then
   fixed at the top left above the header (z-index 9999, v5-base.css):
   navy, white text, a white ring inside a navy one so it reads on the
   photograph and on the slate header alike. Fixed and moved by transform,
   so showing it shifts no layout; a focus that follows a mouse click (Back
   to top, v5-site.js) is not :focus-visible and leaves it hidden. Its
   jump stays the browser's own (the in-page scroll skips it). */
body.v5-site .skip-link{position:fixed;top:var(--sp-1);left:var(--sp-1);font:700 1rem/1.25 var(--lato);border-radius:4px;transform:translateY(calc(-100% - var(--sp-1) - 12px))}
body.v5-site .skip-link:focus:not(:focus-visible){transform:translateY(calc(-100% - var(--sp-1) - 12px))}
body.v5-site .skip-link:focus-visible{transform:none;color:#FFFFFF;outline:3px solid #FFFFFF;outline-offset:0;box-shadow:0 0 0 6px var(--navy)}
@media (prefers-reduced-motion:reduce){body.v5-site .skip-link{transition:none}}
body.v5-site .site-header{
  z-index:1002;
  top:0;
  background-color:transparent;
  backdrop-filter:blur(14px);
  -webkit-backdrop-filter:blur(14px);
  box-shadow:none;
  transform:none;
  transition:transform .3s cubic-bezier(.33,1,.68,1),background-color .4s ease;
}
body.v5-site .site-header.is-solid,
body.v5-site .site-header.scrolled:not(.is-managed){
  background-color:var(--slate);
  backdrop-filter:none;
  -webkit-backdrop-filter:none;
}
body.v5-site .site-header.is-solid:not(.is-hidden),
body.v5-site .site-header.scrolled:not(.is-managed){
  box-shadow:0 4px 20px rgba(0,0,0,.15);
}
body.v5-site .site-header.is-hidden{
  transform:translateY(-100%);
  transition:transform .3s cubic-bezier(.33,1,.68,1);
}
/* Solid variant (child pages: every v5 page but the homepage), content
   below it. Navy (Justin, 2026-10-14): no photograph sits behind it, so it
   is navy from the top and stays navy when it returns on scroll (.is-solid,
   same hide/reveal). The phone link keeps its white outline pill (white on
   navy 10.6:1); the Book button turns white with charcoal text (16.6:1) and
   keeps the homepage's sweep, which brings in charcoal with white text. */
body.v5-hdr-solid .site-header,
body.v5-hdr-solid .site-header.is-solid,
body.v5-hdr-solid .site-header.scrolled:not(.is-managed){background-color:var(--navy);backdrop-filter:none;-webkit-backdrop-filter:none}
body.v5-hdr-solid .site-header:not(.is-hidden){box-shadow:0 4px 20px rgba(0,0,0,.15)}
body.v5-hdr-solid main.v5{padding-top:var(--hdr-h)}
@media (prefers-reduced-motion:reduce){
  body.v5-site .site-header,body.v5-site .site-header.is-hidden{transition:none}
}
body.v5-site .header-container,
body.v5-site .site-header.scrolled .header-container{
  max-width:none;
  height:var(--hdr-h);
  padding:0 var(--hdr-gut);
  column-gap:var(--sp-1);
}
body.v5-site .site-logo-link{
  display:block;
}
body.v5-site .site-logo-icon{
  display:none;
}
/* Header logo (Justin): 25% smaller on 2026-10-13 (62.4 -> 46.8px tall
   from 1000px, .75 x --sp-3 below), and from 1000px 25% smaller again on
   2026-10-14 (35.1px). From 768 to 999px it keeps its size at 767, so a
   tablet never shows a smaller logo than a phone: .75 x --sp-3 with --sp-3
   at 767px (1.57vw = 12.0419px), 29.75px tall and 155px wide at 100% text,
   and the phone header's size at 767 at any toolbar text size. Still
   --hdr-gut from the left edge and centred in the header. */
body.v5-site .site-logo-full{
  display:block;
  height:35.1px;
  width:auto;
  aspect-ratio:981/188;
}
@media (max-width:999px){
  body.v5-site .site-logo{flex-shrink:1;min-width:0}
  body.v5-site .site-logo-full{
    height:calc(.75 * var(--sp-3));
    max-width:100%;
    object-fit:contain;
    object-position:left center;
  }
  body.v5-site .mobile-menu-toggle{flex-shrink:0}
}
@media (min-width:768px) and (max-width:999px){body.v5-site .site-logo-full{height:calc(.75 * clamp(2.08rem,1.727rem + 12.0419px,3.375rem))}}
@media (min-width:1000px){
  body.v5-site .main-nav a{
    display:inline-block;
    padding-block:14px;
    margin-block:-14px;
  }
}
@media (hover:none){
  body.v5-site .main-nav a:hover{opacity:1}
  body.v5-site .hero-cta:hover:not(:focus-visible){
    background:#fff;
    color:var(--navy);
    box-shadow:0 4px 20px rgba(0,0,0,.3);
  }
}
/* v3's keyboard focus ring. */
body.v5-site :is(a,button):focus-visible{
  outline:3px solid #FFFFFF;
  outline-offset:3px;
  box-shadow:0 0 0 9px #1E1F21;
}
/* ACCESSIBILITY TOOLBAR: brand colours and v5 tokens; behaviour in v5-site.js. */
html{font-size:calc(100% * var(--a11y-fs,1))}
@media (min-width:768px){body.v5-site .nav-wrapper{gap:48px}
body.v5-site .main-nav a{white-space:nowrap}
body.v5-site .site-header .cta-button{white-space:nowrap}
}
/* The header button takes the page buttons' type and pill (a.v5-btn); its
   navy fill and white text (10.6:1) suit both header states, and it sweeps
   to white with navy text (10.6:1); its text stays white on hover (the
   base a:hover is slate). Padding in em, so the enlarged-text cap
   below shrinks the whole box. */
body.v5-site .site-header .cta-button{display:inline-flex;align-items:center;justify-content:center;min-height:52px;padding:calc(17em / 18) 2em;border-radius:999px;font:700 1.125rem/1 var(--lato);letter-spacing:normal;text-transform:none;color:#FFFFFF;--sw-bg:#FFFFFF;--sw-fg:#304054}
/* From 768px (Justin, 2026-10-14) the header button and the phone link are
   20% smaller: .9rem type (14.4px), 41.6px tall, padding in em so the box
   follows; each keeps a 44px tap area (::after, below). */
@media (min-width:768px){body.v5-site .site-header .cta-button{min-height:41.6px;font-size:.9rem}}
body.v5-hdr-solid .site-header .cta-button{background-color:#FFFFFF;color:#1E1F21;--sw-bg:#1E1F21;--sw-fg:#FFFFFF}
body.v5-hdr-solid .site-header .cta-button:focus-visible{background-color:#1E1F21}
@media (hover:hover) and (pointer:fine){body.v5-hdr-solid .site-header .cta-button:hover{background-color:#1E1F21}}
/* The phone menu's button: its widest word ('Appointment', 6.06em in
   Readable Font, 9.67em in Dyslexia Font) and its 2em sides fit the panel
   (80vw, at most 350px, less 2rem each side). */
@media (max-width:767px){.a11y-fs-up body.v5-site .site-header .cta-button{font-size:min(1.125rem,(min(80vw,350px) - 4rem) / 10.3)}
.a11y-dyslexic body.v5-site .site-header .cta-button{font-size:min(1.125rem,(min(80vw,350px) - 4rem) / 14.1)}}
@media (min-width:768px) and (max-width:1024px){body.v5-site .nav-wrapper{gap:24px}
}
/* PHONE (header-v5.php; Justin, 2026-10-14): the header's second call to
   action and the quieter one, an outline pill in the header's white (a 2px
   currentColor border, so the toolbar's colour modes recolour it). From
   768px it sits just left of the Book button, with its type and height
   (14.4px, 41.6px); on phones it is 1rem type, 44px tall, at the right
   edge opposite the logo. Its auto left margin takes the free space, so it and the Book
   button sit together on the right. */
body.v5-site .v5-hdr-call{display:inline-flex;flex-shrink:0;align-items:center;justify-content:center;gap:.5em;min-height:41.6px;margin-left:auto;padding:calc(17em / 18 - 2px) 1.25em;border:2px solid currentColor;border-radius:999px;color:#FFFFFF;font:700 .9rem/1 var(--lato);letter-spacing:normal;white-space:nowrap;transition:background-color .3s ease,color .3s ease}
body.v5-site .v5-hdr-call + .nav-wrapper{margin-left:0}
body.v5-site .v5-hdr-call svg{flex:none;width:1em;height:1em;fill:currentColor}
body.v5-site .v5-hdr-call__word{display:none}
/* Over the photograph (transparent header) the pill takes a half-navy fill,
   so its white text holds 4.5:1 on any photo: 4.86:1 over a white pixel
   under the hero's scrim (measured without it: 2.47:1 at 1000x800). */
:where(html:not(.a11y-light) body.v5-site:not(.v5-hdr-solid) .site-header:not(.is-solid)) .v5-hdr-call{background-color:rgba(48,64,84,.5)}
@media (hover:hover) and (pointer:fine){body.v5-site .v5-hdr-call:hover{background-color:#FFFFFF;color:#304054}}
@media (prefers-reduced-motion:reduce){body.v5-site .v5-hdr-call{transition:none}}
@media (max-width:767px){body.v5-site .v5-hdr-call{min-height:44px;padding:0 .75em;font-size:1rem}
.a11y-fs-up body.v5-site .v5-hdr-call{font-size:min(1rem,24px)}
.a11y-fs-up body.v5-site .v5-hdr-call__num{display:none}
.a11y-fs-up body.v5-site .v5-hdr-call__word{display:inline}}
/* "Call" instead of the number (its accessible name keeps the number)
   where the number does not fit beside the whole logo: phones below
   340px, 347px with the Readable Font, 387px with the Dyslexia Font; with
   enlarged text at every width below 1000px; with the Dyslexia Font from
   768 to 999px, and at every width once the text is enlarged too. */
@media (max-width:339px){body.v5-site .v5-hdr-call__num{display:none}body.v5-site .v5-hdr-call__word{display:inline}}
@media (max-width:346px){.a11y-readable body.v5-site .v5-hdr-call__num{display:none}.a11y-readable body.v5-site .v5-hdr-call__word{display:inline}}
@media (max-width:386px){.a11y-dyslexic body.v5-site .v5-hdr-call__num{display:none}.a11y-dyslexic body.v5-site .v5-hdr-call__word{display:inline}}
@media (max-width:999px){.a11y-fs-up body.v5-site .v5-hdr-call__num{display:none}.a11y-fs-up body.v5-site .v5-hdr-call__word{display:inline}}
@media (min-width:768px) and (max-width:999px){.a11y-dyslexic body.v5-site .v5-hdr-call__num{display:none}.a11y-dyslexic body.v5-site .v5-hdr-call__word{display:inline}}
.a11y-fs-up.a11y-dyslexic body.v5-site .v5-hdr-call__num{display:none}
.a11y-fs-up.a11y-dyslexic body.v5-site .v5-hdr-call__word{display:inline}
/* Phones below 360px with the Dyslexia Font and enlarged text: the icon
   alone, a 44px circle, so the logo keeps at least its size at 100% text. */
@media (max-width:359px){.a11y-fs-up.a11y-dyslexic body.v5-site .v5-hdr-call{width:44px;padding:0}
.a11y-fs-up.a11y-dyslexic body.v5-site .v5-hdr-call :is(.v5-hdr-call__num,.v5-hdr-call__word){display:none}}
/* Menu on (body.v5-has-menu, inc/pages.php): the phone header holds the
   menu button too, so the number gives way earlier, at the widths measured
   on v5a's header, which has the button: "Call" below 402px (Readable Font
   409, Dyslexia Font 449); the icon alone below 450px with enlarged text and
   below 340px with the Dyslexia Font. */
@media (max-width:401px){body.v5-has-menu .v5-hdr-call__num{display:none}body.v5-has-menu .v5-hdr-call__word{display:inline}}
@media (max-width:408px){.a11y-readable body.v5-has-menu .v5-hdr-call__num{display:none}.a11y-readable body.v5-has-menu .v5-hdr-call__word{display:inline}}
@media (max-width:448px){.a11y-dyslexic body.v5-has-menu .v5-hdr-call__num{display:none}.a11y-dyslexic body.v5-has-menu .v5-hdr-call__word{display:inline}}
@media (max-width:449px){.a11y-fs-up body.v5-has-menu .v5-hdr-call{width:44px;padding:0}
.a11y-fs-up body.v5-has-menu .v5-hdr-call :is(.v5-hdr-call__num,.v5-hdr-call__word){display:none}}
@media (max-width:339px){.a11y-dyslexic body.v5-has-menu .v5-hdr-call{width:44px;padding:0}
.a11y-dyslexic body.v5-has-menu .v5-hdr-call :is(.v5-hdr-call__num,.v5-hdr-call__word){display:none}}
/* HOME (header-v5.php; Justin, 2026-10-15): on child pages (body
   .v5-has-home) a text link in the header's white, in capitals, before the
   phone link; its auto left margin takes the free space, so it, the phone
   link and the Book button sit together on the right. Its type is the
   phone link's (.9rem from 768px, 1rem on phones), and it is 44px tall at
   every width (the header is at least 57.6px), so it needs no ::after tap
   area. */
body.v5-site .v5-hdr-home{display:inline-flex;flex-shrink:0;align-items:center;min-height:44px;margin-left:auto;color:#FFFFFF;font:700 .9rem/1 var(--lato);letter-spacing:.1em;text-transform:uppercase;text-decoration:none;white-space:nowrap}
body.v5-site .v5-hdr-home + .v5-hdr-call{margin-left:0}
@media (hover:hover) and (pointer:fine){body.v5-site .v5-hdr-home:hover{color:#FFFFFF;text-decoration:underline;text-decoration-thickness:2px;text-underline-offset:.3em}}
@media (max-width:767px){body.v5-site .v5-hdr-home{font-size:1rem}
.a11y-fs-up body.v5-site .v5-hdr-home{font-size:min(1rem,24px)}}
/* Phones with the Home link: the phone link gives way earlier, so the logo
   keeps its full size (measured, 2026-10-15). At 100% text the number
   shows from 415px (Readable Font 421, Dyslexia Font 487), "Call" from
   330px (331, 374), the icon alone below. With enlarged text the gaps stay
   16px (to 999px), "Call" shows from 400px (Readable 401, Dyslexia 464)
   and the icon alone below, and the Home link's type (24px at most) is
   capped to the room left beside the logo at its 100% size (3.91357 x
   --sp-3 at 100% text), the gaps, the 44px icon and 2px; the divisor is
   its width in em: 3.47 (Lato), 3.34 (Readable), 4.72 (Dyslexia). */
@media (max-width:999px){.a11y-fs-up body.v5-site.v5-has-home .header-container{column-gap:16px}}
@media (max-width:767px){.a11y-fs-up body.v5-site.v5-has-home .v5-hdr-home{font-size:min(1rem,24px,(100vw - 2 * var(--hdr-gut) - 3.91357 * clamp(33.28px,27.632px + 1.57vw,54px) - 78px) / 3.47)}
.a11y-fs-up.a11y-readable body.v5-site.v5-has-home .v5-hdr-home{font-size:min(1rem,24px,(100vw - 2 * var(--hdr-gut) - 3.91357 * clamp(33.28px,27.632px + 1.57vw,54px) - 78px) / 3.34)}
.a11y-fs-up.a11y-dyslexic body.v5-site.v5-has-home .v5-hdr-home{font-size:min(1rem,24px,(100vw - 2 * var(--hdr-gut) - 3.91357 * clamp(33.28px,27.632px + 1.57vw,54px) - 78px) / 4.72)}}
@media (max-width:414px){body.v5-site.v5-has-home .v5-hdr-call__num{display:none}body.v5-site.v5-has-home .v5-hdr-call__word{display:inline}}
@media (max-width:420px){.a11y-readable body.v5-site.v5-has-home .v5-hdr-call__num{display:none}.a11y-readable body.v5-site.v5-has-home .v5-hdr-call__word{display:inline}}
@media (max-width:486px){.a11y-dyslexic body.v5-site.v5-has-home .v5-hdr-call__num{display:none}.a11y-dyslexic body.v5-site.v5-has-home .v5-hdr-call__word{display:inline}}
@media (max-width:329px){body.v5-site.v5-has-home .v5-hdr-call{width:44px;padding:0}body.v5-site.v5-has-home .v5-hdr-call :is(.v5-hdr-call__num,.v5-hdr-call__word){display:none}}
@media (max-width:330px){.a11y-readable body.v5-site.v5-has-home .v5-hdr-call{width:44px;padding:0}.a11y-readable body.v5-site.v5-has-home .v5-hdr-call :is(.v5-hdr-call__num,.v5-hdr-call__word){display:none}}
@media (max-width:373px){.a11y-dyslexic body.v5-site.v5-has-home .v5-hdr-call{width:44px;padding:0}.a11y-dyslexic body.v5-site.v5-has-home .v5-hdr-call :is(.v5-hdr-call__num,.v5-hdr-call__word){display:none}}
@media (max-width:399px){.a11y-fs-up body.v5-site.v5-has-home .v5-hdr-call{width:44px;padding:0}.a11y-fs-up body.v5-site.v5-has-home .v5-hdr-call :is(.v5-hdr-call__num,.v5-hdr-call__word){display:none}}
@media (max-width:400px){.a11y-fs-up.a11y-readable body.v5-site.v5-has-home .v5-hdr-call{width:44px;padding:0}.a11y-fs-up.a11y-readable body.v5-site.v5-has-home .v5-hdr-call :is(.v5-hdr-call__num,.v5-hdr-call__word){display:none}}
@media (max-width:463px){.a11y-fs-up.a11y-dyslexic body.v5-site.v5-has-home .v5-hdr-call{width:44px;padding:0}.a11y-fs-up.a11y-dyslexic body.v5-site.v5-has-home .v5-hdr-call :is(.v5-hdr-call__num,.v5-hdr-call__word){display:none}}
/* Enlarged text, from 768px: the Book button and the phone link share one
   size, capped to the room beside the logo (below 1000px at least its
   width at 100% text, 155.2px; from 1000px it is fixed at 183px),
   the gutters (3.5vw each) and the two gaps, so the header keeps one
   line; their padding is in em, so the boxes shrink with the type. The
   divisor is the two boxes' width in em,
   measured: the Book button 13.75 (Lato), 14.43 (Readable Font), 20.56
   (Dyslexia Font); the link with the number 10.85 / 11.25, with "Call"
   5.88 / 5.88 / 7.13. Each box is its font size x 2.889 (1em + 2 x 17/18em
   padding); from 1000px the header is 71.8px tall (--hdr-h), so the type is
   also capped to the header height less 16px (8px above and below). */
@media (min-width:768px){.a11y-fs-up body.v5-site :is(.site-header .cta-button,.v5-hdr-call){font-size:min(.9rem,(93vw - 155.2px - 2 * var(--sp-1) - 4px) / 20.4)}
.a11y-fs-up.a11y-dyslexic body.v5-site :is(.site-header .cta-button,.v5-hdr-call){font-size:min(.9rem,(93vw - 155.2px - 2 * var(--sp-1) - 4px) / 28.2)}}
@media (min-width:1000px){.a11y-fs-up body.v5-site :is(.site-header .cta-button,.v5-hdr-call){font-size:min(.9rem,(93vw - 183px - 2 * var(--sp-1) - 4px) / 25.8,(var(--hdr-h) - 16px) / 2.889)}
.a11y-fs-up.a11y-dyslexic body.v5-site :is(.site-header .cta-button,.v5-hdr-call){font-size:min(.9rem,(93vw - 183px - 2 * var(--sp-1) - 4px) / 28.2,(var(--hdr-h) - 16px) / 2.889)}}
/* The same with the Home link (child pages): it shares the size, so its
   width in em joins the divisor (3.47, Dyslexia Font 4.72) and its gap the
   room. Below 1000px the gaps stay 16px (above), so the three keep at
   least their 100% size (14.4px) at 200% text in the Dyslexia Font. */
@media (min-width:768px){.a11y-fs-up body.v5-site.v5-has-home :is(.site-header .cta-button,.v5-hdr-call,.v5-hdr-home){font-size:min(.9rem,(93vw - 155.2px - 48px - 4px) / 23.9)}
.a11y-fs-up.a11y-dyslexic body.v5-site.v5-has-home :is(.site-header .cta-button,.v5-hdr-call,.v5-hdr-home){font-size:min(.9rem,(93vw - 155.2px - 48px - 4px) / 33)}}
@media (min-width:1000px){.a11y-fs-up body.v5-site.v5-has-home :is(.site-header .cta-button,.v5-hdr-call,.v5-hdr-home){font-size:min(.9rem,(93vw - 183px - 3 * var(--sp-1) - 4px) / 29.3,(var(--hdr-h) - 16px) / 2.889)}
.a11y-fs-up.a11y-dyslexic body.v5-site.v5-has-home :is(.site-header .cta-button,.v5-hdr-call,.v5-hdr-home){font-size:min(.9rem,(93vw - 183px - 3 * var(--sp-1) - 4px) / 33,(var(--hdr-h) - 16px) / 2.889)}}
/* Tap areas, 768px and up: each 41.6px pill reaches 44px through a
   transparent ::after centred on it, 1.2px past its top and bottom, inside
   the header's 8px margins. The Book button's sweep keeps its rounded clip
   on its own span, so the button no longer clips (its ::after would be
   cut off). */
@media (min-width:768px){body.v5-site .v5-hdr-call{position:relative}
body.v5-site :is(.site-header .cta-button,.v5-hdr-call)::after{content:"";position:absolute;left:0;right:0;top:50%;height:max(100%,44px);transform:translateY(-50%)}
body.v5-site .site-header .cta-button{overflow:visible}
body.v5-site .site-header .cta-button .v5-sweep{border-radius:inherit;overflow:clip}}
/* Toggle (Justin, 2026-10-13): back to a fixed tab on the right edge just
   below the header, where it was before P0b (header-v5.php prints it
   after the header), 20% smaller than the 44px header button: 35.2px, its
   icon 19.2px (WCAG 2.5.8 asks for 24). The panel opens from the right
   edge and the tab travels with it. Over readable text (v5-site.js sets
   .is-over-text) it fades to --a11y-tab-faded, so the text shows through;
   it is opaque on hover, focus and press and while the panel is open. */
:root{--a11y-top:calc(var(--hdr-h) + var(--sp-2));--a11y-w:min(15rem,100vw - 48px);--a11y-tab-faded:.1}
/* Hidden until the script that services it is ready. */
.a11y-tab{visibility:hidden}
html.a11y-ready .a11y-tab{visibility:visible}
.a11y-tab,.a11y-panel{position:fixed;top:var(--a11y-top);right:env(safe-area-inset-right,0px)}
button.a11y-tab{z-index:1004;display:flex;align-items:center;justify-content:center;width:35.2px;height:35.2px;padding:0;border:2px solid #FFFFFF;border-right:0;border-radius:var(--radius-small) 0 0 var(--radius-small);background:var(--navy);color:#FFFFFF;box-shadow:0 4px 20px rgba(0,0,0,.15);transition:transform .4s cubic-bezier(.33,1,.68,1),opacity .25s ease}
button.a11y-tab:hover{background:var(--navy)}
@media (hover:hover){button.a11y-tab:hover{background:var(--slate)}}
html.a11y-open button.a11y-tab{transform:translateX(calc(-1 * var(--a11y-w)))}
button.a11y-tab.is-over-text{opacity:var(--a11y-tab-faded)}
button.a11y-tab.is-over-text:is(:hover,:focus,:active),html.a11y-open button.a11y-tab.is-over-text{opacity:1}
/* Over the hero photo (transparent header): a navy backing keeps the menu glyph at 4.5:1+ on any photo (5.1:1 over white). */
:where(html:not(.a11y-light) body.v5-site:not(.v5-hdr-solid) .site-header:not(.is-solid)) button.mobile-menu-toggle:is(*,:hover){background-color:rgba(48,64,84,.75);border-radius:var(--radius-small)}
.a11y-tab svg{display:block;width:19.2px;height:19.2px;fill:currentColor}
.a11y-panel{z-index:1003;width:var(--a11y-w);max-height:calc(100dvh - var(--a11y-top) - var(--sp-1));overflow-y:auto;background:#FFFFFF;color:#1E1F21;border:1px solid var(--navy);border-right:0;border-radius:0 0 0 var(--radius-small);box-shadow:0 4px 20px rgba(0,0,0,.15);font-family:var(--montserrat);text-align:left;transform:translateX(100%);visibility:hidden;transition:transform .4s cubic-bezier(.33,1,.68,1),visibility 0s linear .4s}
html.a11y-open .a11y-panel{transform:none;visibility:visible;transition:transform .4s cubic-bezier(.33,1,.68,1)}
@media (prefers-reduced-motion:reduce){button.a11y-tab,.a11y-panel,html.a11y-open .a11y-panel{transition:none}
}
.a11y-panel__title{margin:0;padding:var(--sp-1) var(--sp-1) var(--sp-0-5);font:700 var(--fs-s)/1.4 var(--lato);letter-spacing:2px;text-transform:uppercase}
.a11y-panel__list{list-style:none;margin:0;padding:0 var(--sp-0-75) var(--sp-1)}
button.a11y-btn{position:relative;display:flex;align-items:center;gap:var(--sp-0-75);width:100%;min-height:48px;padding:var(--sp-0-5) var(--sp-0-75);border:0;border-radius:var(--radius-tiny);background:#FFFFFF;color:#1E1F21;font:400 var(--fs-s)/1.3 var(--montserrat);letter-spacing:0;text-transform:none;text-align:left;transition:none}
button.a11y-btn:hover{background:#FFFFFF}
@media (hover:hover){button.a11y-btn:hover{background:#F3F4F2}
}
/* Pressed: navy fill (the brand's active state), white text 10.6:1; no
   fade (style.css fades button backgrounds), so text never sits on a mid-fade fill. */
button.a11y-btn[aria-pressed="true"]{background:var(--navy);color:#FFFFFF}
button.a11y-btn:focus-visible{z-index:1}
.a11y-btn svg{flex:none;width:1.25em;height:1.25em;fill:var(--slate)}
.a11y-btn[aria-pressed="true"] svg{fill:#FFFFFF}
.a11y-btn[aria-disabled="true"]{cursor:default;opacity:.5}
.a11y-sprite{position:absolute;width:0;height:0;overflow:hidden}
/* Rev 3 (LCP): Lato 400 was fetched at load for two things nobody sees on the
   first screen. The tab's hidden label takes Lato 700 (already loaded). */
.a11y-tab .sr-only{font-family:var(--lato);font-weight:700}
/* The phone menu button's glyph (header.php) made Chrome fetch Lato 400 at load
   although Lato has no U+2630. On v5 it names the Lato 700 file, already
   loaded, under a weight-400 alias: same family metrics, the glyph still comes
   from the system fallback at 400, one request fewer. */
@font-face{font-family:'OHS v5 Lato Menu';src:url('../fonts/lato-latin-700.woff2') format('woff2');font-weight:400;font-style:normal;font-display:swap}
body.v5-site .mobile-menu-toggle{font-family:'OHS v5 Lato Menu',var(--lato);min-width:44px}
html.a11y-grayscale .site-header > *,html.a11y-grayscale main > :not(.hero-parallax),html.a11y-grayscale .hero-parallax > :not(.a11y-ui),html.a11y-grayscale .ohs-ftr{filter:grayscale(1)}
/* High Contrast, OHS palette on charcoal #1E1F21: text white 16.5:1,
   headings slate tint #B5C0CF 9.0:1, links #DADFE7 12.3:1 and underlined,
   buttons navy with white text 10.6:1, borders and focus white. */
html.a11y-contrast body,html.a11y-contrast body *:not(.a11y-ui,.a11y-ui *){background:#1E1F21 !important;background-image:none !important;color:#FFFFFF !important;text-shadow:none !important;box-shadow:none !important;}
html.a11y-contrast body :is(h1,h2,h3,h4,h5,h6):not(.a11y-ui *),html.a11y-contrast body :is(h1,h2,h3,h4,h5,h6) *:not(.a11y-ui *){color:#B5C0CF !important}
html.a11y-contrast body a:not(.a11y-ui *){color:#DADFE7 !important;text-decoration:underline !important}
html.a11y-contrast body button:not(.a11y-ui,.a11y-ui *){background:#304054 !important}
html.a11y-contrast body :is(button,input,textarea,select,table,td,th,tr):not(.a11y-ui,.a11y-ui *){border:1px solid #FFFFFF !important}
html.a11y-negative body,html.a11y-negative body *:not(.a11y-ui,.a11y-ui *){background:#000 !important;background-image:none !important;color:#FFFFFF !important;}
html.a11y-negative body :is(a,b,strong,em,i,u,span,cite,dfn,blockquote):not(.a11y-ui *){color:#FFFF00 !important}
html.a11y-negative body :is(button,input,textarea,select,table,td,th,tr):not(.a11y-ui,.a11y-ui *){border:1px solid #FFFFFF !important}
html.a11y-light body,html.a11y-light body *:not(.a11y-ui,.a11y-ui *){background:#FFFFFF !important;background-image:none !important;color:#1E1F21 !important;text-shadow:none !important;}
html.a11y-light body :is(.site-logo-full,.hero-logo){background:transparent !important;filter:brightness(0) invert(.118)}
html.a11y-light body .scroll-arrow svg{stroke:#1E1F21}
html.a11y-contrast body .ohs-ftr .ohs-ftr__logo,html.a11y-negative body .ohs-ftr .ohs-ftr__logo,html.a11y-light body .ohs-ftr .ohs-ftr__logo{background-image:var(--ftr-logo) !important}
html.a11y-light body .ohs-ftr .ohs-ftr__logo{background-color:transparent !important;filter:brightness(0) invert(.118)}
html.a11y-contrast body :is(.cta-button,.hero-cta,.v5-bar__book):not(:focus-visible),html.a11y-negative body :is(.cta-button,.hero-cta,.v5-bar__book):not(:focus-visible){box-shadow:inset 0 0 0 2px #FFFFFF !important}
html.a11y-light body :is(.cta-button,.hero-cta,.v5-bar__book):not(:focus-visible){box-shadow:inset 0 0 0 2px #1E1F21 !important}
html.a11y-contrast body :is(a,button):focus-visible,html.a11y-negative body :is(a,button):focus-visible,html.a11y-light body :is(a,button):focus-visible{box-shadow:0 0 0 9px #1E1F21 !important}
html.a11y-contrast body :is(.cta-button,.hero-cta,.v5-bar__book):focus-visible,html.a11y-negative body :is(.cta-button,.hero-cta,.v5-bar__book):focus-visible{box-shadow:inset 0 0 0 2px #FFFFFF,0 0 0 9px #1E1F21 !important}
html.a11y-light body :is(.cta-button,.hero-cta,.v5-bar__book):focus-visible{box-shadow:inset 0 0 0 2px #1E1F21,0 0 0 9px #1E1F21 !important}
html.a11y-underline body a:not(.a11y-ui *),html.a11y-underline body a:not(.a11y-ui *) *{text-decoration:underline !important}
/* Readable Font: Atkinson Hyperlegible Next (Braille Institute), SIL OFL 1.1,
   ../fonts/atkinson-hyperlegible-next/OFL.txt. Upstream woff2, unmodified;
   fetched only while the option is on (no preload). Icons, SVG and the
   placeholder markers keep theirs. */
@font-face{font-family:'Atkinson Hyperlegible Next';src:url('../fonts/atkinson-hyperlegible-next/AtkinsonHyperlegibleNext-Regular.woff2') format('woff2');font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:'Atkinson Hyperlegible Next';src:url('../fonts/atkinson-hyperlegible-next/AtkinsonHyperlegibleNext-Bold.woff2') format('woff2');font-weight:700;font-style:normal;font-display:swap}
html.a11y-readable body,html.a11y-readable body *:not(svg,svg *,.mobile-menu-toggle,.v5-ph){font-family:'Atkinson Hyperlegible Next',sans-serif !important}
/* Dyslexia Font: OpenDyslexic by Abbie Gonzalez, SIL OFL 1.1 with Reserved
   Font Name OpenDyslexic, ../fonts/opendyslexic/OFL.txt. The author's woff2,
   unmodified; fetched only while the option is on (no preload). */
@font-face{font-family:'OpenDyslexic';src:url('../fonts/opendyslexic/OpenDyslexic-Regular.woff2') format('woff2');font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:'OpenDyslexic';src:url('../fonts/opendyslexic/OpenDyslexic-Bold.woff2') format('woff2');font-weight:700;font-style:normal;font-display:swap}
html.a11y-dyslexic body,html.a11y-dyslexic body *:not(svg,svg *,.mobile-menu-toggle,.v5-ph){font-family:'OpenDyslexic',sans-serif !important}
/* Neither toolbar font has italic files: italic text sets upright, and
   emphasis and the italic accents carry weight instead (700), so the
   browser never synthesises an oblique. */
html:is(.a11y-readable,.a11y-dyslexic) body *{font-style:normal !important}
html:is(.a11y-readable,.a11y-dyslexic) body :is(em,i,cite,dfn,address,var,.ohs-ftr__mission-text,.v5-hero__word,.v5-hero__lead,.v5-price-strip__price,.v5-steps__num,.v5-sign__name,.v5-four h3){font-weight:700 !important}
/* Emphasis inside bold text: 400 */
html:is(.a11y-readable,.a11y-dyslexic) .v5 :is(h1,h2,h3,.v5-statement__text,strong,b) :is(em,i){font-weight:400 !important}
html{
  scrollbar-width:thin;
  scrollbar-color:var(--navy) var(--off-white);
}
html::-webkit-scrollbar{width:8px}
html::-webkit-scrollbar-track{background:rgb(210,214,219)}
html::-webkit-scrollbar-thumb{background:var(--navy);border-radius:0}
html::-webkit-scrollbar-button{display:none;height:0;width:0}
/* FOOTER (footer-v5.php): page tokens and brand faces, docs/rewrite/FOOTER-INVENTORY.md 6. Every face is already loaded at load; only the logo waits (.is-near). */
/* Mission line: Montserrat Bold Italic 9.000 (github.com/JulietaUla/Montserrat webfonts, latin subset; OFL: ../fonts/montserrat-OFL.txt), fetched only with .is-near. Until then the loaded 400 italic stands in at 105.48% (measured on the earlier one-line statement; the two-sentence statement can break differently in the stand-in, which is replaced while the footer is still two screens away). */
@font-face{font-family:'OHS v5 Mission';src:url('../fonts/montserrat-latin-700italic.woff2') format('woff2');font-style:italic;font-weight:700;font-display:swap;unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:'OHS v5 Mission Stand-in';src:url('../fonts/montserrat-latin-400italic.woff2') format('woff2');font-style:italic;font-weight:700;font-display:swap;size-adjust:105.48%;unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
.ohs-ftr{--ftr-logo:url('../img/ohs-logo-mark-white.svg');--ftr-mission:'OHS v5 Mission';background-color:#304054;color:#FFFFFF;font:400 var(--fs-s)/1.5 var(--montserrat)}
:where(.ohs-ftr) p{margin:0}
.ohs-ftr a,.ohs-ftr a:hover{color:#FFFFFF}
.ohs-ftr a:focus-visible{outline:2px solid #FFFFFF;outline-offset:3px}
.ohs-ftr__green{padding-block:var(--sp-7) var(--sp-2)}
.ohs-ftr__inner{max-width:var(--shell-max);margin-inline:auto;padding-inline:var(--pad-page)}
.ohs-ftr__top{display:grid;grid-template-columns:auto minmax(0,1fr);align-items:center;gap:var(--sp-1-5) var(--grid-col-gap)}
.ohs-ftr__logo{width:var(--sp-7);height:var(--sp-7);background:var(--ftr-logo) center / contain no-repeat}
.ohs-ftr__mission-text{font:italic 700 var(--fs-xl)/1.3 var(--ftr-mission),'OHS v5 Mission Stand-in',sans-serif;font-synthesis:none}
.ohs-ftr__divider{height:1px;margin-block:var(--sp-2);background-color:rgba(243,244,242,.3);transform-origin:right center}
.ohs-ftr__cols{display:grid;grid-template-columns:repeat(4,minmax(min-content,1fr));gap:var(--sp-2) var(--grid-col-gap)}
.ohs-ftr__col a[href^="tel:"]{font-family:var(--lato);font-weight:700;font-size:var(--fs-m)}
/* Contact and footer-nav links: 24px boxes, so stacked or wrapped links pass WCAG 2.5.8 at every width. */
:is(.ohs-ftr__col p,.ohs-ftr__legal nav,.ohs-ftr__legal > p:last-child) a{display:inline-block;padding-block:calc((24px - 1lh) / 2)}
/* The phone keeps its face and size but takes the column's line height (1lh in
   line-height is the parent's), so the phone and the email sit on the same
   24px lines as the hours and the address, each in a 24px box (Justin,
   2026-10-18); top-aligned, or its larger face's baseline adds 1px to the
   line. Was a 48px box (SEO-AUDIT 9.3) and 12px more above the email, a 48px
   step between them and the phone 11px below the other columns' first
   lines. */
.ohs-ftr__col p a[href^="tel:"]{line-height:1lh;vertical-align:top}
.a11y-fs-up .ohs-ftr__col a{overflow-wrap:anywhere}
.ohs-ftr__eyebrow{margin-bottom:var(--sp-0-75);font:700 var(--fs-s)/1.5 var(--lato);letter-spacing:2px;text-transform:uppercase;color:#FFFFFF}
.ohs-ftr__col--social{display:flex;flex-wrap:wrap;gap:var(--sp-0-75);align-items:flex-start}
.ohs-ftr__social{display:flex;align-items:center;justify-content:center;width:48px;height:48px;border:1px solid rgba(243,244,242,.3);border-radius:50%;line-height:0}
.ohs-ftr .ohs-ftr__social,.ohs-ftr .ohs-ftr__social:hover{color:#F3F4F2;text-decoration:none}
.ohs-ftr__social svg{width:20px;height:20px}
/* The copyright line sits centred between the column text and the footer's
   bottom edge (the 2px is the column text's line spacing below its ink). */
.ohs-ftr__legal{padding-top:calc(var(--sp-2) - 2px);text-align:center}
.ohs-ftr__legal > * + *{margin-top:var(--sp-0-5)}
.ohs-ftr .ohs-ftr__legal a{color:#BFBFBF;text-decoration:underline}
@media (hover:hover){.ohs-ftr .ohs-ftr__legal a:hover{color:#FFFFFF}}
.ohs-ftr__links{display:flex;flex-wrap:wrap;justify-content:center;gap:0 var(--sp-1-5);margin:0;padding:0;list-style:none}
.ohs-ftr__sep{display:inline-block;vertical-align:baseline}
html.js .ohs-ftr{--ftr-logo:none;--ftr-mission:'OHS v5 Mission Stand-in';animation:ohsFtrNearFailsafe 0s linear 3s forwards}
html.js .ohs-ftr.is-near-js{animation:none}
html.js .ohs-ftr.is-near{--ftr-logo:url('../img/ohs-logo-mark-white.svg');--ftr-mission:'OHS v5 Mission'}
@keyframes ohsFtrNearFailsafe{to{--ftr-logo:url('../img/ohs-logo-mark-white.svg');--ftr-mission:'OHS v5 Mission'}}
@media (max-width:991px){
  .ohs-ftr__cols{grid-template-columns:repeat(2,minmax(min-content,1fr))}
  .ohs-ftr__legal{text-align:left}
  .ohs-ftr__links{justify-content:flex-start}
}
@media (max-width:767px){.ohs-ftr__top,.ohs-ftr__cols{grid-template-columns:minmax(0,1fr)}}
/* Footer entrance (992+, script-armed, curtain pattern): the logo and the statement fade in together while moving in from the left (one --sp-2), 2s, every line at once, the divider draws, the columns and legal lines fade in (Justin's approved exception to the no-fade rule, R2, B2). --ftr-lag (v5-site.js) staggers groups that start together. */
@media (min-width:992px) and (prefers-reduced-motion:no-preference){
  .ohs-ftr .ohs-ftr__reveal.is-armed{opacity:0;transform:translateX(calc(-1 * var(--sp-2)))}
  .ohs-ftr .ohs-ftr__reveal.is-armed.is-visible{animation:ohsFtrIn 2s cubic-bezier(.33,1,.68,1) forwards}
  /* Columns (R2): headings slide in from the left over 2/3 of the contents'
     travel D (--sp-2); hours rise from lower left, location from below,
     contact from lower right; all 1.2s together. The legal lines unblur
     over 1.5s, starting .7s after the columns (Justin, 2026-10-18; was
     1.2s, as the columns end). Start states exist only while the
     script's .is-armed is on, and the keyframes are to-only, so without it
     all simply shows.
     The footer clips the contact column's start (D right) at the viewport. */
  .ohs-ftr__cols{--ftr-d:var(--sp-2)}
  .ohs-ftr{overflow-x:clip}
  .ohs-ftr__cols.is-armed:not(.is-instant) :is(.ohs-ftr__col--hours,.ohs-ftr__col--location,.ohs-ftr__col--contact) > *{opacity:0}
  .ohs-ftr__cols.is-armed:not(.is-instant) .ohs-ftr__eyebrow{transform:translateX(calc(var(--ftr-d) * -2 / 3))}
  .ohs-ftr__cols.is-armed:not(.is-instant) .ohs-ftr__col--hours > :not(.ohs-ftr__eyebrow){transform:translate(calc(var(--ftr-d) * -.7071),calc(var(--ftr-d) * .7071))}
  .ohs-ftr__cols.is-armed:not(.is-instant) .ohs-ftr__col--location > :not(.ohs-ftr__eyebrow){transform:translateY(var(--ftr-d))}
  .ohs-ftr__cols.is-armed:not(.is-instant) .ohs-ftr__col--contact > :not(.ohs-ftr__eyebrow){transform:translate(calc(var(--ftr-d) * .7071),calc(var(--ftr-d) * .7071))}
  .ohs-ftr__cols.is-armed.is-visible:not(.is-instant) :is(.ohs-ftr__col--hours,.ohs-ftr__col--location,.ohs-ftr__col--contact) > *{animation:ohsFtrIn 1.2s cubic-bezier(.33,1,.68,1) var(--ftr-lag,0s) forwards}
  .ohs-ftr__legal.is-armed:not(.is-instant) > *{opacity:0;filter:blur(6px)}
  .ohs-ftr__legal.is-armed.is-visible:not(.is-instant) > *{animation:ohsFtrIn 1.5s cubic-bezier(.33,1,.68,1) calc(.7s + var(--ftr-lag,0s)) forwards}
  .ohs-ftr .ohs-ftr__divider.is-armed{transform:scaleX(0)}
  .ohs-ftr .ohs-ftr__divider.is-armed.is-visible{animation:ohsFtrDraw 1600ms cubic-bezier(.25,.65,.3,1) forwards}
  .ohs-ftr .ohs-ftr__reveal.is-armed.is-instant{opacity:1;transform:none;animation:none}
}
@keyframes ohsFtrDraw{to{transform:none}}
@keyframes ohsFtrIn{to{opacity:1;transform:none;filter:none}}

/* ===== v5 PAGE SYSTEM: tokens and components in OHS brand. Kept short:
   this file is render-blocking. ===== */
/* Type and space scales (docs/rewrite/INVENTORY.md); :root, for header and footer. */
:root{
  --fs-s:clamp(.833rem,.815rem + .081vw,.9rem);
  /* Body text: 17px at every width (Justin, 2026-10-14, after an outside
     type study; it was 17px at 375 rising to 18px from 1440). In rem, so the
     toolbar's text size still scales it. */
  --fs-m:1.0625rem;
  --fs-l:clamp(1.2rem,1.144rem + .25vw,1.406rem);
  --fs-xl:clamp(1.44rem,1.353rem + .385vw,1.758rem);
  --fs-2xl:clamp(1.728rem,1.6rem + .569vw,2.197rem);
  --fs-3xl:clamp(2.074rem,1.89rem + .816vw,2.747rem);
  --fs-5xl:clamp(2.986rem,2.63rem + 1.583vw,4.292rem);
  --fs-6xl:clamp(3.583rem,3.097rem + 2.159vw,5.364rem);
  --fs-7xl:clamp(4.3rem,3.644rem + 2.916vw,6.705rem);
  /* h2 size (Justin, 2026-10-14, after an outside type study of 69 clinic
     homepages found v5's h2s the largest): 30px at 390 wide, rising in a
     straight line to 40px at 1536, held at 40 above that and at 30 below.
     rem + vw, so the toolbar's text size and zoom still scale it. It
     replaces --fs-5xl and the laptop cut on the h2. --h2-cap is a page's
     fit cap for enlarged text (*-home.css), in the token so the h3 caps
     below follow it. */
  --fs-h2:min(clamp(1.875rem,1.6623rem + .8726vw,2.5rem),var(--h2-cap,100vw));
  /* h3 sizes (Justin, 2026-10-14): each scale size, but never more than
     .75 of the h2 at the same width, so no h3 is larger than an h2 and each
     sits a clear step below it. Set on the h3s under PAGE SYSTEM below. They
     replace the laptop cut (2026-10-13: 16% off from 1000 to 1356). */
  --fs-l-h3:min(var(--fs-l),.75 * var(--fs-h2));
  --fs-xl-h3:min(var(--fs-xl),.75 * var(--fs-h2));
  --fs-2xl-h3:min(var(--fs-2xl),.75 * var(--fs-h2));
  --fs-3xl-h3:min(var(--fs-3xl),.75 * var(--fs-h2));
  --sp-0-25:clamp(.25rem,.241rem + .038vw,.281rem);
  --sp-0-5:clamp(.5rem,.483rem + .076vw,.562rem);
  --sp-0-75:clamp(.75rem,.724rem + .114vw,.844rem);
  --sp-1:clamp(1rem,.966rem + .151vw,1.125rem);
  --sp-1-25:clamp(1.16rem,1.093rem + .298vw,1.406rem);
  --sp-1-5:clamp(1.31rem,1.208rem + .457vw,1.688rem);
  --sp-1-75:clamp(1.452rem,1.311rem + .626vw,1.969rem);
  --sp-2:clamp(1.587rem,1.407rem + .803vw,2.25rem);
  --sp-2-5:clamp(1.842rem,1.577rem + 1.176vw,2.812rem);
  --sp-3:clamp(2.08rem,1.727rem + 1.57vw,3.375rem);
  --sp-3-5:clamp(2.305rem,1.86rem + 1.978vw,3.938rem);
  --sp-4:clamp(2.52rem,1.98rem + 2.4vw,4.5rem);
  --sp-5:clamp(2.924rem,2.187rem + 3.274vw,5.625rem);
  --sp-6:clamp(3.302rem,2.361rem + 4.179vw,6.75rem);
  --sp-7:clamp(3.659rem,2.51rem + 5.11vw,7.875rem);
  --sp-9:clamp(4.327rem,2.745rem + 7.028vw,10.125rem);
  --sp-10:clamp(4.642rem,2.839rem + 8.01vw,11.25rem);
  --radius-tiny:4px;
  --radius-small:8px;
  --radius-card:var(--sp-2-5);
  --radius-large:var(--sp-5);
  /* The page gutter, at least the side safe-area insets (notched phones in
     landscape, with viewport-fit=cover; 0 everywhere else). */
  --pad-page:max(3.5vw,env(safe-area-inset-left,0px),env(safe-area-inset-right,0px));
  /* Header (Justin, 2026-10-13): its bottom edge where the logo's bottom
     was in the 129.07px header, (129.07 + 62.4) / 2 = 95.735px (below
     1000: one --sp-1-5 less, further down); from 768px 25% shorter
     (2026-10-14): 71.801px from 1000, and from 768 to 999 the larger of
     .75 x its old height and the buttons' 2.6rem plus 8px above and below
     (below 768 unchanged, *-site.css PAGE SYSTEM). The logo and the Book
     button sit --hdr-gut from the viewport's edges: 3.5vw, the left offset
     measured on the reference header from 768 to 1920, never under 16px. */
  --hdr-h:71.801px;
  --hdr-gut:max(16px,var(--pad-page));
  /* Heading allowance: em width of the widest 13-letter word plus comma
     (accommodation,), italic runs included, +4%. Longer words need &shy;. */
  --word:8.8;
  --shell-max:120rem;
  --sec-m:var(--sp-5);
  --sec-l:var(--sp-7);
  --grid-cols:12;
  --grid-col-gap:var(--sp-2);
  --grid-row-gap:var(--sp-4);
  /* Theme slots: light = off-white field, charcoal text, slate accent,
     navy button. */
  --sk-bg:#F3F4F2;
  /* The white theme's field (.v5-theme-white); child pages alternate the two
     (v5-page.css). */
  --sk-bg-white:#FFFFFF;
  --sk-text:#1E1F21;
  --sk-link:#304054;
  --sk-border:rgba(30,31,33,.3);
  --sk-accent:#456188;
  --sk-detail-1:#456188;
  --sk-detail-2:#557F8D;
  --sk-btn-bg:#304054;
  --sk-btn-text:#FFFFFF;
}
/* Running text at line-height 1.6 (Justin, 2026-10-14; it was 1.5). */
.v5{font-size:var(--fs-m);line-height:1.6}
html.a11y-readable{--word:8}
html.a11y-dyslexic{--word:12.2}
/* Focus lands below the returning header (WCAG 2.4.11). */
html{scroll-padding-top:calc(var(--hdr-h) + var(--sp-1))}
@media (max-width:991px){:root{--grid-cols:8}}
@media (max-width:767px){:root{--hdr-h:calc(var(--sp-3) + var(--sp-1-5))}}
@media (min-width:768px) and (max-width:999px){:root{--hdr-h:max(.75 * (var(--sp-3) + var(--sp-1-5)),2.6rem + 16px)}}
@media (max-width:767px){:root{--grid-cols:4;--grid-col-gap:var(--sp-1);--grid-row-gap:var(--sp-2)}}
.v5-theme-white{--sk-bg:var(--sk-bg-white)}
.v5-theme-navy{--sk-bg:#304054;--sk-text:#F3F4F2;--sk-link:#FFFFFF;--sk-border:rgba(243,244,242,.3);--sk-accent:#FFFFFF;--sk-btn-bg:#F3F4F2;--sk-btn-text:#304054}
.v5 > section:not(.hero-parallax){position:relative;background-color:var(--sk-bg);color:var(--sk-text);transition:background 200ms ease,color 200ms ease}
:where(.v5) :is(p,h2,h3,figure,ul,ol,dl,dd){margin:0}
.v5 :is(h1,h2,h3){color:inherit;letter-spacing:0;text-transform:none}
/* Headings fit an allowance word (--word) in their column. */
:is(.v5-intro__title,.v5-col-half,.v5-card,.v5-rich){container-type:inline-size}
.v5 h2{font-size:min(var(--fs-h2),100cqi / var(--word));line-height:1.2;text-wrap:balance;overflow-wrap:break-word}
/* Page title (the hero's h1 keeps its own). */
.v5 h1:not(.v5-hero__h1){margin:0;font-size:min(var(--fs-5xl),100cqi / var(--word));line-height:1.2;text-wrap:balance;overflow-wrap:break-word;text-shadow:none}
.v5 h3{font-size:var(--fs-xl);line-height:1.3;text-wrap:balance}
/* The h3 headings take the -h3 sizes (capped at .75 of the h2, :root
   above), so every size rule for them, the toolbar caps included, still
   names --fs-*. The statement has its own size (*-home.css). */
.v5 h3{--fs-l:var(--fs-l-h3);--fs-xl:var(--fs-xl-h3);--fs-2xl:var(--fs-2xl-h3);--fs-3xl:var(--fs-3xl-h3)}
/* <em> in display text switches face: Montserrat italic in the accent
   colour, sized so its x-height matches Lato 700 (measured .516 / .532). */
.v5 :is(h1,h2,h3,.v5-statement__text) em{font:italic 400 .97em/1 var(--montserrat);letter-spacing:0;text-transform:none;color:var(--sk-accent)}
.v5 a{color:var(--sk-link);text-underline-offset:.25em}
.v5 :is(p,li,dd) a:not(.v5-btn){text-decoration:underline}
.v5-pad-x{padding-left:var(--pad-page);padding-right:var(--pad-page)}
.v5-shell{width:100%;max-width:var(--shell-max);margin-inline:auto;container-type:inline-size}
.v5-shell--sm{max-width:55ch;font-size:var(--fs-l)}
.v5-pad-y-m{padding-block:var(--sec-m)}
.v5-pad-y-l{padding-block:var(--sec-l)}
.v5-rule{width:100%;height:1px;background-color:var(--sk-border)}
.v5-eyebrow{font:700 var(--fs-s)/1.6 var(--lato);letter-spacing:2px;text-transform:uppercase}
.v5-eyebrow--gap{padding-bottom:var(--sp-1)}
.v5-eyebrow--gap-l{padding-bottom:var(--sp-1-5)}
/* Space between paragraphs: two thirds of a line, the 1em it was at
   line-height 1.5, so it grows with the line (1.0667em at 1.6). */
.v5-rich p + p,.v5-rich ul + p,.v5-rich p + ul{margin-top:calc(2lh / 3)}
.v5-rich p + h3,.v5-rich ul + h3{margin-top:1em}
.v5-rich h3{font-size:min(var(--fs-l),100cqi / var(--word));margin-top:var(--sp-2);margin-bottom:var(--sp-0-5)}
.v5-rich--l{font-size:var(--fs-l);line-height:1.6}
.v5-list{padding-left:1.25em}
.v5-list li + li{margin-top:.5em}
/* Buttons (B1): pill, Lato 700 18px, no text-transform, 52px tall (17px
   above and below: whole pixels), 36px sides. Padding in em, so the
   enlarged-text caps shrink the whole box. */
.v5-btn{display:inline-flex;align-items:center;justify-content:center;min-height:52px;padding:calc(17em / 18) 2em;background:var(--sk-btn-bg);color:var(--sk-btn-text);border-radius:999px;font:700 1.125rem/1 var(--lato);letter-spacing:normal;text-transform:none;text-decoration:none;text-align:center;max-width:100%}
.v5 a.v5-btn{color:var(--sk-btn-text)}
.v5-btn--light{--sk-btn-bg:#F3F4F2;--sk-btn-text:#304054}
/* SWEEP (B1): hover (fine pointer) or :focus-visible sweeps the new fill
   in from the bottom-left corner to the top-right, edge perpendicular to
   that diagonal, and back on leaving.
   Navy buttons (the text stays white): the fill is the button's ::before,
   the button's box (% minus em) rotated 90deg, clipped to the half-plane
   behind a line parallel to its own diagonal, moved +-half the width and
   height (--sweep -1/1); transform only.
   Where the text colour changes (light buttons, the header button): a span
   (data-label) carries the fill and the label in the new colour, laid out
   exactly as the button's own text and never moved or transformed; an
   animated clip-path reveals it. The span is a size container, so the
   edge's run across the height, H*H/W, is 100cqh * tan(atan2(100cqh, 100cqw)). */
:is(.v5-btn,.cta-button){position:relative;isolation:isolate;overflow:clip}
.v5-btn::before{content:"";position:absolute;inset:-1em -1em -31em;z-index:-1;background:var(--sw-bg,#456188);clip-path:polygon(calc(450% - 8em) calc(113em - 350%),calc(8em - 350%) calc(450% - 143em),calc(8em - 350%) calc(650% - 143em),calc(450% - 8em) calc(113em - 150%));transform-origin:50% calc(50% - 15em);transform:translate(calc(var(--sweep,-1) * (50% - 1em)),calc(var(--sweep,-1) * (16em - 50%))) rotate(90deg);pointer-events:none}
.v5-btn:has(.v5-sweep)::before{content:none}
.v5-sweep{position:absolute;inset:0;container-type:size;pointer-events:none}
.v5-sweep::before{content:attr(data-label);position:absolute;inset:0;display:flex;align-items:center;justify-content:center;padding:0 2em;background:var(--sw-bg,#456188);color:var(--sw-fg,#FFFFFF);text-align:center;text-decoration:inherit;--r:calc(100cqh * tan(atan2(100cqh,100cqw)));--k:calc((var(--sweep,-1) + 1) / 2);clip-path:polygon(calc(-1 * var(--r)) 0,calc(var(--k) * (100cqw + var(--r)) - var(--r)) 0,calc(var(--k) * (100cqw + var(--r))) 100%,calc(-1 * var(--r)) 100%)}
/* Swept, the button's own fill takes the new colour too (no hairline of the
   old fill at the anti-aliased edge): a step once the sweep ends, back at once. */
:is(.v5-btn,.cta-button):focus-visible{--sweep:1;background-color:var(--sw-bg,#456188)}
@media (hover:hover) and (pointer:fine){:is(.v5-btn,.cta-button):hover{--sweep:1;background-color:var(--sw-bg,#456188)}}
@media (hover:hover) and (pointer:fine) and (prefers-reduced-motion:no-preference){.v5-btn::before{transition:transform .8s cubic-bezier(.33,1,.68,1)}
.v5-sweep::before{transition:clip-path .8s cubic-bezier(.33,1,.68,1)}
:is(.v5-btn,.cta-button){transition:background-color 0s}
:is(.v5-btn,.cta-button):is(:hover,:focus-visible){transition-delay:.8s}}
/* Touch: no sweep; pressed darkens at once (navy text 5.7:1 on the light button). */
@media (hover:none),(pointer:coarse){:is(.v5-btn,.cta-button):active{box-shadow:inset 0 0 0 99em rgba(30,31,33,.25)}}
/* The toolbar's colour modes set their own button colours. */
html:is(.a11y-contrast,.a11y-negative,.a11y-light) .v5-btn::before,html:is(.a11y-contrast,.a11y-negative,.a11y-light) .v5-sweep{display:none}
.v5-button-row{display:flex;flex-wrap:wrap;gap:var(--sp-1-25);align-items:center}
.v5-button-row--center{align-self:stretch;justify-content:center}
.v5-book{margin-top:var(--sp-3)}
/* "Or call": body text size and bold everywhere (Justin, 2026-10-14; under
   the letter it took the large text size, 22.5px at 1920, from a rule that
   matched a large block before it); the number has a 48px target, as a
   primary action (SEO-AUDIT 9.3). */
.v5-book p{font-size:var(--fs-m);font-weight:700}
.v5-book p a{display:inline-block;padding-block:calc((48px - 1lh) / 2)}
/* Phones: booking button and call line centred */
@media (max-width:767px){
  .v5-book{flex-direction:column;align-items:center;text-align:center}
}
/* INTRO BLOCK: title column and description column; the description sits
   level with the bottom of the title. One column below 992. */
.v5-intro__gap{padding-bottom:var(--sp-1-5)}
.v5-intro__wrap{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);column-gap:var(--sp-5);row-gap:var(--sp-1);text-align:left}
.v5-intro__title{display:flex;flex-direction:column;align-items:flex-start;gap:var(--sp-1-5);min-width:0}
.v5-intro__desc{display:flex;flex-direction:column;align-items:flex-start;align-self:end;gap:var(--sp-1-5);font-size:var(--fs-l)}
@media (max-width:991px){.v5-intro__wrap{grid-template-columns:minmax(0,1fr)}}
/* CARDS: hairline border, card radius. */
.v5-card{display:flex;flex-direction:column;align-items:flex-start;gap:var(--sp-0-75);padding:var(--sp-1-5);background-color:var(--sk-bg);border:1px solid var(--sk-border);border-radius:var(--radius-small);transform-origin:0 0}
.v5-card h3{font-size:min(var(--fs-2xl),100cqi / var(--word));line-height:1.3}
.v5-cards{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));column-gap:var(--sp-3);row-gap:var(--sp-4);margin-top:var(--sp-5)}
@media (max-width:991px){.v5-cards{grid-template-columns:minmax(0,1fr)}}
@media (max-width:767px){.v5-card h3{font-size:min(var(--fs-xl),100cqi / var(--word))}}
@media (max-width:479px){.v5-card h3{font-size:min(var(--fs-l),100cqi / var(--word))}}
.v5-table{width:100%;border-collapse:collapse}
.v5-table caption{padding-bottom:var(--sp-0-75);font:700 var(--fs-l)/1.3 var(--lato);letter-spacing:0;text-align:left}
.v5-table th,.v5-table td{padding:.625rem 0;border-bottom:1px solid var(--sk-border);text-align:left;vertical-align:top}
.v5-table thead th{border-bottom:2px solid #304054;font:700 var(--fs-s)/1.4 var(--lato);letter-spacing:1px;text-transform:uppercase}
.v5-table thead th:last-child{text-align:right}
.v5-table tbody th{padding-right:1rem;font-weight:400}
.v5-table td{font:700 var(--fs-m)/1.5 var(--lato);text-align:right;white-space:nowrap}
.v5-table td .v5-ph{white-space:normal}
.v5-note{font-size:var(--fs-s)}
/* TWO-COLUMN INFORMATION BLOCKS: the page grid in halves; the media column
   sticks just below the header (--hdr-h) from 768 up. */
.v5-grid{display:grid;grid-template-columns:repeat(var(--grid-cols),minmax(0,1fr));column-gap:var(--grid-col-gap);row-gap:var(--grid-row-gap)}
.v5-col-half{grid-column:span 6}
@media (max-width:991px){.v5-col-half{grid-column:span 4}}
@media (max-width:767px){.v5-col-half{grid-column:1 / -1}}
.v5-info__grid{place-items:start stretch;padding-block:var(--sec-l)}
.v5-info__text{width:100%;margin:auto;padding-inline:2.2vw}
.v5-info__media{position:sticky;top:calc(var(--hdr-h) + var(--sp-1))}
.v5-info__media--first{order:-1}
.v5-info__frame{position:relative;display:flex;aspect-ratio:var(--ratio,1 / 1);overflow:clip}
.v5-parallax{width:100%;height:100%}
/* A photo fills its frame and is never cropped (contain; the photos are as
   square as their frames). */
.v5-info__frame picture{width:100%}
.v5-info__img{display:block;width:100%;height:100%;object-fit:contain}
/* The portrait's frame has rounded corners (10px; it clips the photo). The
   real-ear photo's frame has a navy square of its own size behind it, 20px
   down and 20px toward the text, less sideways where the page margin is
   narrower (13px at 375), drawn as the frame's own shadow: it takes no
   space, never widens the page, and moves with the frame. */
.v5-info__frame--round{border-radius:10px}
.v5-info__frame--backdrop{box-shadow:calc(-1 * min(20px, var(--pad-page))) 20px 0 #304054}
/* SCROLL REVEALS, 768px and up (armed and triggered by v5-site.js; nothing
   here hides anything until the script adds .is-armed; below 768 nothing is
   armed). "up": a section's text, as one block, from opacity 0 and one
   --sp-3-5 below (45px at 768, 58px at 1440), 1s ease. "left" / "right": a
   photo frame from opacity .01 and its own width out to that side, 1.2s
   ease. To-only keyframes, forwards fill; .is-instant (focus) shows at once.
   The section clips sideways so a frame coming in from the side never
   widens the page. */
.v5 > section:has([data-reveal]){overflow-x:clip}
@media (min-width:768px) and (prefers-reduced-motion:no-preference){
  [data-reveal="up"].is-armed{opacity:0;transform:translateY(var(--sp-3-5))}
  [data-reveal="left"].is-armed{opacity:.01;transform:translateX(-100%)}
  [data-reveal="right"].is-armed{opacity:.01;transform:translateX(100%)}
  [data-reveal].is-armed.is-visible{animation:v5-reveal 1s ease forwards}
  :is([data-reveal="left"],[data-reveal="right"]).is-armed.is-visible{animation-duration:1.2s}
  [data-reveal].is-armed.is-instant{opacity:1;transform:none;animation:none}
}
@keyframes v5-reveal{to{opacity:1;transform:none}}
.v5-parallax .v5-ph--img{height:100%}
/* Enlarged text: an image placeholder keeps its frame's shape but may grow to hold its text. */
.a11y-fs-up .v5-info__frame:has(.v5-ph--img){aspect-ratio:auto}
.a11y-fs-up .v5-info__frame :is(.v5-parallax,.v5-ph--img){height:auto}
.a11y-fs-up .v5-info__frame .v5-ph--img{aspect-ratio:var(--ratio,1 / 1)}
.v5-info__gap{padding-bottom:var(--sp-1-5)}
.v5-info__gap-b{padding-top:var(--sp-2)}
.v5-info .v5-book{margin-top:0}
/* Media drift: the frame is the timeline, its content moves within it. */
@keyframes v5-media-drift{0%{transform:translateY(3%)}100%{transform:translateY(-7%)}}
@supports (animation-timeline:view()){
  @media (prefers-reduced-motion:no-preference){
    .v5-info__frame{view-timeline:--v5-media block}
    [data-parallax="1"]{animation-name:v5-media-drift;animation-duration:auto;animation-timing-function:linear;animation-fill-mode:both;animation-timeline:--v5-media;animation-range:entry 50% exit 50%}
  }
}
@media (max-width:991px){.v5-info__text{padding-inline:0}}
@media (max-width:767px){.v5-info__media{position:static;order:-1}}
.v5-sign{margin-top:var(--sp-1-5)}
.v5-sign__name{font:italic 400 var(--fs-xl)/1.4 var(--montserrat)}
/* Running text 16px minimum; labels keep --fs-s */
:is(.v5-note,.ohs-ftr .v5-licence,.ohs-ftr__col p:not(.ohs-ftr__eyebrow)){font-size:1rem}
/* PLACEHOLDERS: meant to look unfinished (brief section 6). */
.v5-ph{padding:.125rem .375rem;border:2px dashed #1E1F21;background:#FFF4B8;color:#1E1F21;font:600 .875rem/1.6 ui-monospace,Menlo,Consolas,monospace;letter-spacing:0;text-transform:none;-webkit-box-decoration-break:clone;box-decoration-break:clone}
.v5-ph--block{display:block;max-width:44em;margin:1rem 0;padding:.75rem 1rem;text-align:left}
.v5-ph--img{display:flex;align-items:center;justify-content:center;width:100%;margin:0;padding:1.25rem;text-align:center}
.ohs-ftr .ohs-ftr__legal .v5-ph{color:#1E1F21;font-size:.75rem}
/* Held zone (footer-v5.php): the phone call-and-book bar to come. */
.v5-held-zone{display:flex;align-items:center;justify-content:center;min-height:64px;margin:0;padding:8px 16px;border-width:2px 0 0;text-align:center}
@media (min-width:1000px){.v5-held-zone{display:none}}
/* Enlarged toolbar text: headings follow the allowance (--word, above);
   other display text is capped so its widest word fits the viewport
   (divisor = measured widest word in em, plus margin; for buttons plus
   their 4em of side padding); grids drop columns, table cells wrap at spaces,
   and placeholders may break mid-word as a last resort. */
.a11y-fs-up .ohs-ftr__mission-text{font-size:min(var(--fs-xl),100vw / 8)}
.a11y-fs-up button.a11y-btn{font-size:min(var(--fs-s),100vw / 16)}
:is(.a11y-fs-up,.a11y-dyslexic) .v5-table td{white-space:normal}
.a11y-fs-up .v5 .v5-ph{overflow-wrap:anywhere}
.a11y-fs-up .v5 :is(p,li,dt,dd){overflow-wrap:break-word}
@media (max-width:1199px){
  .a11y-fs-up .v5-cards{grid-template-columns:minmax(0,1fr)}
}
/* Page fonts and Readable Font: whole words (widest word, measured) */
.a11y-fs-up :is(.v5-card,.v5-book,.v5-button-row){container-type:inline-size}
.a11y-fs-up :is(.v5-book,.v5-button-row) .v5-btn{font-size:min(1.125rem,100cqi / 10.3)}
.a11y-fs-up .v5 .v5-table thead th{font-size:min(var(--fs-s),100cqi / 12.5)}
.a11y-fs-up .v5 .v5-table :is(tbody th,td){font-size:min(var(--fs-m),100cqi / 11)}
/* Dyslexia Font: OpenDyslexic's widest words measure 1.26 to 1.47 times the
   page fonts' (cap-ratio.mjs), so the width caps divide by 1.5 times as much
   and apply at any text size; no-wrap lines wrap; a word that still cannot
   fit breaks rather than widening its column past the viewport. */
.a11y-dyslexic .ohs-ftr__mission-text{font-size:min(var(--fs-xl),100vw / 12)}
.a11y-dyslexic button.a11y-btn{font-size:min(var(--fs-s),100vw / 24)}
/* Both toolbar fonts (Atkinson measured 1px over at 768 / 200%): a word that cannot fit breaks. */
:is(.a11y-readable,.a11y-dyslexic) :is(.v5,.ohs-ftr) :is(h2,h3,p,li,dt,dd,caption,a,span){overflow-wrap:anywhere}
/* Dyslexia Font: whole words fit (widest word, measured) */
.a11y-dyslexic :is(.v5-card,.v5-rich,.ohs-ftr__col,.v5-book,.v5-button-row){container-type:inline-size}
.a11y-dyslexic .ohs-ftr__eyebrow{font-size:min(var(--fs-s),100cqi / 9)}
.a11y-dyslexic :is(.v5-book,.v5-button-row) .v5-btn{font-size:min(1.125rem,100cqi / 14.1)}
.a11y-dyslexic .v5-eyebrow{font-size:min(var(--fs-s),100vw / 13.5)}
.a11y-dyslexic .v5 .v5-table thead th{font-size:min(var(--fs-s),100cqi / 16)}
.a11y-dyslexic .v5 .v5-table :is(tbody th,td){font-size:min(var(--fs-m),100cqi / 15)}
@media (max-width:767px){html.a11y-fs-up.a11y-dyslexic .v5-card{padding:var(--sp-0-75)}}
/* BACK TO TOP (made by v5-site.js): fixed at the right edge, 75px up (40px
   below 768, 16px in windows up to 360px tall), 44px square, Calm Teal (#557F8D, the brand accent: it stands
   off the navy sections, 2.4:1, where navy did not) with a white double
   arrow (4.4:1); a deeper teal on hover and focus (#42626D, same hue about
   10% darker: white 6.6:1); focus ring drawn inside, so the screen edge
   cannot cut it. The arrow blinks twice (two dips to 20%, 1.2s in all) 1s
   after the button appears and every 15s after that; not while hovered or
   focused, not with reduced motion. Hidden, and out of the tab order, until the page has scrolled past
   160px; shown and hidden with a .25s linear fade; hidden while the
   accessibility panel or the phone menu is open. */
.v5-top{position:fixed;right:env(safe-area-inset-right,0px);bottom:75px;z-index:50;display:flex;align-items:center;justify-content:center;width:44px;height:44px;padding:0;border:0;border-radius:var(--radius-tiny);background:#557F8D;color:#FFFFFF;cursor:pointer;opacity:0;visibility:hidden;transition:opacity .25s linear,visibility .25s linear,background-color .25s linear,transform .3s cubic-bezier(.33,1,.68,1)}
.v5-top.is-shown{opacity:1;visibility:visible}
@media (max-width:767px){.v5-top{bottom:calc(40px + env(safe-area-inset-bottom,0px))}}
/* Short windows: at 200% text the accessibility tab reaches down to 202.2px
   (992 x 320), 1.2px into the button at bottom:75px; 16px clears it. */
@media (max-height:360px){.v5-top{bottom:16px}}
@media (hover:hover){.v5-top:hover{background:#42626D}}
body.v5-site .v5-top:focus-visible{background:#42626D;outline:3px solid #FFFFFF;outline-offset:-7px;box-shadow:none}
html.a11y-open .v5-top,body:has(.main-nav.active) .v5-top{opacity:0;visibility:hidden}
html.a11y-light .v5-top{box-shadow:inset 0 0 0 2px #1E1F21}
@media (prefers-reduced-motion:no-preference){.v5-top.is-shown svg{animation:v5-top-blink 15s ease-in-out infinite}
.v5-top:is(:hover,:focus-visible) svg{animation:none}}
@keyframes v5-top-blink{0%,6.7%,10.7%,14.7%,100%{opacity:1}8.7%,12.7%{opacity:.2}}
@media (prefers-reduced-motion:reduce){.v5-top{transition:none}}
/* PHONE CONTACT BAR (footer-v5.php; Justin, 2026-10-14). Below 768px a
   fixed bar at the bottom, the header's counterpart: v5-site.js puts .is-on
   on it (and .v5-bar-on on <html>) exactly while the header is hidden, so
   one of the two is always in view, never both. It slides on transform with
   the header's timing and curve (at once with reduced motion), and is inert
   while off. As tall as the phone header (--hdr-h) plus the home-indicator
   inset; slate like the solid header. Two equal buttons, at least 44px
   tall: the phone link as the header's (white outline pill) and Book online
   as the header's Book button (navy pill, white text 10.6:1; white on slate
   6.3:1). The page keeps room for it: the footer's foot, and
   scroll-padding-bottom for focus and jump links (WCAG 2.4.11). Back to top
   rides up to 20px above the bar while the bar is on. */
.v5-bar{display:none}
@media (max-width:767px){
  :root{--bar-h:calc(var(--hdr-h) + env(safe-area-inset-bottom,0px))}
  /* Room for the bar only where it can show (it needs the script). */
  html.js{scroll-padding-bottom:calc(var(--bar-h) + var(--sp-1))}
  html.js .ohs-ftr{padding-bottom:var(--bar-h)}
  .v5-bar{position:fixed;left:0;right:0;bottom:0;z-index:1002;display:grid;grid-template-columns:repeat(2,minmax(0,1fr));align-items:center;column-gap:var(--sp-1);box-sizing:content-box;height:var(--hdr-h);padding:0 var(--hdr-gut) env(safe-area-inset-bottom,0px);background-color:var(--slate);transform:translateY(100%);transition:transform .3s cubic-bezier(.33,1,.68,1)}
  .v5-bar.is-on{transform:none;box-shadow:0 -4px 20px rgba(0,0,0,.15)}
  .v5-bar a{display:flex;align-items:center;justify-content:center;gap:.5em;min-width:0;min-height:44px;padding:.25em .5em;border-radius:999px;font:700 min(1rem,24px)/1.15 var(--lato);letter-spacing:normal;text-align:center;text-decoration:none;color:#FFFFFF}
  .v5-bar__call{border:2px solid currentColor}
  .v5-bar__book{background-color:var(--navy)}
  .v5-bar svg{flex:none;width:1em;height:1em;fill:currentColor}
  .v5-bar__num{white-space:nowrap}
  .v5-bar__word{display:none}
  /* Back to top sits 20px above the bar while it is on (Justin, 2026-10-14:
     half its 40px gap from the window's foot); the shift leaves out the
     safe-area inset, which both already include. */
  html.v5-bar-on .v5-top{transform:translateY(calc(20px - var(--hdr-h)))}
  /* "Call" in place of the number where it does not fit its half (the
     accessible name keeps the number): below 352px, 366px with the Readable
     Font, 443px with the Dyslexia Font, and at every phone width with
     enlarged text, as in the header. */
  .a11y-fs-up .v5-bar__num{display:none}
  .a11y-fs-up .v5-bar__word{display:inline}
}
@media (max-width:351px){.v5-bar__num{display:none}.v5-bar__word{display:inline}}
@media (max-width:365px){.a11y-readable .v5-bar__num{display:none}.a11y-readable .v5-bar__word{display:inline}}
@media (max-width:442px){.a11y-dyslexic .v5-bar__num{display:none}.a11y-dyslexic .v5-bar__word{display:inline}}
@media (max-width:767px) and (hover:none),(max-width:767px) and (pointer:coarse){.v5-bar a:active{box-shadow:inset 0 0 0 99em rgba(30,31,33,.25)}}
@media (prefers-reduced-motion:reduce){.v5-bar{transition:none}}
/* On child pages the bar matches their navy header: navy, and its Book
   Online button white with charcoal text, as the header's Book button. */
body.v5-hdr-solid .v5-bar{background-color:var(--navy)}
body.v5-hdr-solid .v5-bar .v5-bar__book{background-color:#FFFFFF;color:#1E1F21}
