/* ============================================================
   Beach Living Media — Design System
   Editorial / minimal / premium coastal aesthetic
   ============================================================ */

:root {
  /* Color tokens (from creative brief) */
  --navy: #1c2b3a;
  --ocean: #2f93b3;
  --ocean-deep: #3e6e8b;
  --seafoam: #a9c6ba;
  --sand: #e7dcc6;
  --warm-white: #faf6f0;
  --charcoal: #2a2a28;
  --soft-gray: #8c8c86;
  --gold: #b08d57;
  --white: #ffffff;

  /* Semantic tokens */
  --color-bg: var(--white);
  --color-bg-alt: var(--seafoam);
  --color-bg-dark: var(--navy);
  --color-text: var(--charcoal);
  --color-text-muted: var(--soft-gray);
  --color-text-inverse: var(--warm-white);
  --color-accent: var(--ocean);
  --color-accent-strong: var(--navy);
  --color-highlight: var(--gold);
  --color-border: rgba(42, 42, 40, 0.12);

  /* Typography */
  --font-display: "Poppins", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --font-body: "Poppins", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;

  /* Type scale (fluid) */
  --step-eyebrow: 0.8125rem;
  --step-body: clamp(1rem, 0.96rem + 0.2vw, 1.125rem);
  --step-h3: clamp(1.375rem, 1.25rem + 0.6vw, 1.75rem);
  --step-h2: clamp(2rem, 1.6rem + 1.6vw, 3rem);
  --step-h1: clamp(2.75rem, 2rem + 3vw, 4.75rem);

  /* Spacing scale — spacious, editorial (low density per brief: "large white space") */
  --space-2xs: 0.5rem;
  --space-xs: 0.875rem;
  --space-sm: 1.5rem;
  --space-md: 2.5rem;
  --space-lg: 4rem;
  --space-xl: 6rem;
  --space-2xl: 9rem;

  --max-width: 1200px;
  --transition: 220ms cubic-bezier(0.4, 0, 0.2, 1);
}

/* ---------- Reset ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

body {
  margin: 0;
  font-family: var(--font-body);
  font-size: var(--step-body);
  line-height: 1.65;
  color: var(--color-text);
  background: var(--color-bg);
  -webkit-font-smoothing: antialiased;
}

img { max-width: 100%; display: block; }
a { color: inherit; }

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-optical-sizing: auto;
  font-weight: 600;
  line-height: 1.16;
  margin: 0 0 var(--space-sm);
  letter-spacing: -0.01em;
}
h1 { font-size: var(--step-h1); font-weight: 800; line-height: 1.24; letter-spacing: -0.005em; }
h2 { font-size: var(--step-h2); font-weight: 700; }
h3 { font-size: var(--step-h3); font-weight: 600; }
p { margin: 0 0 var(--space-sm); }

.container {
  max-width: var(--max-width);
  margin-inline: auto;
  padding-inline: var(--space-sm);
}

@media (min-width: 640px) {
  .container { padding-inline: var(--space-md); }
}

.eyebrow {
  display: inline-block;
  font-size: var(--step-eyebrow);
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-accent);
  margin-bottom: var(--space-xs);
}

/* Slide in from the left — section headline + intro paragraphs. Scoped to
   .section-head so tab-panel content (shown/hidden by clicking a tag, not
   by scrolling) is naturally excluded, same as the rest of the reveal system. */
.section-head h2,
.section-head p {
  opacity: 0;
  transform: translateX(-28px);
  transition: opacity 700ms ease, transform 700ms ease;
}
.section-head p { transition-delay: 150ms; }
.section-head h2.is-visible,
.section-head p.is-visible {
  opacity: 1;
  transform: translateX(0);
}
@media (prefers-reduced-motion: reduce) {
  .section-head h2, .section-head p { opacity: 1; transform: none; transition: none; }
}

.accent { color: var(--color-accent); }

/* Keeps a phrase on one line at tablet/desktop widths; on narrow phones the
   phrase is allowed to wrap normally so it doesn't overflow the viewport. */
.nowrap-phrase { white-space: nowrap; }
@media (max-width: 480px) {
  .nowrap-phrase { white-space: normal; }
}

