/* ============================================================
     DESIGN TOKENS
     ============================================================ */
:root {
  --ink: #171B24;
  /* near-black charcoal navy — text, dark sections */
  --paper: #EFF0E9;
  /* pale warm-grey paper — light section backgrounds */
  --paper-2: #E4E5DB;
  /* slightly deeper paper, for cards/alt rows */
  --accent: #B9862B;
  /* antique gold — links, highlights */
  --accent-deep: #26463D;
  /* deep pine — secondary accent, active states */
  --line: #D2CDBB;
  /* hairline rule colour on paper */
  --line-dark: #333A47;
  /* hairline rule colour on ink */

  --font-display: Georgia, "Iowan Old Style", "Palatino Linotype", Palatino, serif;
  --font-body: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-mono: "Courier New", Courier, monospace;

  --nav-h: 4rem;
  --maxw: 68rem;

  /* How many service cards sit on a row at full width. */
  --cards-per-row: 3;

  /* Gallery: how many images are visible at once, and the space
       between them. Overridable per gallery — see the note above the
       gallery wrappers. */
  --per-view: 1.15;
  --slide-gap: 1rem;
}

/* ============================================================
     RESET / BASE
     ============================================================ */
*,
*::before,
*::after {
  box-sizing: border-box;
}

img,
svg,
video,
table {
  max-width: 100%;
}

html {
  scroll-behavior: smooth;
  scroll-padding-top: var(--nav-h);
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-body);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

h1,
h2,
h3 {
  font-family: var(--font-display);
  line-height: 1.15;
  margin: 0 0 0.5em 0;
  font-weight: 400;
}

p {
  margin: 0 0 1em 0;
}

a {
  color: inherit;
}

img {
  max-width: 100%;
  display: block;
}

ul {
  margin: 0;
  padding: 0;
}

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

.skip-link {
  position: absolute;
  left: 1rem;
  top: -3rem;
  background: var(--ink);
  color: var(--paper);
  padding: .6rem 1rem;
  z-index: 200;
  transition: top .2s ease;
  text-decoration: none;
  font-size: .9rem;
}

.skip-link:focus {
  top: 1rem;
}

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

.container {
  max-width: var(--maxw);
  margin-inline: auto;
  padding-inline: 1.5rem;
}

/* ============================================================
     NAVIGATION — sticky, single row on desktop, collapsible on mobile
     Implemented with a checkbox "hack": no JavaScript required.
     ============================================================ */
.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: var(--ink);
  color: var(--paper);
  border-bottom: 1px solid var(--line-dark);
}

.nav-bar {
  max-width: var(--maxw);
  margin-inline: auto;
  padding-inline: 1.5rem;
  height: var(--nav-h);
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.brand {
  font-family: var(--font-display);
  font-size: 1.25rem;
  letter-spacing: .03em;
  text-decoration: none;
  color: var(--paper);
  white-space: nowrap;
}

.brand em {
  font-style: normal;
  color: var(--accent);
}

/* Hidden checkbox driving the mobile menu state */
.menu-toggle {
  position: absolute;
  opacity: 0;
  pointer-events: none;
  /* Explicit size so no future rule can stretch it: the checkbox is
       only a state holder for the CSS menu, never something to look at. */
  width: 1px;
  height: 1px;
}

.menu-label {
  display: none;
  /* shown only on small screens, see media query */
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 2.25rem;
  height: 2.25rem;
  cursor: pointer;
  border: 1px solid var(--line-dark);
}

.menu-label span {
  display: block;
  height: 2px;
  margin-inline: 6px;
  background: var(--paper);
  transition: transform .2s ease, opacity .2s ease;
}

.site-nav ul {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.75rem;
}

.site-nav a {
  display: inline-block;
  padding: .4rem .1rem;
  text-decoration: none;
  font-size: .95rem;
  letter-spacing: .02em;
  color: var(--paper);
  border-bottom: 2px solid transparent;
  transition: border-color .15s ease, color .15s ease;
}

.site-nav a:hover,
.site-nav a:focus-visible {
  border-color: var(--accent);
  color: var(--accent);
}

/* ============================================================
     MOBILE NAV BEHAVIOUR (below 46em / ~736px)
     ============================================================ */
@media (max-width: 46em) {
  .menu-label {
    display: flex;
  }

  .site-nav {
    position: absolute;
    inset-inline: 0;
    top: var(--nav-h);
    background: var(--ink);
    border-bottom: 1px solid var(--line-dark);
    max-height: 0;
    overflow: hidden;
    transition: max-height .25s ease;
  }

  .site-nav ul {
    flex-direction: column;
    gap: 0;
    padding: 0.5rem 1.5rem 1rem;
  }

  .site-nav a {
    display: block;
    padding: .75rem 0;
    border-bottom: 1px solid var(--line-dark);
  }

  /* Checked state reveals the menu — pure CSS, no script */
  .menu-toggle:checked~.site-nav {
    max-height: 24rem;
  }

  .menu-toggle:checked~.menu-label span:nth-child(1) {
    transform: translateY(7px) rotate(45deg);
  }

  .menu-toggle:checked~.menu-label span:nth-child(2) {
    opacity: 0;
  }

  .menu-toggle:checked~.menu-label span:nth-child(3) {
    transform: translateY(-7px) rotate(-45deg);
  }
}

/* ============================================================
     SECTIONS — shared rhythm
     ============================================================ */
section {
  padding: 5rem 0;
  border-bottom: 1px solid var(--line);
}

section:last-of-type {
  border-bottom: none;
}

.eyebrow {
  font-family: var(--font-mono);
  font-size: .78rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--accent-deep);
  margin-bottom: .75rem;
  display: block;
}

