/* ---- Project detail page — hero, project fact-list, Melody House
   panel-sequence crops, the Values sequence. The generic editorial-module
   family this page also uses (.editorial-module, .editorial-duo,
   .editorial-offset, .editorial-story, .full-image-module) now lives in
   components/editorial-modules.css — moved out since Our Story, Contact
   (old), Architectural Design and the Journal article page all reuse it
   too, so it was never really "project-detail" only. Load that file before
   this one. ---- */

/* ---- Next project — static full-bleed link to the next project in
   sequence, placed just before the footer CTA. Reuses .panel/.panel--short
   (panel.css) for the full-bleed image/video + bottom-anchored
   overline/heading layout, but deliberately outside a panel-sequence and
   without data-reveal/data-parallax — this is a plain, un-animated handover
   to the next project, not another scroll-driven moment. Media is whatever
   that next project's own listing card (projects.html) uses — a video where
   one exists, otherwise its hero image:

     <a class="next-project panel panel--short" href="/projects/SLUG/" aria-label="Next project: NAME, SUBURB">
       <div class="panel__bg"><img src="HERO.jpg" alt="" /></div>
       <div class="panel__content">
         <div class="container">
           <p class="eyebrow panel__eyebrow">Next</p>
           <h2 class="heading-h1 panel__heading">NAME</h2>
           <p class="body-regular project-hero-location">SUBURB, STATE</p>
         </div>
       </div>
     </a>

   Follows the fixed Portfolio order (see the footer's Portfolio column) —
   each project's "next" is the one after it in that list, wrapping back to
   the first after the last. ---- */
.next-project .panel__bg img,
.next-project .panel__bg video {
  transition: transform var(--duration-slow) var(--ease-standard);
}

.next-project:hover .panel__bg img,
.next-project:focus-visible .panel__bg img,
.next-project:hover .panel__bg video,
.next-project:focus-visible .panel__bg video {
  transform: scale(1.04);
}

@media (prefers-reduced-motion: reduce) {
  .next-project .panel__bg img,
  .next-project .panel__bg video {
    transition: none;
  }
}

.project-hero-location {
  margin-top: var(--space-4);
  color: rgba(255, 255, 255, 0.9);
}

/* Project Introduction Section — split layout on desktop */
.project-intro-split {
  display: flex;
  flex-direction: column;
  gap: var(--space-8);
}

@media (min-width: 1024px) {
  .project-intro-split {
    flex-direction: row;
    gap: var(--space-16);
  }

  .project-intro-split > * {
    flex: 1 1 50%;
  }

  .project-intro-split--60-40 > :first-child {
    flex-basis: 60%;
  }

  .project-intro-split--60-40 > :last-child {
    flex-basis: 40%;
  }
}

.project-intro-heading {
  max-width: 45rem;
  margin-bottom: var(--space-8);
  line-height: var(--line-height-normal);
}

@media (min-width: 1280px) {
  .project-intro-heading {
    font-size: var(--font-size-h2-md);
  }
}

/* Project Details — a single fact list (Project, Location, Category,
   Expertise, Media) in one consistent rhythm: label, value, hairline.
   Deliberately one column, not a details/expertise split — mixed patterns
   (a bold heading + bullet list beside a bordered grid) read as two
   unrelated components rather than one considered summary. Multi-item
   fields (Expertise, Media) read as comma-separated value lines rather
   than bullets, so every row shares the same shape. */
.project-details-grid {
  display: grid;
  gap: var(--space-6);
}

.project-details-row {
  display: grid;
  gap: var(--space-6);
}

/* Below 480px the row stacks to one column (Project/Location/Category run
   vertically), so the row's own single border-bottom only ever lands under
   the last item — Expertise/Media's own per-item dividers keep going the
   whole way down, but this row reads as one ungapped block instead of
   matching that rhythm. Give each stacked item its own divider here instead
   (row's shared border/padding, above, moves onto the individual items) so
   every field in the fact list gets a line under it on mobile, same as
   Expertise/Media. Reverts to the original single row-level border at
   480px+, where the 3-column layout below makes one shared line correct
   again. */
.project-details-row > .project-details-item {
  border-bottom: 1px solid var(--color-border);
  padding-bottom: var(--space-4);
}

@media (min-width: 480px) {
  .project-details-row {
    grid-template-columns: repeat(3, 1fr);
    border-bottom: 1px solid var(--color-border);
    padding-bottom: var(--space-4);
  }

  .project-details-row > .project-details-item {
    border-bottom: none;
    padding-bottom: 0;
  }
}

.project-details-item--divider {
  border-bottom: 1px solid var(--color-border);
  padding-bottom: var(--space-4);
}

.project-details-label {
  font-size: var(--font-size-2);
  font-weight: var(--font-weight-demibold);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--color-text-muted);
  display: block;
}

.project-details-value {
  margin-top: var(--space-2);
  font-family: var(--font-body);
  font-weight: var(--font-weight-normal);
  font-size: var(--font-size-body-regular);
  line-height: var(--line-height-relaxed);
}