/* Cinematic hero load sequence — each piece fades and rises into place once,
   staggered via --delay (inline per element). Runs on page load, since the
   hero sits above the fold and doesn't need scroll to trigger. */
.hero-in {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity 550ms cubic-bezier(0.22, 1, 0.36, 1), transform 550ms cubic-bezier(0.22, 1, 0.36, 1);
  transition-delay: var(--delay, 0ms);
}
.hero-in.is-visible { opacity: 1; transform: translateY(0); }
h1 .hero-in { display: inline-block; }

/* "Grow Together." — starts white, then settles into the same light coastal
   blue already used elsewhere against this dark hero (the pill badge, the
   "Media" in the logo). A plain color transition — simpler and more robust
   than a clip-path wipe, and there's only ever one copy of the text. */
.grow-together {
  color: var(--warm-white);
  transition: color 550ms cubic-bezier(0.65, 0, 0.35, 1);
  transition-delay: var(--fill-delay, 0ms);
}
.grow-together.is-visible { color: #8fd4e8; }

@media (prefers-reduced-motion: reduce) {
  .hero-in {
    opacity: 1;
    transform: none;
    transition: none;
  }
  .grow-together { color: #8fd4e8; transition: none; }
}

/* Pill badge — used above hero headlines for a stronger, more confident opening beat */
.pill-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  padding: 0.5rem 1rem;
  border: 1px solid rgba(63, 160, 194, 0.4);
  border-radius: 999px;
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: #8fd4e8;
  background: rgba(63, 160, 194, 0.08);
  margin-bottom: var(--space-md);
}
.pill-badge .dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--ocean);
  box-shadow: 0 0 0 4px rgba(63, 160, 194, 0.25);
  flex-shrink: 0;
}

/* ---------- Focus & accessibility ---------- */
a:focus-visible,
button:focus-visible,
input:focus-visible,
textarea:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 3px;
}
.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--navy);
  color: var(--warm-white);
  padding: 0.75rem 1.25rem;
  z-index: 200;
}
.skip-link:focus {
  left: var(--space-sm);
  top: var(--space-sm);
}

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.55rem;
  padding: 1rem 2rem;
  min-height: 44px;
  font-family: var(--font-body);
  font-size: 0.95rem;
  font-weight: 700;
  letter-spacing: 0.01em;
  text-decoration: none;
  border-radius: 3px;
  border: 1px solid transparent;
  cursor: pointer;
  transition: background 250ms ease, color 250ms ease, border-color 250ms ease, transform 250ms ease, box-shadow 250ms ease;
  white-space: nowrap;
}
.btn svg { width: 16px; height: 16px; transition: transform 250ms ease; }
.btn:hover svg { transform: translateX(5px); }
.btn:hover {
  transform: translateY(-3px);
  box-shadow: 0 10px 22px rgba(28, 43, 58, 0.18);
}
.btn:active { transform: translateY(-1px); }

