/* ==========================================================================
   Burgundy Loft Florals
   Ported from the Claude Design canvas in /design. Colour and type values are
   taken verbatim from that file; the inline styles have been consolidated into
   the classes below.
   ========================================================================== */

:root {
  --ink: #2a211f;
  --ink-deep: #111111;
  --burgundy: #6e2132;
  --blush: #d7a0a9;
  --bone: #e4ddd5;
  --bone-rgb: 228 221 213;
  --shell: #f7f1ef;
  --shell-deep: #efe8e3;
  --clay: #c9b8ae;
  --taupe: #a2958c;
  --taupe-mid: #8c8078;
  --taupe-dark: #6b615b;
  --taupe-darker: #5c534e;
  --grey-warm: #7a706a;
  --sand: #ebe3de;
  --sand-deep: #dcd1cb;
  --sand-line: #e3d8d2;
  --mono-label: #9c8f87;
  --pill-label: #b2a49b;

  --serif: "Cormorant Garamond", Georgia, "Times New Roman", serif;
  --sans: "Jost", system-ui, -apple-system, "Segoe UI", sans-serif;
  --numeral: "Times New Roman", Times, serif;
  --mono: ui-monospace, Menlo, Consolas, monospace;

  --shell-max: 1180px;
  --gutter: 40px;
}

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

html {
  scroll-behavior: smooth;
  /* Safari on iOS inflates the type in a narrow column when the phone is turned
     to landscape, which is a guess at what a desktop-width page needed and is
     wrong for one that has a layout of its own at this width. */
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
}

body {
  margin: 0;
  background: var(--bone);
  color: var(--ink-deep);
  font-family: var(--sans);
  font-weight: 300;
  -webkit-font-smoothing: antialiased;
}

img {
  max-width: 100%;
}

a {
  color: var(--burgundy);
  text-decoration: none;
}

a:hover {
  color: var(--ink-deep);
}

::selection {
  background: var(--blush);
  color: var(--ink-deep);
}

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

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  background: var(--ink);
  color: var(--bone);
  padding: 14px 22px;
  font-size: 11px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
}

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

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

/* --------------------------------------------------------------- animation */

