/* ==========================================================================
   Meldroch, LLC — Core Stylesheet
   Design system: cinematic dark, honey-gold accent, glass surfaces
   ========================================================================== */

/* ---------- Design tokens ---------- */
:root {
  /* Color */
  --bg: #08080b;
  --bg-soft: #0d0d13;
  --bg-raised: #121219;
  --surface: rgba(255, 255, 255, 0.04);
  --surface-strong: rgba(255, 255, 255, 0.07);
  --border: rgba(255, 255, 255, 0.09);
  --border-strong: rgba(255, 255, 255, 0.16);
  --text: #f2f2f6;
  --text-muted: #a8a8b6;
  --text-faint: #74747f;
  --gold: #e8b84b;
  --gold-soft: #f3d489;
  --gold-deep: #b8862f;
  --gold-glow: rgba(232, 184, 75, 0.35);
  --danger: #f0716f;
  --success: #6fd39a;

  /* Type — one scale for the whole site. Sizes are the lever for
     density, so they are set once here and never re-invented per
     component. Desktop lands at h1 52 / h2 40 / h3 26 / body 17. */
  --font-display: "Space Grotesk", "Segoe UI", system-ui, sans-serif;
  --font-body: "Inter", "Segoe UI", system-ui, -apple-system, sans-serif;
  /* Homepage headline pairing: a Franklin Gothic-style grotesque for the
     statement line, an elegant italic serif for the phrase that closes
     it. The fallbacks name the real Franklin Gothic and SF Pro so the
     pairing still reads correctly before the webfonts land. */
  --font-hero-lead: "Libre Franklin", "Franklin Gothic Medium", "Franklin Gothic",
    -apple-system, "SF Pro Display", "Segoe UI", system-ui, sans-serif;
  --font-hero-accent: "Cormorant Garamond", "Iowan Old Style", Garamond,
    "Times New Roman", serif;
  /* Desktop and tablet scale. Phones take a tighter one — see the
     ≤720px block in responsive.css, which is the only place the
     compact sizing lives. */
  --fs-hero: clamp(2.5rem, 2.6vw + 1.6rem, 4rem);
  --fs-h1: clamp(2.1rem, 3vw + 1rem, 3.25rem);
  --fs-h2: clamp(1.65rem, 2vw + 0.75rem, 2.5rem);
  --fs-h3: clamp(1.25rem, 0.8vw + 0.85rem, 1.6rem);
  --fs-body: clamp(1rem, 0.25vw + 0.94rem, 1.075rem);
  --fs-small: 0.875rem;

  /* Spacing — a single rhythm. Component padding, stack gaps, and
     section breaks all draw from this so vertical rhythm stays
     consistent instead of every block inventing its own number. */
  --space-2xs: 0.375rem;
  --space-xs: 0.625rem;
  --space-sm: 1rem;
  --space-md: 1.5rem;
  --space-lg: 2.25rem;
  --space-xl: 3.5rem;
  --space-2xl: 5.5rem;

  /* Comfortable inner padding for any panel, card, or form surface.
     Phones override both — a list row there cannot afford a card's
     padding. */
  --pad-card: clamp(1.6rem, 2.4vw, 2.25rem);
  --pad-compact: clamp(1.6rem, 2.4vw, 2.25rem);

  /* Layout */
  --container: 78rem;
  --measure: 68ch;
  --gutter: clamp(1.25rem, 3vw, 2.5rem);
  --section-pad: clamp(3.5rem, 7vw, 6.5rem);
  --radius-sm: 10px;
  --radius: 16px;
  --radius-lg: 22px;

  /* Control sizing — one height for buttons and inputs so a form row
     and the button under it line up without per-component tweaks. */
  --control-h: 2.875rem;
  --control-h-sm: 2.375rem;

  /* Motion */
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-in: cubic-bezier(0.55, 0, 0.55, 0.2);
  --dur-fast: 180ms;
  --dur: 300ms;
  --dur-slow: 600ms;

  /* Z-scale */
  --z-nav: 100;
  --z-menu: 200;
  --z-intro: 1000;
}

/* ---------- Reset & base ---------- */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

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

body {
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  font-size: var(--fs-body);
  line-height: 1.65;
  min-height: 100dvh;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

body.no-scroll { overflow: hidden; }

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

/* The `hidden` attribute is only `display: none` in the UA sheet, so ANY
   author rule that sets display beats it — a component styled
   `display: flex` stays on screen no matter what the JS sets. That is
   exactly how the reviews placeholder kept showing after a review was
   published. This makes the attribute mean what it says, everywhere. */
[hidden] { display: none !important; }

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

button {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  cursor: pointer;
  touch-action: manipulation;
}

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 600;
  line-height: 1.15;
  letter-spacing: -0.015em;
  text-wrap: balance;
}

/* Long-form copy keeps a readable measure no matter how wide the
   surface it sits on gets. */
p { max-width: var(--measure); }

::selection { background: var(--gold); color: #14100a; }

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

@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;
  }
}

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

.section { padding-block: var(--section-pad); position: relative; }

/* Grid items will not shrink below their content's intrinsic width
   unless min-width is cleared. That default is what pushes content out
   of its container when the reader has a large browser or OS text size,
   so every layout grid opts out of it. */
.grid-2 > *,
.grid-3 > *,
.contact-layout > *,
.review-intro-grid > *,
.review-ghost-row > *,
.footer-grid > *,
.stats-strip > *,
.value-list > *,
.terms-list > *,
.proj-grid > *,
.proj-fields > * { min-width: 0; }

/* Long labels must wrap inside the pill rather than widen past it */
.btn { max-width: 100%; }

.section-head { margin-bottom: clamp(2rem, 3.5vw, var(--space-xl)); }

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  font-family: var(--font-display);
  font-size: 0.8rem;
  font-weight: 500;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--gold);
  margin-bottom: 1.1rem;
}

.eyebrow::before {
  content: "";
  width: 2rem;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--gold));
}

.section-title { font-size: var(--fs-h2); margin-bottom: var(--space-sm); }

.section-sub { color: var(--text-muted); font-size: 1.05rem; max-width: var(--measure); }

.text-gold { color: var(--gold); }

.skip-link {
  position: absolute;
  top: -100%;
  left: 1rem;
  z-index: calc(var(--z-intro) + 1);
  background: var(--gold);
  color: #14100a;
  font-weight: 600;
  padding: 0.7rem 1.2rem;
  border-radius: 0 0 var(--radius-sm) var(--radius-sm);
  transition: top var(--dur-fast) var(--ease-out);
}

.skip-link:focus { top: 0; }

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* ---------- Background video (home) ---------- */
.video-bg {
  position: fixed;
  inset: 0;
  z-index: -2;
  overflow: hidden;
  background: var(--bg);
}

.video-bg video {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Subtle 90° black gradient over the video, plus a gentle overall
   dim so foreground text keeps its contrast */
.video-bg::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    linear-gradient(90deg, rgba(0, 0, 0, 0.72) 0%, rgba(0, 0, 0, 0.28) 50%, rgba(0, 0, 0, 0.72) 100%),
    rgba(8, 8, 11, 0.35);
}

/* ---------- Ambient background ---------- */
.ambient {
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background:
    radial-gradient(52rem 34rem at 82% -8%, rgba(232, 184, 75, 0.07), transparent 60%),
    radial-gradient(44rem 30rem at -10% 42%, rgba(120, 110, 255, 0.045), transparent 60%),
    radial-gradient(40rem 28rem at 55% 115%, rgba(232, 184, 75, 0.05), transparent 62%);
}

.ambient::after {
  content: "";
  position: absolute;
  inset: 0;
  opacity: 0.5;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='56' height='97' viewBox='0 0 56 97'%3E%3Cpath d='M28 0L56 16.17v32.34L28 64.68 0 48.51V16.17zM28 64.68L56 80.85V97M28 64.68L0 80.85V97' fill='none' stroke='rgba(255,255,255,0.022)' stroke-width='1'/%3E%3C/svg%3E");
  background-size: 56px 97px;
  -webkit-mask-image: radial-gradient(70rem 44rem at 50% 0%, #000 30%, transparent 75%);
  mask-image: radial-gradient(70rem 44rem at 50% 0%, #000 30%, transparent 75%);
}

/* ---------- Buttons ---------- */
.btn {
  position: relative;
  overflow: hidden;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.55rem;
  min-height: var(--control-h);
  padding: 0.7rem 1.7rem;
  font-family: var(--font-display);
  font-size: 0.9375rem;
  font-weight: 600;
  letter-spacing: 0.03em;
  border-radius: 999px;
  transition:
    transform var(--dur-fast) var(--ease-out),
    box-shadow var(--dur) var(--ease-out),
    background-color var(--dur-fast) var(--ease-out),
    border-color var(--dur-fast) var(--ease-out),
    color var(--dur-fast) var(--ease-out);
  will-change: transform;
}

.btn:active { transform: scale(0.97); }

/* Sheen sweep — a soft band of light crosses the button on hover/press */
.btn::before {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(115deg, transparent 28%, rgba(255, 255, 255, 0.34) 50%, transparent 72%);
  transform: translateX(-130%);
  pointer-events: none;
}

.btn:hover::before,
.btn:focus-visible::before,
.btn:active::before {
  transform: translateX(130%);
  transition: transform 0.65s var(--ease-out);
}

.btn-ghost::before {
  background: linear-gradient(115deg, transparent 28%, rgba(232, 184, 75, 0.22) 50%, transparent 72%);
}

/* Social buttons — gold gradient + inherited sheen */
.social-links {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
}

.btn-social svg {
  width: 0.95rem;
  height: 0.95rem;
  flex: none;
}

.btn-primary {
  background: linear-gradient(135deg, var(--gold-soft), var(--gold) 45%, var(--gold-deep));
  color: #16110a;
  box-shadow: 0 4px 22px -6px var(--gold-glow);
}

.btn-primary:hover {
  transform: translateY(-2px);
  box-shadow: 0 10px 34px -8px var(--gold-glow), 0 0 0 1px rgba(232, 184, 75, 0.4);
}

.btn-ghost {
  border: 1px solid var(--border-strong);
  color: var(--text);
  background: rgba(255, 255, 255, 0.02);
}

.btn-ghost:hover {
  border-color: var(--gold);
  color: var(--gold-soft);
  transform: translateY(-2px);
  box-shadow: 0 8px 26px -12px var(--gold-glow);
}

.btn-small { min-height: var(--control-h-sm); padding: 0.45rem 1.15rem; font-size: 0.84rem; }

.btn .btn-arrow { transition: transform var(--dur-fast) var(--ease-out); }
.btn:hover .btn-arrow { transform: translateX(4px); }

.btn[disabled], .btn[aria-disabled="true"] {
  opacity: 0.45;
  pointer-events: none;
}

/* ---------- Glass card ---------- */
.glass {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  box-shadow: 0 20px 50px -30px rgba(0, 0, 0, 0.8);
}

.card {
  /* One shared inner padding across every surface. Never let this drop
     far enough that content crowds the rounded border — below about
     18px the inner boxes read as clipped. */
  padding: var(--pad-card);
  position: relative;
  overflow: hidden;
  transition:
    transform var(--dur) var(--ease-out),
    border-color var(--dur) var(--ease-out),
    box-shadow var(--dur) var(--ease-out);
}

.card::before {
  content: "";
  position: absolute;
  inset: 0 0 auto;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(232, 184, 75, 0.5), transparent);
  opacity: 0;
  transition: opacity var(--dur) var(--ease-out);
}

.card:hover {
  transform: translateY(-5px);
  border-color: rgba(232, 184, 75, 0.28);
  box-shadow: 0 26px 60px -28px rgba(0, 0, 0, 0.9), 0 0 40px -20px var(--gold-glow);
}

.card:hover::before { opacity: 1; }

.card-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.75rem;
  height: 2.75rem;
  border-radius: var(--radius-sm);
  background: rgba(232, 184, 75, 0.1);
  border: 1px solid rgba(232, 184, 75, 0.25);
  color: var(--gold);
  margin-bottom: var(--space-sm);
}