.btn-accent {
  background: var(--ocean);
  color: var(--warm-white);
  box-shadow: 0 8px 24px rgba(47, 147, 179, 0.35);
}
.btn-accent:hover { background: #3aa5c7; box-shadow: 0 12px 28px rgba(47, 147, 179, 0.4); }

.btn-primary {
  background: var(--navy);
  color: var(--warm-white);
}
.btn-primary:hover { background: #263f56; }

.btn-outline {
  background: transparent;
  color: var(--navy);
  border-color: var(--navy);
}
.btn-outline:hover { background: var(--navy); color: var(--warm-white); }

.btn-on-dark {
  background: var(--warm-white);
  color: var(--navy);
}
.btn-on-dark:hover { background: var(--sand); }

.btn-outline-on-dark {
  background: transparent;
  color: var(--warm-white);
  border-color: rgba(250, 246, 240, 0.55);
}
.btn-outline-on-dark:hover { background: rgba(250, 246, 240, 0.12); border-color: var(--warm-white); }

/* ---------- Header / Nav ---------- */
/* Header is solid navy with light text on every page. On pages with a hero
   video/image (.has-hero) it starts transparent so that media shows through
   behind the logo/nav, then solidifies to the same navy the instant
   scrolling begins — never to a lighter color. */
.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: var(--navy);
  border-bottom: 1px solid transparent;
  transition: background var(--transition), border-color var(--transition), box-shadow var(--transition);
}
.site-header.is-scrolled {
  border-color: rgba(250, 246, 240, 0.12);
  box-shadow: 0 4px 24px rgba(9, 14, 19, 0.28);
}

.site-header.has-hero {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  width: 100%;
  background: transparent;
  border-bottom-color: transparent;
  backdrop-filter: none;
  transition: background 300ms ease, backdrop-filter 300ms ease, box-shadow 300ms ease, border-color 300ms ease;
}
/* Glassmorphism once the visitor scrolls past the hero — translucent, blurred,
   softly shadowed, rather than snapping to a flat solid color. */
.site-header.has-hero.is-scrolled {
  background: rgba(28, 43, 58, 0.55);
  backdrop-filter: blur(16px) saturate(160%);
  -webkit-backdrop-filter: blur(16px) saturate(160%);
  box-shadow: 0 8px 30px rgba(9, 14, 19, 0.16);
  border-bottom-color: rgba(250, 246, 240, 0.1);
}

.nav-wrap {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-block: 1.1rem;
  gap: var(--space-sm);
}
.logo {
  display: flex;
  flex-direction: column;
  font-family: var(--font-display);
  font-size: clamp(1.4rem, 1.2rem + 0.7vw, 1.75rem);
  font-weight: 600;
  text-decoration: none;
  color: var(--warm-white);
  letter-spacing: -0.02em;
  line-height: 1.15;
}
.logo-name { white-space: nowrap; }
.logo-media { color: #8fd4e8; }
.logo-tagline {
  display: block;
  text-align: center;
  font-family: var(--font-body);
  font-size: clamp(0.42rem, 0.32rem + 0.7vw, 0.56rem);
  font-weight: 600;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--warm-white);
  white-space: nowrap;
  line-height: 1.3;
  margin-top: 4px;
}

/* Stronger brand mark on the homepage specifically */
.logo--brand {
  font-size: clamp(1.9rem, 1.6rem + 0.75vw, 2.3rem);
  font-weight: 800;
  letter-spacing: -0.02em;
  white-space: nowrap;
}

.nav-links {
  display: none;
  align-items: center;
  gap: var(--space-md);
  list-style: none;
  margin: 0;
  padding: 0;
}
.nav-links a {
  text-decoration: none;
  font-size: 0.95rem;
  font-weight: 500;
  color: var(--warm-white);
  position: relative;
  padding: 0.5rem 0.95rem;
  border-radius: 999px;
  transition: color 250ms ease, background-color 250ms ease;
}
.nav-links a:hover { color: #8fd4e8; }
/* Premium active-state indicator: a soft rounded pill behind the label,
   instead of an underline — quieter and more editorial. */
.nav-links a.is-active {
  color: #d8f0f8;
  background: rgba(143, 212, 232, 0.16);
}

.nav-cta { display: none; }

.nav-actions { display: flex; align-items: center; gap: var(--space-sm); }

.nav-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  background: transparent;
  border: 1px solid rgba(250, 246, 240, 0.4);
  border-radius: 2px;
  color: var(--warm-white);
  cursor: pointer;
}
.nav-toggle svg { width: 20px; height: 20px; }

@media (min-width: 900px) {
  .nav-links { display: flex; }
  .nav-cta { display: inline-flex; }
  .nav-toggle { display: none; }
}

.mobile-menu {
  display: none;
  flex-direction: column;
  gap: 0;
  border-top: 1px solid rgba(250, 246, 240, 0.15);
  background: var(--navy);
}
.mobile-menu.is-open { display: flex; }
.mobile-menu a:not(.btn) {
  padding: 1rem var(--space-sm);
  text-decoration: none;
  color: var(--warm-white);
  border-bottom: 1px solid rgba(250, 246, 240, 0.15);
  font-weight: 500;
}
.mobile-menu .btn { margin: var(--space-sm); }

@media (min-width: 900px) {
  .mobile-menu { display: none !important; }
}

/* ---------- Hero ---------- */
.hero {
  position: relative;
  min-height: 88vh;
  display: flex;
  align-items: flex-end;
  color: var(--warm-white);
  background-size: cover;
  background-position: center;
  overflow: hidden;
}
/* Extremely faint editorial-grid guides — a quiet nod to the "media" side of
   the brand. Not meant to be consciously noticed. */
.hero::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background-image: repeating-linear-gradient(
    90deg,
    transparent 0,
    transparent calc(25% - 1px),
    rgba(250, 246, 240, 0.05) calc(25% - 1px),
    rgba(250, 246, 240, 0.05) 25%
  );
}
.hero-video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  z-index: 0;
}

