/* "Sand" homepage theme.
   A warm general-practice look: sand (#e5decc) bands top and bottom, a cream
   page, a white content sheet lifted over the hero photo, quiet serif running
   text under firm sans headings, and one earthy accent that drives every
   coloured surface.

   Accent: the practice picks its own in the appearance settings; the value
   arrives after this file as :root{--c-accent:…}. So --c-accent is only a
   default here and every accent surface reads it through var() — including the
   darker shades, which are mixed from it so they follow an override.

   Mixing alone is not enough, though: a mix keeps the accent's lightness, so a
   pale accent (a practice picking #f2c14e) produced pale "dark" shades and the
   whole theme fell below AA — nav links at 3.3 : 1, buttons at 2.4 : 1. The
   mixes are therefore lightness-clamped in OKLCH (see the @supports block under
   the tokens), which is a no-op for the shipped accent and pulls a light one
   down until it reads. Measured across the whole sRGB cube, the worst case is
   4.59 : 1 for --c-accent-deep on the sand band and 4.88 : 1 for white on
   --c-accent-dark — both AA.

   Mobile-first: the base rules target a narrow screen, the media queries layer
   the wider layouts on top. */

/* ---------------------------------------------------------------- tokens -- */

:root {
  --c-accent: #8c7355;

  /* Text-safe shades of the accent. Everything that carries or marks text uses
     one of these two, never the raw --c-accent: the raw value is whatever the
     practice picked and may be pale enough to vanish on paper. */
  --_accent-mix-deep: color-mix(in srgb, var(--c-accent) 68%, #1a1209);
  --_accent-mix-dark: color-mix(in srgb, var(--c-accent) 82%, #1a1209);
  --c-accent-deep: var(--_accent-mix-deep);
  --c-accent-dark: var(--_accent-mix-dark);
  --c-accent-soft: color-mix(in srgb, var(--c-accent) 14%, #ffffff);
  --c-accent-tint: color-mix(in srgb, var(--c-accent) 26%, #ffffff);

  --c-sand: #e5decc;
  --c-sand-deep: #d9d0b9;
  --c-cream: #f9f5f0;
  --c-sheet: #ffffff;
  --c-ink: #1c1a17;
  --c-muted: #5a5349;
  --c-line: #e2dacb;

  /* Inverted from the usual pairing: the serif carries the running text and the
     page title, the sans carries headings, navigation and labels. */
  --font-serif: "Lora", Georgia, "Times New Roman", serif;
  --font-sans: "Open Sans", system-ui, -apple-system, "Segoe UI", Arial, sans-serif;

  --w-page: 68rem;
  --r-card: 8px;
  --r-soft: 4px;
  --shadow-card: 0 1px 2px rgba(60, 45, 25, 0.05), 0 8px 24px rgba(60, 45, 25, 0.07);
  /* Height of the sticky navbar — the bar's own min-height, and the fallback
     for the anchor offset. A practice with many sections wraps the bar onto a
     second row, which only theme.js can know: it writes the measured height to
     --bar-now, so this value stays the one-row (and no-JS) case. */
  --bar-h: 4.5rem;
}

/* The two dark shades, lightness-clamped so they stay readable whatever accent
   a practice sets. The thresholds are the shipped accent's own values (deep
   L 0.460, dark L 0.510), so #8c7355 passes through untouched and only a
   lighter accent is pulled down. Browsers without relative colour syntax keep
   the plain mixes above, which is the right answer for the shipped accent. */
@supports (color: oklch(from white l c h)) {
  :root {
    --c-accent-deep: oklch(from var(--_accent-mix-deep) min(l, 0.46) c h);
    --c-accent-dark: oklch(from var(--_accent-mix-dark) min(l, 0.51) c h);
  }
}

/* Self-hosted webfonts — served from this directory, never from a font CDN
   (see fonts/README.txt for the licences and the reason). */
@font-face {
  font-family: "Lora";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("fonts/lora-400.woff2") format("woff2");
}
@font-face {
  font-family: "Lora";
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url("fonts/lora-400-italic.woff2") format("woff2");
}
@font-face {
  font-family: "Lora";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("fonts/lora-700.woff2") format("woff2");
}
@font-face {
  font-family: "Open Sans";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("fonts/open-sans-400.woff2") format("woff2");
}
@font-face {
  font-family: "Open Sans";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("fonts/open-sans-700.woff2") format("woff2");
}

/* ------------------------------------------------------------------ base -- */

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  /* --bar-now is what theme.js measures; --bar-h is the layout value and must
     not be written to, or the bar's own min-height would chase it upwards. */
  scroll-padding-top: calc(var(--bar-now, var(--bar-h)) + 1rem);
  scroll-behavior: smooth;
}

body {
  margin: 0;
  /* The quote banner breaks out to 100vw, and vw counts the classic desktop
     scrollbar — without this the band sits ~15px wider than the page can show
     and the whole site gets a horizontal scrollbar. `clip`, not `hidden`: the
     latter makes body a scroll container and kills the sticky navbar. */
  overflow-x: clip;
  background: var(--c-cream);
  color: var(--c-ink);
  font-family: var(--font-serif);
  font-size: 1.0625rem;
  line-height: 1.65;
  -webkit-text-size-adjust: 100%;
}

img {
  max-width: 100%;
}

a {
  color: var(--c-accent-deep);
  text-decoration-thickness: 1px;
  text-underline-offset: 0.18em;
}

a:hover {
  color: var(--c-accent-dark);
}

:focus-visible {
  outline: 3px solid var(--c-accent-dark);
  outline-offset: 2px;
  border-radius: 2px;
}

h1,
h2,
h3,
h4 {
  font-family: var(--font-sans);
  color: var(--c-accent-deep);
  line-height: 1.25;
  margin: 0 0 0.75rem;
}

p {
  margin: 0 0 1rem;
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
  }
}

/* ------------------------------------------------------------ info strip -- */

.infostrip {
  background: var(--c-sand);
  border-bottom: 1px solid var(--c-sand-deep);
  font-size: 0.8125rem;
}

.infostrip__inner {
  max-width: var(--w-page);
  margin-inline: auto;
  padding: 0.45rem 1.25rem;
  display: flex;
  flex-wrap: wrap;
  gap: 0.15rem 1.5rem;
  justify-content: space-between;
}

.infostrip p {
  margin: 0;
}

.infostrip__name {
  font-weight: 700;
}

.infostrip__sep {
  color: var(--c-accent-deep);
  padding-inline: 0.3rem;
}

.infostrip__label {
  font-family: var(--font-sans);
  font-weight: 700;
}

/* On sand the plain accent would drop to ~2.4:1 — the deep mix keeps the
   contact links readable, which is the whole point of the strip. */
.infostrip__link {
  color: var(--c-accent-deep);
  text-decoration: none;
}

.infostrip__link:hover,
.infostrip__link:focus-visible {
  text-decoration: underline;
}

/* --------------------------------------------------------------- navbar --- */

.navbar {
  position: sticky;
  top: 0;
  z-index: 20;
  background: #fff;
  border-bottom: 1px solid var(--c-line);
}

/* A bar carrying the open list is taller than a phone screen — a practice with
   ten sections measured 589 px on a 700 px viewport — and a sticky box that
   tall pins itself over the page for the whole scroll: the visitor scrolls and
   only ever sees the menu. It is open in exactly two situations, and neither
   wants stickiness: no JavaScript (theme.js never collapsed it) and the moment
   after a tap on the toggle. Where :has() is unsupported the bar stays sticky,
   which is today's behaviour. */
@media (max-width: 55.999rem) {
  .navbar:has(.navbar__list:not([hidden])) {
    position: static;
  }
}

.navbar__inner {
  max-width: var(--w-page);
  margin-inline: auto;
  padding: 0.5rem 1.25rem;
  display: flex;
  align-items: center;
  gap: 1rem;
  flex-wrap: wrap;
  min-height: var(--bar-h);
}

.navbar__brand {
  display: inline-flex;
  align-items: center;
  /* A practice without a logo shows its name here, and a line of text is a
     28 px tap target; the bar has room for a comfortable one. */
  min-height: 2.75rem;
  margin-right: auto;
  text-decoration: none;
}

.navbar__logo {
  height: 3rem;
  width: auto;
}

.navbar__name {
  font-family: var(--font-sans);
  font-weight: 700;
  font-size: 1.05rem;
  color: var(--c-accent-deep);
}

.navbar__toggle {
  width: 2.75rem;
  height: 2.75rem;
  display: grid;
  place-items: center;
  border: 1px solid var(--c-line);
  border-radius: var(--r-soft);
  background: var(--c-cream);
  cursor: pointer;
}

/* The display above beats the UA's [hidden]{display:none}, so without this rule
   the button a JS-less visitor must never see was drawn anyway — and did
   nothing when tapped. theme.js drops the attribute once it can wire it up. */
.navbar__toggle[hidden] {
  display: none;
}

.navbar__bars,
.navbar__bars::before,
.navbar__bars::after {
  display: block;
  width: 1.25rem;
  height: 2px;
  background: var(--c-accent-deep);
  border-radius: 2px;
}

.navbar__bars {
  position: relative;
}

.navbar__bars::before,
.navbar__bars::after {
  content: "";
  position: absolute;
  left: 0;
}

.navbar__bars::before {
  top: -0.4rem;
}

.navbar__bars::after {
  top: 0.4rem;
}

.navbar__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.1rem 1.4rem;
  width: 100%;
}

/* Collapsed state: only ever set once theme.js has unhidden the button, so a
   no-JS visitor keeps the full list. */
.navbar__list[hidden] {
  display: none;
}

.navbar__item {
  width: 100%;
}

.navbar__link {
  display: block;
  padding: 0.7rem 0;
  font-family: var(--font-sans);
  font-weight: 700;
  font-size: 1rem;
  color: var(--c-accent-deep);
  text-decoration: none;
  border-bottom: 1px solid var(--c-line);
}

.navbar__link:hover,
.navbar__link:focus-visible {
  color: var(--c-accent-dark);
}

.navbar__link.is-active {
  color: var(--c-ink);
}

@media (min-width: 56rem) {
  .navbar__toggle {
    display: none;
  }

  .navbar__list,
  .navbar__list[hidden] {
    display: flex;
    width: auto;
    justify-content: flex-end;
  }

  .navbar__item {
    width: auto;
  }

  /* Tall enough to stay a 44 px target on a tablet, where the wide bar is
     already in use but the finger is still the pointer. */
  .navbar__link {
    display: flex;
    align-items: center;
    min-height: 2.75rem;
    padding: 0.35rem 0;
    border-bottom: 2px solid transparent;
  }

  /* The underline is what says "you are here", so it takes the deep shade: the
     raw accent may be pale enough to leave the marker invisible. */
  .navbar__link:hover,
  .navbar__link:focus-visible,
  .navbar__link.is-active {
    border-bottom-color: var(--c-accent-deep);
  }
}

/* ----------------------------------------------------------------- hero --- */

.hero__plate {
  background: var(--c-sand);
}

.hero__plate-inner {
  max-width: var(--w-page);
  margin-inline: auto;
  padding: 1.75rem 1.25rem;
  display: flex;
  align-items: center;
  gap: 1.25rem;
}

.hero__logo {
  width: 4.5rem;
  height: auto;
  flex: none;
}

/* German compound words run long; hyphenate and, as a last resort, break, so
   the plate never pushes the page sideways on a phone. */
.hero__title {
  font-family: var(--font-serif);
  font-weight: 700;
  font-size: clamp(1.5rem, 5.5vw, 2.4rem);
  line-height: 1.18;
  color: var(--c-ink);
  margin: 0;
  min-width: 0;
  hyphens: auto;
  overflow-wrap: anywhere;
}

/* On a phone the logo sits above the title, as there is no room beside it. */
@media (max-width: 34rem) {
  .hero__plate-inner {
    flex-direction: column;
    align-items: flex-start;
    gap: 0.9rem;
  }

  .hero__logo {
    width: 3.5rem;
  }
}

.hero__photo {
  position: relative;
  overflow: hidden;
  background-color: var(--c-sand-deep);
  background-size: cover;
  background-position: center;
  height: clamp(11rem, 34vw, 24rem);
}

/* No photo of the practice's own: the bundled default (generated by
   scripts/demo_images) — a camomile still life in the theme's own sand tones.
   The title sits on the plate above, never on the picture, so the photo carries
   no scrim and keeps its light. */
.hero__photo--blank {
  background-image: url("hero.jpg");
}

.hero__photo .cms-hero,
.hero__photo .cms-hero__track,
.hero__photo .cms-hero__slide {
  height: 100%;
  margin: 0;
}

.hero__photo .cms-hero__track {
  display: flex;
  transition: transform 0.7s ease;
}

.hero__photo .cms-hero__slide {
  flex: 0 0 100%;
}

.hero__photo .cms-hero__image {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* Fade carousel: theme.js adds .is-ready and toggles .is-active per slide. */
.cms-hero.is-ready[data-transition="fade"] .cms-hero__track {
  display: block;
  position: relative;
  height: 100%;
}

.cms-hero.is-ready[data-transition="fade"] .cms-hero__slide {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity 0.9s ease;
}

.cms-hero.is-ready[data-transition="fade"] .cms-hero__slide.is-active {
  opacity: 1;
}

/* --------------------------------------------------------------- content -- */

.content {
  position: relative;
  z-index: 1;
  max-width: var(--w-page);
  margin: -1.75rem auto 0;
  padding: 2rem 1.25rem 3rem;
  background: var(--c-sheet);
  border-radius: var(--r-card) var(--r-card) 0 0;
  box-shadow: 0 -2px 18px rgba(60, 45, 25, 0.08);
}

/* The rhythm belongs on the wrapper render_homepage_blocks emits, not on the
   sections it wraps. */
.content > .cms-block,
.content > .cms-block--full {
  margin-block: 3rem;
}

.content > .cms-block:first-child,
.content > .cms-block--full:first-child {
  margin-top: 0;
}

.content > .cms-block:last-child,
.content > .cms-block--full:last-child {
  margin-bottom: 0;
}

/* Running text stays at a comfortable measure; cards and grids may use the
   full column. */
.cms-services__description,
.cms-patient-info__body,
.cms-team__bio,
.cms-appointments-link__intro,
.cms-prescription-link__intro,
.cms-patientportal-link__intro {
  max-width: 62ch;
}

@media (min-width: 48rem) {
  body {
    font-size: 1.125rem;
  }

  .hero__plate-inner {
    padding: 2.5rem 1.25rem;
    gap: 2rem;
  }

  .hero__logo {
    width: 6.5rem;
  }

  .content {
    margin-top: -3.5rem;
    padding: 3rem 3rem 4rem;
  }

  .content > .cms-block,
  .content > .cms-block--full {
    margin-block: 4rem;
  }
}

/* The opening-hours and contact panels are short and belong together, so on a
   wide home page they sit side by side while every other block keeps the full
   column. :has() carries this; where it is unsupported the blocks simply stack,
   which is the same layout the narrow screen gets. */
@media (min-width: 62rem) {
  .content--home {
    display: grid;
    grid-template-columns: 1fr 1fr;
    column-gap: 2.5rem;
    row-gap: 4rem;
    align-items: start;
  }

  /* Grid rows carry the rhythm here; margins would double it (they do not
     collapse between grid items). */
  .content--home > .cms-block,
  .content--home > .cms-block--full {
    grid-column: 1 / -1;
    margin-block: 0;
  }

  .content--home > .cms-block:has(> .cms-opening-hours),
  .content--home > .cms-block:has(> .cms-contact) {
    grid-column: span 1;
  }
}

/* On a block page the header already carries the block's title, so the
   section repeating it would say the same word twice. */
.content:not(.content--home) > .cms-block:first-child > section > [class$="__title"] {
  display: none;
}

/* ------------------------------------------------- shared section titles -- */

.cms-team__title,
.cms-opening-hours__title,
.cms-gallery__title,
.cms-services__title,
.cms-patient-info__title,
.cms-contact__title,
.cms-map__title,
.cms-prescription-link__title,
.cms-appointments-link__title,
.cms-patientportal-link__title,
.cms-announcements__title {
  font-family: var(--font-sans);
  font-weight: 700;
  font-size: clamp(1.25rem, 3.4vw, 1.6rem);
  color: var(--c-accent-deep);
  margin: 0 0 1.25rem;
}

/* The section titles that head a full-width block get the source's hairline
   under them; the ones inside a card do not (the card edge does that job). */
.cms-team__title,
.cms-gallery__title,
.cms-services__title,
.cms-patient-info__title,
.cms-map__title {
  padding-bottom: 0.75rem;
  border-bottom: 1px solid var(--c-line);
}

/* Card shell shared by the panels that float on the white sheet. */
.cms-opening-hours,
.cms-contact,
.cms-prescription-link,
.cms-appointments-link,
.cms-patientportal-link {
  background: var(--c-cream);
  border: 1px solid var(--c-line);
  border-radius: var(--r-card);
  padding: 1.5rem;
  box-shadow: var(--shadow-card);
}

@media (min-width: 48rem) {
  .cms-opening-hours,
  .cms-contact,
  .cms-prescription-link,
  .cms-appointments-link,
  .cms-patientportal-link {
    padding: 2rem 2.25rem;
  }
}

/* Buttons and CTAs — one earthy pill everywhere. (.cms-map__link is *not* one
   of them: the map block uses that class for the anchor wrapping the map image,
   so a pill there framed the map in a brown lozenge and left its caption at
   1.31 : 1. It is styled with the map, further down.) */
.cms-contact__submit,
.cms-appointments-link__cta,
.cms-patientportal-link__cta,
.cms-patient-info__download {
  display: inline-block;
  padding: 0.65rem 1.5rem;
  font-family: var(--font-sans);
  font-weight: 700;
  font-size: 0.95rem;
  color: #fff;
  /* White on the raw accent sits near 3.6:1 — the darker mix clears AA and
     still tracks a practice's own accent choice. */
  background: var(--c-accent-dark);
  border: 1px solid transparent;
  border-radius: 999px;
  text-decoration: none;
  cursor: pointer;
  min-height: 2.75rem;
}

.cms-contact__submit:hover,
.cms-appointments-link__cta:hover,
.cms-patientportal-link__cta:hover,
.cms-patient-info__download:hover {
  background: var(--c-accent-deep);
  color: #fff;
}

.cms-prescription-link__unavailable {
  margin: 0.75rem 0 0;
  font-size: 0.9rem;
  color: var(--c-muted);
}

/* ------------------------------------------------------------------ team -- */

/* A list, not a grid: photo beside a name and a short profile, the way the
   source presents its practitioners. */
.cms-team__grid {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 2.25rem;
}

/* Photo, name, role and bio are four flat siblings, so each one is placed
   explicitly — auto-placement would scatter them over two columns. */
.cms-team__member {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0;
}

.cms-team__photo {
  width: 100%;
  max-width: 11rem;
  margin-bottom: 1rem;
  aspect-ratio: 3 / 4;
  object-fit: cover;
  border-radius: var(--r-soft);
  background: var(--c-sand);
}

.cms-team__name {
  font-family: var(--font-sans);
  font-weight: 700;
  font-size: 1.1rem;
  color: var(--c-accent-deep);
  margin: 0 0 0.15rem;
}

.cms-team__role {
  font-family: var(--font-sans);
  font-size: 0.9rem;
  color: var(--c-muted);
  margin: 0 0 0.6rem;
}

.cms-team__bio p {
  margin: 0 0 0.6rem;
}

.cms-team__bio p:last-child {
  margin-bottom: 0;
}

@media (min-width: 40rem) {
  /* An "auto" first column collapses to nothing for a member without a photo,
     so the text still starts at the left edge. */
  .cms-team__member {
    grid-template-columns: auto 1fr;
    align-items: start;
  }

  .cms-team__photo {
    grid-column: 1;
    grid-row: 1 / span 3;
    width: 11rem;
    max-width: none;
    margin: 0 1.75rem 0 0;
  }

  .cms-team__name {
    grid-column: 2;
    grid-row: 1;
  }

  .cms-team__role {
    grid-column: 2;
    grid-row: 2;
  }

  .cms-team__bio {
    grid-column: 2;
    grid-row: 3;
  }
}

/* --------------------------------------------------------- opening hours -- */

.cms-opening-hours__days {
  list-style: none;
  margin: 0;
  padding: 0;
}

.cms-opening-hours__day {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.5rem 0.6rem;
  border-bottom: 1px solid var(--c-line);
  border-radius: var(--r-soft);
}

.cms-opening-hours__day:last-child {
  border-bottom: 0;
}

.cms-opening-hours__day.is-today {
  background: var(--c-accent-soft);
  border-bottom-color: transparent;
}

.cms-opening-hours__day-name {
  font-family: var(--font-sans);
  font-weight: 700;
  font-size: 0.95rem;
}

/* The abbreviation is a narrow-screen convenience; the full name carries the
   meaning, so only one of the two ever shows. */
.cms-opening-hours__day-abbr {
  display: none;
}

.cms-opening-hours__times {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.cms-opening-hours__slot {
  display: block;
}

.cms-opening-hours__note {
  display: block;
  font-size: 0.85rem;
  font-style: italic;
  color: var(--c-muted);
}

.cms-opening-hours__empty {
  margin: 0;
  color: var(--c-muted);
}

/* --------------------------------------------------------------- contact -- */

.cms-contact__group {
  margin-bottom: 1.25rem;
}

.cms-contact__group:last-of-type {
  margin-bottom: 0;
}

.cms-contact__group-title {
  font-family: var(--font-sans);
  font-weight: 700;
  font-size: 0.78rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--c-muted);
  margin: 0 0 0.35rem;
}

.cms-contact__list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.cms-contact__item {
  padding: 0.15rem 0;
}

.cms-contact__primary {
  color: var(--c-accent-deep);
}

.cms-contact__privacy,
.cms-contact__empty {
  margin: 1rem 0 0;
  font-size: 0.9rem;
  color: var(--c-muted);
}

.cms-contact__form {
  margin-top: 1.5rem;
  border-top: 1px solid var(--c-line);
  padding-top: 1.5rem;
}

.cms-contact__field {
  margin-bottom: 1rem;
}

.cms-contact__field label {
  display: block;
  font-family: var(--font-sans);
  font-weight: 700;
  font-size: 0.85rem;
  margin-bottom: 0.3rem;
}

.cms-contact__field input,
.cms-contact__field textarea,
.cms-contact__field select {
  width: 100%;
  min-height: 2.75rem;
  padding: 0.55rem 0.75rem;
  font: inherit;
  font-size: 1rem;
  color: var(--c-ink);
  background: #fff;
  border: 1px solid var(--c-sand-deep);
  border-radius: var(--r-soft);
}

.cms-contact__field textarea {
  min-height: 8rem;
}

.cms-contact__field input:focus-visible,
.cms-contact__field textarea:focus-visible,
.cms-contact__field select:focus-visible {
  border-color: var(--c-accent-dark);
}

.cms-contact__field--consent,
.cms-contact__field--privacy_consent {
  display: flex;
  align-items: flex-start;
  gap: 0.6rem;
}

/* The browser's own 13 px box is far too small to hit — and this one is the
   consent gate, the single control the visitor must not miss. The block emits
   the label before the input, so the box is pulled in front of its sentence
   rather than trailing it (DOM order, and with it the label binding, stays). */
.cms-contact__field--consent input,
.cms-contact__field--privacy_consent input {
  order: -1;
  width: 1.35rem;
  height: 1.35rem;
  min-height: 0;
  flex: none;
  margin-top: 0.2rem;
  accent-color: var(--c-accent-dark);
}

/* The label is bound to the box, so the whole line is the target. */
.cms-contact__field--consent label,
.cms-contact__field--privacy_consent label {
  min-height: 2.75rem;
  display: flex;
  align-items: center;
  font-weight: 400;
  font-family: var(--font-serif);
  font-size: 0.95rem;
}

.cms-contact__hint {
  display: block;
  margin-top: 0.25rem;
  font-size: 0.85rem;
  color: var(--c-muted);
}

.cms-contact__field ul.errorlist,
.cms-contact__error {
  margin: 0.4rem 0 0;
  padding: 0.5rem 0.75rem;
  list-style: none;
  font-size: 0.9rem;
  color: #7d2b20;
  background: #fbeeec;
  border-left: 3px solid #a8392c;
  border-radius: var(--r-soft);
}

.cms-contact__sent {
  padding: 1rem 1.25rem;
  background: var(--c-accent-soft);
  border-left: 3px solid var(--c-accent-deep);
  border-radius: var(--r-soft);
}

/* -------------------------------------------------------------- services -- */

/* One group fills the column; several sit side by side on a wide screen, the
   way the source splits its list in two. */
.cms-services {
  display: grid;
  gap: 0 3rem;
  grid-template-columns: 1fr;
}

.cms-services__title {
  grid-column: 1 / -1;
}

.cms-services__category {
  font-family: var(--font-sans);
  font-weight: 700;
  font-size: 0.95rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--c-muted);
  margin: 0 0 0.5rem;
}

.cms-services__list,
.cms-patient-info__list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.cms-services__item,
.cms-patient-info__item {
  padding: 0.9rem 0;
  border-bottom: 1px solid var(--c-line);
}

.cms-services__item:last-child,
.cms-patient-info__item:last-child {
  border-bottom: 0;
}

/* The small triangle echoes the source's expandable rows without pretending to
   be one — the description is always visible here. */
.cms-services__name,
.cms-patient-info__name {
  position: relative;
  margin: 0;
  padding-left: 1.4rem;
  font-family: var(--font-sans);
  font-weight: 700;
  font-size: 1.05rem;
  color: var(--c-accent-deep);
}

.cms-services__name::before,
.cms-patient-info__name::before {
  content: "";
  position: absolute;
  left: 0.15rem;
  top: 0.5em;
  border: 0.3rem solid transparent;
  border-left-color: var(--c-accent-deep);
}

.cms-services__description,
.cms-patient-info__body {
  padding-left: 1.4rem;
  margin-top: 0.35rem;
  color: var(--c-muted);
}

.cms-services__description p,
.cms-patient-info__body p {
  margin: 0 0 0.6rem;
}

.cms-services__description p:last-child,
.cms-patient-info__body p:last-child {
  margin-bottom: 0;
}

.cms-services__badge {
  display: inline-block;
  margin-left: 0.4rem;
  padding: 0.1rem 0.55rem;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--c-accent-deep);
  background: var(--c-sand);
  border-radius: 999px;
  vertical-align: 0.1em;
}