/* ---------- Hero / Home ---------- */
#home {
  /* min-height: calc(100svh - var(--nav-h)); */
  display: flex;
  align-items: center;
  background:
    linear-gradient(180deg, var(--ink) 0%, var(--ink) 60%, var(--paper) 60%);
  color: var(--paper);
  border-bottom: none;
  padding-bottom: 0;
}

#home .container {
  padding-block: 2rem;
  position: relative;
  top: .35rem;
}

#home h1 {
  font-size: clamp(2.2rem, 6vw, 3.75rem);
  max-width: 20ch;
}

#home .lede {
  max-width: 46ch;
  font-size: 1.1rem;
  color: var(--paper-2);
}

#home .eyebrow {
  color: var(--accent);
}

.cta {
  display: inline-block;
  margin-top: 1rem;
  padding: .8rem 1.5rem;
  background: var(--accent);
  color: var(--ink);
  text-decoration: none;
  font-weight: 600;
  letter-spacing: .02em;
}

.cta:hover,
.cta:focus-visible {
  background: var(--paper);
}

/* ---------- About ---------- */
.about-grid {
  display: grid;
  gap: 2rem;
  grid-template-columns: 1fr;
}

@media (min-width: 46em) {
  .about-grid {
    grid-template-columns: 1fr 1.4fr;
    align-items: start;
  }
}

/* ---------- Services ---------- */
/* Cards per row is fixed by --cards-per-row rather than left to
     auto-fit, so the count is a decision instead of a side effect of
     viewport width. minmax(0, 1fr) rather than 1fr: without the zero
     minimum a long unbroken word would push a column wider than its
     share and overflow the row. */
.card-grid {
  display: grid;
  gap: 1.5rem;
  grid-template-columns: repeat(var(--cards-per-row), minmax(0, 1fr));
  margin-top: 2rem;
}

@media (max-width: 62em) {
  :root {
    --cards-per-row: 2;
  }
}

@media (max-width: 46em) {
  :root {
    --cards-per-row: 1;
  }
}

/* Per-section override. Declared on the section rather than :root, so
     it beats the defaults above at every width — which is exactly why it
     needs its own narrow-screen rule: two cards on a phone would be
     about 150px each. An inline style="--cards-per-row: 2" cannot be
     walked back like this, which is why it is a class. */
.two-up {
  --cards-per-row: 2;
}

@media (max-width: 46em) {
  .two-up {
    --cards-per-row: 1;
  }
}

.card {
  background: var(--paper-2);
  border: 1px solid var(--line);
  padding: 1.75rem;
}

.card h3 {
  font-size: 1.15rem;
}

/* ---------- Included ---------- */
/* #work{ background: var(--ink); color: var(--paper); }
  #work .eyebrow{ color: var(--accent); } */
.included-grid {
  display: grid;
  margin-top: 2rem;
  grid-template-columns: 1fr;
}

.included-item {
  padding: 1.75rem;
}

/* Single column: a rule between each pair of stacked items. */
.included-item+.included-item {
  border-top: 1px solid var(--line-dark);
}