/* ---------- Ocean story (Home page: Hero through Community Partnerships) ----------
   The video pins continuously behind every section from Hero down through
   Community Partnerships — all of them show it through a translucent glass
   panel (varying darkness per section, never fully opaque). The CTA band
   and everything after it live outside this wrapper, on a plain white
   background, and never see the video. Pinning is JS-driven (fixed while scrolling through
   the wrapper, then handed off to an absolutely-positioned match at the
   exact release point) rather than the CSS sticky + negative-margin trick —
   that trick doesn't reliably stop at the wrapper's edge, and was letting
   the video bleed into the sections after it. See updateOceanVideoPin() in
   main.js. Desktop/motion-allowed only. On mobile/reduced-motion, nothing
   here applies and every section keeps its normal static background. */
.ocean-story { position: relative; }
.ocean-story > section { position: relative; z-index: 1; }
.ocean-video-sticky {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100vh;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
}
.ocean-video-sticky.is-released { position: absolute; left: 0; }
.ocean-video-sticky .ocean-video {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Once the sticky video is actually in place, let it show through: the
   hero's own poster image steps aside, and About / Premium Publications swap
   their solid backgrounds for a translucent glass tint over the water. */
.ocean-story.has-ocean-video .hero { background-image: none !important; }
.ocean-story.has-ocean-video #about {
  background: linear-gradient(180deg, rgba(12, 19, 26, 0.32) 0%, rgba(12, 19, 26, 0.58) 100%);
  backdrop-filter: blur(6px) saturate(140%);
  -webkit-backdrop-filter: blur(6px) saturate(140%);
}
.ocean-story.has-ocean-video #about .eyebrow { color: #8fd4e8; }
.ocean-story.has-ocean-video #about h2,
.ocean-story.has-ocean-video #about p { color: var(--warm-white); }
.ocean-story.has-ocean-video #premium-publications {
  /* #premium-publications is also .section-dark, which sets an opaque
     background-color (background: var(--navy) shorthand) — without clearing
     it here, this gradient just layers over solid navy instead of the video. */
  background-color: transparent;
  background-image: linear-gradient(180deg, rgba(12, 19, 26, 0.42) 0%, rgba(9, 14, 19, 0.58) 100%);
  backdrop-filter: blur(3px) saturate(140%);
  -webkit-backdrop-filter: blur(3px) saturate(140%);
}

/* Digital Marketing continues the glass treatment — same family as Premium
   Publications, text flips to white/light-accent for legibility. */
.ocean-story.has-ocean-video #digital-marketing {
  background-image: linear-gradient(180deg, rgba(12, 19, 26, 0.42) 0%, rgba(9, 14, 19, 0.6) 100%);
  backdrop-filter: blur(3px) saturate(140%);
  -webkit-backdrop-filter: blur(3px) saturate(140%);
  color: var(--warm-white);
}
.ocean-story.has-ocean-video #digital-marketing .service-label .accent-line { background: #8fd4e8; }
.ocean-story.has-ocean-video #digital-marketing .icon-block svg { color: #8fd4e8; }

/* Promotional Products continues the same glass-over-video treatment as
   Premium Publications (it's also .section-dark, so it needs the same
   background-color: transparent fix, but its white text / light chips /
   bright accent-line already come free from .section-dark's own rules). */
.ocean-story.has-ocean-video #promotional-products {
  background-color: transparent;
  background-image: linear-gradient(180deg, rgba(12, 19, 26, 0.42) 0%, rgba(9, 14, 19, 0.58) 100%);
  backdrop-filter: blur(3px) saturate(140%);
  -webkit-backdrop-filter: blur(3px) saturate(140%);
}

