/* =============================================================================
   Cecelia Photography — Linen & Moss
   The brand world, October 2026. Documented in docs/BRANDING.md.

   A quiet editorial gallery: white walls, espresso lettering, the six brand
   colours taken straight from the original identity. A light, high-contrast
   serif carries every heading; a widely tracked geometric sans carries every
   label, the way the "Photography" line sits under the wordmark. Photographs
   run large and are left alone. Glass appears only where something floats
   over a photograph.
   ========================================================================== */

/* ----------------------------------------------------------------- fonts -- */

@font-face {
  font-family: 'Cormorant Garamond';
  src: url('/assets/fonts/cormorant-normal-latin.woff2') format('woff2');
  font-weight: 300 600;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Cormorant Garamond';
  src: url('/assets/fonts/cormorant-normal-latin-ext.woff2') format('woff2');
  font-weight: 300 600;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Cormorant Garamond';
  src: url('/assets/fonts/cormorant-italic-latin.woff2') format('woff2');
  font-weight: 300 500;
  font-style: italic;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Cormorant Garamond';
  src: url('/assets/fonts/cormorant-italic-latin-ext.woff2') format('woff2');
  font-weight: 300 500;
  font-style: italic;
  font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Jost';
  src: url('/assets/fonts/jost-latin.woff2') format('woff2');
  font-weight: 300 500;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Jost';
  src: url('/assets/fonts/jost-latin-ext.woff2') format('woff2');
  font-weight: 300 500;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

:root {
  /* The six brand colours, exactly as the identity defines them ---------- */
  --espresso: #544541;   /* lettering, dark grounds            9.1:1 on white */
  --coffee:   #735e4f;   /* links, hover, emphasis             6.1:1 on white */
  --moss:     #756f62;   /* the wordmark; secondary text       5.0:1 on white */
  --petal:    #b2b1ad;   /* decoration only: rules, marks      never for text */
  --linen:    #dbdbd9;   /* hairlines, quiet fields                           */
  --mist:     #f5f5f5;   /* alternate bands                                    */
  --white:    #ffffff;

  /* Roles. Older component names are kept and pointed at the brand, so every
     screen built before the rebrand inherits it without being rewritten. */
  --paper:        var(--white);
  --mount:        var(--mist);
  --mount-deep:   #ebeae7;   /* one step between mist and linen */
  --kraft:        var(--linen);
  --kraft-deep:   var(--petal);
  --ink:          var(--espresso);
  --ink-2:        #685b55;   /* espresso lifted a step: 6.6:1 on white */
  --ink-3:        var(--moss);

  --rule:         var(--linen);
  --rule-soft:    #ebeae7;
  --rule-ink:     rgba(84, 69, 65, 0.16);

  /* States: muted, and tuned to sit beside moss and coffee rather than shout */
  --stop:         #8a4a36;
  --stop-field:   #f5ebe6;
  --fix:          #56603f;
  --fix-field:    #eceee5;
  --wash:         #4f5e66;
  --wash-field:   #e8ecee;
  --hold:         var(--espresso);
  --hold-field:   #ebeae7;

  /* Glass: only ever over a photograph or over scrolling content ---------- */
  --glass:        rgba(255, 255, 255, 0.64);
  --glass-strong: rgba(255, 255, 255, 0.82);
  --glass-edge:   rgba(255, 255, 255, 0.55);
  --glass-dark:   rgba(52, 42, 39, 0.34);
  --glass-blur:   saturate(1.35) blur(18px);

  /* Type ------------------------------------------------------------------ */
  --serif: 'Cormorant Garamond', 'Cormorant', Garamond, 'Times New Roman', serif;
  --sans:  'Jost', 'Futura', 'Century Gothic', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --face:  var(--sans);

  --step--2: clamp(0.688rem, 0.67rem + 0.09vw, 0.75rem);
  --step--1: clamp(0.844rem, 0.82rem + 0.11vw, 0.906rem);
  --step-0:  clamp(1rem, 0.97rem + 0.14vw, 1.0625rem);
  --step-1:  clamp(1.25rem, 1.18rem + 0.33vw, 1.5rem);
  --step-2:  clamp(1.5rem, 1.36rem + 0.67vw, 2rem);
  --step-3:  clamp(1.875rem, 1.6rem + 1.33vw, 2.875rem);
  --step-4:  clamp(2.375rem, 1.9rem + 2.4vw, 4.125rem);
  --step-5:  clamp(2.875rem, 2rem + 4.4vw, 6rem);

  --track-label: 0.24em;    /* the tracked caps of the "Photography" line */

  /* Space ----------------------------------------------------------------- */
  --s-1: 0.25rem;
  --s-2: 0.5rem;
  --s-3: 0.75rem;
  --s-4: 1rem;
  --s-5: 1.5rem;
  --s-6: 2rem;
  --s-7: 3rem;
  --s-8: 4rem;
  --s-9: 6rem;
  --s-10: 8rem;

  --gutter: clamp(1.25rem, 4.5vw, 4rem);
  --measure: 66ch;
  --shell: 82rem;
  --masthead-h: 5.75rem;

  /* Motion ---------------------------------------------------------------- */
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
  --ease-soft: cubic-bezier(0.33, 0, 0.12, 1);
  --t-fast: 160ms;
  --t-base: 300ms;
  --t-slow: 760ms;
  --t-print: 1300ms;

  /* Depth: offset plus soft blur, tinted with espresso, never a flat halo --- */
  --lift-1: 0 1px 2px rgba(84, 69, 65, 0.05), 0 2px 8px rgba(84, 69, 65, 0.04);
  --lift-2: 0 2px 6px rgba(84, 69, 65, 0.06), 0 14px 34px rgba(84, 69, 65, 0.09);
  --lift-3: 0 8px 16px rgba(84, 69, 65, 0.08), 0 30px 70px rgba(84, 69, 65, 0.14);
}

/* --------------------------------------------------------------- reset --- */

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--masthead-h) + 1rem);
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  font-size: var(--step-0);
  font-weight: 350;
  line-height: 1.7;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

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

h1, h2, h3, h4, h5, p, figure, blockquote, ul, ol, dl, dd { margin: 0; }
ul[class], ol[class] { list-style: none; padding: 0; }

a { color: inherit; }
strong, b { font-weight: 500; }

button, input, select, textarea {
  font: inherit;
  color: inherit;
  letter-spacing: inherit;
}

:focus-visible {
  outline: 1.5px solid var(--coffee);
  outline-offset: 3px;
}
:focus:not(:focus-visible) { outline: none; }

::selection { background: var(--linen); color: var(--espresso); }

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

.skip-link {
  position: absolute;
  top: -100%;
  left: var(--s-4);
  z-index: 200;
  padding: var(--s-3) var(--s-5);
  background: var(--ink);
  color: var(--paper);
  text-decoration: none;
  font-size: var(--step--1);
  transition: top var(--t-fast) var(--ease-out);
}
.skip-link:focus { top: var(--s-4); }

/* ------------------------------------------------------------ typography - */

h1, h2, h3, h4 {
  font-family: var(--serif);
  font-weight: 400;
  line-height: 1.08;
  letter-spacing: -0.01em;
  text-wrap: balance;
  font-variant-numeric: lining-nums;
}

/* The display voice: light, large, and allowed one italic word. */
.display {
  font-family: var(--serif);
  font-size: var(--step-5);
  font-weight: 300;
  line-height: 1.02;
  letter-spacing: -0.018em;
}
.display em, .title-xl em, .title-l em { font-style: italic; font-weight: 300; }

.title-xl { font-size: var(--step-4); font-weight: 300; letter-spacing: -0.015em; }
.title-l  { font-size: var(--step-3); font-weight: 400; letter-spacing: -0.012em; }
.title-m  { font-size: var(--step-2); font-weight: 400; line-height: 1.15; }
.title-s  { font-size: var(--step-1); font-weight: 500; line-height: 1.25; letter-spacing: 0; }

/* The second voice of every page: the serif at reading size. */
.lede {
  font-family: var(--serif);
  font-size: var(--step-1);
  font-weight: 400;
  line-height: 1.5;
  color: var(--ink-2);
  max-width: 44ch;
}

.prose { max-width: var(--measure); }
.prose p + p { margin-top: 1em; }
.prose a { color: var(--coffee); text-underline-offset: 0.22em; text-decoration-thickness: 1px; }

/* Label type: the tracked caps under the wordmark. Navigation, labels,
   statuses, figures. Never above a heading as a kicker. */
.spec {
  font-family: var(--sans);
  font-size: var(--step--2);
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: var(--track-label);
  color: var(--ink-3);
  line-height: 1.5;
}
.spec-ink { color: var(--ink); }

.muted { color: var(--ink-3); }
.dim { color: var(--ink-2); }
.tnum { font-variant-numeric: lining-nums tabular-nums; }

/* A short hairline under a heading, the way the reference set uses it. */
.hairline {
  display: block;
  width: 3rem;
  height: 1px;
  background: var(--petal);
  border: 0;
  margin: var(--s-5) 0;
}
.center .hairline, .hairline.is-centered { margin-inline: auto; }

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

.shell {
  width: 100%;
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.shell-narrow { max-width: 56rem; }
.shell-wide { max-width: 100rem; }

.band { padding-block: clamp(4rem, 10vw, 9rem); }
.band-tight { padding-block: clamp(2.5rem, 5vw, 4.5rem); }
.band-mount { background: var(--mist); }
.band-linen { background: var(--linen); }
.band-ink { background: var(--espresso); color: var(--white); }
.band-ink .muted, .band-ink .spec { color: rgba(255, 255, 255, 0.7); }
.band-ink .lede { color: rgba(255, 255, 255, 0.84); }

.center { text-align: center; }
.center .lede, .center .prose { margin-inline: auto; }

.stack > * + * { margin-top: var(--s-4); }
.stack-s > * + * { margin-top: var(--s-2); }
.stack-l > * + * { margin-top: var(--s-6); }
.stack-xl > * + * { margin-top: var(--s-8); }

.row { display: flex; gap: var(--s-4); align-items: center; }
.row-between { justify-content: space-between; }
.row-wrap { flex-wrap: wrap; }
.row-top { align-items: flex-start; }
.spacer { flex: 1 1 auto; }

.grid { display: grid; gap: var(--s-6); }
.grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.grid-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }

@media (max-width: 62rem) {
  .grid-3, .grid-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 40rem) {
  .grid-2, .grid-3, .grid-4 { grid-template-columns: minmax(0, 1fr); }
}

/* A heading sits under more air than it gives away. */
.section-head {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: var(--s-4);
  align-items: end;
  padding-bottom: var(--s-5);
  margin-bottom: var(--s-7);
  border-bottom: 1px solid var(--rule);
}
@media (max-width: 40rem) {
  .section-head { grid-template-columns: minmax(0, 1fr); align-items: start; }
}

.section-head + .stages,
.section-head + .ratecard,
.section-head + .tracker { border-top: 0; }

.band + .band,
.band + .band-tight,
.band-tight + .band { padding-top: clamp(2rem, 4.5vw, 4rem); }
.band-mount + .band, .band + .band-mount, .band-ink + .band, .band + .band-ink { padding-top: clamp(4rem, 10vw, 9rem); }

.rule { height: 1px; background: var(--rule); border: 0; margin: 0; }
.rule-ink { height: 1px; background: var(--rule-ink); border: 0; margin: 0; }