.project-media-link {
  display: inline-block;
  font-family: var(--font-body);
  font-size: var(--font-size-body-regular);
  color: var(--color-text);
  border-bottom: 1px solid transparent;
  transition: border-color var(--duration-base) var(--ease-standard);
}

.project-media-link:hover,
.project-media-link:focus-visible {
  border-color: var(--color-text);
}

/* Melody House's Module 2 -> Module 3 boundary: unlike every other module
   boundary on this page, Module 3 (--4-8) opens straight into a paragraph
   with no heading or image ahead of it to read as "new module starting" —
   so even the standard project-page section-rhythm tightening (40px+40px,
   see layout.css) still looks like a stray gap in one train of thought
   rather than a deliberate break. Tightened further, scoped to this one
   boundary via the two modules' own variant classes rather than lowering
   the site-wide project-page rhythm (every other boundary on this page
   opens into a heading or image and reads fine at the standard amount). */
body.project-page .section:has(> .container > .editorial-module--feature) {
  padding-bottom: var(--space-6);
}

body.project-page .section:has(> .container > .editorial-module--4-8) {
  padding-top: var(--space-6);
}

@media (min-width: 1024px) {
  body.project-page .section:has(> .container > .editorial-module--feature) {
    padding-bottom: var(--space-32);
  }

  body.project-page .section:has(> .container > .editorial-module--4-8) {
    padding-top: var(--space-32);
  }
}

/* .editorial-duo__primary/__secondary's own gap (base rule now in
   editorial-modules.css) is an unconditional
   space-40 (160px) at every width — between the intro paragraph and the
   tall image below it, and between the secondary image and the caption
   below it. Fine at desktop's side-by-side column width, excessive below
   1024px. Scoped to body.project-page (Melody House) rather than the bare
   class, matching the same reduction pages/architectural-design.css
   already applies to its own .editorial-duo instance via .how-we-collaborate
   — .editorial-duo is also reused by journal/sailing-and-architecture,
   which hasn't been reviewed for this. */
body.project-page .editorial-duo__primary,
body.project-page .editorial-duo__secondary {
  gap: var(--space-10);
}

@media (min-width: 1024px) {
  body.project-page .editorial-duo__primary,
  body.project-page .editorial-duo__secondary {
    gap: var(--space-40);
  }
}

/* Melody House highlights sequence — image focal points, scoped to these
   instance classnames so they don't collide with panel.css's own
   panel--home-1..5 crop overrides (those are homepage-specific — this
   sequence already dodges that collision by using its own melody-N names,
   which is also why panel.css's set was itself renamed home-N rather than
   the bare, collision-prone panel--1..5 it used to be). */
.panel--melody-1 .panel__bg img { object-position: center 35%; } /* glass facade in its rolling-hills setting */
.panel--melody-2 .panel__bg img { object-position: center 50%; } /* kitchen counter opening to the pavilion */
.panel--melody-3 .panel__bg img { object-position: center 55%; } /* living room + fireplace */

.panel-sequence--melody {
  margin-block: var(--space-20);
}

@media (min-width: 1024px) {
  .panel-sequence--melody {
    margin-block: var(--space-32);
  }
}

.panel-sequence--melody .panel__heading {
  max-width: 30rem;
  margin-inline: auto;
}

/* The About page's captions are worded/line-broken for full-width headings
   (like the homepage panels), not Melody House's narrower 30rem cap — so
   this opts back out of it for any sequence that also shows its text. */
.panel-sequence--show-text .panel__heading {
  max-width: none;
  margin-inline: 0;
}

/* A full body-copy paragraph (as opposed to the short headings above) still
   needs a capped, comfortable reading width even at full-width — otherwise
   it stretches edge-to-edge and the lines get too long to read easily.
   Combined selector so it wins over the full-width rule above regardless of
   source order. */
.panel-sequence--show-text .panel__heading.panel__body {
  max-width: 34rem;
  margin-inline: auto;
}

/* Hidden by default — Melody House's own page shows just photography, no
   captions. Pages reusing this 3-panel structure with their own content can
   opt back into the homepage's normal show-text behaviour by adding
   .panel-sequence--show-text (e.g. the About page's copy of this sequence). */
.panel-sequence--melody:not(.panel-sequence--show-text) .panel__text-block {
  display: none;
}

/* ---- Values sequence — pinned crossfade (scroll-panels.js/panel-text.js),
   laid out with the exact same proportions/spacing as Editorial Module 2
   (.editorial-module--feature): 3fr:2fr grid, bottom-anchored, 24rem text
   cap. Fully self-contained rather than overriding .panel__bg/.panel__content
   — those classes carry a whole cascade of unconditional, hero-specific
   rules from panel.css (full-bleed absolute positioning, object-fit/height
   sizing, padding-top: header-height, centred text, white text, flex/
   align-items:flex-end anchoring) that this instance doesn't want and kept
   fighting piecemeal. Only .panel is kept (required — see below); the
   media/text wrappers use fresh .values-panel__* classes with zero
   panel.css rules attached to them at all.

   .panel is required because .panel-sequence--ready .panel (panel.css) is
   what makes panels stack exactly on top of each other for the crossfade —
   position/inset/min-height when pinned come entirely from that rule,
   untouched here. .panel__bg/.panel__content are NOT required by
   scroll-panels.js/panel-text.js at all — only the data-panel-bg/
   data-panel-text-motion/data-panel-text attributes are, which live on the
   new .values-panel__* elements instead. */
