/* ============================================================
   The Eighth Beryl — Luxury Event Planning
   Emerald-drenched surface, gold linework, framed photography.
   See DESIGN.md for the system.
   ============================================================ */

:root {
  /* Emerald: the surface, not an accent. Hex equivalents in comments. */
  --emerald-950: oklch(24% 0.045 158);  /* #07271a */
  --emerald-900: oklch(28% 0.05 157);   /* #0c3323 */
  --emerald-800: oklch(33% 0.055 156);  /* #14402d */
  --emerald-700: oklch(40% 0.06 155);   /* #235940 */

  /* Gold: line and light, rarely fill. */
  --gold-300: oklch(87% 0.08 90);       /* #e9d3a2 */
  --gold-400: oklch(76% 0.11 88);       /* #cfa95e */
  --gold-500: oklch(65% 0.11 85);       /* #a8823c */
  --gold-on-cream: oklch(53% 0.089 81); /* the only gold legible on cream — 4.7:1 */

  /* Neutrals, all tinted green. No pure white, black or grey. */
  --cream: oklch(96% 0.015 95);
  --ink: oklch(30% 0.04 155);
  --ivory: oklch(93% 0.012 100);
  --sage: oklch(80% 0.03 150);

  /* The one red the palette admits, kept muted and green-shifted. */
  --alert-bg: oklch(28% 0.06 25);
  --alert-line: oklch(58% 0.13 25);
  --alert-text: oklch(87% 0.055 30);

  --gold-grad: linear-gradient(100deg, #a8823c, #e3c380 45%, #caa155);
  /* House curves. No bounce, no elastic: this brand does not overshoot. */
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);        /* quint, the default */
  --ease-out-quart: cubic-bezier(0.25, 1, 0.5, 1);   /* softer, for small state changes */
  --ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);    /* decisive, for the frame draw */
  --frame: 1px solid color-mix(in oklab, var(--gold-400) 55%, transparent);
  --section-gap: clamp(5rem, 10vw, 8.5rem);
  --font-display: "Bodoni Moda", "Didot", serif;
  --font-body: "Hanken Grotesk", "Segoe UI", sans-serif;

  /* Didone hairlines thin out badly on a dark ground. Pinning the optical-size
     axis low keeps the text cut's sturdier strokes even at display sizes. */
  --display-opsz: "opsz" 20;

  color-scheme: dark;
}

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

html {
  scroll-behavior: smooth;
  scroll-padding-top: 6rem; /* clears the fixed header */
}

body {
  margin: 0;
  background: var(--emerald-950);
  color: var(--ivory);
  font-family: var(--font-body);
  font-size: 1.09rem;
  font-weight: 430;
  line-height: 1.75;
  text-rendering: optimizeLegibility;
}

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

a { color: var(--gold-300); text-decoration-thickness: 1px; text-underline-offset: 3px; }

::selection { background: var(--gold-400); color: var(--emerald-950); }

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

/* ---------- Type ---------- */

/* Every surface set in the display face pins the optical-size axis and carries
   extra weight; both compensate for light-on-dark thinning. */
h1, h2, h3,
.stats strong,
.steps li::before,
.quotes blockquote p,
.gallery figcaption b {
  font-family: var(--font-display);
  font-optical-sizing: none;
  font-variation-settings: var(--display-opsz);
}

h1, h2, h3 {
  font-weight: 580;
  line-height: 1.14;
  margin: 0 0 1.2rem;
  color: var(--ivory);
  text-wrap: balance;
}

h1 { font-size: clamp(2.7rem, 6.5vw, 5.2rem); letter-spacing: 0.005em; }
h2 { font-size: clamp(1.95rem, 3.6vw, 3rem); }
h3 { font-size: clamp(1.32rem, 2vw, 1.58rem); line-height: 1.3; }

h1 em, h2 em {
  font-style: italic;
  font-weight: 560;
  color: var(--gold-400);
}

