/* ==========================================================================
   SIPHER DIGITAL — Design System
   Static site. No build step. Sections below, in order:
   1. Tokens   2. Reset/Base   3. Layout utilities   4. Type utilities
   5. Nav      6. Buttons      7. Cards & atmo blocks 8. Sections (shared)
   9. Footer   10. Forms       11. Motion/reveal states 12. Responsive
   ========================================================================== */

/* 1. TOKENS ---------------------------------------------------------------- */
:root {
  /* Color: ink / neutrals (warm charcoal, not pure black) */
  --ink: #16161c;
  --ink-soft: #4a4a55;
  --muted: #6f6c66; /* darkened from #86837e — 3.56:1 failed WCAG AA on --bg; this hits 4.93:1 */
  --muted-on-navy: #a7a4bb;

  --navy: #1a1b26;
  --navy-2: #22232f;
  --on-navy: #f4f2ec;

  --bg: #faf8f4;
  --surface: #ffffff;
  --surface-2: #f2efe8;
  --line: #e4ded2;
  --line-on-navy: rgba(244, 242, 236, 0.12);

  /* Color: accent — subtle violet */
  --accent: #675fc2;
  --accent-strong: #514797;
  --accent-soft: #edebf9;
  --accent-on-navy: #9b8fe8;

  --success: #386b4f; /* darkened from #3f7a5c — was 4.43:1 on its status bg, just under AA */
  --danger: #b0473f;

  /* Fonts */
  --font-display: 'Geist', 'Plus Jakarta Sans', ui-sans-serif, system-ui, -apple-system, sans-serif;
  --font-body: 'Plus Jakarta Sans', ui-sans-serif, system-ui, -apple-system, sans-serif;

  /* Type scale (fluid) */
  --text-xs: 0.8125rem;
  --text-sm: 0.9375rem;
  --text-base: 1.0625rem;
  --text-lg: 1.1875rem;
  --text-xl: 1.5rem;
  --text-2xl: clamp(1.75rem, 1.5rem + 1vw, 2.25rem);
  --text-3xl: clamp(2.25rem, 1.7rem + 2.2vw, 3.25rem);
  --text-4xl: clamp(2.75rem, 1.9rem + 3.5vw, 4.5rem);
  --text-hero: clamp(2.75rem, 1.7rem + 5.2vw, 6.25rem);

  --lh-tight: 1.08;
  --lh-snug: 1.25;
  --lh-body: 1.65;

  /* Spacing (generous, editorial rhythm) */
  --space-1: 0.5rem;
  --space-2: 1rem;
  --space-3: 1.5rem;
  --space-4: 2rem;
  --space-5: 3rem;
  --space-6: 4rem;
  --space-7: 6rem;
  --space-8: 8rem;
  --space-9: 10rem;

  /* Radius */
  --radius-sm: 6px;
  --radius-md: 12px;
  --radius-lg: 22px;
  --radius-full: 999px;

  /* Shadow — soft, editorial, never skeuomorphic */
  --shadow-sm: 0 1px 2px rgba(22, 22, 28, 0.05);
  --shadow-md: 0 16px 40px -20px rgba(22, 22, 28, 0.22);
  --shadow-lg: 0 32px 80px -24px rgba(22, 22, 28, 0.28);

  /* Motion */
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
  --dur-fast: 200ms;
  --dur-base: 400ms;
  --dur-slow: 700ms;

  /* Layout */
  --container-max: 1280px;
  --container-pad: clamp(1.5rem, 4vw, 4rem);
  --nav-h: 88px;
}

/* 2. RESET / BASE ----------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; padding: 0; }

html {
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
}

@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 {
  font-family: var(--font-body);
  font-size: var(--text-base);
  line-height: var(--lh-body);
  color: var(--ink);
  background: var(--bg);
  min-height: 100dvh;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img, svg { display: block; max-width: 100%; }

a { color: inherit; text-decoration: none; }

button, input, textarea, select {
  font: inherit;
  color: inherit;
  background: none;
  border: none;
}

ul, ol { list-style: none; }

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 600;
  line-height: var(--lh-tight);
  letter-spacing: -0.02em;
  color: var(--ink);
}

::selection { background: var(--accent); color: #fff; }

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 2px;
}

/* Skip link */
.skip-link {
  position: fixed;
  top: -100%;
  left: var(--space-2);
  background: var(--ink);
  color: var(--on-navy);
  padding: 0.75rem 1.25rem;
  border-radius: var(--radius-sm);
  z-index: 999;
  transition: top var(--dur-fast) var(--ease-out);
}
.skip-link:focus { top: var(--space-2); }

/* cursor-pointer on interactive elements */
a, button, [role="button"], input[type="submit"], .magnetic { cursor: pointer; }

/* 3. LAYOUT ------------------------------------------------------------------ */
.container {
  width: 100%;
  max-width: var(--container-max);
  margin-inline: auto;
  padding-inline: var(--container-pad);
}

.section { padding-block: var(--space-8); }
.section--tight { padding-block: var(--space-6); }
.section--navy { background: var(--navy); color: var(--on-navy); }
.section--surface2 { background: var(--surface-2); }

.grid { display: grid; gap: var(--space-4); }
.grid-2 { grid-template-columns: repeat(2, 1fr); }
.grid-3 { grid-template-columns: repeat(3, 1fr); }
.grid-4 { grid-template-columns: repeat(4, 1fr); }
.grid-12 { grid-template-columns: repeat(12, 1fr); }