.card h3 { font-size: var(--fs-h3); margin-bottom: var(--space-xs); }
.card p { color: var(--text-muted); font-size: 1rem; }

/* Featured tier: a hair larger than its neighbours with a faint gold
   edge. Deliberately restrained — the size difference and the warm
   border do the work, not a bright halo. */
.card-featured {
  border-color: rgba(232, 184, 75, 0.22);
  box-shadow:
    0 26px 60px -30px rgba(0, 0, 0, 0.85),
    0 0 22px -12px var(--gold-glow);
}

.card-featured:hover {
  border-color: rgba(232, 184, 75, 0.34);
}

/* Enlarged by layout, not by transform: these cards sit in a
   .reveal-group, whose `.reveal-group.in-view > *` rule sets transform
   and out-specifies anything here — a scale would be silently dropped.
   Extending the block box also keeps the text crisp. Only applies where
   the card has siblings beside it; in one column it would just look
   misaligned. */
@media (min-width: 721px) {
  .card-featured {
    margin-block: -0.85rem;
    padding-block: calc(var(--pad-card) + 0.85rem);
    z-index: 1;
  }

  /* Widen the middle column a touch so the difference reads
     horizontally as well. Ignored where :has() is unsupported, which
     costs nothing — the card is still taller. */
  .grid-3:has(> .card-featured) { grid-template-columns: 1fr 1.07fr 1fr; }
}

/* Decorative brand panel. A class rather than inline styles so phones
   can take a smaller floor — 18rem there reserved 288px to show a logo. */
.brand-panel {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 18rem;
}

.brand-panel img {
  width: clamp(9rem, 45%, 14rem);
  filter:
    drop-shadow(0 20px 40px rgba(0, 0, 0, 0.6))
    drop-shadow(0 0 28px rgba(232, 184, 75, 0.32));
}

/* ---------- Navigation ---------- */
.site-nav {
  position: fixed;
  inset: 0 0 auto;
  z-index: var(--z-nav);
  transition: background-color var(--dur) var(--ease-out), border-color var(--dur) var(--ease-out), box-shadow var(--dur) var(--ease-out);
  border-bottom: 1px solid transparent;
}

.site-nav.scrolled {
  background: rgba(8, 8, 11, 0.72);
  -webkit-backdrop-filter: blur(18px);
  backdrop-filter: blur(18px);
  border-bottom-color: var(--border);
  box-shadow: 0 10px 40px -20px rgba(0, 0, 0, 0.8);
}

/* While the mobile menu is open the nav must NOT have a backdrop
   filter: it would become the containing block for the fixed
   full-screen menu, collapsing it to the height of the bar. */
.site-nav.menu-open,
.site-nav.menu-open.scrolled {
  background: transparent;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  border-bottom-color: transparent;
  box-shadow: none;
}

.nav-inner {
  max-width: var(--container);
  margin-inline: auto;
  padding: 0.6rem var(--gutter);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.2rem;
}

.nav-brand {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1rem;
  letter-spacing: 0.01em;
  color: var(--text);
  transition: color var(--dur-fast) var(--ease-out);
}

.nav-brand img {
  width: 2rem;
  height: 2rem;
  filter: drop-shadow(0 2px 10px rgba(0, 0, 0, 0.55));
}
.nav-brand:hover { color: var(--gold-soft); }

.nav-links {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  list-style: none;
}

.nav-links a:not(.btn) {
  display: inline-block;
  position: relative;
  padding: 0.45rem 0.75rem;
  font-size: 0.85rem;
  font-weight: 500;
  color: var(--text-muted);
  border-radius: 8px;
  transition: color var(--dur-fast) var(--ease-out);
}

.nav-links a:not(.btn)::after {
  content: "";
  position: absolute;
  left: 0.75rem;
  right: 0.75rem;
  bottom: 0.24rem;
  height: 1.5px;
  background: var(--gold);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--dur) var(--ease-out);
}

.nav-links a:not(.btn):hover { color: var(--text); }
.nav-links a:not(.btn):hover::after { transform: scaleX(1); }

.nav-links a[aria-current="page"] { color: var(--gold); }
.nav-links a[aria-current="page"]::after { transform: scaleX(1); }

.nav-cta-item { margin-left: 0.8rem; }

/* Hamburger */
.nav-toggle {
  display: none;
  position: relative;
  z-index: calc(var(--z-menu) + 1);
  width: 2.75rem;
  height: 2.75rem;
  align-items: center;
  justify-content: center;
  flex-direction: column;
  gap: 6px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  background: var(--surface);
}

.nav-toggle span {
  display: block;
  width: 1.25rem;
  height: 2px;
  border-radius: 2px;
  background: var(--text);
  transition: transform var(--dur) var(--ease-out), opacity var(--dur-fast) var(--ease-out);
}

.nav-toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(8px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-8px) rotate(-45deg); }

/* ---------- Page hero (interior pages) ---------- */
.page-hero {
  padding-top: clamp(6rem, 10vw, 8.5rem);
  padding-bottom: clamp(2.25rem, 4vw, 3.25rem);
  text-align: center;
}

.page-hero h1 { font-size: var(--fs-h1); margin-bottom: var(--space-sm); }

/* :not(.eyebrow) — the eyebrow is a <p>, and a bare `.page-hero p`
   out-specifies `.eyebrow`, which was rendering the small caps label
   at body size. */
.page-hero p:not(.eyebrow) {
  color: var(--text-muted);
  font-size: 1.075rem;
  max-width: 42rem;
  margin-inline: auto;
}

/* Contact: the form has to clear the fold on its own, so this page's
   hero gives back every pixel it can without losing the headline. */
.page-hero.page-hero-tight {
  padding-top: clamp(5.25rem, 9vw, 7rem);
  padding-bottom: clamp(1.75rem, 3vw, 2.5rem);
}

.page-hero-tight h1 { margin-bottom: 0.7rem; }
.page-hero-tight p:not(.eyebrow) { font-size: 1rem; max-width: 38rem; }
.page-hero-tight .eyebrow { margin-bottom: 0.8rem; }

/* ---------- Home hero ----------
   Full-height on desktop, where there is room for it. Phones size it
   to its content instead (see the ≤720px block). */
.hero {
  min-height: 100dvh;
  display: flex;
  align-items: center;
  padding-top: 6rem;
  padding-bottom: 4rem;
  position: relative;
}

.hero-scroll {
  position: absolute;
  bottom: 2rem;
  left: 50%;
  transform: translateX(-50%);
  color: var(--text-faint);
  font-size: 0.75rem;
  letter-spacing: 0.25em;
  text-transform: uppercase;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.7rem;
}

.hero-scroll::after {
  content: "";
  width: 1px;
  height: 3rem;
  background: linear-gradient(180deg, var(--gold), transparent);
}

.hero-inner { text-align: center; }

/* A plain italic line rather than a pill — no dot, no outline.
   inline-block, not block: it is a <p>, so it inherits the global
   `max-width` and as a block it would sit left of centre inside that
   box instead of hugging its own text. */
.hero-badge {
  display: inline-block;
  font-size: 0.95rem;
  font-style: italic;
  font-weight: 400;
  letter-spacing: 0.04em;
  color: var(--text);
  margin-bottom: 1.6rem;
}

.hero h1 {
  font-size: var(--fs-hero);
  font-weight: 700;
  margin-bottom: 1.4rem;
  letter-spacing: -0.025em;
}

.hero h1 .line { display: block; }

/* ---------- Hero slogan ----------
   Two faces on one line: the opening words in the grotesque, the
   closing word in the italic serif. Both selectors are written at the
   same specificity as each other and above the generic .hero h1 rules,
   so neither silently loses. */

/* Opening words — clean, tightly-set grotesque. */
.hero h1.hero-slogan .slogan-line {
  font-family: var(--font-hero-lead);
  font-weight: 700;
  font-size: calc(1.22em * 1.15);
  letter-spacing: -0.02em;
  line-height: 1.3;
  /* Trim the leading back off the layout so the headline keeps its
     spacing while the line box stays tall enough for the serif's
     ascenders and descenders. */
  margin-block: -0.08em;
  text-wrap: balance;
}

/* Closing word — elegant italic serif. It sets larger than the
   grotesque beside it because Cormorant runs optically smaller at a
   shared size; this brings the two cap heights into line. */
.hero h1.hero-slogan .slogan-last {
  font-family: var(--font-hero-accent);
  font-style: italic;
  font-weight: 600;
  font-size: 1.2em;
  letter-spacing: 0.005em;
  position: relative;
  white-space: nowrap;
}

/* Only the periods take the brand gold; the words stay white. */
.slogan-dot { color: var(--gold); }

