:root {
  --bf-color-bg: #ffffff;
  --bf-color-text: #1f2430;
  --bf-color-muted: #5b6270;
  --bf-color-primary: #1a5c4a;
  --bf-color-primary-contrast: #ffffff;
  --bf-color-border: #e2e5ea;
  /* O-70: tinted from the Forest primary, not a stock cool grey (design round 1, R1-08). */
  --bf-color-surface: #eef5f1;
  --bf-max-width: 64rem;
  --bf-space: 1.25rem;
  --bf-font-family: system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  /* O-73: headings in a warm serif of their own (the Modern typography keeps them in its sans). */
  --bf-heading-font-family: 'Fraunces', Georgia, serif;
  --bf-brand-size: 1.25rem;
  --bf-brand-logo-height: 2.5rem;
  /* O-61: the longest comfortable line of body text (about 65-75 characters). */
  --bf-measure: 68ch;
  /* O-73: the top band's pattern - scattered dots and rings, drawn as a mask (only its shape counts). */
  --bf-pattern: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='36' height='36'%3E%3Ccircle cx='6' cy='7' r='2'/%3E%3Ccircle cx='24' cy='25' r='2'/%3E%3Ccircle cx='27' cy='8' r='3.5' fill='none' stroke='%23000' stroke-width='1.5'/%3E%3Ccircle cx='9' cy='27' r='1.2'/%3E%3C/svg%3E");
  /* O-75: how strongly the pattern shows. The palette-contrast check measures text over its marks at this strength. */
  --bf-pattern-opacity: 0.09;
}

/* O-73: Fraunces, bundled with the theme rather than loaded from a third party - Google Fonts'
   v38, latin subset, weight 600 only. SIL Open Font License 1.1: fonts/OFL.txt. */
@font-face {
  font-family: 'Fraunces';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('fonts/fraunces-latin-600.woff2') format('woff2');
}

* {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  font-family: var(--bf-font-family);
  color: var(--bf-color-text);
  background: var(--bf-color-bg);
  line-height: 1.5;
}

h1,
h2,
h3 {
  font-family: var(--bf-heading-font-family);
  font-weight: 600;
  line-height: 1.2;
  margin: 0 0 0.5em;
}

p {
  margin: 0 0 1em;
}

/* Prose only: a list item with its own class is a component (a service card), not a line of text. */
main p,
main li:not([class]),
main dt,
main dd,
main blockquote,
main address,
main figcaption {
  max-width: var(--bf-measure);
}

a {
  color: var(--bf-color-primary);
}

.wrap {
  max-width: var(--bf-max-width);
  margin: 0 auto;
  padding: 0 var(--bf-space);
}

/* O-65: a block's own .wrap inside the page body's .wrap adds no second inset, so every block's
   content starts on the same left edge as the brand, the page title and the footer. The full-bleed
   hero breaks out of the page body, so it keeps its own (see .block-hero > .wrap). */
.wrap .wrap {
  max-width: none;
  padding-left: 0;
  padding-right: 0;
}

.skip-link {
  position: absolute;
  left: -999px;
  top: 0;
  background: var(--bf-color-primary);
  color: var(--bf-color-primary-contrast);
  padding: 0.5em 1em;
  z-index: 100;
}

.skip-link:focus {
  left: 0;
}

/* O-70: the palette's primary as a structural accent, not only on links and buttons. */
.site-header {
  border-top: 4px solid var(--bf-color-primary);
  border-bottom: 1px solid var(--bf-color-border);
}

.site-header-inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--bf-space);
  padding-top: var(--bf-space);
  padding-bottom: var(--bf-space);
}

.site-brand {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  max-width: 100%;
  min-height: 44px;
  font-size: var(--bf-brand-size);
  font-weight: 700;
  line-height: 1.2;
  text-decoration: none;
  color: var(--bf-color-text);
}

.site-brand-name {
  text-wrap: balance;
}

.site-brand-logo {
  display: block;
  min-width: 0;
  max-width: 100%;
  max-height: var(--bf-brand-logo-height);
  width: auto;
  height: auto;
}

.site-nav {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1.25rem;
}