.stack { display: flex; flex-direction: column; }
.row { display: flex; align-items: center; }
.row-between { display: flex; align-items: center; justify-content: space-between; }
.wrap { flex-wrap: wrap; }

.gap-1 { gap: var(--space-1); }
.gap-2 { gap: var(--space-2); }
.gap-3 { gap: var(--space-3); }
.gap-4 { gap: var(--space-4); }

/* 4. TYPE UTILITIES ----------------------------------------------------------- */
.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 0.6em;
  font-family: var(--font-body);
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted);
}
.eyebrow::before {
  content: '';
  width: 28px;
  height: 1px;
  background: var(--accent);
  display: inline-block;
}
.section--navy .eyebrow { color: var(--muted-on-navy); }
.section--navy h1, .section--navy h2, .section--navy h3, .section--navy h4 { color: var(--on-navy); }

.h-hero { font-size: var(--text-hero); letter-spacing: -0.03em; }
.h-1 { font-size: var(--text-4xl); }
.h-2 { font-size: var(--text-3xl); }
.h-3 { font-size: var(--text-2xl); }
.h-4 { font-size: var(--text-xl); font-weight: 600; }

.lede {
  font-size: var(--text-lg);
  line-height: var(--lh-snug);
  color: var(--ink-soft);
  max-width: 42ch;
}
.section--navy .lede { color: var(--muted-on-navy); }

.text-muted { color: var(--muted); }
.text-accent { color: var(--accent); }
.text-balance { text-wrap: balance; }
.measure { max-width: 62ch; }

/* word-reveal target: motion.js wraps each word in .word/.word-inner and
   sets the hidden starting transform via GSAP. No-JS / GSAP-blocked
   visitors never get split, so the heading just shows as plain text. */
.split-words .word { overflow: hidden; display: inline-block; vertical-align: top; }
.split-words .word-inner { display: inline-block; will-change: transform; }

/* 5. NAV ---------------------------------------------------------------------- */
.nav {
  position: fixed;
  inset-inline: 0;
  top: 0;
  z-index: 100;
  height: var(--nav-h);
  display: flex;
  align-items: center;
  background: transparent;
  transition: background var(--dur-base) var(--ease-out),
              border-color var(--dur-base) var(--ease-out),
              box-shadow var(--dur-base) var(--ease-out);
  border-bottom: 1px solid transparent;
}
.nav.is-scrolled {
  background: rgba(250, 248, 244, 0.82);
  backdrop-filter: blur(16px) saturate(140%);
  -webkit-backdrop-filter: blur(16px) saturate(140%);
  border-bottom-color: var(--line);
  box-shadow: var(--shadow-sm);
}
.nav.is-scrolled .nav__link,
.nav.is-scrolled .wordmark { color: var(--ink); }

/* Homepage-only: nav stays transparent and hidden (wordmark + links) while
   the hero panel is in view — only the pearl CTA and the square badge (see
   .nav__badge below) read over it. Once scrolled past the hero, .is-scrolled
   gets added (see main.js) and the badge crossfades into the full wordmark. */
.nav--hero-mode .wordmark,
.nav--hero-mode .nav__links,
.nav--hero-mode .nav__toggle {
  opacity: 0;
  pointer-events: none;
  transform: scale(0.9);
  transition: opacity var(--dur-slow) var(--ease-out), transform var(--dur-slow) var(--ease-out);
}
.nav--hero-mode.is-scrolled .wordmark,
.nav--hero-mode.is-scrolled .nav__links,
.nav--hero-mode.is-scrolled .nav__toggle {
  opacity: 1;
  pointer-events: auto;
  transform: scale(1);
}
.nav--hero-mode:not(.is-scrolled) .wordmark { color: var(--on-navy); }

/* Square badge — the mark alone, shown top-left in place of the wordmark
   while the hero is in view. Sized to match the pearl CTA's 44px min-height
   so the hero-mode nav reads as two balanced, equal-weight elements. Only
   ever rendered on the homepage (nav--hero-mode); harmless if markup is
   ever reused elsewhere since it stays display:none outside that context. */
.nav__badge { display: none; }
.nav--hero-mode .nav__badge {
  position: absolute;
  left: var(--container-pad);
  top: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* Matches the pearl button's actual rendered height (padding + line-height
     push it past the 44px min-height floor) so the two feel like one pair. */
  width: var(--nav-cta-size, 57px);
  height: var(--nav-cta-size, 57px);
  color: var(--accent-on-navy);
  opacity: 1;
  transform: translateY(-50%) scale(1);
  transition: opacity var(--dur-slow) var(--ease-out), transform var(--dur-slow) var(--ease-out);
}
.nav--hero-mode.is-scrolled .nav__badge {
  opacity: 0;
  pointer-events: none;
  transform: translateY(-50%) scale(0.7);
}
.nav__badge-icon { width: 33px; height: 34px; }

.nav__inner {
  position: relative;
  width: 100%;
  max-width: var(--container-max);
  margin-inline: auto;
  padding-inline: var(--container-pad);
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.wordmark {
  display: inline-flex;
  align-items: center;
  gap: 0.05em;
  font-family: var(--font-display);
  font-size: 1.5rem;
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--ink);
  transition: color var(--dur-base) var(--ease-out);
}
.wordmark__mark {
  width: 0.6em;
  height: 0.64em;
  flex-shrink: 0;
  color: var(--accent-strong);
}
.wordmark__dot { color: var(--accent-strong); }
.wordmark__sub {
  align-self: flex-end;
  margin-left: 0.3em;
  padding-bottom: 0.1em;
  font-size: 0.34em;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
}

