/* ==========================================================================
   Wedding photography portfolio — public stylesheet
   Warm, editorial, quiet. The photographs are the loudest thing on the page.
   ========================================================================== */

:root {
  /* Everything on the home page lines up to this measure. */
  --home-width: 1150px;

  /* Warm paper palette */
  --paper:      #FBF8F4;
  --paper-2:    #F3ECE3;
  --paper-3:    #EBE1D5;
  --ink:        #211E1A;
  --ink-soft:   #4E463E;
  --muted:      #877C72;
  --line:       #E3D8CA;
  --accent:     #96775A;
  --accent-2:   #C4A98C;
  --on-dark:    #FDFBF8;

  --serif: 'Cormorant Garamond', 'Iowan Old Style', Georgia, 'Times New Roman', serif;
  --sans:  'Jost', -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;

  --wide:   1440px;
  --narrow: 720px;
  --gutter: clamp(1.25rem, 5vw, 4.5rem);

  --header-h: 5.5rem;
  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
}

/* --------------------------------------------------------------------- */
/* Base                                                                   */
/* --------------------------------------------------------------------- */

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: var(--header-h);
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 1.0625rem;
  font-weight: 300;
  line-height: 1.75;
  letter-spacing: 0.005em;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

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

h1, h2, h3, h4 {
  font-family: var(--serif);
  font-weight: 300;
  line-height: 1.14;
  letter-spacing: -0.005em;
  margin: 0;
  text-wrap: balance;
}

p { margin: 0 0 1.15em; }
p:last-child { margin-bottom: 0; }

a { color: inherit; }

button { font: inherit; color: inherit; }

::selection { background: var(--accent-2); color: var(--ink); }

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

.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
}

.skip-link {
  position: absolute;
  top: -100px; left: 1rem;
  z-index: 200;
  background: var(--ink);
  color: var(--on-dark);
  padding: 0.75rem 1.25rem;
  font-size: 0.8rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  text-decoration: none;
  transition: top 0.2s var(--ease);
}
.skip-link:focus { top: 1rem; }

/* --------------------------------------------------------------------- */
/* Shared type                                                            */
/* --------------------------------------------------------------------- */

.eyebrow {
  font-size: 0.6875rem;
  font-weight: 400;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--accent);
  margin: 0 0 1.1rem;
}

.prose {
  font-size: 1.0625rem;
  line-height: 1.85;
  color: var(--ink-soft);
}
.prose p { margin-bottom: 1.4em; }
.prose a { color: var(--accent); text-underline-offset: 0.25em; }

/* --------------------------------------------------------------------- */
/* Buttons                                                                */
/* --------------------------------------------------------------------- */

.btn {
  display: inline-block;
  border: 1px solid var(--ink);
  background: transparent;
  color: var(--ink);
  padding: 0.95rem 2.25rem;
  font-family: var(--sans);
  font-size: 0.72rem;
  font-weight: 400;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  text-decoration: none;
  cursor: pointer;
  transition: background-color 0.35s var(--ease), color 0.35s var(--ease),
              border-color 0.35s var(--ease);
}
.btn:hover { background: var(--ink); color: var(--paper); }

.btn--ghost { border-color: var(--line); color: var(--ink-soft); }
.btn--ghost:hover { background: var(--ink); border-color: var(--ink); color: var(--paper); }

.btn--ghost-light { border-color: rgba(253, 251, 248, 0.75); color: var(--on-dark); }
.btn--ghost-light:hover { background: var(--on-dark); border-color: var(--on-dark); color: var(--ink); }

.btn--small { padding: 0.75rem 1.5rem; font-size: 0.66rem; }
.btn--wide  { padding-inline: 3rem; }

/* --------------------------------------------------------------------- */
/* Header                                                                 */
/* --------------------------------------------------------------------- */

.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: var(--paper);
  border-bottom: 1px solid var(--line);
  transition: background-color 0.4s var(--ease), border-color 0.4s var(--ease),
              color 0.4s var(--ease);
}

/* Sits over the hero image until the visitor scrolls. */
.site-header--over {
  position: fixed;
  left: 0; right: 0;
  background: transparent;
  border-bottom-color: transparent;
  color: var(--on-dark);
}
.site-header--over.is-scrolled {
  background: var(--paper);
  border-bottom-color: var(--line);
  color: var(--ink);
}

.site-header__inner {
  max-width: var(--wide);
  margin-inline: auto;
  padding: 1.35rem var(--gutter);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 2rem;
}

.wordmark {
  text-decoration: none;
  display: block;
  line-height: 1.2;
}
.wordmark__name {
  display: block;
  font-family: var(--serif);
  font-size: clamp(1.3rem, 2.4vw, 1.7rem);
  letter-spacing: 0.06em;
}
.wordmark__sub {
  display: block;
  font-size: 0.6rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--muted);
  margin-top: 0.3rem;
}
.site-header--over:not(.is-scrolled) .wordmark__sub { color: rgba(253, 251, 248, 0.72); }

.site-nav__list {
  list-style: none;
  display: flex;
  align-items: center;
  gap: clamp(1.5rem, 3vw, 2.75rem);
  margin: 0;
  padding: 0;
}
.site-nav__list a {
  text-decoration: none;
  font-size: 0.72rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  padding-block: 0.4rem;
  position: relative;
  transition: color 0.3s var(--ease);
}
.site-nav__list a::after {
  content: '';
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: right;
  transition: transform 0.4s var(--ease);
}
.site-nav__list a:hover::after,
.site-nav__list a[aria-current]::after { transform: scaleX(1); transform-origin: left; }

.site-nav__cta {
  border: 1px solid currentColor;
  padding: 0.6rem 1.5rem !important;
}
.site-nav__cta::after { display: none; }
.site-nav__cta:hover { background: var(--ink); color: var(--paper); border-color: var(--ink); }
.site-header--over:not(.is-scrolled) .site-nav__cta:hover {
  background: var(--on-dark); color: var(--ink); border-color: var(--on-dark);
}

.nav-toggle {
  display: none;
  align-items: center;
  gap: 0.6rem;
  background: none;
  border: 0;
  padding: 0.5rem;
  cursor: pointer;
  /* A thumb needs somewhere to land. Two 1px bars and a caption measured well
     under the 44px a touch target wants. */
  min-height: 44px;
}
/* The two bars have to sit one above the other. As direct children of the
   button they were laid out by its flex row instead, so they showed up as two
   short dashes side by side at slightly different heights - and the cross they
   fold into when the menu opens could never form. */