.site-nav ul {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 1.25rem;
  margin: 0;
  padding: 0;
}

.site-nav a {
  text-decoration: none;
  color: var(--bf-color-text);
}

.site-nav a:hover,
.site-nav a:focus {
  color: var(--bf-color-primary);
}

/* O-148 (Umbraco's U-138): the "More" disclosure a long menu folds its extra pages into is drawn from
   the theme's tokens - no native triangle (list-style and the WebKit marker are off), a 44px tap
   target, and a caret drawn in CSS that turns when it opens. Its pages stack under it in the header, so
   they are never detached from it or off screen however the links wrap. */
.site-nav summary {
  display: flex;
  align-items: center;
  gap: 0.4em;
  min-height: 44px;
  margin-inline: -0.5em;
  padding-inline: 0.5em;
  border-radius: 0.35em;
  list-style: none;
  color: var(--bf-color-text);
  cursor: pointer;
}

.site-nav summary::-webkit-details-marker {
  display: none;
}

.site-nav summary::after {
  content: '';
  width: 0.45em;
  height: 0.45em;
  border-right: 2px solid currentcolor;
  border-bottom: 2px solid currentcolor;
  transform: translateY(-0.15em) rotate(45deg);
}

.site-nav details[open] > summary::after {
  transform: translateY(0.1em) rotate(-135deg);
}

.site-nav summary:is(:hover, :focus-visible) {
  color: var(--bf-color-primary);
}

.site-nav .menu-overflow-items {
  flex-direction: column;
  gap: 0;
  padding-left: 1rem;
}

.site-nav .menu-overflow-items a {
  display: flex;
  align-items: center;
  min-height: 44px;
}

.page-header {
  background: var(--bf-color-surface);
  padding: calc(var(--bf-space) * 1.5) 0;
  margin-bottom: var(--bf-space);
}

.page-header h1 {
  margin: 0;
}

/* O-73 (design round 2, R2-03): the top band - a page's title band, or its hero - carries a quiet
   pattern in the palette's own primary, so it reads as made for this business rather than a flat
   tint. The pattern is a mask over the primary, so it follows whichever palette the owner picked. */
.page-header,
.block-hero {
  position: relative;
  isolation: isolate;
}

.page-header::before,
.block-hero::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--bf-color-primary);
  opacity: var(--bf-pattern-opacity);
  pointer-events: none;
  -webkit-mask-image: var(--bf-pattern);
  mask-image: var(--bf-pattern);
  -webkit-mask-size: 36px 36px;
  mask-size: 36px 36px;
}

.block {
  padding: calc(var(--bf-space) * 1.25) 0;
}

.block-hero {
  /* O-47 (pre-import issue 4, archived commit 540e878; parity with Umbraco's U-49): full-bleed - breaks out of the
     constraining .wrap the rest of a page's blocks sit in so the hero reads as its own band,
     matching Main's own redesigned hero, while its own text stays centered and readable via the
     unchanged inner .wrap. Only uses the existing --bf-color-* tokens, since every tenant picks
     its own palette in the wizard (O-41) - this has to look right under any of them. */
  width: 100vw;
  margin-left: calc(50% - 50vw);
  margin-right: calc(50% - 50vw);
  text-align: center;
  background: linear-gradient(180deg, var(--bf-color-surface), var(--bf-color-bg));
  padding: calc(var(--bf-space) * 2) 0;
}

.block-hero h1 {
  font-size: 2.25rem;
  line-height: 1.15;
  letter-spacing: -0.01em;
}

.block-hero > .wrap {
  max-width: var(--bf-max-width);
  padding-left: var(--bf-space);
  padding-right: var(--bf-space);
}

/* O-77: a hero's image follows its text, so the heading and call to action lead the first screen
   (O-76's generated images are 3:2 - above the heading, one filled a desktop screen). */
.block-hero-image {
  display: block;
  max-width: 100%;
  height: auto;
  border-radius: 0.5rem;
  margin: var(--bf-space) auto 0;
}

/* O-77: from tablet width a hero with an image sits beside it - text on the brand edge, image to
   the right - rather than stacking. */