@keyframes fadeUp {
  from {
    opacity: 0;
    transform: translateY(18px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

@keyframes fadeIn {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

@keyframes ctaGlow {
  0% {
    box-shadow: 0 18px 38px -14px rgba(42, 33, 31, 0.5), 0 0 0 0 rgba(215, 160, 169, 0.95),
      0 0 0 0 rgba(215, 160, 169, 0.6);
  }
  50% {
    box-shadow: 0 18px 38px -14px rgba(42, 33, 31, 0.5), 0 0 0 14px rgba(215, 160, 169, 0),
      0 0 0 26px rgba(215, 160, 169, 0);
  }
  100% {
    box-shadow: 0 18px 38px -14px rgba(42, 33, 31, 0.5), 0 0 0 0 rgba(215, 160, 169, 0),
      0 0 0 0 rgba(215, 160, 169, 0);
  }
}

@keyframes ctaBob {
  0%,
  100% {
    transform: translateY(0) scale(1);
  }
  50% {
    transform: translateY(-6px) scale(1.035);
  }
}

main {
  animation: fadeIn 0.5s ease both;
}

/* ------------------------------------------------------------ type helpers */

.eyebrow {
  font-size: 10px;
  letter-spacing: 0.42em;
  text-transform: uppercase;
  color: var(--taupe);
  margin: 0;
}

.eyebrow--wide {
  letter-spacing: 0.44em;
}

.eyebrow--light {
  color: rgb(var(--bone-rgb) / 0.82);
  letter-spacing: 0.46em;
}

.eyebrow--blush {
  color: var(--blush);
  letter-spacing: 0.44em;
}

.eyebrow--clay {
  color: #5f4f49;
}

.display {
  font-family: var(--serif);
  font-weight: 300;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink);
  margin: 0;
}

.numeral {
  font-family: var(--numeral);
  font-style: italic;
  font-size: clamp(52px, 6vw, 78px);
  line-height: 0.82;
  letter-spacing: -0.02em;
  color: var(--blush);
}

.rule {
  width: 52px;
  height: 1px;
  background: var(--blush);
  border: 0;
  margin: 38px auto 0;
}

/* --------------------------------------------------------------- buttons */

.btn {
  display: inline-block;
  border: 0;
  cursor: pointer;
  font-family: var(--sans);
  font-size: 10.5px;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  padding: 17px 42px;
  transition: background 0.35s, color 0.35s;
}

.btn--solid {
  background: var(--burgundy);
  color: var(--bone);
}

.btn--solid:hover {
  background: var(--ink-deep);
  color: var(--bone);
}

.btn--light {
  background: var(--bone);
  color: var(--ink);
}

.btn--light:hover {
  background: var(--blush);
  color: var(--ink);
}

.btn--outline-light {
  border: 1px solid rgb(var(--bone-rgb) / 0.7);
  color: var(--bone);
  background: transparent;
  letter-spacing: 0.28em;
  padding: 16px 38px;
}

.btn--outline-light:hover {
  background: var(--bone);
  color: var(--ink-deep);
}

.btn--outline-dark {
  border: 1px solid #4a3c37;
  color: #241c1a;
  background: transparent;
  font-size: 10.5px;
  letter-spacing: 0.26em;
  padding: 15px 34px;
  align-self: flex-start;
}

.btn--outline-dark:hover {
  background: #241c1a;
  color: var(--shell);
}

.text-link {
  display: inline-block;
  font-size: 10.5px;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  color: var(--burgundy);
  padding-bottom: 6px;
  border-bottom: 1px solid var(--blush);
  white-space: nowrap;
}

.arrow-link {
  margin-top: 34px;
  font-size: 11.5px;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  color: var(--burgundy);
}

/* ---------------------------------------------------------------- header */

.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: var(--bone);
  border-bottom: 1px solid var(--sand);
}

.site-header__inner {
  max-width: 1280px;
  margin: 0 auto;
  padding: 18px var(--gutter);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
}

.brand {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-shrink: 0;
}

.brand:hover {
  color: inherit;
}

.brand__mark {
  height: 64px;
  width: auto;
  display: block;
}

.brand__name {
  display: block;
  font-family: var(--serif);
  font-size: 19px;
  letter-spacing: 0.34em;
  color: var(--burgundy);
  text-transform: uppercase;
  white-space: nowrap;
}

.brand__tagline {
  display: block;
  font-size: 8.5px;
  letter-spacing: 0.42em;
  color: var(--taupe-mid);
  text-transform: uppercase;
  white-space: nowrap;
  margin-top: 2px;
}

.site-nav {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 14px 22px;
  min-width: 0;
}

.site-nav__link {
  font-size: 11px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--taupe-darker);
  padding-bottom: 3px;
  border-bottom: 1px solid transparent;
  transition: color 0.3s;
  white-space: nowrap;
}

.site-nav__link:hover {
  color: var(--burgundy);
}

.site-nav__link[aria-current="page"] {
  color: var(--burgundy);
  border-bottom-color: var(--blush);
}

/* The hamburger. Hidden until the nav collapses; see the 960px block below.

   Sized 44x44 because that is the smallest square a thumb reliably hits, but
   the bars inside are 24px wide and pushed to the end of that square, so the
   tap area grows inwards and the lines still sit flush with the page gutter
   the wordmark is aligned to. Padding would have moved the lines; this does
   not. */
.nav-toggle {
  display: none;
  align-items: center;
  justify-content: flex-end;
  width: 44px;
  height: 44px;
  flex: 0 0 auto;
  padding: 0;
  background: transparent;
  border: 0;
  color: var(--taupe-darker);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

/* The bars are positioned against this box rather than stacked, so the two
   that survive the open state can rotate about a shared centre.

   Every number here is a whole pixel, and that is the whole point. A 1.5px bar
   was landing on the pixel grid at 0, 7.25 and 14.5, so the browser rasterised
   each of the three differently: at 1x the top bar came out as a solid row with
   a half-lit row under it, the middle as two 75% rows, and the bottom as one
   thin row — three lines of three different weights, which read as the top and
   bottom being clipped. 13px and 1px keep the bars at 0, 6 and 12 whatever the
   pixel ratio. 1px rather than 2px because the header rule, the nav underline
   and the section borders are all 1px: at this size the icon is a piece of the
   same hairline drawing, not a chunkier thing sat next to it. */
.nav-toggle__bars {
  position: relative;
  display: block;
  width: 24px;
  height: 13px;
}

.nav-toggle__bar {
  position: absolute;
  left: 0;
  width: 100%;
  height: 1px;
  background: currentColor;
  transition: transform 0.3s ease, opacity 0.2s ease;
}

.nav-toggle__bar:nth-child(1) { top: 0; }
.nav-toggle__bar:nth-child(2) { top: 6px; }
.nav-toggle__bar:nth-child(3) { bottom: 0; }

/* Open: the outer two meet in the middle and cross, the middle one goes. Half
   the box less half a bar — 6px — which is the distance from either outer bar
   to the centre line, and a whole pixel for the same reason as above. */
.nav-toggle[aria-expanded="true"] .nav-toggle__bar:nth-child(1) {
  transform: translateY(6px) rotate(45deg);
}

.nav-toggle[aria-expanded="true"] .nav-toggle__bar:nth-child(2) {
  opacity: 0;
}

.nav-toggle[aria-expanded="true"] .nav-toggle__bar:nth-child(3) {
  transform: translateY(-6px) rotate(-45deg);
}

/* Guarded, because a touch screen keeps :hover on the last thing tapped: the
   X would stay burgundy until something else was tapped. */
@media (hover: hover) {
  .nav-toggle:hover {
    color: var(--burgundy);
  }
}

/* ---------------------------------------------------------------- section */

.section {
  padding: 112px var(--gutter);
}

.section--shell {
  background: var(--shell);
}

.section--bone {
  background: var(--bone);
}

.section--flush {
  padding: 0;
}

.shell {
  max-width: var(--shell-max);
  margin: 0 auto;
}

.shell--narrow {
  max-width: 760px;
}

.section-head {
  text-align: center;
  margin-bottom: 64px;
}

.section-head .display {
  font-size: clamp(30px, 3.6vw, 48px);
  margin-top: 20px;
}

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

.page-hero {
  background: var(--shell);
  padding: 96px var(--gutter) 84px;
  text-align: center;
  animation: fadeUp 0.8s ease both;
}

.page-hero .display {
  font-size: clamp(34px, 4.6vw, 62px);
  margin-top: 22px;
}

.page-hero__intro {
  max-width: 560px;
  margin: 26px auto 0;
  font-size: 14.5px;
  line-height: 1.9;
  color: var(--taupe-dark);
}

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

.hero {
  position: relative;
  height: 100vh;
  min-height: 744px;
  overflow: hidden;
  background: var(--shell-deep);
}

.hero__image {
  position: absolute;
  inset: 0;
  background-size: cover;
  background-position: 58% 30%;
  background-repeat: no-repeat;
  background-attachment: fixed;
}

.hero__scrim {
  position: absolute;
  inset: 0;
  background: linear-gradient(
    to top,
    rgba(38, 27, 25, 0.66) 0%,
    rgba(38, 27, 25, 0.56) 30%,
    rgba(38, 27, 25, 0.54) 60%,
    rgba(38, 27, 25, 0.42) 100%
  );
}

.hero__body {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 0 var(--gutter);
  text-align: center;
}

.hero__body .eyebrow--light {
  animation: fadeUp 1s ease both;
}

.hero__title {
  font-family: var(--serif);
  font-weight: 300;
  font-size: clamp(44px, 6.4vw, 88px);
  line-height: 1.02;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--bone);
  margin: 24px 0 0;
  text-wrap: pretty;
  animation: fadeUp 1.1s ease 0.12s both;
}

.hero__text {
  max-width: 520px;
  font-size: 15px;
  line-height: 1.85;
  color: rgb(var(--bone-rgb) / 0.9);
  margin: 26px 0 0;
  animation: fadeUp 1.1s ease 0.24s both;
}

.hero__cta {
  margin-top: 38px;
  animation: fadeUp 1.1s ease 0.36s both;
}

.hero__sentinel {
  position: absolute;
  bottom: 0;
  left: 0;
  width: 1px;
  height: 1px;
  pointer-events: none;
}

/* --------------------------------------------------------------- welcome */

.welcome {
  text-align: center;
  animation: fadeUp 0.9s ease both;
}

.welcome__body {
  font-family: var(--serif);
  font-weight: 300;
  font-size: clamp(24px, 2.6vw, 34px);
  line-height: 1.5;
  color: var(--ink);
  margin: 28px 0 0;
  text-wrap: pretty;
}

/* ------------------------------------------------------- service preview */

.service-rows {
  display: flex;
  flex-direction: column;
  gap: 64px;
}

.service-row {
  display: grid;
  grid-template-columns: 0.9fr 1fr;
  gap: 40px;
  align-items: stretch;
}

.service-row--flip,
.service-rows > .service-row:nth-of-type(even) {
  grid-template-columns: 1fr 0.9fr;
}

.service-row__media {
  aspect-ratio: 1 / 1;
  position: relative;
  overflow: hidden;
  background: var(--shell-deep);
}

.service-row--flip .service-row__media,
.service-rows > .service-row:nth-of-type(even) .service-row__media {
  order: 2;
}

.service-row__media img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.service-row__body {
  background: var(--shell);
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 72px 68px;
  transition: background 0.5s;
  color: inherit;
}

.service-row:hover .service-row__body {
  background: var(--shell-deep);
}

.service-row__title {
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(30px, 3.2vw, 42px);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink);
  margin: 0;
  line-height: 1.25;
}

.service-row__text {
  font-size: 17px;
  line-height: 1.9;
  color: var(--taupe-dark);
  margin: 24px 0 0;
  max-width: 520px;
  text-wrap: pretty;
}

/* -------------------------------------------------------------- split band */

.split {
  display: grid;
  align-items: stretch;
}

.split--why {
  grid-template-columns: 1.15fr 1fr;
  background: var(--shell-deep);
}

.split--steps {
  grid-template-columns: 1fr 1.15fr;
  background: var(--bone);
}

.split__media {
  min-height: 520px;
  position: relative;
  overflow: hidden;
  background: var(--shell-deep);
}

.split__media img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.split__panel {
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 88px 64px;
}

.split__panel--clay {
  background: var(--clay);
}

.split__panel--bone {
  background: var(--bone);
  padding: 104px 64px;
}

