/* =====================================================================
   Elphinston Wells — Body sections
   --------------------------------------------------------------------
   Each section below is a self-contained, movable MODULE for the later
   ACF Flexible Content conversion. Content vs structure noted inline.
   Section spacing between modules is handled with --section-gap.
   ===================================================================== */

:root {
  --section-gap: 120px;     /* vertical rhythm between body modules */
  --inset-pad: 30px;        /* padding inside an inset content block */
}

/* Module rhythm. The first module sits directly below the menu bar (the
   body already reserves the bar height via padding-top), so no extra top
   gap on the first; subsequent modules/sections get the section gap above. */
.body-flow > .module + .module,
.body-flow > .sec-do,
.body-flow > .sec-craft,
.body-flow > .sec-featured,
.body-flow > .sec-testimonials,
.body-flow > .sec-story,
.body-flow > .sec-gallery-cta { margin-top: var(--section-gap); }
.body-flow > .sec-do + .sec-craft { margin-top: 30px; }   /* tight: Our difference hugs What We Do */
.body-flow > .sec-do + .module { margin-top: var(--section-gap); }
.body-flow > .module:last-child,
.body-flow > .sec-craft:last-child,
.body-flow > .sec-do:last-child { padding-bottom: var(--section-gap); }

/* =====================================================================
   SECTION — What We Do (section title)
   6-block module (each block 2 cols wide x 2 cols tall). First 3 blocks
   merge into one 6-col-wide x 2-col-tall block holding the title, aligned
   bottom-left. Remaining 3 blocks empty.
   ===================================================================== */
.sec-do-title__title-block {
  grid-column: span 6;                  /* width of first 3 blocks merged */
  /* height of a 2-col block kept square: 2 cols + 1 gutter */
  min-height: calc((2 * var(--do-col)) + (1 * var(--gutter)));
  display: flex;
  flex-direction: column;
  justify-content: flex-end;            /* title bottom-aligned */
  align-items: flex-start;              /* title left-aligned */
  padding: var(--gutter) var(--gutter) var(--gutter) 0;
}
.sec-do-title__title {
  margin: 0;
  color: var(--c1);
  font-variation-settings: "wght" 200, "wdth" 100;   /* one-off lighter weight */
}

/* =====================================================================
   SECTION 1 — Positioning statement
   2-block module. Block 1: positioning copy (large_body), left + vertically
   centred. Block 2: 1px keyline placeholder (content TBC).
   ===================================================================== */
.sec-positioning__copy {
  /* CONTENT: positioning statement. Now flows inside a 4-col inset. */
  margin: 0;
  color: var(--c1);
}
.sec-positioning__title {
  margin: 0;
  color: var(--c1);
}
/* Block 1 copy inset: 4 cols wide, centred in the 6-col block (like Who We Are). */
.sec-positioning__inset {
  grid-column: 2 / 6;                   /* 4 cols centred in the block */
  align-self: center;                   /* vertically centred */
  display: flex;
  flex-direction: column;
  gap: var(--gutter);
  padding: var(--inset-pad) var(--inset-pad) 0;
  text-align: left;                     /* copy reads left-aligned */
}

/* Block 2 holds the carousel; vertically centred within the square block,
   with a 1px 20% keyline border. */
.sec-positioning__carousel-block {
  padding: 0;
  overflow: hidden;                     /* crop the neighbouring images */
  position: relative;
  display: grid;
  grid-template-columns: subgrid;       /* inherit 6 parent cols so children can inset */
  align-content: center;               /* vertically centre content in the block */
}
/* Carousel sits at cols 2–6 of the 6-col block — 4 cols wide, inset 1 each side,
   matching the Who We Are image. */
.sec-positioning__carousel-block .carousel {
  grid-column: 2 / 6;
}
/* Safari static fallback — JS detects Safari, adds .is-carousel-static to <html>
   and returns before cloning. Without clones the track's min-content = block width
   so aspect-ratio resolves correctly and the section height is normal.
   The dedicated .carousel__safari-img sits at the same inset, square, as Who We Are. */
.carousel__safari-img {
  display: none;
}
.is-carousel-static .sec-positioning__carousel-block .carousel {
  display: none;
}
.is-carousel-static .carousel__safari-img {
  display: block;
  grid-column: 2 / 6;
  align-self: center;
  aspect-ratio: 1 / 1;
  width: 100%;
  height: auto;
  object-fit: cover;
}

/* =====================================================================
   Carousel — horizontal strip of vertical images inside Positioning block 2.
   Image height = a 4-column block height. Widths vary (auto from aspect).
   30px gaps. One image centred in the block; neighbours cropped by the
   block's overflow:hidden. Auto-advances every 3s; a sticky scroll moment
   advances 3 images (driven by JS).
   ===================================================================== */
:root {
  /* Height of a 4-col block (square): 4 columns + 3 gutters wide of the
     content area. */
  --carousel-h: calc((4 * var(--do-col)) + (3 * var(--gutter)));
}
.carousel {
  position: relative;
  width: 100%;
  height: var(--carousel-h);
  flex: 0 0 auto;                       /* don't stretch; allow vertical centring */
  align-self: center;
  overflow: hidden;
}
.carousel__track {
  display: flex;
  gap: var(--gutter);                   /* 30px between images */
  height: 100%;
  align-items: stretch;
  /* JS sets transform: translateX() to centre the active image. */
  will-change: transform;
}
.carousel__img {
  height: 100%;
  width: auto;                          /* width varies with the image */
  flex: 0 0 auto;
  object-fit: cover;
  display: block;
  /* Fallback so a missing/slow image still occupies space (grey box) rather
     than collapsing the track to nothing. Real images override via aspect. */
  min-width: calc(var(--carousel-h) * 0.62);
  background: var(--c4);
}

