/* ============================================================================
   Per-section layout + the CSS half of the motion components.
   ========================================================================== */

/* ---- SplitWords ---------------------------------------------------------- */
.sw-box { display: inline-block; overflow: hidden; vertical-align: bottom; padding-bottom: 0.06em; }
.sw-word { display: inline-block; will-change: transform; }

/* ---- ClipReveal ---------------------------------------------------------- */
.clip { position: relative; overflow: hidden; border-radius: var(--radius); }
/* 14% bleed so the +/-7% counter-parallax can never expose an edge. */
.clip__inner { position: absolute; inset: -14%; will-change: transform; }
.clip__inner img, .clip__inner video { width: 100%; height: 100%; object-fit: cover; }

/* ---- LRule --------------------------------------------------------------- */
.lrule { position: relative; width: 280px; height: 124px; }
.lrule__down, .lrule__across {
  position: absolute; background: currentColor; opacity: 0.16;
}
.lrule__down { left: 0; top: 0; width: 1px; height: 0; }
.lrule__across { left: 0; top: 122.8px; height: 1px; width: 1px; }

/* ---- PanelDeck ----------------------------------------------------------- */
.deck { position: relative; min-height: 100vh; display: grid; align-items: center; }
.deck__panel { grid-area: 1 / 1; will-change: transform, opacity; }
.deck.is-static { min-height: 0; display: block; }
.deck.is-static .deck__panel { opacity: 1 !important; visibility: visible !important; }
.deck.is-static .deck__panel + .deck__panel { margin-top: 64px; }

/* ---- 1. HERO ------------------------------------------------------------- */
.hero {
  position: relative;
  height: 100vh;
  height: 100svh;
  overflow: hidden;
  background: #05091f;
}
.hero__canvas { position: absolute; inset: 0; }
/* The prototype's own stylesheet pins the canvas `position: fixed`. Inside a
   100vh section it has to be absolute or the page scrolls and the dock does not. */
.hero__canvas canvas { position: absolute !important; inset: 0; width: 100%; height: 100%; }
/* TOP-LEFT, not bottom (Ben, 2026-08-10). The copy has to clear the fixed
   header, so the offset is derived from the header's own height rather than a
   round number that would collide the moment the header changes. */
.hero__copy {
  position: absolute; left: 0; right: 0; top: 0; z-index: 2;
  padding-top: calc(var(--header-h, 92px) + clamp(20px, 4vh, 56px));
  pointer-events: none;
}
.hero__copy .wrap > * { pointer-events: auto; }
.hero .h-page { color: #f4f7fb; max-width: 15ch; text-wrap: balance; }
/* The caps live in CSS, not in the markup: the h1 stays a real sentence for
   screen readers and the document outline, and only the rendering shouts.
   Caps also set tighter than mixed case, so the tracking opens a hair. */
.hero__title { text-transform: uppercase; letter-spacing: 0.01em; }
.hero__eyebrow { color: #7fd6f4; margin-bottom: 18px; }
.hero__actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 28px; }
.hero__actions .btn { color: #eef2f7; border-color: rgba(255,255,255,0.28); }
.hero__hint {
  margin-top: 22px; font-size: 13px; letter-spacing: 0.06em;
  color: rgba(238, 242, 247, 0.62);
}
#err {
  position: fixed; inset: auto 12px 12px 12px; z-index: 90; color: #fca5a5;
  font: 12px/1.5 ui-monospace, Menlo, monospace; background: rgba(40, 8, 8, .9);
  padding: 10px 13px; border-radius: 8px; display: none; white-space: pre-wrap;
}

/* ---- 2. SERVICES --------------------------------------------------------- */
.services-grid { display: grid; gap: 1px; background: var(--line); margin-top: 48px; }
@media (min-width: 640px) { .services-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1024px) { .services-grid { grid-template-columns: repeat(3, 1fr); } }
.service-card {
  background: var(--bg); padding: 28px 24px 32px; display: flex; flex-direction: column;
  transition: background-color var(--state-ms) var(--ease-out);
}
.service-card:hover { background: var(--bg-alt); }
.service-card__media { border-radius: var(--radius); overflow: hidden; aspect-ratio: 4 / 3; margin-bottom: 20px; }
.service-card__media img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.7s var(--ease-out); }
.service-card:hover .service-card__media img { transform: scale(1.05); }
.service-card__num {
  font-family: var(--font-display); font-size: 12px; letter-spacing: 0.18em;
  color: var(--accent); margin-bottom: 10px;
}
.service-card h3 { margin-bottom: 10px; }
.service-card p { color: var(--muted); font-size: 16px; }
/* The number is also a <p>, so `.service-card p` outranked `.service-card__num`
   and quietly painted it --muted instead of --accent. */