/* Two columns only once there is a second group to fill the other one. auto-fit
   cannot collapse the empty track by itself here — the title spans both, so the
   track is never empty — and a practice with a single, uncategorised list ended
   up with its services in the left half of the sheet under a full-width rule. */
@media (min-width: 52rem) {
  .cms-services:has(.cms-services__group + .cms-services__group) {
    grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr));
  }
}

/* ---------------------------------------------------------- patient info -- */

.cms-patient-info__download {
  margin-top: 0.75rem;
  margin-left: 1.4rem;
  padding: 0.45rem 1.1rem;
  font-size: 0.85rem;
}

/* --------------------------------------------------------------- gallery -- */

.cms-gallery__grid {
  display: grid;
  gap: 0.85rem;
  grid-template-columns: repeat(auto-fill, minmax(13rem, 1fr));
}

.cms-gallery__item {
  margin: 0;
}

.cms-gallery__link {
  display: block;
  border-radius: var(--r-soft);
  overflow: hidden;
}

.cms-gallery__image {
  display: block;
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  transition: transform 0.4s ease;
}

.cms-gallery__link:hover .cms-gallery__image,
.cms-gallery__link:focus-visible .cms-gallery__image {
  transform: scale(1.04);
}

.cms-gallery__caption {
  margin-top: 0.4rem;
  font-size: 0.88rem;
  color: var(--c-muted);
}