.nav__links {
  display: flex;
  align-items: center;
  gap: var(--space-4);
}
.nav__link {
  position: relative;
  font-size: var(--text-sm);
  font-weight: 500;
  color: var(--ink);
  padding-block: 0.4rem;
  opacity: 0.55;
  transition: color var(--dur-base) var(--ease-out), opacity var(--dur-base) var(--ease-out);
}
.nav__link:hover, .nav__link:focus-visible { opacity: 1; }
.nav__link::after {
  content: '';
  position: absolute;
  left: 0; right: 100%;
  bottom: 0;
  height: 1px;
  background: currentColor;
  transition: right var(--dur-base) var(--ease-out);
}
.nav__link:hover::after { right: 0; }
.nav__link.is-active { color: var(--accent); opacity: 1; }

.nav__cta { display: flex; align-items: center; gap: var(--space-3); }

.nav__toggle {
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 44px;
  height: 44px;
  align-items: center;
}
.nav__toggle span {
  width: 22px;
  height: 1.5px;
  background: currentColor;
  color: var(--ink);
  transition: transform var(--dur-base) var(--ease-out), opacity var(--dur-fast);
}

/* mobile full-screen menu */
.mobile-menu {
  position: fixed;
  inset: 0;
  z-index: 99;
  background: var(--navy);
  color: var(--on-navy);
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: var(--space-4) var(--container-pad);
  opacity: 0;
  visibility: hidden;
  transform: translateY(-8px);
  transition: opacity var(--dur-base) var(--ease-out),
              transform var(--dur-base) var(--ease-out),
              visibility 0s linear var(--dur-base);
}
.mobile-menu.is-open {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
  transition: opacity var(--dur-base) var(--ease-out),
              transform var(--dur-base) var(--ease-out),
              visibility 0s;
}
.mobile-menu__link {
  display: block;
  font-family: var(--font-display);
  font-size: clamp(2rem, 9vw, 3rem);
  font-weight: 600;
  letter-spacing: -0.02em;
  padding-block: 0.35em;
  border-bottom: 1px solid var(--line-on-navy);
  opacity: 0;
  transform: translateY(16px);
}
.mobile-menu.is-open .mobile-menu__link {
  opacity: 1;
  transform: translateY(0);
  transition: opacity var(--dur-slow) var(--ease-out), transform var(--dur-slow) var(--ease-out);
}
.mobile-menu__foot {
  margin-top: var(--space-5);
  display: flex;
  justify-content: space-between;
  color: var(--muted-on-navy);
  font-size: var(--text-sm);
}

/* 6. BUTTONS -------------------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.6rem;
  font-family: var(--font-body);
  font-weight: 600;
  font-size: var(--text-sm);
  letter-spacing: -0.01em;
  padding: 0.95rem 1.75rem;
  border-radius: var(--radius-full);
  transition: transform var(--dur-fast) var(--ease-out),
              background var(--dur-base) var(--ease-out),
              color var(--dur-base) var(--ease-out),
              border-color var(--dur-base) var(--ease-out);
  min-height: 44px;
  white-space: nowrap;
}
.btn:active { transform: scale(0.97); }

.btn--primary {
  background: var(--ink);
  color: var(--on-navy);
}
.btn--primary:hover { background: var(--accent-strong); }

.btn--accent {
  background: var(--accent);
  color: #fff;
}
.btn--accent:hover { background: var(--accent-strong); }

.btn--ghost {
  background: transparent;
  border: 1px solid var(--line);
  color: var(--ink);
}
.btn--ghost:hover { border-color: var(--ink); }

.btn--on-navy {
  background: var(--on-navy);
  color: var(--navy);
}
.btn--on-navy:hover { background: var(--accent-on-navy); color: var(--navy); }

.btn--ghost-on-navy {
  background: transparent;
  border: 1px solid var(--line-on-navy);
  color: var(--on-navy);
}
.btn--ghost-on-navy:hover { border-color: var(--on-navy); }

.btn--icon-trail svg { transition: transform var(--dur-base) var(--ease-out); }
.btn--icon-trail:hover svg { transform: translateX(4px); }

/* Pearlescent CTA — soft 3D lift + mother-of-pearl sheen. Self-contained
   light surface so it reads clearly on both the dark hero and light pages. */
.btn--pearl {
  background:
    linear-gradient(135deg, #ffffff 0%, #f8f6fc 28%, #efe9fb 52%, #f9f7ff 74%, #ffffff 100%);
  color: var(--ink);
  border: 1px solid rgba(255, 255, 255, 0.7);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.9),
    inset 0 -8px 14px -6px rgba(103, 95, 194, 0.12),
    0 2px 6px rgba(20, 18, 30, 0.14),
    0 10px 22px -10px rgba(20, 18, 30, 0.35);
  transition: transform var(--dur-fast) var(--ease-out), box-shadow var(--dur-base) var(--ease-out);
}
.btn--pearl:hover {
  transform: translateY(-2px);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 1),
    inset 0 -8px 16px -6px rgba(103, 95, 194, 0.18),
    0 2px 8px rgba(20, 18, 30, 0.16),
    0 18px 34px -12px rgba(103, 95, 194, 0.4),
    0 0 26px rgba(103, 95, 194, 0.28);
}
.btn--pearl:active { transform: translateY(0) scale(0.97); }