/* =====================================================================
   SECTION 2 — Who We Are
   2-block module. Block 1: image inset (4 cols, centred in the block).
   Block 2: content inset (4 cols, centred in the block) — title, body, CTA
   stacked, top + left aligned inside the inset.
   ===================================================================== */
/* Image inset: 4-col-wide box centred in its 6-col block.
   CONTENT: image (grey placeholder for now). */
.sec-who__media {
  grid-column: 2 / 6;                   /* 4 cols centred within the 6-col block */
  align-self: center;                   /* vertically centred in the block */
  background: var(--c4);                /* grey behind the image while it loads */
  aspect-ratio: 1 / 1;                  /* square (adjust to real image ratio) */
  overflow: hidden;
}
.sec-who__media-img {
  width: 100%;
  height: 100%;
  object-fit: cover;                    /* fill the square, centred, no gaps */
  object-position: center center;
  display: block;
}
/* Content inset: 4-col-wide box centred in its 6-col block, no fill. */
.sec-who__inset {
  grid-column: 2 / 6;                   /* 4 cols centred within the 6-col block */
  align-self: center;                   /* inset vertically centred in the block */
  display: flex;
  flex-direction: column;
  gap: var(--gutter);                   /* 30px between title / body / CTA */
  padding: var(--inset-pad) var(--inset-pad) 0;  /* block padding: top + sides */
  align-items: flex-start;              /* content left-aligned */
  text-align: left;
}
.sec-who__title {                       /* CONTENT: title (default_title) */
  margin: 0;
  color: var(--c1);
}
.sec-who__body {                        /* CONTENT: body (default_body) */
  margin: 0;
  color: var(--c1);
}
.sec-who__cta { align-self: flex-start; }   /* CTA hugs its content, left */

/* =====================================================================
   SECTION 3 — Trust Bar
   3-block module. Each block: large stat (large_title, weight 100) over a
   small label (default_body). Both centred horizontally and vertically.
   ===================================================================== */
.sec-trust .block {
  gap: var(--gutter);
}
.sec-trust__stat {                      /* CONTENT: stat — large_title size, one-off wght/wdth */
  margin: 0;
  color: var(--c1);
  font-variation-settings: "wght" 200, "wdth" 100;   /* one-off for this module */
}
.sec-trust__label {                     /* CONTENT: label — default_body */
  margin: 0;
  color: var(--c1);
}

/* =====================================================================
   SECTION 4 — What We Do
   Three rows, each a 4-block module. Per row: blocks 1+2 merge into one
   image block (6 cols wide) but kept to a SINGLE block's height (3-col
   square), block 3 holds the content stack, block 4 is empty.
   Rows are separated by 1px keylines (CTA grey @ 20%): line / row / line
   / row / line / row / line.
   ===================================================================== */
:root {
  --keyline: rgba(54, 57, 66, 0.20);    /* #363942 at 20% */
  /* Height of one 3-col block kept square. Content width = 100vw - 2*30px
     page margins; column = (contentW - 11 gutters) / 12; a 3-col square
     side = 3 columns + 2 gutters. */
  --do-col: calc((100vw - (2 * var(--page-margin)) - (11 * var(--gutter))) / 12);
  --do-row-h: calc((3 * var(--do-col)) + (2 * var(--gutter)));
}

/* Keyline rules between and around the rows. Inset 30px each side to match
   the page margins. Implemented as their own 1px elements so the rows can
   carry their own white background + padding for the collapse. */
.sec-do__line {
  height: 1px;
  margin: 0 var(--page-margin);         /* inset to page margins */
  background: var(--keyline);
}

/* Each row: solid white background with 30px top and bottom padding, so as
   rows collapse and overlap there is always a white border between images. */
.sec-do__row {
  background: var(--c6);
  padding-top: 30px;
  padding-bottom: 30px;
}

/* ---- Collapse-on-scroll (pinned stage) -----------------------------
   The stage (rows + keylines) is pinned under the bar by JS while the
   section scrolls through its reserved window. Rows collapse in sequence,
   scrubbed 1:1 with scroll. Collapsed rows stay stacked; row 3 never
   collapses. JS sets the grid height per row; the image crops vertically.
   -------------------------------------------------------------------- */
.sec-do__stage {
  background: var(--c6);        /* white, so pinned content covers what's behind */
  width: 100%;
}
/* The grid inside a collapsing row is clipped to its JS-driven height. */
.sec-do__row .module__grid {
  overflow: hidden;
}
/* Image crops vertically as the row height shrinks. */
.sec-do__media {
  grid-column: span 6;
  background: var(--c4);                /* grey placeholder */
  overflow: hidden;
  height: 100%;
}
.sec-do__media-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center center;
  display: block;
}

/* Merged image block: spans 6 cols, height of a single 3-col square. */
.sec-do__media {
  grid-column: span 6;
  background: var(--c4);                /* grey placeholder */
}

/* Content block: 3 cols. Title, body and CTA form one top-aligned stack,
   with 30px between each item. */
