/* Mobile-first. The one breakpoint is 701px, where the page goes from one column to two and the
   gallery from two photos a row to four. Sveltia's preview pane only picks up element-level rules,
   so base type and color live on elements and the layout rules are all class-based. */

:root {
  --green: #b9c2ad;
  --cream: #e9e6dc;
  --brown: #4f3e2f;
  /* Dark enough to clear WCAG AA against the green band, at 4.9:1. A lighter rust fails it for
     the section headings and for the email link, which is the only way to contact the business. */
  --accent: #73381f;
  --photo-backdrop: #8f9a84;
  --hairline: rgba(79, 62, 47, 0.2);
  --outline: rgba(79, 62, 47, 0.4);

  /* Whatever the reader already has, until these two families are self-hosted. */
  --font-display: 'Cormorant Garamond', Georgia, 'Times New Roman', serif;
  --font-text: 'Figtree', system-ui, -apple-system, 'Segoe UI', sans-serif;

  --page-width: 1200px;
  --gutter: clamp(18px, 3vw, 32px);
  --band: clamp(48px, 9vw, 72px);
  /* Clears the sticky header when a nav link jumps to a section. */
  --header-offset: 80px;

  /* Bands run full width; their contents stop at --page-width and center. */
  --edge: max(var(--gutter), calc((100% - var(--page-width)) / 2));
}

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

html {
  scroll-behavior: smooth;
}

body {
  margin: 0;
  background: var(--green);
  color: var(--brown);
  font-family: var(--font-text);
  font-size: 16px;
  line-height: 1.5;
  /* The client writes every word on this page. A long unbroken one — a pasted address, a run-on
     compound — has to wrap rather than push the page sideways on a phone. */
  overflow-wrap: break-word;
}

/* Sveltia's preview pane renders its own generic markup, so only element-level rules reach it.
   These keep the preview in the site's typography; the page's own headings restyle from here. */
h1,
h2,
h3 {
  font-family: var(--font-display);
  font-weight: 400;
}

ul {
  padding-left: 1.2em;
}

a {
  color: inherit;
}

/* The skip link's target takes focus programmatically; it should never draw a ring of its own. */
[tabindex='-1']:focus {
  outline: none;
}

main {
  scroll-margin-top: var(--header-offset);
}

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

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

@media (hover: hover) and (pointer: fine) {
  a:hover {
    opacity: 0.75;
  }
}

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

  *,
  *::before,
  *::after {
    transition: none !important;
  }
}

.skip-link {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 10;
  padding: 10px 16px;
  background: var(--cream);
  color: var(--brown);
  border-radius: 0 0 10px 0;
  transform: translateY(-110%);
  transition: transform 0.15s ease;
}

.skip-link:focus {
  transform: none;
}

/* Header */

.site-header {
  position: sticky;
  top: 0;
  z-index: 5;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 10px;
  padding-block: 10px;
  padding-inline: var(--edge);
  background: color-mix(in srgb, var(--green) 95%, transparent);
  backdrop-filter: blur(8px);
}

.wordmark {
  font: 500 clamp(17px, 4vw, 24px) var(--font-display);
  letter-spacing: 0.02em;
  text-decoration: none;
}

.site-header nav {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}

.site-header nav a {
  padding: 6px 10px;
  border: 1px solid var(--outline);
  border-radius: 999px;
  font-size: 12px;
  text-decoration: none;
}

.site-header nav a.nav-contact {
  background: var(--brown);
  border-color: var(--brown);
  color: var(--cream);
}

/* About */

.intro {
  display: grid;
  gap: 28px;
  padding-block: 24px 40px;
  padding-inline: var(--edge);
  background: var(--cream);
  scroll-margin-top: var(--header-offset);
}

.intro-text {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 24px;
}

.intro h1 {
  margin: 0;
  font: 400 clamp(20px, 6.4vw, 30px) / 1.15 var(--font-display);
  letter-spacing: -0.01em;
}

.intro p {
  margin: 0;
  line-height: 1.65;
  text-wrap: pretty;
  /* The CMS offers the client a line break here, so the page has to honor one. */
  white-space: pre-line;
}

.hero-photo {
  order: -1;
  aspect-ratio: 4 / 3;
  border-radius: 12px;
  overflow: hidden;
  background: var(--photo-backdrop);
}

.hero-photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Aims and services */

.offer {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 40px 48px;
  padding-block: var(--band);
  padding-inline: var(--edge);
  background: var(--green);
}

.label {
  margin: 0 0 14px;
  font: italic 400 28px var(--font-display);
  color: var(--accent);
}