.nav-toggle__bars {
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.nav-toggle__bar {
  display: block;
  width: 22px; height: 1px;
  background: currentColor;
  transition: transform 0.3s var(--ease), opacity 0.3s var(--ease);
}
.nav-toggle__bar + .nav-toggle__bar { margin-top: 6px; }
.nav-toggle__label {
  font-size: 0.66rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
}

/* --------------------------------------------------------------------- */
/* Hero                                                                   */
/* --------------------------------------------------------------------- */

.hero {
  position: relative;
  height: 100svh;
  min-height: 34rem;
  display: grid;
  /* Anchored low rather than centred: in a real photograph the faces are
     usually in the middle, and centred text lands straight on them. */
  align-items: end;
  justify-items: center;
  overflow: hidden;
  background: var(--paper-3);
}
.hero__media { position: absolute; inset: 0; background-size: cover; background-position: center; }
/* The hero image sits inside a <picture> so a phone can be handed an upright
   crop of it. <picture> is an inline box, and left alone it becomes the image's
   containing block - which leaves the image's height:100% with nothing to
   resolve against and collapses the hero. display:contents takes it back out of
   the layout, so the image is laid out by .hero__media exactly as before. */
.hero__media picture { display: contents; }
.hero__media img {
  width: 100%; height: 100%;
  object-fit: cover;
  animation: heroIn 1.8s var(--ease) both;
}
@keyframes heroIn {
  from { opacity: 0; transform: scale(1.06); }
  to   { opacity: 1; transform: scale(1); }
}

.hero__veil {
  position: absolute; inset: 0;
  /* Weighted towards the bottom, where the headline sits. A hero can be a
     bright white dress just as easily as a dark room, so the text needs the
     gradient to carry it rather than luck. */
  background:
    linear-gradient(180deg, rgba(24, 21, 18, 0.45) 0%, rgba(24, 21, 18, 0.10) 26%,
                    rgba(24, 21, 18, 0.40) 62%, rgba(24, 21, 18, 0.78) 100%);
}

.hero__content {
  position: relative;
  text-align: center;
  color: var(--on-dark);
  padding: var(--header-h) var(--gutter) clamp(6rem, 14vh, 9.5rem);
  max-width: 46rem;
  animation: fadeUp 1.4s var(--ease) 0.35s both;
}
.hero__eyebrow {
  font-size: 0.66rem;
  letter-spacing: 0.32em;
  text-transform: uppercase;
  margin: 0 0 1.6rem;
  color: rgba(253, 251, 248, 0.85);
}
.hero__title {
  font-size: clamp(2.1rem, 5.4vw, 4.1rem);
  font-weight: 300;
  line-height: 1.12;
  margin-bottom: 2.4rem;
  text-shadow: 0 1px 3px rgba(20, 17, 14, 0.35), 0 2px 40px rgba(20, 17, 14, 0.45);
}
.hero__note { color: rgba(253, 251, 248, 0.8); margin-bottom: 2rem; }

.hero--empty {
  height: auto;
  min-height: 30rem;
  background: var(--paper-2);
  align-items: center;
}
.hero--empty .hero__content { padding-bottom: clamp(3rem, 8vh, 5rem); }
.hero--empty .hero__content { color: var(--ink); }
.hero--empty .hero__eyebrow { color: var(--accent); }
.hero--empty .hero__note { color: var(--muted); }
.hero--empty .hero__title { text-shadow: none; }

.hero__scroll {
  position: absolute;
  bottom: 2.2rem; left: 50%;
  transform: translateX(-50%);
  width: 1px; height: 3.5rem;
  background: rgba(253, 251, 248, 0.35);
  overflow: hidden;
}
.hero__scroll span {
  display: block;
  width: 100%; height: 40%;
  background: var(--on-dark);
  animation: scrollCue 2.4s var(--ease) infinite;
}
@keyframes scrollCue {
  0%   { transform: translateY(-100%); }
  60%  { transform: translateY(250%); }
  100% { transform: translateY(250%); }
}

/* --------------------------------------------------------------------- */
/* Sections                                                               */
/* --------------------------------------------------------------------- */

.section {
  padding: clamp(3.5rem, 6.5vw, 5.5rem) var(--gutter);
  max-width: var(--wide);
  margin-inline: auto;
}
.section--tinted {
  max-width: none;
  background: var(--paper-2);
}
.section--tinted > * { max-width: var(--wide); margin-inline: auto; }

.section__head {
  text-align: center;
  max-width: 40rem;
  margin: 0 auto clamp(2rem, 3.5vw, 3rem);
}
.section__title {
  font-size: clamp(1.9rem, 4vw, 3rem);
}

/* A short, confident opening: the name large and centred, the words set in two
   balanced columns beneath it so a paragraph does not run the width of the
   screen, and a way through to the longer version on the About page. */
.intro {
  padding: clamp(4rem, 8vw, 6.5rem) var(--gutter) clamp(2.5rem, 5vw, 4rem);
}
.intro__inner {
  max-width: 56rem;
  margin-inline: auto;
  text-align: center;
}
.intro__heading {
  font-size: clamp(2.1rem, 5vw, 3.6rem);
  margin-bottom: clamp(1.5rem, 3vw, 2.25rem);
  text-wrap: balance;
}
/* One column. The introduction is four short sentences, and splitting that
   into two columns just makes two narrow ragged ones. */
.intro__body {
  max-width: 40rem;
  margin-inline: auto;
  font-size: 1.08rem;
  line-height: 1.85;
}
.intro__body p { margin-bottom: 1.25em; }

.intro__more { margin: clamp(1.75rem, 3.5vw, 2.5rem) 0 0; }
.intro__more a {
  font-size: 0.7rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--accent);
  text-decoration: none;
  border-bottom: 1px solid var(--line);
  padding-bottom: 0.35rem;
  transition: color 0.3s var(--ease), border-color 0.3s var(--ease);
}
.intro__more a:hover { color: var(--ink); border-color: var(--accent); }


.page-head {
  padding: clamp(3rem, 6vw, 4.5rem) var(--gutter) clamp(2rem, 3.5vw, 3rem);
  max-width: 46rem;
  margin-inline: auto;
  text-align: center;
}
.page-head__title { font-size: clamp(2.2rem, 5.5vw, 3.8rem); }
.page-head__lede {
  margin-top: 1.4rem;
  color: var(--muted);
  font-size: 1.0625rem;
  line-height: 1.8;
}

.centred-page {
  padding: clamp(4rem, 8vw, 6rem) var(--gutter) clamp(4rem, 7vw, 6rem);
  max-width: 40rem;
  margin-inline: auto;
  text-align: center;
}
.centred-page--narrow { max-width: 32rem; }
.centred-page__title { font-size: clamp(2rem, 5vw, 3.2rem); margin-bottom: 1.4rem; }
.centred-page__body { color: var(--muted); }
.centred-page__body--small { font-size: 0.9rem; margin-top: 1.5rem; }
.centred-page__actions {
  margin-top: 2.5rem;
  display: flex;
  gap: 1rem;
  justify-content: center;
  flex-wrap: wrap;
}

.error-detail {
  margin: 2rem 0 0;
  padding: 1rem;
  background: var(--paper-2);
  border-left: 2px solid var(--accent);
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.8rem;
  text-align: left;
  overflow-x: auto;
  white-space: pre-wrap;
}

/* --------------------------------------------------------------------- */
/* Photographs                                                            */
/* --------------------------------------------------------------------- */

.photo { margin: 0; }

.photo__frame {
  display: block;
  width: 100%;
  padding: 0;
  border: 0;
  background-color: var(--paper-3);
  background-size: cover;
  background-position: center;
  overflow: hidden;
  position: relative;
  cursor: zoom-in;
}
div.photo__frame { cursor: default; }

.photo__frame img {
  width: 100%; height: 100%;
  object-fit: cover;
  transition: transform 0.9s var(--ease), opacity 0.7s var(--ease);
}
button.photo__frame:hover img { transform: scale(1.028); }

.photo__caption {
  margin-top: 0.85rem;
  font-size: 0.8rem;
  letter-spacing: 0.02em;
  color: var(--muted);
}

.showcase {
  padding: clamp(1rem, 3vw, 2rem) 0 clamp(3rem, 5.5vw, 4.5rem);
  max-width: none;
  margin-inline: auto;
  overflow: hidden;
}
.showcase__more { padding-inline: var(--gutter); }
.showcase__grid,
.photo-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(1rem, 2.6vw, 2.5rem);
  align-items: start;
}
.photo-grid {
  max-width: var(--wide);
  margin-inline: auto;
  padding: clamp(1rem, 3vw, 2rem) var(--gutter) clamp(3rem, 6vw, 5rem);
}

/* The home page is a taster, not the portfolio. Square tiles and tight gaps,
   the same language the galleries use, so the two pages read as one site — but
   packed as a mosaic around one large photograph, so it is not just a smaller
   contact sheet. The hero stays the only full-width image on the page. */
.showcase__grid {
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(0.5rem, 1.2vw, 1rem);
  max-width: var(--home-width);
  margin-inline: auto;
}
.showcase__grid .photo--wide { grid-column: auto; }
.showcase__grid .photo--wide .photo__frame { max-height: none; }

/* Four columns with the first photograph taking a 2x2 block. The route only
   ever sends 5, 9 or 13 photographs, which are the counts that fill this
   exactly — anything else would leave a hole in the bottom corner. */
