/* Self-hosted fonts (latin subset, OFL) */
@font-face{font-family:'Cormorant Garamond';font-style:italic;font-weight:300;font-display:swap;src:url(/assets/fonts/cormorant-garamond-italic-300.woff2) format('woff2')}
@font-face{font-family:'IBM Plex Mono';font-style:normal;font-weight:400;font-display:swap;src:url(/assets/fonts/ibm-plex-mono-normal-400.woff2) format('woff2')}
@font-face{font-family:'IBM Plex Mono';font-style:normal;font-weight:500;font-display:swap;src:url(/assets/fonts/ibm-plex-mono-normal-500.woff2) format('woff2')}
@font-face{font-family:'Montserrat';font-style:normal;font-weight:500 800;font-display:swap;src:url(/assets/fonts/montserrat-normal-500-800.woff2) format('woff2')}

/* ═══════════════════════════════════════════════════════════════
   EXPOSURE MEDIA — shared stylesheet
   Loaded by every page. Design system is locked: Cormorant Garamond
   Light Italic for accents, Montserrat for display/titles, IBM Plex
   Mono for body/UI. Gold #D4A843, Charcoal #2B2B2B.
   ═══════════════════════════════════════════════════════════════ */

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

:root {
  --charcoal: #2B2B2B;
  --gold: #D4A843;
  /* The same gold, taken down until small text made of it is actually
     readable. #D4A843 is 2.0:1 on the page background — fine as a fill or
     as display type, unreadable as a 0.6rem tracked-out label. This one is
     5.1:1 on off-white and still clears AA on the darker band. Fills,
     rules and big display type keep --gold. */
  --gold-ink: #86631A;
  --light-gray: #D8D8D8;
  --off-white: #F7F5F0;
  /* The alternating band. Deep enough to separate two stacked
     sections without a rule between them, shallow enough that it
     never reads as a box. White is now reserved for the things
     that float: cards, chips, fields. */
  --band: #EFEBE3;
  --white: #FFFFFF;

  /* Elevation. Two layers each: a tight contact shadow that grounds the
     element, plus a wide diffuse one that lifts it off the page. The
     inset highlight along the top edge is the soft bezel — it reads as
     light catching a raised surface. */
  --radius: 11px;      /* buttons, chips — soft enough to lose the harsh corner */
  --radius-lg: 16px;   /* cards, panels, media */
  --radius-sm: 9px;    /* form fields */
  /* A blurred 1px inset rather than a hard line — a crisp white rule across
     the top of a mid-tone button reads as a glare streak, not a bevel. */
  --bezel: inset 0 1px 1px rgba(255, 255, 255, 0.42);
  --bezel-gold: inset 0 1px 1px rgba(255, 255, 255, 0.18);
  --bezel-dark: inset 0 1px 1px rgba(255, 255, 255, 0.10);
  --lift-1: 0 1px 2px rgba(43, 43, 43, 0.07), 0 3px 8px rgba(43, 43, 43, 0.07);
  --lift-2: 0 2px 4px rgba(43, 43, 43, 0.08), 0 8px 20px rgba(43, 43, 43, 0.11);
  --lift-3: 0 4px 8px rgba(43, 43, 43, 0.09), 0 16px 34px rgba(43, 43, 43, 0.15);
  --press: 0 1px 2px rgba(43, 43, 43, 0.12);
  --ease: cubic-bezier(0.4, 0, 0.2, 1);
  /* For big moves. The standard curve front-loads its speed, which on a
     1000px height change means the page lurches and then crawls. This is a
     sine-shaped in-out: it eases off both ends and, for a given distance
     and duration, has about the lowest peak speed a curve can have while
     still reading as eased rather than mechanical. */
  --ease-soft: cubic-bezier(0.37, 0, 0.63, 1);
}

html {
  scroll-behavior: smooth;
  /* This is what paints the rubber-band / overscroll area past the ends of
     the page. Without an explicit background here, the canvas inherits
     body's light background and you get a white bar flashing in under the
     footer when you scroll past the bottom. Charcoal matches both the
     footer and the nav, so overscrolling at either end looks deliberate. */
  background: var(--charcoal);
}

body {
  background: var(--off-white);
  color: var(--charcoal);
  font-family: 'IBM Plex Mono', monospace;
  font-weight: 400;
  overflow-x: hidden;
}

a { color: inherit; }

/* ── LOGO ── */
.logo { display: inline-flex; align-items: center; text-decoration: none; }
.logo img { display: block; height: 2.1rem; width: auto; }
footer .logo img { height: 2.5rem; }

#siteNav .logo { position: relative; }
#siteNav .logo .logo-dark { display: none; }
#siteNav .logo .logo-light { display: block; }

/* ── NAV ──
   Dark translucent glass bar on every screen size. Solid/visible at the
   top of the page, easing toward see-through as you scroll into content —
   the reverse of a typical "transparent until scrolled" nav, by request. */
nav {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 100;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 1.5rem 4rem;
  background: rgba(43, 43, 43, 0.72);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  transition: background 0.3s, backdrop-filter 0.3s, transform 0.3s ease, opacity 0.3s ease;
  color: var(--white);
}

nav.scrolled {
  background: rgba(43, 43, 43, 0.26);
}

nav ul { list-style: none; display: flex; gap: 2.5rem; }

nav ul a {
  text-decoration: none;
  font-size: 0.7rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  opacity: 0.7;
  transition: opacity 0.3s, color 0.3s;
  border-bottom: 1px solid transparent;
  padding-bottom: 0.2rem;
}

nav ul a:hover { opacity: 1; color: var(--gold); border-color: var(--gold); }
nav ul a.active { opacity: 1; color: var(--gold); }

.nav-toggle {
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 26px; height: 20px;
  background: none; border: none; padding: 0;
  cursor: pointer;
  z-index: 101;
  color: inherit; /* buttons don't inherit text color — currentColor needs this */
}
.nav-toggle::before {           /* 44px touch target around the 26px icon */
  content: '';
  position: absolute;
  inset: -12px -9px;
}
.nav-toggle span {
  display: block; width: 100%; height: 2px;
  background: currentColor; border-radius: 2px;
  transition: transform 0.3s ease, opacity 0.3s ease;
}
.nav-toggle.open span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.nav-toggle.open span:nth-child(2) { opacity: 0; }
.nav-toggle.open span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

.mobile-menu { display: none; }  /* desktop; the mobile query re-enables it */

/* ── FIXED BACKGROUND SCENE ── */
/* Sized to the LARGE viewport (browser toolbars collapsed), not inset: 0.
   On phones the toolbar slides away on the first swipe; a scene pinned to
   the visible area grew with it, and background-size: cover re-scaled the
   wall by a few percent — the "grow" on the first swipe. */
.scene {
  position: fixed; top: 0; left: 0; right: 0;
  height: 100vh; height: 100lvh;
  z-index: 0; overflow: hidden;
}

.oak-surface {
  position: absolute; inset: 0;
  background-color: #4f341f;
  background-image: url('/assets/slat-wall.jpg');
  background-size: cover;
  background-position: center;
}

.oak-surface::after {
  content: '';
  position: absolute; inset: 0;
  background: radial-gradient(ellipse at 50% 40%, rgba(247, 245, 240, 0.04), rgba(43, 43, 43, 0.22) 100%);
}

.polaroid-field {
  position: absolute;
  left: 0; right: 0; top: 0;
  height: 420vh;
  will-change: transform;
}

.polaroid {
  position: absolute;
  background: var(--white);
  border-radius: 4px;
  box-shadow: 0 18px 34px rgba(43, 43, 43, 0.22), 0 2px 6px rgba(43, 43, 43, 0.1);
}

.polaroid .photo {
  width: 100%;
  aspect-ratio: 46 / 62;
  background-size: cover;
  background-position: center;
  background-color: var(--light-gray);
  filter: saturate(0.94) contrast(1.02);
}

/* ── CONTINUOUS GLASS PANEL ── */
.glass-shell {
  position: relative;
  z-index: 1;
  /* Back to the original veil. The legibility work now lives in the type
     itself — weight 500 and a light halo around each glyph — rather than in
     hiding the wall behind it. */
  background: rgba(247, 245, 240, 0.18);
  backdrop-filter: blur(2px) saturate(1.1);
  -webkit-backdrop-filter: blur(2px) saturate(1.1);
}

