/* ============================================================
   NOCTIS STUDIO — Cinematic Photography Atelier
   Dark Premium / gallery-in-the-dark
   Mobile-first · breakpoints: 768px, 1100px
   ============================================================ */

:root {
  --black: #0B0B0D;
  --white: #EDEDEA;
  --silver: #7D7F85;
  --red: #E0342C;
  /* Deeper shade of the same signal red — used only where white type sits
     on a red fill, so the label clears 4.5:1 (4.95:1 measured). */
  --red-deep: #C4241D;
  /* The mirror of --red-deep: a brighter shade of the same signal red, used
     only where the red is TYPE on the near-black frame ground, where the brand
     red measures 4.25:1. 4.64:1. */
  --red-lift: #E73E34;
  --black-lift: #101014;
  --line: rgba(237, 237, 234, 0.14);
  --line-soft: rgba(237, 237, 234, 0.08);
  --font-display: 'Marcellus', serif;
  --font-body: 'Figtree', sans-serif;
  --pad: clamp(1.25rem, 5vw, 4.5rem);
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-wipe: cubic-bezier(0.65, 0.05, 0.36, 1);
}

/* ---------- Reset & base ---------- */

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

html {
  scroll-padding-top: 6rem;
}

@media (prefers-reduced-motion: no-preference) {
  html {
    scroll-behavior: smooth;
  }
}

/* The anchor handler parks focus on the destination section so the next Tab
   carries on from there (script.js §4). A section is not an operable control,
   so the browser's default ring — a blue rectangle drawn round a whole band on
   an otherwise monochrome page — is noise rather than a focus cue. Scoped to
   the scroll targets alone; every control inside them keeps its own ring. */
body[tabindex="-1"]:focus,
main > section[tabindex="-1"]:focus {
  outline: none;
}

body {
  background: var(--black);
  color: var(--white);
  font-family: var(--font-body);
  font-weight: 300;
  font-size: 1rem;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

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

a {
  color: inherit;
  text-decoration: none;
}

ul,
ol {
  list-style: none;
}

button {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  cursor: pointer;
}

address {
  font-style: normal;
}

::selection {
  background: var(--red);
  color: var(--white);
}

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

/* ---------- Film grain overlay ---------- */

.grain {
  position: fixed;
  inset: 0;
  z-index: 110;
  pointer-events: none;
  opacity: 0.055;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='240'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.82' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size: 240px 240px;
}

/* ---------- Custom cursor ---------- */

.cursor {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 120;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--white);
  mix-blend-mode: difference;
  pointer-events: none;
  transform: translate(-50%, -50%);
  transition: width 0.28s var(--ease-out), height 0.28s var(--ease-out), opacity 0.2s ease;
  opacity: 0;
  display: none;
}

body.cursor-on .cursor {
  display: block;
}

.cursor.is-visible {
  opacity: 1;
}

.cursor.is-big {
  width: 46px;
  height: 46px;
}

body.cursor-on,
body.cursor-on a,
body.cursor-on button,
body.cursor-on input,
body.cursor-on select,
body.cursor-on textarea,
body.cursor-on label {
  cursor: none;
}

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

.kicker {
  font-family: var(--font-body);
  font-weight: 500;
  font-size: 0.68rem;
  letter-spacing: 0.34em;
  text-transform: uppercase;
  color: var(--silver);
  margin-bottom: 1.1rem;
}

.section-title {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(1.9rem, 4.6vw, 3.4rem);
  line-height: 1.12;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  margin-bottom: 1.25rem;
}

.container {
  max-width: 1320px;
  margin-inline: auto;
  padding-inline: var(--pad);
}

/* Vertical side labels */
.side-label {
  display: none;
}

@media (min-width: 1100px) {
  .side-label {
    display: block;
    position: absolute;
    top: 50%;
    right: 1.35rem;
    transform: translateY(-50%);
    writing-mode: vertical-rl;
    font-size: 0.62rem;
    font-weight: 400;
    letter-spacing: 0.42em;
    text-transform: uppercase;
    color: var(--silver);
    white-space: nowrap;
    z-index: 3;
  }

  /* Hero label aligns to the headline baseline instead of floating mid-plate,
     and takes the off-white so it clears the lit sweep behind it. */
  .side-label-hero {
    top: auto;
    bottom: clamp(6.5rem, 16vh, 9.5rem);
    transform: none;
    color: var(--white);
  }
}

/* Red underline draw */
.u-draw {
  position: relative;
  display: inline-block;
}

.u-draw::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: -0.28em;
  width: 100%;
  height: 1px;
  background: var(--red);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 0.5s var(--ease-out);
}

.nav-link,
.foot-link,
.text-link {
  position: relative;
}

.nav-link::after,
.foot-link::after,
.text-link::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: -0.22em;
  width: 100%;
  height: 1px;
  background: var(--red);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 0.45s var(--ease-out);
}