/* Hairline gold rule under the closing word, fading out to the right.
   Sized and offset in em so it tracks the slogan at every breakpoint.

   The offset has to clear the font's descent, not the box: Cormorant
   reserves ~0.28em below the baseline for descenders, and "Buzz." has
   none, so anchoring the rule to the bottom of the box left it sitting
   a quarter of an em clear of the letters. This pulls it back to sit
   just under them. */
.hero h1.hero-slogan .slogan-last::after {
  content: "";
  position: absolute;
  left: 0.04em;
  right: 0;
  bottom: 0.16em;
  height: 0.028em;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--gold) 0%, var(--gold) 38%, rgba(232, 184, 75, 0) 100%);
}

.hero-sub {
  color: var(--text-muted);
  font-size: clamp(1.05rem, 1.6vw, 1.2rem);
  max-width: 40rem;
  margin: 0 auto 2.6rem;
}

.hero-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  justify-content: center;
}



/* ---------- Grids ---------- */
.grid-3 {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.4rem;
}

.grid-2 {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 1.4rem;
}

/* ---------- Stats strip ---------- */
.stats-strip {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.4rem;
  text-align: center;
}

.stat {
  padding: 1.8rem 1rem;
}

.stat .stat-value {
  font-family: var(--font-display);
  font-size: clamp(2rem, 4vw, 2.8rem);
  font-weight: 700;
  color: var(--gold);
  font-variant-numeric: tabular-nums;
}

.stat .stat-label {
  color: var(--text-muted);
  font-size: 0.9rem;
  margin-top: 0.3rem;
}

/* ---------- CTA band ---------- */
.cta-band {
  text-align: center;
  padding: clamp(3rem, 7vw, 5rem) clamp(1.5rem, 5vw, 4rem);
  border-radius: var(--radius-lg);
  position: relative;
  overflow: hidden;
}

.cta-band::after {
  content: "";
  position: absolute;
  inset: -40% -20% auto;
  height: 120%;
  background: radial-gradient(50% 60% at 50% 0%, rgba(232, 184, 75, 0.14), transparent 70%);
  pointer-events: none;
}

.cta-band h2 { font-size: var(--fs-h2); margin-bottom: 0.9rem; position: relative; z-index: 1; }
.cta-band p { color: var(--text-muted); margin: 0 auto 2rem; position: relative; z-index: 1; }
.cta-band .btn { position: relative; z-index: 1; }

/* ---------- Showcase: "Our Work" infinite gallery ---------- */
.showcase { position: relative; }

/* Default (no-JS / reduced-motion): a plain swipeable row */
.showcase-track {
  display: flex;
  gap: 1.6rem;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  padding: 1.6rem max(calc((100vw - var(--container)) / 2 + var(--gutter)), var(--gutter)) 2.6rem;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}

.showcase-track::-webkit-scrollbar { display: none; }

.showcase-track:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: -2px;
  border-radius: 12px;
}

/* Scroll-driven stage mode (js adds .showcase-live; height set by JS) */
.showcase-live .showcase-sticky {
  position: sticky;
  top: 0;
  height: 100dvh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  overflow: hidden;
}

/* Stage cards: wide panoramic windows. Width stays generous while the
   preview height is capped as a viewport fraction, so cards stay short
   and elongated on every display; media crops cinematically via cover. */
.showcase-live { --stage-card-w: min(86vw, 96rem); }

.showcase-live .pc-media {
  aspect-ratio: auto;
  /* No large floor here — on short/landscape screens a minimum would
     push the card past the viewport and clip the copy below it. */
  height: min(42dvh, 30rem);
}

/* Stacked stage (journey-style): one card area, cards layered on it */
.showcase-live .showcase-track {
  display: block;
  position: relative;
  overflow: visible;
  scroll-snap-type: none;
  width: var(--stage-card-w);
  margin-inline: auto;
  padding: 0;
}

.showcase-live .project-card {
  position: absolute;
  inset: 0;
  width: 100%;
  /* solid backing so the covered card can't ghost through the glass */
  background: var(--bg-raised);
  cursor: pointer;
}

/* First card stays in flow to give the stage its size */
.showcase-live .project-card:first-child {
  position: relative;
  inset: auto;
}

/* Compact horizontal footer row on the stage: text left, button
   right — keeps the card wide and shallow instead of tall */
@media (min-width: 721px) {
  .showcase-live .pc-body {
    grid-template-columns: 1fr auto;
    grid-template-areas:
      "industry visit"
      "name     visit"
      "desc     visit";
    column-gap: 2rem;
    row-gap: 0.3rem;
    padding: 1rem 1.5rem 1.1rem;
  }

  .showcase-live .pc-industry { grid-area: industry; }
  .showcase-live .pc-name { grid-area: name; }
  .showcase-live .pc-desc { grid-area: desc; -webkit-line-clamp: 2; }
  .showcase-live .pc-visit {
    grid-area: visit;
    align-self: center;
    margin-top: 0;
  }
}

.showcase-live .showcase-controls { margin-top: 1.2rem; }

/* Browser-window card */
.project-card {
  position: relative;
  flex: 0 0 auto;
  width: clamp(19rem, 27vw, 25rem);
  scroll-snap-align: center;
  display: flex;
  flex-direction: column;
  border-radius: 22px;
  overflow: hidden;
  background: rgba(255, 255, 255, 0.045);
  border: 1px solid var(--border);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  box-shadow: 0 26px 60px -32px rgba(0, 0, 0, 0.9);
  transform: translateX(var(--slide-x, 0px)) translateY(var(--lift, 0)) scale(calc(var(--zoom, 1) * var(--cscale, 1))) rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg));
  transition:
    transform 0.4s var(--ease-out),
    box-shadow 0.4s var(--ease-out),
    border-color 0.4s var(--ease-out),
    filter 0.4s var(--ease-out);
  will-change: transform;
  perspective: 900px;
}

/* Focus dim: a soft black gradient veils the cards flanking center */
.project-card::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 3;
  pointer-events: none;
  border-radius: inherit;
  background: linear-gradient(180deg, rgba(0, 0, 0, 0.3), rgba(0, 0, 0, 0.72));
  opacity: var(--dim, 0);
  transition: opacity 0.2s linear;
}

/* Scroll-driven mode: the transform is now rewritten every frame, so a
   transition on it only adds lag — each frame's value would chase the
   last one instead of landing. Everything else still eases. */
.showcase-live .project-card {
  transition:
    box-shadow 0.4s var(--ease-out),
    border-color 0.4s var(--ease-out),
    filter 0.4s var(--ease-out);
  /* The stage card is opaque, so the blur has nothing to sample — it was
     pure GPU cost, and the most expensive thing on the page for phones. */
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}

/* The card on stage is distinguished by scale alone (via --cscale) —
   no gold edge glow, so the site previews read as plain windows. */
.project-card.is-center {
  border-color: var(--border-strong);
}

.project-card:hover {
  --lift: -10px;
  --zoom: 1.02;
  border-color: var(--border-strong);
  box-shadow: 0 38px 85px -34px rgba(0, 0, 0, 0.95);
  filter: brightness(1.04);
}

/* Toolbar */
.pc-toolbar {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.7rem 0.95rem;
  background: rgba(255, 255, 255, 0.05);
  border-bottom: 1px solid var(--border);
}

.pc-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  flex: none;
  opacity: 0.85;
}

.pc-dot.r { background: #ff5f57; }
.pc-dot.y { background: #febc2e; }
.pc-dot.g { background: #28c840; }

.pc-address {
  flex: 1;
  min-width: 0;
  margin-left: 0.5rem;
  font-size: 0.72rem;
  color: var(--text-faint);
  background: rgba(0, 0, 0, 0.35);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 0.25rem 0.8rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Media area */
.pc-media {
  position: relative;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  background: var(--bg-soft);
}

.pc-media-motion {
  position: absolute;
  inset: 0;
  z-index: 1; /* sits over the placeholder that acts as its fallback */
}

.pc-media img,
.pc-media video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top center;
  transition: transform 0.5s var(--ease-out), filter 0.5s var(--ease-out);
}

.project-card:hover .pc-media img,
.project-card:hover .pc-media video {
  transform: scale(1.06);
  filter: contrast(1.05);
}

/* Slow cinematic pan for screenshots */
.pc-kenburns { animation: kenburns 16s ease-in-out infinite alternate; }

/* Placeholder for projects without a capture yet */
.pc-placeholder {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.6rem;
  background:
    radial-gradient(120% 130% at 20% 0%, rgba(232, 184, 75, 0.14), transparent 55%),
    radial-gradient(110% 120% at 90% 110%, rgba(120, 110, 255, 0.07), transparent 60%),
    var(--bg-soft);
}

.pc-placeholder-mark {
  font-family: var(--font-display);
  font-size: 3.4rem;
  font-weight: 700;
  line-height: 1;
  color: transparent;
  -webkit-text-stroke: 1.5px rgba(232, 184, 75, 0.6);
}

.pc-placeholder-note {
  font-size: 0.72rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--text-faint);
}

/* Card footer */
.pc-body {
  display: grid;
  gap: 0.45rem;
  padding: 1.15rem 1.3rem 1.35rem;
  align-content: start;
  flex: 1;
}

.pc-industry {
  font-family: var(--font-display);
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--gold);
}

.pc-name { font-size: 1.12rem; }

.pc-desc {
  color: var(--text-muted);
  font-size: 0.9rem;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.pc-visit {
  justify-self: start;
  margin-top: 0.5rem;
  opacity: 0.85;
  transform: translateY(4px);
  transition:
    opacity 0.35s var(--ease-out),
    transform 0.35s var(--ease-out),
    border-color var(--dur-fast) var(--ease-out),
    color var(--dur-fast) var(--ease-out),
    box-shadow var(--dur) var(--ease-out);
}

.project-card:hover .pc-visit {
  opacity: 1;
  transform: translateY(0);
}

.pc-visit-icon {
  width: 0.95rem;
  height: 0.95rem;
  transition: transform 0.3s var(--ease-out);
}

.pc-visit:hover .pc-visit-icon { transform: translate(2px, -2px); }

/* Controls */
.showcase-controls {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 1.4rem;
  margin-top: 0.4rem;
}

.showcase-nav {
  width: 3rem;
  height: 3rem;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--border-strong);
  background: var(--surface);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  color: var(--text);
  transition:
    transform var(--dur-fast) var(--ease-out),
    border-color var(--dur-fast) var(--ease-out),
    color var(--dur-fast) var(--ease-out),
    box-shadow var(--dur) var(--ease-out);
}

.showcase-nav svg { width: 1.15rem; height: 1.15rem; }

.showcase-nav:hover {
  transform: scale(1.08);
  border-color: var(--gold);
  color: var(--gold-soft);
  box-shadow: 0 8px 26px -10px var(--gold-glow);
}

.showcase-nav:active { transform: scale(0.96); }

.showcase-dots { display: flex; gap: 0.55rem; }

.showcase-dot {
  width: 8px;
  height: 8px;
  padding: 0;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.18);
  transition:
    background-color 0.3s var(--ease-out),
    width 0.3s var(--ease-out),
    box-shadow 0.3s var(--ease-out);
}