.sec-do__content {
  grid-column: span 4;
  display: flex;
  flex-direction: column;
  align-items: flex-start;              /* left */
  text-align: left;
  padding: 0 var(--gutter);             /* sides only; row gives vertical pad */
  gap: 0;                               /* explicit spacing below, not a flat gap */
}
.sec-do__title {                        /* CONTENT: title (default_title) */
  margin: 0;
  color: var(--c1);
}
.sec-do__body {                         /* CONTENT: body (default_body) */
  margin: 30px 0 0;                     /* 30px below the title */
  color: var(--c1);
}
.sec-do__cta {
  margin-top: 30px;
  align-self: flex-start;
}

/* Empty 4th block (2 cols; content widens to 4 to fit long titles on 1 line). */
.sec-do__empty {
  grid-column: span 2;
}

/* The square height for the row: drive all three children to the single
   3-col block height via the image's height using aspect-ratio on a sizer. */
.sec-do__media,
.sec-do__content,
.sec-do__empty {
  /* height equals a 3-col square; computed from the grid below */
  min-height: var(--do-row-h);
}

/* =====================================================================
   SECTION — Our Difference (staggered)
   One module containing two independently stacked columns. The right column
   begins lower, preserving the stagger without two square module rows.
   ===================================================================== */
.sec-craft > .sec-do-title + .module { margin-top: var(--title-gap); } /* title -> first content */

.sec-craft__grid { align-items: start; }
.sec-craft__column {
  grid-column: span 6;
  display: grid;
  grid-template-columns: subgrid;
  row-gap: 190px;
}
.sec-craft__column--staggered {
  padding-top: calc(var(--do-col) + var(--gutter));
}
.sec-craft__inset {
  grid-column: 2 / 6;                   /* 4 cols centred within the 6-col block */
  display: flex;
  flex-direction: column;
  gap: var(--gutter);                   /* 30px between icon / title / body */
  align-items: flex-start;              /* left-aligned stack */
  text-align: left;
  padding: var(--inset-pad);            /* 30px */
}

/* Navy icon square: fixed stepped sizes rather than fluid column-derived.
   Fluid scaling made it too large at wide viewports. */
.sec-craft__icon {
  position: relative;
  width: 100px;
  aspect-ratio: 1 / 1;
  background: #000B44;
  overflow: hidden;
  display: grid;
  place-items: center;
}
.sec-craft__icon-img {
  width: 40%;
  height: 40%;
  object-fit: contain;
}
.sec-craft__num {
  font-family: var(--font);
  font-size: 2.6rem;
  font-variation-settings: 'wght' 250, 'wdth' 100;
  color: var(--c6);
  line-height: 1;
  letter-spacing: -0.01em;
}
.sec-craft__title { margin: 0; color: var(--c1); }
.sec-craft__body  { margin: 0; color: var(--c1); width: 75%; }

/* =====================================================================
   SECTION — Featured Work
   Title module (normal margins) + edge-to-edge wide image bands. Each band
   is full-width, 6 columns tall, grey placeholder, with project metadata
   centred vertically and spread across the width (like the hero State 2).
   30px white gaps between projects.
   ===================================================================== */
.sec-featured {
  /* break out to full viewport width for the bands */
}
/* Each project band: full-bleed width, 6-col-tall height. */
.feat-project {
  display: block;           /* <a> elements default to inline — force block */
  text-decoration: none;    /* no underline on <a> */
  color: inherit;
  position: relative;
  width: 100%;
  /* The 30px break belongs to the following project so its cursor treatment
     remains active while crossing between image bands. */
  height: calc((4 * var(--do-col)) + (3 * var(--gutter)) + var(--title-gap));
}
.feat-project__media {
  position: absolute;
  inset: var(--title-gap) 0 0;
  background: var(--c1);               /* dark fill: as image fades out on hover, charcoal bleeds through, darkening */
  overflow: hidden;
}
.feat-project__media::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, rgba(0,0,0,0.50) 0%, transparent 55%);
  pointer-events: none;
  z-index: 1;
}
.feat-project__media-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  display: block;
}
/* Metadata overlay: respects page margins, vertically centred over the band. */
.feat-project__overlay {
  position: absolute;
  inset: var(--title-gap) 0 0;
  padding: 0 var(--page-margin);
  display: flex;
  align-items: center;                 /* vertical centre */
}
.feat-project__meta {
  width: 100%;
  display: grid;
  grid-template-columns: repeat(3, 1fr);   /* spread across the width */
  column-gap: var(--gutter);
}
.feat-meta__cell {
  display: flex;
  flex-direction: column;
  gap: 6px;
  color: var(--c6);                    /* white over the image */
  width: max-content;
  padding: 10px 15px;
  background: transparent;
  -webkit-backdrop-filter: blur(0);
  backdrop-filter: blur(0);
  border: 0.5px solid transparent;
  box-shadow: none;
  transition:
    background 420ms cubic-bezier(0.9, 0, 0.1, 1),
    border-color 420ms cubic-bezier(0.9, 0, 0.1, 1),
    box-shadow 420ms cubic-bezier(0.9, 0, 0.1, 1),
    backdrop-filter 420ms cubic-bezier(0.9, 0, 0.1, 1),
    -webkit-backdrop-filter 420ms cubic-bezier(0.9, 0, 0.1, 1);
}
.feat-project:hover .feat-meta__cell,
.feat-project.is-active .feat-meta__cell {
  background: rgba(255, 255, 255, 0.10);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  border-color: rgba(255, 255, 255, 0.30);
}
.feat-project__media-img {
  transition: opacity 420ms cubic-bezier(0.9, 0, 0.1, 1);
}
.feat-project:hover .feat-project__media-img,
.feat-project.is-active .feat-project__media-img {
  opacity: 0.72;
}
@media (prefers-reduced-motion: reduce) {
  .feat-project__media-img { transition: none; }
}
.feat-meta__cell:nth-child(2) { justify-self: center; }
.feat-meta__cell:nth-child(3) { justify-self: end; }
.feat-meta__cell .hdr-meta__label,
.feat-meta__cell .hdr-meta__value { color: var(--c6); margin: 0; }
/* Mirror the hero metadata transition: bold_body at rest, growing and
   changing variable-font weight/width when its project is hovered. */