/* Community Partnerships continues the glass-over-video treatment too. */
.ocean-story.has-ocean-video #community-partnerships {
  background-image: linear-gradient(180deg, rgba(12, 19, 26, 0.42) 0%, rgba(9, 14, 19, 0.6) 100%);
  backdrop-filter: blur(3px) saturate(140%);
  -webkit-backdrop-filter: blur(3px) saturate(140%);
  color: var(--warm-white);
}
.ocean-story.has-ocean-video #community-partnerships .service-label .accent-line { background: #8fd4e8; }
.ocean-story.has-ocean-video #community-partnerships .chip { background: rgba(255, 255, 255, 0.92); color: var(--navy); }

.hero::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  background: linear-gradient(180deg, rgba(20, 32, 43, 0.35) 0%, rgba(20, 32, 43, 0.55) 55%, rgba(15, 24, 33, 0.82) 100%);
}

/* Stronger fade — used where the source photo has identifiable people we don't want prominent */
.hero-dark::before {
  background: linear-gradient(180deg, rgba(12, 19, 26, 0.8) 0%, rgba(12, 19, 26, 0.9) 45%, rgba(9, 14, 19, 0.97) 100%);
}

/* Lighter fade once the background video (waves, no people) has taken over from the static poster.
   ~12% lighter than before — the water's movement and texture should read
   clearly without competing with the text on top of it. */
.hero-dark.has-video::before {
  background: linear-gradient(180deg, rgba(12, 19, 26, 0.44) 0%, rgba(12, 19, 26, 0.54) 45%, rgba(9, 14, 19, 0.7) 100%);
}
.hero-content {
  position: relative;
  z-index: 2;
  padding-block: var(--space-xl) var(--space-lg);
  max-width: 780px;
}
.hero-content h1 {
  color: var(--warm-white);
  margin-bottom: var(--space-sm);
  /* Soft, wide shadow — reads as depth against the moving water, not weight */
  text-shadow: 0 6px 28px rgba(9, 14, 19, 0.28);
}
.hero-content p {
  font-size: clamp(1.05rem, 1rem + 0.4vw, 1.25rem);
  color: var(--white);
  max-width: 60ch;
  text-shadow: 0 4px 18px rgba(9, 14, 19, 0.22);
}
.hero-actions { display: flex; flex-wrap: wrap; gap: var(--space-xs); margin-top: var(--space-sm); }

/* Secondary-page hero variant (About, Services) — short, single-statement
   heroes read better centered than left-aligned like the taller Home hero. */
.hero-content--center { text-align: center; margin-inline: auto; }

/* ---------- Sections ---------- */
section { padding-block: var(--space-xl); }
.section-alt { background: var(--color-bg-alt); }
.section-dark {
  background: var(--navy);
  color: var(--warm-white);
}
.section-dark h2, .section-dark h3 { color: var(--warm-white); }
.section-dark p { color: var(--white); }
.section-dark .eyebrow { color: #8fd4e8; }

/* About page: a beat of white space between the Who We Serve gradient and
   the video CTA band right after it — margin (not padding) so it reveals
   the page's own white background instead of extending the gradient. */
#who-we-serve { margin-bottom: 2rem; padding-top: 1rem; }

/* About page: tighten the white gap above Who We Serve — the default
   section padding-block (6rem top/bottom on each side) otherwise stacks up
   to ~192px of empty white space between the two sections. */
#who-we-are { padding-bottom: 1rem; }

/* Keep the Who We Serve headline on one line at desktop widths (mobile
   still wraps normally — forcing nowrap there would shrink it too small). */
@media (min-width: 800px) {
  #who-we-serve .section-head { max-width: 900px; }
  #who-we-serve .section-head h2 { white-space: nowrap; }
}

/* Left-to-right blue gradient band, same brand colors as the rest of the site */
.gradient-band {
  /* Horizontal brand gradient, plus a very soft vertical fade at the top/
     bottom edges so the seam against a neighboring light section reads as
     a blend rather than a hard cut. */
  background-image:
    linear-gradient(180deg, rgba(250, 246, 240, 0.12) 0%, transparent 10%, transparent 90%, rgba(250, 246, 240, 0.12) 100%),
    linear-gradient(120deg, var(--navy) 0%, var(--ocean-deep) 55%, var(--ocean) 100%);
}

.section-head { max-width: 640px; margin-bottom: var(--space-lg); }
.section-head.center { margin-inline: auto; text-align: center; }

/* ---------- Grid layouts ---------- */
.grid-2 {
  display: grid;
  gap: var(--space-lg);
  align-items: center;
}
@media (min-width: 800px) {
  .grid-2 { grid-template-columns: 1fr 1fr; }
}
.check-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0.75rem;
}
.check-list li {
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
}
.check-list svg {
  flex-shrink: 0;
  width: 20px;
  height: 20px;
  margin-top: 0.15rem;
  color: var(--color-accent);
}
.check-list span { font-size: 0.98rem; }