.showcase-dot:hover { background: rgba(255, 255, 255, 0.4); }

.showcase-dot.active {
  width: 1.6rem;
  background: var(--gold);
  box-shadow: 0 0 10px 1px var(--gold-glow);
}

/* ---------- Footer ---------- */
.site-footer {
  border-top: 1px solid var(--border);
  padding: clamp(3rem, 6vw, 4.5rem) 0 2rem;
  background: linear-gradient(180deg, transparent, rgba(232, 184, 75, 0.025));
}

.footer-grid {
  display: grid;
  grid-template-columns: 2fr 1fr 1fr;
  gap: 2.5rem;
  margin-bottom: 3rem;
}

.footer-brand {
  display: inline-block;
  margin-bottom: 1.2rem;
}

/* Full logo (gold mark + black wordmark) on a soft light badge so the
   wordmark stays legible against the dark footer */
.footer-brand img {
  width: clamp(9rem, 18vw, 12rem);
  height: auto;
  /* The artwork runs edge to edge in the PNG, so without padding the
     rounded badge shaves the wordmark. Padding insets the image
     inside the background, which still fills the padding box. */
  padding: clamp(0.75rem, 1.6vw, 1.1rem);
  border-radius: 22px;
  background: #faf8f3;
  box-shadow:
    0 18px 44px -20px rgba(0, 0, 0, 0.85),
    0 0 38px -14px var(--gold-glow);
  transition: transform var(--dur) var(--ease-out), box-shadow var(--dur) var(--ease-out);
}

.footer-brand:hover img {
  transform: translateY(-3px);
  box-shadow:
    0 22px 52px -20px rgba(0, 0, 0, 0.9),
    0 0 46px -10px var(--gold-glow);
}

.footer-tagline { color: var(--text-muted); font-size: 0.95rem; max-width: 26rem; }

.footer-col h4 {
  font-size: 0.8rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--text-faint);
  margin-bottom: 1.1rem;
}

.footer-col ul { list-style: none; display: grid; gap: 0.65rem; }

.footer-col a {
  color: var(--text-muted);
  font-size: 0.95rem;
  transition: color var(--dur-fast) var(--ease-out);
}

.footer-col a:hover { color: var(--gold); }

.footer-bottom {
  border-top: 1px solid var(--border);
  padding-top: 1.6rem;
  display: flex;
  flex-wrap: wrap;
  gap: 0.8rem;
  justify-content: space-between;
  color: var(--text-faint);
  font-size: 0.85rem;
}

/* ---------- Services: pricing tables ---------- */
.table-wrap {
  overflow-x: auto;
  border-radius: var(--radius);
  -webkit-overflow-scrolling: touch;
}

.service-table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  min-width: 40rem;
  font-size: 0.95rem;
}

.service-table th,
.service-table td {
  padding: 1.05rem 1.15rem;
  text-align: left;
  vertical-align: top;
  border-bottom: 1px solid var(--border);
}

.service-table thead th {
  font-family: var(--font-display);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--gold);
  background: rgba(232, 184, 75, 0.06);
  border-bottom: 1px solid rgba(232, 184, 75, 0.25);
  white-space: nowrap;
}

.service-table tbody tr {
  transition: background-color var(--dur-fast) var(--ease-out);
}

.service-table tbody tr:hover { background: rgba(255, 255, 255, 0.03); }
.service-table tbody tr:last-child td { border-bottom: 0; }

.service-table .svc-name {
  font-family: var(--font-display);
  font-weight: 600;
  color: var(--text);
  white-space: nowrap;
}

/* "+ Hosting" sits under the tier name rather than lengthening the row */
.service-table .tier-host {
  display: block;
  font-weight: 500;
  color: var(--text-muted);
}

.service-table .svc-price {
  font-family: var(--font-display);
  font-weight: 700;
  color: var(--gold);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.service-table td { color: var(--text-muted); }

.service-table ul {
  list-style: none;
  display: grid;
  gap: 0.35rem;
}

.service-table ul li {
  position: relative;
  padding-left: 1.1rem;
}

.service-table ul li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.55em;
  width: 5px;
  height: 5px;
  border-radius: 1px;
  background: var(--gold);
  transform: rotate(45deg);
}

.tag-popular {
  display: inline-block;
  white-space: nowrap;
  margin-left: 0.6rem;
  padding: 0.15rem 0.6rem;
  border-radius: 999px;
  font-size: 0.66rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: #16110a;
  background: linear-gradient(135deg, var(--gold-soft), var(--gold));
  vertical-align: middle;
}

/* Mobile service cards (shown < 720px via responsive.css) */
.service-cards { display: none; gap: 1.2rem; }

.service-card .svc-card-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  margin-bottom: 0.8rem;
}

.service-card .svc-price { font-size: 1.4rem; }

.service-card dl { display: grid; gap: 0.7rem; margin-top: 1rem; }

.service-card dt {
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--gold);
}

.service-card dd { color: var(--text-muted); font-size: 0.95rem; }

/* Combined packages chart (Services 01) — one horizontal table with a
   grouped header: build pricing on the left, hosting columns grouped */
.combined-table { min-width: 58rem; }

.combined-table .col-tier { width: 15%; }
.combined-table .col-ideal { width: 22%; }
.combined-table .col-features { width: 25%; }
.combined-table .col-build { width: 12%; }
.combined-table .col-host { width: 8.6%; }

.combined-table thead th {
  vertical-align: bottom;
  text-align: left;
}

.combined-table .group-label {
  text-align: center;
  border-bottom: 1px solid rgba(232, 184, 75, 0.22);
  padding-bottom: 0.55rem;
}

.combined-table .subhead {
  font-size: 0.7rem;
  letter-spacing: 0.1em;
  color: var(--text-muted);
  padding-top: 0.6rem;
  text-align: right;
}

.combined-table .save-note {
  display: block;
  font-size: 0.62rem;
  font-weight: 500;
  letter-spacing: 0.08em;
  color: var(--gold-soft);
  text-transform: none;
}

/* Thin divider separating the build column and the hosting group */
.combined-table th.group-start,
.combined-table td.group-start {
  border-left: 1px solid var(--border);
}

.combined-table thead th:nth-child(4),
.combined-table td.svc-price { text-align: right; }

.combined-table .svc-price { white-space: nowrap; }

.combined-table .svc-price .unit {
  color: var(--text-faint);
  font-weight: 500;
  font-size: 0.78em;
  margin-left: 0.15em;
}

.combined-table .svc-name { white-space: normal; }

/* "Includes domain & hosting" note under each hosting figure */
.combined-table .incl-note {
  display: block;
  margin-top: 0.2rem;
  font-family: var(--font-body);
  font-size: 0.68rem;
  font-weight: 400;
  letter-spacing: 0.01em;
  line-height: 1.35;
  white-space: normal;
  color: var(--text-faint);
}

/* Support-hours chart: billing cadence + price under each figure */
.support-table .svc-price { white-space: nowrap; }

.support-table .unit-note {
  display: block;
  margin-top: 0.2rem;
  font-family: var(--font-body);
  font-size: 0.7rem;
  font-weight: 400;
  letter-spacing: 0.01em;
  text-transform: none;
  color: var(--text-faint);
}

.support-table .hours-price {
  display: block;
  margin-top: 0.3rem;
  font-size: 0.95em;
  color: var(--text);
}

.support-table thead .save-note {
  display: inline-block;
  margin-left: 0.3rem;
}

.combined-table .tag-popular {
  display: block;
  width: fit-content;
  margin: 0.45rem 0 0;
}

/* Terms accordion-style list */
.terms-list { display: grid; gap: 1rem; }

.terms-list .term-item { padding: 1.4rem 1.6rem; }

.terms-list .term-item h3 {
  font-size: 1.02rem;
  color: var(--gold-soft);
  margin-bottom: 0.4rem;
}

.terms-list .term-item p { color: var(--text-muted); font-size: 0.95rem; max-width: none; }

/* ---------- Journey (About): scroll-driven slide sequence ----------
   Default layout is static stacked panels (works without JS / with
   reduced motion). js/journey.js adds .journey-live for the sticky
   scroll-driven version where each chapter slides in over the last. */
.journey { position: relative; }

.journey-viewport {
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
  display: grid;
  gap: 1.4rem;
}

.journey-panel {
  display: grid;
  grid-template-columns: 1fr;
  align-items: stretch;
  will-change: transform;
}

.journey-text {
  padding: clamp(1.8rem, 4vw, 3.2rem);
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.journey-text-inner {
  width: 100%;
  max-width: 58rem;
  margin-inline: auto;
}

.journey-text p + p { margin-top: 0.85rem; }

.journey-text .jr-closer {
  color: var(--gold-soft);
  font-family: var(--font-display);
  font-weight: 500;
}

.journey-text .jr-date {
  font-family: var(--font-display);
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--gold);
}

.journey-text h3 { font-size: clamp(1.25rem, 2.2vw, 1.7rem); margin: 0.5rem 0 0.9rem; }
.journey-text p { color: var(--text-muted); font-size: clamp(0.92rem, 1.05vw, 1rem); max-width: 70ch; }

.journey-dots { display: none; }

/* Live (scroll-driven) mode.
   Scroll length is proportional to how many chapters there are, rather
   than a flat 380vh: one screen to pin, then a fixed travel per extra
   chapter. A flat height meant four short chapters cost nearly four
   screens of scrolling, most of it empty. js/journey.js sets --steps. */
.journey-live {
  --steps: 4;
  height: calc(100dvh + (var(--steps) - 1) * 46dvh);
}

.journey-live .journey-sticky {
  position: sticky;
  top: 0;
  height: 100dvh;
  display: flex;
  align-items: center;
  overflow: hidden;
}

.journey-live .journey-viewport {
  position: relative;
  width: 100%;
  height: min(36rem, 80dvh);
  display: block;
}