/* ============================================================== imagery ==
   Photographs run large and are left alone: no mount board, no rounded
   corners, no border. A quiet field shows while they load.
   ======================================================================== */

.frame {
  position: relative;
  display: block;
  overflow: hidden;
  background: var(--mount-deep);
  isolation: isolate;
}
.frame img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.frame-tall   { aspect-ratio: 3 / 4; }
.frame-square { aspect-ratio: 1 / 1; }
.frame-wide   { aspect-ratio: 4 / 3; }
.frame-pano   { aspect-ratio: 16 / 9; }
.frame-sheet  { aspect-ratio: 2 / 3; }

/* Kept for older markup: a mounted print is now simply the photograph. */
.mounted { background: none; padding: 0; border: 0; }
.mounted .frame { border: 0; }

/* The reveal: a curtain lifts off the photograph from the bottom while the
   image settles from a slight enlargement. One authored motion, used on every
   photograph, so the whole site moves the same way. */
.develop { --develop-delay: 0ms; }
.develop .frame,
.develop > .develop-target {
  clip-path: inset(100% 0 0 0);
  transition: clip-path 1150ms var(--ease-out) var(--develop-delay);
}
.develop img {
  transform: scale(1.12);
  transition: transform 1700ms var(--ease-out) var(--develop-delay);
}
.develop.is-developed .frame,
.develop.is-developed > .develop-target { clip-path: inset(0 0 0 0); }
.develop.is-developed img { transform: scale(1); }

/* Text rises a short distance. */
.rise {
  --rise-delay: 0ms;
  opacity: 0.001;
  transform: translateY(18px);
  transition:
    opacity var(--t-slow) var(--ease-out) var(--rise-delay),
    transform var(--t-slow) var(--ease-out) var(--rise-delay);
}
.rise.is-in { opacity: 1; transform: none; }

/* Anything JS never reaches must still be readable and visible. */
.no-js .develop .frame,
.no-js .develop > .develop-target,
.is-revealed .develop .frame,
.is-revealed .develop > .develop-target { clip-path: none; }
.no-js .develop img,
.is-revealed .develop img { transform: none; }
.no-js .rise,
.is-revealed .rise { opacity: 1; transform: none; }

@media (scripting: none) {
  .develop .frame, .develop > .develop-target { clip-path: none; }
  .develop img, .rise { opacity: 1; transform: none; }
}

/* ================================================================ chrome ==
   The masthead: the wordmark centred, the navigation split either side of
   it. Over a hero photograph it is transparent with the wordmark in white;
   once the page scrolls it becomes frosted glass.
   ======================================================================== */

.masthead {
  position: sticky;
  top: 0;
  z-index: 60;
  color: var(--ink);
  background: var(--glass-strong);
  border-bottom: 1px solid var(--rule-soft);
  view-transition-name: masthead;
  transition: background var(--t-base) var(--ease-out),
              border-color var(--t-base) var(--ease-out),
              color var(--t-base) var(--ease-out);
}
@supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
  .masthead {
    background: var(--glass);
    -webkit-backdrop-filter: var(--glass-blur);
    backdrop-filter: var(--glass-blur);
  }
}

.masthead-inner {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  align-items: center;
  gap: var(--s-6);
  min-height: var(--masthead-h);
}

.wordmark {
  grid-column: 2;
  display: block;
  width: clamp(9.5rem, 13vw, 12.5rem);
  color: var(--moss);
  text-decoration: none;
  padding-block: var(--s-3);
  transform-origin: center;
  /* Scaled, not resized: a width change on every scroll frame would force
     the whole masthead to lay out again. */
  transition: transform var(--t-base) var(--ease-out), color var(--t-base) var(--ease-out);
}
.wordmark svg { width: 100%; height: auto; }
.masthead.is-scrolled .wordmark { transform: scale(0.82); }

.nav {
  display: flex;
  align-items: center;
  gap: clamp(1rem, 2.4vw, 2.25rem);
}
.nav-left { grid-column: 1; justify-content: flex-start; }
.nav-right { grid-column: 3; justify-content: flex-end; }

.nav-link {
  position: relative;
  text-decoration: none;
  font-size: 0.6875rem;
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: var(--track-label);
  color: inherit;
  padding-block: var(--s-2);
  white-space: nowrap;
}
.nav-link::after {
  content: '';
  position: absolute;
  left: 0; right: calc(var(--track-label) * 1); bottom: 0.2rem;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--t-base) var(--ease-out);
}
.nav-link:hover::after,
.nav-link[aria-current='page']::after { transform: scaleX(1); }

/* The transparent state, used only while a hero photograph sits beneath. */
.has-hero .masthead:not(.is-scrolled):not(.is-menu-open) {
  background: transparent;
  border-bottom-color: transparent;
  color: var(--white);
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}
.has-hero .masthead:not(.is-scrolled):not(.is-menu-open) .wordmark { color: var(--white); }
.has-hero .masthead:not(.is-scrolled):not(.is-menu-open) .btn-outline {
  --btn-fg: var(--white);
  --btn-edge: rgba(255, 255, 255, 0.6);
}
.has-hero .masthead:not(.is-scrolled):not(.is-menu-open) .btn-outline:hover {
  --btn-bg: var(--white);
  --btn-fg: var(--espresso);
  --btn-edge: var(--white);
}
/* A hero page lets the photograph run up under the masthead. */
.has-hero .masthead { position: fixed; left: 0; right: 0; }

.nav-toggle {
  display: none;
  grid-column: 1;
  justify-self: start;
  width: 2.75rem; height: 2.75rem;
  margin-left: -0.6rem;
  align-items: center;
  justify-content: center;
  background: none;
  border: 0;
  color: inherit;
  cursor: pointer;
}
.nav-toggle svg { width: 1.35rem; height: 1.35rem; }
.masthead .nav-book { display: none; }

/* The mobile menu: a full-height sheet of glass over the page. */
.menu-sheet { display: none; }

@media (max-width: 62rem) {
  .masthead-inner { gap: var(--s-3); --masthead-h: 4.5rem; min-height: 4.5rem; }
  .nav-toggle { display: inline-flex; }
  .nav { display: none; }
  .masthead .nav-book { display: inline-flex; grid-column: 3; justify-self: end; }
  .wordmark { width: 8.75rem; }
  .masthead.is-scrolled .wordmark { transform: scale(0.92); }

  .menu-sheet {
    position: fixed;
    inset: 0;
    z-index: 55;
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding: 6rem var(--gutter) 3rem;
    background: rgba(255, 255, 255, 0.86);
    color: var(--espresso);
    opacity: 0;
    visibility: hidden;
    transition: opacity var(--t-base) var(--ease-out), visibility var(--t-base);
  }
  @supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
    .menu-sheet {
      background: rgba(255, 255, 255, 0.66);
      -webkit-backdrop-filter: saturate(1.4) blur(26px);
      backdrop-filter: saturate(1.4) blur(26px);
    }
  }
  .menu-sheet.is-open { opacity: 1; visibility: visible; }
  .menu-sheet a {
    display: block;
    padding-block: 0.55rem;
    font-family: var(--serif);
    font-size: clamp(2rem, 8vw, 2.75rem);
    font-weight: 300;
    line-height: 1.15;
    text-decoration: none;
    opacity: 0;
    transform: translateY(14px);
    transition: opacity 520ms var(--ease-out), transform 520ms var(--ease-out);
  }
  .menu-sheet.is-open a { opacity: 1; transform: none; }
  .menu-sheet.is-open a:nth-child(2) { transition-delay: 50ms; }
  .menu-sheet.is-open a:nth-child(3) { transition-delay: 100ms; }
  .menu-sheet.is-open a:nth-child(4) { transition-delay: 150ms; }
  .menu-sheet.is-open a:nth-child(5) { transition-delay: 200ms; }
  .menu-sheet a[aria-current='page'] { font-style: italic; }
  .menu-sheet-foot {
    margin-top: var(--s-7);
    padding-top: var(--s-5);
    border-top: 1px solid var(--rule);
  }
  .menu-sheet-foot .spec { display: block; }
  .menu-sheet .menu-sheet-foot a {
    display: inline;
    font-family: var(--sans);
    font-size: var(--step--1);
    font-weight: 350;
    opacity: 1;
    transform: none;
  }
}

/* ---------------------------------------------------------------- footer -
   A quiet band in mist: the wordmark centred, the pages in tracked caps.  */

.colophon {
  background: var(--mist);
  color: var(--ink-2);
  padding-block: clamp(3.5rem, 7vw, 5.5rem) var(--s-6);
  font-size: var(--step--1);
  text-align: center;
}
.colophon a { color: inherit; text-decoration: none; transition: color var(--t-fast) var(--ease-out); }
.colophon a:hover { color: var(--espresso); }
.colophon-mark {
  display: block;
  width: clamp(11rem, 18vw, 14rem);
  margin: 0 auto;
  color: var(--moss);
}
.colophon-mark svg { width: 100%; height: auto; }
.colophon-line {
  margin: var(--s-5) auto 0;
  max-width: 40ch;
  font-family: var(--serif);
  font-size: var(--step-1);
  font-style: italic;
  font-weight: 300;
  color: var(--ink-2);
}
.colophon-nav {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--s-3) clamp(1.25rem, 3vw, 2.5rem);
  margin-top: var(--s-7);
}
.colophon-nav a {
  font-size: 0.6875rem;
  text-transform: uppercase;
  letter-spacing: var(--track-label);
}
.colophon-contact {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--s-2) var(--s-5);
  margin-top: var(--s-5);
}
.colophon-base {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-3) var(--s-5);
  justify-content: space-between;
  margin-top: var(--s-7);
  padding-top: var(--s-5);
  border-top: 1px solid var(--rule);
  font-size: var(--step--2);
  letter-spacing: 0.06em;
  color: var(--ink-3);
}
@media (max-width: 40rem) { .colophon-base { justify-content: center; } }

/* ============================================================== controls ==
   Buttons are squared and lettered in the label voice. Espresso is the one
   solid fill; everything else is outline or glass.
   ======================================================================== */

.btn {
  --btn-bg: var(--espresso);
  --btn-fg: var(--white);
  --btn-edge: var(--espresso);
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.6rem;
  min-height: 2.875rem;
  padding: 0.85rem 1.6rem;
  background: var(--btn-bg);
  color: var(--btn-fg);
  border: 1px solid var(--btn-edge);
  border-radius: 0;
  font-family: var(--sans);
  font-size: 0.6875rem;
  font-weight: 450;
  text-transform: uppercase;
  letter-spacing: 0.2em;
  line-height: 1.2;
  text-decoration: none;
  cursor: pointer;
  overflow: hidden;
  transition: transform var(--t-fast) var(--ease-out),
              background var(--t-base) var(--ease-out),
              color var(--t-base) var(--ease-out),
              border-color var(--t-base) var(--ease-out),
              box-shadow var(--t-base) var(--ease-out);
}
.btn svg { width: 1rem; height: 1rem; flex: none; transition: transform var(--t-base) var(--ease-out); }
.btn:hover { --btn-bg: var(--coffee); --btn-edge: var(--coffee); }
.btn:hover svg { transform: translateX(3px); }
.btn:active { transform: scale(0.98); }