.service-card p.service-card__num { color: var(--accent); font-size: 12px; }
.service-card__more {
  margin-top: auto; padding-top: 20px; font-family: var(--font-display);
  font-size: 12px; text-transform: uppercase; letter-spacing: 0.14em;
  opacity: 0.2; transition: opacity var(--state-ms) var(--ease-out);
}
.service-card:hover .service-card__more, .service-card:focus-within .service-card__more { opacity: 1; }

/* ---- 3. WHAT WE DO ------------------------------------------------------- */
.whatwedo { display: grid; gap: 40px; align-items: center; }
@media (min-width: 1024px) { .whatwedo { grid-template-columns: 1fr 1.15fr; gap: 64px; } }
.whatwedo .clip { aspect-ratio: 16 / 10; }

/* ---- 4. GALLERY ---------------------------------------------------------- */
.gallery-head { display: flex; flex-wrap: wrap; gap: 20px; align-items: flex-end; justify-content: space-between; margin-bottom: 40px; }
.gallery-strip { margin-top: 8px; }

/* ---- 5. HOW IT GETS BUILT ------------------------------------------------ */
.build { display: grid; gap: 40px; }
@media (min-width: 1024px) { .build { grid-template-columns: 0.9fr 24px 1.4fr; gap: 48px; } }
.build__steps { display: grid; gap: 24px; }
.build__steps > li { overflow: hidden; will-change: transform; }
.step {
  border: var(--stroke) solid var(--line); border-radius: var(--radius);
  padding: 24px; background: var(--bg-alt);
  opacity: 0.2; transition: opacity var(--state-ms) var(--ease-out);
}
.step.is-lit { opacity: 1; }
.step__n {
  font-family: var(--font-display); font-size: 12px; letter-spacing: 0.18em;
  color: var(--accent); margin-bottom: 10px;
}
.step h3 { margin-bottom: 8px; }
.step p { color: var(--muted); font-size: 16px; }
.step p.step__n { color: var(--accent); font-size: 12px; }   /* same trap as above */
/* Specificity has to beat `.rope-gauge { display: flex }` in rope.css, which
   loads after this file — the flat `.build__gauge` version lost and the gauge
   showed up on mobile. */
.build .build__gauge { display: none; }
@media (min-width: 1024px) { .build .build__gauge { display: flex; } }

/* ---- 6. ABOUT / PRESS (deck) --------------------------------------------- */
.about-panel { display: grid; gap: 40px; align-items: center; }
@media (min-width: 1024px) { .about-panel { grid-template-columns: 1.1fr 1fr; gap: 64px; } }
.about-panel .clip { aspect-ratio: 4 / 3; }
.about-list { columns: 1; column-gap: 32px; margin-top: 20px; }
@media (min-width: 640px) { .about-list { columns: 2; } }
.about-list li { break-inside: avoid; padding: 7px 0; border-bottom: var(--stroke) solid var(--line-soft); font-size: 16px; }
.press-video { width: 100%; border-radius: var(--radius); border: var(--stroke) solid var(--line); }