.showcase__grid--mosaic { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.showcase__grid--mosaic .photo--lead { grid-column: span 2; grid-row: span 2; }

@media (max-width: 1100px) {
  .showcase__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .showcase__grid--mosaic { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

@media (max-width: 700px) {
  /* Two columns on a phone, with the lead photograph across both. */
  .showcase__grid--mosaic { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .showcase__grid--mosaic .photo--lead { grid-column: span 2; grid-row: span 2; }
}

.photo-grid .photo--wide { grid-column: 1 / -1; }
.photo-grid .photo--wide .photo__frame { max-height: 88svh; }

/* A gentle vertical offset so the grid reads like a printed spread rather
   than a contact sheet. Even-tile galleries opt out: the whole point of them
   is that the rows line up. The home page opts out too — three columns of
   natural shapes already stagger themselves, and offsets on top of that fight
   the dense auto-flow. */
@media (min-width: 800px) {
  .photo-grid:not(.photo-grid--uniform) .photo--portrait:nth-child(4n + 2) { margin-top: clamp(1.5rem, 5vw, 5rem); }
  .photo-grid:not(.photo-grid--uniform) .photo--landscape:nth-child(6n + 5) { margin-top: clamp(1rem, 3vw, 3rem); }
}

/* Even tiles — every frame cropped to the same shape, three across. The frame
   carries the aspect ratio inline (set per gallery), so all this has to do is
   count the columns and tighten the gap.

   Narrower than the full page on purpose: across 1440px the two-column grid
   gives 630px tiles, which is taller than most screens for a portrait shot.
   Capping the grid holds each tile near 360px — small enough to take a row in
   at a glance, with the full photograph a click away in the lightbox. */
.photo-grid--uniform {
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(0.5rem, 1.4vw, 1.25rem);
  max-width: 1150px;
}

/* Where a cropped tile sits on its photograph is set per photograph in the
   admin and written inline, so there is nothing to say here. */

@media (max-width: 1100px) {
  .photo-grid--uniform { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

.showcase__more { text-align: center; margin-top: clamp(2rem, 4vw, 3rem); }

/* The band across the What I Shoot page. Its height is a choice in Site
   settings, and which part of the photograph stays in frame comes from that
   photograph's own focal point — the same one the gallery tiles use. */
.feature-image {
  padding-block: clamp(3rem, 7vw, 6rem);
}
.feature-image .photo__frame { aspect-ratio: var(--banner-ratio, 21 / 9); }

.feature-image--slim     { --banner-ratio: 32 / 9; }
.feature-image--standard { --banner-ratio: 21 / 9; }
.feature-image--tall     { --banner-ratio: 16 / 9; }

/* A 32:9 strip on a phone is a letterbox slot, so every height squares up a
   little. Same specificity as the modifiers above, and later, so it wins. */
@media (max-width: 700px) {
  .feature-image { --banner-ratio: 4 / 3; }
}

/* --------------------------------------------------------------------- */
/* Legal pages                                                            */
/* --------------------------------------------------------------------- */

.legal {
  max-width: 44rem;
  margin-inline: auto;
  padding: 0 var(--gutter) clamp(4rem, 8vw, 7rem);
}
.legal__body p { margin-bottom: 1.4em; }
.legal__contact {
  margin-top: 2.5rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--line);
  font-size: 0.85rem;
  color: var(--muted);
}

/* --------------------------------------------------------------------- */
/* Gallery cards                                                          */
/* --------------------------------------------------------------------- */

.gallery-grid {
  display: grid;
  gap: clamp(2rem, 4vw, 3.5rem);
  max-width: var(--wide);
  margin-inline: auto;
  padding-inline: var(--gutter);
  padding-bottom: clamp(2rem, 5vw, 4rem);
}
/* Inside a section the gutter and the bottom space are already the section's
   job; doing it twice indents the cards and leaves a hole underneath. */
.section .gallery-grid {
  padding-inline: 0;
  padding-bottom: 0;
  max-width: var(--home-width);
}
/* auto-fit counts repetitions using the MAX track size whenever that is a
   definite length, so a minmax(..., 40rem) cap silently collapses the grid to a
   single column. Keep 1fr here and cap the card itself instead — that still
   stops one lone gallery stretching the full width. */
.gallery-grid--two   { grid-template-columns: repeat(auto-fit, minmax(min(100%, 26rem), 1fr)); }
.gallery-grid--three { grid-template-columns: repeat(auto-fit, minmax(min(100%, 19rem), 1fr)); }
.gallery-grid--two,
.gallery-grid--three { justify-content: center; }

.gallery-card { width: 100%; max-width: 40rem; margin-inline: auto; }

.gallery-card__link { text-decoration: none; display: block; }

.gallery-card__frame {
  aspect-ratio: 4 / 5;
  background: var(--paper-3) center / cover;
  overflow: hidden;
  display: grid;
  place-items: center;
}
.gallery-card__frame img {
  width: 100%; height: 100%;
  object-fit: cover;
  transition: transform 1s var(--ease);
}
.gallery-card__link:hover .gallery-card__frame img { transform: scale(1.04); }

.gallery-card__empty {
  font-size: 0.75rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted);
}

.gallery-card__body { padding-top: 1.15rem; text-align: center; }
.gallery-card__title {
  font-size: clamp(1.4rem, 2.4vw, 1.85rem);
  transition: color 0.3s var(--ease);
}
.gallery-card__link:hover .gallery-card__title { color: var(--accent); }
.gallery-card__meta {
  margin: 0.45rem 0 0;
  font-size: 0.68rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--muted);
  display: flex;
  gap: 0.75rem;
  justify-content: center;
  flex-wrap: wrap;
}
.gallery-card__meta span + span::before {
  content: '·';
  margin-right: 0.75rem;
  color: var(--line);
}

.filters {
  display: flex;
  gap: 0.5rem 1.75rem;
  justify-content: center;
  flex-wrap: wrap;
  padding: 0 var(--gutter) clamp(2.5rem, 5vw, 3.5rem);
}
.filter {
  text-decoration: none;
  font-size: 0.7rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--muted);
  padding-bottom: 0.35rem;
  border-bottom: 1px solid transparent;
  transition: color 0.3s var(--ease), border-color 0.3s var(--ease);
}
.filter:hover { color: var(--ink); }
.filter.is-active { color: var(--ink); border-bottom-color: var(--accent); }

/* --------------------------------------------------------------------- */
/* Gallery page                                                           */
/* --------------------------------------------------------------------- */

.gallery-head {
  padding: clamp(3rem, 6vw, 4.5rem) var(--gutter) clamp(1.5rem, 3vw, 2.5rem);
  max-width: 46rem;
  margin-inline: auto;
  text-align: center;
}
.gallery-head__title { font-size: clamp(2.3rem, 6vw, 4.2rem); }
.gallery-head__meta {
  margin: 1.5rem 0 0;
  font-size: 0.7rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--muted);
  display: flex;
  gap: 1.25rem;
  justify-content: center;
  flex-wrap: wrap;
}

.gallery-story {
  max-width: 36rem;
  margin: 0 auto clamp(1rem, 3vw, 2rem);
  padding-inline: var(--gutter);
  text-align: center;
  font-family: var(--serif);
  font-size: clamp(1.15rem, 2.1vw, 1.4rem);
  line-height: 1.75;
  color: var(--ink-soft);
}

.gallery-nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  flex-wrap: wrap;
  max-width: var(--wide);
  margin-inline: auto;
  padding: clamp(2.5rem, 5vw, 4rem) var(--gutter);
  border-top: 1px solid var(--line);
}
.gallery-nav__link { text-decoration: none; max-width: 16rem; }
.gallery-nav__link--next { text-align: right; margin-left: auto; }
.gallery-nav__label {
  display: block;
  font-size: 0.64rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 0.4rem;
}
.gallery-nav__title {
  font-family: var(--serif);
  font-size: 1.3rem;
  transition: color 0.3s var(--ease);
}
.gallery-nav__link:hover .gallery-nav__title { color: var(--accent); }
.gallery-nav__all {
  font-size: 0.68rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--muted);
  text-decoration: none;
  order: 3;
  width: 100%;
  text-align: center;
  padding-top: 1.5rem;
}
.gallery-nav__all:hover { color: var(--ink); }

.preview-bar {
  position: sticky;
  top: var(--header-h);
  z-index: 60;
  background: var(--accent);
  color: var(--on-dark);
  padding: 0.7rem var(--gutter);
  font-size: 0.78rem;
  letter-spacing: 0.05em;
  display: flex;
  gap: 1rem;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
}
.preview-bar a { color: inherit; }

/* --------------------------------------------------------------------- */
/* About                                                                  */
/* --------------------------------------------------------------------- */

.about {
  display: grid;
  grid-template-columns: 1fr;
  gap: clamp(2.5rem, 5vw, 4rem);
  max-width: var(--home-width);
  margin-inline: auto;
  padding: clamp(1rem, 3vw, 2rem) var(--gutter) clamp(2.5rem, 5vw, 4rem);
  align-items: center;
}
@media (min-width: 900px) {
  .about { grid-template-columns: 1fr 0.9fr; }
  .about__text { padding-top: 1rem; }
}
.about__text { max-width: 34rem; }
/* Capping the height means the frame crops, so the photograph's own focal
   point decides what stays in it. */
.about__image .photo__frame { max-height: 34rem; }

/* --------------------------------------------------------------------- */
/* Approach                                                               */
/* --------------------------------------------------------------------- */

.approach__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: clamp(2.25rem, 5vw, 3.5rem);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr));
}
.approach__item {
  text-align: center;
  position: relative;
  padding-top: clamp(2.5rem, 5vw, 3.5rem);
}
/* A large, pale numeral behind each step. It is decoration, not content — the
   list is already ordered, and a screen reader announces the order itself. */
.approach__number {
  position: absolute;
  top: 0;
  left: 50%;
  transform: translateX(-50%);
  font-family: var(--serif);
  font-size: clamp(3.5rem, 8vw, 5.5rem);
  line-height: 0.8;
  font-weight: 300;
  color: var(--paper-3);
  font-variant-numeric: lining-nums;
  user-select: none;
  pointer-events: none;
}
.approach__title {
  position: relative;
  font-size: 1.55rem;
  margin-bottom: 0.7rem;
}
.approach__body { color: var(--muted); font-size: 0.97rem; margin: 0; }

/* --------------------------------------------------------------------- */
/* Quotes                                                                 */
/* --------------------------------------------------------------------- */