/* Scroll-reveal fade-in used across editorial sections */
.reveal { opacity: 0; transform: translateY(28px); transition: opacity 700ms ease, transform 700ms ease; }
.reveal.is-visible { opacity: 1; transform: translateY(0); }
@media (prefers-reduced-motion: reduce) {
  .reveal { opacity: 1; transform: none; transition: none; }
}

/* Digital Marketing icon grid — flex, capped to exactly 3 per row so a
   partial last row (2 items) wraps and centers instead of hugging the left
   edge under a fixed column grid. */
.icon-grid {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-sm) var(--space-md);
  margin-bottom: var(--space-md);
  max-width: 560px;
  margin-inline: auto;
}
.icon-block {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 0.5rem;
  flex: 0 1 150px;
  padding: 0.75rem;
  border-radius: 12px;
  opacity: 0;
  transform: translateY(15px);
  transition: opacity 500ms ease-out, transform 250ms ease, box-shadow 250ms ease;
  transition-delay: calc(var(--i, 0) * 100ms);
}
.service-block.is-visible .icon-block { opacity: 1; transform: translateY(0); }
/* Services page tab-panels (.service-panel) never get an is-visible toggle
   like .service-block does — there's no scroll trigger, just a click-to-show
   tab switcher — so without this, icons there stay stuck at opacity:0. */
.service-panel .icon-block { opacity: 1; transform: none; }
.icon-block:hover {
  transform: translateY(-4px) scale(1.03);
  box-shadow: 0 10px 26px rgba(47, 147, 179, 0.25);
  transition-delay: 0ms;
}
.icon-block svg { width: 30px; height: 30px; color: var(--color-accent); }
.icon-block span { font-weight: 600; font-size: 0.92rem; }
@media (prefers-reduced-motion: reduce) {
  .icon-block { opacity: 1; transform: none; }
}

/* Digital Marketing (Home) — exactly 4 icons, sized/gapped to fit one row
   at desktop widths (4 * 130px + 3 * gap comfortably clears the 720px
   service-block container once its own padding is subtracted). Still wraps
   to 2 per row on narrow/mobile viewports via the base .icon-grid's
   flex-wrap — no separate breakpoint needed. */
.icon-grid--quad {
  max-width: 620px;
  gap: var(--space-sm);
}
.icon-grid--quad .icon-block { flex: 0 1 130px; }

/* Service-block paragraph and chip-row/check-list fade in/out together with
   the label, headline, and icons — the whole section's content participates
   in the block-level is-visible toggle, so it all fades away together when
   scrolling back up past the section (see the bidirectional block observer
   in main.js), not just the headline. */