/* ── HERO (homepage) ── */
#hero.block {
  padding-top: 8.5rem;
  min-height: 74vh;
  display: flex;
  align-items: center;
}
/* The hero is a flex container, so without an explicit width its panel
   shrinks to fit its text instead of honouring max-width — which is what
   made it narrower than every other panel on the page. */
#hero.block .section-inner { margin: 0 auto; width: 100%; }

/* Interior pages get a shorter hero so they don't each read as a homepage */
#hero.block.page-hero { min-height: 0; padding-top: 8.5rem; padding-bottom: 2.5rem; }

.hero-eyebrow {
  font-family: 'Cormorant Garamond', serif;
  font-style: italic; font-weight: 300;
  font-size: 1.35rem;
  color: var(--charcoal);
  opacity: 0.75;
  margin-bottom: 1.25rem;
  text-shadow: 0 0 6px rgba(247, 245, 240, 0.5), 0 0 14px rgba(247, 245, 240, 0.4), 0 0 26px rgba(247, 245, 240, 0.3);
}

.hero-title {
  font-family: 'Montserrat', sans-serif;
  font-weight: 800;
  font-size: clamp(2.6rem, 6.4vw, 4.6rem);
  line-height: 1.02;
  letter-spacing: 0.01em;
  text-transform: uppercase;
  color: var(--charcoal);
  margin-bottom: 1.5rem;
}

.page-hero .hero-title { font-size: clamp(2.1rem, 4.8vw, 3.4rem); }
.hero-title span { color: var(--gold); }

.hero-sub {
  font-size: 0.8rem;
  letter-spacing: 0.2em;
  opacity: 0.65;
  margin-bottom: 2.5rem;
  text-transform: uppercase;
  text-shadow: 0 0 6px rgba(247, 245, 240, 0.5), 0 0 14px rgba(247, 245, 240, 0.4), 0 0 26px rgba(247, 245, 240, 0.3);
}

/* ── BUTTONS ──
   Raised rather than drawn: a soft bezel along the top edge, a shadow
   underneath, and a small lift on hover so they feel like objects you
   can press rather than rectangles of text. */
.btn {
  display: inline-block;
  padding: 0.9rem 2.5rem;
  border: none;
  border-radius: var(--radius);
  background: var(--white);
  color: var(--charcoal);
  text-decoration: none;
  font-family: 'IBM Plex Mono', monospace;
  font-size: 0.7rem;
  letter-spacing: 0.25em;
  text-transform: uppercase;
  box-shadow: var(--bezel), var(--lift-1);
  transition: transform 0.26s var(--ease), box-shadow 0.26s var(--ease),
              background 0.26s var(--ease), color 0.26s var(--ease);
}

.btn:hover {
  transform: translateY(-2px);
  box-shadow: var(--bezel), var(--lift-3);
}

.btn:active { transform: translateY(0); box-shadow: var(--press); }

.btn-gold {
  background: var(--gold);
  color: var(--charcoal);
  box-shadow: var(--bezel-gold), var(--lift-2),
              0 6px 18px rgba(212, 168, 67, 0.28);
}

.btn-gold:hover {
  background: var(--gold);
  color: var(--charcoal);
  transform: translateY(-2px);
  box-shadow: var(--bezel-gold), var(--lift-3),
              0 12px 28px rgba(212, 168, 67, 0.38);
}

.btn-gold:active { transform: translateY(0); box-shadow: var(--press); }

.btn-row { display: flex; gap: 1rem; justify-content: center; flex-wrap: wrap; }

/* ── GENERIC SECTION ── */
section.block { position: relative; padding: 4.5rem 2rem; }

.section-inner {
  max-width: 1000px;
  margin: 0 auto;
  text-align: center;
  background: rgba(247, 245, 240, 0.8);
  /* Was 0.6. "Double the opacity" can't literally apply — 0.6 doubled is
     past solid — so the see-through half was halved instead: 40% of the
     photo wall showing through becomes 20%. The frosted glass layer behind
     (.glass-shell) is untouched; only the panels sitting on it changed. */
  border: 1px solid rgba(255, 255, 255, 0.6);
  border-radius: 22px;
  box-shadow: 0 16px 40px rgba(43, 43, 43, 0.1);
  padding: 2.6rem 2.5rem;
}

.section-inner.wide { max-width: 1000px; }  /* kept as a hook; width is uniform */

.section-label {
  font-size: 0.65rem;
  letter-spacing: 0.4em;
  text-transform: uppercase;
  color: var(--gold-ink);
  font-weight: 500;
  text-shadow: 0 0 6px rgba(247, 245, 240, 0.5), 0 0 14px rgba(247, 245, 240, 0.4), 0 0 26px rgba(247, 245, 240, 0.3);
  margin-bottom: 1.25rem;
}

.section-title {
  font-family: 'Montserrat', sans-serif;
  font-weight: 800;
  text-transform: uppercase;
  font-size: clamp(1.9rem, 4.4vw, 3.1rem);
  line-height: 1.15;
  margin-bottom: 1.25rem;
  color: var(--charcoal);
}

.section-accent {
  font-family: 'Cormorant Garamond', serif;
  font-style: italic; font-weight: 300;
  font-size: 1.5rem;
  color: var(--charcoal);
  opacity: 0.8;
}

.section-body {
  font-size: 0.88rem;
  line-height: 1.95;
  /* 0.7 put this at 5.1:1 — technically a pass, but this is 14px mono with
     wide leading, and it read as washed out. 0.84 is 7.9:1 and still clearly
     secondary to the headings. */
  opacity: 0.84;
  font-weight: 500;
  /* A centred glow, not a drop shadow. Offsetting it downward left a pale
     smear under every glyph, and the dark layer under dark text doubled the
     letterform — together they read as embossed. With no offset it just
     holds the panel colour tight around each letter, which is the only job
     it ever had. */
  text-shadow: 0 0 6px rgba(247, 245, 240, 0.55),
               0 0 14px rgba(247, 245, 240, 0.45),
               0 0 28px rgba(247, 245, 240, 0.35);
  max-width: 600px;
  margin: 0 auto 1.7rem;
}

.section-body:last-child { margin-bottom: 0; }
.section-body + .section-body { margin-top: -1.5rem; }

/* ── SERVICE CARDS ── */
.services-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 1.25rem;
  margin-top: 2.25rem;
  text-align: left;
}

.service-card {
  border: none;
  border-radius: var(--radius-lg);
  padding: 1.75rem 1.5rem;
  background: var(--white);
  box-shadow: var(--bezel), var(--lift-1);
  transition: transform 0.3s var(--ease), box-shadow 0.3s var(--ease);
  text-decoration: none;
  display: block;
  color: inherit;
}

.service-card:hover {
  transform: translateY(-5px);
  box-shadow: var(--bezel), var(--lift-3);
}

.service-card h3 {
  font-family: 'Montserrat', sans-serif;
  font-weight: 700;
  font-size: 1.1rem;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  margin-bottom: 0.9rem;
  color: var(--charcoal);
}

.service-card p { font-size: 0.82rem; line-height: 1.85; opacity: 0.8; }

.service-number {
  font-family: 'Cormorant Garamond', serif;
  font-style: italic;
  font-size: 1.6rem;
  color: var(--gold-ink);
  margin-bottom: 1rem;
  display: block;
}

.card-link {
  display: inline-block;
  margin-top: 1.25rem;
  font-size: 0.62rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--gold-ink);
  border-bottom: 1px solid transparent;
  transition: border-color 0.3s;
}
.service-card:hover .card-link { border-color: var(--gold); }

/* ═══════════════════════════════════════════════════════════════
   SERVICES PICKER
   Two-stage drill-down: pick a medium, then the kind of work. All
   eight panels are rendered in the HTML and hidden with CSS rather
   than injected by JS — so the copy is still in the page for search
   engines, and it all stays readable if the script never runs.
   ═══════════════════════════════════════════════════════════════ */

.picker {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: 1rem;
  margin-top: 1.75rem;
}

.picker-option {
  font-family: 'Montserrat', sans-serif;
  font-weight: 700;
  font-size: 0.92rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--charcoal);
  background: var(--white);
  border: none;
  border-radius: var(--radius);
  padding: 1.5rem 2.75rem;
  cursor: pointer;
  min-width: 232px;
  box-shadow: var(--bezel), var(--lift-1);
  transition: transform 0.28s var(--ease), box-shadow 0.28s var(--ease),
              background 0.28s var(--ease), color 0.28s var(--ease);
}

.picker-option:hover {
  transform: translateY(-2px);
  box-shadow: var(--bezel), var(--lift-3);
}