.quote-band {
  background: var(--paper-2);
  padding: clamp(3.5rem, 6.5vw, 5.5rem) var(--gutter);
}
/* On the home page this follows the tinted collections band, so it drops the
   tint rather than merging into one huge beige block. */
.quote-band--paper { background: var(--paper); }
.quote-band--plain {
  background: transparent;
  padding-block: clamp(2.5rem, 5vw, 4rem);
}
.quote-band__inner { max-width: var(--home-width); margin-inline: auto; }

/* --------------------------------------------------------------------- */
/* Carousel                                                               */
/* --------------------------------------------------------------------- */

/* Reviews vary a lot in length, so the track is as tall as its longest slide
   and the others centre inside it. Sliding the height around as it advances
   would shove the rest of the page up and down. */
.carousel { position: relative; }

.carousel__viewport { overflow: hidden; }
.carousel__viewport:focus-visible { outline: 2px solid var(--accent); outline-offset: 1rem; }

.carousel__track {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: 1fr;
}
/* Every slide occupies the same cell; only opacity says which one is showing.
   Stacking rather than scrolling keeps the height stable and needs no maths. */
.carousel__slide {
  grid-area: 1 / 1;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.55s var(--ease), visibility 0.55s var(--ease);
}
.carousel__slide.is-current { opacity: 1; visibility: visible; }

/* Without JavaScript there is no is-current, so show the first review. */
.carousel:not(.is-ready) .carousel__slide:first-child { opacity: 1; visibility: visible; }

.carousel__controls {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 1.5rem;
  margin-top: clamp(2rem, 4vw, 3rem);
}

.carousel__arrow {
  background: none;
  border: 1px solid var(--line);
  border-radius: 50%;
  width: 2.75rem;
  height: 2.75rem;
  display: grid;
  place-items: center;
  font-size: 1rem;
  color: var(--ink-soft);
  cursor: pointer;
  transition: background-color 0.3s var(--ease), color 0.3s var(--ease),
              border-color 0.3s var(--ease);
}
.carousel__arrow:hover { background: var(--ink); border-color: var(--ink); color: var(--paper); }

.carousel__dots { display: flex; align-items: center; gap: 0.65rem; }
.carousel__dot {
  width: 0.5rem;
  height: 0.5rem;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: var(--paper-3);
  cursor: pointer;
  transition: background-color 0.3s var(--ease), transform 0.3s var(--ease);
}
.carousel__dot:hover { background: var(--accent-2); }
.carousel__dot.is-current { background: var(--accent); transform: scale(1.35); }

@media (max-width: 700px) {
  .carousel__controls { gap: 1rem; }
  .carousel__arrow { width: 2.4rem; height: 2.4rem; }

  /* The dot stays 8px because that is the look, but the thing you tap is a
     28x43px box around it. The gap is widened to exactly twice the sideways
     reach so neighbouring targets meet without overlapping. */
  .carousel__dots { gap: 1.25rem; }
  .carousel__dot { position: relative; }
  .carousel__dot::after {
    content: '';
    position: absolute;
    inset: -1.1rem -0.625rem;
  }
}

/* Selected work: each slide is a row of three square tiles, the same shape and
   spacing the galleries use, rotating through nine. The sets either side stay
   in view, dimmed and softened, so it reads as one long strip of work rather
   than three separate pictures. */
/* Full width, so the sets either side are clipped by the window rather than by
   a box inside it. The active set is the one held at the page measure. */
.showcase-carousel { width: 100%; }
.showcase-carousel .carousel__viewport { overflow: hidden; }

.showcase-carousel .carousel__track {
  display: flex;
  grid-template-columns: none;
  column-gap: clamp(0.75rem, 2vw, 1.75rem);
  transition: transform 0.75s var(--ease);
  will-change: transform;
}
/* The row is positioned by script, so it must not be centred by the flexbox. */
.showcase-carousel .carousel__track { justify-content: flex-start; }

.showcase-slide {
  grid-area: auto;
  /* Deliberately about half the height of a laptop screen. Big enough to be
     worth looking at, small enough that the next section is visible under it —
     a carousel that fills the window tends to be the only thing anyone sees. */
  flex: 0 0 min(33rem, 44vw);
  display: block;

  /* Overrides the cross-fade the other carousel uses: here the neighbours are
     meant to be seen, just clearly not the one being looked at. */
  visibility: visible;
  opacity: 0.3;
  filter: blur(3px) saturate(0.75);
  transform: scale(0.965);
  pointer-events: none;
  transition: opacity 0.75s var(--ease), filter 0.75s var(--ease),
              transform 0.75s var(--ease);
}
.showcase-carousel .carousel__slide.is-current {
  opacity: 1;
  filter: none;
  transform: none;
  pointer-events: auto;
}

/* Before the script runs there is no is-current, so show the first set. */
.showcase-carousel:not(.is-ready) .carousel__slide:first-child {
  opacity: 1;
  filter: none;
  transform: none;
  pointer-events: auto;
}

/* On a phone the carousel is the same carousel, just sized for the screen:
   one photograph nearly filling it with the neighbours showing at the edges,
   the same dots and arrows underneath, driven by the same script. It used to
   stand down here into a grid of small square tiles instead. */
@media (max-width: 700px) {
  .showcase-slide { flex-basis: 82vw; }
}

/* The phone is served a crop that is already composed for an upright screen, so
   it wants to sit centred rather than take the wide photograph's focal point -
   and that focal point is written as an inline style, which only !important can
   answer. */
@media (max-width: 700px) {
  .hero__media img { object-position: center !important; }
}

/* The hero photograph is landscape - 3:2 - and a phone held upright is roughly
   1:2 the other way. Filling that full height crops the picture to about a
   third of its width: a narrow vertical strip through the middle, which is why
   it reads as being zoomed right in. Shortening the frame brings the box closer
   to the shape of the photograph and lets about half of it through instead.
   It also stops the hero being taller than the screen in landscape, where the
   old 34rem floor was more than the whole viewport. */
/* The collections on the home page and the portfolio index. auto-fit sizes its
   columns from min(100%, 19rem), which is 304px on a phone, and only one of
   those fits across - so every collection became a slab about 440px tall and
   the portfolio turned into a very long scroll. Two across is what a wide
   screen shows, just smaller. */
@media (max-width: 700px) {
  /* Every list of galleries goes two across on a phone - the home page, the
     portfolio index, and the child galleries inside a collection. A full-width
     card is about 440px tall, which made all three an endless scroll. */
  .gallery-grid--two,
  .gallery-grid--three {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 1.15rem 0.75rem;
  }
  /* Sized for a tile about 170px across rather than the full width. */
  .gallery-card__body { padding-top: 0.7rem; }
  .gallery-card__title { font-size: 1.05rem; }
  .gallery-card__meta { font-size: 0.62rem; }

  /* An odd number of galleries leaves the last one alone on the bottom row,
     pushed against the left edge with a hole beside it. Let it span both
     columns but hold it to the width of one, so it centres under the pair
     above. Three collections read as two and one, centred, rather than as a
     row with something missing. */
  .gallery-grid--two > .gallery-card:last-child:nth-child(odd),
  .gallery-grid--three > .gallery-card:last-child:nth-child(odd) {
    grid-column: 1 / -1;
    width: calc((100% - 0.75rem) / 2);
  }
}

/* The reviews cross-fade in place on every screen. The one thing changed for
   a phone is the timing: both slides used to be part-way visible at once, so
   two blocks of text were briefly readable on top of each other, which is what
   looked like it was struggling. Now the old one finishes leaving before the
   new one starts arriving. */
@media (max-width: 700px) {
  .quote-band .carousel__slide { transition-duration: 0.25s; }
  .quote-band .carousel__slide.is-current { transition-delay: 0.25s; }
}

.quote {
  max-width: 44rem;
  margin: 0 auto;
  text-align: center;
}
.quote__text {
  font-family: var(--serif);
  font-style: italic;
  font-size: clamp(1.4rem, 3.2vw, 2.25rem);
  line-height: 1.5;
  color: var(--ink);
  margin: 0;
}
.quote__text::before { content: '“'; }
.quote__text::after  { content: '”'; }
.quote__author {
  margin-top: 1.75rem;
  font-size: 0.68rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--muted);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 0.5rem 0.9rem;
}
.quote__author span + .quote__meta::before {
  content: '';
  display: inline-block;
  width: 1.25rem;
  height: 1px;
  background: var(--line);
  vertical-align: middle;
  margin-right: 0.9rem;
}

.testimonials {
  display: grid;
  gap: clamp(2rem, 4vw, 3rem);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 20rem), 1fr));
}
.testimonial {
  margin: 0;
  padding: clamp(1.75rem, 3vw, 2.5rem);
  background: var(--paper);
  border: 1px solid var(--line);
}
.testimonial__text {
  font-family: var(--serif);
  font-style: italic;
  font-size: 1.2rem;
  line-height: 1.65;
  color: var(--ink-soft);
}
.testimonial__author {
  margin-top: 1.25rem;
  font-size: 0.66rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--muted);
}