/* ---------------------------------------------------------- quote banner -- */

/* Breaks out of the content sheet into a full-width sand band. */
.cms-quote-banner {
  position: relative;
  margin-inline: calc(50% - 50vw);
  padding: 3rem 1.5rem;
  background-color: var(--c-sand);
  background-size: cover;
  background-position: center;
  text-align: center;
}

.cms-quote-banner--photo::before {
  content: "";
  position: absolute;
  inset: 0;
  background: rgba(38, 28, 16, 0.58);
}

.cms-quote-banner__inner {
  position: relative;
  max-width: 46rem;
  margin-inline: auto;
}

.cms-quote-banner__quote {
  margin: 0;
  font-family: var(--font-serif);
  font-style: italic;
  font-size: clamp(1.2rem, 3.4vw, 1.7rem);
  line-height: 1.45;
  color: var(--c-ink);
}

.cms-quote-banner__attribution {
  margin: 1rem 0 0;
  font-family: var(--font-sans);
  font-size: 0.85rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--c-muted);
}

.cms-quote-banner--photo .cms-quote-banner__quote,
.cms-quote-banner--photo .cms-quote-banner__attribution {
  color: #fff;
}

/* ------------------------------------------------------------------- map -- */

/* The whole map — picture plus the address under it — is one link to
   OpenStreetMap, framed like a gallery tile rather than dressed as a button. */
