/* Home page. The hero belongs to the shared shell and is finished.
   Sections below the hero (services, why us, gallery, reviews) are written
   under the marker at the bottom of this file. */

/* ---------- hero ---------- */
.hero {
  position: relative;
  min-height: calc(100vh - var(--announce-h));
  display: grid;
  /* The wordmark used to sit in the middle of the frame, over her eyes. With the
     name gone from the hero (the header already carries it) the face is the only
     subject, so the line and the button drop to the foot of the frame and leave
     it alone. */
  align-items: end;
  overflow: hidden;
  background: var(--bg-deep);
  color: #fff;
}
@supports (min-height: 100svh) { .hero { min-height: calc(100svh - var(--announce-h)); } }

.hero-media {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  /* cover crops the long side. On the usual window shapes it crops the width, so
     the whole height is shown and this only nudges the frame; held above centre
     the hairline stays in and the shoulders take the cut. */
  object-position: 50% 22%;
}
/* Wider than 16:9 (a laptop with a lot of browser chrome) is the one shape where
   cover crops top and bottom instead. Held high, her chin drops onto the tagline
   and the button lands across her mouth, so here the frame centres: the crown of
   the head is cropped instead, which is an ordinary way to crop a portrait. */
@media (min-aspect-ratio: 16/9) {
  .hero-media { object-position: 50% 50%; }
}
.hero-veil {
  position: absolute; inset: 0;
  background:
    linear-gradient(180deg, rgba(10,10,13,0.42) 0%, rgba(10,10,13,0.26) 42%, rgba(10,10,13,0.72) 100%);
}
.hero-content {
  position: relative;
  text-align: center;
  padding-top: var(--header-h);
  /* the line sits on the chin, just under her lips, and the button below it on
     the neck. Raising the floor is what lifts them: the block is bottom aligned. */
  padding-bottom: clamp(80px, 11.7vh, 140px);
}
.hero-eyebrow {
  font-size: var(--fs-eyebrow);
  text-transform: uppercase;
  letter-spacing: var(--ls-wide);
  color: rgba(255,255,255,0.78);
  margin-bottom: clamp(18px, 3vh, 30px);
}
/* The h1 still carries the brand name for search and for a screen reader, it is
   just not drawn: see .sr-only in layout.css. */
.hero-sub {
  margin: 0 auto;
  max-width: 44ch;
  color: rgba(255,255,255,0.88);
  /* Bigger, but capped so the line never breaks. The wordmark above is 104px and
     this used to top out at 18px, which is too far a drop for the one sentence
     that has to sell the studio. Measured at 1440 and 390: 1.45rem is the largest
     that still holds on one line on a phone; 1.6rem breaks it. */
  font-size: clamp(1.05rem, 2.4vw, 2rem);   /* 1.05rem is the largest that still holds one line at 390 */
}
.hero-actions {
  margin-top: clamp(28px, 4.5vh, 48px);
  display: flex; flex-wrap: wrap; gap: 14px; justify-content: center;
}
@media (max-width: 640px) {
  /* one call to action, so it keeps a button shape instead of becoming a full
     width band across the photograph */
  .hero-actions .btn { flex: 0 1 auto; width: min(300px, 100%); }
}

/* ---------- HOME SECTIONS BELOW THIS LINE ---------- */

/* ============================================================
   1. SERVICES, full bleed category tiles
   ============================================================ */
.section-head { text-align: center; margin-bottom: clamp(34px, 5vw, 62px); }
.section-head .eyebrow { margin-bottom: 14px; }
.section-head .lede {
  margin: clamp(16px, 2vw, 22px) auto 0;
  max-width: 52ch;
  font-size: var(--fs-small);
}

/* The three photographs meet edge to edge. The 1px gap with a --line background
   behind it drew a hairline between them, which reads as a table of cards; the
   images are stronger as one continuous band. */
.services-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0;
}
@media (min-width: 760px) {
  .services-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

.service-card { margin: 0; }
.service-link {
  position: relative;
  display: block;
  aspect-ratio: 1 / 1;
  overflow: hidden;
  background: var(--bg-deep);
  color: #fff;
}
.service-img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  transition: transform 1.1s var(--ease);
}
.service-link:hover .service-img,
.service-link:focus-visible .service-img { transform: scale(1.045); }
@media (hover: none) { .service-link:hover .service-img { transform: none; } }