.journey-live .journey-panel {
  position: absolute;
  top: 0;
  left: var(--gutter);
  right: var(--gutter);
  height: 100%;
  transform: translateX(112%);
}

.journey-live .journey-panel:first-child { transform: none; }

/* Solid backing + fade veil so a covered chapter never ghosts through
   and attention stays on the chapter currently on stage */
.journey-live .journey-text {
  height: 100%;
  position: relative;
  background: var(--bg-raised);
  overflow: hidden;
}

.journey-live .journey-text::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  background: linear-gradient(180deg, rgba(0, 0, 0, 0.35), rgba(0, 0, 0, 0.75));
  opacity: var(--dim, 0);
  transition: opacity 0.2s linear;
}

.journey-live .journey-dots {
  position: absolute;
  left: 50%;
  bottom: max(1.4rem, env(safe-area-inset-bottom));
  transform: translateX(-50%);
  display: flex;
  gap: 0.15rem;
}

/* The diamond is drawn by ::before so the button itself can carry a
   full 44px hit area without the marker growing to match. */
.journey-dot {
  width: 2.75rem;
  height: 2.75rem;
  padding: 0;
  border: 0;
  background: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.journey-dot::before {
  content: "";
  width: 11px;
  height: 11px;
  transform: rotate(45deg);
  border: 1.5px solid rgba(232, 184, 75, 0.5);
  background: transparent;
  transition: background-color var(--dur-fast) var(--ease-out), box-shadow var(--dur-fast) var(--ease-out);
}

.journey-dot.active::before {
  background: var(--gold);
  box-shadow: 0 0 12px 1px var(--gold-glow);
}

/* ---------- Vertical stack (Services: support terms) ----------
   Default is a plain stacked list (no JS / reduced motion);
   js/stack.js adds .vstack-live for the pinned scroll version where
   each term slides DOWN over the previous one. */
.vstack { position: relative; }

.vstack-viewport { display: grid; gap: 1rem; }

.vstack-dots { display: none; }

/* Same proportional scroll budget as the About journey — js/stack.js
   sets --steps from the number of terms. */
.vstack-live {
  --steps: 4;
  height: calc(100dvh + (var(--steps) - 1) * 38dvh);
}

.vstack-live .vstack-sticky {
  position: sticky;
  top: 0;
  height: 100dvh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}

.vstack-live .vstack-viewport {
  position: relative;
  display: block;
  width: min(46rem, 100%);
  height: min(16rem, 44dvh);
}

.vstack-live .vstack-panel {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  text-align: center;
  /* Generous breathing room so copy never crowds the card edge */
  padding: clamp(2rem, 5vw, 3.5rem) clamp(2rem, 7vw, 5rem);
  background: var(--bg-raised);
  transform: translateY(-115%);
  will-change: transform;
  overflow: hidden;
}

.vstack-live .vstack-panel > * {
  width: 100%;
  max-width: 44rem;
}

.vstack-live .vstack-panel h3 { font-size: 1.25rem; margin-bottom: 0.75rem; }
.vstack-live .vstack-panel p { margin-inline: auto; }

/* Fade veil on the cards behind the one in focus */
.vstack-live .vstack-panel::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  background: linear-gradient(180deg, rgba(0, 0, 0, 0.35), rgba(0, 0, 0, 0.75));
  opacity: var(--dim, 0);
  transition: opacity 0.2s linear;
}

.vstack-live .vstack-panel:first-child { transform: none; }

.vstack-live .vstack-dots {
  display: flex;
  gap: 0.15rem;
  margin-top: 1.6rem;
}

/* ---------- Values ---------- */
.value-list { counter-reset: value; display: grid; gap: 1.2rem; }

.value-item {
  counter-increment: value;
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--space-md);
  padding: var(--pad-card);
  align-items: start;
}

.value-item::after {
  content: "0" counter(value);
  grid-column: 1;
  grid-row: 1;
  font-family: var(--font-display);
  font-size: 1.5rem;
  font-weight: 700;
  color: transparent;
  -webkit-text-stroke: 1px rgba(232, 184, 75, 0.55);
  line-height: 1.2;
}

.value-item > div { grid-column: 2; grid-row: 1; }
.value-item h3 { font-size: var(--fs-h3); margin-bottom: var(--space-2xs); }
.value-item p { color: var(--text-muted); font-size: 1rem; }

/* ---------- Reviews placeholder ---------- */
.reviews-empty {
  text-align: center;
  padding: clamp(3rem, 8vw, 5.5rem) clamp(1.5rem, 5vw, 4rem);
  position: relative;
  overflow: hidden;
}

.reviews-empty .quote-mark {
  font-family: var(--font-display);
  font-size: clamp(4rem, 10vw, 7rem);
  line-height: 1;
  color: rgba(232, 184, 75, 0.35);
  user-select: none;
}

.reviews-empty h2 { font-size: var(--fs-h2); margin: 0.5rem auto 1.2rem; max-width: 24ch; }

.reviews-empty p {
  color: var(--text-muted);
  max-width: 36rem;
  margin: 0 auto 2.2rem;
}

.review-ghost-row {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.4rem;
  margin-top: 3.5rem;
}

.review-ghost {
  padding: 1.6rem;
  text-align: left;
  opacity: 0.55;
}

.review-ghost .ghost-stars { display: flex; gap: 0.25rem; color: var(--gold); margin-bottom: 1rem; }
.review-ghost .ghost-stars svg { width: 1rem; height: 1rem; }

.review-ghost .ghost-line {
  height: 0.6rem;
  border-radius: 4px;
  background: linear-gradient(90deg, rgba(255,255,255,0.09), rgba(255,255,255,0.04));
  margin-bottom: 0.55rem;
}

.review-ghost .ghost-line.short { width: 62%; }

.review-ghost .ghost-avatar {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  margin-top: 1.2rem;
}

.review-ghost .ghost-avatar span:first-child {
  width: 2.2rem;
  height: 2.2rem;
  border-radius: 50%;
  background: rgba(232, 184, 75, 0.16);
  border: 1px solid rgba(232, 184, 75, 0.3);
}

.review-ghost .ghost-avatar span:last-child {
  height: 0.55rem;
  width: 5.5rem;
  border-radius: 4px;
  background: rgba(255, 255, 255, 0.08);
}

/* ---------- Reviews: form + status side by side ---------- */
.review-intro-grid {
  display: grid;
  grid-template-columns: 1.05fr 1fr;
  gap: 1.6rem;
  align-items: stretch;
}

/* The row stays two columns whether or not reviews exist. It used to
   collapse to one once something was published, which — combined with the
   placeholder refusing to hide — stacked the form and the panel on top of
   each other. The panel swaps its copy instead (see js/reviews.js). */

.review-form-card { padding: clamp(1.6rem, 3.5vw, 2.4rem); }

/* Placeholder tuned for the narrower column */
.review-intro-grid .reviews-empty {
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: clamp(2rem, 4vw, 3rem) clamp(1.5rem, 3vw, 2.4rem);
}

.review-intro-grid .reviews-empty h2 { font-size: clamp(1.15rem, 2vw, 1.5rem); }
.review-intro-grid .reviews-empty p { font-size: 0.95rem; }
/* .quote-mark is a <p>, so this has to out-specify the sibling
   `.review-intro-grid .reviews-empty p` rule or the decorative mark
   collapses to body size. */
.review-intro-grid .reviews-empty .quote-mark { font-size: clamp(3rem, 6vw, 4.5rem); }

.review-intro-grid .review-ghost-row {
  grid-template-columns: 1fr;
  gap: 1rem;
  margin-top: 2.2rem;
}

.review-intro-grid .review-ghost:nth-child(3) { display: none; }

/* ---------- Review form: star input ---------- */
.star-input {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  /* Five 44px targets plus the label can outgrow a phone's width once
     text is scaled up — wrapping beats losing the fifth star offscreen. */
  flex-wrap: wrap;
}

.star-input button {
  width: 2.6rem;
  height: 2.6rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border-radius: 8px;
  color: rgba(255, 255, 255, 0.22);
  transition: color var(--dur-fast) var(--ease-out), transform var(--dur-fast) var(--ease-out);
}

.star-input button svg { width: 1.75rem; height: 1.75rem; fill: currentColor; }

.star-input button:hover { transform: scale(1.12); }
.star-input button.on { color: var(--gold); }

.rating-label {
  margin-left: 0.6rem;
  font-family: var(--font-display);
  font-size: 0.82rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--gold-soft);
}

/* ---------- Published review wall ---------- */
.review-wall {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(19rem, 1fr));
  gap: 1.4rem;
}

.review-card { display: flex; flex-direction: column; gap: 0.9rem; }

.review-stars { display: flex; gap: 0.2rem; }
.review-stars svg { width: 1.05rem; height: 1.05rem; }
.review-stars svg.on { fill: var(--gold); }
.review-stars svg.off { fill: rgba(255, 255, 255, 0.16); }

.review-text {
  margin: 0;
  color: var(--text-muted);
  font-size: 0.97rem;
  line-height: 1.7;
  white-space: pre-wrap;
}

.review-author {
  display: flex;
  align-items: center;
  gap: 0.8rem;
  margin-top: auto;
  padding-top: 0.6rem;
  border-top: 1px solid var(--border);
}

.review-avatar {
  flex: none;
  width: 2.5rem;
  height: 2.5rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: rgba(232, 184, 75, 0.14);
  border: 1px solid rgba(232, 184, 75, 0.32);
  color: var(--gold-soft);
  font-family: var(--font-display);
  font-size: 0.8rem;
  font-weight: 700;
}

.review-author > span:last-child { display: grid; }
.review-name { font-weight: 600; font-size: 0.95rem; }
.review-company,
.review-date { color: var(--text-faint); font-size: 0.8rem; }

/* ---------- Moderation page ---------- */
.mod-stars { display: flex; gap: 0.25rem; margin-bottom: 1rem; }
.mod-stars svg { width: 1.5rem; height: 1.5rem; }
.mod-stars svg.on { fill: var(--gold); }
.mod-stars svg.off { fill: rgba(255, 255, 255, 0.16); }

.mod-quote {
  margin: 0 0 1.4rem;
  padding: 1.1rem 1.3rem;
  border-radius: var(--radius-sm);
  background: rgba(255, 255, 255, 0.04);
  border-left: 3px solid var(--gold);
  color: var(--text);
  font-size: 1rem;
  line-height: 1.7;
  white-space: pre-wrap;
}