.btn-ghost, .btn-outline {
  --btn-bg: transparent;
  --btn-fg: var(--espresso);
  --btn-edge: var(--petal);
}
.btn-ghost:hover, .btn-outline:hover { --btn-bg: var(--espresso); --btn-fg: var(--white); --btn-edge: var(--espresso); }

.btn-quiet {
  --btn-bg: transparent;
  --btn-fg: var(--ink-2);
  --btn-edge: transparent;
  padding-inline: 0.5rem;
}
.btn-quiet:hover { --btn-bg: transparent; --btn-edge: transparent; --btn-fg: var(--espresso); text-decoration: underline; text-underline-offset: 0.3em; }

.btn-mount {
  --btn-bg: var(--mist);
  --btn-fg: var(--espresso);
  --btn-edge: var(--linen);
}
.btn-mount:hover { --btn-bg: var(--linen); --btn-fg: var(--espresso); --btn-edge: var(--linen); }

/* Over a photograph: frosted glass with white lettering. */
.btn-glass {
  --btn-bg: rgba(255, 255, 255, 0.16);
  --btn-fg: var(--white);
  --btn-edge: rgba(255, 255, 255, 0.5);
  -webkit-backdrop-filter: var(--glass-blur);
  backdrop-filter: var(--glass-blur);
}
.btn-glass:hover { --btn-bg: var(--white); --btn-fg: var(--espresso); --btn-edge: var(--white); }
.btn-light { --btn-bg: var(--white); --btn-fg: var(--espresso); --btn-edge: var(--white); }
.btn-light:hover { --btn-bg: var(--linen); --btn-fg: var(--espresso); --btn-edge: var(--linen); }