p { margin: 0 0 1.15rem; max-width: 68ch; text-wrap: pretty; }

.lede {
  font-size: clamp(1.16rem, 1.7vw, 1.32rem);
  font-weight: 420;
  line-height: 1.68;
  color: var(--sage);
}

/* 13.1px clears the Twenty-Pixel Rule's tracked-label exception; 12.8px did not. */
.kicker {
  display: block;
  font-size: 0.82rem;
  font-weight: 640;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--gold-300);
  margin-bottom: 1.1rem;
}

/* Visually hidden, still announced. */
.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute;
  top: 0; left: 50%;
  translate: -50% -110%;
  z-index: 100;
  background: var(--gold-grad);
  color: var(--emerald-950);
  font-weight: 650;
  padding: 0.75rem 1.5rem;
  border-radius: 0 0 4px 4px;
  text-decoration: none;
  transition: translate 0.2s var(--ease-out);
}
.skip-link:focus-visible { translate: -50% 0; }

/* ---------- Layout primitives ---------- */

.wrap { width: min(1200px, calc(100% - 3rem)); margin-inline: auto; }
.wrap-narrow { width: min(820px, calc(100% - 3rem)); margin-inline: auto; }

section { padding-block: calc(var(--section-gap) / 2); }

/* Gold rule with centre diamond — the banner's divider.
   Quarter-gap margins keep a ruled break at ~1.5x the plain section rhythm
   instead of the 2x it was, so the vertical pacing stays even down the page. */
.rule {
  border: 0;
  height: 1px;
  background: var(--gold-grad);
  opacity: 0.65;
  position: relative;
  margin: calc(var(--section-gap) / 4) auto;
  width: min(560px, 72%);
  overflow: visible;
}
.rule::after {
  content: "";
  position: absolute;
  left: 50%; top: 50%;
  width: 7px; height: 7px;
  translate: -50% -50%;
  rotate: 45deg;
  background: var(--gold-400);
}

/* The divider rules itself out from the centre, then sets its stone.
   The diamond stays hidden during the draw so it is never seen squashed. */
.rule { transform-origin: 50% 50%; }
.rule.will-draw { transform: scaleX(0); }
.rule.will-draw::after { opacity: 0; }
.rule.in-view {
  transform: scaleX(1);
  transition: transform 0.85s var(--ease-out-expo);
}
.rule.in-view::after {
  opacity: 1;
  transition: opacity 0.4s var(--ease-out-quart) 0.6s;
}

/* Hairline double-frame for photography — the banner's signature */
.frame {
  position: relative;
  overflow: hidden;
  background: var(--emerald-900);
}
.frame::after {
  content: "";
  position: absolute;
  inset: 10px;
  border: var(--frame);
  pointer-events: none;
}

/* The signature entrance: the vitrine's glass edge draws open from the centre
   over the photograph. clip-path only, so nothing here touches layout.
   .will-draw is applied by JS, so with no JS the frame is simply present. */
.frame.will-draw::after {
  clip-path: inset(47% 47%);
  opacity: 0;
}
.frame.in-view::after {
  clip-path: inset(0);
  opacity: 1;
  transition: clip-path 0.95s var(--ease-out-expo) 0.12s,
              opacity 0.45s var(--ease-out-quart) 0.12s;
}
.frame img {
  width: 100%; height: 100%;
  object-fit: cover;
  transition: transform 0.6s var(--ease-out);
}
.frame:hover img,
a.frame:focus-visible img { transform: scale(1.03); }

/* Outlined pills — the banner's "what we offer" chips */
.pills { display: flex; flex-wrap: wrap; gap: 0.65rem; padding: 0; margin: 1.4rem 0 0; list-style: none; }
.pill {
  border: 1px solid color-mix(in oklab, var(--gold-400) 60%, transparent);
  color: var(--gold-300);
  border-radius: 999px;
  padding: 0.32rem 1.05rem;
  font-size: 0.86rem;
  letter-spacing: 0.03em;
  white-space: nowrap;
}

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