.feat-meta__cell .hdr-meta__value {
  --meta-wght: var(--bold-body-wght);
  --meta-wdth: var(--bold-body-wdth);
  font-size: var(--bold-body-size);
  line-height: var(--bold-body-lh);
  font-variation-settings: "wght" var(--meta-wght), "wdth" var(--meta-wdth);
  transition:
    font-size 420ms cubic-bezier(0.9, 0, 0.1, 1),
    line-height 420ms cubic-bezier(0.9, 0, 0.1, 1),
    --meta-wght 420ms cubic-bezier(0.9, 0, 0.1, 1),
    --meta-wdth 420ms cubic-bezier(0.9, 0, 0.1, 1);
}
.feat-project:hover .feat-meta__cell .hdr-meta__value,
.feat-project.is-active .feat-meta__cell .hdr-meta__value {
  --meta-wght: var(--default-title-wght);
  --meta-wdth: var(--default-title-wdth);
  font-size: 26px;
  line-height: var(--default-title-lh);
}

/* =====================================================================
   SECTION — Testimonials
   Title + three 4-block modules. Per module: image cell (2-col image,
   vertically centred, RIGHT-aligned) | merged quote (6 cols, default_title
   light) | attribution (name + 5 stars + Google review).
   ===================================================================== */
.sec-testimonials > .sec-testimonial + .sec-testimonial { margin-top: var(--section-gap); }
.sec-testimonials > .sec-do-title + .sec-testimonial { margin-top: var(--title-gap); }

/* Image cell: hidden globally until real photography is available. */
.sec-testimonial__imgcell { display: none; }

/* Quote: was 6 cols; absorbs the 3 cols the image cell occupied → 9 cols. */
.sec-testimonial__quote {
  grid-column: span 9;
  display: flex;
  align-items: center;
  padding: var(--gutter);
  min-height: var(--do-row-h);             /* matches grid row height used throughout */
}
.sec-testimonial__quotetext {
  margin: 0;
  color: var(--c1);
  font-size: var(--default-title-size);
  line-height: var(--default-title-lh);
  font-variation-settings: "wght" 200, "wdth" 100;   /* light */
  max-width: 640px;
}

/* Attribution: name, stars, source. */
.sec-testimonial__attr {
  aspect-ratio: auto;
  justify-content: center;              /* vertical centre */
  align-items: flex-start;
  text-align: left;
  gap: var(--gutter);
}
.sec-testimonial__name { margin: 0; color: var(--c1); }
.sec-testimonial__stars { color: var(--accent); letter-spacing: 2px; font-size: 18px; }
.sec-testimonial__source { margin: 0; color: var(--c1); }

/* =====================================================================
   SECTION — Our Story (horizontal timeline carousel)
   Image, date-box, image, date-box... Images 5:3, 4-col tall. Date boxes
   are 2-col wide with two years and a centred line. Horizontal trackpad
   gestures and the arrow controls move the track; vertical scroll remains
   normal. The focused image settles 30px from the left edge.
   ===================================================================== */
.sec-story { --four: calc((4 * var(--do-col)) + (3 * var(--gutter))); }   /* 4-col length */
.story-carousel {
  position: relative;
  width: 100%;
  height: var(--four);                  /* 4-col tall band */
  overflow: hidden;
}
/* The section remains in normal vertical flow. Horizontal trackpad gestures
   move the timeline; ordinary vertical scrolling passes straight through. */
.story-pin-track {
  position: relative;
  height: auto;
}
.story-pin {
  position: relative;
}
.story-carousel__track {
  display: flex;
  gap: var(--gutter);                   /* 30px between items */
  height: 100%;
  align-items: flex-end;                /* BOTTOM-aligned to the module */
  padding-left: var(--page-margin);     /* focused image settles 30px from edge */
  will-change: transform;
  transform: translate3d(0, 0, 0);
}
.story-item { flex: 0 0 auto; }

/* Images: 5:3 ratio, but the LONGEST edge is capped at 4 columns.
   --four = 4-col length. Landscape: width = 4 cols, height = 3/5 of that.
   Portrait: height = 4 cols, width = 3/5 of that. */
.story-item--img {
  background: var(--c4);                /* grey placeholder */
  background-size: cover;
  background-position: center;
}
.story-item--landscape {               /* wide: long edge = width */
  width: var(--four);
  height: calc(var(--four) * 3 / 5);
}
.story-item--portrait {                /* tall: long edge = height */
  height: var(--four);
  width: calc(var(--four) * 3 / 5);
}

/* Date box: 2-col wide; top year (left), centred line, bottom year (right).
   Years sit 30px above/below the line. Bottom-aligned in the module. */