.filter-bar { display: flex; flex-wrap: wrap; gap: 0.6rem; }
.filter-btn {
  font-size: var(--text-sm);
  font-weight: 500;
  padding: 0.6rem 1.1rem;
  border-radius: var(--radius-full);
  border: 1px solid var(--line);
  color: var(--ink-soft);
  transition: background var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out);
}
.filter-btn:hover { border-color: var(--ink); color: var(--ink); }
.filter-btn.is-active { background: var(--ink); border-color: var(--ink); color: var(--on-navy); }

.pill-row { display: flex; flex-wrap: wrap; gap: 0.6rem; }
.pill {
  display: inline-flex;
  align-items: center;
  font-size: var(--text-xs);
  font-weight: 500;
  padding: 0.5rem 1rem;
  border-radius: var(--radius-full);
  border: 1px solid var(--line);
  color: var(--ink-soft);
}
.section--navy .pill { border-color: var(--line-on-navy); color: var(--muted-on-navy); }

.service-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-6);
  align-items: center;
  padding-block: var(--space-7);
}
.service-row:not(:last-child) { border-bottom: 1px solid var(--line); }
.service-row--reverse .service-row__media { order: 2; }
.service-row__index {
  font-family: var(--font-display);
  font-size: var(--text-sm);
  color: var(--accent);
  font-weight: 600;
}

/* Pricing cards */
.price-card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: var(--space-4);
  display: flex;
  flex-direction: column;
  height: 100%;
  transition: transform var(--dur-base) var(--ease-out), box-shadow var(--dur-base) var(--ease-out), border-color var(--dur-base) var(--ease-out);
}
.price-card:hover { transform: translateY(-4px); box-shadow: var(--shadow-md); }
.price-card--featured {
  background: var(--navy);
  color: var(--on-navy);
  border-color: var(--navy);
  position: relative;
}
.price-card--featured .text-muted { color: var(--muted-on-navy); }
.price-card__badge {
  position: absolute;
  top: -13px;
  left: var(--space-4);
  background: var(--accent);
  color: #fff;
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 0.35rem 0.9rem;
  border-radius: var(--radius-full);
}
.price-card__amount {
  font-family: var(--font-display);
  font-size: var(--text-3xl);
  font-weight: 600;
  letter-spacing: -0.02em;
  margin-top: var(--space-2);
}
.price-card__list { margin-top: var(--space-4); flex: 1; display: flex; flex-direction: column; gap: 0.75rem; }
.price-card__list li { display: flex; align-items: flex-start; gap: 0.6rem; font-size: var(--text-sm); }
.price-card__list svg { flex-shrink: 0; margin-top: 0.2rem; color: var(--accent); }
.price-card--featured .price-card__list svg { color: var(--accent-on-navy); }
.price-card__amount--range { font-size: var(--text-2xl); }

/* Add-ons list — a clean modular price sheet, not another row of cards */
.addon-list { border-top: 1px solid var(--line); }
.addon-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-3);
  padding-block: 1.1rem;
  border-bottom: 1px solid var(--line);
}
.addon-row__name { font-weight: 500; }
.addon-row__price {
  font-family: var(--font-display);
  font-weight: 600;
  color: var(--ink-soft);
  white-space: nowrap;
}

/* Timeline (Process page) */
.timeline { position: relative; }
.timeline::before {
  content: '';
  position: absolute;
  left: 28px;
  top: 8px;
  bottom: 8px;
  width: 1px;
  background: var(--line);
}
.timeline__item {
  position: relative;
  display: grid;
  grid-template-columns: 56px 1fr;
  gap: var(--space-4);
  padding-block: var(--space-5);
}
.timeline__item:not(:last-child) { border-bottom: 1px solid var(--line); }
.timeline__dot {
  position: relative;
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: var(--surface);
  border: 1px solid var(--line);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--text-sm);
  color: var(--accent);
  z-index: 1;
}
.timeline__meta {
  display: flex;
  align-items: baseline;
  gap: var(--space-3);
  flex-wrap: wrap;
}

.text-link {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-weight: 600;
  font-size: var(--text-sm);
  color: var(--ink);
  padding-bottom: 2px;
  border-bottom: 1px solid var(--line);
  transition: border-color var(--dur-base) var(--ease-out), color var(--dur-base) var(--ease-out);
}
.text-link:hover { border-color: var(--ink); color: var(--accent-strong); }
.text-link svg { transition: transform var(--dur-base) var(--ease-out); }
.text-link:hover svg { transform: translateX(3px); }

/* 7. CARDS & ATMO PLACEHOLDER BLOCKS ---------------------------------------------- */
.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: var(--space-4);
  transition: transform var(--dur-base) var(--ease-out), box-shadow var(--dur-base) var(--ease-out), border-color var(--dur-base) var(--ease-out);
}
.card:hover { box-shadow: var(--shadow-md); border-color: transparent; transform: translateY(-4px); }

.card__index {
  font-family: var(--font-display);
  font-size: var(--text-sm);
  color: var(--muted);
  font-weight: 600;
}