.btn {
  display: inline-block;
  font-family: var(--font-body);
  font-weight: 650;
  font-size: 0.95rem;
  letter-spacing: 0.05em;
  padding: 0.9rem 1.9rem;
  border-radius: 4px;
  text-decoration: none;
  cursor: pointer;
  border: 0;
  /* border-color was animated but never listed here, so the outline button snapped. */
  transition: transform 0.25s var(--ease-out), box-shadow 0.25s var(--ease-out),
              border-color 0.25s var(--ease-out), opacity 0.25s var(--ease-out);
}
.btn-gold {
  background: var(--gold-grad);
  color: var(--emerald-950);
}
.btn-gold:hover, .btn-gold:focus-visible { transform: translateY(-1px); box-shadow: 0 8px 24px rgb(0 0 0 / 0.35); }
.btn-outline {
  background: transparent;
  border: 1px solid color-mix(in oklab, var(--gold-400) 70%, transparent);
  color: var(--gold-300);
}
.btn-outline:hover, .btn-outline:focus-visible { border-color: var(--gold-300); transform: translateY(-1px); }
.btn:active { transform: translateY(1px); }
.btn:disabled {
  opacity: 0.55;
  cursor: not-allowed;
  transform: none;
  box-shadow: none;
}

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

.site-header {
  position: fixed;
  inset-inline: 0; top: 0;
  z-index: 50;
  transition: background-color 0.35s, border-color 0.35s;
  border-bottom: 1px solid transparent;
}
/* An open menu needs the solid bar too, or the logo and toggle
   float over bare hero photography at the top of the page. */
.site-header.scrolled,
.site-header:has(.nav-links.open) {
  background: color-mix(in oklab, var(--emerald-950) 92%, transparent);
  backdrop-filter: blur(10px);
  border-bottom-color: color-mix(in oklab, var(--gold-400) 30%, transparent);
}
.nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding-block: 0.9rem;
}
.brand {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  min-height: 44px;
  text-decoration: none;
  color: var(--ivory);
}
.site-header .brand img { height: 40px; width: auto; }
.site-footer .brand img { height: 34px; width: auto; }
.brand-name {
  font-family: var(--font-body);
  font-size: 0.92rem;
  font-weight: 650;
  letter-spacing: 0.22em;
  text-transform: uppercase;
}
.nav-links {
  display: flex;
  align-items: center;
  gap: clamp(1.1rem, 2.5vw, 2.1rem);
  list-style: none;
  margin: 0; padding: 0;
}
.nav-links a {
  color: var(--ivory);
  text-decoration: none;
  font-size: 0.95rem;
  letter-spacing: 0.04em;
  padding-block: 0.3rem;
  border-bottom: 1px solid transparent;
  transition: color 0.2s, border-color 0.2s;
}
.nav-links a:hover { color: var(--gold-300); }
.nav-links a[aria-current="page"] {
  color: var(--gold-300);
  border-bottom-color: var(--gold-400);
}
.nav-links .nav-cta {
  border: 1px solid color-mix(in oklab, var(--gold-400) 70%, transparent);
  border-radius: 999px;
  padding: 0.45rem 1.3rem;
  color: var(--gold-300);
}
.nav-links .nav-cta:hover { border-color: var(--gold-300); }

.nav-toggle {
  display: none;
  background: none;
  border: 1px solid color-mix(in oklab, var(--gold-400) 60%, transparent);
  border-radius: 4px;
  color: var(--gold-300);
  font: inherit;
  font-size: 0.95rem;
  min-height: 44px;
  padding: 0.4rem 1.1rem;
  cursor: pointer;
  transition: border-color 0.2s;
}
.nav-toggle:hover { border-color: var(--gold-300); }