.btn-danger { --btn-bg: transparent; --btn-fg: var(--stop); --btn-edge: rgba(138, 74, 54, 0.4); }
.btn-danger:hover { --btn-bg: var(--stop); --btn-fg: #fff; --btn-edge: var(--stop); }

.btn-l { min-height: 3.25rem; padding: 1rem 2.1rem; font-size: 0.71875rem; }
.btn-s { min-height: 2.25rem; padding: 0.55rem 1rem; font-size: 0.625rem; letter-spacing: 0.18em; }
.btn-block { display: flex; width: 100%; }

.btn[disabled], .btn[aria-disabled='true'] {
  opacity: 0.45;
  cursor: not-allowed;
  pointer-events: none;
  box-shadow: none;
}

.btn.is-busy { color: transparent; pointer-events: none; }
.btn.is-busy::after {
  content: '';
  position: absolute;
  inset: 50% auto auto 50%;
  width: 1rem; height: 1rem;
  margin: -0.5rem 0 0 -0.5rem;
  border: 1.5px solid currentColor;
  border-top-color: transparent;
  border-radius: 50%;
  color: var(--btn-fg);
  animation: spin 640ms linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* A text link in the label voice, with a rule that grows on hover. */
.link-arrow {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  text-decoration: none;
  font-size: 0.6875rem;
  font-weight: 450;
  text-transform: uppercase;
  letter-spacing: 0.2em;
  color: var(--espresso);
  padding-bottom: 0.4rem;
  transition: gap var(--t-base) var(--ease-out), color var(--t-fast) var(--ease-out);
}
.link-arrow::after {
  content: '';
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 1px;
  background: var(--petal);
  transform-origin: left;
  transition: background var(--t-base) var(--ease-out);
}
.link-arrow:hover { gap: 0.95rem; color: var(--coffee); }
.link-arrow:hover::after { background: var(--coffee); }
.link-arrow svg { width: 0.95em; height: 0.95em; flex: none; }

/* ------------------------------------------------------------------ tags - */

.tag {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.32rem 0.6rem;
  background: var(--mist);
  color: var(--ink-2);
  font-size: var(--step--2);
  font-weight: 450;
  text-transform: uppercase;
  letter-spacing: 0.18em;
  white-space: nowrap;
}
.tag::before {
  content: '';
  width: 0.4rem; height: 0.4rem;
  background: currentColor;
  flex: none;
}
.tag-plain::before { display: none; }
/* Waiting is the loudest thing on an admin table, so it is drawn in ink:
   a keyline the tinted states never get, and a hollow marker against their
   filled one. Neutral labels sit quietly on mount with no keyline at all. */
.tag-hold {
  background: var(--hold-field);
  color: var(--ink);
  box-shadow: inset 0 0 0 1px var(--hold);
  font-weight: 700;
}
.tag-hold::before { background: transparent; box-shadow: inset 0 0 0 1px currentColor; }
.tag-fix  { background: var(--fix-field);  color: #3b491f; }
.tag-stop { background: var(--stop-field); color: var(--stop); }
.tag-wash { background: var(--wash-field); color: #2f4453; }
.tag-ink  { background: var(--ink); color: #fff; }

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

.field { display: block; }
.field + .field { margin-top: var(--s-5); }

.field-label {
  display: block;
  margin-bottom: var(--s-2);
  font-size: var(--step--2);
  font-weight: 450;
  text-transform: uppercase;
  letter-spacing: 0.18em;
  color: var(--ink-2);
}
.field-hint {
  margin-top: var(--s-2);
  font-size: var(--step--1);
  color: var(--ink-3);
  max-width: 52ch;
}
.field-error {
  margin-top: var(--s-2);
  font-size: var(--step--1);
  color: var(--stop);
  font-weight: 500;
}

.input, .textarea, .select {
  width: 100%;
  padding: 0.72rem 0.9rem;
  background: var(--paper);
  color: var(--ink);
  border: 1px solid var(--rule);
  border-radius: 0;
  font-size: var(--step-0);
  transition: border-color var(--t-fast) var(--ease-out),
              box-shadow var(--t-fast) var(--ease-out),
              background var(--t-fast) var(--ease-out);
}
.input::placeholder, .textarea::placeholder { color: var(--ink-3); opacity: 1; }
.input:hover, .textarea:hover, .select:hover { border-color: var(--petal); }
.input:focus, .textarea:focus, .select:focus {
  outline: none;
  border-color: var(--espresso);
  box-shadow: inset 0 -1px 0 var(--espresso);
}
.textarea { min-height: 8rem; resize: vertical; line-height: 1.55; }

.select {
  appearance: none;
  padding-right: 2.4rem;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8' fill='none' stroke='%23544541' stroke-width='1.4'%3E%3Cpath d='M1 1.5 6 6.5l5-5'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.9rem center;
  background-size: 0.7rem;
}

.field.has-error .input,
.field.has-error .textarea,
.field.has-error .select { border-color: var(--stop); }

.input[aria-invalid='true'] { border-color: var(--stop); }

/* Checkbox / radio drawn as a ruled box, matching the mount language. */
.check {
  display: grid;
  grid-template-columns: 1.15rem 1fr;
  gap: var(--s-3);
  align-items: start;
  cursor: pointer;
  font-size: var(--step--1);
  line-height: 1.5;
}
.check input {
  appearance: none;
  width: 1.15rem; height: 1.15rem;
  margin: 0.16rem 0 0;
  border: 1px solid var(--ink-3);
  background: var(--paper);
  display: grid;
  place-content: center;
  cursor: pointer;
  transition: background var(--t-fast) var(--ease-out), border-color var(--t-fast) var(--ease-out);
}
.check input[type='radio'] { border-radius: 50%; }
.check input::after {
  content: '';
  width: 0.6rem; height: 0.6rem;
  transform: scale(0);
  transition: transform 160ms var(--ease-out);
  background: var(--paper);
  clip-path: polygon(14% 46%, 0 60%, 40% 100%, 100% 22%, 86% 8%, 38% 70%);
}
.check input[type='radio']::after { clip-path: none; border-radius: 50%; width: 0.45rem; height: 0.45rem; }
.check input:checked { background: var(--ink); border-color: var(--ink); }
.check input:checked::after { transform: scale(1); }
.check input:hover { border-color: var(--ink); }

.fieldset { border: 0; padding: 0; margin: 0; }
.fieldset legend { padding: 0; margin-bottom: var(--s-3); }

.field-row {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--s-5);
}
.field-row > .field + .field { margin-top: 0; }
@media (max-width: 40rem) { .field-row { grid-template-columns: minmax(0, 1fr); } }

/* --------------------------------------------------------------- notices - */

.notice {
  display: flex;
  gap: var(--s-3);
  align-items: flex-start;
  padding: var(--s-4) var(--s-5);
  background: var(--mount);
  border-top: 2px solid var(--ink);
  font-size: var(--step--1);
  line-height: 1.5;
}
.notice + .notice { margin-top: var(--s-3); }
.notice svg { width: 1.05rem; height: 1.05rem; flex: none; margin-top: 0.15rem; }
.notice-success { background: var(--fix-field); border-top-color: var(--fix); color: #33401c; }
.notice-error   { background: var(--stop-field); border-top-color: var(--stop); color: #6f2c16; }
.notice-warning { background: var(--hold-field); border-top-color: var(--hold); color: var(--ink); }
.notice-info    { background: var(--wash-field); border-top-color: var(--wash); color: #2b3e4c; }

.flash-stack {
  position: fixed;
  z-index: 120;
  top: 5.25rem;
  right: var(--gutter);
  width: min(24rem, calc(100vw - 2 * var(--gutter)));
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
  pointer-events: none;
}
.flash-stack .notice {
  pointer-events: auto;
  box-shadow: var(--lift-3);
  background: var(--paper);
  animation: flash-in 420ms var(--ease-out) both;
}
.flash-stack .notice-success { background: #f4f7ec; }
.flash-stack .notice-error   { background: #fdf1ec; }
.flash-stack .notice-warning { background: #f2ece1; }
.flash-stack .notice-info    { background: #eef3f6; }
.flash-stack .notice.is-leaving { animation: flash-out 260ms var(--ease-in-out) both; }

@keyframes flash-in {
  from { opacity: 0; transform: translateX(18px) scale(0.98); }
  to   { opacity: 1; transform: none; }
}
@keyframes flash-out {
  to { opacity: 0; transform: translateX(12px); }
}

.flash-close {
  margin-left: auto;
  background: none;
  border: 0;
  padding: 0.1rem 0.25rem;
  cursor: pointer;
  color: inherit;
  opacity: 0.55;
}
.flash-close:hover { opacity: 1; }


/* ================================================================== home ==
   An editorial sequence: a full-bleed photograph with the studio's sentence,
   a quiet statement, an asymmetric spread, the photographer, the process,
   the collections, and a closing photograph with one invitation in glass.
   ======================================================================== */

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

.hero {
  position: relative;
  min-height: 100vh;
  min-height: 100svh;
  display: grid;
  align-items: end;
  overflow: hidden;
  color: var(--white);
  background: var(--espresso);
  isolation: isolate;
}
.hero-media {
  position: absolute;
  inset: 0;
  z-index: -2;
}
.hero-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 35%;
  transform: scale(1.06);
  animation: hero-drift 2600ms var(--ease-soft) both;
}
@keyframes hero-drift {
  from { transform: scale(1.14); opacity: 0; }
  12%  { opacity: 1; }
  to   { transform: scale(1.06); opacity: 1; }
}
/* Legibility: espresso, not black, so the shade belongs to the palette. */
.hero::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background:
    linear-gradient(to bottom, rgba(52, 42, 39, 0.42) 0%, rgba(52, 42, 39, 0) 26%),
    linear-gradient(to top, rgba(52, 42, 39, 0.72) 0%, rgba(52, 42, 39, 0.18) 46%, rgba(52, 42, 39, 0) 70%);
}
.hero-inner {
  padding-top: calc(var(--masthead-h) + 2rem);
  padding-bottom: clamp(3rem, 9vh, 6.5rem);
  text-align: center;
}
.hero-title {
  font-family: var(--serif);
  font-size: clamp(3rem, 8.2vw, 7.25rem);
  font-weight: 300;
  line-height: 0.98;
  letter-spacing: -0.02em;
  text-wrap: balance;
}
.hero-title em { font-style: italic; }
/* Each line lifts out of its own mask: the most visible motion on the site,
   and the only one that runs without being scrolled to. */
.hero-line { display: block; overflow: hidden; padding-bottom: 0.08em; margin-bottom: -0.08em; }
.hero-line > span {
  display: block;
  transform: translateY(105%);
  animation: line-up 1300ms var(--ease-out) both;
}
.hero-line:nth-child(2) > span { animation-delay: 120ms; }
@keyframes line-up { to { transform: none; } }

.hero-sub {
  margin-top: var(--s-5);
  font-size: 0.6875rem;
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: 0.3em;
  color: rgba(255, 255, 255, 0.88);
  animation: fade-up 1100ms var(--ease-out) 420ms both;
}
.hero-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--s-3);
  margin-top: var(--s-6);
  animation: fade-up 1100ms var(--ease-out) 560ms both;
}
@keyframes fade-up {
  from { opacity: 0; transform: translateY(16px); }
  to   { opacity: 1; transform: none; }
}
@media (max-width: 34rem) {
  .hero-actions { display: grid; grid-template-columns: minmax(0, 1fr); width: 100%; max-width: 20rem; margin-inline: auto; }
}

.hero-cue {
  position: absolute;
  left: 50%;
  bottom: 1.25rem;
  width: 1px;
  height: 2.5rem;
  background: rgba(255, 255, 255, 0.35);
  overflow: hidden;
  transform: translateX(-50%);
}
.hero-cue::after {
  content: '';
  position: absolute;
  inset: 0;
  background: var(--white);
  transform: translateY(-100%);
  animation: cue 2400ms var(--ease-in-out) 1600ms 3 both;
}
@keyframes cue {
  0%   { transform: translateY(-100%); }
  55%  { transform: translateY(0); }
  100% { transform: translateY(100%); }
}
@media (max-height: 40rem) { .hero-cue { display: none; } }

/* --- statement ----------------------------------------------------------- */

.statement {
  max-width: 46rem;
  margin-inline: auto;
  text-align: center;
}
.statement-mark { display: block; width: 2.5rem; margin: 0 auto var(--s-6); color: var(--petal); }
.statement-mark svg { width: 100%; height: auto; }
.statement-text {
  font-family: var(--serif);
  font-size: clamp(1.625rem, 1.2rem + 1.9vw, 2.625rem);
  font-weight: 300;
  line-height: 1.32;
  color: var(--espresso);
}
.statement-text em { font-style: italic; color: var(--coffee); }
.statement .spec { margin-top: var(--s-6); }

/* --- spread: an asymmetric editorial layout of five photographs ----------- */

.spread {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: clamp(0.75rem, 1.8vw, 1.5rem);
  align-items: start;
}
.spread-item { display: block; text-decoration: none; color: inherit; }
.spread-item .frame img { transition: transform 1400ms var(--ease-out); }
.spread-item:hover .frame img { transform: scale(1.045); }
.spread-item figcaption {
  display: flex;
  justify-content: space-between;
  gap: var(--s-3);
  margin-top: var(--s-3);
}
.spread > :nth-child(1) { grid-column: 1 / span 5; }
.spread > :nth-child(1) .frame { aspect-ratio: 4 / 5; }
.spread > :nth-child(2) { grid-column: 7 / span 6; margin-top: 18%; }
.spread > :nth-child(2) .frame { aspect-ratio: 4 / 3; }
.spread > :nth-child(3) { grid-column: 2 / span 4; margin-top: -2%; }
.spread > :nth-child(3) .frame { aspect-ratio: 1 / 1; }
.spread > :nth-child(4) { grid-column: 7 / span 3; margin-top: 6%; }
.spread > :nth-child(4) .frame { aspect-ratio: 3 / 4; }
.spread > :nth-child(5) { grid-column: 10 / span 3; margin-top: 22%; }
.spread > :nth-child(5) .frame { aspect-ratio: 3 / 4; }
@media (max-width: 47.9375rem) {
  .spread { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .spread > * { grid-column: auto !important; margin-top: 0 !important; }
  .spread > :nth-child(1) { grid-column: 1 / -1 !important; }
  .spread > :nth-child(2) .frame { aspect-ratio: 3 / 4; }
  .spread > :nth-child(5) { display: none; }
}

/* --- the photographer, in the reference set's portrait-left layout -------- */

.portrait-split {
  display: grid;
  grid-template-columns: minmax(0, 0.9fr) minmax(0, 1fr);
  gap: clamp(2rem, 7vw, 7rem);
  align-items: center;
}
.portrait-split .frame { aspect-ratio: 4 / 5; }
.portrait-copy { max-width: 32rem; }
.portrait-copy .prose { color: var(--ink-2); margin-top: var(--s-2); }
.portrait-copy .link-arrow { margin-top: var(--s-6); }
@media (max-width: 56rem) {
  .portrait-split { grid-template-columns: minmax(0, 1fr); }
  .portrait-split .frame { aspect-ratio: 4 / 3; }
}

/* --- process: five steps, numbered because the order is the information --- */

.stages {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: clamp(1rem, 2.4vw, 2rem);
  border-top: 0;
}
.stage { padding: 0; border: 0; position: relative; }
.stage-mark {
  display: block;
  font-family: var(--serif);
  font-size: var(--step-3);
  font-weight: 300;
  font-style: italic;
  line-height: 1;
  color: var(--petal);
  padding-bottom: var(--s-4);
  margin-bottom: var(--s-4);
  border-bottom: 1px solid var(--rule);
}
.stage h3 { font-size: var(--step-1); font-weight: 500; margin-bottom: var(--s-2); }
.stage p { font-size: var(--step--1); color: var(--ink-2); max-width: 26ch; }
@media (max-width: 62rem) {
  .stages { grid-template-columns: repeat(2, minmax(0, 1fr)); row-gap: var(--s-7); }
}
@media (max-width: 34rem) { .stages { grid-template-columns: minmax(0, 1fr); } }

/* --- collections: portrait cards with a glass caption over the photograph - */

.plate-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(18rem, 100%), 1fr));
  gap: clamp(1rem, 2.4vw, 2rem);
}
.plate {
  position: relative;
  display: block;
  text-decoration: none;
  color: inherit;
}
.plate .frame { aspect-ratio: 3 / 4; }
.plate img { transition: transform 1400ms var(--ease-out); }
.plate:hover img { transform: scale(1.05); }
.plate-meta {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s-3);
  padding-top: var(--s-4);
}
.plate-name { font-family: var(--serif); font-size: var(--step-2); font-weight: 400; line-height: 1.1; }

/* Glass caption variant, used where a card sits on the photograph itself. */
.plate-glass .plate-meta {
  position: absolute;
  left: var(--s-3); right: var(--s-3); bottom: var(--s-3);
  padding: var(--s-3) var(--s-4);
  background: var(--glass);
  border: 1px solid var(--glass-edge);
  color: var(--espresso);
  transition: transform var(--t-base) var(--ease-out), background var(--t-base) var(--ease-out);
}
@supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
  .plate-glass .plate-meta {
    background: rgba(255, 255, 255, 0.58);
    -webkit-backdrop-filter: var(--glass-blur);
    backdrop-filter: var(--glass-blur);
  }
}
.plate-glass:hover .plate-meta { transform: translateY(-4px); background: rgba(255, 255, 255, 0.74); }
.plate-glass .plate-meta .spec { color: var(--ink-2); }

/* --- closing invitation: a photograph with one glass panel on it ---------- */

.invite {
  position: relative;
  display: grid;
  place-items: center;
  min-height: clamp(32rem, 82vh, 46rem);
  padding: clamp(3rem, 8vw, 6rem) var(--gutter);
  overflow: hidden;
  isolation: isolate;
  background: var(--espresso);
}
.invite-media { position: absolute; inset: 0; z-index: -2; }
.invite-media img { width: 100%; height: 100%; object-fit: cover; }
.invite::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: rgba(52, 42, 39, 0.26);
}
.glass-panel {
  width: min(36rem, 100%);
  padding: clamp(2rem, 5vw, 3.5rem);
  text-align: center;
  color: var(--espresso);
  background: var(--glass-strong);
  border: 1px solid var(--glass-edge);
  box-shadow: 0 30px 80px rgba(52, 42, 39, 0.22);
}
@supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
  .glass-panel {
    background: rgba(255, 255, 255, 0.6);
    -webkit-backdrop-filter: saturate(1.4) blur(24px);
    backdrop-filter: saturate(1.4) blur(24px);
  }
}
.glass-panel .lede { margin: var(--s-4) auto 0; color: var(--ink-2); }
.glass-panel .row { justify-content: center; margin-top: var(--s-6); flex-wrap: wrap; gap: var(--s-3); }
@media (max-width: 34rem) {
  .glass-panel .row { display: grid; grid-template-columns: minmax(0, 1fr); }
}

/* ============================================================ page heads ==
   Every inner page opens the same way: a centred serif title, a short
   hairline, and at most one sentence. No kicker above the title.
   ======================================================================== */

.page-head {
  padding-top: clamp(3.5rem, 8vw, 6.5rem);
  padding-bottom: clamp(2.5rem, 5vw, 4rem);
  text-align: center;
}
.page-head h1 { font-size: var(--step-4); font-weight: 300; }
.page-head .hairline { margin-inline: auto; }
.page-head .lede { margin-inline: auto; text-align: center; }

/* A full-width photograph under the head of an inner page. */
.page-banner .frame { aspect-ratio: 21 / 8; }
@media (max-width: 48rem) { .page-banner .frame { aspect-ratio: 4 / 3; } }

/* Questions: a list of quiet rows rather than a grid of cards. */
.faq { border-top: 1px solid var(--rule); }
.faq-item { padding: var(--s-5) 0; border-bottom: 1px solid var(--rule); display: grid; grid-template-columns: minmax(0, 0.8fr) minmax(0, 1.2fr); gap: var(--s-5); }
.faq-item h3 { font-size: var(--step-2); font-weight: 400; }
.faq-item p { color: var(--ink-2); max-width: 52ch; }
@media (max-width: 48rem) { .faq-item { grid-template-columns: minmax(0, 1fr); gap: var(--s-2); } }


/* Two-column editorial passage: a sentence beside a photograph. */
.passage {
  display: grid;
  grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr);
  gap: clamp(2rem, 6vw, 6rem);
  align-items: start;
}
@media (max-width: 62rem) { .passage { grid-template-columns: minmax(0, 1fr); } }
.passage-sticky { position: sticky; top: calc(var(--masthead-h) + 2rem); }
@media (max-width: 62rem) { .passage-sticky { position: static; } }