.split__heading {
  font-family: var(--serif);
  font-weight: 300;
  font-size: clamp(28px, 3.2vw, 42px);
  line-height: 1.2;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  margin: 22px 0 0;
}

.split__panel--clay .split__heading {
  color: #241c1a;
}

.split__panel--bone .split__heading {
  color: var(--ink);
}

.split__text {
  font-size: 14.5px;
  line-height: 1.9;
  margin: 26px 0 0;
  max-width: 420px;
}

.split__panel--clay .split__text {
  color: #3e332f;
}

.split__panel--bone .split__text {
  color: var(--taupe-darker);
  max-width: 440px;
  margin-top: 24px;
}

/* ----------------------------------------------------------------- steps */

.steps {
  display: flex;
  flex-direction: column;
  margin-top: 36px;
}

.step {
  display: grid;
  grid-template-columns: 96px 1fr;
  gap: 28px;
  align-items: stretch;
  padding: 26px 0;
  border-top: 1px solid var(--sand);
}

.step__numeral {
  display: flex;
  align-items: center;
  justify-content: center;
}

.step__title {
  font-family: var(--serif);
  font-size: 20px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink);
  margin: 0;
  font-weight: 400;
}

.step__body {
  font-size: 13.5px;
  line-height: 1.8;
  color: var(--grey-warm);
  margin-top: 8px;
}

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

.gallery-preview__head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 32px;
  margin-bottom: 52px;
}

.gallery-preview__head .display {
  font-size: clamp(30px, 3.4vw, 44px);
  margin-top: 18px;
}

.tile {
  aspect-ratio: 3 / 4;
  overflow: hidden;
  background: var(--shell-deep);
}

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

.tile:hover img {
  transform: scale(1.05);
}

/* ------------------------------------------------------------ closing CTA */

.closing-cta {
  position: relative;
  padding: 132px var(--gutter);
  text-align: center;
  background: var(--ink);
  overflow: hidden;
}

.closing-cta__inner {
  position: relative;
  max-width: 640px;
  margin: 0 auto;
}

.closing-cta__heading {
  font-family: var(--serif);
  font-weight: 300;
  font-size: clamp(32px, 4.4vw, 60px);
  line-height: 1.12;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--bone);
  margin: 24px 0 0;
}

.closing-cta__text {
  font-size: 14.5px;
  line-height: 1.9;
  color: rgb(var(--bone-rgb) / 0.72);
  margin: 26px 0 0;
}

.closing-cta .btn {
  margin-top: 40px;
}

/* ---------------------------------------------------------------- about */

.about-grid {
  max-width: 1120px;
  margin: 0 auto;
  display: grid;
  grid-template-columns: 0.9fr 1fr;
  gap: 72px;
  align-items: center;
}

.about-grid__portrait {
  aspect-ratio: 3 / 4;
  overflow: hidden;
  background: var(--shell-deep);
}

.about-grid__portrait img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.about__byline {
  font-size: 10px;
  letter-spacing: 0.4em;
  text-transform: uppercase;
  color: var(--taupe);
}

.about__heading {
  font-family: var(--serif);
  font-weight: 300;
  font-size: clamp(26px, 3vw, 40px);
  line-height: 1.24;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--ink);
  margin: 20px 0 0;
}

.about__body p {
  font-size: 15px;
  line-height: 1.95;
  color: var(--taupe-darker);
  margin: 28px 0 0;
}

.about__body p + p {
  margin-top: 20px;
}

.stats {
  display: flex;
  gap: 44px;
  margin-top: 44px;
  padding-top: 32px;
  border-top: 1px solid var(--sand);
  flex-wrap: wrap;
}

.stat__value {
  font-family: var(--serif);
  font-size: 36px;
  font-weight: 300;
  color: var(--burgundy);
  line-height: 1;
}

.stat__label {
  font-size: 9.5px;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  color: var(--mono-label);
  margin-top: 8px;
}

.testimonial {
  background: var(--clay);
  padding: 104px var(--gutter);
  text-align: center;
}

.testimonial__quote {
  font-family: var(--serif);
  font-style: italic;
  font-weight: 300;
  font-size: clamp(22px, 2.6vw, 34px);
  line-height: 1.6;
  color: #241c1a;
  text-wrap: pretty;
  max-width: 700px;
  margin: 0 auto;
}

.testimonial__attribution {
  font-size: 10px;
  letter-spacing: 0.32em;
  text-transform: uppercase;
  color: #5f4f49;
  margin-top: 30px;
}

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

.service-list {
  max-width: 1080px;
  margin: 0 auto;
}

.service-item {
  display: grid;
  grid-template-columns: 96px 1fr 200px;
  gap: 32px;
  align-items: start;
  padding: 52px 0;
  border-bottom: 1px solid var(--sand);
}

.service-item__numeral {
  display: flex;
  align-items: flex-start;
  justify-content: center;
}

.service-item__title {
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(22px, 2.4vw, 30px);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink);
  margin: 0;
}

.service-item__body {
  font-size: 14.5px;
  line-height: 1.9;
  color: var(--taupe-darker);
  margin: 16px 0 0;
  max-width: 560px;
}

.tag-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 20px;
  padding: 0;
  list-style: none;
}

.tag {
  font-size: 9.5px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--taupe-mid);
  border: 1px solid var(--sand-line);
  padding: 7px 13px;
}

.service-item__price {
  text-align: right;
  padding-top: 6px;
}

.service-item__price-label {
  font-size: 9.5px;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  color: var(--taupe);
}

.service-item__price-value {
  font-family: var(--serif);
  font-size: 30px;
  font-weight: 300;
  color: var(--burgundy);
  margin-top: 8px;
}

.service-outro {
  text-align: center;
  padding-top: 64px;
}

.service-outro p {
  font-size: 14px;
  line-height: 1.9;
  color: var(--taupe-dark);
  max-width: 520px;
  margin: 0 auto;
}

.service-outro .btn {
  margin-top: 30px;
}

/* --------------------------------------------------------------- rentals */

.filter-bar {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  justify-content: center;
  padding-bottom: 52px;
  border-bottom: 1px solid var(--sand);
  margin-bottom: 52px;
}

.filter-chip {
  font-family: var(--sans);
  font-size: 10px;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  padding: 12px 22px;
  border: 1px solid var(--sand-line);
  background: transparent;
  color: var(--taupe-dark);
  cursor: pointer;
  transition: all 0.3s;
}

.filter-chip:hover {
  border-color: var(--ink);
  color: var(--ink);
}

/* The catalog's chips are buttons that filter in place; the journal's are
   links to a page per category. Same look, two ways of saying "this one". */
.filter-chip[aria-pressed="true"],
.filter-chip[aria-current="page"] {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--bone);
}

.rental-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(258px, 1fr));
  gap: 40px 28px;
}

.rental-card {
  display: flex;
  flex-direction: column;
}

.rental-card[hidden] {
  display: none;
}

.rental-card__media {
  aspect-ratio: 4 / 5;
  overflow: hidden;
  background: var(--shell-deep);
}

.rental-card__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.rental-card__body {
  padding: 20px 2px 0;
}

.rental-card__cat {
  font-size: 9.5px;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--pill-label);
}

.rental-card__name {
  font-family: var(--serif);
  font-weight: 400;
  font-size: 21px;
  letter-spacing: 0.06em;
  color: var(--ink);
  margin: 10px 0 0;
  line-height: 1.3;
}