@media (min-width: 46em) {
  .included-grid {
    grid-template-columns: repeat(3, 1fr);
  }

  /* Three across: vertical rules between columns, horizontal rules
       above every row after the first. The 3n and n+4 selectors below
       are tied to the column count above — change one, change both. */
  .included-item+.included-item {
    border-top: none;
  }

  .included-item {
    border-right: 1px solid var(--line-dark);
  }

  .included-item:nth-child(3n) {
    border-right: none;
  }

  /* The final item ends a row too, even when that row is short —
       without this it draws a rule with nothing to its right. */
  .included-item:last-child {
    border-right: none;
  }

  .included-item:nth-child(n+4) {
    border-top: 1px solid var(--line-dark);
  }
}

.included-item .eyebrow {
  color: var(--accent-deep);
  background: none;
}

.included-item h3 {
  color: var(--paper);
  font-size: 1.1rem;
}

.included-item p {
  color: var(--paper-2);
  font-size: .95rem;
}

/* ---------- Reviews --------------------- */
div#reviews .container {
  border-top: 1px solid var(--line);
}

/* ---------- Gallery / Carousel ---------- */
.carousel {
  position: relative;
  margin-top: 2.5rem;
}

.carousel-track {
  display: flex;
  gap: var(--slide-gap);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  padding-bottom: .5rem;
  scrollbar-width: none;
  /* Firefox */
}

.carousel-track::-webkit-scrollbar {
  display: none;
}

/* WebKit */

/* Slide width is derived from --per-view, so the number of visible
     images is a setting rather than a hand-tuned percentage. Fractional
     values are deliberate: 2.4 shows two whole slides plus a sliver of
     the next, which signals that the strip scrolls. */
/* A gallery holding a single image: it fills the width and reads as a
     plain figure rather than a one-item carousel. Clicking it still
     opens the full-screen viewer. */
.slide:only-child {
  flex: 0 0 100%;
  scroll-snap-align: start;
}

.slide:only-child img {
  height: auto;
  max-height: 30rem;
}

.slide {
  flex: 0 0 calc((100% - (var(--per-view) - 1) * var(--slide-gap)) / var(--per-view));
  scroll-snap-align: center;
  margin: 0;
}

.slide img {
  width: 100%;
  height: 15rem;
  object-fit: cover;
  border: 1px solid var(--line);
  background: var(--paper-2);
}

.slide figcaption {
  font-family: var(--font-mono);
  font-size: .82rem;
  color: var(--accent-deep);
  padding-top: .6rem;
}

.carousel-btn {
  position: absolute;
  top: 40%;
  transform: translateY(-50%);
  width: 2.5rem;
  height: 2.5rem;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--line-dark);
  background: var(--paper);
  color: var(--ink);
  font-size: 1rem;
  line-height: 1;
  cursor: pointer;
}

.carousel-btn:hover,
.carousel-btn:focus-visible {
  background: var(--accent);
  border-color: var(--accent);
}

.carousel-btn.prev {
  left: -0.6rem;
}

.carousel-btn.next {
  right: -0.6rem;
}

@media (max-width: 30em) {
  .carousel-btn.prev {
    left: 0;
  }

  .carousel-btn.next {
    right: 0;
  }
}

.carousel-dots {
  display: flex;
  justify-content: center;
  gap: .6rem;
  margin-top: 1.25rem;
}

.dot {
  width: .65rem;
  height: .65rem;
  border-radius: 50%;
  border: 1px solid var(--line-dark);
  background: var(--paper-2);
  padding: 0;
  cursor: pointer;
}

.dot[aria-current="true"] {
  background: var(--accent);
  border-color: var(--accent);
}

.agenda-note {
  font-size: .9rem;
  color: var(--accent-deep);
}

/* ---------- Calendar: horizontal month browser ---------- */
.cal-browser {
  position: relative;
  margin-top: 2rem;
}

.cal-track {
  display: flex;
  gap: 2.5rem;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  padding-bottom: .5rem;
  scrollbar-width: none;
}

.cal-track::-webkit-scrollbar {
  display: none;
}

.cal-slide {
  flex: 0 0 min(19rem, 78%);
  scroll-snap-align: start;
}

/* Leave room for the arrow buttons so months don't sit under them. */
@media (min-width: 46em) {
  .cal-track {
    padding-inline: 3rem;
  }

  .cal-slide {
    flex-basis: 19rem;
  }
}

.cal-month {
  border-collapse: collapse;
  width: 100%;
  table-layout: fixed;
}