/* Atmospheric gradient placeholder blocks — stand in for photography */
.atmo {
  position: relative;
  border-radius: var(--radius-lg);
  overflow: hidden;
  background-color: var(--navy);
  isolation: isolate;
}
.atmo::before {
  content: '';
  position: absolute;
  inset: 0;
  background-image:
    radial-gradient(120% 90% at 15% 10%, rgba(155, 143, 232, 0.55), transparent 60%),
    radial-gradient(90% 80% at 85% 90%, rgba(103, 95, 194, 0.45), transparent 55%),
    radial-gradient(140% 100% at 50% 50%, #2a2b3a, #14151d 75%);
}
.atmo::after {
  content: '';
  position: absolute;
  inset: 0;
  opacity: 0.35;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}
.atmo--warm::before {
  background-image:
    radial-gradient(120% 90% at 20% 15%, rgba(220, 210, 190, 0.9), transparent 60%),
    radial-gradient(100% 90% at 85% 85%, rgba(155, 143, 232, 0.35), transparent 55%),
    radial-gradient(140% 100% at 50% 50%, #f2eee4, #e6e0d2 75%);
}
.atmo--warm.atmo { background-color: var(--surface-2); }
.atmo--soft::before {
  background-image:
    radial-gradient(110% 90% at 20% 20%, rgba(103, 95, 194, 0.18), transparent 60%),
    radial-gradient(120% 100% at 80% 80%, rgba(103, 95, 194, 0.10), transparent 55%),
    radial-gradient(140% 100% at 50% 50%, #ffffff, #f2efe8 80%);
}
.atmo--soft.atmo { background-color: var(--surface); }
.atmo--soft::after { opacity: 0.06; }

.atmo-mark {
  position: absolute;
  z-index: 1;
  font-family: var(--font-display);
  font-weight: 600;
  color: rgba(244, 242, 236, 0.5);
  letter-spacing: -0.02em;
  text-shadow: 0 1px 4px rgba(0, 0, 0, 0.35);
}
.atmo--warm .atmo-mark, .atmo--soft .atmo-mark { color: rgba(22, 22, 28, 0.28); }

/* Real client-site photography — sits on the same .atmo block, replacing the
   gradient with a cover-fit screenshot. ::before is hidden rather than the
   photo layered on top of it, so the noise texture (::after) still reads. */
.atmo--photo {
  background-size: cover;
  background-position: center;
}
.atmo--photo::before { opacity: 0; }
.atmo--photo::after { opacity: 0.08; }
.atmo--photo-deboer { background-image: url('../assets/img/portfolio/deboer-bakery.jpg'); }
.atmo--photo-1855 { background-image: url('../assets/img/portfolio/1855-barbershop.jpg'); }
.atmo--photo-alpine { background-image: url('../assets/img/portfolio/alpine-paeonies.jpg'); }

.atmo--photo-web-dev { background-image: url('../assets/img/services/web-development.jpg'); }
.atmo--photo-ui-ux { background-image: url('../assets/img/services/ui-ux-design.jpg'); }
.atmo--photo-branding { background-image: url('../assets/img/services/branding.jpg'); }
.atmo--photo-marketing { background-image: url('../assets/img/services/marketing-ads.jpg'); }
.atmo--photo-automation { background-image: url('../assets/img/services/automation.jpg'); }
.atmo--photo-crm { background-image: url('../assets/img/services/crm.jpg'); }

/* Elastic gallery — accordion-style hover/tap expand for the homepage
   "Recent builds" showcase. Ported from a React component (this project has
   no React/build step) — the actual behaviour is just a flex-basis
   transition plus opacity/filter states, all portable to plain CSS. Reuses
   .atmo as the "photo" layer rather than a second image element. Doesn't
   use data-atmo-reveal on its .atmo children (that GSAP tween sets an
   inline transform, which would fight the hover-driven scale below —
   same class of bug as the pricing-page fix earlier). */
.elastic-gallery {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  height: 460px;
}
.elastic-item {
  position: relative;
  flex: 1;
  min-height: 0;
  display: block;
  overflow: hidden;
  border-radius: var(--radius-lg);
  transition: flex 700ms cubic-bezier(0.25, 1, 0.5, 1);
}
.elastic-item .atmo {
  position: absolute;
  inset: 0;
  border-radius: 0;
  transition: filter 700ms var(--ease-out), transform 900ms var(--ease-out);
  filter: brightness(0.55);
  transform: scale(1.08);
}
.elastic-item.is-active .atmo { filter: brightness(1); transform: scale(1); }
.elastic-item__scrim {
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, rgba(15, 14, 20, 0.85), rgba(15, 14, 20, 0.15) 55%, transparent);
  opacity: 0;
  transition: opacity var(--dur-slow) var(--ease-out);
}
.elastic-item.is-active .elastic-item__scrim { opacity: 1; }
.elastic-item__content {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  padding: var(--space-3);
}
.elastic-item__active {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.6rem;
  opacity: 0;
  transform: translateY(1.5rem);
  transition: opacity var(--dur-slow) var(--ease-out), transform var(--dur-slow) var(--ease-out);
}
.elastic-item.is-active .elastic-item__active {
  opacity: 1;
  transform: translateY(0);
  transition-delay: 150ms;
}
.elastic-item__tag {
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--on-navy);
  background: rgba(255, 255, 255, 0.14);
  border: 1px solid rgba(255, 255, 255, 0.3);
  padding: 0.35rem 0.8rem;
  border-radius: var(--radius-full);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
.elastic-item__title {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(1.5rem, 1.1rem + 2vw, 2.25rem);
  line-height: 1;
  color: var(--on-navy);
  letter-spacing: -0.01em;
}
.elastic-item__cta {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted-on-navy);
}
.elastic-item__cta svg { transition: transform var(--dur-base) var(--ease-out); }
.elastic-item:hover .elastic-item__cta svg { transform: translate(2px, -2px); }
.elastic-item__label {
  position: absolute;
  left: var(--space-3);
  bottom: var(--space-3);
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--on-navy);
  opacity: 1;
  transition: opacity var(--dur-base) var(--ease-out);
}
.elastic-item.is-active .elastic-item__label { opacity: 0; }