@media (min-width: 56rem) {
  .block-hero-with-image > .wrap {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: calc(var(--bf-space) * 2);
    align-items: center;
    text-align: left;
  }

  .block-hero-with-image p {
    margin-left: 0;
    margin-right: 0;
  }

  .block-hero-with-image .block-hero-image {
    margin: 0;
  }
}

/* O-68: every paragraph in the centred hero is centred as a box too, not only its text - the prose
   measure (O-61) otherwise leaves a narrower paragraph pinned to the hero's left edge. */
.block-hero p {
  margin-left: auto;
  margin-right: auto;
}

.block-hero-subheading {
  color: var(--bf-color-muted);
  font-size: 1.1rem;
  max-width: 40rem;
}

.button {
  display: inline-block;
  background: var(--bf-color-primary);
  color: var(--bf-color-primary-contrast);
  text-decoration: none;
  padding: 0.65em 1.4em;
  border: 0;
  border-radius: 0.35em;
  font: inherit;
  font-weight: 600;
  cursor: pointer;
  box-shadow: 0 6px 16px -8px var(--bf-color-primary);
  transition:
    transform 0.15s ease,
    box-shadow 0.15s ease,
    opacity 0.15s ease;
}

.button:hover,
.button:focus {
  opacity: 0.9;
  transform: translateY(-1px);
  box-shadow: 0 10px 20px -8px var(--bf-color-primary);
}

@media (prefers-reduced-motion: reduce) {
  .button {
    transition: none;
  }
  .button:hover,
  .button:focus {
    transform: none;
  }
}

.block-cta {
  background: var(--bf-color-surface);
  text-align: center;
  border: 1px solid var(--bf-color-border);
  border-radius: 0.75rem;
  padding: calc(var(--bf-space) * 1.5);
}

.block-cta p {
  max-width: 32rem;
  margin-left: auto;
  margin-right: auto;
  color: var(--bf-color-muted);
}

.block-service-list h2 {
  text-align: center;
}

.service-list,
.faq-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--bf-space);
}

.service-list {
  grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
}

.service-list-item {
  border: 1px solid var(--bf-color-border);
  border-radius: 0.5rem;
  padding: var(--bf-space);
}

.service-list-item h3 {
  margin-top: 0;
}

.faq-list {
  max-width: 40rem;
}

.faq-list dt {
  font-weight: 700;
  margin-top: 1em;
}

.faq-list dd {
  margin: 0.25em 0 0;
  color: var(--bf-color-muted);
}

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

.contact-details li {
  margin-bottom: 0.5em;
}

.hours-table {
  border-collapse: collapse;
  width: 100%;
  max-width: var(--bf-measure);
}

.hours-table th,
.hours-table td {
  text-align: left;
  padding: 0.4em 0.75em 0.4em 0;
  border-bottom: 1px solid var(--bf-color-border);
}

/* O-66: an action link (Get directions) - a 44px target that reads as a link, not a button. */
.link-action {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  font-weight: 600;
}

.block-location-directions {
  margin-top: 0.5em;
}

/* O-78: in the map's place, when the address couldn't be placed: how to ask the way. */
.block-location-ask {
  background: var(--bf-color-surface);
  border-radius: 0.5rem;
  padding: var(--bf-space);
  margin-top: var(--bf-space);
}

.block-hero-location {
  max-width: var(--bf-measure);
  font-weight: 600;
}

.block-location-map {
  display: block;
  width: 100%;
  max-width: var(--bf-measure);
  aspect-ratio: 4 / 3;
  border: 1px solid var(--bf-color-border);
  border-radius: 0.5rem;
  margin-top: var(--bf-space);
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
}

.site-footer {
  border-top: 1px solid var(--bf-color-border);
  margin-top: calc(var(--bf-space) * 2);
  padding: var(--bf-space) 0;
  color: var(--bf-color-muted);
}

.site-footer-credit {
  margin: 0;
  font-size: 0.9rem;
}

/* O-64: footer links are small print ("Request editor access"), not calls to action - the footer's
   own muted colour, and each kept on one line so the credit wraps between items, not inside one. */
.site-footer a {
  color: inherit;
  white-space: nowrap;
}