.service-scrim {
  position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(10,10,13,0) 34%, rgba(10,10,13,0.34) 60%, rgba(10,10,13,0.80) 100%);
}
.service-body {
  position: absolute; left: 0; right: 0; bottom: 0;
  padding: clamp(20px, 2.6vw, 34px);
}
.service-title {
  display: block;
  font-family: var(--font-sans);
  font-weight: 400;
  font-size: clamp(0.95rem, 1.45vw, 1.15rem);
  letter-spacing: var(--ls-wide);
  line-height: 1.3;
}
.service-text {
  display: block;
  margin-top: 10px;
  max-width: 32ch;
  font-size: var(--fs-small);
  line-height: 1.6;
  color: rgba(255, 255, 255, 0.85);
}

/* ============================================================
   2. WHY US, three reasons on one narrow centred measure, an index over each
   heading and a hairline between them.

   This replaced a zigzag: an axis down the middle, numbered pills sitting on
   it, copy one side and a 16:9 photo the other. The photographs went first
   (the front page carried fifteen images and these three proved nothing that
   the gallery did not already show), which left half of every row empty. The
   axis and the pills went with them: enlarging the numeral to fill that half
   only made the section look cheap, and the space reads better spent on the
   measure than on a graphic.
   ============================================================ */
.why-list {
  /* tokens.css resets ul only, an ol still carries the 40px list padding */
  list-style: none;
  /* the measure is what holds this section together now, so it is capped here
     rather than on the copy. Widened from 600 to 740 when the type went up a
     step: the same paragraph at 17px in a 600px column ran to three lines. */
  max-width: 740px;
  margin: 0 auto;
  padding: 0;
}

.why-row {
  display: grid;
  justify-items: center;
  text-align: center;
}
/* The rule sits between reasons, never above the first or below the last: a
   frame around the group would fight the section's own top and bottom padding.
   Equal margin and padding put the line exactly halfway between two reasons. */
/* Two fixed steps rather than one clamp. The step is doubled either side of the
   rule, so a clamp that looked right on a phone landed at 74 + 74 = 148px on a
   desktop and the three reasons stopped reading as one list. The phone keeps
   the 34 it always had; only the desktop comes in. */
.why-row + .why-row {
  margin-top: 34px;
  border-top: 1px solid var(--line);
  padding-top: 34px;
}
@media (min-width: 900px) {
  .why-row + .why-row { margin-top: 28px; padding-top: 28px; }
}
/* the section's own top and bottom come in a step as well */
.why.section { padding-block: clamp(48px, 6.5vw, 96px); }

/* The index is a label, not a graphic: same small letterspaced Jost as every
   other eyebrow on the site. It was a lit pill on a gradient outline while it
   had an axis to sit on; with the axis gone that treatment had nothing to
   belong to and only drew attention to itself. */
.why-num {
  font-family: var(--font-sans);
  /* Up from 0.78rem and off --ink-muted. At the smaller size in the lighter
     grey the digit read as a stray character floating above the heading rather
     than as an index belonging to it. */
  font-size: 1rem;
  font-weight: 300;
  letter-spacing: var(--ls-mid);
  line-height: 1;
  color: var(--ink-soft);
  margin-bottom: clamp(12px, 1.4vw, 18px);
}
/* Bare 1, 2, 3. The mockup showed them as 01, 02, 03; Nikodem asked for the
   plain digit, so the leading zero is not added here or in the markup. */
.why-num i { font-style: normal; }

/* The section ran on black while it was a map with photographs on it. On the
   white ground of the services grid above, the same three reasons read as part
   of one page instead of an interruption, and the hairlines carry more of the
   structure than a change of ground ever did. The .why--dark modifier and its
   overrides are gone with it; the section takes the page's own colours now. */
.why-title {
  /* Set like the header nav: Jost at the body's 300, uppercase, --ls-mid. It
     was Cormorant, then Jost 400 on --ls-wide to match the service tiles;
     Nikodem picked the nav's setting instead, which is lighter and tracked
     tighter, so the headings sit quieter under the section title.
     Only the size is the section's own, since a nav link is 13px. */
  font-family: var(--font-sans);
  font-weight: 300;
  font-size: clamp(1rem, 1.55vw, 1.2rem);
  text-transform: uppercase;
  letter-spacing: var(--ls-mid);
  line-height: 1.3;
}
.why-text {
  margin-top: 14px;
  /* the measure is set on .why-list now, so nothing narrows it again here */
  color: var(--ink-soft);
  /* Up from --fs-small (13px), which was set when the copy sat beside a
     photograph and had a caption's job. Standing alone on a wide white
     section it was simply too small to read. */
  font-size: clamp(0.9375rem, 1.1vw, 1.0625rem);
  /* Centred copy: without this the first line fills the measure and the second
     is left as a two-word orphan under the middle of it. Balance splits the two
     lines evenly instead, which is what centring is for. It is the right call
     here and the wrong one in the footer, where the lines are ranged left and
     are meant to fill their column. */
  text-wrap: balance;
}