@media (min-width: 768px) {
  .elastic-gallery { flex-direction: row; gap: var(--space-3); height: 560px; }
  .elastic-item.is-active { flex: 3.4; }
  .elastic-item__label {
    left: 50%;
    bottom: var(--space-4);
    transform: translateX(-50%);
    writing-mode: vertical-rl;
    font-size: var(--text-sm);
  }
}

/* Work-page showcase cards — full-bleed photo, category + name overlaid on
   a navy/violet-tinted scrim (rather than flat black) so it reads as part of
   the same palette as the rest of the site. Each card links to an internal
   case study page instead of straight out to the live site. */
.showcase-card {
  position: relative;
  display: block;
  aspect-ratio: 4 / 3;
  border-radius: var(--radius-lg);
  overflow: hidden;
}
.showcase-card .atmo {
  position: absolute;
  inset: 0;
  border-radius: 0;
  transition: transform 900ms var(--ease-out);
}
.showcase-card:hover .atmo,
.showcase-card:focus-visible .atmo { transform: scale(1.05); }

.showcase-card__scrim {
  position: absolute;
  inset: 0;
  background: linear-gradient(to top,
    rgba(26, 27, 38, 0.92) 0%,
    rgba(26, 27, 38, 0.55) 35%,
    rgba(81, 71, 151, 0.2) 62%,
    rgba(26, 27, 38, 0) 88%);
  transition: background var(--dur-base) var(--ease-out);
}
.showcase-card:hover .showcase-card__scrim,
.showcase-card:focus-visible .showcase-card__scrim {
  background: linear-gradient(to top,
    rgba(26, 27, 38, 0.95) 0%,
    rgba(26, 27, 38, 0.65) 40%,
    rgba(103, 95, 194, 0.28) 66%,
    rgba(26, 27, 38, 0) 88%);
}

.showcase-card__content {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  padding: var(--space-4);
}
.showcase-card__tag {
  align-self: flex-start;
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--on-navy);
  background: rgba(255, 255, 255, 0.14);
  border: 1px solid rgba(255, 255, 255, 0.3);
  padding: 0.35rem 0.8rem;
  border-radius: var(--radius-full);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
.showcase-card__title {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(1.5rem, 1.15rem + 1.6vw, 2rem);
  color: var(--on-navy);
  letter-spacing: -0.01em;
  margin-top: 0.85rem;
}
.showcase-card__arrow {
  position: absolute;
  top: var(--space-4);
  right: var(--space-4);
  z-index: 1;
  width: 40px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.14);
  border: 1px solid rgba(255, 255, 255, 0.3);
  color: var(--on-navy);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  opacity: 0;
  transition: opacity var(--dur-base) var(--ease-out);
}
.showcase-card__arrow svg { transition: transform var(--dur-base) var(--ease-out); }
.showcase-card:hover .showcase-card__arrow,
.showcase-card:focus-visible .showcase-card__arrow { opacity: 1; }
.showcase-card:hover .showcase-card__arrow svg,
.showcase-card:focus-visible .showcase-card__arrow svg { transform: translate(2px, -2px); }

.showcase-card--wide { aspect-ratio: 21 / 9; }

@media (min-width: 861px) {
  .showcase-card--wide { grid-column: 1 / -1; }
}
@media (max-width: 860px) {
  .showcase-card--wide { aspect-ratio: 4 / 3; }
  .showcase-card__arrow { opacity: 1; }
}

/* Case study pages — quick-facts side panel. */
.cs-meta {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-4);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
}
.cs-meta__row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--space-3);
  padding-bottom: var(--space-3);
  border-bottom: 1px solid var(--line);
}
.cs-meta__row:last-child { border-bottom: none; padding-bottom: 0; }
.cs-meta__label {
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--muted);
}
.cs-meta__value { font-weight: 600; text-align: right; }

.cs-layout {
  display: grid;
  grid-template-columns: 1.6fr 1fr;
  gap: var(--space-6);
  align-items: start;
}
@media (max-width: 860px) {
  .cs-layout { grid-template-columns: 1fr; }
}

/* Homepage hero — flat violet panel, no bevel/bloom, just the wordmark.
   Deliberately separate from .atmo: that treatment stays multi-tone for
   content placeholders, this stays flat and quiet for the hero moment. */
.hero-panel {
  position: relative;
  overflow: hidden;
  background: linear-gradient(175deg, #332c54 0%, #211d33 55%, #17141f 100%);
}
.hero-panel::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 0;
  background: radial-gradient(55% 45% at 50% 45%, rgba(103, 95, 194, 0.32), transparent 72%);
}
/* Kinetic grid canvas (js/kinetic-grid.js) — sits between the background
   and the hero content, sized to its hero via ResizeObserver in JS. Shared
   by both the dark homepage hero and the light inner-page heroes; the
   script itself picks a palette to match whichever it's dropped into. */