.rental-card__desc {
  font-size: 12.5px;
  line-height: 1.75;
  color: var(--grey-warm);
  margin: 10px 0 0;
}

.rental-card__meta {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-top: 16px;
  padding-top: 14px;
  border-top: 1px solid var(--sand);
}

.rental-card__price {
  font-family: var(--serif);
  font-size: 22px;
  font-weight: 400;
  color: var(--burgundy);
}

.rental-card__unit {
  font-size: 9.5px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--taupe);
}

.rental-empty {
  text-align: center;
  color: var(--taupe-dark);
  font-size: 14px;
  padding: 40px 0;
}

.reserve {
  text-align: center;
  margin-top: 88px;
  padding-top: 56px;
  border-top: 1px solid var(--sand);
}

.reserve__heading {
  font-family: var(--serif);
  font-weight: 300;
  font-size: clamp(24px, 2.8vw, 36px);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink);
  margin: 0;
}

.reserve__body {
  font-size: 14px;
  line-height: 1.9;
  color: var(--taupe-dark);
  max-width: 480px;
  margin: 20px auto 0;
}

.reserve__form {
  max-width: 660px;
  margin: 44px auto 0;
  text-align: left;
  background: var(--shell);
  padding: 48px 44px;
}

.reserve__note {
  font-size: 11.5px;
  line-height: 1.7;
  color: var(--mono-label);
  margin-top: 20px;
}

/* ----------------------------------------------------------------- forms */

.field {
  display: flex;
  flex-direction: column;
  gap: 9px;
}

.field label,
.field-group__label {
  font-size: 9.5px;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  color: var(--taupe);
}

.field input,
.field textarea {
  font-family: var(--sans);
  font-size: 14px;
  font-weight: 300;
  color: var(--ink);
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--sand-deep);
  padding: 11px 0;
  outline: none;
  border-radius: 0;
}

.field textarea {
  resize: vertical;
}

.field input:focus,
.field textarea:focus {
  border-bottom-color: var(--burgundy);
}

.field-pair {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 26px;
}

.field-stack {
  display: flex;
  flex-direction: column;
  gap: 26px;
}

.field-group {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.chip-row {
  display: flex;
  flex-wrap: wrap;
  gap: 9px;
}

.chip {
  font-family: var(--sans);
  font-size: 10px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  padding: 11px 18px;
  border: 1px solid var(--sand-line);
  background: transparent;
  color: var(--taupe-dark);
  cursor: pointer;
  transition: all 0.3s;
}

.chip[aria-pressed="true"] {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--bone);
}

.form-status {
  margin-top: 18px;
  font-size: 13px;
  line-height: 1.7;
  color: var(--burgundy);
}

.form-status:empty {
  margin-top: 0;
}

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

.gallery-grid {
  --gallery-gap: 20px;
  --gallery-cols: 3;
  max-width: var(--shell-max);
  margin: 0 auto;
  display: grid;
  grid-template-columns: repeat(var(--gallery-cols), 1fr);
  gap: var(--gallery-gap);
  /* A wide tile takes two columns, so it needs two free ones — and at the two
     columns a phone gets, "two free" means a whole empty row. Reaching one with
     only the second column left, the browser cannot split it: it moves the tile
     down and leaves the half-row behind it blank. Three such gaps opened part
     way down the gallery on a phone, each reading as a photograph that failed
     to load rather than as a layout that ran out of room.

     `dense` lets a later single-column tile drop back into a gap the placement
     has already passed. The trade is that such a tile arrives ahead of its
     turn: measured here, ten of the thirty-five tiles shift, every one of them
     by a single place — the tile after the gap swaps with the one before it.
     For a wall of photographs in no particular order that costs nothing. There
     is no sequence to preserve, and no tile is focusable, so neither the tab
     order nor a screen reader's reading order moves at all.

     Three columns has always packed without gaps, and this leaves it exactly as
     it was: same rows, same order, same height, measured. It is set here rather
     than in the phone breakpoint so that a client who adds tiles in the CMS
     cannot open the same hole at a width nobody thought to check. */
  grid-auto-flow: row dense;
}

.gallery-tile {
  overflow: hidden;
  background: var(--shell-deep);
  aspect-ratio: 4 / 5;
}

.gallery-tile--wide {
  grid-column: span 2;
}

/* A wide tile is two columns AND the gap between them, so a fixed ratio can
   never match the standard tile's height: at three columns it came out 13px
   taller, and the rows read as ragged. The ratio it would need is
   (2col + gap) / (1.25col), which depends on the column width and so cannot be
   written as a ratio at all.

   So the height is stated once, in terms of the column width, and every tile
   takes it. Container query units are what make the column width knowable:
   100cqw inside the grid is the grid's own width, and the columns are equal
   fractions of what is left after the gaps.

   The aspect-ratios above stay as the fallback for anything without container
   query support — a browser that ignored the height below and had no ratio
   would collapse every tile to nothing. */
@supports (container-type: inline-size) {
  .gallery-grid { container-type: inline-size; }

  .gallery-tile,
  .gallery-tile--wide {
    aspect-ratio: auto;
    height: calc(
      (100cqw - (var(--gallery-cols) - 1) * var(--gallery-gap))
      / var(--gallery-cols) * 1.25
    );
  }
}

.gallery-tile img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* ------------------------------------------------------------------ blog */

.post-list {
  max-width: 1000px;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
}

.post-row {
  display: grid;
  grid-template-columns: 1fr 1.15fr;
  gap: 52px;
  align-items: center;
  padding: 56px 0;
  border-bottom: 1px solid var(--sand);
}

.post-row__media {
  aspect-ratio: 4 / 3;
  overflow: hidden;
  background: var(--shell-deep);
}

.post-row__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.post-row__meta {
  font-size: 9.5px;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  color: var(--pill-label);
}

.post-row__title {
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(22px, 2.5vw, 32px);
  line-height: 1.28;
  letter-spacing: 0.06em;
  color: var(--ink);
  margin: 16px 0 0;
  text-wrap: pretty;
}

.post-row__title a {
  color: inherit;
}

.post-row__title a:hover {
  color: var(--burgundy);
}

.post-row__excerpt {
  font-size: 14px;
  line-height: 1.9;
  color: var(--taupe-dark);
  margin: 16px 0 0;
}

.post-row__more {
  margin-top: 22px;
  font-size: 10px;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  color: var(--burgundy);
  border-bottom: 1px solid var(--blush);
  display: inline-block;
  padding-bottom: 5px;
}

.empty-state {
  max-width: 560px;
  margin: 0 auto;
  text-align: center;
  padding: 40px 0 20px;
}

.empty-state p {
  font-size: 15px;
  line-height: 1.9;
  color: var(--taupe-dark);
}

/* ------------------------------------------------------------- post page */

.post {
  max-width: 720px;
  margin: 0 auto;
}

.post__cover {
  max-width: 1000px;
  margin: 0 auto 64px;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  background: var(--shell-deep);
}

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

.post__body {
  font-size: 16px;
  line-height: 1.95;
  color: var(--taupe-darker);
}

.post__body h2,
.post__body h3 {
  font-family: var(--serif);
  font-weight: 400;
  letter-spacing: 0.06em;
  color: var(--ink);
  margin: 48px 0 0;
}

.post__body h2 {
  font-size: 28px;
}

.post__body h3 {
  font-size: 22px;
}