.cal-month caption {
  font-family: var(--font-display);
  font-size: 1.1rem;
  text-align: left;
  padding-bottom: .6rem;
  border-bottom: 1px solid var(--line);
  margin-bottom: .4rem;
}

.cal-month th {
  font-family: var(--font-mono);
  font-size: .7rem;
  font-weight: 400;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: #6B7080;
  padding: .4rem 0;
}

.cal-month td {
  padding: 1px 0;
  text-align: center;
  font-size: .85rem;
  font-variant-numeric: tabular-nums;
}

.cal-month td .d {
  display: block;
  line-height: 2rem;
}

/* Event days. Adjacent cells share an edge, so the backgrounds
     join into a continuous bar across the week. */
.cal-month td.is-event .d {
  background: var(--ev);
  color: var(--paper);
}

.cal-month td.is-start .d {
  border-radius: 1rem 0 0 1rem;
}

.cal-month td.is-end .d {
  border-radius: 0 1rem 1rem 0;
}

.cal-month td.is-start.is-end .d {
  border-radius: 1rem;
}

/* Drawn as an overlay so it can't reshape the bar underneath. */
.cal-month td.is-today {
  position: relative;
}

.cal-month td.is-today .d {
  font-weight: 700;
}

.cal-month td.is-today::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 1.85rem;
  height: 1.85rem;
  transform: translate(-50%, -50%);
  border: 2px solid var(--ink);
  border-radius: 50%;
  pointer-events: none;
}

/* On a filled day the dark ring disappears — switch to the light one. */
.cal-month td.is-event.is-today::after {
  border-color: var(--paper);
}

.cal-btn {
  position: absolute;
  top: 45%;
  transform: translateY(-50%);
  width: 2.5rem;
  height: 2.5rem;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--line-dark);
  background: var(--paper);
  color: var(--ink);
  font-size: 1rem;
  line-height: 1;
  cursor: pointer;
  z-index: 2;
}

.cal-btn:hover,
.cal-btn:focus-visible {
  background: var(--accent);
  border-color: var(--accent);
}

.cal-btn:disabled {
  opacity: .3;
  cursor: default;
  background: var(--paper);
}

.cal-btn.prev {
  left: 0;
}

.cal-btn.next {
  right: 0;
}

@media (max-width: 46em) {

  /* Arrows drop below the track on narrow screens. Reserve space with
       padding and sit them inside it, so they clear the legend rule. */
  .cal-browser {
    padding-bottom: 3.75rem;
  }

  .cal-btn {
    top: auto;
    bottom: 0;
    transform: none;
  }

  .cal-btn.prev {
    left: 0;
  }

  .cal-btn.next {
    left: 3.25rem;
    right: auto;
  }
}

.cal-legend {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: .6rem 1.75rem;
  /* margin-top: 2.5rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--line); */
  margin-left: 1rem;
}

.cal-legend li {
  display: flex;
  align-items: center;
  gap: .6rem;
  font-size: .9rem;
}

.cal-legend .swatch {
  width: 1rem;
  height: 1rem;
  border-radius: 50%;
  background: var(--ev);
  flex: none;
}

/* ---------- Rates ------------ */
.container.rates {
  padding-top: 4rem;
}

.container.rates div.content {
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  padding-left: 1rem;
}

.container.rates .eyebrow {
  margin-bottom: .3rem;
}

div.container.rates div.content h3 {
  font-family: var(--font-body);
  font-size: 1.1rem;
  color: var(--fbc-secondary-text);
  font-weight: bolder;
  margin-bottom: 0.3rem;
  margin-top: 1rem;
  font-size: 1rem;
}

.container.rates div.content span {
  margin-left: .5rem;
  font-size: .9rem;
  color: var(--muted);
}

/* ---------- Contact ---------- */
.contact-wrap {
  display: grid;
  gap: 2rem;
  grid-template-columns: 1fr;
}

@media (min-width: 46em) {
  .contact-wrap {
    grid-template-columns: 1fr 1fr;
  }
}

form {
  display: grid;
  gap: 1rem;
  max-width: 32rem;
}

label {
  font-size: .9rem;
  font-weight: 600;
}

/* Scoped to the form. As a bare element selector this also matched the
     header's menu-toggle checkbox, which is absolutely positioned with
     no offsets — so it sat at its static position and stretched the full
     header width from there, pushing the page wider by exactly the nav
     bar's indent. Invisible, because the checkbox is opacity:0. */