.service-block .container > p {
  opacity: 0;
  transform: translateY(15px);
  transition: opacity 500ms ease, transform 500ms ease;
  transition-delay: 200ms;
}
.service-block.is-visible .container > p { opacity: 1; transform: translateY(0); }
.service-block .chip-row,
.service-block .check-list {
  opacity: 0;
  transition: opacity 500ms ease;
  transition-delay: 300ms;
}
.service-block.is-visible .chip-row,
.service-block.is-visible .check-list { opacity: 1; }
@media (prefers-reduced-motion: reduce) {
  .service-block .container > p,
  .service-block .chip-row,
  .service-block .check-list {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

/* Product / focus-area chips */
.chip-row { display: flex; flex-wrap: wrap; justify-content: center; gap: 0.6rem; margin-bottom: var(--space-md); }
.chip {
  padding: 0.5rem 1rem;
  border-radius: 999px;
  background: rgba(47, 147, 179, 0.12);
  color: var(--navy);
  font-size: 0.85rem;
  font-weight: 600;
}
.section-dark .chip { background: rgba(255, 255, 255, 0.92); color: var(--navy); }

/* ---------- Service tabs ---------- */
.service-tabs {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-2xs);
  margin-bottom: var(--space-lg);
}
.service-tab {
  font-family: var(--font-body);
  font-size: 0.92rem;
  font-weight: 600;
  padding: 0.75rem 1.4rem;
  border-radius: 999px;
  border: 1px solid var(--color-border);
  background: transparent;
  color: var(--charcoal);
  cursor: pointer;
  transition: background var(--transition), color var(--transition), border-color var(--transition);
}
.service-tab:hover { border-color: var(--color-accent); color: var(--color-accent); }
.service-tab.is-active {
  background: var(--navy);
  border-color: var(--navy);
  color: var(--warm-white);
}
.service-panel { max-width: 720px; margin-inline: auto; text-align: center; }
.service-panel[hidden] { display: none; }

/* Dark/gradient section variant — used when the Find Your Fit tabs sit on
   the navy gradient band instead of a light background */
.section-dark .service-tab {
  border-color: rgba(250, 246, 240, 0.35);
  color: var(--warm-white);
}
.section-dark .service-tab:hover { border-color: var(--color-accent); color: #8fd4e8; }
.section-dark .service-tab.is-active {
  background: var(--ocean);
  border-color: var(--ocean);
  color: var(--warm-white);
}

/* Stacked, always-visible service blocks (Home page) — replaces the tab/panel
   switcher there; each block is its own full-width section with alternating
   backgrounds, centered content, and a distinct service-name label. */
.service-block {
  overflow: hidden;
  position: relative;
}
.service-block .container {
  max-width: 720px;
  text-align: center;
}

/* Signature reveal: the service label fades and comes into focus (blur)
   while rising slightly, with a soft rounded clip-path sweeping across it —
   evokes a gentle swell without literal wave imagery. The left-to-right
   slide-in runs on the standalone `translate` property (independent of
   `transform`, which just carries the vertical rise) specifically so it can
   carry its own transition-delay — 0.30s behind everything else, so the
   label is already fading/rising into place before it starts sliding over
   from off-screen. Re-triggers every time the section scrolls into or out
   of view (see the block-level is-visible toggle below), so it slides back
   out to the left if you scroll back up past it. */
.service-label {
  position: relative;
  display: inline-block;
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 400;
  font-size: clamp(1.9rem, 1.5rem + 2vw, 3rem);
  letter-spacing: -0.01em;
  margin-bottom: var(--space-sm);
  color: inherit;
  opacity: 0;
  filter: blur(8px);
  transform: translateY(25px);
  translate: -35vw 0;
  clip-path: inset(0 100% -0.3em 0 round 0.6em);
  transition:
    opacity 700ms cubic-bezier(0.22, 1, 0.36, 1),
    filter 700ms cubic-bezier(0.22, 1, 0.36, 1),
    transform 700ms cubic-bezier(0.22, 1, 0.36, 1),
    clip-path 850ms cubic-bezier(0.22, 1, 0.36, 1),
    translate 700ms cubic-bezier(0.22, 1, 0.36, 1) 300ms;
}
.service-block.is-visible .service-label {
  opacity: 1;
  filter: blur(0);
  transform: translateY(0);
  translate: 0 0;
  clip-path: inset(0 0% -0.3em 0 round 0.6em);
}

/* Headline — each line comes into focus independently, staggered via --i.
   Delay pushed back 0.30s (from the original 150ms base) so the headline
   still starts after the label's now-later slide-in has finished settling. */
.headline { display: block; }
.headline .line {
  display: block;
  opacity: 0;
  filter: blur(6px);
  transform: translateY(20px);
  transition:
    opacity 600ms cubic-bezier(0.22, 1, 0.36, 1),
    filter 600ms cubic-bezier(0.22, 1, 0.36, 1),
    transform 600ms cubic-bezier(0.22, 1, 0.36, 1);
  transition-delay: calc(450ms + var(--i, 0) * 120ms);
}
.service-block.is-visible .headline .line {
  opacity: 1;
  filter: blur(0);
  transform: translateY(0);
}

@media (prefers-reduced-motion: reduce) {
  .service-label,
  .headline .line {
    opacity: 1;
    filter: none;
    transform: none;
    translate: none;
    clip-path: none;
    transition: none;
  }
}

/* ---------- CTA band ----------
   Default treatment: a photo band with a dark overlay and white text —
   used as-is on About and Services. */
.cta-band {
  position: relative;
  background-size: cover;
  background-position: center;
  color: var(--warm-white);
  text-align: center;
}
.cta-band::before {
  content: "";
  position: absolute;
  inset: 0;
  background: rgba(19, 30, 41, 0.72);
}
/* Lighter once the video (moving water, not a static photo) has taken over —
   same reasoning as the hero's own has-video overlay. */
.cta-band.has-video::before { background: rgba(12, 19, 26, 0.5); }
.cta-band .container { position: relative; z-index: 2; max-width: 720px; }
.cta-band h2 { color: var(--warm-white); }
.cta-band p { color: var(--white); }
/* Same light coastal blue as "Grow Together." on the Hero — only used where
   it's added in markup (the About page's video CTA), not Home's white one,
   where it would be too low-contrast to read. */
.cta-highlight { color: #8fd4e8; }

/* Home page only: closes the alternation on a clean, opaque white panel —
   the video-over-glass treatment stops at Community Partnerships, right
   before this, so no photo/overlay is needed here at all. */
.cta-band--white {
  background: var(--color-bg);
}
.cta-band--white::before { display: none; }
.cta-band--white h2,
.cta-band--white p { color: var(--color-text); }

/* ---------- Wave outro ----------
   A short, purely decorative closing strip between the CTA and the footer —
   the ocean video again, full color, no overlay, no copy. Same self-
   contained video pattern as .hero (see main.js), just without any text
   content to gate contrast against, so it needs no dark overlay at all. */
.wave-outro {
  position: relative;
  height: clamp(180px, 22vw, 320px);
  padding: 0;
  overflow: hidden;
  background-size: cover;
  background-position: center;
}

/* ---------- Forms ---------- */
.form-field { margin-bottom: var(--space-sm); }
.form-field label {
  display: block;
  font-size: 0.9rem;
  font-weight: 600;
  margin-bottom: 0.4rem;
}
.form-field input,
.form-field textarea {
  width: 100%;
  font-family: var(--font-body);
  font-size: 1rem;
  padding: 0.85rem 1rem;
  border: 1px solid var(--color-border);
  background: var(--white);
  color: var(--charcoal);
  border-radius: 2px;
}
.form-field textarea { min-height: 140px; resize: vertical; }
.form-note { font-size: 0.85rem; color: var(--color-text-muted); margin-top: var(--space-sm); }

/* ---------- Footer ---------- */
.site-footer {
  background: var(--navy);
  color: rgba(250, 246, 240, 0.75);
  padding-block: var(--space-lg) var(--space-md);
  font-size: 0.9rem;
}
.footer-grid {
  display: grid;
  gap: var(--space-md);
  margin-bottom: var(--space-lg);
}
@media (min-width: 700px) {
  .footer-grid { grid-template-columns: 2fr 1fr 1fr; }
}
.site-footer h4 {
  color: var(--warm-white);
  font-family: var(--font-body);
  font-size: 0.85rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  font-weight: 600;
  margin-bottom: var(--space-sm);
}
.footer-links { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.6rem; }
.footer-links a { text-decoration: none; color: inherit; }
.footer-links a:hover { color: var(--warm-white); }
.footer-bottom {
  border-top: 1px solid rgba(250, 246, 240, 0.15);
  padding-top: var(--space-sm);
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs);
  justify-content: space-between;
  font-size: 0.8rem;
  /* Dark gray against the navy footer — deliberately low-contrast so the
     copyright/credits line reads as quiet fine print, not a call to action. */
  color: #4a4a4a;
}
.footer-bottom a { color: #4a4a4a; text-decoration: underline; }

/* ---------- Utilities ---------- */
.text-center { text-align: center; }
.mt-0 { margin-top: 0; }
.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}