.nav-link:hover::after,
.nav-link:focus-visible::after,
.foot-link:hover::after,
.foot-link:focus-visible::after,
.text-link:hover::after,
.text-link:focus-visible::after {
  transform: scaleX(1);
}

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

.btn {
  display: inline-block;
  font-family: var(--font-body);
  font-weight: 400;
  font-size: 0.72rem;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  padding: 0.95rem 1.7rem;
  border: 1px solid var(--line);
  transition: background 0.35s ease, color 0.35s ease, border-color 0.35s ease;
}

.btn-line:hover,
.btn-line:focus-visible {
  background: var(--white);
  color: var(--black);
  border-color: var(--white);
}

.btn-ghost {
  border-color: transparent;
  color: var(--silver);
}

.btn-ghost:hover,
.btn-ghost:focus-visible {
  color: var(--white);
  border-color: var(--line);
}

.btn-solid {
  background: var(--white);
  color: var(--black);
  border-color: var(--white);
}

.btn-solid:hover,
.btn-solid:focus-visible {
  background: var(--red-deep);
  border-color: var(--red-deep);
  color: var(--white);
}

.btn:disabled {
  opacity: 0.45;
  cursor: not-allowed;
  pointer-events: none;
}

/* ============================================================
   HEADER / NAV
   ============================================================ */

.site-head {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 80;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 1.1rem var(--pad);
  transition: background 0.4s ease, border-color 0.4s ease, padding 0.4s ease;
  border-bottom: 1px solid transparent;
}

.site-head.scrolled {
  background: rgba(11, 11, 13, 0.86);
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
  border-bottom-color: var(--line-soft);
  padding-block: 0.8rem;
}

.brand {
  display: flex;
  align-items: baseline;
  gap: 0.55rem;
  z-index: 90;
}

.brand-name {
  font-family: var(--font-display);
  font-size: 1.22rem;
  letter-spacing: 0.3em;
  text-transform: uppercase;
}

.brand-sub {
  font-size: 0.6rem;
  font-weight: 400;
  letter-spacing: 0.42em;
  text-transform: uppercase;
  color: var(--silver);
}

.head-cta {
  display: none;
}

/* Tablet keeps a visible booking CTA — the desktop nav only arrives at 1100px */
@media (min-width: 768px) and (max-width: 1099px) {
  .head-cta {
    display: inline-block;
    font-size: 0.68rem;
    letter-spacing: 0.26em;
    text-transform: uppercase;
    border: 1px solid var(--line);
    padding: 0.6rem 1.1rem;
    margin-left: auto;
    margin-right: 1.4rem;
    transition: background 0.35s ease, color 0.35s ease, border-color 0.35s ease;
  }

  .head-cta:hover,
  .head-cta:focus-visible {
    background: var(--white);
    color: var(--black);
    border-color: var(--white);
  }
}

/* Mobile nav overlay */
.nav {
  position: fixed;
  inset: 0;
  z-index: 85;
  background: rgba(11, 11, 13, 0.97);
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: var(--pad);
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.45s ease, visibility 0.45s ease;
}

body.menu-open .nav {
  opacity: 1;
  visibility: visible;
}

.nav-list {
  display: flex;
  flex-direction: column;
  gap: 1.4rem;
  counter-reset: navitem;
}

.nav-link {
  font-family: var(--font-display);
  font-size: clamp(1.7rem, 7vw, 2.6rem);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  line-height: 1;
  display: inline-block;
  transform: translateY(18px);
  opacity: 0;
  transition: transform 0.55s var(--ease-out), opacity 0.55s ease;
  counter-increment: navitem;
}

.nav-link::before {
  content: "0" counter(navitem);
  font-family: var(--font-body);
  font-size: 0.62rem;
  font-weight: 400;
  letter-spacing: 0.3em;
  color: var(--silver);
  margin-right: 1rem;
  vertical-align: 0.9em;
}

body.menu-open .nav-link {
  transform: translateY(0);
  opacity: 1;
}

body.menu-open .nav-list li:nth-child(1) .nav-link { transition-delay: 0.06s; }
body.menu-open .nav-list li:nth-child(2) .nav-link { transition-delay: 0.11s; }
body.menu-open .nav-list li:nth-child(3) .nav-link { transition-delay: 0.16s; }
body.menu-open .nav-list li:nth-child(4) .nav-link { transition-delay: 0.21s; }
body.menu-open .nav-list li:nth-child(5) .nav-link { transition-delay: 0.26s; }
body.menu-open .nav-list li:nth-child(6) .nav-link { transition-delay: 0.31s; }

.nav-link-cta::before {
  content: "0" counter(navitem);
  color: var(--red);
}

.nav-foot {
  position: absolute;
  bottom: 2rem;
  left: var(--pad);
  right: var(--pad);
  font-size: 0.64rem;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--silver);
}

/* Hamburger */
.menu-btn {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  z-index: 90;
  padding: 0.4rem 0;
}