form input,
form textarea {
  width: 100%;
  font: inherit;
  padding: .65rem .75rem;
  border: 1px solid var(--line-dark);
  background: var(--paper);
  color: var(--ink);
}

textarea {
  min-height: 8rem;
  resize: vertical;
}

input:focus-visible,
textarea:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 1px;
}

/* ---------- Footer ---------- */
.site-footer {
  background: var(--ink);
  color: var(--paper-2);
  padding: 2rem 0;
  font-size: .85rem;
}

.site-footer .container {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  justify-content: space-between;
}

/* ---------- Lightbox / full-screen viewer ----------
     Driven by :target — clicking a slide sets the URL hash, which
     reveals the matching overlay. No JavaScript required. */
.zoom {
  display: block;
  position: relative;
  cursor: zoom-in;
}

.zoom::after {
  content: "\2921";
  /* diagonal expand arrow */
  position: absolute;
  right: .5rem;
  bottom: .5rem;
  width: 2rem;
  height: 2rem;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(23, 27, 36, .75);
  color: var(--paper);
  font-size: 1rem;
  opacity: 0;
  transition: opacity .15s ease;
}

.zoom:hover::after,
.zoom:focus-visible::after {
  opacity: 1;
}

.lightbox {
  position: fixed;
  inset: 0;
  z-index: 300;
  background: rgba(23, 27, 36, .96);
  opacity: 0;
  visibility: hidden;
  transition: opacity .2s ease, visibility .2s ease;
}

/* The images live on one horizontal track, exactly like the carousel.
     Moving between them is a scroll, so it glides and follows a drag
     instead of cutting from one overlay to the next. */
.lightbox-track {
  position: absolute;
  inset: 0;
  display: flex;
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  scrollbar-width: none;
  overscroll-behavior: contain;
}

.lightbox-track::-webkit-scrollbar {
  display: none;
}

.lb-slide {
  flex: 0 0 100%;
  scroll-snap-align: center;
  scroll-snap-stop: always;
  /* one image per swipe, never two */
  position: relative;
  margin: 0;
  padding: 3.5rem 1rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1rem;
}

/* Two rules rather than one selector list: a browser that does not
     understand :has() discards the entire list it appears in, which
     would take the .is-open fallback with it. */
.lightbox:has(.lb-slide:target) {
  opacity: 1;
  visibility: visible;
}

.lightbox.is-open {
  opacity: 1;
  visibility: visible;
}

/* No touch-action restriction: the track scrolls horizontally by
     itself now, and pan-y here would have forbidden exactly the drag
     the viewer depends on. It was there for the old swipe handler,
     which no longer exists. */
.lightbox img {
  -webkit-user-drag: none;
  user-select: none;
}

/* One per slide, filling it, so clicking beside the image closes the
     viewer. It lives inside the slide rather than the overlay because
     the track covers the overlay edge to edge — anything underneath
     that would never receive a click. */
.lightbox-backdrop {
  position: absolute;
  inset: 0;
  cursor: zoom-out;
}

/* Three layers inside the viewer, stated outright rather than left to
     source order. Giving the image a z-index to clear the backdrop also
     lifted it over the controls, which had none of their own — so each
     layer names its place:
         0  backdrop, filling the slide to catch a click
         1  the image and its caption
         2  the arrows and the close button, above everything */
.lightbox-backdrop {
  z-index: 0;
}

.lb-slide img,
.lb-slide figcaption {
  position: relative;
  z-index: 1;
}

.lightbox-nav,
.lightbox-close {
  z-index: 2;
}

.lightbox img {
  max-width: 100%;
  max-height: 78vh;
  width: auto;
  object-fit: contain;
}

.lightbox figcaption {
  color: var(--paper-2);
  font-family: var(--font-mono);
  font-size: .82rem;
  text-align: center;
}

.lightbox-close,
.lightbox-nav {
  position: absolute;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2.75rem;
  height: 2.75rem;
  color: var(--paper);
  text-decoration: none;
  background: rgba(255, 255, 255, .08);
  border: 1px solid rgba(255, 255, 255, .25);
  font-size: 1.1rem;
  line-height: 1;
}

.lightbox-close:hover,
.lightbox-close:focus-visible,
.lightbox-nav:hover,
.lightbox-nav:focus-visible {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--ink);
}