.story-item--dates {
  width: calc((2 * var(--do-col)) + (1 * var(--gutter)));
  height: var(--four);
  display: flex;
  flex-direction: column;
  justify-content: flex-end;            /* bottom-aligned */
}
.story-dates__year { margin: 0; color: var(--c1); }
.story-dates__year--top    { text-align: left; margin-bottom: 30px; }
.story-dates__year--bottom { text-align: right; margin-top: 30px; }
.story-dates__line { height: 1px; width: 100%; background: var(--keyline); }

/* Caption module below the carousel. Editable copy merges the first two
   blocks of the four-block module. */
.sec-story-caption__cell {
  grid-column: span 6;
  align-items: flex-start;
  text-align: left;
  padding: var(--gutter) var(--gutter) 0;
}
.sec-story-caption__copy {
  display: flex;
  flex-direction: column;
  gap: var(--gutter);
  width: 100%;
  opacity: 1;
  transform: translateY(0);
  filter: blur(0);
  transition:
    opacity 240ms cubic-bezier(0.8, 0, 0.2, 1),
    transform 320ms cubic-bezier(0.8, 0, 0.2, 1),
    filter 240ms cubic-bezier(0.8, 0, 0.2, 1);
}
.sec-story-caption__title,
.sec-story-caption__body {
  margin: 0;
  color: var(--c1);
  text-align: left;
}
.sec-story-caption__copy.is-leaving {
  opacity: 0;
  transform: translateY(-10px);
  filter: blur(2px);
}
.sec-story-caption__copy.is-entering {
  opacity: 0;
  transform: translateY(12px);
  filter: blur(2px);
  transition: none;
}

@media (prefers-reduced-motion: reduce) {
  .sec-story-caption__copy { transition: none; }
}

/* =====================================================================
   SECTION — Gallery CTA
   Full-bleed image prompting the visitor to view the portfolio gallery.
   Dark gradient bottom-half; title, label and CTA over image.
   ===================================================================== */
.sec-gallery-cta {
  position: relative;
  width: 100%;
  height: clamp(360px, 55vh, 680px);
  overflow: hidden;
}
.sec-gallery-cta__media {
  position: absolute;
  inset: 0;
  background: var(--c1);              /* charcoal placeholder */
}
.sec-gallery-cta__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.sec-gallery-cta__overlay {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  padding: 60px var(--page-margin);
  gap: 20px;
  background: rgba(33, 36, 41, 0.45);
  color: var(--c6);
  text-align: center;
}
.sec-gallery-cta__title {
  margin: 0;
  color: var(--c6);
  font-variation-settings: "wght" 200, "wdth" 100;
}

@media (max-width: 481px) {
  .sec-gallery-cta {
    height: auto;
    aspect-ratio: 4 / 5;
  }
  .sec-gallery-cta__overlay { padding: 40px var(--page-margin); gap: 16px; }
  .sec-gallery-cta__title {
    font-size: var(--default-title-size);
    line-height: var(--default-title-lh);
    font-variation-settings: "wght" 200, "wdth" 100;
    text-align: center;
  }
}

/* =====================================================================
   SECTION — Get in Touch
   Title + 2-block module. Left: invitation + contact details (4-col inset,
   centred). Right: enquiry form (4-col inset, centred). Mirrors the Who We
   Are 2-block subgrid pattern.
   ===================================================================== */
.body-flow > .sec-contact { margin-top: var(--section-gap); }

/* Uniform title-module -> content gap across the post-hero sections. */
.sec-story .sec-do-title + .story-carousel { margin-top: var(--title-gap); }
.sec-contact > .sec-do-title + .module { margin-top: var(--title-gap); }

.sec-contact__inset {
  grid-column: 2 / 6;                   /* 4 cols centred within the 6-col block */
  align-self: center;
  display: flex;
  flex-direction: column;
  gap: var(--gutter);                   /* 30px */
  align-items: flex-start;
  text-align: left;
}
.sec-contact__intro { margin: 0; color: var(--c1); }

.sec-contact__details { display: flex; flex-direction: column; gap: var(--gutter); width: 100%; }
.sec-contact__detail { display: flex; flex-direction: column; gap: 4px; }
.sec-contact__label { margin: 0; color: var(--c2); }
.sec-contact__value { margin: 0; color: var(--c1); }

/* Enquiry form */
.sec-contact__form {
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: var(--gutter);                   /* field to field, textarea to button, button to note */
  align-items: flex-start;
  text-align: left;
}
.sec-contact__field { display: flex; flex-direction: column; gap: calc(var(--gutter) / 3); width: 100%; }
.sec-contact__flabel { margin: 0; color: var(--c1); text-align: left; }
.sec-contact__input {
  width: 100%;
  padding: 12px 15px;
  border: 1px solid var(--keyline);     /* 20% grey keyline */
  background: var(--c6);
  color: var(--c1);
  font-family: var(--font-family);
}
.sec-contact__input:focus { outline: none; border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); }
.sec-contact__textarea { resize: vertical; min-height: 110px; }
.sec-contact__cta {
  align-self: flex-start;
  background: var(--cta-fill);
  border-color: var(--cta-fill);
  color: var(--c6);
}
/* Privacy notice under the submit button (UK GDPR: inform at point of collection) */
.sec-contact__note { margin: 0; color: var(--c1); text-align: left; }
.sec-contact__note a { text-decoration: underline; }
.sec-contact__note a:hover,
.sec-contact__note a:focus-visible { color: var(--c-action); }