@media (max-width: 820px) {
  .nav-toggle { display: block; }
  .nav-links {
    position: absolute;
    top: 100%; left: 0; right: 0;
    flex-direction: column;
    align-items: stretch;
    text-align: center;
    background: var(--emerald-950);
    border-bottom: 1px solid color-mix(in oklab, var(--gold-400) 30%, transparent);
    padding: 0.6rem 1.5rem 1.2rem;
    gap: 0.2rem;
    display: none;
    opacity: 0;
    translate: 0 -10px;
    /* allow-discrete lets display participate, so the panel fades and settles
       instead of snapping. Browsers without support just snap, as before. */
    transition: opacity 0.26s var(--ease-out-quart),
                translate 0.26s var(--ease-out-quart),
                display 0.26s allow-discrete;
  }
  .nav-links.open { display: flex; opacity: 1; translate: 0 0; }
  @starting-style {
    .nav-links.open { opacity: 0; translate: 0 -10px; }
  }
  /* Full-width, 44px-tall tap targets rather than 30px text runs. */
  .nav-links a {
    display: block;
    min-height: 44px;
    padding-block: 0.75rem;
    border-bottom: 0;
  }
  .nav-links a[aria-current="page"] { border-bottom: 0; }
  .nav-links .nav-cta { margin-top: 0.5rem; }
}

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

.hero {
  position: relative;
  min-height: min(94svh, 900px);
  display: flex;
  align-items: flex-end;
  padding: 0;
  isolation: isolate;
}
.hero-media, .hero-media img { position: absolute; inset: 0; z-index: -2; }
.hero-media img { width: 100%; height: 100%; object-fit: cover; }
.hero::before {
  content: "";
  position: absolute; inset: 0; z-index: -1;
  background:
    /* Top scrim: the header is transparent over the hero, so the nav needs
       ground of its own before the page is scrolled. */
    linear-gradient(to bottom, color-mix(in oklab, var(--emerald-950) 72%, transparent), transparent 22%),
    linear-gradient(to top, var(--emerald-950) 4%, color-mix(in oklab, var(--emerald-950) 78%, transparent) 34%, color-mix(in oklab, var(--emerald-950) 30%, transparent) 70%),
    color-mix(in oklab, var(--emerald-950) 26%, transparent);
}
.hero-inner { padding-block: clamp(7rem, 14vh, 10rem) clamp(3.5rem, 7vh, 5.5rem); }
.hero h1 { max-width: 12ch; margin-bottom: 1.6rem; }
.hero .lede { color: var(--ivory); max-width: 52ch; }
.hero-ctas { display: flex; flex-wrap: wrap; gap: 1rem; margin-top: 2.2rem; }

/* ---------- Editorial rows ---------- */

.row {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: clamp(1.5rem, 4vw, 4rem);
  align-items: center;
}
.row + .row { margin-top: clamp(3.5rem, 7vw, 6rem); }
.row .media { grid-column: 1 / 7; aspect-ratio: 4 / 3.1; }
.row .copy { grid-column: 7 / 13; }
.row.flip .media { grid-column: 7 / 13; order: 2; }
.row.flip .copy { grid-column: 1 / 7; order: 1; }

@media (max-width: 760px) {
  .row .media, .row .copy,
  .row.flip .media, .row.flip .copy { grid-column: 1 / -1; order: initial; }
  .row .media { aspect-ratio: 16 / 10; }
}

/* ---------- Stats band ---------- */

.stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 2rem;
  text-align: center;
  border-block: var(--frame);
  padding-block: clamp(2.5rem, 5vw, 3.75rem);
}
.stats strong {
  display: block;
  font-family: var(--font-display);
  font-size: clamp(2.4rem, 4.5vw, 3.4rem);
  font-weight: 500;
  color: var(--gold-400);
  line-height: 1.1;
}
.stats span {
  font-size: 0.82rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--sage);
}

/* ---------- The Beryl Standard (process) ---------- */