.panel-sequence--values {
  margin-block: var(--space-20);
}

@media (min-width: 1024px) {
  .panel-sequence--values {
    margin-block: var(--space-32);
  }
}

/* Neutralise panel.css's hero-only defaults that would otherwise leak
   through .panel, then centre .values-panel__inner within whatever height
   .panel ends up with (100svh once pinned). padding-top reserves space for
   the fixed .site-header (panel.css's own .panel__content normally does
   this too) — without it, the centred block can creep up underneath the
   nav, since .panel itself runs the full pinned height behind it. */
.panel-sequence--values .panel {
  color: var(--color-text);
  overflow: visible;
  display: flex;
  align-items: center;
  justify-content: center;
  padding-top: var(--header-height);
}

/* Sized to its own natural content height (not stretched — align-items:
   center above sizes flex children to their intrinsic height), so the
   internal grid below never inherits an oversized row the way the previous
   attempt's align-items: end on the full 100svh .panel did. Width/padding
   values copied from grid.css's .container rule directly, rather than
   using that class, to keep this block genuinely self-contained. */
.values-panel__inner {
  width: 100%;
  max-width: var(--container-max-site);
  margin-inline: auto;
  padding-inline: var(--gutter-sm);
  display: flex;
  flex-direction: column;
  gap: var(--space-8);
}

@media (min-width: 768px) {
  .values-panel__inner {
    padding-inline: var(--gutter-md);
  }
}

@media (min-width: 1024px) {
  .values-panel__inner {
    padding-inline: var(--gutter-lg);
    display: grid;
    grid-template-columns: 3fr 2fr;
    gap: var(--space-16);
    align-items: end;
  }
}

.values-panel__media {
  aspect-ratio: 4 / 5;
  overflow: hidden;
}

@media (min-width: 768px) {
  .values-panel__media {
    /* Taller than the standard 16:9 landscape crop — matches the site's
       existing .editorial-image--landscape.editorial-image--tall variant. */
    aspect-ratio: 4 / 3;
  }
}

.values-panel__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.values-panel__text {
  text-align: left;
  /* Safety clip: caps how far the scroll-linked text drift (see
     data-drift-distance on the section, panel-text.js) can ever visually
     travel outside this box, regardless of viewport size — it should never
     be able to paint over .values-panel__media above it. */
  overflow: hidden;
}

/* Matches .editorial-module--feature .editorial-text-block's cap exactly. */
.values-panel__heading,
.values-panel__body {
  max-width: 24rem;
}

/* Matches .editorial-heading's own margin-bottom — same gap Module 2 uses
   between its heading and paragraph, just applied as margin-top here since
   .values-panel__heading is shared by both the h3 and the p (for the
   max-width cap above) and can't carry a heading-only margin itself. */
.values-panel__body {
  margin-top: var(--space-6);
}

/* Panel 1's section-intro line — a custom size a step up from .heading-h2,
   deliberately more prominent than the .heading-h3 value names below it.
   Fixed height (not min-height) + overflow: hidden, same technique as
   panel.css's .panel__eyebrow, so this slot — populated on Panel 1, empty
   on Panels 2–4 — occupies the exact same box either way. Without this,
   Panel 1's block is taller than the others, and since every panel is
   centered within the same panel height, that mismatch pushes Panel 1's
   text/image to a different vertical position (and exit height) than the
   rest. */
.values-intro-heading {
  font-family: var(--font-heading);
  font-weight: var(--font-weight-normal);
  font-size: calc(var(--font-size-h2) * 1.15);
  line-height: var(--line-height-normal);
  letter-spacing: var(--tracking-tight);
  /* x2: below 768px the container is narrow enough that this heading wraps
     to two lines — a single-line box height here would silently clip the
     second line instead of just reserving consistent space across panels. */
  height: calc(var(--font-size-h2) * 1.15 * var(--line-height-normal) * 2);
  overflow: hidden;
  margin-bottom: var(--space-8);
}

@media (min-width: 768px) {
  .values-intro-heading {
    /* Single line from here up — the wider container fits it on one line. */
    font-size: calc(var(--font-size-h2-md) * 1.15);
    height: calc(var(--font-size-h2-md) * 1.15 * var(--line-height-normal));
  }
}

@media (min-width: 1280px) {
  .values-intro-heading {
    font-size: calc(var(--font-size-h2-lg) * 1.15);
    height: calc(var(--font-size-h2-lg) * 1.15 * var(--line-height-normal));
  }
}