/* =====================================================================
   FOOTER — charcoal, reversed out. Echoes the logo's solid dark square.
   ===================================================================== */
.ew-footer {
  background: var(--c-dark);            /* Dark Grey — deepest ground */
  color: var(--c6);
  margin-top: var(--section-gap);
  padding: var(--section-gap) 0 var(--gutter);
}
.ew-footer__top { padding-bottom: var(--section-gap); }

.ew-footer__brand { align-items: flex-start; text-align: left; gap: var(--gutter); padding-top: 0; }
.ew-footer__logo { display: block; height: var(--logo-h); color: var(--c6); }
.ew-footer__logo .hdr-logo__svg { height: 100%; width: auto; }
.ew-footer__tagline { margin: 0; color: var(--c5); }

.ew-footer__col { align-items: flex-start; text-align: left; gap: 12px; padding-top: 0; }
.ew-footer__heading { margin: 0 0 6px; color: var(--c6); }
.ew-footer__nav { display: flex; flex-direction: column; gap: 12px; }
.ew-footer__link { margin: 0; color: var(--c5); transition: color 200ms var(--ease); }
a.ew-footer__link:hover { color: var(--accent); }

.ew-footer__base { padding-top: var(--gutter); border-top: 1px solid rgba(255,255,255,0.15); }
.ew-footer__legal-left { align-items: flex-start; text-align: left; padding-top: 0; gap: calc(var(--gutter) / 3); }
.ew-footer__legal-right { flex-direction: row; justify-content: flex-end; align-items: center; gap: var(--gutter); padding-top: 0; }
.ew-footer__legal { margin: 0; color: var(--c2); }

/* =====================================================================
   Our Story — prev/next arrow nav buttons
   Same button shell as the rest of the site. The pair sits at the top-right
   of the far-right caption block; each arrow nudges in its travel direction.
   ===================================================================== */
.sec-story-caption__nav {
  align-items: flex-end;
  justify-content: flex-start;
  padding: var(--gutter) 0 0 var(--gutter);
}
.story-nav { display: flex; gap: 15px; }

/* Square-ish icon button: same vertical/horizontal padding as the text
   buttons (10px/15px) around a fixed icon box. */
.btn--nav {
  --nav-icon: 16px;
  padding: 10px 15px;
}
.btn--nav::after { content: none; display: none; }   /* no text pseudo here */
.btn--nav .nav-arrow {
  width: var(--nav-icon);
  height: var(--nav-icon);
  display: block;
  transition: transform 300ms cubic-bezier(0.9, 0, 0.1, 1);
}
.btn--nav:hover .nav-arrow,
.btn--nav:focus-visible .nav-arrow { transform: translateX(var(--nav-nudge, 0)); }
.btn--nav[data-dir="prev"] { --nav-nudge: -3px; }
.btn--nav[data-dir="next"] { --nav-nudge: 3px; }
@media (prefers-reduced-motion: reduce) {
  .btn--nav .nav-arrow { transition: none; }
}

/* =====================================================================
   Frosted "View project" button revealed on image hover
   Same button sizing/logic as the rest of the site, but the fill is the
   frosted-glass texture used by the menu bar in State 2 (3% white tint +
   blur + 0.5px white@50% stroke). Centred over the image; fades in on hover.
   ===================================================================== */
.btn--frost {
  background: rgba(255, 255, 255, 0.03);
  -webkit-backdrop-filter: blur(4.8px);
  backdrop-filter: blur(4.8px);
  border: 0.5px solid rgba(255, 255, 255, 0.50);   /* same stroke as the menu bar */
  color: var(--c6);                                /* white label over image */
}
/* One fixed button becomes the cursor over project imagery. It sits above
   all image content, so its backdrop-filter can also blur overlaid type. */
.project-cursor {
  position: fixed;
  top: 0;
  left: 0;
  transform: translate3d(
    calc(var(--cursor-x, 0px) - 50%),
    calc(var(--cursor-y, 0px) - 50%),
    0
  );
  scale: 0.88;
  opacity: 0;
  pointer-events: none;
  transition:
    opacity 220ms cubic-bezier(0.8, 0, 0.2, 1),
    scale 320ms cubic-bezier(0.8, 0, 0.2, 1);
  z-index: 10000;
  white-space: nowrap;
  will-change: transform;
}
.project-cursor.is-visible {
  opacity: 1;
  scale: 1;
}
.feat-project,
.ew-header.is-state-1 .ew-header__hero,
.ew-header.is-state-2 .ew-header__hero { cursor: none; }

/* =====================================================================
   RESPONSIVE — phone tier only
   ---------------------------------------------------------------------
   601px and above keeps the desktop 12-column/block layout. The 820px
   breakpoint may still tune scale/spacing via tokens, but it should not
   introduce a separate structural layout. The first structural adjustment
   starts at 600px, and the true stacked mobile layout starts at 481px.
   ===================================================================== */

/* First breakpoint: keep the desktop block structure, but let the text
   insets in the first two modules use their full parent block width. */