.steps {
  counter-reset: step;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: clamp(1.8rem, 3.5vw, 3rem);
  margin-top: 2.5rem;
  padding: 0;
  list-style: none;
}
.steps li { counter-increment: step; }
.steps li::before {
  content: "0" counter(step);
  display: block;
  font-family: var(--font-display);
  font-style: italic;
  font-size: 1.7rem;
  color: var(--gold-400);
  margin-bottom: 0.6rem;
}
.steps h3 { margin-bottom: 0.5rem; }
.steps p { font-size: 0.98rem; color: var(--sage); margin: 0; }

/* ---------- Portfolio ---------- */

.filters {
  display: flex;
  flex-wrap: wrap;
  gap: 0.65rem;
  margin: 2rem 0 2.8rem;
}
.filters button {
  font: inherit;
  font-size: 0.9rem;
  letter-spacing: 0.04em;
  background: none;
  border: 1px solid color-mix(in oklab, var(--gold-400) 55%, transparent);
  color: var(--gold-300);
  border-radius: 999px;
  min-height: 44px;
  padding: 0.42rem 1.35rem;
  cursor: pointer;
  transition: color 0.25s, border-color 0.25s;
}
.filter-count { color: var(--sage); font-size: 0.9rem; margin: -1.4rem 0 2.4rem; }
.filters button:hover { border-color: var(--gold-300); }
.filters button[aria-pressed="true"] {
  background: var(--gold-grad);
  color: var(--emerald-950);
  border-color: transparent;
  font-weight: 650;
}

.gallery {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: clamp(1rem, 2vw, 1.6rem);
}
.gallery figure { margin: 0; }
.gallery .item { grid-column: span 2; display: block; }
.gallery .item.wide { grid-column: span 4; }
/* display:block matters because these frames are anchors on the home page. */
.gallery .item .frame { display: block; aspect-ratio: 4 / 3; }
.gallery .item.wide .frame { aspect-ratio: 16 / 8.4; }
.gallery figcaption {
  padding-top: 0.85rem;
  font-size: 0.95rem;
  color: var(--sage);
}
.gallery figcaption b {
  display: block;
  font-weight: 580;
  font-size: 1.16rem;
  line-height: 1.35;
  color: var(--ivory);
  letter-spacing: 0.005em;
}
.gallery .item.hidden { display: none; }

/* Filtering: the grid dims, re-lays out while it is invisible, then the
   surviving events settle back in sequence. Crossfading the container is what
   keeps the reflow from being seen; no layout property is animated. */
.gallery { transition: opacity 0.16s var(--ease-out-quart); }
.gallery.swapping { opacity: 0; }
@keyframes item-settle {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: none; }
}
.gallery.settling .item:not(.hidden) {
  animation: item-settle 0.5s var(--ease-out) backwards;
  animation-delay: calc(var(--i, 0) * 45ms);
}

@media (max-width: 900px) {
  .gallery { grid-template-columns: 1fr 1fr; }
  .gallery .item, .gallery .item.wide { grid-column: span 1; }
  .gallery .item.wide .frame { aspect-ratio: 4 / 3; }
}
@media (max-width: 560px) {
  .gallery { grid-template-columns: 1fr; }
}

/* ---------- Testimonials ---------- */

.quotes {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: clamp(1.8rem, 3.5vw, 3rem);
}
.quotes blockquote {
  margin: 0;
  padding-top: 1.6rem;
  border-top: var(--frame);
}
.quotes blockquote p {
  font-style: italic;
  font-weight: 520;
  font-size: 1.3rem;
  line-height: 1.55;
  color: var(--ivory);
}
.quotes cite {
  font-style: normal;
  font-size: 0.86rem;
  font-weight: 550;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--gold-300);
}

/* ---------- Cream CTA panel ---------- */

.panel {
  background: var(--cream);
  color: var(--ink);
  border-radius: 10px;
  padding: clamp(2.4rem, 5vw, 4rem);
  position: relative;
}
.panel::after {
  content: "";
  position: absolute;
  inset: 10px;
  border: 1px solid color-mix(in oklab, var(--gold-500) 45%, transparent);
  border-radius: 6px;
  pointer-events: none;
}
/* The Cream Exception Rule. Nothing on cream may use emerald-ground colours:
   sage lands at 1.6:1 and gold-300 at 1.3:1 against this background. */