.post__body p {
  margin: 20px 0 0;
}

.post__body img {
  height: auto;
  margin: 32px 0 0;
}

.post__body blockquote {
  margin: 32px 0 0;
  padding-left: 26px;
  border-left: 2px solid var(--blush);
  font-family: var(--serif);
  font-style: italic;
  font-size: 20px;
  line-height: 1.6;
  color: var(--ink);
}

.post__body ul,
.post__body ol {
  margin: 20px 0 0;
  padding-left: 22px;
}

.post__body li {
  margin-top: 8px;
}

/* A photo dropped into the middle of a post: the same width as the text it
   interrupts, with the caption in the site's mono label voice. */
.post-figure {
  margin: 40px 0 0;
}

.post-figure img {
  display: block;
  width: 100%;
  height: auto;
}

.post-figure figcaption {
  margin-top: 12px;
  font-family: var(--sans);
  font-size: 12px;
  letter-spacing: 0.08em;
  line-height: 1.7;
  color: var(--taupe-mid);
}

.post__category {
  color: inherit;
  border-bottom: 1px solid var(--sand-deep);
}

.post__category:hover {
  color: var(--burgundy);
  border-bottom-color: var(--blush);
}

/* The two neighbouring posts. One column when there is only a newer post to
   offer, which is why the empty side is a placeholder span rather than nothing:
   the older step stays on the right where it always is. */
.post-nav {
  max-width: 720px;
  margin: 72px auto 0;
  padding-top: 36px;
  border-top: 1px solid var(--sand);
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 32px;
}

.post-nav__step {
  display: block;
  color: var(--taupe-dark);
}

.post-nav__step--older {
  text-align: right;
}

.post-nav__label {
  display: block;
  font-family: var(--sans);
  font-size: 10px;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--mono-label);
}

.post-nav__title {
  display: block;
  margin-top: 10px;
  font-family: var(--serif);
  font-size: 19px;
  line-height: 1.4;
  color: var(--ink);
}

.post-nav__step:hover .post-nav__title {
  color: var(--burgundy);
}

.post__back {
  max-width: 720px;
  margin: 64px auto 0;
  padding-top: 32px;
  border-top: 1px solid var(--sand);
}

/* Journal pagination. Only painted when there is a second page, so it never
   shows a row of controls that go nowhere. */
.pager {
  max-width: 1000px;
  margin: 72px auto 0;
  padding-top: 36px;
  border-top: 1px solid var(--sand);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
}

.pager__step {
  font-family: var(--sans);
  font-size: 11px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ink);
}

.pager__step:hover {
  color: var(--burgundy);
}

.pager__step--spent {
  color: var(--clay);
}

.pager__count {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.14em;
  color: var(--mono-label);
}

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

.contact-grid {
  max-width: 1080px;
  margin: 0 auto;
  display: grid;
  grid-template-columns: 1.25fr 0.85fr;
  gap: 80px;
  align-items: start;
}

.contact-aside {
  background: var(--shell);
  padding: 48px 40px;
}

.contact-aside__heading {
  font-family: var(--serif);
  font-size: 15px;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--burgundy);
}

.contact-aside__rule {
  width: 36px;
  height: 1px;
  background: var(--blush);
  border: 0;
  margin: 22px 0 30px;
}

.contact-row {
  margin-bottom: 26px;
}

.contact-row__label {
  font-size: 9.5px;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  color: var(--taupe);
}

.contact-row__value {
  font-size: 14px;
  line-height: 1.7;
  color: #3e332f;
  margin-top: 8px;
}

.contact-row__value a {
  color: #3e332f;
}

.contact-row__value a:hover {
  color: var(--burgundy);
}

/* --------------------------------------------------------- floating CTA */

.floating-cta {
  position: fixed;
  right: 32px;
  bottom: 32px;
  z-index: 60;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.5s cubic-bezier(0.4, 0, 0.2, 1);
}

.floating-cta.is-visible {
  opacity: 1;
  pointer-events: auto;
}

.floating-cta__button {
  position: relative;
  /* inline-block + a block label so the anchor takes the label's real height.
     While the label was inline its padding never counted toward the anchor's
     box, leaving it 19px tall against a 46px visual — which made the frame
     shorter than the button it was meant to surround. */
  display: inline-block;
  animation: ctaGlow 2.1s ease-out infinite, ctaBob 2.1s ease-in-out infinite;
}

.floating-cta__button:hover {
  animation: none;
}

/* Sits just outside the button's edges and stretches with it. */
.floating-cta__frame {
  position: absolute;
  inset: -9px;
  pointer-events: none;
  overflow: visible;
}

.floating-cta__frame > svg {
  display: block;
  width: 100%;
  height: 100%;
  overflow: visible;
}

/* The vine: four edges, each scaling in from the corner the previous one
   finished at, so it reads as one line travelling clockwise. */
.floating-cta__edge {
  position: absolute;
  background: #4a6741;
  transition: transform 0.36s ease;
}

.floating-cta__edge--t,
.floating-cta__edge--b {
  height: 1.7px;
  width: 100%;
  transform: scaleX(0);
}

.floating-cta__edge--r,
.floating-cta__edge--l {
  width: 1.7px;
  height: 100%;
  transform: scaleY(0);
}

.floating-cta__edge--t {
  top: 0;
  left: 0;
  transform-origin: left center;
}

.floating-cta__edge--r {
  top: 0;
  right: 0;
  transform-origin: center top;
}

.floating-cta__edge--b {
  bottom: 0;
  right: 0;
  transform-origin: right center;
}

.floating-cta__edge--l {
  bottom: 0;
  left: 0;
  transform-origin: center bottom;
}

.floating-cta__button:hover .floating-cta__edge,
.floating-cta__button:focus-visible .floating-cta__edge {
  transform: scale(1);
}

.floating-cta__button:hover .floating-cta__edge--r,
.floating-cta__button:focus-visible .floating-cta__edge--r {
  transition-delay: 0.36s;
}

.floating-cta__button:hover .floating-cta__edge--b,
.floating-cta__button:focus-visible .floating-cta__edge--b {
  transition-delay: 0.72s;
}

.floating-cta__button:hover .floating-cta__edge--l,
.floating-cta__button:focus-visible .floating-cta__edge--l {
  transition-delay: 1.08s;
}

/* Corner sprigs: fixed aspect so they never squash, flipped per corner. */
.floating-cta__sprig {
  position: absolute;
  width: 36px;
  height: 36px;
}

.floating-cta__sprig--tl {
  top: -13px;
  left: -13px;
}

.floating-cta__sprig--tr {
  top: -13px;
  right: -13px;
  transform: scaleX(-1);
}

.floating-cta__sprig--br {
  bottom: -13px;
  right: -13px;
  transform: scale(-1, -1);
}

.floating-cta__sprig--bl {
  bottom: -13px;
  left: -13px;
  transform: scaleY(-1);
}

/* The flip lives on the parent so this transform is free to animate. */
.floating-cta__sprig-inner {
  display: block;
  width: 100%;
  height: 100%;
  transform: scale(0.35);
  transform-origin: center;
  opacity: 0;
  transition: transform 0.85s cubic-bezier(0.34, 1.4, 0.4, 1), opacity 0.5s ease;
}

.floating-cta__sprig-inner > svg {
  display: block;
  width: 100%;
  height: 100%;
  overflow: visible;
}