.mod-meta {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.4rem 1.2rem;
  margin: 0 0 1.6rem;
  font-size: 0.9rem;
}

.mod-meta dt {
  color: var(--text-faint);
  font-size: 0.72rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  align-self: center;
}

.mod-meta dd { margin: 0; color: var(--text); }

.mod-actions { display: flex; flex-wrap: wrap; gap: 0.9rem; }

/* ---------- Owner / Developer access ---------- */
.pw-wrap { position: relative; display: flex; }
.pw-wrap input { padding-right: 4.2rem; }

.pw-toggle {
  position: absolute;
  right: 0.5rem;
  top: 50%;
  transform: translateY(-50%);
  padding: 0.35rem 0.6rem;
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--gold);
  border-radius: 6px;
}

.pw-toggle:hover { color: var(--gold-soft); background: rgba(232, 184, 75, 0.1); }

.access-head {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 1.8rem;
}

.access-head-actions { display: flex; gap: 0.6rem; }

.access-tabs {
  display: flex;
  gap: 0.5rem;
  margin-bottom: 1.6rem;
  border-bottom: 1px solid var(--border);
}

.access-tab {
  padding: 0.7rem 1.1rem;
  font-family: var(--font-display);
  font-size: 0.92rem;
  font-weight: 600;
  color: var(--text-muted);
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  transition: color var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out);
}

.access-tab:hover { color: var(--text); }
.access-tab.active { color: var(--gold); border-bottom-color: var(--gold); }

.access-hint { color: var(--text-muted); font-size: 0.92rem; margin-bottom: 1.2rem; }
.access-empty { color: var(--text-faint); font-size: 0.95rem; padding: 1.5rem 0; }

.admin-list { display: grid; gap: 1rem; }

.admin-item { padding: 1.2rem 1.3rem; }

.admin-item-head {
  display: flex;
  flex-wrap: wrap;
  gap: 0.8rem;
  align-items: flex-start;
  justify-content: space-between;
  margin-bottom: 0.7rem;
}

.admin-sub { display: block; color: var(--text-faint); font-size: 0.82rem; }

.admin-quote {
  color: var(--text-muted);
  font-size: 0.94rem;
  line-height: 1.65;
  white-space: pre-wrap;
  margin-bottom: 1rem;
}

.btn.danger { border-color: rgba(240, 113, 111, 0.4); color: var(--danger); }
.btn.danger:hover { border-color: var(--danger); color: #fff; background: rgba(240, 113, 111, 0.14); box-shadow: none; }

/* Showcase project editor */
.proj-grid { display: grid; grid-template-columns: 15rem 1fr; gap: 1.3rem; align-items: start; }

.proj-cover { display: grid; gap: 0.5rem; }

.proj-cover img {
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  object-position: top center;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
}

.cover-none {
  display: flex;
  align-items: center;
  justify-content: center;
  aspect-ratio: 16 / 9;
  border-radius: var(--radius-sm);
  border: 1px dashed var(--border-strong);
  color: var(--text-faint);
  font-size: 0.8rem;
}

.proj-upload { justify-content: center; cursor: pointer; }
.proj-fields { display: grid; gap: 0.8rem; }

.proj-row-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-top: 1.1rem;
  padding-top: 1rem;
  border-top: 1px solid var(--border);
}

.proj-row-actions .btn[disabled] { opacity: 0.35; pointer-events: none; }

.access-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.8rem;
  align-items: center;
  margin-top: 1.4rem;
}

/* Diagnostics readout */
.diag-list { display: grid; gap: 0.6rem; margin-top: 1.2rem; }

.diag-row {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.8rem;
  align-items: start;
  padding: 0.9rem 1.1rem;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  background: rgba(255, 255, 255, 0.03);
  font-size: 0.92rem;
}

.diag-row.pass { border-color: rgba(111, 211, 154, 0.3); }
.diag-row.fail { border-color: rgba(240, 113, 111, 0.4); }

.diag-mark { font-weight: 700; line-height: 1.5; }
.diag-row.pass .diag-mark { color: var(--success); }
.diag-row.fail .diag-mark { color: var(--danger); }

.diag-detail {
  display: block;
  margin-top: 0.25rem;
  color: var(--text-muted);
  font-size: 0.82rem;
  word-break: break-word;
}

/* Footer owner link — deliberately quiet */
.footer-access {
  color: var(--text-faint);
  font-size: 0.78rem;
  opacity: 0.6;
  transition: opacity var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out);
}

.footer-access:hover { opacity: 1; color: var(--gold); }

/* ---------- Contact ---------- */
.contact-layout {
  display: grid;
  grid-template-columns: 1fr 1.35fr;
  gap: 1.5rem;
  align-items: start;
}

.contact-aside { padding: var(--pad-card); }
.contact-aside h2 { font-size: var(--fs-h3); margin-bottom: var(--space-xs); }
.contact-aside > p { color: var(--text-muted); font-size: 0.975rem; margin-bottom: var(--space-md); }

.contact-points { list-style: none; display: grid; gap: var(--space-sm); }

.contact-points li {
  display: flex;
  gap: 0.8rem;
  align-items: flex-start;
  color: var(--text-muted);
  font-size: 0.95rem;
}

.contact-points svg {
  flex: none;
  width: 1.15rem;
  height: 1.15rem;
  color: var(--gold);
  margin-top: 0.15rem;
}

/* The contact form stays a touch tighter than a general card: it is the
   one surface where fitting the fold on a phone earns more than the
   extra breathing room would. */
.contact-form { padding: clamp(1.4rem, 2vw, 1.85rem); }

.form-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-sm);
}

.form-field { display: grid; gap: 0.4rem; min-width: 0; }
.form-field.full { grid-column: 1 / -1; }

/* A grid item defaults to min-width:auto, so a 1fr track cannot shrink
   below its content's min-content width. An <input> carries an intrinsic
   width of ~20 characters, which scales with the font — so at a large
   browser/OS text size the track, and the field with it, grew wider than
   the card and spilled out of it. Letting these shrink is what keeps the
   form inside its container when text is scaled up. */
.form-grid > *,
.form-field > * { min-width: 0; }

.form-field label {
  font-size: 0.875rem;
  line-height: 1.35;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--text);
}

.form-field label .req { color: var(--gold); }
.form-field label .opt { color: var(--text-faint); font-weight: 400; }

.form-field input,
.form-field select,
.form-field textarea {
  width: 100%;
  min-height: var(--control-h);
  padding: 0.55rem 0.9rem;
  font: inherit;
  /* Stays at 16px on purpose — anything smaller makes iOS Safari
     zoom the page when a field is focused. */
  font-size: 1rem;
  line-height: 1.4;
  color: var(--text);
  background: rgba(255, 255, 255, 0.035);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  transition: border-color var(--dur-fast) var(--ease-out), box-shadow var(--dur-fast) var(--ease-out), background-color var(--dur-fast) var(--ease-out);
}

/* Sized in em, not rem, so the box holds a whole number of lines at any
   text size — in rem it stayed put while the text grew and sliced the
   last line in half. 1.4 line-height + 0.55em padding top and bottom. */
.form-field textarea {
  resize: vertical;
  min-height: 5em;
  padding-block: 0.55em;
  overflow-y: auto;
}

.form-field select {
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='9' viewBox='0 0 14 9' fill='none'%3E%3Cpath d='M1 1l6 6 6-6' stroke='%23a8a8b6' stroke-width='2' stroke-linecap='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.8rem center;
  padding-right: 2.2rem;
}

.form-field select:invalid { color: var(--text-faint); }
.form-field option { background: var(--bg-raised); color: var(--text); }

.form-field optgroup {
  background: var(--bg-raised);
  color: var(--gold);
  font-style: normal;
  font-weight: 600;
}

.form-field input::placeholder,
.form-field textarea::placeholder { color: var(--text-faint); }

.form-field input:focus,
.form-field select:focus,
.form-field textarea:focus {
  outline: none;
  border-color: var(--gold);
  background: rgba(232, 184, 75, 0.045);
  box-shadow: 0 0 0 3px rgba(232, 184, 75, 0.14);
}

.form-field.invalid input,
.form-field.invalid select,
.form-field.invalid textarea {
  border-color: var(--danger);
  box-shadow: 0 0 0 3px rgba(240, 113, 111, 0.12);
}

.field-error {
  display: none;
  font-size: 0.74rem;
  line-height: 1.35;
  color: var(--danger);
}

.form-field.invalid .field-error { display: block; }

/* Honeypot — hidden from humans, invisible to layout */
.hp-field {
  position: absolute !important;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
}

.form-footer {
  grid-column: 1 / -1;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.8rem;
  margin-top: 0.1rem;
}

.form-status {
  display: none;
  align-items: center;
  gap: 0.6rem;
  font-size: 0.92rem;
  font-weight: 500;
}

.form-status.visible { display: inline-flex; }
.form-status.success { color: var(--success); }
.form-status.error { color: var(--danger); }
.form-status svg { width: 1.2rem; height: 1.2rem; flex: none; }

.btn .spinner {
  display: none;
  width: 1.05rem;
  height: 1.05rem;
  border: 2px solid rgba(22, 17, 10, 0.25);
  border-top-color: #16110a;
  border-radius: 50%;
}

.btn.loading .spinner { display: inline-block; animation: spin 0.7s linear infinite; }
.btn.loading .btn-label-idle { display: none; }
.btn .btn-label-busy { display: none; }
.btn.loading .btn-label-busy { display: inline; }

/* ---------- Navigation: Services dropdown ----------
   The toggle is a <button> that has to sit in the row as if it were one of
   the nav links, so its box mirrors `.nav-links a:not(.btn)` exactly. The
   menu items are also <a> inside .nav-links, which means the link rule
   (specificity 0,2,1 — :not(.btn) counts) applies to them too; every rule
   that overrides it below is written at 0,3,0 or higher so it cannot be
   silently dropped. */
.nav-dropdown { position: relative; }

.nav-dropdown-toggle {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  position: relative;
  padding: 0.45rem 0.75rem;
  font-family: inherit;
  font-size: 0.85rem;
  font-weight: 500;
  color: var(--text-muted);
  border-radius: 8px;
  transition: color var(--dur-fast) var(--ease-out);
}

/* Same underline the links carry */
.nav-dropdown-toggle::after {
  content: "";
  position: absolute;
  left: 0.75rem;
  right: 0.75rem;
  bottom: 0.24rem;
  height: 1.5px;
  background: var(--gold);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--dur) var(--ease-out);
}