/* --------------------------------------------------------------------- */
/* Packages                                                               */
/* --------------------------------------------------------------------- */

.packages {
  display: grid;
  gap: clamp(1.5rem, 3vw, 2.5rem);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 19rem), 1fr));
  max-width: var(--wide);
  margin-inline: auto;
  padding: clamp(1rem, 3vw, 2rem) var(--gutter) 0;
  align-items: start;
}
.package {
  position: relative;
  padding: clamp(2rem, 3.5vw, 3rem) clamp(1.5rem, 3vw, 2.5rem);
  border: 1px solid var(--line);
  background: var(--paper);
  display: flex;
  flex-direction: column;
  gap: 0.85rem;
  height: 100%;
}
.package--featured {
  background: var(--paper-2);
  border-color: var(--accent-2);
}
.package__flag {
  position: absolute;
  top: 0; left: 50%;
  transform: translate(-50%, -50%);
  background: var(--accent);
  color: var(--on-dark);
  font-size: 0.6rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  padding: 0.4rem 1rem;
  white-space: nowrap;
}
.package__name { font-size: 1.85rem; }
.package__summary { color: var(--muted); font-size: 0.95rem; margin: 0; }
.package__price {
  font-family: var(--serif);
  font-size: 1.35rem;
  color: var(--accent);
  margin: 0;
  padding-bottom: 0.85rem;
  border-bottom: 1px solid var(--line);
}
.package__items {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0.65rem;
  font-size: 0.95rem;
  color: var(--ink-soft);
  flex: 1;
}
.package__items li { padding-left: 1.35rem; position: relative; line-height: 1.6; }
.package__items li::before {
  content: '';
  position: absolute;
  left: 0; top: 0.7em;
  width: 0.5rem; height: 1px;
  background: var(--accent-2);
}
.package .btn { margin-top: 0.85rem; align-self: flex-start; }

/* Four packages in a three-column grid strands the last one - Extras - alone on
   the second row, hard against the left edge with a gap beside it. Put it in the
   middle column instead so it sits under the three above.
   The grid is three columns from about 1086px up, and never four, because the
   section is capped at var(--wide). Below that it is two columns or one, where
   nothing is stranded and this must not apply - which is what the min-width is
   doing. :nth-child(3n + 1) means "first in its row", so this only fires when
   the last card really is on its own. */
@media (min-width: 1086px) {
  .packages > .package:last-child:nth-child(3n + 1) { grid-column: 2; }
}

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

.faq__list {
  display: grid;
  gap: 0;
  max-width: 46rem;
  margin: 0 auto;
  border-top: 1px solid var(--line);
}
.faq__item { padding: clamp(1.5rem, 3vw, 2rem) 0; border-bottom: 1px solid var(--line); }
.faq__item dt {
  font-family: var(--serif);
  font-size: 1.35rem;
  margin-bottom: 0.5rem;
}
.faq__item dd { margin: 0; color: var(--muted); }
.faq__note {
  text-align: center;
  margin-top: 2.5rem;
  font-size: 0.95rem;
  color: var(--muted);
}
.faq__note a { color: var(--accent); }

/* --------------------------------------------------------------------- */
/* Contact                                                                */
/* --------------------------------------------------------------------- */

.contact {
  display: grid;
  grid-template-columns: 1fr;
  gap: clamp(2.5rem, 5vw, 4.5rem);
  max-width: var(--wide);
  margin-inline: auto;
  padding: clamp(1rem, 3vw, 2rem) var(--gutter) clamp(4rem, 8vw, 7rem);
  align-items: start;
}
@media (min-width: 900px) {
  .contact { grid-template-columns: 1fr 0.62fr; }
}
.contact__form-wrap { max-width: 42rem; }
.contact__image { margin-bottom: 2rem; }
.contact__image .photo__frame { max-height: 30rem; }
.contact__details-title { font-size: 1.5rem; margin-bottom: 1rem; }
.contact__details p { margin-bottom: 0.5rem; }
.contact__details a { color: var(--accent); text-underline-offset: 0.25em; }
.contact__area { color: var(--muted); font-size: 0.9rem; margin-top: 1rem !important; }

/* --------------------------------------------------------------------- */
/* Forms                                                                  */
/* --------------------------------------------------------------------- */

.form__row {
  display: grid;
  gap: 0 1.5rem;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr));
}

.field { margin-bottom: 1.5rem; }
.field--narrow { max-width: 22rem; }

.field label {
  display: block;
  font-size: 0.68rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin-bottom: 0.6rem;
}
.field__hint, .req { color: var(--muted); letter-spacing: 0.1em; }
.req { color: var(--accent); }