.menu-btn-label {
  font-size: 0.64rem;
  font-weight: 500;
  letter-spacing: 0.34em;
  text-transform: uppercase;
  color: var(--silver);
  transition: color 0.3s ease;
}

.menu-btn:hover .menu-btn-label {
  color: var(--white);
}

.menu-btn-lines {
  display: flex;
  flex-direction: column;
  gap: 6px;
  width: 26px;
}

.menu-btn-lines i {
  display: block;
  height: 1px;
  background: var(--white);
  transition: transform 0.4s var(--ease-out), width 0.4s var(--ease-out);
}

.menu-btn-lines i:last-child {
  width: 70%;
  align-self: flex-end;
}

body.menu-open .menu-btn-lines i:first-child {
  transform: translateY(3.5px) rotate(45deg);
}

body.menu-open .menu-btn-lines i:last-child {
  width: 100%;
  transform: translateY(-3.5px) rotate(-45deg);
}

/* Desktop nav */
@media (min-width: 1100px) {
  .menu-btn {
    display: none;
  }

  .nav {
    position: static;
    inset: auto;
    background: none;
    padding: 0;
    opacity: 1;
    visibility: visible;
    flex-direction: row;
    transition: none;
  }

  .nav-foot {
    display: none;
  }

  .nav-list {
    flex-direction: row;
    align-items: center;
    gap: 2.2rem;
  }

  .nav-link {
    font-family: var(--font-body);
    font-weight: 400;
    font-size: 0.7rem;
    letter-spacing: 0.28em;
    transform: none;
    opacity: 1;
    transition: color 0.3s ease;
    color: var(--silver);
  }

  .nav-link:hover,
  .nav-link:focus-visible {
    color: var(--white);
  }

  .nav-link::before {
    display: none;
  }

  .nav-link-cta {
    color: var(--white);
    border: 1px solid var(--line);
    padding: 0.65rem 1.2rem;
    transition: background 0.35s ease, color 0.35s ease, border-color 0.35s ease;
  }

  .nav-link-cta::after {
    display: none;
  }

  .nav-link-cta:hover,
  .nav-link-cta:focus-visible {
    background: var(--white);
    color: var(--black);
    border-color: var(--white);
  }
}

/* ============================================================
   HERO
   ============================================================ */

.hero {
  position: relative;
  min-height: 100vh;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  overflow: hidden;
  isolation: isolate;
}

.hero-media {
  position: absolute;
  inset: 0;
  z-index: -2;
  background: var(--black-lift);
}

/* The hero plate carries hard specular highlights (lantern bokeh), so it is
   printed down to a graded dark plate before the scrim goes over it —
   otherwise grayscale(1) contrast(1.1) pushes those blooms to 255. */
.hero-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: grayscale(1) contrast(1.1);
  opacity: 0.58;
  transform: scale(1.12);
  will-change: transform;
  background: var(--black-lift);
}

/* Never drops below .76 anywhere the type sits: over the plate's brightest
   (blown-white) region the headline band still composites to ~gray 45, so
   #EDEDEA reads 11.7:1; the wordmark band holds ~15:1. */
.hero-shade {
  position: absolute;
  inset: 0;
  z-index: -1;
  background:
    linear-gradient(180deg, rgba(11, 11, 13, 0.93) 0%, rgba(11, 11, 13, 0.92) 10%, rgba(11, 11, 13, 0.76) 38%, rgba(11, 11, 13, 0.9) 80%, var(--black) 100%);
}

.hero-inner {
  padding: 0 var(--pad) clamp(6.5rem, 16vh, 9.5rem);
  max-width: 1320px;
  margin-inline: auto;
  width: 100%;
}

/* Silver reads at ~3.4:1 over the hero plate even under the scrim, so the two
   silver items inside the hero copy take the off-white instead. Every other
   kicker and ghost button on the page stays silver on pure black (4.9:1). */
.hero-inner .kicker,
.hero-actions .btn-ghost {
  color: var(--white);
}

.hero-title {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(2.5rem, 9vw, 6.4rem);
  line-height: 1.04;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  margin-bottom: 1.6rem;
}

.hero-title span {
  display: block;
}

.hero-sub {
  max-width: 34rem;
  color: var(--white);
  font-size: clamp(0.95rem, 1.4vw, 1.08rem);
  margin-bottom: 2.2rem;
}

.hero-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.9rem;
}

.hero-frame-data {
  position: absolute;
  right: var(--pad);
  bottom: 1.6rem;
  display: flex;
  align-items: center;
  gap: 0.7rem;
  font-size: 0.62rem;
  font-weight: 400;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--silver);
}

.rec-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--red);
  animation: rec-blink 1.8s ease-in-out infinite;
}

@keyframes rec-blink {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.25; }
}

.hero-frame-sep {
  opacity: 0.5;
}

/* 44px hit area (WCAG 2.5.8) with the hairline kept as the visual. */
.scroll-cue {
  position: absolute;
  left: calc(var(--pad) - 22px);
  bottom: 1.35rem;
  width: 44px;
  height: 56px;
  display: grid;
  place-items: center;
  overflow: hidden;
}