@media (max-width: 820px) { /* --bp-soft: tuning breakpoint */
  .sec-craft__icon { width: 90px; }

  /* Footer: the email address no longer fits a 3-col block. Brand takes the
     full row; Explore and Contact split it below. Stacks fully at 600. */
  .ew-footer__top .ew-footer__brand { grid-column: 1 / -1; }
  .ew-footer__top .ew-footer__col { grid-column: span 6; }
  .ew-footer__top .module__grid { row-gap: 32px; }

  /* N3 revised: hide Our Story at 820px (not 600px). The section switches to
     vertical card stack here anyway and the content is still placeholder.
     Hiding at the layout-change point prevents the mid-range rough appearance. */
  .sec-story { display: none; }

  .sec-who__inset,
  .sec-positioning__inset {
    grid-column: 1 / -1;
    width: 100%;
    padding: var(--inset-pad) var(--inset-pad) 0;
  }

  /* What We Do — 2+2 layout; image locked to landscape so content height
     doesn't force it square. JS still runs here and measures these heights. */
  .sec-do__media {
    grid-column: 1 / span 6;
    aspect-ratio: 4 / 3;
    min-height: 0;
    height: auto;
    align-self: start;
  }
  .sec-do__content {
    grid-column: 7 / span 6;
    min-height: 0;
  }
  .sec-do__empty {
    display: none;
  }

  /* Our Difference — staggered 2×2 is too tall at this width; stack to a
     single flowing column so the 4 items read top-to-bottom. */
  .sec-craft__column {
    grid-column: 1 / -1;
    row-gap: 60px;
    padding-top: 0;
  }
  .sec-craft__column--staggered {
    padding-top: 0;
    margin-top: 60px;
  }
  .sec-craft__inset {
    grid-column: 1 / 9;
    padding: var(--inset-pad) 0;
  }

  /* Our Story — at 820px and below: switch to vertical card stack.
     JS (story.js) also detects this width and calls initPhone().
     The desktop caption module and date-box items are hidden;
     story.js injects per-image captions into the DOM instead. */
  .story-carousel { height: auto; overflow: visible; }
  .story-carousel__track {
    flex-direction: column;
    height: auto;
    gap: 0;
    padding-left: 0;
    padding-bottom: 0;
    overflow: visible;
    scroll-snap-type: none;
    align-items: flex-start;
  }
  .story-item--img,
  .story-item--portrait,
  .story-item--landscape {
    width: 100%;
    height: auto;
    aspect-ratio: 4 / 3;
    background-size: cover;
    background-position: center;
  }
  .story-item--dates { display: none; }
  .sec-story-caption { display: none; }
  .story-phone-caption { padding: 20px 0 48px; }
  .story-phone-caption__dates { margin: 0 0 6px; color: var(--c2); }
  .story-phone-caption__title { margin: 0 0 10px; color: var(--c1); }
  .story-phone-caption__body { margin: 0; color: var(--c1); }
}

/* Structural adjustments that apply at 600px and below (covers both the
   482–600 mid-range and the full phone layout at 481px). */
@media (max-width: 600px) { /* --bp-structural */
  .sec-craft__icon { width: 80px; }

  /* Testimonials — quote and attribution stack full-width at this width.
     Collapse the gap so the name reads as a direct attribution of the quote. */
  .sec-testimonial .module__grid { row-gap: 0; }
  .sec-testimonial__quote {
    grid-column: 1 / -1;
    padding-bottom: 0;
  }
  .sec-testimonial__attr {
    grid-column: 1 / -1;
    padding: 16px var(--gutter) var(--gutter);
  }

  /* Featured Work — formula height produces a thin ~200px band at 600px;
     clamp to a more usable proportion. Meta stacks left. */
  .feat-project { height: clamp(240px, 45vw, 380px); }
  .feat-project__meta { grid-template-columns: 1fr; row-gap: 6px; }
  .feat-meta__cell,
  .feat-meta__cell:nth-child(2),
  .feat-meta__cell:nth-child(3) { justify-self: start; }

  /* S8: footer Explore + Contact columns (~25% wide) wrap badly in the
     482–600px range. Collapse all footer columns to full-width here
     (the 481px rule only caught the true-phone stack). */
  .ew-footer__top .module__grid > * { grid-column: 1 / -1; }
  .ew-footer__top .module__grid { row-gap: 32px; }

  /* Contact section: force both halves (info + form) to full-width and
     clip any overflow so nothing bleeds past the page margin. */
  .sec-contact .module__grid > .block { grid-column: 1 / -1; }
  .sec-contact { overflow-x: hidden; }
  .sec-contact__inset { width: 100%; min-width: 0; grid-column: 1 / -1; }
  .sec-contact__input { min-width: 0; }
  /* Contact halves hug their content. Left square, the tall form block took
     its height as its width and ran past the viewport. */
  .sec-contact .module__grid > .block { aspect-ratio: auto; }
  .sec-contact .module__grid { row-gap: calc(var(--gutter) * 2); }
}

/* Positioning module exception for the middle responsive range: keep the
   desktop grid language, but stack the carousel above the copy on the left. */