.floating-cta__button:hover .floating-cta__sprig-inner,
.floating-cta__button:focus-visible .floating-cta__sprig-inner {
  transform: scale(1);
  opacity: 1;
}

/* Stagger the corners so the sprigs open after the vine reaches them. */
.floating-cta__button:hover .floating-cta__sprig--tl .floating-cta__sprig-inner,
.floating-cta__button:focus-visible .floating-cta__sprig--tl .floating-cta__sprig-inner { transition-delay: 0.1s; }
.floating-cta__button:hover .floating-cta__sprig--tr .floating-cta__sprig-inner,
.floating-cta__button:focus-visible .floating-cta__sprig--tr .floating-cta__sprig-inner { transition-delay: 0.46s; }
.floating-cta__button:hover .floating-cta__sprig--br .floating-cta__sprig-inner,
.floating-cta__button:focus-visible .floating-cta__sprig--br .floating-cta__sprig-inner { transition-delay: 0.82s; }
.floating-cta__button:hover .floating-cta__sprig--bl .floating-cta__sprig-inner,
.floating-cta__button:focus-visible .floating-cta__sprig--bl .floating-cta__sprig-inner { transition-delay: 1.18s; }

.sprig-stem,
.sprig-leaves {
  stroke-dashoffset: 100;
  transition: stroke-dashoffset 0.7s cubic-bezier(0.22, 0.61, 0.36, 1);
}

.sprig-leaves {
  transition-duration: 0.55s;
}

.floating-cta__button:hover .sprig-stem,
.floating-cta__button:focus-visible .sprig-stem,
.floating-cta__button:hover .sprig-leaves,
.floating-cta__button:focus-visible .sprig-leaves {
  stroke-dashoffset: 0;
}

.sprig-bloom circle {
  fill: var(--bone);
}

.floating-cta__label {
  position: relative;
  display: block;
  background: var(--burgundy);
  color: var(--bone);
  font-size: 10.5px;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  padding: 17px 30px;
  box-shadow: 0 18px 38px -14px rgba(42, 33, 31, 0.5);
  transition: background 0.35s;
}

.floating-cta__button:hover .floating-cta__label,
.floating-cta__button:focus-visible .floating-cta__label {
  background: var(--ink-deep);
}

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

.site-footer {
  background: var(--ink);
  padding: 76px var(--gutter) 40px;
}

.site-footer__grid {
  display: grid;
  grid-template-columns: 1.4fr 1fr 1fr 1fr;
  gap: 52px;
  padding-bottom: 56px;
  border-bottom: 1px solid rgb(var(--bone-rgb) / 0.14);
}

.site-footer__wordmark {
  width: 212px;
  height: auto;
  display: block;
}

.site-footer__tagline {
  font-family: var(--serif);
  font-style: italic;
  font-size: 19px;
  font-weight: 300;
  line-height: 1.6;
  color: rgb(var(--bone-rgb) / 0.72);
  margin: 28px 0 0;
  max-width: 280px;
}

.site-footer__label {
  font-size: 9.5px;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: rgb(var(--bone-rgb) / 0.45);
}

.site-footer__list {
  display: flex;
  flex-direction: column;
  gap: 13px;
  margin: 22px 0 0;
  padding: 0;
  list-style: none;
  font-size: 12.5px;
  font-weight: 300;
  line-height: 1.6;
  color: rgb(var(--bone-rgb) / 0.78);
}

.site-footer__list a {
  color: rgb(var(--bone-rgb) / 0.78);
  letter-spacing: 0.06em;
  transition: color 0.3s;
}

.site-footer__list a:hover {
  color: var(--blush);
}

.site-footer__bar {
  display: flex;
  justify-content: space-between;
  gap: 24px;
  padding-top: 26px;
  font-size: 10px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: rgb(var(--bone-rgb) / 0.38);
}

/* ------------------------------------------------------------ responsive */

@media (max-width: 1080px) {
  .site-footer__grid {
    grid-template-columns: 1fr 1fr;
    gap: 44px;
  }
}

@media (max-width: 960px) {
  :root {
    --gutter: 28px;
  }

  .nav-toggle {
    display: flex;
  }

  /* Stacked, and each row a full-width band rather than a word: the link is
     then as wide as the menu and 44px tall, so it is hit by aiming anywhere on
     the line instead of at eleven pixels of tracked capitals. The gap goes,
     because the padding now provides the rhythm. */
  .site-nav {
    display: none;
    width: 100%;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    padding: 10px 0 8px;
    border-top: 1px solid var(--sand);
  }

  .site-nav.is-open {
    display: flex;
  }

  .site-nav__link {
    padding: 14px 0;
  }

  /* The desktop underline is a 1px rule under the words; here the row is the
     target, so the current page is marked at its start instead. */
  .site-nav__link[aria-current="page"] {
    border-bottom-color: transparent;
    box-shadow: inset 3px 0 0 var(--blush);
    padding-left: 12px;
  }

  .site-header__inner {
    flex-wrap: wrap;
    gap: 12px;
  }

  /* The site name is a field a client can edit, so no amount of sizing below
     guarantees it fits. Letting the wordmark shrink and clip means a long name
     loses its tail rather than pushing the hamburger onto a line of its own —
     nowrap keeps it on one line, and min-width:0 is what lets a flex item
     shrink past the width of its own content at all. */
  .brand {
    flex: 0 1 auto;
    min-width: 0;
  }

  .brand > span {
    min-width: 0;
  }

  .brand__name,
  .brand__tagline {
    overflow: hidden;
    text-overflow: ellipsis;
  }

  .hero {
    height: auto;
    min-height: 600px;
    padding: 140px 0;
  }

  .hero__image {
    background-attachment: scroll;
  }

  .hero__body {
    position: relative;
    inset: auto;
    padding: 0 var(--gutter);
  }

  /* `.service-rows > .service-row:nth-of-type(even)` is spelled out here rather
     than covered by `.service-row`, because a media query adds no specificity:
     the two-column rule up top is a class plus a child combinator plus a
     pseudo-class and simply outranked the one-column rule below. Every even row
     on the home page — half of them — stayed two columns wide on a phone, and
     since the media tile is a square sized off its own column, the row was
     wider than the viewport and dragged the whole page sideways with it. */
  .service-row,
  .service-row--flip,
  .service-rows > .service-row:nth-of-type(even),
  .split--why,
  .split--steps,
  .about-grid,
  .contact-grid,
  .post-row {
    grid-template-columns: 1fr;
  }

  /* A grid track is `minmax(auto, 1fr)`, and `auto` as a minimum is min-content
     — so one long unbreakable word (an email address, a URL) makes the track
     wider than the grid and pushes the column off the side of the page. */
  .service-row > *,
  .split > *,
  .about-grid > *,
  .contact-grid > *,
  .post-row > * {
    min-width: 0;
  }

  .service-row--flip .service-row__media,
  .service-rows > .service-row:nth-of-type(even) .service-row__media {
    order: 0;
  }

  .split--why .split__media,
  .split--steps .split__media {
    min-height: 380px;
  }

  .split__panel,
  .split__panel--bone {
    padding: 64px var(--gutter);
  }

  .service-row__body {
    padding: 48px 40px;
  }

  .about-grid {
    gap: 44px;
  }

  .contact-grid {
    gap: 48px;
  }


  /* Two columns, and the height above follows from the same variable rather
     than needing its own rule. A wide tile is the full width here. */
  .gallery-grid {
    --gallery-cols: 2;
  }

  .gallery-tile--wide {
    grid-column: span 2;
  }

  .service-item {
    grid-template-columns: 64px 1fr;
    gap: 20px;
  }

  .service-item__price {
    grid-column: 2;
    text-align: left;
    padding-top: 20px;
  }

  .section {
    padding: 80px var(--gutter);
  }

  .post-row {
    gap: 28px;
  }
}