.aims-intro {
  margin: 0 0 22px;
  font: 400 22px / 1.3 var(--font-display);
  text-wrap: pretty;
}

.aims {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.aims li {
  display: flex;
  gap: 12px;
  font-size: 15px;
}

.aims li::before {
  content: '';
  flex: none;
  width: 7px;
  height: 7px;
  margin-top: 8px;
  border-radius: 50%;
  background: var(--accent);
}

.services {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  max-width: 440px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.services li {
  /* A flex item refuses to shrink below its content by default, so one unbroken word would push
     the pill past the edge of the page however the text is set to wrap. */
  min-width: 0;
  padding: 6px 12px;
  border-radius: 999px;
  /* Light enough that the label clears 4.5:1 against the pill it sits on. */
  background: color-mix(in srgb, var(--brown) 12%, transparent);
  font-size: 13px;
  line-height: 1.3;
}

/* Photos */

#photos {
  padding-block: var(--band);
  padding-inline: var(--edge);
  background: var(--cream);
  scroll-margin-top: var(--header-offset);
}

.section-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 20px;
  margin-bottom: 20px;
}

.section-head h2 {
  margin: 0;
  font: 400 clamp(28px, 7vw, 36px) var(--font-display);
}

.album-link {
  font-size: 14px;
  font-weight: 500;
  text-underline-offset: 4px;
}

.gallery {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  grid-auto-rows: 44vw;
  gap: 10px;
  margin: 0;
  padding: 0;
  list-style: none;
}

/* The tile is the list item, not the link: without a usable album address the photos render
   unlinked, and they still have to look like photos. */
.gallery li {
  position: relative;
  border-radius: 14px;
  overflow: hidden;
  background: var(--photo-backdrop);
}

.gallery a {
  display: block;
  height: 100%;
}

.gallery img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.6s ease;
}

.caption {
  position: absolute;
  bottom: 12px;
  left: 12px;
  max-width: calc(100% - 24px);
  padding: 6px 14px;
  border-radius: 999px;
  background: var(--cream);
  color: var(--brown);
  font: italic 400 15px / 1.3 var(--font-display);
  /* The caption doubles as the photo's description, so it can run long. Two lines is as much as a
     tile can give it; the rest stays in the markup for a screen reader to read out. */
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
}

/* Where there's a real pointer the caption stays out of the photo's way until it's wanted. A touch
   screen has no hover to reveal it with, so there it stays visible. A touchscreen laptop reports
   both, which is why this asks for a fine pointer too. */
@media (hover: hover) and (pointer: fine) {
  .caption {
    opacity: 0;
    transition: opacity 0.3s ease;
  }

  .gallery li:hover .caption,
  .gallery a:focus-visible .caption {
    opacity: 1;
  }

  .gallery li:hover img {
    transform: scale(1.03);
  }
}

/* Contact */

#contact {
  padding-block: var(--band);
  padding-inline: var(--edge);
  background: var(--green);
  scroll-margin-top: var(--header-offset);
}

#contact h2 {
  margin: 0 0 16px;
  font: 400 clamp(28px, 3.6vw, 44px) / 1.05 var(--font-display);
}

#contact p {
  max-width: 440px;
  margin: 0 0 18px;
  font-size: 15px;
  line-height: 1.6;
  white-space: pre-line;
}

.email {
  display: inline-block;
  padding-block: 8px;
  border-bottom: 1px solid currentColor;
  color: var(--accent);
  font: 400 22px var(--font-display);
  text-decoration: none;
  word-break: break-word;
}

/* Footer */

footer {
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 20px;
  padding-block: 0 24px;
  padding-inline: var(--edge);
  font-size: 12px;
}

/* A border on the footer itself would run the full width of the window. As a flex item taking a
   whole row, the rule stops where the page's contents do. */
footer::before {
  content: '';
  flex-basis: 100%;
  margin-bottom: 18px;
  border-top: 1px solid var(--hairline);
}

@media (min-width: 701px) {
  .site-header {
    gap: 16px;
    padding-block: 18px;
  }

  .site-header nav {
    gap: 6px;
  }

  .site-header nav a {
    padding: 8px 14px;
    font-size: 13px;
  }

  .intro {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    align-items: center;
    gap: 48px;
    padding-block: 56px;
  }

  .intro h1 {
    font-size: clamp(24px, 2.6vw, 38px);
  }

  .hero-photo {
    order: 0;
    border-radius: 18px;
  }

  .gallery {
    grid-template-columns: repeat(4, 1fr);
    grid-auto-rows: clamp(200px, 20vw, 280px);
  }

  .caption {
    font-size: 17px;
  }
}