/* ============================================================ price list ==
   The offer reads as a printed rate card: ruled rows, figures in the
   right-hand column, no matching cards.
   ======================================================================== */

.ratecard { border-top: 1px solid var(--rule); }

.rate {
  display: grid;
  grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr) auto;
  gap: var(--s-5);
  align-items: start;
  padding: var(--s-6) 0;
  border-bottom: 1px solid var(--rule);
  transition: background var(--t-base) var(--ease-out);
}
.rate:hover { background: var(--mount); }
.rate-title { display: flex; flex-direction: column; gap: var(--s-2); }
.rate-name { font-size: var(--step-2); font-variation-settings: 'wdth' 104; letter-spacing: -0.026em; }
.rate-spec { display: flex; flex-wrap: wrap; gap: var(--s-2) var(--s-4); }
.rate-includes { font-size: var(--step--1); color: var(--ink-2); }
.rate-includes li { position: relative; padding-left: 1rem; }
.rate-includes li + li { margin-top: 0.3rem; }
.rate-includes li::before {
  content: '';
  position: absolute;
  left: 0; top: 0.62em;
  width: 0.45rem; height: 1px;
  background: var(--kraft-deep);
}
.rate-figure { text-align: right; min-width: 9rem; }
.rate-amount {
  font-family: var(--serif);
  font-size: var(--step-3);
  font-weight: 400;
  letter-spacing: 0;
  font-variant-numeric: lining-nums tabular-nums;
  display: block;
}
.rate-figure form { margin-top: var(--s-4); }
@media (max-width: 56rem) {
  .rate { grid-template-columns: minmax(0, 1fr); gap: var(--s-4); }
  .rate-figure { text-align: left; }
  .rate-figure form { margin-top: var(--s-3); }
}

.placeholder-price {
  display: inline-block;
  margin-top: var(--s-1);
  font-size: var(--step--2);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--ink-3);
}

/* ============================================================== stepper == */

.stepper {
  display: flex;
  flex-wrap: wrap;
  gap: 0;
  border-block: 1px solid var(--rule);
  margin-bottom: var(--s-7);
}
.step-item {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  padding: var(--s-3) var(--s-4) var(--s-3) 0;
  margin-right: var(--s-4);
  font-size: var(--step--2);
  font-weight: 450;
  text-transform: uppercase;
  letter-spacing: 0.18em;
  color: var(--ink-3);
  text-decoration: none;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  transition: color var(--t-fast) var(--ease-out), border-color var(--t-fast) var(--ease-out);
}
.step-item .step-dot {
  width: 0.5rem; height: 0.5rem;
  border: 1px solid currentColor;
  flex: none;
}
.step-item.is-done { color: var(--ink-2); }
.step-item.is-done .step-dot { background: var(--ink-2); }
.step-item.is-current { color: var(--ink); border-bottom-color: var(--ink); }
.step-item.is-current .step-dot { background: var(--ink); }
a.step-item:hover { color: var(--ink); }

/* ============================================================= calendar == */

.calendar {
  border: 1px solid var(--rule);
  background: var(--paper);
}
.calendar-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-3);
  padding: var(--s-4);
  border-bottom: 1px solid var(--rule);
}
.calendar-month {
  font-family: var(--serif);
  font-size: var(--step-1);
  letter-spacing: -0.02em;
  font-weight: 500;
}
.calendar-nav { display: flex; gap: var(--s-2); }
.calendar-nav button, .calendar-nav a {
  width: 2.25rem; height: 2.25rem;
  display: grid; place-content: center;
  border: 1px solid var(--rule);
  background: var(--paper);
  cursor: pointer;
  text-decoration: none;
  transition: border-color var(--t-fast) var(--ease-out), background var(--t-fast) var(--ease-out);
}
.calendar-nav button:hover, .calendar-nav a:hover { border-color: var(--ink); background: var(--mount); }
.calendar-nav [aria-disabled='true'] { opacity: 0.3; pointer-events: none; }

.calendar-weekdays {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  border-bottom: 1px solid var(--rule-soft);
}
.calendar-weekdays span {
  padding: var(--s-2) var(--s-1);
  text-align: center;
  font-size: var(--step--2);
  font-weight: 450;
  text-transform: uppercase;
  letter-spacing: 0.18em;
  color: var(--ink-3);
}

.calendar-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 1px;
  background: var(--rule-soft);
}
.day {
  position: relative;
  min-height: 3.6rem;
  background: var(--paper);
  border: 0;
  padding: var(--s-2);
  text-align: left;
  font: inherit;
  color: var(--ink-3);
  cursor: default;
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  transition: background var(--t-fast) var(--ease-out), color var(--t-fast) var(--ease-out);
}
.day-num { font-size: var(--step--1); font-variant-numeric: tabular-nums; }
.day-count {
  font-size: var(--step--2);
  text-transform: uppercase;
  letter-spacing: 0.08em;
}
.day-empty { background: var(--mount); }
.day.is-open { color: var(--ink); cursor: pointer; }
.day.is-open .day-count { color: var(--ink-2); }
.day.is-open::after {
  content: '';
  position: absolute;
  left: var(--s-2); right: var(--s-2); bottom: var(--s-2);
  height: 2px;
  background: var(--ink);
  transform: scaleX(0.25);
  transform-origin: left;
  transition: transform var(--t-base) var(--ease-out);
}
.day.is-open:hover { background: var(--mount); }
.day.is-open:hover::after { transform: scaleX(1); }
.day.is-selected { background: var(--ink); color: var(--paper); }
.day.is-selected .day-count { color: rgba(255,255,255,0.72); }
.day.is-selected::after { background: var(--paper); transform: scaleX(1); }
.day.is-past { color: #b6afa2; }

@media (max-width: 40rem) { .day { min-height: 3rem; padding: var(--s-1); } }

.timeslots { display: flex; flex-wrap: wrap; gap: var(--s-2); }
.timeslot {
  padding: 0.6rem 0.95rem;
  border: 1px solid var(--rule);
  background: var(--paper);
  font-size: var(--step--1);
  font-variant-numeric: tabular-nums;
  cursor: pointer;
  transition: all var(--t-fast) var(--ease-out);
}
.timeslot:hover { border-color: var(--ink); background: var(--mount); }
.timeslot.is-chosen { background: var(--ink); color: var(--paper); border-color: var(--ink); }

.slot-panel {
  border: 1px solid var(--rule);
  padding: var(--s-5);
  background: var(--paper);
  min-height: 12rem;
}
.slot-panel.is-loading { opacity: 0.5; transition: opacity var(--t-fast) linear; }

/* =============================================================== gallery == */

.plate-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(19rem, 100%), 1fr));
  gap: clamp(1rem, 2.5vw, 2.25rem);
}

.plate {
  display: block;
  text-decoration: none;
  position: relative;
}
.plate .frame { aspect-ratio: 3 / 4; }
.plate img { transition: transform 1000ms var(--ease-out), filter 700ms var(--ease-out); }
.plate:hover img { transform: scale(1.035); }
.plate-meta {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s-3);
  padding-top: var(--s-3);
  margin-top: var(--s-3);
  border-top: 1px solid var(--rule);
}
.plate-name { font-size: var(--step-1); font-weight: 500; letter-spacing: -0.018em; }
.plate:hover .plate-meta { border-top-color: var(--ink); }
.plate-meta { transition: border-color var(--t-base) var(--ease-out); }

/* Mixed-rhythm collection wall: not every print the same size. */
.wall {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: clamp(0.75rem, 2vw, 1.75rem);
}
.wall > * { grid-column: span 4; }
.wall > .w-wide { grid-column: span 8; }
.wall > .w-full { grid-column: span 12; }
.wall > .w-half { grid-column: span 6; }
@media (max-width: 62rem) {
  .wall > * { grid-column: span 6; }
  .wall > .w-wide, .wall > .w-full { grid-column: span 12; }
}
@media (max-width: 40rem) { .wall > * { grid-column: span 12 !important; } }

.filter-bar {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--s-3) clamp(1.25rem, 3vw, 2.5rem);
  padding-bottom: var(--s-5);
  margin-bottom: var(--s-7);
}
.filter-chip {
  position: relative;
  padding-block: var(--s-2);
  font-size: 0.6875rem;
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: var(--track-label);
  color: var(--ink-3);
  text-decoration: none;
  transition: color var(--t-fast) var(--ease-out);
}
.filter-chip::after {
  content: '';
  position: absolute;
  left: 0; right: var(--track-label); bottom: 0.15rem;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--t-base) var(--ease-out);
}
.filter-chip:hover { color: var(--espresso); }
.filter-chip:hover::after { transform: scaleX(1); }
.filter-chip[aria-current='true'] { color: var(--espresso); }
.filter-chip[aria-current='true']::after { transform: scaleX(1); }

/* Lightbox — the loupe over a sheet. */
.loupe {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: grid;
  place-items: center;
  padding: clamp(1rem, 4vw, 3rem);
  background: rgba(255, 255, 255, 0.97);
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--t-base) var(--ease-out), visibility var(--t-base);
}
@supports (backdrop-filter: blur(1px)) {
  .loupe { background: rgba(255, 255, 255, 0.9); backdrop-filter: blur(18px) saturate(1.2); }
}
.loupe.is-open { opacity: 1; visibility: visible; }
.loupe-figure {
  max-width: min(72rem, 100%);
  max-height: 100%;
  display: flex;
  flex-direction: column;
  gap: var(--s-3);
  transform: scale(0.97);
  transition: transform var(--t-base) var(--ease-out);
}
.loupe.is-open .loupe-figure { transform: none; }
.loupe-figure img {
  max-height: calc(100vh - 12rem);
  width: auto;
  margin-inline: auto;
  border: 0;
  background: var(--mist);
  box-shadow: var(--lift-3);
}
.loupe-bar { display: flex; align-items: center; justify-content: space-between; gap: var(--s-4); }
.loupe-close, .loupe-prev, .loupe-next {
  width: 2.75rem; height: 2.75rem;
  display: grid; place-content: center;
  background: var(--glass);
  border: 1px solid var(--rule);
  -webkit-backdrop-filter: var(--glass-blur);
  backdrop-filter: var(--glass-blur);
  cursor: pointer;
  transition: border-color var(--t-fast) var(--ease-out), background var(--t-fast) var(--ease-out);
}
.loupe-close:hover, .loupe-prev:hover, .loupe-next:hover { border-color: var(--ink); background: var(--mount); }
.loupe-close { position: absolute; top: var(--gutter); right: var(--gutter); }
.loupe-nav { display: flex; gap: var(--s-2); }

/* ================================================== client & admin shell == */

.console {
  display: grid;
  grid-template-columns: 16.5rem minmax(0, 1fr);
  min-height: 100vh;
  min-height: 100svh;
}
@media (max-width: 62rem) { .console { grid-template-columns: minmax(0, 1fr); } }

.console-rail {
  background: var(--mist);
  border-right: 1px solid var(--rule);
  padding: var(--s-5) var(--s-4);
  display: flex;
  flex-direction: column;
  gap: var(--s-6);
  position: sticky;
  top: 0;
  height: 100vh;
  height: 100svh;
  overflow-y: auto;
}
@media (max-width: 62rem) {
  .console-rail {
    position: static;
    height: auto;
    border-right: 0;
    border-bottom: 1px solid var(--rule);
    flex-direction: row;
    align-items: center;
    gap: var(--s-4);
    overflow-x: auto;
  }
  .console-rail .rail-foot { margin-left: auto; }
}