@media (min-width: 482px) and (max-width: 600px) {
  .sec-who .module__grid > .block:first-child {
    grid-column: 1 / -1;
    grid-row: 1;
  }
  .sec-who .module__grid > .block:nth-child(2) {
    grid-column: 1 / -1;
    grid-row: 2;
    aspect-ratio: 2 / 1;
  }
  .sec-who__media,
  .sec-who__inset {
    grid-column: 1 / -1;
    width: 100%;
  }
  .sec-who__inset {
    align-self: start;
  }

  .sec-positioning {
    --carousel-h: calc(100vw - (2 * var(--page-margin)));
  }
  .sec-positioning .module__grid > .sec-positioning__carousel-block {
    grid-column: 1 / -1;
    grid-row: 1;
  }
  .sec-positioning .module__grid > .block.block--subgrid {
    grid-column: 1 / -1;
    grid-row: 2;
    aspect-ratio: auto; /* text block hugs content; specificity matches base rule */
  }
  .sec-positioning__carousel-block .carousel {
    grid-column: 1 / -1;               /* full-width at this breakpoint */
    width: 100%;
    height: var(--carousel-h);
  }
  /* Static single image — carousel JS returns early at ≤600px */
  .sec-positioning__carousel-block .carousel__track { transform: none !important; }
  .sec-positioning__carousel-block .carousel__img:not(:first-child) { display: none; }
  .sec-positioning__carousel-block .carousel__img:first-child {
    width: 100%;
    height: 100%;
    object-fit: cover;
  }
  .sec-positioning__inset {
    grid-column: 1 / -1;
    width: 100%;
  }
  .sec-positioning__inset {
    align-self: start;
  }

}

@media (max-width: 481px) {
  :root {
    --mobile-block-square: calc(100vw - (2 * var(--page-margin)));
    --do-row-h: var(--mobile-block-square);
  }

  .module__grid > * { grid-column: 1 / -1 !important; }
  .module__grid > [aria-hidden="true"] { display: none !important; }

  .body-flow .module .block:not(.block--auto-h) {
    aspect-ratio: 1 / 1;
  }

  /* Text-content subgrid blocks hug content — no forced square at phone.
     Specificity must match the general rule (0,4,0) so we add .block to the chain. */
  .sec-who .block.block--subgrid:last-child,
  .sec-positioning .block.block--subgrid:not(.sec-positioning__carousel-block),
  .sec-contact .module .block.block--subgrid {
    aspect-ratio: auto;
  }

  .block--subgrid { display: block !important; }
  .block--subgrid > * { grid-column: 1 / -1 !important; }

  /* Who We Are — image left-aligned, text full-width to match Positioning section */
  .sec-who__media {
    aspect-ratio: 1 / 1;
    width: 80%;
    height: auto;
    margin-right: auto;
  }
  .sec-who__inset {
    width: 100%;
    padding: 24px 0 0;
  }

  /* Positioning: image carousel first, then copy. */
  .sec-positioning {
    --carousel-h: var(--mobile-block-square);
  }
  .sec-positioning .module__grid > .sec-positioning__carousel-block { order: 1; }
  .sec-positioning .module__grid > .block--subgrid { order: 2; }
  .sec-positioning__carousel-block {
    margin-top: 0;
    padding: 0;
    align-content: center;
  }
  .sec-positioning__carousel-block .carousel {
    grid-column: 1 / -1;               /* full-width at phone */
    width: 100%;
    height: var(--carousel-h);
  }
  .sec-positioning__carousel-block .carousel__track {
    align-items: center;
    transform: none !important;
  }
  /* Static single image at phone — carousel JS returns early at ≤600px */
  .sec-positioning__carousel-block .carousel__img:not(:first-child) { display: none; }
  .sec-positioning__carousel-block .carousel__img:first-child {
    width: 100%;
    height: 100%;
    object-fit: cover;
  }
  .sec-positioning__inset {
    padding: 24px 0 0;    /* N2: zero side padding — page-margin is the only inset */
    margin-top: 0;
  }

  /* Trust Bar — stacked, centred at phone. Each stat is its own statement:
     large number, quiet label, deliberate border between items. */
  .sec-trust .module__grid {
    row-gap: 0;
  }
  .sec-trust .module__grid > * {
    grid-column: 1 / -1 !important;
    text-align: center;
    align-items: center;
    padding: 40px 0;
    border-top: 0.5px solid rgba(54, 57, 66, 0.18);
  }
  .sec-trust .module__grid > *:first-child {
    padding-top: 0;
    border-top: none;
  }
  .sec-trust .block {
    gap: 8px;
  }
  .sec-trust__stat {
    font-size: clamp(64px, 16vw, 80px);
  }

  /* What We Do */
  .sec-do__stage { width: 100%; }
  .sec-do__row .module__grid { overflow: hidden; }
  .sec-do__content { padding: 24px 0 0; }
  .sec-do__empty { display: none; }

  /* Our Difference */
  .sec-craft__column {
    display: block;
    row-gap: 0;
    padding-top: 0;
  }
  .sec-craft__column--staggered {
    margin-top: 0;
    padding-top: 0;
  }
  .sec-craft__inset {
    grid-column: 1 / -1;
    width: 100%;
    padding: 0;
  }
  .sec-craft__inset + .sec-craft__inset,
  .sec-craft__column + .sec-craft__column {
    margin-top: 72px;
  }
  .sec-craft__body { width: 100%; }
  .sec-craft__icon { width: 72px; }

  /* Featured Work */
  .feat-project { height: clamp(280px, 60vh, 460px); }
  .feat-project__meta { grid-template-columns: 1fr; row-gap: 8px; }
  .feat-meta__cell,
  .feat-meta__cell:nth-child(2),
  .feat-meta__cell:nth-child(3) { justify-self: start; }

  /* Contact */
  .sec-contact .block--subgrid > * { grid-column: 1 / -1 !important; }
  .sec-contact__inset { grid-column: 1 / -1 !important; width: 100%; max-width: 100%; min-width: 0; overflow-wrap: break-word; }
  .sec-contact__input { min-width: 0; }
  .sec-contact { overflow-x: hidden; }

  /* Footer */
  .ew-footer__top .module__grid { row-gap: 32px; }
}