.picker-option:active { transform: translateY(-1px); box-shadow: var(--press); }

.picker-option[aria-pressed="true"] {
  background: var(--gold);
  color: var(--charcoal);
  box-shadow: var(--bezel-gold), var(--lift-2),
              0 10px 26px rgba(212, 168, 67, 0.34);
}

/* Once a work type is chosen the medium row minimizes rather than leaving:
   it scales down and fades back, staying live so it doubles as the way to
   switch media — which is why there's no separate "change selection" link.
   Scaling is a compositor transform, so it stays smooth; the max-height
   shrinking alongside it is what lets the work types rise into the space. */
.picker.medium-row {
  max-height: 240px;
  /* Must stay visible: overflow clipping is applied in the element's own
     coordinate space, BEFORE the transform — so hiding it here would slice
     the bottom off the buttons and then shrink the slice. Visible overflow
     lets max-height control the layout height while scale() handles what
     you actually see. */
  overflow: visible;
  transform-origin: top center;
  transition: max-height 0.5s var(--ease),
              transform 0.5s var(--ease),
              opacity 0.42s var(--ease),
              margin-top 0.5s var(--ease);
}

.picker.medium-row.minimized {
  max-height: 44px;   /* the 64px row's visual height at scale(0.68) */
  transform: scale(0.68);
  opacity: 0.5;
  margin-top: 0.5rem;
  margin-bottom: 0.35rem;
}

.picker.medium-row.minimized:hover { opacity: 0.92; }

.type-picker {
  max-height: 0;
  overflow: visible;
  opacity: 0;
  margin-top: 0;
  transform: translateY(8px) scale(0.97);
  pointer-events: none;
  transition: max-height 0.5s var(--ease),
              opacity 0.38s var(--ease),
              transform 0.5s var(--ease),
              margin-top 0.5s var(--ease);
}

.type-picker.open {
  max-height: 340px;
  opacity: 1;
  margin-top: 1.5rem;
  transform: translateY(0) scale(1);
  pointer-events: auto;
}

.chip {
  font-family: 'IBM Plex Mono', monospace;
  font-size: 0.68rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--charcoal);
  background: var(--white);
  border: none;
  border-radius: var(--radius);
  padding: 0.75rem 1.6rem;
  cursor: pointer;
  box-shadow: var(--bezel), var(--lift-1);
  transition: transform 0.25s var(--ease), box-shadow 0.25s var(--ease),
              background 0.25s var(--ease), color 0.25s var(--ease);
}

.chip:hover {
  transform: translateY(-2px);
  box-shadow: var(--bezel), var(--lift-2);
}

.chip:active { transform: translateY(0); box-shadow: var(--press); }

.chip[aria-pressed="true"] {
  background: var(--gold);
  color: var(--charcoal);
  box-shadow: var(--bezel-gold), var(--lift-2),
              0 8px 20px rgba(212, 168, 67, 0.30);
}

/* The nav is fixed, so a plain scrollIntoView tucks the heading underneath
   it. Offset the anchor by roughly the bar's height. */
#offer, #faqs, [id] { scroll-margin-top: 92px; }

.picker-hint {
  font-family: 'Cormorant Garamond', serif;
  font-style: italic;
  font-size: 1.05rem;
  opacity: 0.6;
  margin-top: 1.5rem;
}

/* Two stages occupying the same spot: the picker, then the answer. Only
   one is ever mounted, so the content genuinely replaces the buttons
   rather than pushing them around. */
.stage { animation: panelIn 0.4s ease both; }

@keyframes panelIn {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* Panels: with JS active, only the selected one shows. Without JS every
   panel shows in sequence, each with its own visible heading — so the copy
   is always readable and always indexable. */
.js-on .offer-panel { display: none; }
.js-on .offer-panel.active { display: block; }

#offerStage { margin-top: 2.5rem; }
#introStage { margin-top: 0; }

.offer-panel + .offer-panel { margin-top: 3.5rem; }
.js-on .offer-panel + .offer-panel { margin-top: 0; }

.offer-panel h3 {
  font-family: 'Montserrat', sans-serif;
  font-weight: 800;
  text-transform: uppercase;
  font-size: clamp(1.5rem, 3.2vw, 2.2rem);
  line-height: 1.2;
  margin-bottom: 1.15rem;
  color: var(--charcoal);
}

.offer-panel .section-body { margin-bottom: 1.6rem; }

.offer-panel .panel-kicker {
  font-size: 0.6rem;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--gold-ink);
  margin-bottom: 1rem;
}

/* Pricing sits inside the drilled-in stage, so it only turns up once
   someone has actually seen what they'd be paying for. */
.offer-footer {
  margin-top: 2.25rem;
  padding-top: 0;
}

.offer-footer .section-body { margin-bottom: 1.5rem; }


@media (max-width: 700px) {
  .picker-option { min-width: 0; width: 100%; padding: 1.15rem 1.5rem; font-size: 0.78rem; }
  /* Stacked, so the scaled row needs proportionally more room than desktop. */
  .picker.medium-row.minimized { max-height: 82px; }
  .picker { gap: 0.7rem; }
  .chip { padding: 0.6rem 1.1rem; font-size: 0.62rem; letter-spacing: 0.14em; }
  .type-picker.open { max-height: 420px; }
}

/* ── CHECK LIST (service detail pages) ── */
.check-list {
  list-style: none;
  text-align: left;
  max-width: 560px;
  margin: 0 auto;
  display: grid;
  gap: 0.9rem;
}

.check-list li {
  position: relative;
  padding-left: 2.1rem;
  font-size: 0.85rem;
  line-height: 1.8;
  /* The text is softened with its colour, not with opacity — opacity on
     the <li> faded the dash along with it, and a faded 1px gold line over
     the photo wall all but disappeared. */
  color: rgba(43, 43, 43, 0.8);
}

/* The dash: big enough to read as a mark at a glance, not a hairline.
   Centred on the first line of text, rounded so it matches the soft
   corners everywhere else. */
.check-list li::before {
  content: '';
  position: absolute;
  left: 0;
  top: calc(0.9em - 1.5px);
  width: 16px;
  height: 3px;
  border-radius: 2px;
  background: var(--gold);
}

/* ── FAQ ──
   Collapsed by default, so the whole block is a short stack of one-line
   questions instead of a wall of answers. Built on <details>/<summary>,
   which means no JavaScript and correct keyboard behavior for free. */
.faq-list { text-align: left; max-width: 660px; margin: 0 auto; display: grid; gap: 0.6rem; }

.faq-item {
  border: none;
  border-radius: var(--radius-lg);
  background: var(--white);
  padding: 0 1.25rem;
  box-shadow: var(--bezel), var(--lift-1);
  transition: box-shadow 0.28s var(--ease), transform 0.28s var(--ease);
}

.faq-item:hover { transform: translateY(-1px); box-shadow: var(--bezel), var(--lift-2); }
.faq-item.is-open { box-shadow: var(--bezel), var(--lift-2); }

.faq-item summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  padding: 1.15rem 0.25rem;
  font-family: 'IBM Plex Mono', monospace;
  font-size: 0.8rem;
  line-height: 1.6;
  color: var(--charcoal);
  opacity: 0.82;
  transition: opacity 0.25s, color 0.25s;
}

.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary:hover { opacity: 1; color: var(--gold); }
.faq-item.is-open summary { opacity: 1; }

/* Thin plus that becomes a minus when open. */
.faq-mark {
  position: relative;
  flex: 0 0 11px;
  width: 11px;
  height: 11px;
}
.faq-mark::before,
.faq-mark::after {
  content: '';
  position: absolute;
  top: 50%; left: 0;
  width: 11px; height: 1px;
  background: var(--gold);
  transition: transform 0.28s ease;
}
.faq-mark::after { transform: rotate(90deg); }
.faq-item.is-open .faq-mark::after { transform: rotate(0deg); }

.faq-item p {
  font-size: 0.8rem;
  line-height: 1.95;
  opacity: 0.65;
  padding: 0 0.25rem 1.5rem;
  max-width: 58ch;
}

/* ── GALLERY GRID ── */
.gallery-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
  gap: 1rem;
  margin-top: 3rem;
}

.gallery-item {
  position: relative;
  aspect-ratio: 4 / 5;
  overflow: hidden;
  background: var(--light-gray);
  border: none;
  border-radius: var(--radius-lg);
  box-shadow: var(--lift-1);
  transition: transform 0.35s var(--ease), box-shadow 0.35s var(--ease);
}