.cms-map__link {
  display: block;
  text-decoration: none;
}

.cms-map__image {
  display: block;
  width: 100%;
  border-radius: var(--r-soft);
}

.cms-map__caption {
  display: block;
  margin: 0.6rem 0 0;
  font-size: 0.9rem;
  color: var(--c-muted);
}

.cms-map__link:hover .cms-map__caption,
.cms-map__link:focus-visible .cms-map__caption {
  color: var(--c-accent-deep);
  text-decoration: underline;
}

.cms-map__directions {
  margin-top: 1rem;
}

.cms-map__directions p {
  margin: 0 0 0.6rem;
}

.cms-map__directions p:last-child {
  margin-bottom: 0;
}

/* --------------------------------------------------------- announcements -- */

.cms-announcements__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 1rem;
}

.cms-announcements__item {
  --a-tone: var(--c-muted);
  padding: 1rem 1.25rem;
  background: color-mix(in srgb, var(--a-tone) 9%, white);
  border: 1px solid color-mix(in srgb, var(--a-tone) 26%, white);
  border-left: 4px solid var(--a-tone);
  border-radius: var(--r-soft);
}

/* The tone is also the colour of the date line, so each value has to clear AA
   on its own 9 % wash: #a4700d only reached 3.84 : 1, #8d5f0b reaches 4.94. */
