/* ==========================================================================
   LUXURY MEDIA WALL — Section components
   Projects · Modal · Before/After · Services · Why · Process · Configurator
   Materials · Detail gallery · Video · Testimonials · CTA · Contact
   ========================================================================== */

/* ===================== MARQUEE (capability strip) ======================== */
.marquee {
  border-block: 1px solid var(--line);
  overflow: hidden; padding-block: 1.25rem; background: var(--white);
  -webkit-mask-image: linear-gradient(to right, transparent, #000 9%, #000 91%, transparent);
          mask-image: linear-gradient(to right, transparent, #000 9%, #000 91%, transparent);
}
.marquee__track { display: flex; width: max-content; animation: marquee 46s linear infinite; }

/* Pause on hover is a pointer affordance. Restricted to devices that
   genuinely hover: Android Chrome can leave :hover stuck on an element
   the finger passed over while scrolling, which paused the strip for the
   rest of the visit with no way for the visitor to release it. */
@media (hover: hover) and (pointer: fine) {
  .marquee:hover .marquee__track { animation-play-state: paused; }
}
.marquee__group { display: flex; align-items: center; flex: none; }
.marquee__group span {
  padding-inline: 2.1rem;
  font-size: .69rem; font-weight: 500; letter-spacing: .26em; text-transform: uppercase;
  color: var(--muted); white-space: nowrap;
  display: inline-flex; align-items: center; gap: 2.1rem;
}
.marquee__group span::after { content: ""; width: 4px; height: 4px; background: var(--champagne); border-radius: 50%; }
@keyframes marquee { to { transform: translateX(-50%); } }

/* ==================== SHOWCASE (drifting photo corridor) ================ */
/* Cards start far behind the page and travel toward the reader, drifting
   outward to the left or right lane as they come. Two mirrored paths, one
   per lane; the stagger between cards is set in JS from SHOWCASE_SECONDS.

   Distances are in cqw - percentages of this section's own width - so the
   whole construction scales with the container rather than the viewport,
   and the geometry holds identically on a phone and a 27in monitor. */
.showcase {
  position: relative; overflow: hidden;
  container-type: inline-size;
  background: var(--ink); color: var(--ivory);
  isolation: isolate;
  /* Every child is absolutely positioned, so the band has no content to
     stand it up. Tall enough for a card to arrive, pass and leave. */
  height: clamp(480px, 66vh, 820px);
}
.showcase__stage {
  position: absolute; inset: 0; z-index: 0; pointer-events: none;
  perspective: 30cqw; perspective-origin: 50% 52%;
}
.showcase__inner { position: absolute; inset: 0; transform-style: preserve-3d; }

.showcase__card {
  position: absolute; left: 50%; top: 52%;
  /* Half the width and height are negated in the margins so the card stays
     centred on its own path; change one and the other three must follow. */
  width: 38cqw; height: 52cqw; margin-left: -19cqw; margin-top: -26cqw;
  overflow: hidden; backface-visibility: hidden;
  border: 1px solid rgba(245, 242, 236, .1);
  animation-duration: var(--showcase-dur, 22s);
  animation-timing-function: linear;
  animation-iteration-count: infinite;
}
.showcase__card img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* Right-hand lane. Sweeps out to the right as it approaches.

   The starting depth matters more than the card size for how large these
   read. Perspective scale is 30 / (30 - z), so a card starting at -258cqw
   is drawn at roughly a ninth of its size and stays small for most of the
   trip. Starting at -132cqw it enters at about a fifth instead, and every
   photograph spends far longer at a legible size. */
@keyframes showcaseR {
  from { transform: translate3d(-11cqw, 0, -132cqw) rotateY(-6deg); }
  to   { transform: translate3d(44cqw, 0, 14cqw) rotateY(-28deg); }
}
/* Left-hand lane: the same path mirrored. */
@keyframes showcaseL {
  from { transform: translate3d(11cqw, 0, -132cqw) rotateY(6deg); }
  to   { transform: translate3d(-44cqw, 0, 14cqw) rotateY(28deg); }
}

/* With no copy set over the band, the scrim's only job is to feather the
   top and bottom edges into the ink so cards enter and leave the frame
   rather than being cut off by a hard border. The centre stays clear. */
.showcase__scrim {
  position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background: linear-gradient(to bottom,
    var(--ink) 0%, rgba(13,13,13,.12) 15%,
    rgba(13,13,13,.12) 85%, var(--ink) 100%);
}

/* Because the geometry is expressed in cqw, a 375px container shrinks the
   whole corridor to match: cards spent most of their life under 40px wide,
   reading as specks rather than photographs. Phones get a wider card and a
   shorter corridor, so each picture arrives large enough to recognise. */
@media (max-width: 720px) {
  .showcase__card {
    width: 76cqw; height: 102cqw; margin-left: -38cqw; margin-top: -51cqw;
  }

  @keyframes showcaseR {
    from { transform: translate3d(-8cqw, 0, -74cqw) rotateY(-5deg); }
    to   { transform: translate3d(52cqw, 0, 12cqw) rotateY(-26deg); }
  }
  @keyframes showcaseL {
    from { transform: translate3d(8cqw, 0, -74cqw) rotateY(5deg); }
    to   { transform: translate3d(-52cqw, 0, 12cqw) rotateY(26deg); }
  }
}

/* A corridor of moving photographs is exactly what reduced motion is for.
   The cards stop where they are and the section reads as a still collage. */
@media (prefers-reduced-motion: reduce) {
  .showcase__card { animation: none !important; }
  .showcase__stage { display: none; }
}

/* ======================= INTRO / STUDIO STATEMENT ======================= */
.intro { display: grid; grid-template-columns: minmax(0,.85fr) minmax(0,1.15fr); gap: clamp(2.5rem, 6vw, 6rem); align-items: start; }

/* ======================= COVERFLOW (featured work) ====================== */
/* A 3D coverflow: the centre card faces the reader square-on, its
   neighbours turn away into the depth on either side.

   Every position is expressed as a `data-pos` value rather than an inline
   style, so JS only decides WHICH slot a card occupies and the geometry
   stays here where it can be tuned. Slots: c (centre), r1/r2 to the right,
   l1/l2 to the left, and everything else parked out of sight. */
/* Set on the page's own light ground rather than a dark band, so the
   photographs are the only dark mass in the section and the carousel sits
   in the same rhythm as the sections either side of it. */
.coverflow { position: relative; overflow: hidden; background: var(--ivory); isolation: isolate; }
.coverflow > .shell { position: relative; z-index: 1; }
.coverflow__eyebrow { color: var(--champagne-dim, #a98c4f); }

.coverflow__stage {
  position: relative; display: flex; align-items: center; justify-content: center;
  height: clamp(620px, 88vh, 860px);
  margin-top: clamp(1.6rem, 3vw, 2.6rem);
  perspective: 1900px;
}

.coverflow__card {
  position: absolute; width: min(560px, 90vw); height: clamp(580px, 82vh, 800px);
  padding: 0; border: 1px solid rgba(23,23,23,.1); background: #171311;
  overflow: hidden; cursor: pointer; color: inherit; font: inherit; text-align: left;
  transform-origin: center center;
  /* The single transition every slot change animates through. */
  transition: transform .8s cubic-bezier(.25, 1, .5, 1),
              opacity .8s cubic-bezier(.25, 1, .5, 1),
              filter .8s cubic-bezier(.25, 1, .5, 1),
              box-shadow .8s cubic-bezier(.25, 1, .5, 1);
}
.coverflow__card img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* --- the five visible slots ------------------------------------------- */
.coverflow__card[data-pos="c"] {
  transform: translateX(0) scale(1) rotateY(0deg);
  opacity: 1; z-index: 30; filter: brightness(1); cursor: default;
  /* Softer on a light ground - the heavy black glow that read as depth on
     the dark band would sit on the ivory as a grey smudge. */
  box-shadow: 0 30px 70px rgba(23,23,23,.28), 0 8px 22px rgba(23,23,23,.12);
}
/* Depth is carried by scale, angle and a light desaturation rather than by
   opacity. Fading a photograph out on a dark ground reads as distance; on
   this ivory one it just reads as a washed-out grey rectangle, so the side
   cards stay nearly opaque and recede by going quieter instead. */
.coverflow__card[data-pos="r1"] { transform: translateX(60%) scale(.84) rotateY(-24deg); opacity: .95; z-index: 20; filter: brightness(.9) saturate(.85); }
.coverflow__card[data-pos="l1"] { transform: translateX(-60%) scale(.84) rotateY(24deg);  opacity: .95; z-index: 20; filter: brightness(.9) saturate(.85); }
.coverflow__card[data-pos="r2"] { transform: translateX(112%) scale(.68) rotateY(-38deg); opacity: .78; z-index: 10; filter: brightness(.82) saturate(.7) blur(1px); }
.coverflow__card[data-pos="l2"] { transform: translateX(-112%) scale(.68) rotateY(38deg); opacity: .78; z-index: 10; filter: brightness(.82) saturate(.7) blur(1px); }
/* Parked: still in the DOM and still animating in, but out of the way. */
.coverflow__card[data-pos="off"] { transform: scale(.4); opacity: 0; z-index: 0; pointer-events: none; }

/* --- caption ---------------------------------------------------------- */
.coverflow__veil {
  position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background: linear-gradient(180deg, rgba(0,0,0,.42) 0%, rgba(0,0,0,.08) 26%,
                              rgba(0,0,0,.68) 60%, rgba(0,0,0,.96) 100%);
}
.coverflow__num {
  position: absolute; top: 1.1rem; right: 1.15rem; z-index: 3;
  font-size: .64rem; font-weight: 600; letter-spacing: .2em; color: rgba(255,255,255,.9);
}
.coverflow__num i { font-style: normal; color: var(--champagne); }

/* Only the centre card's caption is shown; the rest would be unreadable at
   that angle and would fight the photograph. */
.coverflow__body {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 3;
  padding: 1.4rem 1.25rem 1.5rem; text-align: center;
  opacity: 0; transform: translateY(16px);
  transition: opacity .5s var(--ease) .1s, transform .5s var(--ease) .1s;
}
.coverflow__card[data-pos="c"] .coverflow__body { opacity: 1; transform: none; }

/* The card is a real <button>, so its children are spans and every one of
   them needs an explicit display value or the caption sets as one run-on
   line of inline text. */
.coverflow__veil,
.coverflow__body,
.coverflow__title,
.coverflow__rule,
.coverflow__desc { display: block; }
.coverflow__num { display: inline-block; }

.coverflow__title {
  font-family: var(--font-serif); font-size: 1.3rem; line-height: 1.16; color: var(--white);
  text-shadow: 0 3px 12px rgba(0,0,0,.95);
}
.coverflow__rule {
  width: 34px; height: 2px; background: var(--champagne); margin: .65rem auto .55rem;
  box-shadow: 0 0 8px rgba(198,166,107,.7);
}
.coverflow__desc {
  font-size: .8rem; line-height: 1.45; color: rgba(255,255,255,.88);
  max-width: 270px; margin: 0 auto .95rem; text-shadow: 0 2px 8px rgba(0,0,0,.9);
}
.coverflow__cta {
  display: inline-flex; align-items: center; gap: .5rem;
  padding: .58rem 1.2rem;
  background: linear-gradient(135deg, var(--champagne) 0%, #a48256 100%);
  color: #110d0c; font-size: .625rem; font-weight: 700;
  letter-spacing: .17em; text-transform: uppercase;
  box-shadow: 0 4px 14px rgba(0,0,0,.4), 0 0 15px rgba(198,166,107,.28);
}
.coverflow__cta svg { width: 13px; height: 13px; }

/* --- controls --------------------------------------------------------- */
.coverflow__controls {
  display: flex; align-items: center; justify-content: center; gap: 1.15rem;
  margin-top: clamp(1.4rem, 3vw, 2.2rem);
}
.coverflow__arrow {
  width: 50px; height: 50px; border-radius: 50%; flex: none;
  background: var(--white); border: 1px solid var(--line); color: var(--charcoal);
  display: inline-flex; align-items: center; justify-content: center; cursor: pointer;
  box-shadow: 0 4px 14px rgba(23,23,23,.08);
  transition: border-color .3s var(--ease), color .3s var(--ease), background-color .3s var(--ease);
}
.coverflow__arrow svg { width: 19px; height: 19px; }
.coverflow__arrow:hover { border-color: var(--champagne); color: var(--champagne); }

.coverflow__dots { display: flex; align-items: center; gap: .5rem; }
.coverflow__dot {
  height: 8px; width: 8px; border-radius: 9999px; border: 0; padding: 0; cursor: pointer;
  background: rgba(23,23,23,.2);
  transition: width .35s var(--ease), background-color .35s var(--ease);
}
.coverflow__dot[aria-current="true"] { width: 28px; background: var(--champagne); }

@media (max-width: 720px) {
  /* A 90vw card leaves a phone no room for neighbours: the first side card
     was landing 153px over a 338px centre and crowding the caption. The
     card gives back a little width, the sides push out far enough to read
     as a peek, and the second tier is dropped - at this width it was three
     slivers of noise rather than depth. */
  .coverflow__card { width: 78vw; height: clamp(520px, 74vh, 660px); }
  .coverflow__card[data-pos="r1"] { transform: translateX(76%) scale(.78) rotateY(-24deg); }
  .coverflow__card[data-pos="l1"] { transform: translateX(-76%) scale(.78) rotateY(24deg); }
  .coverflow__card[data-pos="r2"],
  .coverflow__card[data-pos="l2"] { opacity: 0; pointer-events: none; }
  .coverflow__stage { height: clamp(560px, 80vh, 700px); }
}

/* Motion here is decoration, not information: the cards land in place and
   the arrows still work. */
@media (prefers-reduced-motion: reduce) {
  .coverflow__card { transition: none; }
  .coverflow__body { transition: none; }
}

/* ================== CFLOW (drag coverflow — services) =================== */
/* Unlike the featured carousel above, position here is continuous: a drag
   moves the ring by a fraction of a card and a flick carries. Every card's
   transform is written by JS each frame, so this file only sets the things
   that do not change per frame. Card width drives pitch, depth and
   perspective, so it is the one measured value. */
.cflow { position: relative; --cflow-card: clamp(230px, 26vw, 360px); }

.cflow__frame {
  /* The vertical padding keeps the card shadows clear of the overflow clip. */
  overflow: hidden; padding-block: 2.5rem;
  cursor: grab; outline: none;
  perspective: calc(var(--cflow-card) * 3);
  /* Horizontal drag is ours; the page keeps vertical scrolling. */
  touch-action: pan-y;
}
.cflow__frame:active { cursor: grabbing; }
.cflow__frame:focus-visible { outline: 2px solid var(--champagne); outline-offset: 4px; }

.cflow__ring {
  position: relative; transform-style: preserve-3d;
  height: calc(var(--cflow-card) * 1.25);   /* 4:5 portrait, as the photography is */
}

.cflow__card {
  position: absolute; left: 50%; top: 0;
  width: var(--cflow-card); height: 100%;
  overflow: hidden; background: var(--ivory-deep);
  will-change: transform, opacity;
  box-shadow: 0 18px 44px rgba(23,23,23,.22);
  border: 1px solid rgba(23,23,23,.08);
}
.cflow__card img { width: 100%; height: 100%; object-fit: cover; display: block; user-select: none; }

.cflow__arrow {
  position: absolute; top: calc(50% - 3.2rem); transform: translateY(-50%);
  width: 46px; height: 46px; border-radius: 50%; z-index: 200;
  background: var(--white); border: 1px solid var(--line); color: var(--charcoal);
  display: inline-flex; align-items: center; justify-content: center; cursor: pointer;
  box-shadow: 0 4px 14px rgba(23,23,23,.1);
  transition: border-color .3s var(--ease), color .3s var(--ease);
}
.cflow__arrow svg { width: 18px; height: 18px; }
.cflow__arrow:hover { border-color: var(--champagne); color: var(--champagne); }
.cflow__arrow--prev { left: 0; }
.cflow__arrow--next { right: 0; }

.cflow__caption { text-align: center; margin-top: .4rem; min-height: 7.5rem; }
.cflow__label {
  display: block; font-size: .6rem; font-weight: 600; letter-spacing: .22em;
  text-transform: uppercase; color: var(--champagne-dim, #a98c4f);
}
.cflow__title {
  display: block; margin-top: .55rem;
  font-family: var(--font-serif); font-size: clamp(1.25rem, 2vw, 1.6rem); color: var(--ink);
}
.cflow__text {
  margin: .6rem auto 0; max-width: 46ch;
  font-size: .88rem; line-height: 1.65; color: var(--muted);
}
.cflow__cta {
  display: inline-flex; align-items: center; gap: .5rem; margin-top: 1rem;
  font-size: .63rem; font-weight: 600; letter-spacing: .2em; text-transform: uppercase;
  color: var(--ink); border-bottom: 1px solid var(--line); padding-bottom: .35rem;
  transition: color .35s var(--ease), border-color .35s var(--ease);
}
.cflow__cta svg { width: 13px; height: 13px; }
.cflow__cta:hover { color: var(--champagne); border-color: var(--champagne); }

.cflow__dots { display: flex; align-items: center; justify-content: center; gap: .45rem; margin-top: 1.4rem; }
.cflow__dot {
  width: 8px; height: 8px; border-radius: 9999px; border: 0; padding: 0; cursor: pointer;
  background: var(--ink); opacity: .22;
  transition: opacity .3s var(--ease), width .3s var(--ease), background-color .3s var(--ease);
}
.cflow__dot[aria-current="true"] { opacity: 1; width: 26px; background: var(--champagne); }

@media (max-width: 720px) {
  .cflow { --cflow-card: 68vw; }
  .cflow__arrow { top: auto; bottom: -.4rem; transform: none; }
  .cflow__arrow--prev { left: .25rem; }
  .cflow__arrow--next { right: .25rem; }
  .cflow__caption { min-height: 9.5rem; padding-inline: 3.4rem; }
}

/* =========================== PROJECT GRID =============================== */
.projects__grid {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(1.2rem, 2.2vw, 2.1rem);
}

/* The whole card is the control, so it is a real <button>; its children are
   spans (button content model) and therefore need explicit display values. */
.project-card {
  position: relative; display: block; width: 100%; padding: 0; text-align: left;
  background: var(--ivory-deep); overflow: hidden; isolation: isolate;
  cursor: pointer; color: inherit; font: inherit;
}
.project-card__media,
.project-card__veil,
.project-card__body,
.project-card__title,
.project-card__line,
.project-card__desc { display: block; }
.project-card__num { display: inline-block; }
.project-card__media { position: relative; overflow: hidden; aspect-ratio: 4 / 5; background: var(--ivory-deep); }
.project-card__media img {
  width: 100%; height: 100%; object-fit: cover;
  transform: scale(1.01);
  transition: transform 1.5s var(--ease), filter 1.5s var(--ease);
}
.project-card:hover .project-card__media img,
.project-card:focus-visible .project-card__media img { transform: scale(1.1); }

/* Dark overlay that rises on hover */
.project-card__veil {
  position: absolute; inset: 0; z-index: 2;
  background: linear-gradient(to top, rgba(11,11,11,.92) 0%, rgba(11,11,11,.62) 38%, rgba(11,11,11,.12) 72%, rgba(11,11,11,0) 100%);
  opacity: .55; transition: opacity .8s var(--ease);
}
.project-card:hover .project-card__veil, .project-card:focus-visible .project-card__veil { opacity: 1; }

.project-card__num {
  position: absolute; top: 1.15rem; left: 1.25rem; z-index: 4;
  font-size: .66rem; font-weight: 600; letter-spacing: .2em; color: rgba(255,255,255,.9);
}
.project-card__num i { font-style: normal; color: var(--champagne); }

.project-card__body {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 4;
  padding: 1.5rem 1.35rem 1.45rem;
}
.project-card__title {
  font-family: var(--font-serif); color: var(--white);
  font-size: clamp(1.16rem, 1.55vw, 1.42rem); line-height: 1.18;
}

/* Gold accent line that draws in under the title */
.project-card__line {
  height: 1px; background: var(--champagne); margin-top: .95rem;
  transform: scaleX(0); transform-origin: left center;
  transition: transform .9s var(--ease) .05s;
}
.project-card:hover .project-card__line, .project-card:focus-visible .project-card__line { transform: scaleX(1); }

.project-card__reveal {
  overflow: hidden;
  display: grid; grid-template-rows: 0fr;
  transition: grid-template-rows .85s var(--ease);
}
.project-card:hover .project-card__reveal, .project-card:focus-visible .project-card__reveal { grid-template-rows: 1fr; }
.project-card__reveal > * { min-height: 0; display: block; }

.project-card__desc {
  margin-top: .95rem; font-size: .855rem; line-height: 1.65;
  color: rgba(255,255,255,.76);
  opacity: 0; transform: translateY(10px);
  transition: opacity .7s var(--ease) .12s, transform .7s var(--ease) .12s;
}
.project-card:hover .project-card__desc, .project-card:focus-visible .project-card__desc { opacity: 1; transform: none; }

.tags { display: flex; flex-wrap: wrap; gap: .45rem; margin-top: 1rem; }
.tag {
  font-size: .575rem; font-weight: 600; letter-spacing: .17em; text-transform: uppercase;
  padding: .38rem .68rem; border: 1px solid rgba(255,255,255,.26); color: rgba(255,255,255,.85);
}
.tag--light { border-color: var(--line); color: var(--muted); }

.project-card__cta {
  display: inline-flex; align-items: center; gap: .6rem; margin-top: 1.25rem;
  font-size: .655rem; font-weight: 600; letter-spacing: .21em; text-transform: uppercase;
  color: var(--champagne);
  opacity: 0; transform: translateY(10px);
  transition: opacity .7s var(--ease) .2s, transform .7s var(--ease) .2s;
}
.project-card:hover .project-card__cta, .project-card:focus-visible .project-card__cta { opacity: 1; transform: none; }
.project-card__cta svg { width: 14px; height: 14px; transition: transform .55s var(--ease); }
.project-card:hover .project-card__cta svg { transform: translateX(5px); }

/* Touch devices never hover, so the card opens itself: the description,
   material tags and call to action are shown without any interaction. */
@media (hover: none) {
  .project-card__veil { opacity: .92; }
  .project-card__line { transform: scaleX(1); }
  .project-card__reveal { grid-template-rows: 1fr; }
  .project-card__desc,
  .project-card__cta { opacity: 1; transform: none; }
  .mat::before { opacity: 1; }
  .mat__meta { grid-template-rows: 1fr; }
  .mat__desc { opacity: 1; }
  .masonry__item::after { opacity: 1; transform: none; }
}

/* =========================== PROJECT MODAL ============================== */
.modal {
  position: fixed; inset: 0; z-index: 120;
  display: grid; place-items: center;
  padding: clamp(.75rem, 3vw, 2.5rem);
  visibility: hidden; pointer-events: none;
}
.modal.is-open { visibility: visible; pointer-events: auto; }

.modal__backdrop {
  position: absolute; inset: 0;
  background: rgba(9,9,9,.72);
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
  opacity: 0; transition: opacity .6s var(--ease-soft);
}
.modal.is-open .modal__backdrop { opacity: 1; }

.modal__panel {
  position: relative; z-index: 2;
  width: min(1120px, 100%); max-height: calc(100vh - clamp(1.5rem, 6vw, 5rem));
  background: var(--ivory); overflow-y: auto; overscroll-behavior: contain;
  display: grid; grid-template-columns: minmax(0, 1.05fr) minmax(0, .95fr);
  box-shadow: var(--shadow-lg);
  opacity: 0; transform: translateY(34px) scale(.985);
  transition: opacity .6s var(--ease), transform .8s var(--ease);
}
.modal.is-open .modal__panel { opacity: 1; transform: none; }

.modal__media { position: relative; background: var(--ivory-deep); min-height: 320px; }
.modal__media img { width: 100%; height: 100%; object-fit: cover; }
.modal__badge {
  position: absolute; top: 1.1rem; left: 1.1rem;
  background: rgba(11,11,11,.62); backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
  color: var(--white); padding: .5rem .85rem;
  font-size: .6rem; font-weight: 600; letter-spacing: .2em;
}
.modal__badge i { font-style: normal; color: var(--champagne); }

.modal__body { padding: clamp(1.75rem, 3.5vw, 3.2rem); }
.modal__close {
  position: absolute; top: 0; right: 0; z-index: 6;
  width: 54px; height: 54px; display: grid; place-items: center;
  background: var(--ink); color: var(--ivory);
  transition: background-color .4s var(--ease), transform .5s var(--ease);
}
.modal__close:hover { background: var(--champagne); color: var(--ink); transform: rotate(90deg); }
.modal__close svg { width: 16px; height: 16px; }

.spec { border-top: 1px solid var(--line); padding-top: 1.05rem; margin-top: 1.05rem; }
.spec:first-of-type { border-top: 0; }
.spec dt {
  font-size: .6rem; font-weight: 600; letter-spacing: .24em; text-transform: uppercase;
  color: var(--champagne-dim); margin-bottom: .45rem;
}
.spec dd { font-size: .93rem; line-height: 1.7; color: var(--charcoal); }

.feature-list { display: grid; gap: .55rem; margin-top: .3rem; }
.feature-list li {
  display: flex; gap: .7rem; align-items: baseline;
  font-size: .89rem; color: var(--muted); line-height: 1.6;
}
.feature-list li::before {
  content: ""; width: 5px; height: 5px; flex: none; margin-top: .5rem;
  background: var(--champagne); transform: rotate(45deg);
}

/* ======================== BEFORE / AFTER SLIDER ========================= */
.ba__grid { display: grid; grid-template-columns: repeat(3, minmax(0,1fr)); gap: clamp(1.2rem, 2.2vw, 2rem); }

.ba-card { background: var(--white); border: 1px solid var(--line-soft); }
.ba-stage {
  position: relative; aspect-ratio: 4 / 3; overflow: hidden;
  cursor: ew-resize; user-select: none; -webkit-user-select: none;
  touch-action: pan-y;
  background: var(--ivory-deep);
}
.ba-stage img, .ba-stage .ba-before {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
  pointer-events: none; -webkit-user-drag: none;
}
/* The "after" photograph is clipped from the left edge by the handle position */
.ba-stage__after { clip-path: inset(0 0 0 var(--pos, 50%)); }

.ba-stage__label {
  position: absolute; bottom: .85rem; z-index: 5;
  font-size: .59rem; font-weight: 600; letter-spacing: .2em; text-transform: uppercase;
  padding: .42rem .75rem; color: var(--white);
  background: rgba(11,11,11,.6); backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
  pointer-events: none; transition: opacity .4s var(--ease-soft);
}
.ba-stage__label--before { left: .85rem; }
.ba-stage__label--after  { right: .85rem; background: rgba(198,166,107,.92); color: var(--ink); }

.ba-stage__handle {
  position: absolute; top: 0; bottom: 0; left: var(--pos, 50%); z-index: 6;
  width: 2px; background: var(--white); transform: translateX(-1px);
  box-shadow: 0 0 0 1px rgba(0,0,0,.14), 0 0 22px rgba(0,0,0,.28);
  pointer-events: none;
}
.ba-stage__grip {
  position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
  width: 48px; height: 48px; border-radius: 50%;
  background: var(--white); color: var(--ink);
  display: grid; place-items: center; grid-auto-flow: column; gap: 3px;
  box-shadow: 0 8px 26px rgba(0,0,0,.3);
  transition: transform .35s var(--ease);
}
.ba-stage:hover .ba-stage__grip { transform: translate(-50%, -50%) scale(1.08); }
.ba-stage__grip svg { width: 9px; height: 12px; fill: currentColor; }

.ba-card__body { padding: 1.35rem 1.35rem 1.6rem; }
.ba-card__body h3 { font-size: 1.16rem; }
.ba-card__body p { margin-top: .55rem; font-size: .87rem; line-height: 1.7; color: var(--muted); }

/* Both sides are photographs now, so they share the same object-fit rules
   above; this only holds the tone while the image is still loading. */
.ba-before { background: var(--ivory-deep); }

/* ============================== SERVICES ================================ */
.svc__grid {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(1.2rem, 2.2vw, 2rem);
}

.svc-card {
  display: flex; flex-direction: column;
  background: var(--white);
  border: 1px solid var(--line-soft);
  overflow: hidden; isolation: isolate;
  transition: transform .7s var(--ease), box-shadow .7s var(--ease), border-color .7s var(--ease);
}
.svc-card:hover, .svc-card:focus-within {
  transform: translateY(-6px); box-shadow: var(--shadow-md); border-color: transparent;
}

/* Sources are portrait, the band is landscape — object-position (set per card
   in the config) decides which slice of the wall shows. */
.svc-card__media { position: relative; aspect-ratio: 3 / 2; overflow: hidden; background: var(--ivory-deep); }
.svc-card__media img {
  width: 100%; height: 100%; object-fit: cover;
  transform: scale(1.02);
  transition: transform 1.5s var(--ease);
}
.svc-card:hover .svc-card__media img { transform: scale(1.09); }

.svc-card__body {
  display: flex; flex-direction: column; flex: 1;
  padding: clamp(1.5rem, 2.4vw, 2.1rem) clamp(1.35rem, 2vw, 1.9rem) clamp(1.6rem, 2.4vw, 2.1rem);
}

.svc-card__label {
  font-size: .63rem; font-weight: 600; letter-spacing: .24em; text-transform: uppercase;
  color: var(--champagne-dim);
}
.svc-card h3 {
  margin-top: .85rem;
  font-size: clamp(1.28rem, 1.85vw, 1.62rem); line-height: 1.16;
}
.svc-card p {
  margin-top: .85rem; font-size: .89rem; line-height: 1.72; color: var(--muted);
  /* Keep every card's text block the same depth so the CTAs line up */
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical;
  overflow: hidden;
}

.svc-card__cta {
  display: inline-flex; align-items: center; gap: .55rem;
  margin-top: auto; padding-top: 1.35rem;
  font-size: .78rem; font-weight: 600; letter-spacing: .02em;
  color: var(--champagne-dim);
  transition: gap .45s var(--ease), color .45s var(--ease);
}
.svc-card__cta svg { width: 15px; height: 15px; transition: transform .5s var(--ease); }
.svc-card:hover .svc-card__cta { gap: .85rem; }
.svc-card:hover .svc-card__cta svg { transform: translateX(3px); }

/* One dark card so the eye lands somewhere first */
.svc-card--flagship .svc-card__body { background: var(--ink); }
.svc-card--flagship .svc-card__label { color: var(--champagne); }
.svc-card--flagship h3 { color: var(--ivory); }
.svc-card--flagship p { color: var(--muted-dark); }
.svc-card--flagship .svc-card__cta { color: var(--champagne); }

/* ============================ WHY CHOOSE US ============================= */
/* The film runs edge to edge, flush with the top of the section, with the
   copy beneath it inside the normal page width. */
.why-band { padding-top: 0; }
.why { display: grid; grid-template-columns: minmax(0,1fr); }
.why__media { position: relative; width: 100%; aspect-ratio: 16 / 9; max-height: 92vh; overflow: hidden; margin-bottom: clamp(2rem, 4vw, 3.5rem); }
.why__media img, .why__media video { width: 100%; height: 100%; object-fit: cover; display: block; }

/* Beneath a full-width film the four points sit side by side on wide
   screens instead of stretching into very long lines. */
.why__list { margin-top: 2.6rem; display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); column-gap: clamp(1.5rem, 3vw, 3rem); }
.why__item { display: grid; grid-template-columns: auto 1fr; gap: 1.4rem; padding-block: 1.5rem; border-top: 1px solid var(--line); }
.why__item { border-bottom: 1px solid var(--line); }
.why__item b {
  font-family: var(--font-serif); font-size: 1rem; font-weight: 400; color: var(--champagne-dim);
  padding-top: .18rem;
}
.why__item h3 { font-size: 1.1rem; }
.why__item p { margin-top: .5rem; font-size: .89rem; line-height: 1.72; color: var(--muted); }

/* ========================== PROCESS TIMELINE ============================ */
/* Set on the light ground. The hairline between cells is the grid's own
   background showing through a 1px gap, so it moves from the dark rule to
   the light one along with everything else. */
.process__grid { display: grid; grid-template-columns: repeat(3, minmax(0,1fr)); gap: 1px; background: var(--line); }
.step {
  position: relative; background: var(--white);
  padding: clamp(1.9rem, 3vw, 2.7rem) clamp(1.4rem, 2.2vw, 2.1rem) clamp(2.4rem, 3.6vw, 3.2rem);
  overflow: hidden;
}
.step__num {
  font-family: var(--font-serif); font-size: clamp(2.5rem, 4.6vw, 3.6rem); line-height: 1;
  color: rgba(23,23,23,.16);
  transition: color .7s var(--ease);
}
.step:hover .step__num { color: var(--champagne); }
.step h3 { margin-top: 1.2rem; font-size: clamp(1.1rem, 1.5vw, 1.32rem); color: var(--ink); }
.step p { margin-top: .7rem; font-size: .875rem; line-height: 1.72; color: var(--muted); }
/* Progress bar drawn as the step scrolls into view */
.step__bar { position: absolute; left: 0; bottom: 0; height: 2px; width: 100%; background: rgba(23,23,23,.09); }
.step__bar::after {
  content: ""; position: absolute; inset: 0; background: var(--champagne);
  transform: scaleX(0); transform-origin: left center;
  transition: transform 1.1s var(--ease);
}
.step.is-visible .step__bar::after { transform: scaleX(1); }

/* ============================ CONFIGURATOR ============================== */
.cfg { display: grid; grid-template-columns: minmax(0, 1fr); }

/* Edge to edge across the section, 16:9 but never taller than the screen.
   The readout's text lines up with the page content, not the screen edge. */
.cfg__stage {
  position: relative; width: 100%; aspect-ratio: 16 / 9; max-height: 92vh; overflow: hidden;
  background: #14120f; isolation: isolate;
  margin-bottom: clamp(2rem, 4vw, 3.5rem);
}
.cfg__photo {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; object-position: 50% 45%;
}
.cfg__scrim {
  position: absolute; inset: 0; z-index: 2;
  background: linear-gradient(to top, rgba(9,9,9,.9) 0%, rgba(9,9,9,.55) 30%, rgba(9,9,9,.05) 62%);
}

.cfg__readout {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 3;
  padding: clamp(1.3rem, 2.6vw, 2.2rem) max(var(--gutter), calc((100% - var(--shell)) / 2 + var(--gutter)));
}
.cfg__readout-label {
  display: block;
  font-size: .6rem; font-weight: 600; letter-spacing: .26em; text-transform: uppercase;
  color: var(--champagne);
}
.cfg__readout-title {
  margin-top: .6rem; color: var(--white);
  font-size: clamp(1.35rem, 2.3vw, 2rem); line-height: 1.12;
}
.cfg__readout-spec {
  margin-top: .5rem; font-size: .82rem; line-height: 1.6;
  color: rgba(255,255,255,.72);
}
.cfg__readout-cta {
  display: inline-flex; align-items: center; gap: .55rem; margin-top: 1.1rem; padding: 0;
  font-size: .68rem; font-weight: 600; letter-spacing: .18em; text-transform: uppercase;
  color: var(--champagne);
  transition: gap .45s var(--ease);
}
.cfg__readout-cta svg { width: 14px; height: 14px; transition: transform .5s var(--ease); }
.cfg__readout-cta:hover { gap: .9rem; }
.cfg__readout-cta:hover svg { transform: translateX(3px); }

/* Controls */
.cfg__panel { display: grid; gap: 1.9rem; }
.cfg__group h4 {
  font-family: var(--font-sans); font-size: .62rem; font-weight: 600;
  letter-spacing: .24em; text-transform: uppercase; color: var(--champagne);
  margin-bottom: 1rem;
}
/* The showcase film runs edge to edge across the section, between the
   heading and the configurator. 16:9, but never taller than the screen. */
.cfg-film {
  position: relative; width: 100%; aspect-ratio: 16 / 9; max-height: 92vh;
  overflow: hidden; background: #1a1815;
  margin: clamp(1.6rem, 3.5vw, 2.8rem) 0 clamp(2.4rem, 5vw, 4rem);
}
.cfg-film video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }

/* Full width below the photograph, so the switches sit in columns. */
.toggles { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); column-gap: clamp(1.5rem, 3vw, 3rem); row-gap: .1rem; }
.cfg__panel .btn--wide { justify-self: start; width: auto; min-width: min(100%, 320px); }
.toggle {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  width: 100%; padding: .82rem 0; border-bottom: 1px solid var(--line-dark);
  font-size: .74rem; letter-spacing: .12em; text-transform: uppercase;
  color: var(--muted-dark); transition: color .4s var(--ease-soft);
}
.toggle:hover { color: var(--ivory); }
.toggle__box {
  position: relative; width: 42px; height: 22px; border-radius: 999px; flex: none;
  background: rgba(255,255,255,.13); transition: background-color .45s var(--ease);
}
.toggle__box::after {
  content: ""; position: absolute; top: 3px; left: 3px; width: 16px; height: 16px; border-radius: 50%;
  background: var(--ivory); transition: transform .45s var(--ease), background-color .45s var(--ease);
}
.toggle[aria-pressed="true"] { color: var(--ivory); }
.toggle[aria-pressed="true"] .toggle__box { background: var(--champagne); }
.toggle[aria-pressed="true"] .toggle__box::after { transform: translateX(20px); background: var(--ink); }

/* ============================= MATERIALS ================================ */
.materials__grid { display: grid; grid-template-columns: repeat(5, minmax(0,1fr)); gap: clamp(.7rem, 1.4vw, 1.15rem); }

.mat {
  position: relative; aspect-ratio: 3 / 4; overflow: hidden; isolation: isolate;
  background-size: 290%; background-position: 50% 40%; background-color: var(--ivory-deep);
  transition: transform .8s var(--ease);
}
.mat::before {
  content: ""; position: absolute; inset: 0; z-index: 1;
  background: linear-gradient(to top, rgba(9,9,9,.9) 0%, rgba(9,9,9,.42) 40%, rgba(9,9,9,.04) 78%);
  opacity: .8; transition: opacity .7s var(--ease);
}
.mat:hover { transform: translateY(-6px); }
.mat:hover::before { opacity: 1; }

.mat__inner { position: absolute; inset: auto 0 0 0; z-index: 2; padding: 1rem .95rem 1.05rem; }
.mat__name {
  font-family: var(--font-serif); color: var(--white); font-size: 1.02rem; line-height: 1.2;
}
.mat__meta {
  display: grid; grid-template-rows: 0fr; overflow: hidden;
  transition: grid-template-rows .8s var(--ease);
}
.mat:hover .mat__meta, .mat:focus-within .mat__meta { grid-template-rows: 1fr; }
.mat__meta > div { min-height: 0; }
.mat__desc {
  margin-top: .6rem; font-size: .74rem; line-height: 1.6; color: rgba(255,255,255,.78);
  opacity: 0; transition: opacity .6s var(--ease) .1s;
}
.mat:hover .mat__desc, .mat:focus-within .mat__desc { opacity: 1; }
.mat__use {
  display: block; margin-top: .6rem;
  font-size: .55rem; font-weight: 600; letter-spacing: .18em; text-transform: uppercase;
  color: var(--champagne);
}

/* ============================== WALL GUIDE ============================== */
/* Editorial two-column read: a wide photograph of the wall type with the
   specification notes set beneath it. Deliberately long-form - this is the
   section that answers "which one do I actually want", so the text is the
   point and the picture is the evidence. */
.guide {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0;
  border-top: 1px solid var(--line);
}
.guide__item {
  display: flex; flex-direction: column;
  border-bottom: 1px solid var(--line);
  border-right: 1px solid var(--line);
  background: var(--white);
}
/* Every second item sits against the grid edge, so it keeps no right rule. */
.guide__item:nth-child(2n) { border-right: 0; }

.guide__media { position: relative; overflow: hidden; aspect-ratio: 16 / 10; background: var(--ivory-deep); }
.guide__media img {
  width: 100%; height: 100%; object-fit: cover;
  transform: scale(1.01);
  transition: transform 1.6s var(--ease);
}
.guide__item:hover .guide__media img { transform: scale(1.06); }

.guide__body { padding: clamp(1.6rem, 2.6vw, 2.6rem); display: flex; flex-direction: column; flex: 1; }
.guide__title {
  font-family: var(--font-serif); font-size: clamp(1.24rem, 1.75vw, 1.6rem);
  line-height: 1.2; color: var(--ink);
}
.guide__text {
  margin-top: 1rem; font-size: .93rem; line-height: 1.78; color: var(--muted);
}
.guide__cta {
  display: inline-flex; align-items: center; gap: .55rem; margin-top: auto; padding-top: 1.5rem;
  font-size: .645rem; font-weight: 600; letter-spacing: .21em; text-transform: uppercase;
  color: var(--ink); align-self: flex-start;
  border-bottom: 1px solid var(--line); padding-bottom: .4rem;
  transition: color .45s var(--ease), border-color .45s var(--ease);
}
.guide__cta svg { width: 14px; height: 14px; transition: transform .5s var(--ease); }
/* Both expanders are phone-only; the desktop column shows every wall type
   and its full specification with no interaction. */
.guide__more, .guide__all { display: none; }
.guide__cta:hover { color: var(--champagne); border-color: var(--champagne); }
.guide__cta:hover svg { transform: translateX(5px); }

/* ======================= DETAIL GALLERY (MASONRY) ======================= */
.masonry { columns: 4; column-gap: clamp(.7rem, 1.4vw, 1.15rem); }
.masonry__item {
  break-inside: avoid; margin-bottom: clamp(.7rem, 1.4vw, 1.15rem);
  position: relative; overflow: hidden; background: var(--ivory-deep);
  background-size: cover; background-position: 50% 50%;
}
.masonry__item::after {
  content: attr(data-caption);
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 2;
  padding: 2.6rem .95rem .9rem;
  background: linear-gradient(to top, rgba(9,9,9,.88), transparent);
  color: var(--ivory);
  font-size: .6rem; font-weight: 600; letter-spacing: .19em; text-transform: uppercase;
  opacity: 0; transform: translateY(12px);
  transition: opacity .6s var(--ease), transform .7s var(--ease);
}
.masonry__item:hover::after { opacity: 1; transform: none; }
.masonry__item::before {
  content: ""; position: absolute; inset: 0; z-index: 1;
  background: rgba(198,166,107,.14); opacity: 0; transition: opacity .6s var(--ease);
}
.masonry__item:hover::before { opacity: 1; }
/* Varied heights create the editorial masonry rhythm */
.masonry__item--tall  { aspect-ratio: 3 / 4; }
.masonry__item--wide  { aspect-ratio: 4 / 3; }
.masonry__item--sq    { aspect-ratio: 1; }

/* =============================== VIDEO ================================== */
/* The band is light; the video frame inside it stays dark, because the play
   button, the scrim and the label all sit over footage. */
.video-band { position: relative; overflow: hidden; background: var(--white); }
/* Edge to edge across the section; 16:9 but never taller than the screen. */
.video-frame { position: relative; width: 100%; aspect-ratio: 16 / 9; max-height: 92vh; background: #0b0b0b; overflow: hidden; }
.video-frame video { width: 100%; height: 100%; object-fit: cover; }
.video-frame__scrim {
  position: absolute; inset: 0; z-index: 2;
  background: linear-gradient(to top, rgba(9,9,9,.78), rgba(9,9,9,.12) 55%, rgba(9,9,9,.42));
  transition: opacity .7s var(--ease-soft);
}
.video-frame.is-playing .video-frame__scrim { opacity: 0; pointer-events: none; }

.video-play {
  position: absolute; inset: 0; z-index: 4; display: grid; place-items: center;
  transition: opacity .6s var(--ease-soft);
}
.video-frame.is-playing .video-play { opacity: 0; pointer-events: none; }
.video-play__btn {
  width: clamp(74px, 9vw, 108px); aspect-ratio: 1; border-radius: 50%;
  border: 1px solid rgba(255,255,255,.5);
  display: grid; place-items: center; color: var(--white);
  background: rgba(255,255,255,.08);
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
  transition: background-color .5s var(--ease), transform .5s var(--ease), border-color .5s var(--ease);
}
.video-play__btn:hover { background: var(--champagne); color: var(--ink); border-color: var(--champagne); transform: scale(1.06); }
.video-play__btn svg { width: 24px; height: 24px; fill: currentColor; margin-left: 4px; }
.video-play__label {
  position: absolute; bottom: 12%; left: 50%; transform: translateX(-50%);
  font-size: .62rem; letter-spacing: .28em; text-transform: uppercase; color: rgba(255,255,255,.72);
  white-space: nowrap;
}

.video-chapters { display: grid; grid-template-columns: repeat(4, minmax(0,1fr)); gap: 1px; background: var(--line); margin-top: clamp(1.5rem, 3vw, 2.5rem); }
.video-chapters div { background: var(--white); padding: 1.4rem 1.2rem; }
.video-chapters b {
  display: block; font-size: .6rem; font-weight: 600; letter-spacing: .2em;
  color: var(--champagne-dim, #a98c4f);
}
.video-chapters span { display: block; margin-top: .5rem; font-size: .82rem; color: var(--muted); }

/* ============================ TESTIMONIALS ============================== */
.quotes__grid { display: grid; grid-template-columns: repeat(3, minmax(0,1fr)); gap: clamp(1.2rem, 2.4vw, 2.2rem); }

/* Phone-only control; the desktop grid shows every review at once. */
.quotes__more { display: none; }
.quote {
  position: relative; background: var(--white); border: 1px solid var(--line-soft);
  padding: clamp(1.9rem, 3vw, 2.7rem);
  display: flex; flex-direction: column;
  transition: transform .7s var(--ease), box-shadow .7s var(--ease), border-color .7s var(--ease);
}
.quote:hover { transform: translateY(-6px); box-shadow: var(--shadow-md); border-color: transparent; }
.quote__mark {
  font-family: var(--font-serif); font-size: 4.2rem; line-height: .6; color: var(--champagne);
  opacity: .32; margin-bottom: .9rem;
}
.quote__stars { display: flex; gap: .22rem; margin-bottom: 1.1rem; }
.quote__stars svg { width: 14px; height: 14px; fill: var(--champagne); }
.quote p {
  font-family: var(--font-serif); font-size: clamp(1.02rem, 1.35vw, 1.16rem);
  line-height: 1.62; color: var(--charcoal); flex: 1;
}
.quote__by { margin-top: 1.7rem; padding-top: 1.15rem; border-top: 1px solid var(--line); }
.quote__by b { display: block; font-size: .8rem; font-weight: 600; letter-spacing: .04em; }
.quote__by span { display: block; margin-top: .28rem; font-size: .66rem; letter-spacing: .18em; text-transform: uppercase; color: var(--muted); }

/* ============================== CTA BAND ================================ */
.cta-band { position: relative; overflow: hidden; background: var(--ink); isolation: isolate; }
.cta-band__bg { position: absolute; inset: 0; z-index: 0; }
.cta-band__bg img { width: 100%; height: 100%; object-fit: cover; opacity: .3; }
.cta-band__bg::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(to right, rgba(9,9,9,.94) 0%, rgba(9,9,9,.7) 52%, rgba(9,9,9,.86) 100%);
}
.cta-band__inner { position: relative; z-index: 2; text-align: center; }
.cta-band h2 { color: var(--white); max-width: 18ch; margin-inline: auto; }
.cta-band__actions { margin-top: 2.5rem; display: flex; flex-wrap: wrap; gap: 1rem; justify-content: center; }
.cta-band__phone {
  display: inline-block; margin-top: 2.4rem;
  font-family: var(--font-serif); font-size: clamp(1.5rem, 2.6vw, 2.1rem); color: var(--champagne);
  transition: opacity .4s var(--ease-soft);
}
.cta-band__phone:hover { opacity: .78; }

/* ============================== CONTACT ================================= */
.contact { display: grid; grid-template-columns: minmax(0,.82fr) minmax(0,1.18fr); gap: clamp(2.5rem, 5vw, 5rem); align-items: start; }

.contact__card { border: 1px solid var(--line); padding: clamp(1.6rem, 2.6vw, 2.3rem); background: var(--white); }
.contact__card + .contact__card { margin-top: 1rem; }
.contact__card h4 {
  font-family: var(--font-sans); font-size: .62rem; font-weight: 600;
  letter-spacing: .24em; text-transform: uppercase; color: var(--champagne-dim); margin-bottom: .9rem;
}
.contact__big { font-family: var(--font-serif); font-size: clamp(1.4rem, 2.2vw, 1.85rem); display: inline-block; transition: color .4s var(--ease-soft); }
.contact__big:hover { color: var(--champagne-dim); }
.contact__note { margin-top: .6rem; font-size: .84rem; color: var(--muted); line-height: 1.7; }

.form { display: grid; grid-template-columns: repeat(2, minmax(0,1fr)); gap: 1.35rem 1.15rem; }
.field { display: flex; flex-direction: column; gap: .5rem; }
.field--full { grid-column: 1 / -1; }
.field label {
  font-size: .62rem; font-weight: 600; letter-spacing: .21em; text-transform: uppercase; color: var(--muted);
}
.field label .req { color: var(--champagne-dim); }
.field input, .field select, .field textarea {
  width: 100%; padding: .92rem 1rem;
  background: var(--white); border: 1px solid var(--line);
  font-size: .92rem; color: var(--charcoal);
  transition: border-color .4s var(--ease-soft), box-shadow .4s var(--ease-soft);
}
.field textarea { resize: vertical; min-height: 128px; }
.field select { appearance: none; cursor: pointer; padding-right: 2.6rem;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' fill='none' stroke='%236E6A63' stroke-width='1.4'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 1rem center; background-size: 12px;
}
.field input:focus, .field select:focus, .field textarea:focus {
  outline: none; border-color: var(--champagne); box-shadow: 0 0 0 3px rgba(198,166,107,.16);
}
.field input::placeholder, .field textarea::placeholder { color: #a9a49b; }
.field.has-error input, .field.has-error select, .field.has-error textarea { border-color: #b4462f; }
.field__error { font-size: .7rem; color: #b4462f; min-height: 0; display: none; }
.field.has-error .field__error { display: block; }

.form__foot { grid-column: 1 / -1; display: flex; flex-wrap: wrap; gap: 1rem; align-items: center; justify-content: space-between; }
.form__note { font-size: .74rem; color: var(--muted); max-width: 40ch; line-height: 1.6; }

.form__status {
  grid-column: 1 / -1; display: none;
  padding: 1.05rem 1.2rem; border: 1px solid var(--champagne);
  background: rgba(198,166,107,.1); font-size: .87rem; line-height: 1.65;
}
.form__status.is-shown { display: block; }

/* =========================== SIGNATURE SIGN-OFF ========================= */
.signoff { background: var(--ivory); border-top: 1px solid var(--line-soft); }
.signoff__inner { display: flex; flex-direction: column; align-items: center; gap: 1.6rem; text-align: center; }

.signoff__mark { width: min(560px, 78vw); }
.signoff__mark svg { width: 100%; height: auto; overflow: visible; color: var(--champagne); }

/* pathLength="1" normalises the outline so the dash maths needs no
   getTotalLength() call — the whole draw is pure CSS. */
.signoff__mark path {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.15;
  stroke-linecap: round;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
}
.js .signoff__mark.is-visible path {
  animation: signWrite 3.4s cubic-bezier(.6, 0, .25, 1) forwards;
}
@keyframes signWrite { to { stroke-dashoffset: 0; } }

/* Without scripting the mark is simply shown complete. */
html:not(.js) .signoff__mark path { stroke-dashoffset: 0; }

.signoff__note {
  font-size: .78rem; letter-spacing: .12em; color: var(--muted);
}

@media (prefers-reduced-motion: reduce) {
  .signoff__mark path { stroke-dashoffset: 0; }
  .js .signoff__mark.is-visible path { animation: none; }

  /* The global reduced-motion rule collapses every animation to .001ms and
     one iteration. For the marquee that meant it snapped to its end frame
     (translateX(-50%)) and froze there, leaving the strip parked mid-word.
     Stop it at the start instead, so it reads as a deliberate static row -
     which is what someone asking for reduced motion should get. */
  .marquee__track { animation: none !important; transform: none !important; }
  .marquee { overflow-x: auto; -webkit-overflow-scrolling: touch; }
}

/* ================================ SHARE ================================= */
.share { margin-top: 1.6rem; padding-top: 1.3rem; border-top: 1px solid var(--line); }
.share--center { border-top: 0; padding-top: 0; margin-top: 2.2rem; text-align: center; }

.share__label {
  display: block; margin-bottom: .85rem;
  font-size: .62rem; font-weight: 600; letter-spacing: .22em; text-transform: uppercase;
  color: var(--muted);
}
.share__row { display: flex; flex-wrap: wrap; gap: .6rem; }
.share--center .share__row { justify-content: center; }

.share__btn {
  display: inline-flex; align-items: center; gap: .55rem;
  padding: .68rem 1.15rem;
  border: 1px solid var(--line);
  font-size: .68rem; font-weight: 600; letter-spacing: .14em; text-transform: uppercase;
  color: var(--charcoal); background: var(--white);
  transition: border-color .4s var(--ease), color .4s var(--ease),
              background-color .4s var(--ease), transform .4s var(--ease);
}
.share__btn svg { width: 15px; height: 15px; flex: none; }
.share__btn:hover, .share__btn:focus-visible {
  border-color: var(--champagne); color: var(--champagne-dim); transform: translateY(-2px);
}
.share__btn--wa svg { fill: currentColor; stroke: none; }
.share__btn--wa:hover, .share__btn--wa:focus-visible {
  background: #1FAF54; border-color: #1FAF54; color: #fff;
}

/* ============================ RESPONSIVE ================================ */
@media (max-width: 1100px) {
  .why__list { grid-template-columns: 1fr; }
  .why__item { border-bottom: 0; }
  .why__item:last-child { border-bottom: 1px solid var(--line); }
  .projects__grid { grid-template-columns: repeat(2, minmax(0,1fr)); }
  .svc__grid      { grid-template-columns: repeat(2, minmax(0,1fr)); }
  .ba__grid       { grid-template-columns: repeat(2, minmax(0,1fr)); }
  .quotes__grid   { grid-template-columns: 1fr; }

  /* Two reviews, then the rest on request. Three cost 1,384px for copy a
     visitor skims; the button is right there for anyone who wants more. */
  .quotes__grid:not(.is-expanded) .quote:nth-child(n + 3) { display: none; }

  /* Four claims, each a row of its own, ran the section past 1,200px.
     Tighter padding and a smaller measure keep all four without the bulk. */
  .why__item { gap: 1rem; padding-block: 1.05rem; }
  .why__item h3 { font-size: 1rem; }
  .why__item p { margin-top: .35rem; font-size: .84rem; line-height: 1.6; }
  .quotes__more {
    display: block; margin: 1.6rem auto 0; padding: .95rem 1.6rem;
    font-family: inherit; font-size: .645rem; font-weight: 600;
    letter-spacing: .21em; text-transform: uppercase;
    color: var(--ink); background: none; border: 1px solid var(--line);
    cursor: pointer;
  }
  .process__grid  { grid-template-columns: repeat(2, minmax(0,1fr)); }
  .materials__grid { grid-template-columns: repeat(4, minmax(0,1fr)); }
  .masonry { columns: 3; }
  .intro { grid-template-columns: 1fr; }
  .cfg { grid-template-columns: 1fr; }
  .contact { grid-template-columns: 1fr; }
  .modal__panel { grid-template-columns: 1fr; }
  /* Stacked layout: give the image a definite height. An aspect-ratio alone
     leaves the grid row circular-dependent and it collapses to zero. */
  .modal__media { aspect-ratio: auto; height: min(46vh, 420px); min-height: 0; }
  .video-chapters { grid-template-columns: repeat(2, minmax(0,1fr)); }
}

@media (max-width: 720px) {
  /* ---------------------------------------------------------------------
     VERTICAL RHYTHM ON PHONES
     The section padding is clamp(5rem, 11vw, 10.5rem). On a 375px screen
     11vw is only 41px, so the clamp sits permanently on its 5rem floor -
     a value chosen for desktop. That put 160px of empty space between
     every one of 13 sections, roughly a fifth of a screen each time, and
     it read as the page having stopped.
     --------------------------------------------------------------------- */
  :root { --section-y: 2.1rem; }
  .section--tight { padding-block: 1.8rem; }
  .section-head { margin-bottom: 1.5rem; }
  .mt-14 { margin-top: 2.25rem; }
  .mt-10 { margin-top: 1.75rem; }
  .mb-10 { margin-bottom: 1.6rem; }

  .projects__grid { grid-template-columns: 1fr; }
  .svc__grid      { grid-template-columns: 1fr; }
  .ba__grid       { grid-template-columns: 1fr; }
  /* Six steps in a single column ran 1,744px for six short paragraphs.
     Two-across halves that; the copy is brief enough to take the narrower
     measure without becoming a column of single words. */
  .process__grid  { grid-template-columns: repeat(2, minmax(0,1fr)); }
  .step { padding: 1.35rem 1rem 1.9rem; }
  .step__num { font-size: 2.1rem; }
  .step h3 { margin-top: .8rem; font-size: 1rem; }
  .step p { margin-top: .5rem; font-size: .81rem; line-height: 1.6; }
  .materials__grid { grid-template-columns: repeat(2, minmax(0,1fr)); }
  .masonry { columns: 1; }

  /* One wall type at a time; the right-hand rule would otherwise cut the
     single column in half. */
  .guide { grid-template-columns: 1fr; }
  .guide__item { border-right: 0; }
  .guide__media { aspect-ratio: 4 / 3; }
  .guide__text { font-size: .9rem; line-height: 1.72; }

  /* Eight full specifications stacked in one column ran to 1,300px each -
     a third of the whole page. The notes stay, but folded: four lines as a
     taster, the rest one tap away. Everything is still in the markup, so
     search engines and screen readers see the complete text either way. */
  .guide__item:not(.is-open) .guide__text {
    display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 4;
    overflow: hidden;
  }
  .guide__more {
    display: inline-flex; align-items: center; gap: .4rem; margin-top: .7rem;
    font-size: .645rem; font-weight: 600; letter-spacing: .19em; text-transform: uppercase;
    color: var(--champagne-dim, #a98c4f); background: none; border: 0; padding: 0;
    font-family: inherit; cursor: pointer; align-self: flex-start;
  }
  .guide__more::after { content: "+"; font-size: .95rem; line-height: 1; }
  .guide__item.is-open .guide__more::after { content: "\2212"; }   /* minus */
  .guide__cta { padding-top: 1.15rem; }

  /* Three of eight until asked. */
  .guide:not(.is-expanded) .guide__item:nth-child(n + 4) { display: none; }
  .guide__all {
    display: block; margin: 1.5rem auto 0; padding: .95rem 1.6rem;
    font-family: inherit; font-size: .645rem; font-weight: 600;
    letter-spacing: .21em; text-transform: uppercase;
    color: var(--ink); background: none; border: 1px solid var(--line);
    cursor: pointer;
  }

  /* ---------------------------------------------------------------------
     PHONES: LET THE PHOTOGRAPHY BREATHE
     On a desktop grid a card is one of three and the caption block is a
     small part of it. On a 375px phone that same block ate roughly half
     the picture, so the work itself read as a thumbnail.

     Below, the card keeps only what identifies the project - number, title
     and the tap cue. The description and the material tags are already on
     the detail screen one tap away, so they are dropped here rather than
     duplicated over the photograph.
     --------------------------------------------------------------------- */
  .project-card__media { aspect-ratio: 3 / 4; }        /* taller frame = bigger photo */
  .project-card__veil {
    /* Darkens only the caption band; the wall itself stays uncovered. */
    background: linear-gradient(to top,
      rgba(11,11,11,.90) 0%, rgba(11,11,11,.55) 26%,
      rgba(11,11,11,.10) 52%, rgba(11,11,11,0) 70%);
    opacity: 1;
  }
  .project-card__desc,
  .project-card .tags { display: none; }
  .project-card__body { padding: 1.15rem 1.1rem 1.15rem; }
  .project-card__title { font-size: 1.24rem; }
  .project-card__line { margin-top: .7rem; }
  .project-card__cta { margin-top: .85rem; }

  /* Section intros carry the same words as desktop but at a size that does
     not push the first photograph below the fold. */
  .lede { font-size: .93rem; line-height: 1.6; }
  .lede--detail { display: none; }
  .section-head__aside { margin-top: .9rem; }

  /* Service cards: the photograph is the selling point, so the supporting
     paragraph is capped at three lines rather than running to six. */
  .svc-card__body p {
    display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3;
    overflow: hidden;
  }
  .masonry__item::after { font-size: .62rem; }
  .form { grid-template-columns: 1fr; }
  .cfg__stage { aspect-ratio: 4 / 3; }
  .marquee__group span { padding-inline: 1.3rem; gap: 1.3rem; font-size: .63rem; }
  .video-chapters { grid-template-columns: 1fr; }
  .ba-stage { aspect-ratio: 3 / 2; }
}

@media (max-width: 460px) {
  .masonry { columns: 1; }
  .materials__grid { grid-template-columns: 1fr; }
}

/* Secondary phone line — same treatment, stepped back so the primary
   number still reads first. */
.contact__big--alt { display: block; margin-top: .45rem; font-size: .86em; color: var(--muted); }
.contact__big--alt:hover { color: var(--champagne-dim); }
.footer__phone--alt { font-size: 1.12rem; opacity: .72; margin-top: -.1rem; }
.drawer__phone--alt { font-size: 1.15rem; opacity: .72; }