.gallery-item:hover { transform: translateY(-4px); box-shadow: var(--lift-3); }

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

.gallery-item:hover img { transform: scale(1.05); }

.gallery-empty {
  grid-column: 1 / -1;
  border-radius: var(--radius-lg);
  padding: 3rem 1.5rem;
  border: 1px dashed rgba(43, 43, 43, 0.25);
  font-size: 0.8rem;
  letter-spacing: 0.06em;
  opacity: 0.6;
  line-height: 1.9;
}

/* ── CONTACT ── */
.contact-form {
  display: flex; flex-direction: column; gap: 1rem;
  max-width: 520px; margin: 2.5rem auto 0;
  text-align: left;
}

.contact-form input,
.contact-form textarea,
.contact-form select {
  width: 100%;
  background: var(--white);
  border: none;
  border-radius: var(--radius-sm);
  box-shadow: inset 0 1px 3px rgba(43, 43, 43, 0.09);
  color: var(--charcoal);
  padding: 0.9rem 1.1rem;
  font-family: 'IBM Plex Mono', monospace;
  font-size: 0.8rem;
  letter-spacing: 0.03em;
  outline: none;
  transition: box-shadow 0.3s var(--ease);
  -webkit-appearance: none;
  appearance: none;
}

.contact-form select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' stroke='%232B2B2B' stroke-width='1.4' fill='none' stroke-linecap='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 1.1rem center;
  text-transform: uppercase;
  font-size: 0.68rem;
  letter-spacing: 0.12em;
}

.contact-form input::placeholder,
.contact-form textarea::placeholder {
  color: rgba(43, 43, 43, 0.4);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  font-size: 0.68rem;
}

.contact-form input:focus,
.contact-form textarea:focus,
.contact-form select:focus {
  box-shadow: inset 0 1px 3px rgba(43, 43, 43, 0.06), 0 0 0 2px rgba(212, 168, 67, 0.55);
}

.contact-form textarea { min-height: 130px; resize: vertical; }

.contact-form button {
  background: var(--gold);
  color: var(--charcoal);
  border: none;
  border-radius: var(--radius);
  padding: 0.95rem;
  font-family: 'IBM Plex Mono', monospace;
  font-weight: 500;
  font-size: 0.7rem;
  letter-spacing: 0.25em;
  text-transform: uppercase;
  cursor: pointer;
  box-shadow: var(--bezel-gold), var(--lift-2), 0 6px 18px rgba(212, 168, 67, 0.28);
  transition: transform 0.26s var(--ease), box-shadow 0.26s var(--ease);
}
.contact-form button:hover {
  transform: translateY(-2px);
  box-shadow: var(--bezel-gold), var(--lift-3), 0 12px 28px rgba(212, 168, 67, 0.38);
}
.contact-form button:active { transform: translateY(0); box-shadow: var(--press); }

.contact-direct {
  margin-top: 1.75rem;
  font-size: 0.78rem;
  line-height: 2.1;
  opacity: 0.7;
  letter-spacing: 0.05em;
}
.contact-direct a { color: var(--gold-ink); text-decoration: none; }
.contact-direct a:hover { text-decoration: underline; }

/* ── FOOTER ── */
footer {
  position: relative;
  z-index: 2;
  background: var(--charcoal);
  color: var(--light-gray);
  text-align: center;
  padding: 2.75rem 2rem 2rem;
  font-size: 0.7rem;
  letter-spacing: 0.15em;
}

.footer-tagline {
  font-family: 'Cormorant Garamond', serif;
  font-style: italic;
  font-weight: 300;
  font-size: 1.15rem;
  letter-spacing: 0.02em;
  opacity: 0.75;
  margin: 1rem 0 2rem;
  text-transform: none;
}

.footer-nav {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: 1.75rem;
  margin-bottom: 2.25rem;
}

.footer-nav a {
  text-decoration: none;
  font-size: 0.62rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  opacity: 0.78;
  transition: opacity 0.3s, color 0.3s;
}
.footer-nav a:hover { opacity: 1; color: var(--gold); }

.footer-meta { font-size: 0.66rem; line-height: 2.2; opacity: 0.72; }
.footer-meta a { color: inherit; text-decoration: none; }
.footer-meta a:hover { color: var(--gold); }

.footer-areas {
  margin-top: 1.5rem;
  font-size: 0.6rem;
  letter-spacing: 0.18em;
  opacity: 0.7;
  line-height: 2;
}

/* links inside footer-areas lines */
.footer-areas a { color: inherit; text-decoration: none; }
.footer-areas a:hover { color: var(--gold); }
.footer-areas.footer-social { margin-top: 0; }

footer .copyright {
  opacity: 0.68;
  text-transform: uppercase;
  margin-top: 2rem;
  font-size: 0.6rem;
}

/* ═══════════════════════════════════════════════════════════════
   CLEAN MODE  (body.clean)
   Used on the service / transactional pages. Same type system, same
   nav and footer, but no wood scene, no Polaroids and no frosted
   glass — these are the pages someone reads when they're seriously
   evaluating, so they get editorial calm instead of atmosphere.
   Also much lighter to load, which matters for the pages Google
   sends commercial-intent traffic to.
   ═══════════════════════════════════════════════════════════════ */

body.clean { background: var(--off-white); }

/* The nav's translucency exists to let the wood scene show through. On a
   clean page there's nothing behind it but white, so the same rgba reads
   as washed-out grey — and fading toward transparent on scroll would just
   dissolve it into the page. Solid charcoal at both states instead. */
body.clean nav,
body.clean nav.scrolled {
  background: var(--charcoal);
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}

body.clean .glass-shell {
  background: transparent;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}

body.clean .section-inner {
  background: transparent;
  border: none;
  box-shadow: none;
  border-radius: 0;
  padding: 0;
  max-width: 820px;
}

body.clean .section-inner.wide { max-width: 820px; }

body.clean section.block { padding: 3.6rem 2rem; }

/* Alternating bands give the page structure without decoration. Both tones
   are off-white: a full-width slab of pure #FFF next to a warm background
   reads as glare, and it flattens the cards that are supposed to float on
   top of it. */
body.clean section.block:nth-of-type(even) {
  background: var(--band);
}

body.clean #hero.block.page-hero {
  min-height: 0;
  padding-top: 9rem;
  padding-bottom: 3rem;
  background: var(--off-white);
}

/* A short gold rule under the hero eyebrow — the one flourish that
   survives into clean mode, so it still reads as the same brand. */
body.clean .hero-eyebrow { position: relative; padding-bottom: 1.25rem; }
body.clean .hero-eyebrow::after {
  content: '';
  position: absolute;
  left: 50%; bottom: 0;
  width: 34px; height: 2px;
  margin-left: -17px;
  background: var(--gold);
}

/* Cards, panels and fields stay white on BOTH bands now. That contrast is
   the whole point of the elevation system — flipping them to the band
   colour on alternate sections was what made them sink into the page. */
body.clean .service-card {
  background: var(--white);
  border-color: rgba(43, 43, 43, 0.12);
}

body.clean .faq-item { background: var(--white); border-color: rgba(43, 43, 43, 0.12); }

body.clean .contact-form input,
body.clean .contact-form textarea,
body.clean .contact-form select { background: var(--white); }

@media (max-width: 700px) {
  body.clean section.block { padding: 2.5rem 1.5rem; }
  body.clean #hero.block.page-hero { padding-top: 8.5rem; padding-bottom: 3rem; }
}

/* ── SCROLL REVEAL ── */
.js .fade-in {
  opacity: 0;
  transform: translateY(24px) scale(0.97);
  transition: opacity 0.6s ease, transform 0.6s ease;
}
.js .fade-in.visible { opacity: 1; transform: translateY(0) scale(1); }

.js .reveal-item {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity 0.6s ease, transform 0.6s ease;
}

/* Reveal states only apply once the inline <head> script has added .js to
   <html>; without JS everything renders visible. */
/* --reveal-opacity lets each element reveal to ITS OWN resting opacity */
.js .fade-in.visible .reveal-item {
  opacity: var(--reveal-opacity, 1);
  transform: translateY(0);
}