.scroll-cue span {
  display: block;
  width: 1px;
  height: 56px;
  background: var(--white);
  animation: cue-drop 2.4s var(--ease-wipe) infinite;
}

@keyframes cue-drop {
  0% { transform: translateY(-100%); }
  55% { transform: translateY(0); }
  100% { transform: translateY(100%); }
}

@media (max-width: 767px) {
  .hero-frame-data {
    right: auto;
    left: var(--pad);
    bottom: 1.5rem;
  }

  .scroll-cue {
    display: none;
  }
}

/* ============================================================
   SECTION RHYTHM
   ============================================================ */

.works,
.services,
.about,
.process,
.quotes,
.packages,
.booking {
  position: relative;
  padding-block: clamp(5.5rem, 13vw, 10rem);
}

/* ============================================================
   SELECTED WORKS — horizontal strip
   ============================================================ */

.works {
  border-top: 1px solid var(--line-soft);
}

.works-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 1.5rem;
  margin-bottom: clamp(2.2rem, 5vw, 3.6rem);
}

.works-head .section-title {
  margin-bottom: 0;
}

.works-meta {
  display: flex;
  align-items: center;
  gap: 1.6rem;
}

.works-counter {
  font-family: var(--font-display);
  font-size: 1.05rem;
  letter-spacing: 0.24em;
  text-transform: uppercase;
}

.works-counter #fr-total {
  color: var(--silver);
}

.works-nav {
  display: flex;
  gap: 0.5rem;
}

.strip-btn {
  width: 44px;
  height: 44px;
  border: 1px solid var(--line);
  display: grid;
  place-items: center;
  font-size: 0.95rem;
  transition: background 0.3s ease, color 0.3s ease, border-color 0.3s ease;
}

.strip-btn:hover:not(:disabled),
.strip-btn:focus-visible {
  background: var(--white);
  color: var(--black);
  border-color: var(--white);
}

.strip-btn:disabled {
  opacity: 0.32;
  cursor: not-allowed;
}

.works-hint {
  display: none;
  font-size: 0.62rem;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--silver);
}

@media (min-width: 768px) {
  .works-hint {
    display: block;
  }
}

.works-track {
  --strip-h: clamp(380px, 54vh, 540px);
  --track-pad: max(var(--pad), calc((100% - 1320px) / 2 + var(--pad)));
  display: flex;
  align-items: flex-start;
  gap: clamp(1.1rem, 2.6vw, 2.2rem);
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  scroll-padding-inline: var(--track-pad);
  padding-inline: var(--track-pad);
  padding-bottom: 1.4rem;
  -webkit-user-select: none;
  user-select: none;
  scrollbar-width: thin;
  scrollbar-color: var(--silver) transparent;
}

.works-track.dragging {
  scroll-snap-type: none;
  cursor: grabbing;
}

.works-track::-webkit-scrollbar {
  height: 3px;
}

.works-track::-webkit-scrollbar-track {
  background: var(--line-soft);
}

.works-track::-webkit-scrollbar-thumb {
  background: var(--silver);
}

/* Keep the frames clear of the vertical side label, which only exists >=1100px */
@media (min-width: 1100px) {
  .works-track {
    padding-right: calc(var(--pad) + 2.5rem);
  }
}

/* Contact-sheet frame */
.work-frame {
  flex: none;
  scroll-snap-align: start;
  border: 1px solid var(--line);
  background: var(--black-lift);
  padding: 0.6rem;
  position: relative;
}

.frame-head {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  font-size: 0.58rem;
  font-weight: 400;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  color: var(--silver);
  padding: 0.15rem 0.1rem 0.5rem;
}

.frame-media {
  position: relative;
  overflow: hidden;
  background: var(--black-lift);
}

/* Below 880px each frame is capped by WIDTH, so a whole frame is always
   visible at its snap position. From 880px up the strip height drives the
   frame again, contact-sheet style. */
.works-track .work-frame {
  --frame-w: min(520px, calc(100vw - 2 * var(--pad) - 1.5rem));
  width: min(calc(var(--frame-w) + 1.2rem + 2px), 100%);
  min-width: 0;
}

.works-track .work-frame:has(.frame-media.port) {
  --frame-w: min(360px, calc(100vw - 2 * var(--pad) - 1.5rem));
}

.works-track .frame-media {
  width: 100%;
}

.works-track .frame-media.land {
  aspect-ratio: 3 / 2;
}

.works-track .frame-media.port {
  aspect-ratio: 4 / 5;
}

@media (min-width: 880px) {
  .works-track .work-frame {
    --frame-w: calc(var(--strip-h) * 3 / 2);
  }

  .works-track .work-frame:has(.frame-media.port) {
    --frame-w: calc(var(--strip-h) * 4 / 5);
  }

  .works-track .frame-media {
    height: var(--strip-h);
  }
}