/* ---- drift band ---------------------------------------------------------- */
/* The band is deliberately 116% wide so the +/-8% scrub never shows an edge;
   its scope has to clip, or that 16% becomes real page-level scroll. */
[data-drift-scope] { overflow: hidden; }
.drift-band { display: flex; gap: 16px; width: 116%; margin-left: -8%; }
.drift-band img {
  width: 25%; aspect-ratio: 4 / 3; object-fit: cover;
  border-radius: var(--radius); border: var(--stroke) solid var(--line);
}

/* ---- 7. REVIEWS ---------------------------------------------------------- */
.reviews__viewport { overflow: hidden; }
.reviews__strip { display: flex; will-change: transform; }
.review {
  flex: 0 0 auto; padding: 0 4px;
  opacity: 0.2; transition: opacity var(--state-ms) var(--ease-out);
}
.review.is-lit { opacity: 1; }
.review__inner {
  border: var(--stroke) solid var(--line); border-radius: var(--radius);
  padding: 32px; height: 100%;
}
.review blockquote { font-size: clamp(1.0625rem, 1.6vw, 1.375rem); line-height: 1.45; }
.review__by { margin-top: 22px; font-family: var(--font-display); font-size: 13px; letter-spacing: 0.1em; text-transform: uppercase; }
.review__src { color: var(--muted); font-size: 13px; margin-top: 4px; }
.reviews__nav { display: flex; gap: 8px; align-items: center; justify-content: center; margin-top: 28px; }
.reviews__nav button {
  width: 40px; height: 40px; border: var(--stroke) solid var(--line);
  border-radius: var(--radius); display: grid; place-items: center;
  opacity: 0.5; transition: opacity var(--state-ms) var(--ease-out);
}
.reviews__nav button:hover { opacity: 1; }
/* The stepper rope is 14 knots at the measured 65.76 pitch = 855px. That does
   not fit a phone, so the wrap scrolls rather than the page. */
.reviews__stepper-wrap { margin-top: 26px; display: flex; justify-content: flex-start; overflow-x: auto; }
@media (min-width: 960px) { .reviews__stepper-wrap { justify-content: center; overflow-x: visible; } }

/* ---- 8. FAQ -------------------------------------------------------------- */
.faq { border-top: var(--stroke) solid var(--line); margin-top: 40px; }
.faq__item { border-bottom: var(--stroke) solid var(--line); }
.faq__q {
  width: 100%; display: flex; gap: 24px; align-items: baseline; justify-content: space-between;
  padding: 22px 0; text-align: left;
  font-family: var(--font-display); font-size: clamp(1rem, 1.6vw, 1.25rem); font-weight: 500;
  opacity: 0.2; transition: opacity var(--state-ms) var(--ease-out);
}
.faq__item.is-open .faq__q, .faq__q:hover, .faq__q:focus-visible { opacity: 1; }
.faq__sign { flex: 0 0 auto; color: var(--accent); font-size: 20px; line-height: 1; }
.faq__a { overflow: hidden; height: 0; }
.faq__a > div { padding: 0 0 24px; max-width: 76ch; color: var(--muted); }

/* ---- 9. CONTACT ---------------------------------------------------------- */
.contact { display: grid; gap: 48px; }
@media (min-width: 1024px) { .contact { grid-template-columns: 1fr 1.1fr; gap: 80px; } }
.nap { margin-top: 32px; display: grid; gap: 24px; }
.nap h3 {
  font-family: var(--font-display); font-size: 12px; text-transform: uppercase;
  letter-spacing: 0.18em; color: var(--muted); margin-bottom: 6px;
}
.nap a { border-bottom: var(--stroke) solid var(--line); }
.nap a:hover { border-bottom-color: var(--accent); }