/* Fixed, not absolute: anchored to the viewport itself, so the close
     button cannot drift off-screen if anything ever makes the page
     wider than the window. env() keeps it clear of a notch or a
     rounded corner; max() means it still has a sensible inset on
     devices that report nothing. */
.lightbox-close {
  position: fixed;
  top: max(1rem, env(safe-area-inset-top));
  right: max(1rem, env(safe-area-inset-right));
  font-size: 1.4rem;
}

.lightbox-nav {
  top: 50%;
  transform: translateY(-50%);
}

.lightbox-nav.prev {
  left: max(1rem, env(safe-area-inset-left));
}

.lightbox-nav.next {
  right: max(1rem, env(safe-area-inset-right));
}

@media (max-width: 30em) {
  .lightbox-nav.prev {
    left: max(.35rem, env(safe-area-inset-left));
  }

  .lightbox-nav.next {
    right: max(.35rem, env(safe-area-inset-right));
  }
}

/* Leave room for the controls so a tall image never sits under them. */
.lb-slide {
  padding-top: max(4.5rem, calc(env(safe-area-inset-top) + 3.5rem));
  padding-bottom: max(3.5rem, calc(env(safe-area-inset-bottom) + 2rem));
}

/* More images fit as the viewport widens. */
@media (min-width: 46em) {
  :root {
    --per-view: 2.4;
  }
}

@media (min-width: 72em) {
  :root {
    --per-view: 3.4;
  }
}

/* ============================================================
     LIGHT TROPICAL VARIANT
     No dark bands at all — the page reads as one continuous sheet of
     warm paper, with sections separated by tone and hairlines rather
     than by inverted blocks. Accents are darkened versions of the
     tropical palette, because a coral that works on near-black is too
     pale to read on near-white.
     ============================================================ */
:root {
  --ink: #16332C;
  /* deep palm — text only, no longer a background */
  --paper: #FDFAF5;
  /* near-white shell */
  --paper-2: #F2EADC;
  /* warm sand, for tinted bands and cards */
  --paper-3: #E9F0EC;
  /* palest lagoon, for the hero wash */
  --accent: #A84322;
  /* deep coral — links, highlights */
  --accent-deep: #0F5B50;
  /* lagoon teal — eyebrows, calendar bars */
  --line: #E6DACA;
  /* hairline on paper */
  --line-dark: #D9CCB8;
  /* was the rule colour on dark bands */
  --muted: #55655F;
  /* secondary text */

  /* Five saturated hues, each dark enough to carry small text on the
       pale page and to hold white text when used as a fill. */
  --coral: #A84322;
  --teal: #0F5B50;
  --mango: #8F5B06;
  --hibiscus: #A62550;
  --sea: #0D5A73;

  /* Their pale counterparts, used as section washes. Body text keeps
       an 11:1 ratio or better on every one of them. */
  --wash-coral: #FCEBE3;
  --wash-teal: #E6F0EC;
  --wash-mango: #FBEFD9;
  --wash-hibiscus: #FBE8EC;
  --wash-sea: #E6F0F2;
}

/* --- header: pale, held down by a hairline instead of mass --- */
.site-header {
  background: rgba(253, 250, 245, .92);
  backdrop-filter: saturate(140%) blur(8px);
  color: var(--ink);
  border-bottom: 1px solid var(--line);
}

.brand {
  color: var(--ink);
}

.site-nav a {
  color: var(--ink);
}

.menu-label {
  border-color: var(--line);
}

.menu-label span {
  background: var(--ink);
}

@media (max-width: 46em) {
  .site-nav {
    background: var(--paper);
    border-bottom-color: var(--line);
  }

  .site-nav a {
    border-bottom-color: var(--line);
  }
}

/* --- hero: a wash of light rather than an inverted block --- */
#home {
  color: var(--ink);
  background:
    radial-gradient(70% 60% at 85% 5%, var(--wash-sea) 0%, transparent 60%),
    radial-gradient(60% 55% at 10% 15%, var(--wash-hibiscus) 0%, transparent 55%),
    radial-gradient(80% 70% at 50% 100%, var(--wash-mango) 0%, transparent 60%),
    linear-gradient(180deg, var(--paper-2) 0%, var(--paper) 75%);
}

/* A photograph behind the hero, set from content.ini. The gradient
     layered over it is a scrim: without one, dark text on an unknown
     photo is a coin toss. It fades to solid paper at the bottom so the
     image meets the next section cleanly rather than being cut off. */