.frame-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: grayscale(1) contrast(1.1);
  transition: transform 1.1s var(--ease-out), filter 0.7s ease;
  background: var(--black-lift);
}

/* Printing-down pass. Three of the frames are shot on white seamless; without
   this they read as glaring rectangles in a near-black strip. Hover lifts it. */
.frame-media::after {
  content: "";
  position: absolute;
  inset: 0;
  background: rgba(11, 11, 13, 0.28);
  pointer-events: none;
  transition: background 0.7s ease;
}

.work-frame:hover .frame-media img {
  transform: scale(1.045);
  filter: grayscale(1) contrast(1.16);
}

.work-frame:hover .frame-media::after {
  background: rgba(11, 11, 13, 0.12);
}

.frame-caption {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: baseline;
  gap: 0.25rem 1rem;
  padding: 0.65rem 0.1rem 0.2rem;
}

.frame-title {
  font-family: var(--font-display);
  font-size: 0.86rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.frame-meta {
  font-size: 0.62rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--silver);
}

/* One red frame corner on the featured shot */
.work-frame.featured::before {
  content: "";
  position: absolute;
  top: -1px;
  left: -1px;
  width: 26px;
  height: 26px;
  border-top: 2px solid var(--red);
  border-left: 2px solid var(--red);
  z-index: 2;
}

.work-frame.featured .frame-head span:first-child {
  /* --red is 4.25:1 on the frame ground — just under AA, and this is 0.58rem
     text. Lifted rather than deepened because the ground is near-black; the
     brand red itself is untouched, so the five surfaces that use it as a FILL
     keep their exact colour and their white ink keeps its exact ratio. */
  color: var(--red-lift);
}

/* ============================================================
   SERVICES — numbered rows
   ============================================================ */

.services {
  border-top: 1px solid var(--line-soft);
}

.service-list {
  margin-top: clamp(2.4rem, 6vw, 4.4rem);
  border-top: 1px solid var(--line);
}

.service-row {
  display: grid;
  grid-template-columns: auto 1fr;
  column-gap: 1.4rem;
  row-gap: 0.8rem;
  padding-block: clamp(1.8rem, 4vw, 3rem);
  border-bottom: 1px solid var(--line);
}

.service-num {
  font-family: var(--font-display);
  font-size: 0.85rem;
  letter-spacing: 0.2em;
  color: var(--silver);
  padding-top: 0.55em;
}

.service-title {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(1.6rem, 4.4vw, 2.7rem);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  line-height: 1.1;
  margin-bottom: 0.7rem;
}

.service-row:hover .u-draw::after,
.service-row:focus-within .u-draw::after {
  transform: scaleX(1);
}

.service-text {
  max-width: 38rem;
  color: var(--silver);
  font-size: 0.95rem;
}

.service-meta {
  grid-column: 2;
  font-size: 0.72rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  line-height: 1.9;
}

.service-meta span {
  color: var(--silver);
}

@media (min-width: 768px) {
  .service-row {
    grid-template-columns: 4rem 1fr auto;
    align-items: start;
  }

  .service-meta {
    grid-column: auto;
    text-align: right;
    padding-top: 0.8em;
  }
}

/* ============================================================
   ABOUT THE ATELIER
   ============================================================ */

.about {
  border-top: 1px solid var(--line-soft);
}

.about-grid {
  display: grid;
  gap: clamp(2.4rem, 6vw, 5rem);
}

.about-portrait {
  border: 1px solid var(--line);
  background: var(--black-lift);
  padding: 0.6rem;
  max-width: 460px;
}

.about-portrait .frame-media {
  aspect-ratio: 4 / 5;
}

.about-copy .section-title {
  max-width: 18ch;
}

.about-lede {
  font-size: clamp(1.05rem, 1.8vw, 1.25rem);
  font-weight: 300;
  line-height: 1.6;
  max-width: 36rem;
  margin-bottom: 1.4rem;
}

.about-text {
  color: var(--silver);
  max-width: 36rem;
  margin-bottom: 1.4rem;
}

.about-sig {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin-top: 2.2rem;
  font-family: var(--font-display);
  font-size: 0.8rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
}

.sig-rule {
  display: inline-block;
  width: 44px;
  height: 1px;
  background: var(--red);
}

@media (min-width: 768px) {
  .about-grid {
    grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
    align-items: center;
  }
}

/* ============================================================
   PROCESS
   ============================================================ */

.process {
  border-top: 1px solid var(--line-soft);
}

.process-grid {
  margin-top: clamp(2.4rem, 6vw, 4.4rem);
  display: grid;
  gap: 2.4rem;
}

.process-step {
  border-top: 1px solid var(--line);
  padding-top: 1.4rem;
}

.step-num {
  font-family: var(--font-display);
  font-size: 1.9rem;
  letter-spacing: 0.1em;
  line-height: 1;
  margin-bottom: 1.1rem;
}

.step-num span {
  color: var(--silver);
}

/* One red accent for the whole process band */
.process-step:first-child .step-num span {
  color: var(--red);
}