.rail-nav { display: flex; flex-direction: column; gap: 1px; }
@media (max-width: 62rem) { .rail-nav { flex-direction: row; gap: var(--s-1); } }

.rail-link {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--s-3);
  padding: 0.6rem 0.75rem;
  text-decoration: none;
  font-size: var(--step--1);
  font-weight: 500;
  color: var(--ink-2);
  white-space: nowrap;
  overflow: hidden;
  transition: background var(--t-fast) var(--ease-out),
              color var(--t-fast) var(--ease-out);
}
/* Same active mark as the site nav: a hairline that grows from the leading
   edge, never a coloured slab down the side of a list item. */
.rail-link::before {
  content: '';
  position: absolute;
  inset: 0 auto 0 0;
  width: 1px;
  background: var(--ink);
  transform: scaleY(0);
  transform-origin: top;
  transition: transform var(--t-base) var(--ease-out);
}
.rail-link svg { width: 1.05rem; height: 1.05rem; flex: none; opacity: 0.72; }
.rail-link:hover { background: var(--mount-deep); color: var(--ink); }
.rail-link[aria-current='page'] {
  background: var(--paper);
  color: var(--ink);
  font-weight: 600;
}
.rail-link[aria-current='page']::before { transform: scaleY(1); }
.rail-link[aria-current='page'] svg { opacity: 1; }
@media (max-width: 62rem) {
  .rail-link::before {
    inset: auto 0 0 0;
    width: auto;
    height: 1px;
    transform: scaleX(0);
    transform-origin: left;
  }
  .rail-link[aria-current='page']::before { transform: scaleX(1); }
}

.rail-count {
  margin-left: auto;
  min-width: 1.35rem;
  padding: 0 0.3rem;
  text-align: center;
  background: var(--ink);
  color: var(--paper);
  font-size: 0.625rem;
  font-weight: 700;
  line-height: 1.35rem;
  font-variant-numeric: tabular-nums;
}

.console-main { padding: clamp(1.5rem, 3vw, 2.75rem) var(--gutter) var(--s-9); min-width: 0; }

.console-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--s-4);
  padding-bottom: var(--s-4);
  margin-bottom: var(--s-6);
  border-bottom: 1px solid var(--rule);
}

/* --------------------------------------------------------------- panels -- */

.panel {
  border: 1px solid var(--rule);
  background: var(--paper);
}
.panel-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s-3);
  padding: var(--s-4) var(--s-5);
  border-bottom: 1px solid var(--rule);
  background: var(--mount);
}
.panel-body { padding: var(--s-5); }
.panel-body-flush { padding: 0; }
.panel-foot {
  padding: var(--s-4) var(--s-5);
  border-top: 1px solid var(--rule);
  background: var(--mount);
}

.readout {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  border: 1px solid var(--rule);
  background: var(--rule);
  gap: 1px;
}
.readout > div { background: var(--paper); padding: var(--s-4) var(--s-5); }
.readout-value {
  font-family: var(--serif);
  display: block;
  font-size: var(--step-2);
  font-weight: 500;
  letter-spacing: -0.024em;
  font-variant-numeric: tabular-nums;
  margin-top: var(--s-1);
}

/* ---------------------------------------------------------------- table -- */

.table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }

.table { width: 100%; border-collapse: collapse; font-size: var(--step--1); }
.table th, .table td {
  padding: 0.72rem 0.9rem;
  text-align: left;
  vertical-align: middle;
  border-bottom: 1px solid var(--rule-soft);
}
.table th {
  font-size: var(--step--2);
  font-weight: 450;
  text-transform: uppercase;
  letter-spacing: 0.18em;
  color: var(--ink-3);
  border-bottom-color: var(--rule);
  white-space: nowrap;
  background: var(--paper);
  position: sticky;
  top: 0;
  z-index: 1;
}
.table tbody tr { transition: background var(--t-fast) var(--ease-out); }
.table tbody tr:hover { background: var(--mount); }
.table td.num { text-align: right; font-variant-numeric: tabular-nums; }
.table a { text-decoration: none; font-weight: 500; }
.table a:hover { text-decoration: underline; text-underline-offset: 0.2em; }
.table-compact th, .table-compact td { padding: 0.5rem 0.7rem; }

/* --------------------------------------------------------------- record -- */

.record { display: grid; gap: 0; border-top: 1px solid var(--rule); }
.record > div {
  display: grid;
  grid-template-columns: 10rem minmax(0, 1fr);
  gap: var(--s-4);
  padding: 0.7rem 0;
  border-bottom: 1px solid var(--rule-soft);
}
.record dt {
  font-size: var(--step--2);
  font-weight: 450;
  text-transform: uppercase;
  letter-spacing: 0.18em;
  color: var(--ink-3);
  padding-top: 0.15em;
}
.record dd { margin: 0; font-size: var(--step--1); }
@media (max-width: 40rem) {
  .record > div { grid-template-columns: minmax(0, 1fr); gap: var(--s-1); }
}

/* ---------------------------------------------------------- empty state -- */

.empty {
  padding: clamp(2.5rem, 6vw, 4.5rem) var(--s-5);
  text-align: center;
  border: 1px dashed var(--rule);
  background: var(--mount);
}
.empty-mark {
  width: 3.5rem; height: 3.5rem;
  margin: 0 auto var(--s-4);
  border: 1px solid var(--kraft-deep);
  display: grid;
  place-content: center;
  color: var(--kraft-deep);
}
.empty-mark svg { width: 1.5rem; height: 1.5rem; }
.empty h3 { font-size: var(--step-1); margin-bottom: var(--s-2); }
.empty p { color: var(--ink-2); font-size: var(--step--1); max-width: 40ch; margin-inline: auto; }
.empty .btn { margin-top: var(--s-5); }

/* --------------------------------------------------------------- tracker -
   A booking's progress reads as the wet-print sequence it actually is. */

.tracker { display: flex; border: 1px solid var(--rule); overflow: hidden; }
.tracker-step {
  flex: 1;
  padding: var(--s-3) var(--s-4);
  border-right: 1px solid var(--rule);
  background: var(--paper);
  min-width: 0;
}
.tracker-step:last-child { border-right: 0; }
.tracker-step .spec { color: var(--ink-3); }
.tracker-step.is-done { background: var(--mount); }
.tracker-step.is-done .spec { color: var(--ink-2); }
.tracker-step.is-current { background: var(--ink); }
.tracker-step.is-current .spec { color: rgba(255, 255, 255, 0.62); }
.tracker-step.is-current .tracker-name { color: var(--paper); }
.tracker-name { display: block; font-size: var(--step--1); font-weight: 600; margin-top: 0.2rem; }
@media (max-width: 48rem) {
  .tracker { flex-direction: column; }
  .tracker-step { border-right: 0; border-bottom: 1px solid var(--rule); }
  .tracker-step:last-child { border-bottom: 0; }
}

/* ------------------------------------------------------------- file grid - */

.filegrid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(11rem, 100%), 1fr));
  gap: var(--s-4);
}
.filecell { border: 1px solid var(--rule); background: var(--paper); }
.filecell .frame { aspect-ratio: 1 / 1; background: var(--mount); }
.filecell-body {
  padding: var(--s-3);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-2);
  border-top: 1px solid var(--rule-soft);
}
.filecell-name {
  font-size: var(--step--2);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}
.filecell-doc {
  display: grid;
  place-content: center;
  aspect-ratio: 1 / 1;
  background: var(--mount);
  color: var(--kraft-deep);
}
.filecell-doc svg { width: 2rem; height: 2rem; }

/* -------------------------------------------------------------- contract - */

.document {
  background: var(--paper);
  border: 1px solid var(--rule);
  padding: clamp(1.5rem, 4vw, 3.5rem);
  max-width: 46rem;
}
.document p { font-size: var(--step-0); line-height: 1.7; max-width: 68ch; }
.document p + p { margin-top: 1em; }
.contract-heading {
  font-size: var(--step-1);
  letter-spacing: -0.02em;
  margin-top: 1.8em;
  margin-bottom: 0.5em;
  padding-bottom: 0.35em;
  border-bottom: 1px solid var(--rule);
}
.contract-heading:first-child { margin-top: 0; }
.contract-list { margin: 1em 0; padding-left: 1.2rem; list-style: none; }
.contract-list li { position: relative; padding-left: 0.9rem; font-size: var(--step-0); line-height: 1.65; }
.contract-list li + li { margin-top: 0.4em; }
.contract-list li::before {
  content: '';
  position: absolute; left: 0; top: 0.78em;
  width: 0.45rem; height: 1px; background: var(--kraft-deep);
}

.signature-block {
  margin-top: var(--s-7);
  padding-top: var(--s-5);
  border-top: 2px solid var(--ink);
}
.signature-line {
  font-family: var(--serif);
  font-style: italic;
  font-size: var(--step-3);
  letter-spacing: -0.01em;
  padding-bottom: var(--s-2);
  border-bottom: 1px solid var(--ink);
  display: inline-block;
  min-width: 16rem;
}

/* ---------------------------------------------------------------- misc --- */

.dropzone {
  border: 1px dashed var(--kraft-deep);
  background: var(--mount);
  padding: clamp(1.5rem, 4vw, 3rem);
  text-align: center;
  transition: background var(--t-fast) var(--ease-out), border-color var(--t-fast) var(--ease-out);
}
.dropzone.is-over { background: var(--mount-deep); border-color: var(--ink); }
.dropzone input[type='file'] { display: block; width: 100%; margin: var(--s-4) auto 0; max-width: min(24rem, 100%); }

.progress {
  height: 2px;
  background: var(--rule);
  overflow: hidden;
}
/* Scales rather than resizes, so the bar never triggers layout. */
.progress span {
  display: block;
  height: 100%;
  width: 100%;
  background: var(--ink);
  transform-origin: left;
  transform: scaleX(0);
  transition: transform var(--t-base) var(--ease-out);
}

.pagination { display: flex; gap: var(--s-2); align-items: center; justify-content: center; margin-top: var(--s-6); }

.chip-row { display: flex; flex-wrap: wrap; gap: var(--s-2); }

.detail-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr);
  gap: var(--s-6);
  align-items: start;
}
@media (max-width: 68rem) { .detail-grid { grid-template-columns: minmax(0, 1fr); } }

/* --------------------------------------------------------------- errors -- */

.error-page {
  min-height: 70vh;
  display: grid;
  place-content: center;
  text-align: center;
  padding: var(--s-8) var(--gutter);
}
.error-code {
  font-family: var(--serif);
  font-size: clamp(5rem, 18vw, 11rem);
  font-weight: 300;
  line-height: 0.85;
  letter-spacing: -0.02em;
  color: var(--petal);
}
.error-page h1 { font-size: var(--step-3); margin: var(--s-4) 0 var(--s-3); }
.error-page p { color: var(--ink-2); max-width: 44ch; margin-inline: auto; }

/* ---------------------------------------------------------------- print -- */