#home {
  background-image:
    linear-gradient(180deg,
      rgba(253, 250, 245, .74) 0%,
      rgba(253, 250, 245, .68) 55%,
      var(--paper) 100%),
    url("/img/DSC_4588.jpg");
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}

#home {
  background-position: center 40%;
}

#home .eyebrow {
  color: var(--accent-deep);
}

#home .lede {
  color: var(--muted);
}

.cta {
  background: var(--accent);
  color: #FFFFFF;
}

.cta:hover,
.cta:focus-visible {
  background: var(--accent-deep);
  color: #FFFFFF;
}

/* --- each section carries a different hue: a wash behind it and a
         matching accent on its eyebrow, so the page moves through the
         palette rather than repeating one colour --- */
#about {
  background: var(--paper);
}

#about .eyebrow {
  color: var(--sea);
}

#about .slide img {
  height: 20rem;
}

#services {
  background: var(--wash-mango);
}

#services .eyebrow {
  color: var(--mango);
}

#gallery_1 {
  background: var(--wash-sea);
}

#gallery_1 .eyebrow {
  color: var(--sea);
}

#agenda {
  background: var(--wash-teal);
}

#agenda .eyebrow {
  color: var(--teal);
}

#contact {
  background: var(--wash-hibiscus);
}

#contact .eyebrow {
  color: var(--hibiscus);
}

#contact p.note {
  color: var(--hibiscus);
}

/* Cards pick up the section hue as a top edge, cycling through the
     palette so a row of three is never monotone. */
.card {
  background: var(--paper);
  border-color: var(--line);
  border-top: 3px solid var(--mango);
}

.card:nth-child(3n+2) {
  border-top-color: var(--coral);
}

.card:nth-child(3n) {
  border-top-color: var(--sea);
}

/* --- nearby: a tinted band, not a dark one --- */
/* #work {
  background: var(--wash-coral);
  color: var(--ink);
}

#work .eyebrow {
  color: var(--coral);
} */

.included-item .eyebrow {
  color: var(--teal);
}

.included-item:nth-child(3n+2) .eyebrow {
  color: var(--hibiscus);
}

.included-item:nth-child(3n) .eyebrow {
  color: var(--sea);
}

.included-item h3 {
  color: var(--ink);
}

.included-item p {
  color: var(--muted);
}

.included-item+.included-item {
  border-top-color: var(--line);
}

@media (min-width: 46em) {
  .included-item {
    border-right-color: var(--line);
  }

  .included-item:nth-child(n+4) {
    border-top-color: var(--line);
  }
}

#included .included-item .carousel {
  margin-top: initial;
}

/* --- gallery: keep the zoom chip legible over pale photographs --- */
.zoom::after {
  background: rgba(22, 51, 44, .78);
  color: #FFFFFF;
}

/* --- lightbox: frosted white rather than blackout --- */
.lightbox {
  background: rgba(253, 250, 245, .97);
}

.lightbox figcaption {
  color: var(--muted);
}

.lightbox-close,
.lightbox-nav {
  color: var(--ink);
  background: rgba(22, 51, 44, .06);
  border-color: var(--line);
}

.lightbox-close:hover,
.lightbox-close:focus-visible,
.lightbox-nav:hover,
.lightbox-nav:focus-visible {
  background: var(--accent);
  border-color: var(--accent);
  color: #FFFFFF;
}

/* --- calendar: white numerals on the coloured booking bars --- */
.cal-month td.is-event .d {
  color: #FFFFFF;
}

.cal-month td.is-event.is-today::after {
  border-color: #FFFFFF;
}

.cal-btn:hover,
.cal-btn:focus-visible {
  background: var(--accent);
  color: #FFFFFF;
}

/* --- small colour throughout the furniture --- */
.dot[aria-current="true"] {
  background: var(--teal);
  border-color: var(--teal);
}

.dot:nth-child(3n+2)[aria-current="true"] {
  background: var(--coral);
  border-color: var(--coral);
}

.dot:nth-child(3n)[aria-current="true"] {
  background: var(--sea);
  border-color: var(--sea);
}

.brand em {
  color: var(--coral);
}

.site-nav a:hover,
.site-nav a:focus-visible {
  color: var(--coral);
  border-color: var(--coral);
}

.agenda-note {
  color: var(--teal);
}

.cal-legend .swatch {
  box-shadow: 0 0 0 3px var(--paper);
}