.js .fade-in.visible .reveal-item.r1 { transition-delay: 0.28s; }
.js .fade-in.visible .reveal-item.r2 { transition-delay: 0.40s; }
.js .fade-in.visible .reveal-item.r3 { transition-delay: 0.52s; }
.js .fade-in.visible .reveal-item.r4 { transition-delay: 0.64s; }
.js .fade-in.visible .reveal-item.r5 { transition-delay: 0.76s; }
/* The reel is the likely LCP element: no stagger delay on it. */
.js .fade-in.visible #reelStage.reveal-item { transition-delay: 0s; }
/* Hero headline paints immediately (it is the first thing Google times). */
.js #hero h1.reveal-item { opacity: 1; transform: none; transition: none; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .fade-in, .reveal-item { opacity: 1 !important; transform: none !important; transition: none !important; }
  .polaroid-field { transform: none !important; }
}

/* ── MOBILE ── */
@media (max-width: 700px) {
  nav { padding: 1rem 1.25rem; flex-direction: row; justify-content: center; align-items: center; }
  nav.nav-hidden { opacity: 0; pointer-events: none; }
  .logo img { height: 1.6rem; }
  nav ul { display: none; }

  .nav-toggle {
    display: flex;
    -webkit-tap-highlight-color: transparent;
    position: absolute;
    left: 1.25rem;
    top: 50%;
    transform: translateY(-50%);
  }

  /* Always laid out; visibility + transform carry the animation. Toggling
     display would cancel the transition outright, which is what made the
     hamburger snap open instead of sliding. */
  .mobile-menu {
    display: flex;
    position: fixed;
    top: 0; left: 0; right: 0;
    z-index: 99;
    flex-direction: column;
    background: var(--white);
    padding: 5rem 1.5rem 1.1rem;
    border-radius: 0 0 var(--radius-lg) var(--radius-lg);
    transform: translateY(-100%);
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    box-shadow: var(--lift-3);
    transition: transform 0.42s var(--ease),
                opacity 0.3s var(--ease),
                visibility 0.42s;
    max-height: 100vh;
    max-height: 100dvh;   /* iOS: 100vh runs under the toolbar */
    overflow-y: auto;
    overscroll-behavior: contain;
  }
  .mobile-menu.open {
    transform: translateY(0);
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
  }

  /* Links cascade in behind the panel rather than arriving all at once. */
  .mobile-menu a, .mobile-menu .submenu-label {
    opacity: 0;
    transform: translateY(-6px);
    transition: opacity 0.3s var(--ease), transform 0.3s var(--ease);
  }
  .mobile-menu.open a, .mobile-menu.open .submenu-label {
    opacity: 1;
    transform: none;
  }
  .mobile-menu.open a:nth-child(1)  { transition-delay: 0.10s; }
  .mobile-menu.open a:nth-child(2)  { transition-delay: 0.14s; }
  .mobile-menu.open a:nth-child(3)  { transition-delay: 0.18s; }
  .mobile-menu.open a:nth-child(4)  { transition-delay: 0.22s; }
  .mobile-menu.open a:nth-child(5)  { transition-delay: 0.26s; }
  .mobile-menu.open a:nth-child(6)  { transition-delay: 0.30s; }
  .mobile-menu a {
    text-decoration: none;
    color: var(--charcoal);
    font-family: 'Montserrat', sans-serif;
    font-weight: 700;
    letter-spacing: 0.15em;
    text-transform: uppercase;
    font-size: 0.8rem;
    /* Rows run the full width of the menu, so a slightly shorter row is
       still easy to hit — ~39px here, down from ~48px. Much tighter than
       this and thumbs start catching the neighbouring link. */
    padding: 0.72rem 0;
    text-align: center;
  }
  
  #hero.block { padding-top: 8rem; min-height: auto; }
  #hero.block.page-hero { padding-top: 7.5rem; min-height: auto; }
  section.block { padding: 2.75rem 1.25rem; }
  .section-inner { padding: 1.85rem 1.35rem; border-radius: 14px; }
  .gallery-grid { grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 0.6rem; }
  .footer-nav { gap: 1.1rem; }
}

/* ═══════════════════════════════════════════════════════════════
   SERVICES: REEL + DICTIONARY DEFINITION
   Three states share one block — the reel opens the page, a
   definition of the chosen medium sits in the middle, and the work
   type detail is the answer. Each replaces the last in place.
   ═══════════════════════════════════════════════════════════════ */

.reel {
  position: relative;
  aspect-ratio: 16 / 9;
  width: 100%;
  margin: 0 auto 2.25rem;
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--charcoal);
  box-shadow: var(--lift-3);
}

.reel iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }

/* Soft vignette over the reel (the diagonal "screen mesh" lines were removed Oct 8). */
.reel::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  border-radius: inherit;
  background: radial-gradient(ellipse at 50% 45%, transparent 60%, rgba(0, 0, 0, 0.22) 100%);
}
.reel.is-playing::after { display: none; }

.reel-placeholder {
  position: absolute; inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1.1rem;
  background: linear-gradient(145deg, #34291f 0%, #221a13 100%);
  color: rgba(247, 245, 240, 0.5);
  font-size: 0.62rem;
  letter-spacing: 0.3em;
  text-transform: uppercase;
}

.reel-play {
  width: 58px; height: 58px;
  border-radius: 50%;
  background: rgba(212, 168, 67, 0.16);
  box-shadow: inset 0 0 0 1px rgba(212, 168, 67, 0.5);
  position: relative;
}
.reel-play::after {
  content: '';
  position: absolute;
  top: 50%; left: 54%;
  transform: translate(-50%, -50%);
  border-left: 15px solid var(--gold);
  border-top: 9px solid transparent;
  border-bottom: 9px solid transparent;
}

/* Click-to-play facade, filled in by functions/_lib/reel.js. Charcoal frame, gold play ring. */
.reel-facade { position: absolute; inset: 0; background: var(--charcoal); }
.reel-facade-btn {
  position: absolute; inset: 0; z-index: 3; width: 100%; height: 100%;
  display: block; padding: 0; border: 0; cursor: pointer;
  background: transparent; color: var(--off-white); font: inherit;
}
.reel-thumb { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.reel-video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; background: var(--charcoal); }
.reel-sound {
  position: absolute; right: 1rem; bottom: 1rem;
  display: inline-flex; align-items: center; gap: 0.55rem;
  padding: 0.55rem 0.9rem 0.55rem 0.75rem; border-radius: 999px;
  background: rgba(43, 43, 43, 0.62); box-shadow: inset 0 0 0 1.5px var(--gold);
  font-size: 0.64rem; letter-spacing: 0.2em; text-transform: uppercase;
  transition: background 0.25s var(--ease, ease), transform 0.25s var(--ease, ease);
}
.reel-sound::before {
  content: ""; width: 0; height: 0;
  border-left: 8px solid var(--gold); border-top: 5px solid transparent; border-bottom: 5px solid transparent;
}
.reel-facade-btn:hover .reel-sound, .reel-facade-btn:focus-visible .reel-sound { background: rgba(212, 168, 67, 0.28); transform: translateY(-1px); }
.reel-facade-btn:focus-visible { outline: 2px solid var(--gold); outline-offset: -4px; }
@media (prefers-reduced-motion: reduce) { .reel-sound { transition: none; } }
.reel-nojs { position: absolute; left: 1rem; bottom: 1rem; z-index: 3; color: var(--gold); font-size: 0.7rem; letter-spacing: 0.14em; text-transform: uppercase; }
@media (prefers-reduced-motion: reduce) { .reel-thumb, .reel-facade .reel-play { transition: none; } .reel-facade-btn:hover .reel-thumb { transform: none; } }

/* ── Dictionary entry ── */
/* Both entries occupy the SAME grid cell rather than one replacing the
   other in flow. The container then sizes to whichever is taller, so the
   card height never changes between photography and cinematography and
   nothing below it moves. It also makes the swap a true crossfade. */
/* :not([hidden]) matters: an ID selector outranks the UA stylesheet's
   `[hidden] { display: none }`, so without it the stage keeps its
   height after being unmounted and leaves a dead gap on the page. */
#introStage:not([hidden]) { display: grid; }

.definition {
  grid-area: 1 / 1;
  visibility: hidden;
  opacity: 0;
  pointer-events: none;
  text-align: left;
  max-width: 640px;
  margin: 2.25rem auto 0;
  padding: 1.6rem 1.8rem 1.7rem;
  background: var(--white);
  border-radius: var(--radius-lg);
  box-shadow: var(--bezel), var(--lift-2);
}

.definition.active {
  visibility: visible;
  opacity: 1;
  pointer-events: auto;
}

.def-head {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0.55rem;
  margin-bottom: 1.15rem;
  padding-bottom: 0.9rem;
  /* the one rule that earns its keep: a dictionary headword sits above a
     rule, and it's inside a card rather than separating two sections */
  box-shadow: 0 1px 0 rgba(43, 43, 43, 0.09);
}

.def-word {
  font-family: 'Montserrat', sans-serif;
  font-weight: 800;
  font-size: 1.5rem;
  letter-spacing: -0.01em;
  color: var(--charcoal);
}

.def-phonetic {
  font-family: 'IBM Plex Mono', monospace;
  font-size: 0.68rem;
  letter-spacing: 0.04em;
  color: var(--gold-ink);
}

.def-pos {
  font-family: 'Cormorant Garamond', serif;
  font-style: italic;
  font-weight: 300;
  font-size: 1rem;
  opacity: 0.5;
}

.def-senses { list-style: none; display: grid; gap: 1.15rem; }

.def-senses li { display: flex; gap: 0.75rem; }

.def-num {
  font-family: 'Cormorant Garamond', serif;
  font-style: italic;
  font-size: 0.95rem;
  color: var(--gold-ink);
  flex: 0 0 auto;
  line-height: 1.78;   /* matches .def-text so numerals sit on the first line */
}

.def-text { font-size: 0.82rem; line-height: 1.78; opacity: 0.84; }
.def-text em { font-style: italic; opacity: 0.9; }

.def-lead {
  font-family: 'Montserrat', sans-serif;
  font-weight: 700;
  font-size: 0.64rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--charcoal);
  opacity: 0.85;
  margin-right: 0.15rem;
}