@media print {
  body { background: #fff; color: #000; font-size: 11pt; }
  .masthead, .colophon, .console-rail, .flash-stack, .no-print { display: none !important; }
  .console { display: block; }
  .console-main { padding: 0; }
  .document, .panel { border: 0; padding: 0; }
  a[href]::after { content: ''; }
  .develop img, .rise { opacity: 1 !important; filter: none !important; transform: none !important; }
}

/* -------------------------------------------------------- reduced motion - */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
  .develop img, .develop > .develop-target { opacity: 1; filter: none; transform: none; }
  .rise { opacity: 1; transform: none; }
}

/* ========================================================= promo + category ==
   Added Aug 2026 with promo codes, managed categories and gallery management.
   Everything here is built from the existing tokens: mount fields, hairline
   rules, ink for anything that carries weight.
   ========================================================================== */

/* A code is read aloud and typed in, so it is set in the widest, most
   unambiguous letterforms the family offers, with generous tracking. */
.input-code {
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}
.input-code::placeholder {
  letter-spacing: 0.06em;
  text-transform: none;
  font-weight: 400;
}

.promo-entry {
  display: flex;
  gap: var(--s-3);
  align-items: flex-start;
}
.promo-entry.has-error .input { border-color: var(--stop); }
@media (max-width: 34rem) {
  .promo-entry { flex-direction: column; }
  .promo-entry .btn { width: 100%; }
}

.promo-applied {
  display: flex;
  align-items: center;
  gap: var(--s-4);
  padding: var(--s-4);
  background: var(--fix-field);
  border-top: 2px solid var(--fix);
}
.promo-mark {
  display: grid;
  place-content: center;
  width: 2.25rem;
  height: 2.25rem;
  flex: none;
  color: var(--fix);
  border: 1px solid currentColor;
}
.promo-mark svg { width: 1.1rem; height: 1.1rem; }
.promo-line { color: var(--fix); font-weight: 600; }

/* A two-state control reads better as one object than as two loose radios. */
.segmented {
  display: inline-flex;
  border: 1px solid var(--rule);
  background: var(--paper);
  overflow: hidden;
}
.segment { position: relative; }
.segment input {
  position: absolute;
  inset: 0;
  opacity: 0;
  cursor: pointer;
  margin: 0;
}
.segment span {
  display: block;
  padding: 0.55rem 0.95rem;
  font-size: var(--step--2);
  font-weight: 450;
  text-transform: uppercase;
  letter-spacing: 0.18em;
  color: var(--ink-3);
  white-space: nowrap;
  transition: background var(--t-fast) var(--ease-out), color var(--t-fast) var(--ease-out);
}
.segment + .segment span { border-left: 1px solid var(--rule); }
.segment input:hover + span { background: var(--mount); color: var(--ink); }
.segment input:checked + span { background: var(--ink); color: var(--paper); }
.segment input:focus-visible + span { outline: 2px solid var(--ink); outline-offset: 2px; }

.category-rows { display: flex; flex-direction: column; gap: 1px; background: var(--rule-soft); }
.category-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr) 6rem auto auto;
  gap: var(--s-3);
  align-items: center;
  padding: var(--s-3) 0;
  background: var(--paper);
}
.category-row .field + .field { margin-top: 0; }
.category-order { max-width: 6rem; }
.category-live { justify-self: center; }
.category-actions { display: flex; align-items: center; gap: var(--s-2); justify-self: end; }
@media (max-width: 62rem) {
  .category-row { grid-template-columns: minmax(0, 1fr) 5rem auto; }
  .category-row .field:nth-child(3) { grid-column: 1 / -1; }
  .category-actions { grid-column: 1 / -1; justify-self: start; }
}

/* ============================================== gallery management (admin) == */

.collection-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(17rem, 100%), 1fr));
  gap: var(--s-5);
}
.collection-card {
  display: block;
  border: 1px solid var(--rule);
  background: var(--paper);
  text-decoration: none;
  transition: border-color var(--t-fast) var(--ease-out), box-shadow var(--t-base) var(--ease-out);
}
.collection-card:hover { border-color: var(--ink); box-shadow: var(--lift-2); }
.collection-card .frame { background: var(--mount); }
.collection-card img { transition: transform 700ms var(--ease-out); }
.collection-card:hover img { transform: scale(1.03); }
.collection-body {
  display: block;
  padding: var(--s-4);
  border-top: 1px solid var(--rule-soft);
}
.collection-body .spec { display: block; margin-top: var(--s-2); }
.collection-empty {
  display: grid;
  place-content: center;
  width: 100%;
  height: 100%;
  color: var(--kraft-deep);
}
.collection-empty svg { width: 2rem; height: 2rem; }

.photo-order { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 1px; background: var(--rule-soft); }

.photo-item {
  display: grid;
  grid-template-columns: auto 5rem minmax(0, 1fr) auto;
  grid-template-areas: 'grip thumb meta actions' 'grip thumb alt alt';
  gap: var(--s-2) var(--s-4);
  align-items: center;
  padding: var(--s-3);
  background: var(--paper);
  /* Transform and opacity only: this list is dragged, so it must stay cheap. */
  transition: opacity var(--t-fast) var(--ease-out), box-shadow var(--t-base) var(--ease-out);
}
.photo-item.is-cover { background: var(--mount); }

.photo-grip {
  grid-area: grip;
  display: grid;
  place-content: center;
  width: 1.75rem;
  align-self: stretch;
  color: var(--ink-3);
  cursor: grab;
}
.photo-grip svg { width: 1rem; height: 1rem; }
.photo-item:active .photo-grip { cursor: grabbing; }

.photo-thumb { grid-area: thumb; aspect-ratio: 1 / 1; background: var(--mount); }
.photo-meta { grid-area: meta; display: flex; align-items: center; gap: var(--s-3); flex-wrap: wrap; }
.photo-pos {
  min-width: 1.6rem;
  padding: 0.15rem 0.35rem;
  text-align: center;
  background: var(--mount-deep);
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.photo-item.is-cover .photo-pos { background: var(--paper); }
.photo-actions { grid-area: actions; display: flex; align-items: center; gap: var(--s-1); }
.photo-alt { grid-area: alt; display: flex; align-items: center; gap: var(--s-2); }
.input-inline { padding: 0.45rem 0.6rem; font-size: var(--step--1); }

/* Dragging: the lifted row loses its ground and gains a shadow, and the row it
   would displace opens a gap. Both are transform/opacity only. */
.photo-item.is-dragging {
  opacity: 0.4;
  box-shadow: var(--lift-3);
}
.photo-item.is-over { box-shadow: inset 0 2px 0 var(--ink); }

@media (max-width: 48rem) {
  .photo-item {
    grid-template-columns: auto 4rem minmax(0, 1fr);
    grid-template-areas: 'grip thumb meta' 'grip thumb actions' 'alt alt alt';
  }
  .photo-actions { justify-content: flex-start; }
}

/* The order status line is the only feedback that a drop was saved, so it
   moves rather than simply swapping text. */
[data-order-status] {
  display: inline-block;
  transition: opacity var(--t-fast) var(--ease-out), transform var(--t-fast) var(--ease-out);
}
[data-order-status].is-changing { opacity: 0; transform: translateY(-4px); }

@media (prefers-reduced-motion: reduce) {
  .collection-card img,
  [data-order-status] { transition: none; }
  .photo-item.is-dragging { opacity: 0.4; box-shadow: none; }
}

/* ======================================================= page transitions ==
   Moving between pages cross-fades the content while the masthead stays put.
   Browsers with view transitions get a soft blur-through; everything else
   gets an opacity fade on the main region. Both are skipped entirely for
   anyone who asks for reduced motion.
   ======================================================================== */

#main { transition: opacity 220ms var(--ease-out), transform 220ms var(--ease-out); }
body.is-leaving #main { opacity: 0; transform: translateY(6px); }

@view-transition { navigation: auto; }

::view-transition-old(root) {
  animation: vt-out 260ms var(--ease-in-out) both;
}
::view-transition-new(root) {
  animation: vt-in 520ms var(--ease-out) 60ms both;
}
::view-transition-group(masthead) { animation-duration: 0s; }
@keyframes vt-out {
  to { opacity: 0; filter: blur(6px); transform: translateY(-6px); }
}
@keyframes vt-in {
  from { opacity: 0; filter: blur(6px); transform: translateY(10px); }
}

/* ============================================================== toasts ==
   Flash messages float over the page, so they are the other place glass
   belongs.                                                                 */

.flash-stack { top: calc(var(--masthead-h) + 0.75rem); }
.flash-stack .notice {
  background: var(--glass-strong);
  border-top-width: 1px;
  border: 1px solid var(--rule);
}
@supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
  .flash-stack .notice,
  .flash-stack .notice-success,
  .flash-stack .notice-error,
  .flash-stack .notice-warning,
  .flash-stack .notice-info {
    background: rgba(255, 255, 255, 0.7);
    -webkit-backdrop-filter: var(--glass-blur);
    backdrop-filter: var(--glass-blur);
  }
}
.flash-stack .notice-success { border-left: 2px solid var(--fix); }
.flash-stack .notice-error   { border-left: 2px solid var(--stop); }
.flash-stack .notice-warning { border-left: 2px solid var(--hold); }
.flash-stack .notice-info    { border-left: 2px solid var(--wash); }

/* ================================================================ logos == */

.logo { display: block; color: var(--moss); }
.logo svg { width: 100%; height: auto; }
.logo-white { color: var(--white); }
.rail-logo { display: block; width: 9.5rem; color: var(--moss); padding: var(--s-2) var(--s-3) 0; }
.rail-logo svg { width: 100%; height: auto; }
@media (max-width: 62rem) { .rail-logo { width: 7rem; padding: 0; flex: none; } }

/* ===================================================== reduced motion (new) */

@media (prefers-reduced-motion: reduce) {
  .hero-media img, .hero-line > span, .hero-sub, .hero-actions { animation: none !important; transform: none !important; opacity: 1 !important; }
  .hero-cue { display: none; }
  .develop .frame, .develop > .develop-target { clip-path: none !important; }
  .develop img { transform: none !important; }
  ::view-transition-old(root), ::view-transition-new(root) { animation: none !important; }
  .menu-sheet a { opacity: 1 !important; transform: none !important; }
}

/* =================================================================== print */

@media print {
  .hero, .invite, .menu-sheet { display: none !important; }
  .develop .frame { clip-path: none !important; }
  .develop img { transform: none !important; }
}

/* ================================================================== auth == */

.auth-card > h1 { text-align: center; font-size: var(--step-4); font-weight: 300; }
.auth-card > h1 + .hairline + p,
.auth-card > h1 + .hairline + .dim { text-align: center; max-width: 34ch; margin-inline: auto; }
.auth-card .panel { box-shadow: var(--lift-2); border-color: var(--rule-soft); }
.rail-tag { display: block; margin: calc(var(--s-6) * -1 + var(--s-2)) 0 0 var(--s-3); }
@media (max-width: 62rem) { .rail-tag { display: none; } }

/* ============================================================= documents ==
   Invoices and agreements: the wordmark at the head, a hairline at the foot,
   and the brand colours kept when printed.                                 */