@media (max-width: 640px) {
  .field-pair {
    grid-template-columns: 1fr;
  }

  /* Two 19px serif titles side by side is two words per line on a phone. */
  .post-nav {
    grid-template-columns: 1fr;
    gap: 26px;
  }

  .post-nav__step--older {
    text-align: left;
  }

  .pager {
    flex-direction: column;
    gap: 14px;
  }

  .reserve__form {
    padding: 32px 24px;
  }

  .site-footer__grid {
    grid-template-columns: 1fr;
  }

  .site-footer__bar {
    flex-direction: column;
    gap: 10px;
  }

  .gallery-preview__head {
    flex-direction: column;
    align-items: flex-start;
    gap: 18px;
  }

  .stats {
    gap: 28px;
  }

  .floating-cta {
    right: 16px;
    bottom: 16px;
  }

  .floating-cta__label {
    padding: 15px 22px;
    font-size: 10px;
  }

  /* The wordmark and the hamburger share one line, so the wordmark has to fit
     in what is left after 44px of button. At 19px with 0.34em of tracking
     "Burgundy Loft" alone measured 243px against the 264px a 320px phone has
     between its gutters: the header ran off the side of every page, and once
     the row was allowed to wrap the button dropped onto a line of its own at
     the left. Tracking is what is given back first — it is the widest part of
     the setting and the least missed at this size — and the rest scales with
     the viewport rather than sitting on one value chosen for one phone. */
  .brand {
    gap: 10px;
  }

  .brand__mark {
    height: 40px;
  }

  .brand__name {
    font-size: clamp(12.5px, 4vw, 15px);
    letter-spacing: 0.2em;
  }

  .brand__tagline {
    font-size: clamp(7px, 2.2vw, 8px);
    letter-spacing: 0.3em;
  }

  /* The ceiling is the 44px the desktop clamp bottoms out at, so the two meet
     at this breakpoint and nothing changes above it; below it the title scales
     with the viewport. It had to: at 44px "REMEMBERED" — ten uppercase letters
     with 0.11em of tracking — is wider than a 320px screen, and the hero title
     was cropped at both edges by the section's own overflow. */
  .hero__title {
    font-size: clamp(30px, 9.5vw, 44px);
  }

  /* iOS zooms the page in on focus when a field's text is under 16px, and it
     does not zoom back out afterwards. */
  .field input,
  .field textarea {
    font-size: 16px;
  }

  .contact-aside {
    padding: 36px 24px;
  }

  /* An email address has nowhere to break, so it either wraps mid-word here or
     sets the width of the column it is in. */
  .contact-row__value,
  .site-footer__list {
    overflow-wrap: anywhere;
  }

  /* Uppercase serif with a tenth of an em of tracking sets very wide, and a
     heading is one long word more often than not — "CONSULTATION" alone came to
     310px against the 264px a 320px phone has between its gutters, and every
     display heading on the site was running off the edge. The clamps below all
     meet their existing values at 640px, so nothing changes above this
     breakpoint; below it the type scales with the viewport instead of sitting
     on a floor that assumed a wider screen. */
  .page-hero .display {
    font-size: clamp(24px, 7.4vw, 34px);
  }

  .section-head .display,
  .gallery-preview__head .display {
    font-size: clamp(22px, 6.6vw, 30px);
  }

  .service-row__title {
    font-size: clamp(22px, 6.6vw, 30px);
  }

  .split__heading {
    font-size: clamp(21px, 6.4vw, 28px);
  }

  .closing-cta__heading {
    font-size: clamp(24px, 7.4vw, 32px);
  }

  /* 68px of padding either side of a 320px screen leaves 184px for a title
     that needs rather more than that. */
  .service-row__body {
    padding: 40px 28px;
  }

  /* The numeral moves above its step rather than beside it: a 96px column for
     "1." left about 130px for the words, which is narrower than the single
     word "CONSULTATION" needs at any size worth reading. */
  .step {
    grid-template-columns: 1fr;
    gap: 10px;
  }

  .step__numeral {
    justify-content: flex-start;
  }
}

/* ------------------------------------------------------- touch hit areas */

/* Standalone links set in 10px tracked capitals are 14–19px tall, which is
   under half a fingertip. The extra height is an invisible overlay rather than
   padding because the underline on most of these IS their bottom border, and
   padding would drop the rule away from the words it belongs to. Kept to
   coarse pointers so a mouse, which needs none of it, gets none of it.

   Only links with clear space around them are listed. A link inside a
   paragraph or a stacked list would have its overlay reach over its
   neighbours and start swallowing their taps, which is worse than a small
   target. Those get real padding further down instead. */
@media (pointer: coarse) {
  .text-link,
  a.arrow-link,
  .review-card__link,
  .post-row__more,
  .pager__step {
    position: relative;
  }

  .text-link::after,
  a.arrow-link::after,
  .review-card__link::after,
  .post-row__more::after,
  .pager__step::after {
    content: "";
    position: absolute;
    inset: -13px 0;
  }

  /* The footer's Explore list is the other copy of the site navigation, and it
     was 15px-tall rows 13px apart — four links inside one thumb. The gap comes
     off as the padding goes on, so the column keeps the height it had. */
  .site-footer__list {
    gap: 2px;
  }

  .site-footer__list a {
    display: inline-block;
    padding: 9px 0;
  }

  /* The phone number and the email address are what anyone opens the contact
     sidebar for. Padding rather than the overlay above, because these sit in a
     stacked list and an overlay would reach into the row below it. */
  .contact-row {
    margin-bottom: 18px;
  }

  .contact-row__value a {
    display: inline-block;
    padding: 7px 0;
  }
}

/* -------------------------------------------------------------------- FAQ */

.faq-item {
  border-bottom: 1px solid var(--sand);
}

.faq-question {
  width: 100%;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 32px;
  background: transparent;
  border: 0;
  padding: 32px 0;
  text-align: left;
  cursor: pointer;
  font-family: var(--serif);
}

.faq-question__text {
  font-family: var(--serif);
  font-weight: 400;
  font-size: 21px;
  line-height: 1.4;
  letter-spacing: 0.04em;
  color: var(--ink);
}

.faq-question__sign {
  font-family: var(--serif);
  font-size: 22px;
  color: var(--blush);
  line-height: 1;
  flex-shrink: 0;
}

.faq-answer p {
  font-family: var(--sans);
  font-size: 14.5px;
  font-weight: 300;
  line-height: 1.95;
  color: var(--taupe-dark);
  margin: 0 0 32px;
  max-width: 640px;
}

/* ------------------------------------------------------------ placeholder */

/* Striped stand-in used wherever photography has not been shot yet. Defined
   last so it wins over the flat background on the tile it is applied to
   (.rental-card__media, .gallery-tile, .post-row__media, .tile). */