.kinetic-grid-canvas {
  position: absolute;
  inset: 0;
  z-index: 1;
  width: 100%;
  height: 100%;
  pointer-events: none;
  display: block;
}
.hero-mark {
  position: relative;
  z-index: 2;
  display: inline-flex;
  align-items: center;
  gap: 0.01em;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(3rem, 3rem + 6vw, 8rem);
  line-height: 1;
  letter-spacing: -0.03em;
  color: var(--on-navy);
  /* -0.06em corrects the descender-driven optical low bias (see prior
     note); the added -3.5rem is a deliberate compositional shift, opening
     clear space below the mark for the scroll cue. */
  transform: translateY(calc(-0.06em - 3.5rem));
}
.hero-mark__icon {
  width: 0.6em;
  height: 0.64em;
  flex-shrink: 0;
  color: var(--accent-on-navy);
}
.hero-mark__text span { color: var(--accent-on-navy); }

/* Scroll-down cue. Positioning and the bounce animation are split across
   two elements on purpose: the <a> holds a *static* position (so it can be
   placed differently per hero variant, or at a JS-computed point on the
   homepage, without fighting the animation), and the bounce lives on the
   icon alone as a pure translateY oscillation. */
.hero-scroll-cue {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  z-index: 2;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 14px 16px;
  color: var(--on-navy);
  opacity: 0.65;
  transition: opacity var(--dur-base) var(--ease-out);
}
.hero-scroll-cue:hover, .hero-scroll-cue:focus-visible { opacity: 1; }
.hero-scroll-cue svg { display: block; animation: hero-scroll-bounce 2.2s ease-in-out infinite; }
@keyframes hero-scroll-bounce {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(8px); }
}

/* Inner-page hero — flipped to the light palette, no dark/violet background.
   Needs its own position/overflow so the kinetic grid canvas has somewhere
   to sit, and its own text-above-canvas stacking + bottom-pinned cue since
   there's no "sipher." mark here for the homepage's midpoint math to key off. */
.hero--light {
  position: relative;
  overflow: hidden;
  background: var(--surface-2);
}
.hero--light > .container { position: relative; z-index: 2; }
.hero--light .hero-scroll-cue {
  top: auto;
  bottom: 1.5rem;
  transform: translateX(-50%);
  color: var(--ink);
}

/* 8. SHARED SECTIONS -------------------------------------------------------------- */
.section-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--space-4);
  margin-bottom: var(--space-6);
}

.divider {
  height: 1px;
  background: var(--line);
  border: none;
}
.section--navy .divider { background: var(--line-on-navy); }

.stat {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}
.stat__value {
  font-family: var(--font-display);
  font-size: var(--text-4xl);
  font-weight: 600;
  letter-spacing: -0.02em;
}
.stat__label { color: var(--muted); font-size: var(--text-sm); }
.section--navy .stat__label { color: var(--muted-on-navy); }

/* 9. FOOTER -------------------------------------------------------------------------- */
.footer {
  background: var(--navy);
  color: var(--on-navy);
  padding-block: var(--space-7) var(--space-4);
}
.footer__top {
  display: grid;
  grid-template-columns: 1.6fr repeat(3, 1fr);
  gap: var(--space-5);
  padding-bottom: var(--space-6);
  border-bottom: 1px solid var(--line-on-navy);
}
.footer__brand .wordmark { color: var(--on-navy); font-size: 1.75rem; }
.footer__tagline { color: var(--muted-on-navy); margin-top: var(--space-2); max-width: 32ch; }
.footer__col-title {
  font-size: var(--text-xs);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted-on-navy);
  margin-bottom: var(--space-2);
  font-weight: 600;
}
.footer__link {
  display: block;
  padding-block: 0.4rem;
  color: var(--on-navy);
  font-size: var(--text-sm);
  transition: color var(--dur-base) var(--ease-out), padding-left var(--dur-base) var(--ease-out);
}
.footer__link:hover { color: var(--accent-on-navy); padding-left: 0.35rem; }
.footer__bottom {
  padding-top: var(--space-4);
  display: flex;
  justify-content: space-between;
  align-items: center;
  color: var(--muted-on-navy);
  font-size: var(--text-xs);
  flex-wrap: wrap;
  gap: var(--space-2);
}
.footer__bottom a {
  color: inherit;
  text-decoration: underline;
  text-decoration-color: transparent;
  transition: text-decoration-color var(--dur-base) var(--ease-out);
}
.footer__bottom a:hover { text-decoration-color: currentColor; }
.footer__socials { display: flex; gap: var(--space-3); }
.footer__socials a { color: var(--muted-on-navy); transition: color var(--dur-base) var(--ease-out); }
.footer__socials a:hover { color: var(--on-navy); }

/* Light footer — every page except the homepage flips to this so the site
   doesn't close on a dark navy block that only really belongs to the hero. */
.footer--light { background: var(--surface-2); color: var(--ink); }
.footer--light .footer__top { border-bottom-color: var(--line); }
.footer--light .footer__brand .wordmark { color: var(--ink); }
.footer--light .footer__tagline { color: var(--ink-soft); }
.footer--light .footer__col-title { color: var(--muted); }
.footer--light .footer__link { color: var(--ink); }
.footer--light .footer__link:hover { color: var(--accent-strong); }
.footer--light .footer__bottom { color: var(--muted); }
.footer--light .footer__socials a { color: var(--muted); }
.footer--light .footer__socials a:hover { color: var(--ink); }