.nav-dropdown-toggle:hover { color: var(--text); }
.nav-dropdown-toggle:hover::after { transform: scaleX(1); }

.nav-dropdown-toggle.is-current { color: var(--gold); }
.nav-dropdown-toggle.is-current::after { transform: scaleX(1); }

.nav-dropdown.open > .nav-dropdown-toggle { color: var(--text); }
.nav-dropdown.open > .nav-dropdown-toggle.is-current { color: var(--gold); }

.nav-caret {
  width: 0.7rem;
  height: 0.7rem;
  flex: none;
  transition: transform var(--dur) var(--ease-out);
}

.nav-dropdown.open .nav-caret { transform: rotate(180deg); }

.nav-menu {
  position: absolute;
  top: calc(100% + 0.5rem);
  left: 50%;
  /* `translate` centres, `transform` animates — they compose, so the two
     never fight over the same property. */
  translate: -50% 0;
  width: min(23rem, calc(100vw - 2rem));
  padding: 0.4rem;
  display: grid;
  gap: 0.15rem;
  background: rgba(11, 11, 16, 0.94);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  -webkit-backdrop-filter: blur(18px);
  backdrop-filter: blur(18px);
  box-shadow:
    0 26px 60px -26px rgba(0, 0, 0, 0.92),
    0 0 32px -22px var(--gold-glow);
  opacity: 0;
  visibility: hidden;
  transform: translateY(-6px) scale(0.98);
  transform-origin: top center;
  transition:
    opacity var(--dur) var(--ease-out),
    transform var(--dur) var(--ease-out),
    visibility var(--dur);
}

.nav-dropdown.open .nav-menu {
  opacity: 1;
  visibility: visible;
  transform: translateY(0) scale(1);
}

/* 0,3,0 — beats `.nav-links a:not(.btn)` at 0,2,1 */
.nav-links .nav-menu .nav-menu-item {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.8rem;
  align-items: center;
  padding: 0.7rem 0.75rem;
  border-radius: 11px;
  color: var(--text-muted);
  transition:
    background-color var(--dur-fast) var(--ease-out),
    color var(--dur-fast) var(--ease-out);
}

/* The sliding underline belongs to the top-level links only */
.nav-links .nav-menu .nav-menu-item::after { content: none; }

.nav-links .nav-menu .nav-menu-item:hover {
  background: rgba(232, 184, 75, 0.09);
  color: var(--text);
}

.nav-links .nav-menu .nav-menu-item[aria-current="page"] {
  background: rgba(232, 184, 75, 0.12);
  color: var(--text);
}

.nav-menu-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.15rem;
  height: 2.15rem;
  flex: none;
  border-radius: 9px;
  background: rgba(232, 184, 75, 0.1);
  border: 1px solid rgba(232, 184, 75, 0.25);
  color: var(--gold);
}

.nav-menu-icon svg { width: 1.05rem; height: 1.05rem; }

.nav-menu-item[aria-current="page"] .nav-menu-icon {
  background: rgba(232, 184, 75, 0.18);
  border-color: rgba(232, 184, 75, 0.45);
}

.nav-menu-text { display: grid; gap: 0.12rem; min-width: 0; }

.nav-menu-text strong {
  font-family: var(--font-display);
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--text);
  line-height: 1.3;
}

.nav-menu-text small {
  font-size: 0.775rem;
  line-height: 1.35;
  color: var(--text-faint);
}

/* ---------- Video editing: page hero accent ---------- */
.page-hero .h-accent {
  font-family: var(--font-hero-accent);
  font-style: italic;
  font-weight: 600;
  color: var(--gold);
  /* The serif sets optically smaller than the grotesque beside it, and
     needs the extra line box or `background-clip`-free ink still gets
     clipped by the shorter box on the descender. */
  font-size: 1.06em;
  letter-spacing: 0.005em;
}

/* Anchor target sits clear of the fixed nav */
.reel-work { scroll-margin-top: 5rem; }

.reel-head-row {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.75rem 1.5rem;
}

.reel-count {
  font-family: var(--font-display);
  font-size: 0.8rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--text-faint);
  white-space: nowrap;
}

/* ---------- Video editing: work grid ----------
   auto-fill with a 20rem floor lands on three columns at desktop widths,
   two on tablets, one on phones — without a breakpoint per column count.
   `dense` lets a featured card span two tracks without leaving a hole. */
.reel-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 20rem), 1fr));
  grid-auto-flow: dense;
  gap: clamp(1.35rem, 2.4vw, 2.1rem);
}

/* 0,3,0 — `.reveal.in-view` in animations.css sits at 0,2,0 and loads
   later, so a hover transform written at 0,2,0 here would lose to it once
   the card had revealed. Every card rule that touches transform or
   transition is raised above that. */
.reel-grid .reel-card {
  position: relative;
  display: flex;
  flex-direction: column;
  width: 100%;
  padding: 0;
  text-align: left;
  border-radius: var(--radius-lg);
  overflow: hidden;
  border: 1px solid var(--border);
  background: var(--bg-raised);
  box-shadow: 0 20px 50px -34px rgba(0, 0, 0, 0.9);
  transition:
    opacity var(--dur-slow) var(--ease-out),
    transform var(--dur) var(--ease-out),
    border-color var(--dur) var(--ease-out),
    box-shadow var(--dur) var(--ease-out);
  /* The shorthand above would otherwise reset the stagger that
     `.reveal` sets, so the delay is re-declared here. */
  transition-delay: var(--reveal-delay, 0ms);
}

.reel-grid .reel-card:hover,
.reel-grid .reel-card:focus-visible {
  transform: translateY(-4px);
  border-color: rgba(232, 184, 75, 0.3);
  box-shadow:
    0 30px 64px -30px rgba(0, 0, 0, 0.95),
    0 0 42px -24px var(--gold-glow);
}

.reel-thumb {
  position: relative;
  display: block;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  background: linear-gradient(140deg, #12121a, #0a0a0e 60%);
}

.reel-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.75s var(--ease-out), filter var(--dur) var(--ease-out);
}

.reel-grid .reel-card:hover .reel-thumb img,
.reel-grid .reel-card:focus-visible .reel-thumb img { transform: scale(1.055); }

/* Initial of the title, for a project with no still yet */
.reel-thumb-fallback {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-display);
  font-size: 3.2rem;
  font-weight: 700;
  color: rgba(232, 184, 75, 0.22);
}

.reel-thumb-broken { background: linear-gradient(140deg, #14141d, #0a0a0e 60%); }

/* Keeps the title legible over any frame */
.reel-scrim {
  position: absolute;
  inset: auto 0 0;
  height: 62%;
  background: linear-gradient(180deg, transparent, rgba(6, 6, 9, 0.82) 78%);
  opacity: 0.9;
  transition: opacity var(--dur) var(--ease-out);
  pointer-events: none;
}

.reel-grid .reel-card:hover .reel-scrim { opacity: 1; }

.reel-play {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  opacity: 0;
  transform: scale(0.9);
  transition: opacity var(--dur) var(--ease-out), transform var(--dur) var(--ease-out);
  pointer-events: none;
}

.reel-play svg {
  width: 3.1rem;
  height: 3.1rem;
  filter: drop-shadow(0 6px 20px rgba(0, 0, 0, 0.6));
}

.reel-grid .reel-card:hover .reel-play,
.reel-grid .reel-card:focus-visible .reel-play {
  opacity: 1;
  transform: scale(1);
}

/* The label sits over the bottom of the frame, not in a band beneath it —
   the card stays one clean image. */
.reel-meta {
  position: absolute;
  inset: auto 0 0;
  display: grid;
  gap: 0.2rem;
  padding: 1.1rem 1.25rem 1.15rem;
  pointer-events: none;
}

.reel-cat {
  font-family: var(--font-display);
  font-size: 0.7rem;
  font-weight: 500;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--gold);
}

.reel-title {
  font-family: var(--font-display);
  font-size: 1.02rem;
  font-weight: 600;
  line-height: 1.3;
  letter-spacing: -0.01em;
  color: #fff;
  text-shadow: 0 2px 14px rgba(0, 0, 0, 0.55);
}

/* A featured project always carries the warm edge, at every width. */
.reel-grid .reel-card.is-featured { border-color: rgba(232, 184, 75, 0.24); }

/* Above 1180px the grid is always exactly three tracks, which is the only
   place a featured project can take a two-by-two block without leaving a
   hole beside it: the two standard cards that follow stack in the third
   column. Spanning two columns on ONE row does not work — a 16:9 card
   across two tracks is twice as tall as its single-track neighbour, and
   `dense` cannot fill the 225px of dead space that leaves underneath.
   `.can-span` is set by js/reel.js only when at least two projects follow,
   so the block always has something to sit beside it. */
@media (min-width: 1180px) {
  .reel-grid .reel-card.is-featured.can-span {
    grid-column: span 2;
    grid-row: span 2;
  }

  /* Height now comes from the two rows it straddles, not from a ratio */
  .reel-grid .reel-card.is-featured.can-span .reel-thumb {
    aspect-ratio: auto;
    flex: 1;
    min-height: 0;
  }

  .reel-grid .reel-card.is-featured.can-span .reel-title { font-size: 1.45rem; }
  .reel-grid .reel-card.is-featured.can-span .reel-cat { font-size: 0.74rem; }
  .reel-grid .reel-card.is-featured.can-span .reel-meta { padding: 1.5rem 1.7rem 1.55rem; }
  .reel-grid .reel-card.is-featured.can-span .reel-play svg { width: 3.8rem; height: 3.8rem; }
}

/* An empty feed hides its whole section (data-hide-empty in js/reel.js)
   rather than showing a placeholder box, so there is no empty state to
   style here. */

/* ---------- Video editing: lightbox ---------- */
.reel-modal {
  position: fixed;
  inset: 0;
  z-index: var(--z-intro);
  display: grid;
  place-items: center;
  padding: clamp(1rem, 4vw, 3rem);
  opacity: 0;
  transition: opacity var(--dur) var(--ease-out);
}

.reel-modal[hidden] { display: none; }
.reel-modal.open { opacity: 1; }

.reel-modal-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(4, 4, 7, 0.86);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
}