.carousel-btn:hover,
.carousel-btn:focus-visible {
  background: var(--accent);
  color: #FFFFFF;
}

/* --- footer: closing band, still paper --- */
.site-footer {
  background: var(--paper-2);
  color: var(--muted);
  border-top: 1px solid var(--line);
}

/* A text gallery: the slides hold quotations rather than pictures, so
     they need their own box treatment — the image rules do not apply. */
.text-gallery {
  margin-top: 2.5rem;
  --per-view: 1.15;
}

@media (min-width: 46em) {
  .text-gallery {
    --per-view: 2.2;
  }
}

.text-gallery .slide {
  background: var(--paper);
  border: 1px solid var(--line);
  border-left: 3px solid var(--teal);
  border-radius: .5rem;
  padding: 1.5rem;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}

.text-gallery blockquote {
  margin: 0;
  font-family: var(--font-display);
  font-size: 1.05rem;
  line-height: 1.5;
}

.text-gallery figcaption {
  margin-top: 1rem;
  font-family: var(--font-mono);
  font-size: .75rem;
  letter-spacing: .04em;
  color: var(--muted);
}

.text-gallery .slide:nth-child(3n+2) {
  border-left-color: var(--coral);
}

.text-gallery .slide:nth-child(3n) {
  border-left-color: var(--hibiscus);
}

/* A single image used as a section illustration: wider, and without a
     carousel's furniture. */
.section-image {
  margin-top: 2rem;
}

.section-image .carousel-track {
  padding-bottom: 0;
}

.section-image figcaption {
  text-align: left;
}

/* A gallery inside a single service card: narrower, tighter, and it
     shows one image at a time since the card is only a third as wide. */
.card-gallery {
  /* Sits between the card title and its description, so it needs
       breathing room on both sides rather than just above. */
  margin: 1rem 0 1.25rem;
  --per-view: 1.1;
  --slide-gap: .5rem;
}

.card-gallery .slide img {
  height: 9rem;
}

.card-gallery figcaption {
  font-size: .72rem;
  padding-top: .4rem;
}

.card-gallery .carousel-btn {
  width: 2rem;
  height: 2rem;
  font-size: .8rem;
}

.card-gallery .carousel-dots {
  margin-top: .75rem;
}

/* A gallery sitting inside another section: it inherits the host's
     container, so it only needs spacing and a lighter heading. */
.section-gallery {
  margin-top: 2.75rem;
}

.section-gallery-title {
  font-size: 1.05rem;
  margin-bottom: 1rem;
  color: var(--accent-deep);
}

.section-gallery .carousel {
  margin-top: 0;
}

/* --- softened geometry, as in the tropical variant --- */
.card,
.slide img,
.lightbox img,
input,
textarea {
  border-radius: .5rem;
}

.cta,
.carousel-btn,
.cal-btn,
.lightbox-close,
.lightbox-nav {
  border-radius: 999px;
}

.menu-label {
  border-radius: .35rem;
}

/* Honeypot: off-screen rather than display:none, since some bots skip
     fields that are not rendered at all. */
.hp {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.form-status {
  padding: .75rem 1rem;
  border-left: 3px solid var(--accent-deep);
  background: var(--paper-2);
  font-size: .92rem;
}

.form-status.is-error {
  border-left-color: var(--accent);
}

/* The script moves focus here so it is announced; a focus ring on a
     paragraph nobody clicked looks like a bug, so it is suppressed —
     but only for the mouse path. Keyboard users keep the ring. */
.form-status:focus {
  outline: none;
}

.form-status:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 2px;
}

/* Per-field validation. The native bubble is unreliable on mobile —
     Safari on iOS shows none at all — so the message is drawn in the
     page, under the field it belongs to. */
.field-error {
  display: block;
  margin-top: .35rem;
  font-size: .85rem;
  color: var(--accent);
}

/* The UA rule for the hidden attribute is [hidden]{display:none}, which
     a class selector outranks — so display:block above would keep these
     visible (and reserving space) even when empty. Restate it. */
.field-error[hidden] {
  display: none;
}

input.is-invalid,
textarea.is-invalid {
  border-color: var(--accent);
  /* A second ring rather than a thicker border, so the field does not
       change size when it becomes invalid and shift the layout. */
  box-shadow: 0 0 0 1px var(--accent);
}

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

  .lightbox-track {
    scroll-behavior: auto;
  }

  * {
    transition-duration: 0.01ms !important;
  }
}