/* ============================================================
   3. GALLERY, continuous marquee (js/gallery.js)
   ============================================================ */
.marquee {
  position: relative;
  /* no script and reduced motion both land here: a plain swipeable strip */
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x proximity;
  scrollbar-width: none;
  -ms-overflow-style: none;
  -webkit-overflow-scrolling: touch;
}
.marquee::-webkit-scrollbar { width: 0; height: 0; display: none; }

/* switched on by gallery.js once the animation takes over the scrolling */
.marquee.is-auto {
  overflow: hidden;
  scroll-snap-type: none;
  touch-action: pan-y;
  cursor: grab;
}
.marquee.is-auto.is-dragging { cursor: grabbing; }

.marquee-track {
  display: flex;
  width: max-content;
  gap: clamp(8px, 1.1vw, 16px);
}
.marquee.is-auto .marquee-track { will-change: transform; }

.marquee-item {
  flex: 0 0 auto;
  width: clamp(200px, 50vw, 290px);
  margin: 0;
  scroll-snap-align: center;
}
.marquee-item img {
  width: 100%;
  height: auto;
  aspect-ratio: 3 / 4;
  object-fit: cover;
  background: var(--bg-alt);
  -webkit-user-drag: none;
  user-select: none;
}

/* ============================================================
   4. CLIENT REVIEWS, a strip that keeps moving
   ============================================================ */
/* The section runs on black, the same --ink ground as "why us", so the two dark
   bands on the page are the same black and neither reads brown.
   The heading uses .section-title--caps like every other section title, so all
   four titles on the home page are one size and one typeface. */
.reviews { background: var(--ink); color: #fff; overflow: hidden; }
.reviews[hidden] { display: none; } /* switched off for the early opening */
.reviews .section-title { color: #fff; }

.rv-rail {
  margin-top: clamp(30px, 4vw, 52px);
  overflow: hidden;
  /* No fade at the ends. It worked while the cards were outlines on black, but
     a solid white card fading to black reads as a smudge across the card, not as
     the strip continuing. A clean clip at the edge is honest and quiet. */
}
/* The track holds the three cards twice, so translating it by exactly half its
   width lands the copy where the original started and the loop never jumps. */
.rv-track {
  display: flex;
  width: max-content;
  animation: rvRun 52s linear infinite;
}
.rv-rail:hover .rv-track,
.rv-rail:focus-within .rv-track { animation-play-state: paused; }
@media (prefers-reduced-motion: reduce) { .rv-track { animation: none; } }
@keyframes rvRun { to { transform: translateX(-50%); } }
/* one real review so far: no loop, the card stands centred */
.rv-rail--single .rv-track { animation: none; width: auto; justify-content: center; padding-inline: var(--pad-x); }
.rv-rail--single .rv-card { margin-right: 0; width: min(420px, 100%); }

/* The card is a white block on the black band, so everything inside it uses the
   light-surface colours, not the section's. */
.rv-card {
  /* The spacing is a right margin on every card, never a flex gap on the track:
     with a gap the track is 6 cards + 5 gaps, so half of it is half a gap short
     of one set and the loop jumps at the seam. As a margin every card is the
     same width, so half the track is exactly one set. */
  margin: 0 clamp(18px, 2.4vw, 34px) 0 0;
  flex: 0 0 auto;
  width: clamp(270px, 27vw, 350px);
  display: flex; flex-direction: column; gap: 14px;
  padding: clamp(22px, 2.4vw, 30px);
  background: var(--bg);
  color: var(--ink);
}
/* name row: the round photo first, the name beside it */
.rv-who { display: flex; align-items: center; gap: 12px; }
.rv-av {
  flex: 0 0 auto;
  width: 40px; height: 40px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--ink);
  color: var(--bg);
  font-family: var(--font-display); font-size: 1.05rem; line-height: 1;
  object-fit: cover; /* holds for an <img> swapped in later, same circle */
}
.rv-name {
  font-size: var(--fs-small);
  text-transform: uppercase; letter-spacing: var(--ls-mid);
}
.rv-quote {
  margin: 0;
  color: var(--ink-soft);
  font-size: var(--fs-small); line-height: var(--lh-body);
}
.stars { display: inline-flex; gap: 3px; }
.stars .star { fill: var(--ink); }

.reviews-cta { margin-top: clamp(40px, 6vw, 74px); text-align: center; }