.field input,
.field select,
.field textarea {
  width: 100%;
  font-family: var(--sans);
  font-size: 1rem;
  font-weight: 300;
  color: var(--ink);
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--line);
  border-radius: 0;
  padding: 0.7rem 0;
  transition: border-color 0.3s var(--ease);
  appearance: none;
}
.field textarea { line-height: 1.7; resize: vertical; }
.field select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' fill='none' stroke='%23877C72' stroke-width='1.2'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.2rem center;
  background-size: 0.7rem;
  padding-right: 1.6rem;
  cursor: pointer;
}
.field input:focus,
.field select:focus,
.field textarea:focus {
  outline: none;
  border-bottom-color: var(--accent);
}
.field input::placeholder,
.field textarea::placeholder { color: #B6ABA0; }

.field--error input,
.field--error textarea { border-bottom-color: #A6503F; }
.field__error {
  margin: 0.5rem 0 0;
  font-size: 0.82rem;
  color: #A6503F;
  letter-spacing: 0;
  text-transform: none;
}

.form__note {
  margin-top: 1.25rem;
  font-size: 0.82rem;
  color: var(--muted);
}

.form-alert {
  padding: 1rem 1.25rem;
  margin-bottom: 2rem;
  background: var(--paper-2);
  border-left: 2px solid #A6503F;
  font-size: 0.92rem;
}

.form--inline {
  display: flex;
  gap: 1rem;
  align-items: flex-start;
  justify-content: center;
  flex-wrap: wrap;
  margin-top: 2rem;
}
.form--inline .field { margin-bottom: 0; min-width: 14rem; }
.form--inline input { text-align: center; letter-spacing: 0.1em; }

/* The honeypot must be reachable by bots and invisible to everyone else. */
.hp {
  position: absolute;
  left: -9999px;
  width: 1px; height: 1px;
  overflow: hidden;
}

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

.cta {
  background: var(--paper-2);
  padding: clamp(3.5rem, 6.5vw, 5.5rem) var(--gutter);
  border-top: 1px solid var(--line);
}
/* Where the block above is already tinted, the call to action steps back to
   plain paper rather than continuing the same slab. */
.section--tinted + .cta,
.quote-band:not(.quote-band--paper) + .cta { background: var(--paper); }
.cta__inner { max-width: 36rem; margin-inline: auto; text-align: center; }
.cta__title { font-size: clamp(1.9rem, 4.2vw, 2.9rem); margin-bottom: 1.1rem; }
.cta__body { color: var(--muted); margin-bottom: 2.25rem; }

.empty-state {
  text-align: center;
  padding: clamp(3rem, 8vw, 6rem) var(--gutter);
  max-width: 32rem;
  margin-inline: auto;
}
.empty-state__title {
  font-family: var(--serif);
  font-size: 1.6rem;
  margin-bottom: 0.6rem;
}
.empty-state__body { color: var(--muted); }
.empty-state__body a { color: var(--accent); }

/* --------------------------------------------------------------------- */
/* Breadcrumbs                                                            */
/* --------------------------------------------------------------------- */

.crumbs {
  display: flex;
  gap: 0.6rem;
  justify-content: center;
  flex-wrap: wrap;
  font-size: 0.66rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 1.1rem;
}
.crumbs a { color: var(--accent); text-decoration: none; }
.crumbs a:hover { color: var(--ink); }

/* --------------------------------------------------------------------- */
/* Reviews                                                                */
/* --------------------------------------------------------------------- */

/* line-height: 1 makes the row hug whatever follows it, so anywhere the stars
   head a block they are given their own space rather than sitting on the text. */
.stars { display: inline-flex; gap: 0.2em; line-height: 1; }
.star { color: var(--line); font-size: 1rem; }
.star--on { color: var(--accent); }

.review .stars,
.testimonial .stars {
  display: flex;
  margin-bottom: clamp(1rem, 2vw, 1.35rem);
}

.rating-summary {
  display: flex;
  gap: 0.75rem;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  margin: 0 0 1.1rem;
}
.rating-summary .star { font-size: 1.15rem; }
.rating-summary__text { font-size: 0.9rem; color: var(--muted); }
.rating-summary__text strong { color: var(--ink); font-weight: 400; }

/* Columns rather than grid rows: reviews vary wildly in length, and a grid
   leaves a row-sized hole under every short card. Columns pack them like a
   pinboard, so the gaps stay even whatever people wrote. */
.review-grid {
  columns: 3 21rem;
  column-gap: clamp(1.25rem, 2.5vw, 2rem);
  max-width: var(--wide);
  margin-inline: auto;
  padding: 0 var(--gutter) clamp(3rem, 6vw, 5rem);
}

.review {
  background: var(--paper-2);
  border: 1px solid var(--line);
  padding: clamp(1.5rem, 3vw, 2rem);
  break-inside: avoid;
  margin-bottom: clamp(1.25rem, 2.5vw, 2rem);
}
.review__body {
  margin: 0 0 clamp(1.25rem, 2.5vw, 1.75rem);
  font-family: var(--serif);
  font-size: 1.15rem;
  line-height: 1.7;
  color: var(--ink-soft);
  white-space: pre-wrap;
}
.review__foot {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  padding-top: clamp(1rem, 2vw, 1.25rem);
  border-top: 1px solid var(--line);
}
.review__author { font-size: 0.95rem; }
.review__meta {
  font-size: 0.68rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
}
.review__source { color: var(--accent); }

.review-form-wrap {
  max-width: 40rem;
  margin-inline: auto;
  background: var(--paper);
  border: 1px solid var(--line);
  padding: clamp(1.5rem, 3.5vw, 2.5rem);
}

/* The radios are reversed in the DOM (5 first) so ~ can light up the ones to
   the left of the hovered star. */
.rating-field { border: 0; padding: 0; margin: 0 0 1.75rem; }
.rating-field legend {
  padding: 0;
  font-size: 0.68rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin-bottom: 0.6rem;
}
.rating-input {
  display: inline-flex;
  flex-direction: row-reverse;
  justify-content: flex-end;
  gap: 0.2rem;
  /* Contain the absolutely-positioned inputs below. */
  position: relative;
}
/* The radios stay in the accessibility tree and keep arrow-key support, but
   pointer-events:none stops the stacked 1px boxes from swallowing clicks meant
   for the star labels — without it, clicking the fourth star can select a
   different rating entirely. */
.rating-input input {
  position: absolute;
  top: 0;
  left: 0;
  opacity: 0;
  width: 1px;
  height: 1px;
  pointer-events: none;
}
.rating-input label {
  cursor: pointer;
  font-size: 1.85rem;
  line-height: 1;
  color: var(--line);
  margin: 0;
  transition: color 0.15s var(--ease), transform 0.15s var(--ease);
}
.rating-input label:hover { transform: scale(1.12); }
.rating-input input:checked ~ label,
.rating-input label:hover,
.rating-input label:hover ~ label { color: var(--accent); }
.rating-input input:focus-visible + label { outline: 2px solid var(--accent); outline-offset: 3px; }

.notice {
  max-width: 40rem;
  margin: 0 auto clamp(2rem, 4vw, 3rem);
  padding: 1rem 1.35rem;
  background: var(--paper-2);
  border-left: 2px solid var(--accent);
  font-size: 0.95rem;
}

.quote-band__more,
.section__more {
  text-align: center;
  margin-top: 2rem;
}
.quote-band__more a {
  font-size: 0.7rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--muted);
  text-decoration: none;
  border-bottom: 1px solid var(--line);
  padding-bottom: 0.3rem;
}
.quote-band__more a:hover { color: var(--ink); border-bottom-color: var(--accent); }

.quote .stars { display: flex; justify-content: center; margin-bottom: 1.5rem; }
.quote .star { font-size: 1.1rem; }
.testimonial .stars { margin-bottom: 0.85rem; }

.section__lede {
  margin-top: 1rem;
  color: var(--muted);
  font-size: 0.97rem;
}

/* --------------------------------------------------------------------- */
/* Footer                                                                 */
/* --------------------------------------------------------------------- */

.site-footer {
  background: var(--ink);
  color: var(--on-dark);
  padding: clamp(3.5rem, 7vw, 6rem) var(--gutter) 2rem;
}
.site-footer__inner {
  max-width: var(--wide);
  margin-inline: auto;
  display: grid;
  gap: clamp(2rem, 5vw, 4rem);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr));
}
.site-footer__name {
  font-family: var(--serif);
  font-size: 1.75rem;
  margin-bottom: 0.6rem;
}
.site-footer__tagline {
  color: rgba(253, 251, 248, 0.6);
  font-size: 0.92rem;
  max-width: 22rem;
  line-height: 1.7;
}
.site-footer__nav ul,
.social {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0.7rem;
}
.site-footer__nav a,
.site-footer__contact a {
  color: rgba(253, 251, 248, 0.75);
  text-decoration: none;
  font-size: 0.78rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  transition: color 0.3s var(--ease);
}
.site-footer__nav a:hover,
.site-footer__contact a:hover { color: var(--on-dark); }
.site-footer__contact { display: grid; gap: 0.7rem; align-content: start; }
.social { margin-top: 0.6rem; }

.site-footer__base {
  max-width: var(--wide);
  margin: clamp(2.5rem, 5vw, 4rem) auto 0;
  padding-top: 1.75rem;
  border-top: 1px solid rgba(253, 251, 248, 0.12);
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  font-size: 0.75rem;
  color: rgba(253, 251, 248, 0.45);
}
.site-footer__base p { margin: 0; }
.site-footer__base a { color: inherit; text-decoration: none; }
.site-footer__base a:hover { color: var(--on-dark); }

/* --------------------------------------------------------------------- */
/* Lightbox                                                               */
/* --------------------------------------------------------------------- */

.lightbox {
  position: fixed;
  inset: 0;
  z-index: 300;
  display: grid;
  place-items: center;
}
.lightbox[hidden] { display: none; }

.lightbox__backdrop {
  position: absolute;
  inset: 0;
  background: rgba(18, 16, 14, 0.94);
  animation: fadeIn 0.3s var(--ease) both;
  cursor: zoom-out;
}

.lightbox__stage {
  position: relative;
  margin: 0;
  padding: clamp(2.5rem, 6vw, 4rem) clamp(3rem, 8vw, 6rem);
  max-width: 100vw;
  max-height: 100svh;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1rem;
  pointer-events: none;
}
.lightbox__image {
  max-width: 100%;
  max-height: calc(100svh - 9rem);
  width: auto; height: auto;
  object-fit: contain;
  box-shadow: 0 30px 80px rgba(0, 0, 0, 0.45);
  animation: lightboxIn 0.4s var(--ease) both;
}
.lightbox.is-swapping .lightbox__image { opacity: 0.25; transition: opacity 0.15s linear; }

@keyframes lightboxIn {
  from { opacity: 0; transform: scale(0.985); }
  to   { opacity: 1; transform: scale(1); }
}
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes fadeUp {
  from { opacity: 0; transform: translateY(1.5rem); }
  to   { opacity: 1; transform: none; }
}

.lightbox__caption {
  position: relative;
  color: rgba(253, 251, 248, 0.72);
  font-size: 0.8rem;
  letter-spacing: 0.08em;
  text-align: center;
  display: flex;
  gap: 1rem;
  align-items: baseline;
  justify-content: center;
  flex-wrap: wrap;
}
.lightbox__count {
  font-size: 0.68rem;
  letter-spacing: 0.2em;
  color: rgba(253, 251, 248, 0.45);
}