/* 10. FORMS -------------------------------------------------------------------------- */
.field { display: flex; flex-direction: column; gap: 0.55rem; }
.field label {
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--ink);
}
.section--navy .field label { color: var(--on-navy); }
.field .hint { font-size: var(--text-xs); color: var(--muted); }
.field input,
.field textarea,
.field select {
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 0.9rem 1rem;
  background: var(--surface);
  font-size: var(--text-base);
  min-height: 44px;
  transition: border-color var(--dur-fast) var(--ease-out), box-shadow var(--dur-fast) var(--ease-out);
}
.field textarea { min-height: 140px; resize: vertical; }
.field input:focus, .field textarea:focus, .field select:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 4px var(--accent-soft);
  outline: none;
}
.field input:invalid[data-touched="true"], .field textarea:invalid[data-touched="true"] {
  border-color: var(--danger);
}
.field .error-msg {
  display: none;
  font-size: var(--text-xs);
  color: var(--danger);
}
.field input:invalid[data-touched="true"] ~ .error-msg,
.field textarea:invalid[data-touched="true"] ~ .error-msg {
  display: block;
}
.field-required::after { content: ' *'; color: var(--accent-strong); }

.form-status {
  padding: 1rem 1.25rem;
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
  display: none;
}
.form-status.is-visible { display: block; }
.form-status--success { background: #e9f2ec; color: var(--success); }
.form-status--error { background: #f6e9e8; color: var(--danger); }

/* 11. MOTION / REVEAL STATES ---------------------------------------------------------- */
.reveal { opacity: 0; transform: translateY(24px); }
.js .reveal { transition: opacity var(--dur-slow) var(--ease-out), transform var(--dur-slow) var(--ease-out); }
.js .reveal.is-visible { opacity: 1; transform: translateY(0); }
.no-js .reveal, .reduced-motion .reveal { opacity: 1; transform: none; }

/* whole-page enter/exit crossfade — entry is a pure CSS animation so the
   page is never dependent on JS running before it becomes visible (a
   page-wide "nothing displays" bug if a script is ever slow or blocked).
   JS only ever adds .is-leaving, for the outbound transition on internal clicks. */
@keyframes page-enter { from { opacity: 0; } to { opacity: 1; } }
.js body { animation: page-enter 480ms var(--ease-out) both; }
.js body.is-leaving { animation: none; opacity: 0; transition: opacity 220ms var(--ease-in-out); }
.reduced-motion.js body { animation: none; opacity: 1; }
.reduced-motion.js body.is-leaving { opacity: 1 !important; transition: none !important; }

.magnetic { transition: transform var(--dur-fast) var(--ease-out); }

/* Legal document body (Privacy Policy, Terms of Use) — plain semantic
   markup, styled centrally so the pages themselves stay clean HTML. */
.legal-body { max-width: 720px; }
.legal-body h2 { font-size: var(--text-2xl); margin-top: var(--space-7); margin-bottom: var(--space-2); }
.legal-body h2:first-child { margin-top: 0; }
.legal-body h3 { font-size: var(--text-lg); margin-top: var(--space-4); margin-bottom: 0.4em; }
.legal-body p, .legal-body li { color: var(--ink-soft); }
.legal-body p { margin-top: 1em; }
.legal-body ul, .legal-body ol { margin-top: 1em; padding-left: 1.4em; }
.legal-body li { margin-top: 0.5em; }
.legal-body li::marker { color: var(--accent); }
.legal-body a { color: var(--accent-strong); text-decoration: underline; text-decoration-color: transparent; transition: text-decoration-color var(--dur-base) var(--ease-out); }
.legal-body a:hover { text-decoration-color: currentColor; }
.legal-body strong { color: var(--ink); font-weight: 600; }
.legal-updated { color: var(--muted); font-size: var(--text-sm); }

/* 12. RESPONSIVE ------------------------------------------------------------------------ */
@media (max-width: 1024px) {
  .grid-4 { grid-template-columns: repeat(2, 1fr); }
  .footer__top { grid-template-columns: 1fr 1fr; }
}

@media (max-width: 860px) {
  .nav__links { display: none; }
  .nav__toggle { display: flex; }
  .nav__cta .btn { padding: 0.7rem 1.3rem; font-size: var(--text-xs); }
  /* Mobile pearl button renders shorter (smaller padding/font) — keep the
     badge matched to it rather than the desktop 57px. */
  .nav--hero-mode .nav__badge { width: 46px; height: 46px; }
  .nav__badge-icon { width: 27px; height: 28px; }
  .grid-2, .grid-3 { grid-template-columns: 1fr; }
  .service-row { grid-template-columns: 1fr; gap: var(--space-4); padding-block: var(--space-5); }
  .service-row--reverse .service-row__media { order: 0; }
  .section { padding-block: var(--space-6); }
  .section-head { flex-direction: column; align-items: flex-start; gap: var(--space-2); }
  .footer__top { grid-template-columns: 1fr; gap: var(--space-4); }
}

@media (max-width: 540px) {
  :root { --nav-h: 76px; }
  .btn { width: 100%; }
  .btn.btn--inline, .nav__cta .btn { width: auto; }
}

@media (hover: none) {
  .card:hover { transform: none; }
}