/* ---- service page -------------------------------------------------------- */
.svc-hero { padding-top: 168px; }
.svc-body { display: grid; gap: 40px; }
@media (min-width: 1024px) { .svc-body { grid-template-columns: 1fr 1fr; gap: 64px; } }
.svc-grid { display: grid; gap: 16px; grid-template-columns: repeat(2, 1fr); margin-top: 40px; }
@media (min-width: 768px) { .svc-grid { grid-template-columns: repeat(4, 1fr); } }
.svc-grid .clip { aspect-ratio: 4 / 5; }

/* The video that sits in every service page's intro, exactly where their own
   Divi layout puts it. 16/9 because that is what the source file is. */
.svc-video { margin-top: 40px; aspect-ratio: 16 / 9; }

/* Mid-page CTA band — their section [2] on all six service pages: one photo,
   a scrim, a heading, a paragraph and the Contact Us button. */
.svc-cta {
  position: relative; overflow: hidden; isolation: isolate;
  border-radius: var(--radius); border: var(--stroke) solid var(--line);
  padding: clamp(40px, 7vw, 88px) clamp(24px, 5vw, 64px);
}
.svc-cta__bg { position: absolute; inset: 0; z-index: -2; }
.svc-cta__bg img { width: 100%; height: 100%; object-fit: cover; }
/* The photos are outdoor daylight, so the scrim has to be heavy enough for
   18px body text, not just the heading. Measured against #eef2f7 on the
   lightest of the six (seawall.jpg): 0.72 clears 4.5:1. */