.lightbox__btn {
  position: absolute;
  z-index: 2;
  background: none;
  border: 0;
  padding: 0.85rem;
  cursor: pointer;
  color: rgba(253, 251, 248, 0.7);
  transition: color 0.25s var(--ease), transform 0.25s var(--ease);
}
.lightbox__btn:hover { color: var(--on-dark); }
.lightbox__btn svg {
  width: 26px; height: 26px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.1;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.lightbox__btn--close { top: 1.25rem; right: 1.25rem; }
.lightbox__btn--prev  { left: 0.5rem;  top: 50%; transform: translateY(-50%); }
.lightbox__btn--next  { right: 0.5rem; top: 50%; transform: translateY(-50%); }
.lightbox__btn--prev:hover { transform: translateY(-50%) translateX(-3px); }
.lightbox__btn--next:hover { transform: translateY(-50%) translateX(3px); }
.lightbox__btn[hidden] { display: none; }

body.lightbox-open { overflow: hidden; }

/* --------------------------------------------------------------------- */
/* Reveal on scroll                                                       */
/* --------------------------------------------------------------------- */

[data-reveal] {
  opacity: 0;
  transform: translateY(1.75rem);
  transition: opacity 0.9s var(--ease), transform 0.9s var(--ease);
  will-change: opacity, transform;
}
[data-reveal].is-visible { opacity: 1; transform: none; }
/* If scripting is off, nothing should stay invisible. */
.no-js [data-reveal] { opacity: 1; transform: none; }

/* --------------------------------------------------------------------- */
/* Small screens                                                          */
/* --------------------------------------------------------------------- */

@media (max-width: 860px) {
  :root { --header-h: 4.5rem; }

  .nav-toggle { display: flex; }

  .site-nav {
    position: fixed;
    inset: 0;
    background: var(--paper);
    color: var(--ink);
    display: grid;
    place-items: center;
    opacity: 0;
    visibility: hidden;
    transform: translateY(-1rem);
    transition: opacity 0.35s var(--ease), transform 0.35s var(--ease), visibility 0.35s;
    z-index: 90;
  }
  .site-nav.is-open { opacity: 1; visibility: visible; transform: none; }

  .site-nav__list {
    flex-direction: column;
    gap: 2rem;
    text-align: center;
  }
  .site-nav__list a { font-size: 0.9rem; letter-spacing: 0.24em; }

  body.nav-open { overflow: hidden; }
  body.nav-open .nav-toggle { position: relative; z-index: 95; color: var(--ink); }
  body.nav-open .nav-toggle .nav-toggle__bar:first-child { transform: translateY(3.5px) rotate(45deg); }
  body.nav-open .nav-toggle .nav-toggle__bar:last-of-type { transform: translateY(-3.5px) rotate(-45deg); }
  body.nav-open .wordmark { position: relative; z-index: 95; color: var(--ink); }

  .photo-grid { grid-template-columns: 1fr; }
  /* Even tiles stay two across on a phone — they are made to be tapped open,
     and one square per screen turns a long gallery into an endless scroll. */
  .photo-grid--uniform { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* The showcase keeps its own breakpoints, up with the rest of its rules. */

  .gallery-nav { justify-content: center; text-align: center; }
  .gallery-nav__link--next { text-align: center; margin-left: 0; }

  .lightbox__btn--prev { left: 0; }
  .lightbox__btn--next { right: 0; }
  .lightbox__stage { padding-inline: 2.75rem; }
}

@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;
  }
  [data-reveal] { opacity: 1; transform: none; }
  .hero__scroll { display: none; }
}

@media print {
  .site-header, .site-footer, .cta, .lightbox, .nav-toggle, .hero__scroll { display: none !important; }
  body { background: #fff; }
  [data-reveal] { opacity: 1; transform: none; }
}

/* ===================================================================== */
/* Client galleries                                                       */
/* Numbers, ticking, downloading, and the two extra arrangements.         */
/* ===================================================================== */

/* The number and the tick sit over the frame, so the figure is the anchor. */
.photo { position: relative; }

/* --------------------------------------------------------------------- */
/* The number                                                             */
/* --------------------------------------------------------------------- */
/* Always on, never hover-only: a phone has no hover, and the number is the
   whole point — it is what she gets told over the phone. */
.photo__number {
  position: absolute;
  left: 0.6rem;
  bottom: 0.6rem;
  z-index: 2;
  min-width: 1.9rem;
  padding: 0.22rem 0.5rem;
  border-radius: 2px;
  background: rgba(24, 21, 18, 0.62);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  color: var(--on-dark);
  font-size: 0.72rem;
  font-weight: 400;
  letter-spacing: 0.08em;
  text-align: center;
  font-variant-numeric: tabular-nums;
  pointer-events: none;
  transition: background 0.2s var(--ease);
}
.photo:hover .photo__number { background: rgba(24, 21, 18, 0.85); }
.photo-grid--story .photo__number { font-size: 0.82rem; padding: 0.3rem 0.65rem; }

/* --------------------------------------------------------------------- */
/* The tick                                                               */
/* --------------------------------------------------------------------- */
.photo__pick {
  position: absolute;
  top: 0.55rem;
  right: 0.55rem;
  z-index: 3;
  display: grid;
  place-items: center;
  width: 2.1rem;
  height: 2.1rem;
  cursor: pointer;
}
.photo__pick-box {
  position: absolute;
  inset: 0;
  margin: 0;
  opacity: 0;
  cursor: pointer;
}
.photo__pick-mark {
  width: 1.55rem;
  height: 1.55rem;
  border: 1px solid rgba(253, 251, 248, 0.85);
  border-radius: 50%;
  background: rgba(24, 21, 18, 0.42);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  transition: background 0.18s var(--ease), border-color 0.18s var(--ease),
              transform 0.18s var(--ease);
  position: relative;
}
/* The tick itself, drawn rather than shipped as an image. */
.photo__pick-mark::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 46%;
  width: 0.46rem;
  height: 0.24rem;
  border-left: 1.6px solid var(--on-dark);
  border-bottom: 1.6px solid var(--on-dark);
  transform: translate(-50%, -50%) rotate(-45deg) scale(0.5);
  opacity: 0;
  transition: opacity 0.15s var(--ease), transform 0.15s var(--ease);
}
.photo__pick:hover .photo__pick-mark { transform: scale(1.08); }
.photo__pick-box:focus-visible + .photo__pick-mark {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}
.photo__pick-box:checked + .photo__pick-mark {
  background: var(--accent);
  border-color: var(--accent);
}
.photo__pick-box:checked + .photo__pick-mark::after {
  opacity: 1;
  transform: translate(-50%, -50%) rotate(-45deg) scale(1);
}
.photo.is-picked .photo__frame { outline: 2px solid var(--accent); outline-offset: 3px; }
.photo.is-picked .photo__number { background: var(--accent); }

/* --------------------------------------------------------------------- */
/* The bar above the grid                                                 */
/* --------------------------------------------------------------------- */
.client-tools {
  max-width: var(--wide);
  margin-inline: auto;
  padding: 0 var(--gutter) clamp(1rem, 2vw, 1.5rem);
  display: flex;
  flex-wrap: wrap;
  gap: 1.25rem 2rem;
  align-items: end;
  justify-content: space-between;
}
.client-tools__title {
  font-family: var(--serif);
  font-size: clamp(1.15rem, 2vw, 1.5rem);
  margin: 0 0 0.25rem;
}
.client-tools__body {
  margin: 0;
  max-width: 46ch;
  font-size: 0.92rem;
  color: var(--muted);
  line-height: 1.6;
}
.client-tools__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  align-items: center;
}
.client-tools__form { margin: 0; }

.btn--quiet {
  background: transparent;
  border: 1px solid var(--line);
  color: var(--ink-soft);
}
.btn--quiet:hover { background: var(--ink); border-color: var(--ink); color: var(--paper); }