.panel :is(h2, h3, h4) { color: var(--ink); }
.panel :is(p, li) { color: color-mix(in oklab, var(--ink) 82%, var(--cream)); }
/* A trailing margin on the last child sits inside the panel and reads as extra
   bottom padding. It also pushed vertically-centred panel columns off centre. */
.panel :is(p, h2, h3, h4, ul, ol):last-child { margin-bottom: 0; }
.panel .kicker { color: var(--gold-on-cream); }
/* :not(.btn) matters — the gold CTA sits inside this panel and keeps its own
   emerald-on-gold colour. */
.panel a:not(.btn) { color: var(--gold-on-cream); font-weight: 550; }
.panel a:not(.btn):hover { color: var(--ink); }
/* The action column sizes to the button rather than taking a 1fr share, which
   left a ~210px button floating in ~450px of column with dead space either
   side. Now it anchors to the panel's right edge and the copy takes the rest. */
.panel-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: clamp(1.5rem, 4vw, 3.5rem);
  align-items: center;
  position: relative;
  z-index: 1;
}
@media (max-width: 760px) { .panel-grid { grid-template-columns: 1fr; } }

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

.form-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1.3rem 1.5rem;
}
.form-grid .full { grid-column: 1 / -1; }
@media (max-width: 640px) { .form-grid { grid-template-columns: 1fr; } }

label {
  display: block;
  font-size: 0.86rem;
  font-weight: 650;
  letter-spacing: 0.06em;
  margin-bottom: 0.45rem;
  color: var(--gold-300);
}
label .opt { font-weight: 400; color: var(--sage); letter-spacing: 0; }

input, select, textarea {
  width: 100%;
  font: inherit;
  color: var(--ivory);
  background: var(--emerald-800);
  border: 1px solid var(--emerald-700);
  border-radius: 4px;
  padding: 0.85rem 1rem;
  min-height: 48px;
  transition: border-color 0.2s, box-shadow 0.2s;
}
input::placeholder, textarea::placeholder { color: color-mix(in oklab, var(--sage) 72%, transparent); }
input:focus, select:focus, textarea:focus {
  /* Transparent outline is deliberate: it survives forced-colors mode. */
  outline: 2px solid transparent;
  border-color: var(--gold-400);
  box-shadow: 0 0 0 2px var(--gold-400);
}
input[aria-invalid="true"], select[aria-invalid="true"], textarea[aria-invalid="true"] {
  border-color: var(--alert-line);
}
input[aria-invalid="true"]:focus, select[aria-invalid="true"]:focus, textarea[aria-invalid="true"]:focus {
  box-shadow: 0 0 0 2px var(--alert-line);
}

select {
  appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, var(--gold-300) 50%), linear-gradient(135deg, var(--gold-300) 50%, transparent 50%);
  background-position: calc(100% - 20px) 50%, calc(100% - 14px) 50%;
  background-size: 6px 6px;
  background-repeat: no-repeat;
}
/* An unchosen select should read as a prompt, not as an answer. */
select:has(option[value=""]:checked) { color: color-mix(in oklab, var(--sage) 72%, transparent); }
option { background: var(--emerald-900); color: var(--ivory); }

/* Without this the calendar and spinner glyphs render dark-on-dark. */
::-webkit-calendar-picker-indicator { filter: invert(85%) sepia(18%) saturate(340%) hue-rotate(2deg); cursor: pointer; }

textarea { min-height: 150px; resize: vertical; }