.svc-cta::after {
  content: ''; position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(90deg, rgba(5,9,31,0.88), rgba(5,9,31,0.72));
}
.svc-cta * { color: #eef2f7; }
.svc-cta .lede { color: #cbd6e4; }
.svc-cta__inner { max-width: 62ch; }

/* Cross-links between the six services, at the foot of each service page. */
/* The hairline grid is drawn by each cell's own OUTLINE, not by a 1px gap over
   a coloured container: the gallery's jump list is 7 items in a 5-column grid,
   and a coloured container paints the three empty cells as a grey slab. */
.svc-more { display: grid; gap: 1px; margin-top: 48px; }
@media (min-width: 640px) { .svc-more { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1024px) { .svc-more { grid-template-columns: repeat(5, 1fr); } }
.svc-more a {
  outline: var(--stroke) solid var(--line);
  background: var(--bg); padding: 22px 20px; display: block;
  font-family: var(--font-display); font-size: 14px; font-weight: 500;
  transition: background-color var(--state-ms) var(--ease-out);
}
.svc-more a:hover, .svc-more a:focus-visible { background: var(--bg-alt); }
.svc-more span {
  display: block; font-size: 11px; letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--accent); margin-bottom: 8px;
}

/* ---- interior page hero -------------------------------------------------- */
/* Same clearance as .svc-hero so every interior page starts on the same line. */
.page-hero { padding-top: 168px; }

/* ---- header nav: the Services submenu ------------------------------------ */
.nav__group { position: relative; }
.nav__group > button { display: inline-flex; align-items: center; gap: 7px; }
.nav__panel {
  position: absolute; top: calc(100% + 14px); left: -20px; min-width: 232px;
  padding: 8px; border-radius: var(--radius);
  background: rgba(5, 9, 31, 0.96);
  -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
  border: var(--stroke) solid rgba(255, 255, 255, 0.16);
  /* Opacity is the state, per the universal rule; visibility only stops it
     eating clicks while it is dim. */
  opacity: 0; visibility: hidden;
  transition: opacity var(--state-ms) var(--ease-out), visibility 0s linear var(--state-ms);
}
.nav__group:hover .nav__panel,
.nav__group:focus-within .nav__panel {
  opacity: 1; visibility: visible; transition-delay: 0s;
}
.nav__panel a {
  display: block; padding: 9px 12px; border-radius: 6px; letter-spacing: 0.08em;
  text-transform: none; font-size: 13px;
}
.nav__panel a::after { display: none; }
.nav-mobile__sub { padding-left: 16px; }
.nav-mobile__sub a { font-size: 13px; opacity: 0.78; padding: 9px 0; }
.nav-mobile__label {
  display: block; padding: 12px 0 4px; font-family: var(--font-display);
  font-size: 12px; text-transform: uppercase; letter-spacing: 0.18em; color: #9fb0c4;
}

/* ---- about page ---------------------------------------------------------- */
.about-montage { display: grid; gap: 12px; grid-template-columns: repeat(2, 1fr); margin-top: 48px; }
@media (min-width: 768px) { .about-montage { grid-template-columns: repeat(4, 1fr); } }
.about-montage .clip { aspect-ratio: 1 / 1; }
.svc-list { display: grid; gap: 12px; margin-top: 32px; }
.svc-list > li { overflow: hidden; }
.svc-list__item {
  border: var(--stroke) solid var(--line); border-radius: var(--radius);
  padding: 16px 20px; font-family: var(--font-display); font-size: 15px; font-weight: 500;
}
.area-list { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 28px; }
.area-list li {
  border: var(--stroke) solid var(--line); border-radius: 999px;
  padding: 8px 16px; font-size: 14px; color: var(--muted);
}

/* ---- gallery page -------------------------------------------------------- */
.gal-group + .gal-group { margin-top: clamp(56px, 8vw, 104px); }
.gal-group__head { max-width: 62ch; }
.gal-grid { display: grid; gap: 12px; grid-template-columns: repeat(2, 1fr); margin-top: 36px; }
@media (min-width: 768px) { .gal-grid { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 1200px) { .gal-grid { grid-template-columns: repeat(4, 1fr); } }
.gal-grid .clip { aspect-ratio: 1 / 1; }
.gal-count {
  font-family: var(--font-display); font-size: 12px; letter-spacing: 0.18em;
  text-transform: uppercase; color: var(--accent);
}

/* ---- testimonials page --------------------------------------------------- */
.wall { columns: 1; column-gap: 20px; margin-top: 48px; }
@media (min-width: 700px) { .wall { columns: 2; } }
@media (min-width: 1100px) { .wall { columns: 3; } }
.wall > figure {
  break-inside: avoid; margin: 0 0 20px;
  border: var(--stroke) solid var(--line); border-radius: var(--radius); padding: 28px;
}
.wall blockquote { font-size: 17px; line-height: 1.5; }
.wall figcaption { margin-top: 20px; }
.wall figcaption b {
  display: block; font-family: var(--font-display); font-size: 13px; font-weight: 500;
  letter-spacing: 0.1em; text-transform: uppercase;
}
.wall figcaption span { display: block; color: var(--muted); font-size: 13px; margin-top: 4px; }

/* ---- legal / prose pages ------------------------------------------------- */
.prose { max-width: 76ch; }
.prose > * + * { margin-top: 20px; }
.prose h2 {
  font-family: var(--font-display); font-weight: 500; font-size: 1.25rem;
  letter-spacing: -0.01em; margin-top: 44px;
}
.prose p { color: var(--muted); font-size: 17px; }
.prose ul { margin-top: 12px; }
.prose li { color: var(--muted); font-size: 17px; padding: 6px 0 6px 18px; position: relative; }
.prose li::before { content: ''; position: absolute; left: 0; top: 17px; width: 7px; height: 1px; background: var(--accent); }

/* ---- reduced motion ------------------------------------------------------ */
@media (prefers-reduced-motion: reduce) {
  * { animation-duration: 0.001ms !important; transition-duration: 0.001ms !important; }
  .clip { clip-path: none !important; }
  .clip__inner { transform: none !important; }
  .deck { min-height: 0; display: block; }
  .deck__panel { opacity: 1 !important; visibility: visible !important; }
  .deck__panel + .deck__panel { margin-top: 64px; }
  .drift-band { width: 100%; margin-left: 0; }
  .step, .review, .faq__q, .service-card__more { opacity: 1 !important; }
  .svc-list__item { opacity: 1 !important; }
  .rope-marquee { overflow-x: auto; }
}