/* --------------------------------------------------------------------- */
/* The bar that follows them down the page                                */
/* --------------------------------------------------------------------- */
.pick-bar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 60;
  background: var(--paper);
  border-top: 1px solid var(--line);
  box-shadow: 0 -10px 30px rgba(33, 30, 26, 0.09);
  animation: pick-bar-in 0.22s var(--ease);
  /* Clears the home indicator on an iPhone. Resolves to 0 on everything else,
     so the bar is unchanged on a desktop. */
  padding-bottom: env(safe-area-inset-bottom, 0px);
}
@keyframes pick-bar-in {
  from { transform: translateY(100%); }
  to   { transform: translateY(0); }
}
@media (prefers-reduced-motion: reduce) {
  .pick-bar { animation: none; }
}
.pick-bar[hidden] { display: none; }
.pick-bar__inner {
  max-width: var(--wide);
  margin-inline: auto;
  padding: 0.85rem var(--gutter);
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem 1.5rem;
  align-items: center;
  justify-content: space-between;
}
.pick-bar__count {
  margin: 0;
  font-size: 0.92rem;
  display: flex;
  align-items: baseline;
  gap: 0.45rem;
}
.pick-bar__count strong { font-size: 1.15rem; }
.pick-bar__clear {
  border: 0;
  background: none;
  padding: 0;
  font-size: 0.74rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 3px;
}
.pick-bar__clear:hover { color: var(--ink); }
.pick-bar__numbers {
  margin: 0;
  flex: 1 1 12rem;
  min-width: 0;
  font-size: 0.8rem;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.pick-bar__actions {
  display: flex;
  gap: 0.6rem;
  align-items: center;
}
.pick-bar__actions form { margin: 0; }

@media (max-width: 700px) {
  .pick-bar__numbers { display: none; }
  .pick-bar__inner { padding-inline: 1rem; }
  .pick-bar__actions { flex: 1 1 100%; }
  .pick-bar__actions .btn { flex: 1 1 auto; text-align: center; }
}

/* --------------------------------------------------------------------- */
/* Sending the list                                                       */
/* --------------------------------------------------------------------- */
.send-dialog {
  border: 1px solid var(--line);
  border-radius: 3px;
  padding: clamp(1.5rem, 4vw, 2.5rem);
  max-width: 34rem;
  width: calc(100vw - 2rem);
  background: var(--paper);
  color: var(--ink);
}
.send-dialog::backdrop { background: rgba(24, 21, 18, 0.55); }
.send-dialog__title {
  font-family: var(--serif);
  font-size: clamp(1.5rem, 3vw, 2rem);
  margin: 0 0 0.5rem;
}
.send-dialog__lead { margin: 0 0 1.5rem; color: var(--muted); font-size: 0.92rem; }
.send-dialog__numbers { font-variant-numeric: tabular-nums; }
.send-dialog__form label {
  display: block;
  margin: 0 0 0.35rem;
  font-size: 0.72rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted);
}
.send-dialog__optional { text-transform: none; letter-spacing: 0; }
.send-dialog__form input,
.send-dialog__form select,
.send-dialog__form textarea {
  width: 100%;
  margin: 0 0 1.1rem;
  padding: 0.7rem 0.8rem;
  border: 1px solid var(--line);
  border-radius: 2px;
  background: var(--paper-2, #F3ECE3);
  color: var(--ink);
  font: inherit;
  font-size: 0.95rem;
}
.send-dialog__form textarea { resize: vertical; }

/* iOS zooms the whole page in when a form field smaller than 16px is tapped,
   and does not zoom back out afterwards, which leaves the gallery scrolled
   sideways. Only touch devices are affected, so only they are touched here. */
/* Pressing and holding a photograph on a phone otherwise picks it up and
   lets it be dragged around the page, which reads as the carousel breaking. */
@media (pointer: coarse) {
  .carousel img,
  .photo img {
    -webkit-user-drag: none;
    -webkit-touch-callout: none;
    user-select: none;
  }

  /* The carousel moves itself. A finger dragged across it should scroll the
     page up and down and nothing else - never shove the row sideways. */
  .carousel__viewport,
  .carousel__track {
    touch-action: pan-y;
  }

  /* will-change puts whatever it is set on onto its own compositing layer, and
     it is set on every photograph on the page - a couple of hundred of them in
     a gallery. A phone does not have the memory to hold that many layers and
     starts dropping frames scrolling past them. The reveal still animates; it
     just is not promoted in advance. */
  [data-reveal] { will-change: auto; }

  /* The blur on the photographs either side is much the most expensive thing
     the carousel does: it has to be recomputed every frame of the three
     quarters of a second the row is moving, over images nearly as wide as the
     screen. Dimming and shrinking them says the same thing and costs nothing,
     because both of those are handled by the compositor. */
  .showcase-slide {
    filter: none;
    transition: opacity 0.75s var(--ease), transform 0.75s var(--ease);
  }
}

@media (pointer: coarse) {
  .send-dialog__form input,
  .send-dialog__form select,
  .send-dialog__form textarea { font-size: 1rem; }
}
.send-dialog__form input:focus,
.send-dialog__form select:focus,
.send-dialog__form textarea:focus { outline: 2px solid var(--accent); outline-offset: 1px; }
.send-dialog__actions {
  display: flex;
  gap: 0.6rem;
  justify-content: flex-end;
  margin-top: 0.5rem;
}
.send-dialog__error {
  margin: 0 0 1rem;
  padding: 0.7rem 0.8rem;
  border-left: 2px solid #B4593C;
  background: rgba(180, 89, 60, 0.08);
  font-size: 0.9rem;
}
.send-dialog__done p { color: var(--muted); }

/* --------------------------------------------------------------------- */
/* Arrangements                                                           */
/* --------------------------------------------------------------------- */

/* Masonry: every photograph at its own proportions, packed into columns.
   Columns rather than grid, because grid cannot pack ragged heights without
   either cropping or leaving holes. */
.photo-grid--masonry {
  display: block;
  column-count: 3;
  column-gap: clamp(1rem, 2.6vw, 2.5rem);
}
.photo-grid--masonry .photo {
  break-inside: avoid;
  -webkit-column-break-inside: avoid;
  margin-bottom: clamp(1rem, 2.6vw, 2.5rem);
}
.photo-grid--masonry .photo--wide { grid-column: auto; }
@media (max-width: 1100px) { .photo-grid--masonry { column-count: 2; } }
@media (max-width: 620px)  { .photo-grid--masonry { column-count: 1; } }

/* Story: one photograph at a time, big, the way she would walk someone
   through the day. */
.photo-grid--story {
  display: block;
  max-width: 68rem;
}
.photo-grid--story .photo { margin: 0 auto clamp(1.5rem, 4vw, 3.5rem); }
.photo-grid--story .photo--portrait { max-width: 46rem; }
.photo-grid--story .photo--wide { grid-column: auto; }

/* --------------------------------------------------------------------- */
/* Dark tone                                                              */
/* --------------------------------------------------------------------- */
/* The whole page is built on these variables, so swapping them here turns the
   gallery dark without a second stylesheet to keep in step. */
body.tone-charcoal {
  --paper:    #1A1917;
  --paper-2:  #211F1D;
  --paper-3:  #2A2724;
  --ink:      #F2EEE8;
  --ink-soft: #CFC7BC;
  --muted:    #9A9086;
  --line:     #35312C;
  --accent:   #C4A98C;
  --accent-2: #96775A;
  --on-dark:  #1A1917;
}
body.tone-charcoal .photo__number { background: rgba(0, 0, 0, 0.6); color: #F2EEE8; }
body.tone-charcoal .photo:hover .photo__number { background: rgba(0, 0, 0, 0.85); }
body.tone-charcoal .photo.is-picked .photo__number { background: var(--accent); color: #1A1917; }
body.tone-charcoal .pick-bar { box-shadow: 0 -10px 30px rgba(0, 0, 0, 0.4); }
body.tone-charcoal .btn:hover { background: var(--accent); border-color: var(--accent); color: #1A1917; }

/* --------------------------------------------------------------------- */
/* Ticking from inside the lightbox                                       */
/* --------------------------------------------------------------------- */
/* Sits with the other lightbox controls, top-left, out of the way of the
   close button but obviously part of the same set. */
.lightbox__pick {
  position: absolute;
  top: clamp(0.75rem, 2vw, 1.5rem);
  left: clamp(0.75rem, 2vw, 1.5rem);
  z-index: 3;
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.6rem 1.1rem 0.6rem 0.75rem;
  border: 1px solid rgba(253, 251, 248, 0.4);
  border-radius: 2px;
  background: rgba(24, 21, 18, 0.55);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  color: var(--on-dark);
  font-size: 0.72rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background 0.18s var(--ease), border-color 0.18s var(--ease);
}
.lightbox__pick[hidden] { display: none; }
.lightbox__pick:hover { background: rgba(24, 21, 18, 0.8); border-color: rgba(253, 251, 248, 0.7); }
.lightbox__pick:focus-visible { outline: 2px solid var(--on-dark); outline-offset: 3px; }

.lightbox__pick-mark {
  position: relative;
  width: 1.15rem;
  height: 1.15rem;
  border: 1px solid rgba(253, 251, 248, 0.85);
  border-radius: 50%;
  flex: none;
  transition: background 0.18s var(--ease), border-color 0.18s var(--ease);
}
.lightbox__pick-mark::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 46%;
  width: 0.36rem;
  height: 0.19rem;
  border-left: 1.5px solid var(--ink);
  border-bottom: 1.5px solid var(--ink);
  transform: translate(-50%, -50%) rotate(-45deg) scale(0.5);
  opacity: 0;
  transition: opacity 0.15s var(--ease), transform 0.15s var(--ease);
}
.lightbox__pick.is-on { background: var(--accent); border-color: var(--accent); color: var(--on-dark); }
.lightbox__pick.is-on .lightbox__pick-mark { background: var(--on-dark); border-color: var(--on-dark); }
.lightbox__pick.is-on .lightbox__pick-mark::after { opacity: 1; transform: translate(-50%, -50%) rotate(-45deg) scale(1); }

@media (max-width: 700px) {
  /* On a phone the close button owns the top-right, so this drops to the
     bottom where a thumb can actually reach it. */
  .lightbox__pick {
    top: auto;
    bottom: clamp(3.5rem, 12vh, 6rem);
    left: 50%;
    transform: translateX(-50%);
  }
}

/* A gallery that is going to be deleted says so, and says it louder as the
   date gets close. */
.client-tools__until {
  margin: 0.6rem 0 0;
  font-size: 0.82rem;
  color: var(--muted);
}
.client-tools__closing {
  margin: 0.75rem 0 0;
  padding: 0.7rem 0.9rem;
  border-left: 2px solid var(--accent);
  background: rgba(150, 119, 90, 0.09);
  font-size: 0.9rem;
  line-height: 1.55;
  max-width: 46ch;
}
body.tone-charcoal .client-tools__closing { background: rgba(196, 169, 140, 0.12); }