.step-title {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 1.05rem;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  margin-bottom: 0.7rem;
}

.step-text {
  color: var(--silver);
  font-size: 0.92rem;
  margin-bottom: 1rem;
}

.step-meta {
  font-size: 0.62rem;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--white);
  opacity: 0.7;
}

@media (min-width: 768px) {
  .process-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 3rem 2.4rem;
  }
}

@media (min-width: 1100px) {
  .process-grid {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

/* ============================================================
   AWARDS & PRESS — marquee strip
   ============================================================ */

.awards {
  position: relative;
  border-block: 1px solid var(--line);
  padding-block: 1.6rem;
  background: var(--black-lift);
}

.marquee {
  overflow: hidden;
}

.marquee-track {
  display: flex;
  width: max-content;
  animation: marquee 30s linear infinite;
}

.marquee:hover .marquee-track,
.marquee.is-paused .marquee-track {
  animation-play-state: paused;
}

/* The strip starts moving on its own and runs forever, and :hover is a pause
   only a mouse can reach — a keyboard or a touch screen had no way to stop it
   (WCAG 2.2.2). This is a real control rather than a focus-trick on the strip,
   and it keeps out of the frame until focus finds it, the same bargain the
   skip-link convention makes, so the band still reads as one unbroken line of
   press. When it does show it takes the band's own micro-caps and hairline. */
.marquee-toggle {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

.marquee-toggle:focus {
  top: 50%;
  right: var(--pad);
  transform: translateY(-50%);
  z-index: 4;
  width: auto;
  height: auto;
  overflow: visible;
  clip: auto;
  padding: 0.5rem 1rem;
  border: 1px solid var(--line);
  background: var(--black);
  color: var(--white);
  font-size: 0.62rem;
  font-weight: 500;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  outline: 2px solid var(--white);
  outline-offset: 2px;
}

@keyframes marquee {
  to {
    transform: translateX(-50%);
  }
}

.marquee-list {
  display: flex;
  align-items: center;
  flex: none;
}

.marquee-list li {
  font-family: var(--font-display);
  font-size: 0.82rem;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--silver);
  white-space: nowrap;
  padding-inline: 1.6rem;
}

.mq-star {
  color: var(--silver);
  font-size: 0.72rem;
  padding-inline: 0;
}

/* ============================================================
   CLIENT QUOTES — contact-sheet captions
   ============================================================ */

.quote-grid {
  margin-top: clamp(2.4rem, 6vw, 4rem);
  display: grid;
  gap: 1.4rem;
}

.quote-card {
  border: 1px solid var(--line);
  background: var(--black-lift);
  padding: 1.6rem 1.5rem 1.4rem;
  display: flex;
  flex-direction: column;
  gap: 1.2rem;
  transition: border-color 0.4s ease, transform 0.5s var(--ease-out);
}

.quote-card:hover {
  border-color: rgba(237, 237, 234, 0.32);
  transform: translateY(-4px);
}

.quote-ref {
  display: flex;
  justify-content: space-between;
  font-size: 0.58rem;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--silver);
  border-bottom: 1px dashed var(--line);
  padding-bottom: 0.8rem;
}

.quote-text p {
  font-size: 1.02rem;
  font-weight: 300;
  line-height: 1.6;
}

.quote-attr {
  margin-top: auto;
  display: flex;
  align-items: center;
  gap: 0.7rem;
  font-size: 0.64rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--silver);
}

.attr-tick {
  flex: none;
  width: 18px;
  height: 1px;
  background: var(--silver);
}

/* One red accent for the whole quotes band */
.quote-card:nth-child(2) .attr-tick {
  background: var(--red);
}

@media (min-width: 768px) {
  .quote-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

/* ============================================================
   PACKAGES
   ============================================================ */

.packages {
  border-top: 1px solid var(--line-soft);
}

.tier-grid {
  margin-top: clamp(2.4rem, 6vw, 4rem);
  display: grid;
  gap: 1.4rem;
}

.tier {
  position: relative;
  border: 1px solid var(--line);
  padding: 2.2rem 1.8rem 2rem;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  background: var(--black);
  transition: border-color 0.4s ease, transform 0.5s var(--ease-out);
}

.tier:hover {
  border-color: rgba(237, 237, 234, 0.32);
  transform: translateY(-5px);
}

.tier-featured {
  border-color: rgba(224, 52, 44, 0.55);
  background: var(--black-lift);
}

.tier-featured:hover {
  border-color: var(--red);
}

.tier-flag {
  position: absolute;
  top: -0.62rem;
  left: 1.6rem;
  background: var(--red-deep);
  color: var(--white);
  font-size: 0.62rem;
  font-weight: 500;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  padding: 0.28rem 0.7rem;
}

.tier-num {
  font-family: var(--font-display);
  font-size: 0.85rem;
  letter-spacing: 0.3em;
  color: var(--silver);
}

.tier-name {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 1.45rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.tier-price {
  font-family: var(--font-display);
  font-size: clamp(2rem, 4vw, 2.6rem);
  letter-spacing: 0.04em;
  margin-block: 0.4rem 0.6rem;
}

.tier-desc {
  color: var(--silver);
  font-size: 0.9rem;
  margin-bottom: 1.1rem;
}

.tier-list {
  display: grid;
  gap: 0.55rem;
  margin-bottom: 1.8rem;
}

.tier-list li {
  font-size: 0.88rem;
  color: var(--white);
  padding-left: 1.2rem;
  position: relative;
}

.tier-list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.65em;
  width: 8px;
  height: 1px;
  background: var(--silver);
}

.tier-cta {
  margin-top: auto;
  text-align: center;
}

.tier-note {
  margin-top: 2.2rem;
  font-size: 0.78rem;
  color: var(--silver);
  max-width: 46rem;
}

@media (min-width: 1100px) {
  .tier-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    align-items: stretch;
  }
}