.form-status {
  margin-top: 1.2rem;
  padding: 1rem 1.2rem;
  border-radius: 4px;
  font-weight: 600;
  max-width: none;
  display: none;
  opacity: 0;
  translate: 0 -6px;
  transition: opacity 0.3s var(--ease-out-quart),
              translate 0.3s var(--ease-out-quart),
              display 0.3s allow-discrete;
}
.form-status.ok, .form-status.err { display: block; opacity: 1; translate: 0 0; }
@starting-style {
  .form-status.ok, .form-status.err { opacity: 0; translate: 0 -6px; }
}
.form-status.ok { background: var(--emerald-800); border: 1px solid var(--gold-400); color: var(--gold-300); }
.form-status.err { background: var(--alert-bg); border: 1px solid var(--alert-line); color: var(--alert-text); }

/* Empty by default, so it must not hold space until it has something to say. */
.field-error {
  display: none;
  margin-top: 0.4rem;
  font-size: 0.85rem;
  font-weight: 550;
  letter-spacing: 0;
  text-transform: none;
  color: var(--alert-text);
  opacity: 0;
  translate: 0 -4px;
  transition: opacity 0.24s var(--ease-out-quart),
              translate 0.24s var(--ease-out-quart),
              display 0.24s allow-discrete;
}
.field-error:not(:empty) { display: block; opacity: 1; translate: 0 0; }
@starting-style {
  .field-error:not(:empty) { opacity: 0; translate: 0 -4px; }
}

/* Scoped to the emerald block only. These used to apply inside the cream panel
   too, painting the email, phone and Instagram links at 1.3:1. */
/* Promoted from h3 to h2 to close a heading-level skip; kept at title size. */
.contact-aside :is(h2, h3) {
  font-size: clamp(1.3rem, 2vw, 1.55rem);
  line-height: 1.3;
  margin-bottom: 0.6rem;
}
.contact-aside .panel p { margin-bottom: 1.5rem; }

/* Ruled rows rather than a loose stack of paragraphs. Previously each link's
   separation came from padding inside its own box, so the tap targets shared an
   edge with no gap between them. The hairline is the brand's own device, tinted
   with ink because gold would compete with the panel's inner frame. */
.contact-routes {
  list-style: none;
  margin: 0;
  padding: 0;
  border-block: 1px solid color-mix(in oklab, var(--ink) 14%, transparent);
}
.contact-routes li + li { border-top: 1px solid color-mix(in oklab, var(--ink) 14%, transparent); }
.contact-routes a {
  display: flex;
  align-items: center;
  min-height: 48px;
  padding-block: 0.55rem;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}
.next-steps { margin-top: 2.6rem; }
.next-steps :is(h2, h3) { margin-bottom: 1rem; }
.next-steps p { color: var(--sage); }
.next-steps a { color: var(--gold-300); }

/* The same conceptual object as .steps, so it borrows that vocabulary — Bodoni
   italic numerals in gold — instead of inventing a second numbered-list style.
   Ruled rather than boxed: a card here would sit inside the cream panel's
   shadow and read as a container stack. */
.next-steps ol {
  counter-reset: next-step;
  list-style: none;
  margin: 0;
  padding: 0;
  border-bottom: 1px solid color-mix(in oklab, var(--gold-400) 22%, transparent);
}
.next-steps li {
  counter-increment: next-step;
  display: grid;
  grid-template-columns: 2.3rem 1fr;
  gap: 0 0.85rem;
  align-items: baseline;
  margin: 0;
  padding: 0.9rem 0;
  border-top: 1px solid color-mix(in oklab, var(--gold-400) 22%, transparent);
  color: var(--sage);
  font-size: 0.99rem;
  line-height: 1.6;
}
.next-steps li::before {
  content: "0" counter(next-step);
  font-family: var(--font-display);
  font-optical-sizing: none;
  font-variation-settings: var(--display-opsz);
  font-style: italic;
  font-weight: 560;
  font-size: 1.35rem;  /* 21.6px, clearing the Twenty-Pixel Rule for gold-400 */
  line-height: 1;
  color: var(--gold-400);
}

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