.doc-head {
  margin-bottom: 2.75rem;
  padding-bottom: 1.75rem;
  border-bottom: 1px solid var(--rule);
}
.doc-logo { width: 11rem; }
.doc-head .title-m { font-family: var(--serif); }
.doc-foot {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--s-2) var(--s-5);
  margin-top: var(--s-8);
  padding-top: var(--s-4);
  border-top: 1px solid var(--rule);
  font-size: var(--step--2);
  letter-spacing: 0.08em;
  color: var(--ink-3);
}
@media print {
  body { color: var(--espresso); }
  .logo, .doc-logo, .doc-foot, .tag, .spec { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
}
@media (max-width: 34rem) {
  .doc-head, .page-print .sheet > .row { flex-wrap: wrap; gap: var(--s-5); }
  .doc-head > div[style*='text-align:right'],
  .page-print .sheet > .row > div[style*='text-align:right'] { text-align: left !important; }
}
.error-page .error-code { color: var(--petal); }

/* Figures: ruled cells on white, so a short last row leaves white space
   rather than a grey slab where the missing cells would be. */
.readout {
  background: var(--paper);
  gap: 0;
  border: 0;
  border-top: 1px solid var(--rule);
  border-left: 1px solid var(--rule);
}
.readout > div { box-shadow: inset -1px -1px 0 var(--rule); }

/* ========================================== client & studio: small screens ==
   Below desktop the rail becomes a drawer behind a slim glass bar, tables
   become labelled cards, and nothing on the page scrolls sideways.
   ======================================================================== */

.console-bar, .console-scrim { display: none; }

@media (max-width: 62rem) {
  .console { display: block; }

  .console-bar {
    position: sticky;
    top: 0;
    z-index: 60;
    display: grid;
    grid-template-columns: 2.75rem 1fr 2.75rem;
    align-items: center;
    gap: var(--s-3);
    min-height: 3.75rem;
    padding: 0 var(--gutter);
    background: var(--glass-strong);
    border-bottom: 1px solid var(--rule-soft);
  }
  @supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
    .console-bar { background: var(--glass); -webkit-backdrop-filter: var(--glass-blur); backdrop-filter: var(--glass-blur); }
  }
  .console-toggle {
    width: 2.75rem; height: 2.75rem;
    margin-left: -0.6rem;
    display: grid; place-content: center;
    background: none; border: 0; color: var(--espresso); cursor: pointer;
  }
  .console-toggle svg { width: 1.35rem; height: 1.35rem; }
  .console-bar-logo { justify-self: center; width: 8.25rem; color: var(--moss); }
  .console-bar-logo svg { width: 100%; height: auto; }
  .console-bar-tag { justify-self: end; font-size: 0.625rem; white-space: nowrap; }

  /* The rail, restored to a column, slides in from the left. */
  .console-rail {
    position: fixed;
    top: 0; bottom: 0; left: 0;
    z-index: 70;
    width: min(19rem, 86vw);
    height: 100vh;
    height: 100dvh;
    flex-direction: column;
    align-items: stretch;
    gap: var(--s-5);
    padding: var(--s-5) var(--s-4) var(--s-6);
    border-right: 1px solid var(--rule);
    border-bottom: 0;
    overflow-x: hidden;
    overflow-y: auto;
    overscroll-behavior: contain;
    box-shadow: var(--lift-3);
    /* Its own compositing layer, kept for the life of the page: iOS Safari
       could otherwise drop the painted panel while it slid, leaving it open
       but invisible. The open state is translate3d(0) rather than none so
       the layer is never torn down and rebuilt. */
    transform: translate3d(-104%, 0, 0);
    will-change: transform;
    -webkit-backface-visibility: hidden;
    backface-visibility: hidden;
    visibility: hidden;
    transition: transform 340ms var(--ease-out), visibility 0s linear 340ms;
  }
  .console-rail.is-open {
    transform: translate3d(0, 0, 0);
    visibility: visible;
    transition: transform 340ms var(--ease-out), visibility 0s;
  }
  .console-rail .rail-logo { width: 9rem; padding: var(--s-2) var(--s-3) 0; }
  .console-rail .rail-tag { display: block; }
  .console-rail .rail-nav { flex-direction: column; gap: 1px; }
  .console-rail .rail-link { padding-block: 0.8rem; font-size: var(--step-0); }
  .console-rail .rail-link::before { inset: 0 auto 0 0; width: 1px; height: auto; transform: scaleY(0); transform-origin: top; }
  .console-rail .rail-link[aria-current='page']::before { transform: scaleY(1); }
  .console-rail .rail-foot { margin-left: 0; }

  .console-scrim {
    display: block;
    position: fixed;
    inset: 0;
    z-index: 65;
    background: rgba(52, 42, 39, 0.32);
    opacity: 0;
    transition: opacity 340ms var(--ease-out);
  }
  .console-scrim[hidden] { display: none; }
  .console-scrim.is-on { opacity: 1; }

  .console-main { padding: var(--s-5) var(--gutter) var(--s-8); }
  .flash-stack { top: calc(3.75rem + 0.75rem); }
}

/* Figures: two to a row on phones rather than one tall stack. */
@media (max-width: 40rem) {
  .readout { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .readout > div { padding: var(--s-3) var(--s-4); }
  .readout-value { font-size: var(--step-2); }
}

/* Amounts never break between the R and the figure. */
td.num, .num, .rate-amount, .readout-value { white-space: nowrap; }

/* Native file pickers carry an intrinsic width; keep them inside the screen. */
input[type='file'] { max-width: 100%; }

/* Filter bars: a compact two-column grid on phones, search across the top. */
@media (max-width: 40rem) {
  .console-main form[method='get'] .row {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--s-3);
  }
  .console-main form[method='get'] .row > * { min-width: 0; flex: none !important; margin: 0 !important; }
  .console-main form[method='get'] .row > .field:first-child,
  .console-main form[method='get'] .row > .btn,
  .console-main form[method='get'] .row > button { grid-column: 1 / -1; }
  .console-main form[method='get'] .field-label { margin-bottom: var(--s-1); }
  .console-main form[method='get'] .panel-body { padding: var(--s-4); }
}

/* Tables become labelled cards whenever the table itself is short of room,
   on any device: the measure is the table's own container, so a tablet with
   the rail open counts as narrow too. Labels come from the header row
   (app.js copies them onto each cell as data-label, and wraps any bare
   table in .table-wrap). Browsers without container queries fall back to
   the viewport width. */
.console-main .table-wrap { container-type: inline-size; container-name: table; }

@container table (max-width: 46rem) {
  .table-wrap > .table:not(.table-keep) thead { display: none; }
  .table-wrap > .table:not(.table-keep),
  .table-wrap > .table:not(.table-keep) tbody,
  .table-wrap > .table:not(.table-keep) tfoot,
  .table-wrap > .table:not(.table-keep) tr { display: block; width: 100%; }
  .table-wrap > .table:not(.table-keep) tbody tr {
    padding: var(--s-3) var(--s-4);
    border-bottom: 1px solid var(--rule);
  }
  .table-wrap > .table:not(.table-keep) tbody tr:hover { background: transparent; }
  .table-wrap > .table:not(.table-keep) td,
  .table-wrap > .table:not(.table-keep) tfoot th {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: var(--s-4);
    padding: 0.3rem 0;
    border: 0;
    text-align: right;
    position: static;
    background: none;
  }
  .table-wrap > .table:not(.table-keep) td::before {
    content: attr(data-label);
    flex: none;
    max-width: 45%;
    text-align: left;
    font-size: 0.625rem;
    font-weight: 450;
    text-transform: uppercase;
    letter-spacing: 0.18em;
    color: var(--ink-3);
  }
  .table-wrap > .table:not(.table-keep) td:not([data-label])::before,
  .table-wrap > .table:not(.table-keep) td[data-label='']::before { display: none; }
  /* The first cell names the row: give it the line to itself. */
  .table-wrap > .table:not(.table-keep) tbody td:first-child {
    display: block;
    text-align: left;
    padding-bottom: var(--s-2);
    font-weight: 450;
  }
  .table-wrap > .table:not(.table-keep) tbody td:first-child::before { display: none; }
  /* Totals rows keep their label beside the figure. */
  .table-wrap > .table:not(.table-keep) tfoot tr {
    display: flex;
    justify-content: space-between;
    padding: var(--s-2) var(--s-4);
    border-top: 1px solid var(--rule-soft);
  }
  .table-wrap > .table:not(.table-keep) tfoot th,
  .table-wrap > .table:not(.table-keep) tfoot td { display: block; padding: 0; width: auto; }
  .table-wrap > .table:not(.table-keep) td .btn,
  .table-wrap > .table:not(.table-keep) td form { margin-left: auto; }
  
}

@supports not (container-type: inline-size) {
  @media (max-width: 47.99rem) {
  .table-wrap > .table:not(.table-keep) thead { display: none; }
  .table-wrap > .table:not(.table-keep),
  .table-wrap > .table:not(.table-keep) tbody,
  .table-wrap > .table:not(.table-keep) tfoot,
  .table-wrap > .table:not(.table-keep) tr { display: block; width: 100%; }
  .table-wrap > .table:not(.table-keep) tbody tr {
    padding: var(--s-3) var(--s-4);
    border-bottom: 1px solid var(--rule);
  }
  .table-wrap > .table:not(.table-keep) tbody tr:hover { background: transparent; }
  .table-wrap > .table:not(.table-keep) td,
  .table-wrap > .table:not(.table-keep) tfoot th {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: var(--s-4);
    padding: 0.3rem 0;
    border: 0;
    text-align: right;
    position: static;
    background: none;
  }
  .table-wrap > .table:not(.table-keep) td::before {
    content: attr(data-label);
    flex: none;
    max-width: 45%;
    text-align: left;
    font-size: 0.625rem;
    font-weight: 450;
    text-transform: uppercase;
    letter-spacing: 0.18em;
    color: var(--ink-3);
  }
  .table-wrap > .table:not(.table-keep) td:not([data-label])::before,
  .table-wrap > .table:not(.table-keep) td[data-label='']::before { display: none; }
  /* The first cell names the row: give it the line to itself. */
  .table-wrap > .table:not(.table-keep) tbody td:first-child {
    display: block;
    text-align: left;
    padding-bottom: var(--s-2);
    font-weight: 450;
  }
  .table-wrap > .table:not(.table-keep) tbody td:first-child::before { display: none; }
  /* Totals rows keep their label beside the figure. */
  .table-wrap > .table:not(.table-keep) tfoot tr {
    display: flex;
    justify-content: space-between;
    padding: var(--s-2) var(--s-4);
    border-top: 1px solid var(--rule-soft);
  }
  .table-wrap > .table:not(.table-keep) tfoot th,
  .table-wrap > .table:not(.table-keep) tfoot td { display: block; padding: 0; width: auto; }
  .table-wrap > .table:not(.table-keep) td .btn,
  .table-wrap > .table:not(.table-keep) td form { margin-left: auto; }
  
}
}

@media (prefers-reduced-motion: reduce) {
  .console-rail, .console-scrim { transition: none !important; }
}

/* ------------------------------------------------------------------ pay link
   The page behind "Pay now" in invoice emails: one invoice, one decision. */
.pay-page { max-width: 36rem; padding-block: clamp(2.5rem, 7vw, 5rem) clamp(4rem, 9vw, 7rem); }
.pay-head { margin-bottom: clamp(1.75rem, 5vw, 2.75rem); }
.pay-head .title-xl { margin-top: var(--s-2); }
.pay-notice { margin-bottom: var(--s-5); }
.pay-small { font-size: var(--step--1); line-height: 1.55; }
.pay-card .panel-foot { align-items: center; gap: var(--s-3); }