/* ============================================================
   BOOKING
   ============================================================ */

.booking {
  border-top: 1px solid var(--line-soft);
}

.booking-grid {
  display: grid;
  gap: clamp(2.8rem, 7vw, 5.5rem);
}

.booking-lede {
  color: var(--silver);
  max-width: 30rem;
  margin-bottom: 2rem;
}

.booking-still {
  border: 1px solid var(--line);
  background: var(--black-lift);
  padding: 0.6rem;
  max-width: 420px;
  margin-bottom: 2.2rem;
}

.booking-still .frame-media {
  aspect-ratio: 4 / 3;
}

.booking-address p {
  margin-bottom: 1.2rem;
  font-size: 0.92rem;
  line-height: 1.7;
}

.addr-label {
  display: block;
  font-size: 0.6rem;
  font-weight: 500;
  letter-spacing: 0.32em;
  text-transform: uppercase;
  color: var(--silver);
  margin-bottom: 0.25rem;
}

.text-link {
  display: inline-block;
}

/* Form */
.booking-form {
  border: 1px solid var(--line);
  background: var(--black-lift);
  padding: clamp(1.6rem, 4vw, 2.6rem);
  display: flex;
  flex-direction: column;
  gap: 1.4rem;
  align-self: start;
}

.field {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  min-width: 0;
}

.field-row {
  display: grid;
  gap: 1.4rem;
}

@media (min-width: 768px) {
  .field-row {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

.field label {
  font-size: 0.62rem;
  font-weight: 500;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--silver);
}

.req {
  color: var(--red);
  margin-left: 0.3rem;
}

.field input,
.field select,
.field textarea {
  width: 100%;
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--line);
  color: var(--white);
  font-family: var(--font-body);
  font-weight: 300;
  font-size: 0.95rem;
  padding: 0.6rem 0.1rem;
  border-radius: 0;
  transition: border-color 0.35s ease;
}

.field select {
  appearance: none;
  -webkit-appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%237D7F85'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.2rem center;
}

.field select option {
  background: var(--black);
  color: var(--white);
}

.field input::placeholder,
.field textarea::placeholder {
  color: rgba(125, 127, 133, 0.55);
}

.field input:focus,
.field select:focus,
.field textarea:focus {
  outline: none;
  border-bottom-color: var(--white);
}

/* `outline: none` above deleted the only shape cue these eight controls had:
   focus was signalled by the underline changing colour and by nothing else,
   which a low-vision or colour-blind user can miss entirely (WCAG 2.4.11).
   The underline treatment is unchanged — this only puts the ring back, and
   only for keyboard focus, so clicking a field still shows no ring.
   Same specificity as the rule above and later in the file, so it wins. */
.field input:focus-visible,
.field select:focus-visible,
.field textarea:focus-visible {
  outline: 2px solid var(--white);
  outline-offset: 3px;
}

/* Error state only — the form paints no error state at all today, so nothing
   that currently renders moves. The message names the field as well, so the
   red underline is a second cue rather than the only one. */
.field input[aria-invalid="true"],
.field select[aria-invalid="true"],
.field textarea[aria-invalid="true"] {
  border-bottom-color: var(--red-lift);
}

.field textarea {
  resize: vertical;
  min-height: 7rem;
}

.field input[type="date"] {
  color-scheme: dark;
}

.form-submit {
  align-self: flex-start;
}

.form-note {
  font-size: 0.72rem;
  color: var(--silver);
}

/* Hidden until the form actually complains, and `hidden` keeps it out of the
   flex flow so the empty state does not pay for the column gap. --red-lift is
   the shade that clears 4.5:1 as TYPE on the form's --black-lift ground. */
.form-error {
  font-size: 0.78rem;
  line-height: 1.5;
  color: var(--red-lift);
}

.form-success {
  border: 1px solid rgba(224, 52, 44, 0.5);
  padding: 1.2rem 1.3rem;
  font-size: 0.9rem;
  line-height: 1.7;
}