/* O-67: at desktop width the content fills the page instead of hugging a narrow left column -
   Location and Hours share a row where they're neighbours (Home), the contact details sit beside
   the contact form, and a location's address sits beside its map. */
@media (min-width: 48rem) {
  .flow {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: calc(var(--bf-space) * 2);
  }

  .flow > * {
    grid-column: 1 / -1;
  }

  .flow > .block-location:has(+ .block-hours),
  .flow > .block-location:has(+ .block-hours) + .block-hours {
    grid-column: auto;
  }

  .block-contact-details > .wrap,
  .block-location:has(.block-location-map) > .wrap,
  .block-location:has(.block-location-ask) > .wrap {
    display: grid;
    grid-template-columns: minmax(0, 2fr) minmax(0, 3fr);
    column-gap: calc(var(--bf-space) * 2);
    align-items: start;
  }

  .block-contact-details > .wrap > h2 {
    grid-column: 1 / -1;
  }

  .block-contact-details .contact-form {
    margin-top: 0;
  }

  .block-location:has(.block-location-map) .block-location-directions {
    display: contents;
  }

  .block-location:has(.block-location-map) .block-location-map,
  .block-location-ask {
    grid-column: 2;
    grid-row: 1 / span 3;
    max-width: none;
    margin-top: 0;
  }
}

/* O-62: below 40rem the nav collapses behind a menu button. It only does once the head script has
   marked the page .bf-js, so without script the nav simply stays visible and no dead button shows. */
.site-nav-toggle {
  display: none;
}

@media (max-width: 40rem) {
  /* The brand and the menu button share the first row; a long name wraps rather than pushing
     the button onto a row of its own. */
  .bf-js .site-brand {
    flex: 1 1 0;
    min-width: 0;
  }

  .bf-js .site-nav-toggle {
    flex: none;
    display: inline-flex;
    align-items: center;
    min-width: 44px;
    min-height: 44px;
    gap: 0.5em;
    padding: 0 1em;
    border: 1px solid var(--bf-color-border);
    border-radius: 0.35em;
    background: var(--bf-color-bg);
    color: var(--bf-color-text);
    font: inherit;
    cursor: pointer;
  }

  /* The icon is drawn in the button's own text colour and carries no name: the word beside it is the button's. */
  .site-nav-toggle-icon {
    flex: none;
  }

  .site-nav {
    flex-basis: 100%;
  }

  .bf-js .site-nav:not(.is-open) {
    display: none;
  }

  .site-nav ul {
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    width: 100%;
  }

  .site-nav a {
    display: flex;
    align-items: center;
    min-height: 44px;
  }
}

.contact-form-honeypot {
  position: absolute;
  left: -9999px;
  top: -9999px;
}

/* O-137: stacked under the details on a phone, the form keeps a line of room from them (Umbraco's
   U-79 form does); the side-by-side layout below resets it. */
.contact-form {
  margin-top: 1.5rem;
}

.contact-form .field {
  margin-bottom: 1em;
}

.contact-form label {
  display: block;
  margin-bottom: 0.25em;
  font-weight: 600;
}

.contact-form input,
.contact-form textarea {
  width: 100%;
  max-width: 30rem;
  min-height: 44px;
  padding: 0.5em;
  border: 1px solid var(--bf-color-border);
  border-radius: 0.25em;
  font: inherit;
}

.contact-form-status {
  padding: 0.75em 1em;
  border-radius: 0.25em;
  margin-bottom: 1em;
}

.contact-form-status-success {
  background: #e6f4ea;
  color: #1a5c2a;
}

.contact-form-status-error {
  background: #fbe8e6;
  color: #8a1f14;
}

/* O-133 / U-125: the slim notice the people who run a site with no plan see above its header. */
.no-plan-notice {
  background: var(--bf-color-surface);
  border-bottom: 1px solid var(--bf-color-border);
  color: var(--bf-color-text);
  font-size: 0.9rem;
  text-align: center;
  padding: 0.5rem 1rem;
}

.no-plan-notice p {
  margin: 0;
}

.no-plan-notice a {
  color: var(--bf-color-text);
  font-weight: 600;
  text-decoration: underline;
}