@media (max-width: 700px) {
  .reel { margin-bottom: 1.5rem; }
  .definition { padding: 1.35rem 1.25rem; }
  .def-word { font-size: 1.2rem; }
}

/* ═══════════════════════════════════════════════════════════════
   MOTION
   Anything that appears or disappears gets a transition. `hidden`
   and `display` can't be animated, so stages are faded first and
   only unmounted once they're invisible.
   ═══════════════════════════════════════════════════════════════ */

#reelStage[hidden], #introStage[hidden], #offerStage[hidden] { display: none; }

#reelStage, #introStage, #offerStage {
  opacity: 0;
  transform: translateY(12px);
  transition: opacity 0.34s var(--ease-soft), transform 0.44s var(--ease-soft);
}

/* Only while the script is driving a height change. It clips, so the
   content is consumed by the shrinking box rather than spilling out of it,
   and it carries the height transition — which is deliberately a touch
   longer than the fade, so the box is still settling as the new content
   arrives instead of stopping dead underneath it. The class comes off once
   the move lands, handing the stage back to `height: auto` so it still
   reflows on resize and late font loads. */
#reelStage.is-sizing, #introStage.is-sizing, #offerStage.is-sizing {
  /* Clip vertically only. `hidden` would clip the full-bleed carousel to the
     column width mid-animation and then let it pop out to the edges. */
  overflow-x: visible;
  overflow-y: clip;
  /* --h-dur is set per move by the script: a 1000px collapse and a 300px
     one at the same duration would travel at wildly different speeds, and
     the fast one is what reads as a lurch. Scaling time with distance keeps
     every move at roughly the same rate. */
  transition: opacity 0.34s var(--ease-soft), transform 0.44s var(--ease-soft),
              height var(--h-dur, 0.46s) var(--ease-soft),
              margin-top var(--h-dur, 0.46s) var(--ease-soft);
}

#reelStage.is-in, #introStage.is-in, #offerStage.is-in {
  opacity: 1;
  transform: none;
}

/* The hint line fades rather than blinking out. */
.picker-hint {
  transition: opacity 0.3s var(--ease), max-height 0.34s var(--ease), margin-top 0.34s var(--ease);
  overflow: hidden;
  max-height: 3rem;
}
.picker-hint.is-out { opacity: 0; max-height: 0; margin-top: 0; }

/* Definitions crossfade in place — see the grid stack above. */
.definition { transition: opacity 0.32s var(--ease), visibility 0.32s; }

/* ── FAQ accordion ──
   <details> opens instantly by default. The wrapper animates its own
   height so the answer unrolls instead of appearing. */
.faq-body {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 0.34s var(--ease), opacity 0.26s var(--ease);
  opacity: 0;
}
/* Driven by a class, NOT by [open]: a closed <details> doesn't render its
   children at all, so flipping `open` gives the transition no previous
   value to animate from and it snaps. The script sets `open` first, then
   adds this a frame later, once there's something to animate. */
.faq-item.is-open .faq-body { grid-template-rows: 1fr; opacity: 1; }
.faq-body > div { overflow: hidden; }

.faq-item summary { transition: opacity 0.25s var(--ease), color 0.25s var(--ease); }

/* ── Images ──
   Photos fade up as they decode rather than popping in. */
.polaroid .photo { transition: opacity 0.6s var(--ease); }
.gallery-item img { opacity: 0; transition: opacity 0.5s var(--ease), transform 0.35s var(--ease); }
.gallery-item img.loaded { opacity: 1; }

/* ── Nav ── */
nav ul a, .footer-nav a { transition: opacity 0.25s var(--ease), color 0.25s var(--ease), border-color 0.25s var(--ease); }
.nav-toggle span { transition: transform 0.35s var(--ease), opacity 0.25s var(--ease); }

@media (prefers-reduced-motion: reduce) {
  #reelStage, #introStage, #offerStage,
  #reelStage.is-sizing, #introStage.is-sizing, #offerStage.is-sizing,
  .faq-body, .picker-hint, .gallery-item img, .polaroid .photo {
    transition: none !important;
  }
  #reelStage, #introStage, #offerStage { opacity: 1; transform: none; }
}

/* Closing state for the FAQ: the JS holds `open` until this finishes. */


/* Quote form sits inside the drill-down, so it echoes the selection back. */
.quote-for {
  font-size: 0.68rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  opacity: 0.6;
  margin-bottom: 0.3rem;
}
.quote-for strong { color: var(--gold-ink); font-weight: 500; }

/* ═══════════════════════════════════════════════════════════════
   SERVICES: WORK CAROUSELS
   A looping filmstrip. Fixed height; each slide takes its width from its
   own aspect ratio (set inline from the manifest), so nothing is cropped.
   The strip runs the full width of the window with soft edges, and every
   photo snaps to the centre — there's no start or end to line up with.

   Each block holds one strip per medium (definition view) or per medium +
   work type (detail view), stacked in the same grid cell. The script marks
   the matching one .is-active and it crossfades in; the others stay laid
   out but invisible, so switching never changes the block's height.
   ═══════════════════════════════════════════════════════════════ */
.work { margin-top: 2.5rem; text-align: center; }
#introStage > .work { grid-column: 1 / -1; }
#offerStage > .work { margin: 2.75rem 0 0.5rem; }
.work[hidden], .work.is-empty { display: none; }

.carousel {
  display: grid;
  width: 100vw;
  margin: 1rem 0 0 calc(50% - 50vw);
}

.carousel-track {
  grid-area: 1 / 1;
  position: relative;          /* offsetLeft is measured from here */
  display: flex;
  gap: 12px;
  height: clamp(190px, 22vw, 290px);
  padding: 8px 0 22px;         /* room above and below for the shadows */
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x mandatory;
  scroll-behavior: auto;       /* the loop's silent jump must be instant */
  overscroll-behavior-x: contain;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
  -webkit-mask-image: linear-gradient(to right, transparent 0, #000 7%, #000 93%, transparent 100%);
          mask-image: linear-gradient(to right, transparent 0, #000 7%, #000 93%, transparent 100%);
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.45s var(--ease-soft), visibility 0s linear 0.45s;
}
.carousel-track.is-active {
  opacity: 1;
  visibility: visible;
  transition: opacity 0.45s var(--ease-soft), visibility 0s;
}
.carousel-track::-webkit-scrollbar { display: none; }
.carousel-track:focus { outline: none; }

.carousel-slide {
  flex: 0 0 auto;
  height: 100%;
  margin: 0;
  scroll-snap-align: center;
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--light-gray);
  box-shadow: var(--lift-2);
}
/* The slot already has the photo's exact shape, so cover crops nothing —
   it only guards against a sub-pixel gap from rounding. */
.carousel-slide img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity 0.5s var(--ease);
}
.carousel-slide img.loaded { opacity: 1; }