.reel-modal-panel {
  position: relative;
  width: min(64rem, 100%);
  /* The grid area is already the viewport minus .reel-modal's padding, so
     100% here is the real ceiling — a dvh calc would ignore that padding
     and let a tall panel run off the bottom on short windows. */
  max-height: 100%;
  overflow-y: auto;
  border-radius: var(--radius-lg);
  padding: clamp(0.75rem, 1.5vw, 1rem);
  transform: translateY(12px) scale(0.985);
  transition: transform var(--dur) var(--ease-out);
}

.reel-modal.open .reel-modal-panel { transform: translateY(0) scale(1); }

.reel-modal-close {
  position: absolute;
  top: clamp(1.1rem, 2vw, 1.4rem);
  right: clamp(1.1rem, 2vw, 1.4rem);
  z-index: 2;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.6rem;
  height: 2.6rem;
  border-radius: 999px;
  border: 1px solid var(--border-strong);
  background: rgba(10, 10, 14, 0.75);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  color: var(--text);
  transition: background-color var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out);
}

.reel-modal-close:hover { background: rgba(232, 184, 75, 0.16); border-color: var(--gold); }
.reel-modal-close svg { width: 1.05rem; height: 1.05rem; }

.reel-modal-stage {
  position: relative;
  aspect-ratio: 16 / 9;
  border-radius: var(--radius);
  overflow: hidden;
  background: #000;
}

.reel-stage-frame,
.reel-stage-video,
.reel-stage-image {
  width: 100%;
  height: 100%;
  border: 0;
  display: block;
}

.reel-stage-image { object-fit: contain; }

.reel-stage-empty {
  display: grid;
  place-items: center;
  height: 100%;
  color: var(--text-muted);
  margin-inline: auto;
}

.reel-modal-info {
  display: grid;
  gap: 0.45rem;
  padding: clamp(1.1rem, 2vw, 1.5rem) clamp(0.5rem, 1.5vw, 1rem) clamp(0.5rem, 1vw, 0.75rem);
}

.reel-modal-cat {
  font-family: var(--font-display);
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--gold);
}

.reel-modal-title { font-size: var(--fs-h3); }
.reel-modal-desc { color: var(--text-muted); font-size: 0.975rem; }
.reel-modal-open { justify-self: start; margin-top: 0.5rem; }

/* ---------- Access: video portfolio editor ---------- */
.vp-grid {
  display: grid;
  grid-template-columns: 15rem 1fr;
  gap: 1.3rem;
  align-items: start;
}

.vp-grid > *,
.vp-fields > * { min-width: 0; }

.vp-still { display: grid; gap: 0.5rem; }

.vp-still img {
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
}

.vp-fields { display: grid; gap: 0.8rem; }
.vp-fields .form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 0.8rem; }
.vp-fields .form-row > * { min-width: 0; }

.vp-toggles {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.2rem;
  align-items: center;
  padding-top: 0.2rem;
}

.vp-check {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--text);
  cursor: pointer;
}

.vp-check input {
  width: 1.05rem;
  height: 1.05rem;
  accent-color: var(--gold);
  cursor: pointer;
}

.vp-hint {
  color: var(--text-faint);
  font-size: 0.78rem;
  line-height: 1.45;
}

/* A hidden project stays editable but reads as off */
.admin-item.is-hidden { opacity: 0.62; border-style: dashed; }

.vp-flag {
  display: inline-block;
  margin-left: 0.5rem;
  padding: 0.1rem 0.5rem;
  border-radius: 999px;
  font-family: var(--font-display);
  font-size: 0.68rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  border: 1px solid var(--border-strong);
  color: var(--text-faint);
}

.vp-flag.on { border-color: rgba(232, 184, 75, 0.45); color: var(--gold); }

/* ---------- Access: video file upload ---------- */
.vp-video-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.6rem 0.75rem;
}

.vp-file {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  min-width: 0;
  font-size: 0.85rem;
  color: var(--text-muted);
  word-break: break-all;
}

.vp-file-none { color: var(--text-faint); font-style: italic; }

.vp-file-dot {
  width: 0.5rem;
  height: 0.5rem;
  flex: none;
  border-radius: 999px;
  background: var(--success);
  box-shadow: 0 0 8px -1px var(--success);
}

/* Upload progress — the one place a long wait needs a readout */
.vp-progress {
  height: 4px;
  margin-top: 0.6rem;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.09);
  overflow: hidden;
}

.vp-progress[hidden] { display: none; }

.vp-progress-bar {
  display: block;
  width: 0%;
  height: 100%;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--gold-deep), var(--gold), var(--gold-soft));
  box-shadow: 0 0 12px 1px var(--gold-glow);
  transition: width var(--dur) var(--ease-out);
}

.form-field.vp-video input[disabled] { opacity: 0.5; }

/* ---------- Lightbox: waiting on a signed playback URL ---------- */
.reel-stage-loading {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  margin: 0;
  max-width: none;
  color: var(--text-muted);
  font-size: 0.9rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  pointer-events: none;
}

/* Inline upload feedback. The pane's shared status line sits below every
   project and the Save button, so on a list of any length a failure down
   there is invisible — this sits against the control that caused it. */
.vp-upload-msg {
  margin-top: 0.6rem;
  padding: 0.6rem 0.75rem;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  background: rgba(255, 255, 255, 0.03);
  color: var(--text-muted);
  font-size: 0.85rem;
  line-height: 1.5;
  max-width: none;
}

.vp-upload-msg[hidden] { display: none; }

.vp-upload-msg.error {
  border-color: rgba(240, 113, 111, 0.4);
  background: rgba(240, 113, 111, 0.08);
  color: var(--danger);
}

.vp-upload-msg.success {
  border-color: rgba(111, 211, 154, 0.35);
  background: rgba(111, 211, 154, 0.08);
  color: var(--success);
}

/* ---------- Oversized primary CTA ----------
   One per page at most. It inherits .btn-primary's gradient and sheen and
   only changes scale and weight of presence, so it reads as the same button
   family rather than a new component. */
.btn-xl {
  min-height: 3.6rem;
  padding: 1rem 2.4rem;
  gap: 0.75rem;
  font-size: 1.05rem;
  letter-spacing: 0.02em;
  border-radius: 999px;
  box-shadow:
    0 10px 34px -10px var(--gold-glow),
    0 0 0 1px rgba(232, 184, 75, 0.28),
    0 0 46px -20px var(--gold-glow);
}

.btn-xl:hover {
  transform: translateY(-3px);
  box-shadow:
    0 18px 48px -12px var(--gold-glow),
    0 0 0 1px rgba(232, 184, 75, 0.5),
    0 0 64px -18px var(--gold-glow);
}

.btn-xl-icon {
  width: 1.25rem;
  height: 1.25rem;
  flex: none;
}

/* Sets expectations for what the button does before it is pressed */
.cta-note {
  position: relative;
  z-index: 1;
  margin: 1.1rem auto 0;
  color: var(--text-faint);
  font-size: 0.85rem;
}

/* ---------- Creative pricing boxes (Video Editing 03) ----------
   Same glass card as the packages on the homepage, with a price block and
   an itemised list. `.card p` is (0,1,1), so every <p> override here is
   written at (0,2,0) or higher — otherwise the muted body colour wins and
   the figure reads like a caption. */
.price-card { display: flex; flex-direction: column; }

.price-card .price-scope {
  color: var(--text-faint);
  font-size: 0.85rem;
  letter-spacing: 0.02em;
  margin-top: -0.15rem;
}

.price-card .price-figure {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0.45rem;
  margin: 1.1rem 0 1.2rem;
  padding-bottom: 1.2rem;
  border-bottom: 1px solid var(--border);
}

.price-card .price-amount {
  font-family: var(--font-display);
  font-size: clamp(1.9rem, 1.2vw + 1.5rem, 2.35rem);
  font-weight: 700;
  line-height: 1;
  color: var(--gold);
  font-variant-numeric: tabular-nums;
}

.price-card .price-unit {
  color: var(--text-faint);
  font-size: 0.85rem;
}

.price-list {
  list-style: none;
  display: grid;
  gap: 0.55rem;
  margin-top: auto;
}

.price-list li {
  position: relative;
  padding-left: 1.15rem;
  color: var(--text-muted);
  font-size: 0.95rem;
  line-height: 1.5;
}

.price-list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.62em;
  width: 5px;
  height: 5px;
  border-radius: 999px;
  background: var(--gold);
}

/* Standing note under the boxes — the one thing that is not per-package */
.price-note {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem 1.5rem;
  margin-top: 1.5rem;
  padding: var(--pad-compact) var(--pad-card);
  border-radius: var(--radius);
}

.price-note-label {
  font-family: var(--font-display);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--gold);
  flex: none;
}

.price-note p:not(.price-note-label) {
  color: var(--text-muted);
  font-size: 0.95rem;
  flex: 1 1 18rem;
  margin: 0;
}

.price-note .btn { flex: none; margin-left: auto; }

/* ---------- Work-grid notice ----------
   A quiet aside, not a warning: muted text on a barely-there surface, so it
   reads as housekeeping rather than an apology for the work. Sits above the
   grid so it is seen before anything is opened. */
.reel-notice {
  display: flex;
  align-items: flex-start;
  gap: 0.6rem;
  max-width: none;
  margin-bottom: clamp(1.25rem, 2.5vw, 1.75rem);
  padding: 0.7rem 0.95rem;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  background: rgba(255, 255, 255, 0.025);
  color: var(--text-faint);
  font-size: 0.875rem;
  line-height: 1.5;
}

.reel-notice svg {
  width: 1rem;
  height: 1rem;
  flex: none;
  margin-top: 0.18em;
  color: var(--gold);
  opacity: 0.75;
}

@media (max-width: 720px) {
  .reel-notice { font-size: 0.83rem; padding: 0.65rem 0.85rem; }
}

/* ---------- Roomier CTA band ----------
   For a headline that runs to two lines, where the base band's spacing
   reads as cramped. Written at (0,2,0)+ so it beats the base `.cta-band`
   rules rather than relying on file order — and mirrored in responsive.css,
   because a phone must NOT inherit this desktop padding. */
.cta-band.cta-band-roomy {
  padding-block: clamp(3.75rem, 8vw, 6rem);
}

.cta-band.cta-band-roomy h2 {
  line-height: 1.28;
  margin-bottom: 1.35rem;
}

.cta-band.cta-band-roomy > p:not(.cta-note) {
  margin-bottom: 2.6rem;
}

.cta-band.cta-band-roomy .cta-note {
  margin-top: 1.35rem;
}