.cms-announcements__item--info { --a-tone: var(--c-accent-deep); }
.cms-announcements__item--important { --a-tone: #8d5f0b; }
.cms-announcements__item--alert { --a-tone: #a8392c; }
.cms-announcements__item--good { --a-tone: #3f7048; }

.cms-announcements__headline {
  font-size: 1.02rem;
  margin: 0 0 0.2rem;
  color: var(--c-ink);
}

.cms-announcements__period {
  margin: 0 0 0.4rem;
  font-family: var(--font-sans);
  font-size: 0.82rem;
  color: var(--a-tone);
}

.cms-announcements__body p {
  margin: 0 0 0.5rem;
}

.cms-announcements__body p:last-child {
  margin-bottom: 0;
}

.cms-announcements__close {
  display: none;
}

/* --------------------------------------------- prescription / portal CTA -- */

.cms-prescription-link__intro p,
.cms-appointments-link__intro p,
.cms-patientportal-link__intro p {
  margin: 0 0 0.75rem;
}

/* The embedded prescription form reuses the contact-form look so both public
   forms on a page read as one family. */
.cms-prescription-link form {
  margin-top: 1.25rem;
}

.cms-prescription-link label {
  display: block;
  font-family: var(--font-sans);
  font-weight: 700;
  font-size: 0.85rem;
  margin-bottom: 0.3rem;
}

.cms-prescription-link__field {
  margin-bottom: 1rem;
}

.cms-prescription-link input:not([type="checkbox"]):not([type="radio"]),
.cms-prescription-link textarea,
.cms-prescription-link select {
  width: 100%;
  min-height: 2.75rem;
  padding: 0.55rem 0.75rem;
  font: inherit;
  font-size: 1rem;
  color: var(--c-ink);
  background: #fff;
  border: 1px solid var(--c-sand-deep);
  border-radius: var(--r-soft);
}

.cms-prescription-link input:focus-visible,
.cms-prescription-link textarea:focus-visible,
.cms-prescription-link select:focus-visible {
  border-color: var(--c-accent-dark);
}

/* The consent gate, laid out and sized like the contact form's. */
.cms-prescription-link__field--consent {
  display: flex;
  align-items: flex-start;
  gap: 0.6rem;
}

.cms-prescription-link__field--consent input {
  order: -1;
  width: 1.35rem;
  height: 1.35rem;
  flex: none;
  margin-top: 0.2rem;
  accent-color: var(--c-accent-dark);
}

.cms-prescription-link__field--consent label {
  min-height: 2.75rem;
  display: flex;
  align-items: center;
  margin-bottom: 0;
  font-family: var(--font-serif);
  font-weight: 400;
  font-size: 0.95rem;
}

.cms-prescription-link__hint {
  display: block;
  margin-top: 0.25rem;
  font-size: 0.85rem;
  color: var(--c-muted);
}

.cms-prescription-link ul.errorlist,
.cms-prescription-link__error {
  margin: 0.4rem 0 0;
  padding: 0.5rem 0.75rem;
  list-style: none;
  font-size: 0.9rem;
  color: #7d2b20;
  background: #fbeeec;
  border-left: 3px solid #a8392c;
  border-radius: var(--r-soft);
}

.cms-prescription-link button[type="submit"] {
  display: inline-block;
  margin-top: 0.5rem;
  padding: 0.65rem 1.5rem;
  min-height: 2.75rem;
  font-family: var(--font-sans);
  font-weight: 700;
  font-size: 0.95rem;
  color: #fff;
  background: var(--c-accent-dark);
  border: 1px solid transparent;
  border-radius: 999px;
  cursor: pointer;
}

.cms-prescription-link button[type="submit"]:hover {
  background: var(--c-accent-deep);
}

.cms-prescription-link button[type="submit"][disabled] {
  background: var(--c-sand-deep);
  color: var(--c-muted);
  cursor: not-allowed;
}

/* ---------------------------------------------------------------- footer -- */

.footer {
  margin-top: 0;
  background: var(--c-sand);
  border-top: 1px solid var(--c-sand-deep);
  font-size: 0.95rem;
}

.footer__inner {
  max-width: var(--w-page);
  margin-inline: auto;
  padding: 2.5rem 1.25rem 1.5rem;
  display: grid;
  gap: 2rem;
}

.footer__logo {
  width: 5rem;
  height: auto;
  margin-bottom: 1rem;
}

.footer__heading {
  font-family: var(--font-sans);
  font-weight: 700;
  font-size: 1rem;
  color: var(--c-accent-deep);
  margin: 0 0 0.75rem;
}

.footer__contact {
  font-style: normal;
}

.footer__line {
  margin: 0 0 0.5rem;
}

.footer__label {
  font-family: var(--font-sans);
  font-weight: 700;
  font-size: 0.85rem;
}

.footer a {
  color: var(--c-accent-deep);
  text-decoration: none;
}

.footer a:hover,
.footer a:focus-visible {
  text-decoration: underline;
}

.footer__hours {
  list-style: none;
  margin: 0;
  padding: 0;
}

.footer__hours-row {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.15rem 0;
}

.footer__day {
  font-family: var(--font-sans);
  font-weight: 700;
  font-size: 0.85rem;
}

.footer__slots {
  font-variant-numeric: tabular-nums;
  text-align: right;
}

.footer__slots span {
  display: block;
}

.footer__nav {
  list-style: none;
  margin: 0;
  padding: 0;
}

/* The source marks its footer links with a small chevron. */
.footer__nav li {
  padding: 0.2rem 0;
}

.footer__nav a::before {
  content: "›";
  margin-right: 0.4rem;
  color: var(--c-accent-dark);
}

.footer__bottom {
  max-width: var(--w-page);
  margin: 0 auto;
  padding: 1rem 1.25rem 2rem;
  font-size: 0.85rem;
  color: var(--c-muted);
}

.footer__bottom a {
  color: var(--c-muted);
}

@media (min-width: 48rem) {
  .footer__inner {
    grid-template-columns: 1.2fr 1fr 1fr;
    gap: 3rem;
    padding: 3rem 1.25rem 1.5rem;
  }
}

/* -------------------------------------------------------------- narrowest -- */

/* Below ~20rem a full weekday name and its times no longer share a row; swap
   in the abbreviation the block already provides. */
@media (max-width: 20rem) {
  .cms-opening-hours__day-name {
    display: none;
  }

  .cms-opening-hours__day-abbr {
    display: inline;
    font-family: var(--font-sans);
    font-weight: 700;
    font-size: 0.95rem;
  }
}