.carousel-controls {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 14px;
  margin-top: 0.15rem;
}
.carousel-count {
  min-width: 5.2em;
  text-align: center;
  font-size: 0.62rem;
  letter-spacing: 0.2em;
  color: rgba(43, 43, 43, 0.55);
  font-variant-numeric: tabular-nums;
}
.carousel-btn {
  width: 40px;
  height: 40px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: 50%;
  background: var(--white);
  color: var(--charcoal);
  cursor: pointer;
  box-shadow: var(--bezel), var(--lift-1);
  transition: transform 0.25s var(--ease), box-shadow 0.25s var(--ease);
}
.carousel-btn[hidden] { display: none; }
.carousel-btn svg { width: 17px; height: 17px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.carousel-btn:hover { transform: translateY(-2px); box-shadow: var(--bezel), var(--lift-2); }
.carousel-btn:active { transform: translateY(0); box-shadow: var(--press); }

@media (max-width: 640px) {
  .carousel-track { gap: 9px; }
  .carousel-btn { width: 38px; height: 38px; }
}
@media (prefers-reduced-motion: reduce) {
  .carousel-track, .carousel-slide img, .carousel-btn { transition: none; }
}

/* ═══════════════════════════════════════════════════════════════
   CAROUSEL: SHORT SETS
   .is-still — the whole set fits on screen: one copy, centred, no
   scrolling, no arrows. .is-short — one or two photos that don't fit:
   no loop, and the spacers let the first and last still reach centre.
   ═══════════════════════════════════════════════════════════════ */
.carousel-spacer { display: none; flex: 0 0 auto; }
.carousel-track.is-short .carousel-spacer { display: block; }
.carousel-track.is-still {
  justify-content: center;
  overflow-x: hidden;
  scroll-snap-type: none;
  -webkit-mask-image: none;
          mask-image: none;
}
.carousel-track.is-still > .is-copy,
.carousel-track.is-still > .carousel-spacer { display: none; }
.carousel-controls[hidden] { display: none; }

/* ═══════════════════════════════════════════════════════════════
   SCROLL-LINKED PARALLAX
   Where supported, the wall's drift is a scroll-driven animation (see
   site.js) instead of a script updating it every frame.
   ═══════════════════════════════════════════════════════════════ */
@keyframes em-parallax {
  from { transform: translateY(0); }
  to   { transform: translateY(var(--parallax-shift, 0px)); }
}
.polaroid-field.is-scroll-linked {
  animation: em-parallax linear both;
  animation-timeline: scroll(root block);
}

/* ═══════════════════════════════════════════════════════════════
   PHONES: PERFORMANCE + TOUCH
   ═══════════════════════════════════════════════════════════════ */
@media (max-width: 700px) {
  /* Re-blurring the moving wall behind the whole page every frame was the
     main cause of dropped frames while scrolling on phones. The veil
     thickens a touch to make up for the missing blur. */
  .glass-shell {
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    background: rgba(247, 245, 240, 0.24);
  }

}

/* Touch screens of any width (phones sideways, tablets): the small text
   links keep their look but get finger-sized hit areas. */
@media (max-width: 700px), (pointer: coarse) {
  .footer-nav { row-gap: 0.25rem; }
  .footer-nav a { display: inline-block; padding: 0.95rem 0.3rem; margin: -0.6rem -0.3rem; }
  .footer-meta a { display: inline-block; padding: 0.7rem 0.4rem; margin: -0.7rem -0.4rem; }
  footer .logo { padding: 0.5rem; margin: -0.5rem; }
  nav ul a, .contact-direct a { position: relative; }
  nav ul a::after, .contact-direct a::after { content: ''; position: absolute; inset: -14px -10px; }
}

/* Portrait screens only ever see a narrow slice of the wall, so they get a
   centre crop at full resolution instead of the whole wide photo. */
@media (max-aspect-ratio: 3/4) {
  .oak-surface { background-image: url('/assets/slat-wall-portrait.jpg'); }
}

/* Long single words ("CINEMATOGRAPHY") ran past the panel edge on phones
   up to ~400px wide. Scale titles with the screen below that. */
@media (max-width: 440px) {
  .section-title { font-size: clamp(1.4rem, 7vw, 1.9rem); }
}

/* iOS zooms the page into any field whose text is under 16px. */
@supports (-webkit-touch-callout: none) {
  .contact-form input,
  .contact-form textarea,
  .contact-form select { font-size: 16px; }
  .contact-form select { letter-spacing: 0.06em; }
}

/* ═══════════════════════════════════════════════════════════════
   ABOUT: RECENT STORIES
   Cards drawn by site.js from assets/stories.json. Phones get the
   cards only; desktop cards open the set as a contact sheet.
   ═══════════════════════════════════════════════════════════════ */
.stories {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1.75rem;
  margin-top: 2rem;
  text-align: left;
}
.story {
  background: var(--white);
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--lift-2);
  display: flex;
  flex-direction: column;
  transition: transform 0.35s var(--ease), box-shadow 0.35s var(--ease);
}
.story-lead { aspect-ratio: 16 / 10; overflow: hidden; background: var(--light-gray); }
.story-lead img,
.story-thumbs img { display: block; width: 100%; height: 100%; object-fit: cover; }
.story-thumbs { display: grid; grid-template-columns: repeat(3, 1fr); gap: 4px; padding: 4px 4px 0; }
.story-thumbs img { aspect-ratio: 4 / 3; height: auto; border-radius: 4px; background: var(--light-gray); }
.story-lead img, .story-thumbs img { opacity: 0; transition: opacity 0.5s var(--ease), transform 0.6s var(--ease); }
.story-lead img.loaded, .story-thumbs img.loaded { opacity: 1; }
.story-copy { padding: 1.2rem 1.4rem 1.4rem; display: flex; flex-direction: column; flex: 1; }
.story-meta {
  font-family: 'IBM Plex Mono', monospace;
  font-size: 0.6rem; letter-spacing: 0.2em; text-transform: uppercase;
  color: var(--gold-ink); margin: 0 0 0.35rem;
}
.story-copy h3 {
  font-family: 'Montserrat', sans-serif; font-weight: 800; text-transform: uppercase;
  font-size: 1.15rem; line-height: 1.2; margin: 0 0 0.45rem; color: var(--charcoal);
}
.story-blurb {
  font-family: 'IBM Plex Mono', monospace; font-size: 0.78rem; line-height: 1.7;
  color: rgba(43, 43, 43, 0.8); margin: 0 0 0.9rem;
}
.story-open {
  align-self: flex-start; margin-top: auto;
  display: inline-flex; align-items: baseline; gap: 0.5rem;
  font-family: 'IBM Plex Mono', monospace; font-size: 0.68rem; letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--charcoal); background: none; border: 0; padding: 0 0 2px; cursor: pointer;
  border-bottom: 1px solid var(--gold);
}
.story-count { letter-spacing: 0.1em; color: rgba(43, 43, 43, 0.5); }
@media (hover: hover) and (min-width: 701px) {
  .story { cursor: pointer; }
  .story:hover { transform: translateY(-3px); box-shadow: var(--lift-3); }
  .story:hover .story-lead img { transform: scale(1.03); }
  .story-open:hover { color: var(--gold-ink); }
}
@media (max-width: 700px) {
  .stories { grid-template-columns: 1fr; gap: 1.35rem; margin-top: 1.5rem; }
  .story-open { display: none; }          /* phones: the cards are the gallery */
  .story-copy { padding: 1.05rem 1.15rem 1.2rem; }
}

/* ── Contact sheet ── */
html.sheet-open { overflow: hidden; }
.sheet {
  width: min(1180px, calc(100vw - 4rem));
  max-height: calc(100vh - 4rem);
  margin: auto;
  padding: 0;
  border: 0;
  border-radius: var(--radius-lg);
  background: var(--off-white);
  color: var(--charcoal);
  box-shadow: 0 30px 80px rgba(0, 0, 0, 0.35);
  overflow: hidden;
  flex-direction: column;
}
.sheet[open] { display: flex; animation: sheet-in 0.35s var(--ease) both; }
.sheet::backdrop { background: rgba(24, 22, 20, 0.62); backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px); }
@keyframes sheet-in { from { opacity: 0; transform: translateY(14px) scale(0.985); } }
.sheet-head {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  padding: 1.25rem 1.5rem 1rem;
  border-bottom: 1px solid rgba(43, 43, 43, 0.08);
}
.sheet-meta {
  font-family: 'IBM Plex Mono', monospace; font-size: 0.6rem; letter-spacing: 0.2em;
  text-transform: uppercase; color: var(--gold-ink); margin: 0 0 0.25rem;
}
.sheet-head h3 { font-family: 'Montserrat', sans-serif; font-weight: 800; text-transform: uppercase; font-size: 1.3rem; margin: 0; }
.sheet-close, .sheet-nav {
  width: 42px; height: 42px; flex: 0 0 auto;
  display: inline-flex; align-items: center; justify-content: center;
  border: 0; border-radius: 50%; background: var(--white); color: var(--charcoal); cursor: pointer;
  box-shadow: var(--bezel), var(--lift-1);
  transition: transform 0.25s var(--ease), box-shadow 0.25s var(--ease);
}
.sheet-close:hover, .sheet-nav:hover { transform: translateY(-2px); box-shadow: var(--bezel), var(--lift-2); }
.sheet-close svg, .sheet-nav svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }

/* Justified rows: each frame grows in proportion to its shape, so every
   row comes out level and nothing is cropped. The filler keeps a short
   last row from stretching. */
.sheet-grid {
  display: flex; flex-wrap: wrap; gap: 10px;
  padding: 1.25rem 1.5rem 1.6rem;
  overflow-y: auto;
  overscroll-behavior: contain;
}
.sheet-grid[hidden], .sheet-view[hidden] { display: none; }
.sheet-grid::after { content: ''; flex: 10 1 0; }
.sheet-grid figure {
  flex: var(--ar) 1 calc(var(--ar) * 210px);
  min-width: 0; margin: 0;
  background: #1b1b1b; padding: 6px 6px 0; border-radius: 3px;
  box-shadow: var(--lift-1); cursor: zoom-in;
  transition: transform 0.25s var(--ease), box-shadow 0.25s var(--ease);
}
.sheet-grid figure:hover, .sheet-grid figure:focus-visible { transform: translateY(-2px); box-shadow: var(--lift-2); outline: none; }
.sheet-grid figure:focus-visible { box-shadow: 0 0 0 2px var(--gold), var(--lift-2); }
.sheet-grid img { display: block; width: 100%; height: auto; aspect-ratio: var(--ar); object-fit: cover; background: #2a2a2a; opacity: 0; transition: opacity 0.4s var(--ease); }
.sheet-grid img.loaded { opacity: 1; }
.sheet-grid figcaption, .sheet-view figcaption {
  display: flex; justify-content: space-between; gap: 0.75rem;
  font-family: 'IBM Plex Mono', monospace; font-size: 0.56rem; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--gold); padding: 0.4rem 0.15rem 0.45rem; white-space: nowrap;
}
.sheet-grid figcaption span + span, .sheet-view figcaption span + span { color: #bbb; }

/* One frame, large. */
.sheet-view {
  position: relative;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 1rem;
  padding: 1.25rem 1.25rem 1.1rem;
  min-height: 0;
}
.sheet-view figure { margin: 0; background: #1b1b1b; padding: 8px 8px 0; border-radius: 4px; justify-self: center; max-width: 100%; }
.sheet-view img { display: block; max-width: 100%; max-height: calc(100vh - 15rem); width: auto; height: auto; margin: 0 auto; }
.sheet-view .sv-pos { color: var(--gold) !important; }
.sheet-back {
  grid-column: 1 / -1; justify-self: center;
  font-family: 'IBM Plex Mono', monospace; font-size: 0.66rem; letter-spacing: 0.16em; text-transform: uppercase;
  background: none; border: 0; border-bottom: 1px solid var(--gold); padding: 0 0 2px; cursor: pointer; color: var(--charcoal);
}
@media (prefers-reduced-motion: reduce) {
  .sheet[open] { animation: none; }
  .story, .story-lead img, .sheet-grid figure { transition: none; }
}

/* ── Recent Stories: phone viewer ──
   Arrows + swipe on the lead photo step through the whole set; the
   thumbs become a strip of every frame. Desktop keeps lead + 3 thumbs. */
.story-step, .story-pos { display: none; }
.story-thumb { display: block; padding: 0; border: 0; background: none; cursor: inherit; border-radius: 4px; overflow: hidden; }
.story-thumb.is-first, .story-thumb.is-extra { display: none; }
@media (max-width: 700px) {
  .story-lead { position: relative; background: #1b1b1b; }
  .story-lead img { object-fit: contain; transition: opacity 0.12s linear; }
  .story-step {
    position: absolute; top: 50%; transform: translateY(-50%);
    width: 38px; height: 38px; border: 0; border-radius: 50%;
    display: inline-flex; align-items: center; justify-content: center;
    background: rgba(255, 255, 255, 0.9); color: var(--charcoal);
    box-shadow: var(--lift-1); -webkit-tap-highlight-color: transparent;
  }
  .story-step::before { content: ''; position: absolute; inset: -6px; }   /* 50px tap target */
  .story-step:active { transform: translateY(-50%) scale(0.94); }
  .story-step[data-step="-1"] { left: 10px; }
  .story-step[data-step="1"] { right: 10px; }
  .story-step svg { width: 17px; height: 17px; fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
  .story-pos {
    display: block; position: absolute; right: 10px; bottom: 10px;
    font-family: 'IBM Plex Mono', monospace; font-size: 0.6rem; letter-spacing: 0.14em;
    color: #fff; background: rgba(20, 20, 20, 0.55); padding: 0.3rem 0.55rem; border-radius: 999px;
    font-variant-numeric: tabular-nums;
  }
  .story-thumbs {
    display: flex; gap: 5px; overflow-x: auto; padding: 5px;
    scrollbar-width: none; overscroll-behavior-x: contain; scroll-snap-type: x proximity;
  }
  .story-thumbs::-webkit-scrollbar { display: none; }
  .story-thumb, .story-thumb.is-first, .story-thumb.is-extra {
    display: block; flex: 0 0 auto; width: 64px; height: 48px; scroll-snap-align: center;
    opacity: 0.55; transition: opacity 0.2s var(--ease), box-shadow 0.2s var(--ease);
  }
  .story-thumb.is-current { opacity: 1; box-shadow: 0 0 0 2px var(--gold); }
  .story-thumb img { width: 100%; height: 100%; aspect-ratio: auto; border-radius: 4px; }
}

/* ── Contact forms: honeypot + status ── */
.form-hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
.contact-form { position: relative; }
.contact-form button[disabled] { opacity: 0.7; cursor: default; }
.contact-form.is-sent input, .contact-form.is-sent textarea, .contact-form.is-sent select { opacity: 0.6; }
.form-status {
  margin: 0.25rem 0 0;
  padding: 0.9rem 1.1rem;
  border-radius: var(--radius-sm);
  font-family: 'IBM Plex Mono', monospace;
  font-size: 0.78rem;
  line-height: 1.6;
  text-align: left;
}
.form-status[hidden] { display: none; }
.form-status.is-ok { background: rgba(212, 168, 67, 0.14); color: var(--charcoal); box-shadow: inset 0 0 0 1px rgba(212, 168, 67, 0.45); }
.form-status.is-error { background: rgba(180, 60, 40, 0.08); color: #7a2a1c; box-shadow: inset 0 0 0 1px rgba(180, 60, 40, 0.3); }
.form-status a { color: inherit; }

/* Testimonials (Google reviews) */
section.testimonials { background: var(--band); }
.quote-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 1.5rem; margin-top: 2rem; }
.quote-card, .pull-quote {
  margin: 0; background: var(--white);
  border: 1px solid rgba(43, 43, 43, 0.12); border-top: 2px solid var(--gold);
  border-radius: 6px; padding: 1.6rem 1.6rem 1.4rem;
}
.quote-card blockquote, .pull-quote blockquote { margin: 0; }
.quote-card blockquote p, .pull-quote blockquote p {
  font-family: 'Cormorant Garamond', serif; font-style: italic; font-weight: 400;
  font-size: 1.3rem; line-height: 1.5; color: var(--charcoal); margin: 0;
}
.quote-card figcaption, .pull-quote figcaption {
  margin-top: 1rem; font-size: 0.72rem; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--gold-ink);
}
.pull-quote { margin-top: 1.6rem; }
.quote-meta { margin-top: 1.75rem; font-size: 0.85rem; color: var(--charcoal); opacity: 0.85; }
.quote-meta a { color: var(--gold-ink); text-decoration: none; border-bottom: 1px solid var(--gold); }
.quote-stars { color: var(--gold); letter-spacing: 0.12em; }
@media (max-width: 720px) { .quote-grid { grid-template-columns: 1fr; } }