.form-success .success-ref {
  display: block;
  font-size: 0.62rem;
  font-weight: 500;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--white);
  margin-bottom: 0.5rem;
}

@media (min-width: 1100px) {
  .booking-grid {
    grid-template-columns: minmax(0, 6fr) minmax(0, 6fr);
    align-items: start;
  }
}

/* ============================================================
   FOOTER
   ============================================================ */

.site-foot {
  border-top: 1px solid var(--line);
  padding-top: clamp(3rem, 7vw, 5rem);
}

.foot-grid {
  display: grid;
  gap: 2.4rem;
  padding-bottom: clamp(2.6rem, 6vw, 4rem);
}

.foot-logo {
  font-family: var(--font-display);
  font-size: 1.4rem;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  margin-bottom: 0.8rem;
}

.foot-logo span {
  display: block;
  font-family: var(--font-body);
  font-weight: 400;
  font-size: 0.58rem;
  letter-spacing: 0.44em;
  color: var(--silver);
  margin-top: 0.3rem;
}

.foot-tag {
  font-size: 0.85rem;
  color: var(--silver);
}

.foot-head {
  font-family: var(--font-body);
  font-weight: 500;
  font-size: 0.62rem;
  letter-spacing: 0.32em;
  text-transform: uppercase;
  color: var(--silver);
  margin-bottom: 1.1rem;
}

.foot-nav ul {
  display: grid;
  gap: 0.6rem;
}

.foot-nav li {
  font-size: 0.88rem;
  color: var(--white);
}

.foot-link {
  color: var(--white);
  transition: color 0.3s ease;
}

.foot-link:hover,
.foot-link:focus-visible {
  color: var(--silver);
}

.foot-bar {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: center;
  gap: 0.8rem;
  border-top: 1px solid var(--line-soft);
  padding-block: 1.4rem;
  font-size: 0.7rem;
  color: var(--silver);
  letter-spacing: 0.06em;
}

.foot-fin {
  font-family: var(--font-display);
  font-size: 0.85rem;
  letter-spacing: 0.4em;
  text-transform: uppercase;
  color: var(--white);
}

.foot-fin span {
  color: var(--red);
}

@media (min-width: 768px) {
  .foot-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (min-width: 1100px) {
  .foot-grid {
    grid-template-columns: 2fr 1fr 1fr 1fr;
  }
}

/* ============================================================
   REVEALS
   ============================================================ */

/* The hidden state is scoped to .js (set by the inline head script and
   dropped again if script.js never boots), so no-JS visitors get the full
   page instead of a blank one. */

.reveal {
  transition: opacity 0.85s ease, transform 0.85s var(--ease-out);
  transition-delay: var(--d, 0s);
}

.js .reveal {
  opacity: 0;
  transform: translateY(26px);
}

.js .reveal.in {
  opacity: 1;
  transform: translateY(0);
}

/* The wipe is a retracting curtain, NOT a clip-path on .wipe itself.
   Chromium factors an element's own clip-path into IntersectionObserver
   geometry: a box clipped to zero width reports intersectionRatio 0, so the
   observer that adds .in never fires and the frame stays hidden forever.
   WebKit does not, which is why the frames appeared in Safari but not Chrome.
   Clipping a pseudo-element instead leaves the observed box's geometry intact. */
.wipe::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 3;
  background: var(--black-lift);
  transform: scaleX(0);
  transform-origin: right center;
  pointer-events: none;
  transition: transform 1.15s var(--ease-wipe);
  transition-delay: var(--d, 0s);
}

/* Covered only while JS is alive to uncover it — no-JS keeps scaleX(0). */
.js .wipe::before {
  transform: scaleX(1);
}

.js .wipe.in::before {
  transform: scaleX(0);
}

/* ============================================================
   REDUCED MOTION — all motion off
   ============================================================ */

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.001s !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001s !important;
    transition-delay: 0s !important;
  }

  html {
    scroll-behavior: auto;
  }

  .reveal,
  .wipe {
    opacity: 1 !important;
    transform: none !important;
    clip-path: none !important;
  }

  .wipe::before {
    transform: scaleX(0) !important;
  }

  .marquee-track {
    animation: none !important;
    transform: none !important;
    flex-wrap: wrap;
    width: 100%;
  }

  .marquee-list {
    flex-wrap: wrap;
    row-gap: 0.5rem;
  }

  .marquee-list[aria-hidden="true"] {
    display: none;
  }

  /* Nothing is moving under this preference, so the pause control has nothing
     to pause — and a dead control is worse than no control. */
  .marquee-toggle {
    display: none !important;
  }

  .rec-dot,
  .scroll-cue span {
    animation: none !important;
  }

  .hero-media img {
    transform: none !important;
  }

  .cursor {
    display: none !important;
  }

  body.cursor-on,
  body.cursor-on a,
  body.cursor-on button,
  body.cursor-on input,
  body.cursor-on select,
  body.cursor-on textarea,
  body.cursor-on label {
    cursor: auto;
  }
}