.site-footer {
  border-top: var(--frame);
  padding: clamp(3rem, 6vw, 4.5rem) 0 2rem;
  margin-top: var(--section-gap);
}
.footer-grid {
  display: grid;
  grid-template-columns: 2fr 1fr 1fr;
  gap: 2.5rem;
}
@media (max-width: 760px) { .footer-grid { grid-template-columns: 1fr; } }
.site-footer h4 {
  font-size: 0.8rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--gold-300);
  margin: 0 0 1rem;
}
.site-footer ul { list-style: none; margin: 0; padding: 0; }
.site-footer li { margin-bottom: 0.15rem; }
.site-footer a {
  color: var(--sage);
  text-decoration: none;
  display: inline-block;
  padding-block: 0.5rem;
  transition: color 0.2s;
}
.site-footer a:hover { color: var(--gold-300); }
.site-footer .brand { padding-block: 0; margin-bottom: 1rem; }
.footer-brand p { color: var(--sage); font-size: 0.96rem; max-width: 38ch; }
.footer-bottom {
  margin-top: 3rem;
  padding-top: 1.4rem;
  border-top: 1px solid color-mix(in oklab, var(--gold-400) 18%, transparent);
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 1rem;
  font-size: 0.85rem;
  color: color-mix(in oklab, var(--sage) 75%, transparent);
}

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

.reveal {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity 0.7s var(--ease-out), transform 0.7s var(--ease-out);
}
.reveal.in { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .reveal { opacity: 1; transform: none; transition: none; }
  .frame img, .btn, .skip-link { transition: none; }
  .frame:hover img, a.frame:focus-visible img { transform: none; }
  .btn:hover, .btn:focus-visible, .btn:active { transform: none; }

  /* Every state still resolves, it just arrives already resolved.
     JS also withholds .will-draw entirely, so the draws never begin. */
  .frame::after, .rule, .rule::after {
    transition: none;
    clip-path: none;
    transform: none;
    opacity: 1;
  }
  .gallery, .nav-links, .form-status, .field-error { transition: none; }
  .gallery.swapping { opacity: 1; }
  .gallery.settling .item:not(.hidden) { animation: none; }
  .nav-links { opacity: 1; translate: none; }
  .form-status.ok, .form-status.err,
  .field-error:not(:empty) { opacity: 1; translate: none; }
}

/* ---------- Page hero (inner pages) ---------- */

.page-head {
  padding-top: clamp(8rem, 16vh, 11rem);
  padding-bottom: clamp(1rem, 3vh, 2rem);
}
.page-head h1 { max-width: 16ch; }

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

/* Its own grid rather than the 12-column editorial row. The row's column spans
   had to be set inline, which then beat the stylesheet's mobile reset and left
   the form pinned to 7 of 12 columns on a phone. */
.contact-layout {
  display: grid;
  grid-template-columns: minmax(0, 1.55fr) minmax(0, 1fr);
  gap: clamp(2rem, 4vw, 4rem);
  align-items: start;
}
@media (max-width: 860px) {
  .contact-layout { grid-template-columns: 1fr; }
}

.form-actions { margin: 1.6rem 0 0; }

/* ---------- Rhythm utilities ---------- */

.stack-sm { margin-top: 2.5rem; }
.stack-md { margin-top: 3rem; }
.stack-lg { margin-top: 3.5rem; }
.section-flush { padding-top: 0; }
.section-tight { padding-top: 1rem; }
.lede { max-width: 56ch; }
.media--portrait { aspect-ratio: 4 / 4.6; }
.steps--stacked { grid-template-columns: 1fr; gap: 2.2rem; }
.panel-grid h2 { margin-bottom: 0.8rem; }
.panel-action { align-self: center; justify-self: start; }
@media (min-width: 761px) { .panel-action { justify-self: end; } }
.follow-note { margin-top: 3rem; color: var(--sage); font-size: 0.96rem; }
.follow-note a { display: inline-block; padding-block: 0.6rem; }