.placeholder {
  background: repeating-linear-gradient(135deg, #f1eae6 0 9px, #e7ded8 9px 18px);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 18px;
  text-align: center;
}

.placeholder span {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.1em;
  line-height: 1.7;
  color: var(--mono-label);
  white-space: pre-line;
}

.gallery-tile.placeholder span,
.post-row__media.placeholder span {
  font-size: 10.5px;
  line-height: 1.8;
}

/* ----------------------------------------------------------- social links */

.social-links {
  display: flex;
  gap: 14px;
  margin: 22px 0 0;
  padding: 0;
  list-style: none;
}

.social-link {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  color: rgb(var(--bone-rgb) / 0.78);
  border: 1px solid rgb(var(--bone-rgb) / 0.22);
  border-radius: 50%;
  transition: color 0.3s, border-color 0.3s, background 0.3s;
}

.social-link:hover,
.social-link:focus-visible {
  color: var(--ink);
  background: var(--blush);
  border-color: var(--blush);
}

.social-link__icon {
  width: 19px;
  height: 19px;
  display: block;
}

/* ------------------------------------------- editor-swappable media tiles */

/* Every media tile ships with both an <img> and its placeholder label, and the
   `placeholder` class decides which one is painted — so uploading a photo in
   the editor is a class toggle rather than a rebuild of the tile. */
.placeholder > img {
  display: none;
}

:not(.placeholder) > [data-bh-ph] {
  display: none;
}

/* HoneyBook enquiry embed -------------------------------------------------
   The widget renders its own form into .hb-p-*; all this does is hold the
   space so the page does not jump as it arrives, and give the CMS editor
   something honest to look at in its place. */
.hb-embed { min-height: 460px; }

.hb-embed[data-hb-placeholder] {
  display: grid;
  place-items: center;
  padding: 48px 28px;
  text-align: center;
  border: 1px dashed var(--sand-deep);
  border-radius: 14px;
  background: var(--shell);
  color: var(--taupe-mid);
  font-size: 13px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.hb-embed[data-hb-placeholder] .hb-p-66b6227826700a0008d77856-1 { display: none; }
.hb-embed[data-hb-placeholder]::after {
  content: "Booking form \2014 shown on the live site. Edit its fields in HoneyBook.";
  max-width: 30ch;
  line-height: 1.7;
}

.hb-embed__fallback {
  padding: 24px 0;
  color: var(--taupe-dark);
}

/* Reviews ------------------------------------------------------------------
   One card, two surfaces: a scrolling rail on the home page and a masonry wall
   on /reviews/. Everything specific to a surface lives on the container, so the
   card itself never has to know which one it is in. */

.review-card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 30px 30px 26px;
  background: var(--shell);
  border: 1px solid var(--sand-line);
  border-radius: 16px;
}

/* A row the client started and has not filled in yet. */
.review-card--blank { display: none; }

.review-card__stars {
  font-size: 15px;
  letter-spacing: 0.18em;
  line-height: 1;
  color: var(--burgundy);
}
.review-card__stars-off { color: var(--clay); }

.review-card__text {
  font-family: var(--serif);
  font-size: 19px;
  line-height: 1.6;
  color: var(--ink);
  margin: 0;
}

.review-card__byline {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 12px;
  margin-top: auto;
}

.review-card__author {
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--taupe-darker);
}

.review-card__when {
  font-size: 11px;
  letter-spacing: 0.08em;
  color: var(--taupe);
}

.review-card__link {
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--burgundy);
  border-bottom: 1px solid var(--blush);
  align-self: flex-start;
  padding-bottom: 2px;
}
.review-card__link:hover { border-bottom-color: var(--burgundy); }

/* One switch for every optional part of a card, and for the two states of the
   section. Anything the client has not filled in takes up no room at all rather
   than drawing its own margins around nothing. */
.review-card .is-empty,
.review-wall-wrap.is-empty,
.review-rail-wrap.is-empty,
.review-empty.is-empty { display: none; }

/* --- the wall on /reviews/ --- */
.review-wall {
  column-width: 320px;
  column-gap: 20px;
  max-width: var(--shell-max);
  margin: 0 auto;
  padding: 0 var(--gutter);
}
/* Without this a review is split across two columns mid-sentence. */
.review-wall .review-card {
  break-inside: avoid;
  margin: 0 0 20px;
}

.review-empty {
  max-width: 46ch;
  margin: 0 auto;
  padding: 40px var(--gutter);
  text-align: center;
  color: var(--taupe-mid);
  font-family: var(--serif);
  font-size: 20px;
}

.review-prompt {
  max-width: 560px;
  margin: 64px auto 0;
  padding: 40px var(--gutter);
  text-align: center;
  background: var(--sand);
  border-radius: 20px;
}
.review-prompt__heading {
  font-family: var(--serif);
  font-weight: 300;
  font-size: 30px;
  margin: 0 0 10px;
}
.review-prompt__body {
  color: var(--taupe-dark);
  margin: 0 0 22px;
}

/* --- the rail on the home page --- */
.reviews-band__more { margin-top: 28px; text-align: center; }

.review-rail-wrap { margin-top: 34px; }

/* --- rails: a row that keeps moving on its own --- */

/* The rail scrolls; the track holds the cards. site.js appends an inert copy
   of the track beside it, so the gap BETWEEN the two tracks has to match the
   gap between two cards or the seam shows as a wider space every lap. Both
   read the same value. */
.rail {
  display: flex;
  gap: var(--rail-gap);
  overflow-x: auto;
  /* A vertical swipe on a phone still scrolls the page. */
  touch-action: pan-y;
  scrollbar-width: none;
}
.rail::-webkit-scrollbar { display: none; }

.rail__track {
  display: flex;
  gap: var(--rail-gap);
  /* Never let the track shrink to fit: it is wider than the rail on purpose,
     and a flex parent would otherwise squeeze it down to the visible width and
     leave nothing to scroll. */
  flex: 0 0 auto;
}

/* Grabbing to fling should feel like grabbing, and the text should not select
   out from under the drag. */
.rail { cursor: grab; }
.rail.is-dragging { cursor: grabbing; }
.rail.is-dragging .rail__track { user-select: none; }

/* Dragging a photo out of the row is the browser's default and it fights the
   only drag this row wants, which is the one that moves it: the picture tears
   loose under a ghost image and the carousel stays put. Suppressed here for
   Safari and cancelled in site.js for everything else. */
.rail img {
  -webkit-user-drag: none;
  user-select: none;
}

/* Scroll snapping fights an animation that moves by fractions of a pixel: the
   browser keeps pulling the row back to the nearest card. The rail is driven,
   so it does not need it. */

.review-rail {
  --rail-gap: 20px;
  padding: 4px var(--gutter) 22px;
}

.review-rail .review-card {
  flex: 0 0 clamp(260px, 78vw, 380px);
}

.tile-rail {
  --rail-gap: 14px;
  padding: 0 var(--gutter);
}

.tile-rail .tile {
  flex: 0 0 clamp(190px, 42vw, 260px);
}

/* The row template is markup for cloning, never a card. */
.rail__track > template,
.review-wall > template { display: none; }

.review-rail.is-dragging {
  cursor: grabbing;
  scroll-snap-type: none;
  user-select: none;
}
.review-rail.is-dragging .review-card { pointer-events: none; }

@media (max-width: 620px) {
  .review-card { padding: 24px 22px 20px; }
  .review-card__text { font-size: 17px; }
}
