/* Grid & Frame — "Bold Signal" design system.
   Near-black ground, oversized black-weight display type, electric-lime accent, dense/technical.
   Replaces the earlier "Warm light" direction, which read as too soft/template-like. */

:root {
  --bg: #0b0c0f;
  --bg-shade: #131519;
  --card: #1e2127;
  --ink: #f5f4f0;
  --ink-soft: #a8aab0;
  --ink-faint: #8b8f97;
  --line: #262a31;
  --line-soft: #1d2026;
  --accent: #c8ff4d;
  --accent-dark: #a6e022;
  --accent-ink: #0b0c0f;
  --accent-soft: #1e2410;
  --accent-soft-line: #3a4a12;
  --accent-2: #ff5a3c;
  --font-display: 'Archivo', -apple-system, blinkmacsystemfont, 'Segoe UI', roboto, helvetica, arial, sans-serif;
  --font-body: -apple-system, blinkmacsystemfont, 'Segoe UI', roboto, helvetica, arial, sans-serif;
  --font-mono: 'JetBrains Mono', ui-monospace, sfmono-regular, menlo, consolas, monospace;
  --container: 1180px;
  --pad: clamp(20px, 5vw, 48px);
  --radius: 14px;
  --radius-sm: 8px;
  --radius-pill: 999px;
  --shadow-hover: 0 22px 44px -22px rgb(0, 0, 0, 0.7);
  --shadow-float: 0 30px 70px -30px rgb(0, 0, 0, 0.8);
  --shadow-accent: 0 0 50px -12px rgb(200, 255, 77, 0.4);
}

* {
  box-sizing: border-box;
}

html {
  text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 17px;
  line-height: 1.6;
  overflow-x: hidden;
}

img {
  max-width: 100%;
  height: auto;
  display: block;
}

a {
  color: inherit;
}

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 900;
  line-height: 1.02;
  letter-spacing: -0.03em;
  margin: 0 0 0.5em;
  color: var(--ink);
  text-transform: uppercase;
}

h3, h4 {
  font-weight: 700;
  text-transform: none;
}

p {
  margin: 0 0 1.1em;
}

p:last-child {
  margin-bottom: 0;
}

::selection {
  background: var(--accent-soft);
  color: var(--accent-dark);
}

.container {
  max-width: var(--container);
  margin: 0 auto;
  padding: 0 var(--pad);
}

.section {
  position: relative;
  padding: clamp(56px, 9vw, 108px) 0;
}

/* One shared grid layer, pinned to the viewport rather than each section's
   own box, so the lines stay in phase across every section boundary
   instead of restarting (and visibly jumping) at each one. */
.section::before {
  content: '';
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(var(--line-soft) 1px, transparent 1px),
    linear-gradient(90deg, var(--line-soft) 1px, transparent 1px);
  background-size: 56px 56px;
  background-attachment: fixed;
  opacity: 0.5;
  pointer-events: none;
  z-index: 0;
}

.section .container {
  position: relative;
  z-index: 1;
}

.section-tight {
  padding: clamp(36px, 6vw, 64px) 0;
}

.section-shade {
  background-color: var(--bg-shade);
  /* Fades from the plain black into the shade and back instead of cutting
     straight across, so the seam between adjacent sections reads as a
     gradient, not a hard line. */
  background-image: linear-gradient(
    to bottom,
    var(--bg),
    var(--bg-shade) 96px,
    var(--bg-shade) calc(100% - 96px),
    var(--bg)
  );
}

.section-ink {
  background: var(--accent);
  color: var(--accent-ink);
}

.section-ink h1, .section-ink h2, .section-ink h3 {
  color: var(--accent-ink);
}

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
  font-family: var(--font-mono);
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--accent);
  margin: 0 0 1.1em;
}

.eyebrow::before {
  content: '';
  width: 22px;
  height: 1px;
  background: var(--accent);
}

.eyebrow.center {
  justify-content: center;
}

.lede {
  font-size: clamp(1.05rem, 1.6vw, 1.3rem);
  color: var(--ink-soft);
  /* Measured ~92 characters per line at the old 46em on a full-width
     desktop viewport — well past the ~65-75ch that stays comfortable
     to read. */
  max-width: 34em;
  line-height: 1.55;
}

.lede.center {
  margin-left: auto;
  margin-right: auto;
}

.section-ink .lede {
  color: rgb(11, 12, 15, 0.72);
}

.h1 {
  font-size: clamp(2.5rem, 5.6vw, 4.6rem);
}

@media (max-width: 700px) {
  /* The base 1.02 line-height is tuned for the 1-2 lines a wide viewport
     wraps to. A long headline on a phone wraps to 3+ lines at that height
     and reads as cramped. */
  .h1 {
    line-height: 1.1;
  }
}

.h2 {
  font-size: clamp(1.9rem, 3.6vw, 2.8rem);
}

.h3 {
  font-size: clamp(1.35rem, 2vw, 1.7rem);
}

.italic {
  font-style: italic;
  color: var(--accent);
}

/* ---------- motion: scroll reveal ---------- */
.reveal {
  opacity: 0;
  transform: translateY(20px);
  /* Plain "ease" was the one motion curve on the page that didn't match
     the expo-out used everywhere else (hero words, hero-stack, page
     iris) — it read as a slightly different, generic-feeling animation. */
  transition: opacity 0.7s cubic-bezier(0.16, 1, 0.3, 1), transform 0.7s cubic-bezier(0.16, 1, 0.3, 1);
}

.reveal.is-visible {
  opacity: 1;
  transform: translateY(0);
}

.work-grid .reveal:nth-child(2),
.process .reveal:nth-child(2),
.price-grid .reveal:nth-child(2),
.care-grid .reveal:nth-child(2),
.case-grid .reveal:nth-child(2) {
  transition-delay: 0.09s;
}

.work-grid .reveal:nth-child(3),
.process .reveal:nth-child(3),
.price-grid .reveal:nth-child(3),
.care-grid .reveal:nth-child(3),
.case-grid .reveal:nth-child(3) {
  transition-delay: 0.18s;
}

.price-grid .reveal:nth-child(4),
.case-grid .reveal:nth-child(4) {
  transition-delay: 0.27s;
}

@media (prefers-reduced-motion: reduce) {
  .reveal {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

/* ---------- motion: one-time hero entrance on initial page load ---------- */
@keyframes hero-stack-in {
  from {
    opacity: 0;
    transform: translate(-50%, -50%) translateY(64px) scale(0.88) rotate(var(--rotate, 0deg));
  }

  to {
    opacity: var(--rest-opacity, 1);
    transform: translate(-50%, -50%) translateY(0) scale(1) rotate(var(--rotate, 0deg));
  }
}

@keyframes case-hero-in {
  from {
    opacity: 0;
    transform: translateY(40px) scale(0.95);
  }

  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

@media (prefers-reduced-motion: reduce) {
  .hero-stack-item,
  .case-hero-shot {
    animation: none;
  }

  .hero-stack-item {
    --tilt-x: 0deg;
    --tilt-y: 0deg;

    transition: none;
  }
}

/* ---------- buttons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.6em;
  font-family: var(--font-body);
  font-size: 0.98rem;
  font-weight: 600;
  padding: 0.95em 1.6em;
  border-radius: var(--radius-pill);
  text-decoration: none;
  border: 1px solid transparent;
  cursor: pointer;
  transition: transform 0.15s ease, background 0.15s ease, border-color 0.15s ease, color 0.15s ease;
  white-space: nowrap;
}

.btn:active {
  transform: translateY(1px);
}

.btn-primary {
  background: var(--accent);
  color: var(--accent-ink);
  transition: background 0.15s ease, box-shadow 0.15s ease;
}

.btn-primary:hover,
.btn-primary:focus-visible {
  background: var(--accent-dark);
  /* The lime glow used to live only on the "Most common" pricing card —
     reusing a lighter version here makes it read as a repeatable
     this-is-the-one-to-click signal instead of a one-off badge. */
  box-shadow: 0 0 32px -10px rgb(200, 255, 77, 0.45);
}

.btn-outline {
  background: transparent;
  border-color: var(--ink);
  color: var(--ink);
}

.btn-outline:hover {
  border-color: var(--accent);
  color: var(--accent);
}

.section-ink .btn-outline {
  border-color: var(--accent-ink);
  color: var(--accent-ink);
}

.section-ink .btn-outline:hover {
  background: var(--accent-ink);
  border-color: var(--accent-ink);
  color: var(--accent);
}

.btn-row {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  margin-top: 2em;
}

.link-arrow {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
  font-weight: 600;
  text-decoration: none;
  color: var(--accent);
  padding: 12px 0;
  margin: -12px 0;
}

.link-arrow::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: 12px;
  border-bottom: 1px solid var(--accent-soft-line);
}

.link-arrow:hover::after {
  border-color: var(--accent);
}

/* ---------- header ---------- */
.site-header {
  position: sticky;
  top: 0;
  z-index: 40;
  border-bottom: 1px solid var(--line-soft);
}

.site-header::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  /* Was 0.92 alpha with no blur behind it — barely visible against plain
     background, but a hard-edged 8% ghost of whatever scrolls underneath
     once a high-contrast work-card screenshot (white badges/text) passes
     beneath the sticky header. Fully opaque, no bleed-through possible. */
  background: var(--bg);
}

.site-header .container {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-top: 18px;
  padding-bottom: 18px;
}

.wordmark {
  font-family: var(--font-display);
  font-size: 1.28rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  text-decoration: none;
  color: var(--ink);
}

.wordmark em {
  font-style: italic;
  color: var(--accent);
  margin: 0 0.06em;
}

.nav {
  display: flex;
  align-items: center;
  gap: clamp(18px, 2.6vw, 34px);
}

.nav a {
  font-size: 0.96rem;
  font-weight: 500;
  text-decoration: none;
  color: var(--ink-soft);
}

.nav .btn {
  padding: 0.6em 1.3em;
  font-size: 0.9rem;
}

.nav .btn-primary {
  color: var(--accent-ink);
}

.nav-toggle {
  display: none;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  min-height: 44px;
  background: none;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 8px 10px;
  cursor: pointer;
}

.nav-toggle span,
.nav-toggle span::before,
.nav-toggle span::after {
  content: '';
  display: block;
  width: 18px;
  height: 2px;
  background: var(--ink);
  position: relative;
  transition: transform 0.15s ease, opacity 0.15s ease;
}

.nav-toggle span::before {
  position: absolute;
  top: -6px;
}

.nav-toggle span::after {
  position: absolute;
  top: 6px;
}

/* The transform transition above was already declared for this morph, but
   nothing ever set a transform on the open state — the icon was
   pixel-identical open or closed. */
html.nav-open .nav-toggle span {
  opacity: 0;
}

html.nav-open .nav-toggle span::before {
  top: 0;
  transform: rotate(45deg);
  opacity: 1;
}

html.nav-open .nav-toggle span::after {
  top: 0;
  transform: rotate(-45deg);
  opacity: 1;
}

@media (max-width: 760px) {
  .nav-toggle {
    display: flex;
  }

  .nav {
    position: fixed;
    inset: 65px 0 0;
    background: var(--bg);
    flex-direction: column;
    align-items: flex-start;
    padding: 26px var(--pad) 40px;
    gap: 22px;
    transform: translateY(-8px);
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.15s ease, transform 0.15s ease;
    overflow-y: auto;
  }

  .nav a {
    font-size: 1.15rem;
    color: var(--ink);
    /* Text-only height at this size was under 30px — below the 44px
       minimum touch target. */
    padding: 10px 0;
  }

  .nav .btn-primary {
    margin-top: 8px;
    width: 100%;
    justify-content: center;
    padding: 0.95em 1.6em;
    font-size: 1rem;
  }

  html.nav-open .nav {
    transform: translateY(0);
    opacity: 1;
    pointer-events: auto;
  }

  html.nav-open {
    overflow: hidden;
  }
}

/* ---------- footer ---------- */
.site-footer {
  border-top: 1px solid var(--line);
  padding: 48px 0 40px;
}

.site-footer .container {
  display: flex;
  flex-wrap: wrap;
  gap: 24px;
  align-items: flex-start;
  justify-content: space-between;
}

.footer-brand .wordmark {
  display: block;
  margin-bottom: 0.5em;
}

.footer-brand p {
  color: var(--ink-faint);
  font-size: 0.92rem;
  max-width: 30em;
}

.footer-nav {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 28px;
}

.footer-nav a {
  text-decoration: none;
  color: var(--ink-soft);
  font-size: 0.94rem;
}

.footer-nav a:hover {
  color: var(--accent);
}

.footer-bottom {
  margin-top: 34px;
  padding-top: 20px;
  border-top: 1px solid var(--line-soft);
  color: var(--ink-faint);
  font-size: 0.84rem;
}

/* :not(.btn) matters here: without it this rule (two classes + a type
   selector = higher specificity than .nav .btn-primary's two classes)
   overrode the button's own dark text color, on hover everywhere and
   permanently on whichever page the button's own link points to
   (aria-current="page" on /contact.html) — lime text on a lime button,
   unreadable either way. */
.nav a:not(.btn):hover,
.nav a:not(.btn)[aria-current="page"] {
  color: var(--accent);
}

/* ---------- hero ---------- */
.hero {
  position: relative;
  overflow: hidden;
  padding: clamp(48px, 8vw, 96px) 0 clamp(40px, 7vw, 72px);
}

.hero::before {
  content: '';
  position: absolute;
  top: -20%;
  right: -10%;
  width: 60vw;
  height: 60vw;
  max-width: 700px;
  max-height: 700px;
  background: radial-gradient(circle, rgb(200, 255, 77, 0.16), transparent 70%);
  pointer-events: none;
  z-index: 0;
  animation: ambient-drift 14s ease-in-out infinite alternate;
}

.hero::after {
  content: '';
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(var(--line-soft) 1px, transparent 1px),
    linear-gradient(90deg, var(--line-soft) 1px, transparent 1px);
  background-size: 56px 56px;
  background-attachment: fixed;
  opacity: 0.65;
  pointer-events: none;
  z-index: 0;
}

@keyframes ambient-drift {
  from {
    transform: translate(0, 0) scale(1);
  }

  to {
    transform: translate(-6%, 8%) scale(1.08);
  }
}

@media (prefers-reduced-motion: reduce) {
  .hero::before {
    animation: none;
  }
}

.hero .container {
  position: relative;
  z-index: 1;
}

.hero-grid {
  display: flex;
  flex-direction: column;
  gap: clamp(28px, 4vw, 40px);
}

.hero .h1 {
  max-width: 22em;
  perspective: 800px;
}

.hero .h1 .word {
  display: inline-block;
  animation: word-in 0.7s cubic-bezier(0.16, 1, 0.3, 1) both;
  animation-delay: calc(var(--i, 0) * 0.06s + 0.1s);
}

.hero .h1 .word:nth-child(odd) {
  --word-x: -50px;
  --word-ry: -32deg;
}

.hero .h1 .word:nth-child(even) {
  --word-x: 50px;
  --word-ry: 32deg;
}

.hero-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 26px;
  margin-top: 1.5em;
  padding-top: 1.3em;
  border-top: 1px solid var(--line);
}

.hero-meta div {
  font-family: var(--font-mono);
  font-size: 0.82rem;
  color: var(--ink-faint);
}

.hero-meta strong {
  display: block;
  color: var(--accent);
  font-size: 1.3rem;
  font-weight: 700;
}

.hero-meta .link-arrow {
  padding: 13px 0;
  margin: 0.3em 0 0;
  display: inline-flex;
}

.hero-visual {
  position: relative;
  width: 100%;
  height: clamp(280px, 25vw, 420px);
}

.hero-scene {
  position: absolute;
  inset: 0;
  cursor: grab;
}

.hero-scene canvas {
  display: block;
  width: 100%;
  height: 100%;
}

.hero-stack {
  position: relative;
  height: clamp(280px, 25vw, 420px);
}

.hero-stack-item {
  position: absolute;
  top: var(--top, 50%);
  left: var(--left, 50%);
  width: var(--card-width, 36%);
  aspect-ratio: 16 / 10;
  border-radius: var(--radius);
  border: 1px solid var(--line);
  box-shadow: var(--shadow-float);
  opacity: var(--rest-opacity, 1);
  transform: translate(-50%, -50%) scale(var(--scale, 1)) rotate(var(--rotate, 0deg)) perspective(900px) rotateX(var(--tilt-y, 0deg)) rotateY(var(--tilt-x, 0deg));
  transition: transform 0.4s cubic-bezier(0.16, 1, 0.3, 1), top 0.55s cubic-bezier(0.16, 1, 0.3, 1), left 0.55s cubic-bezier(0.16, 1, 0.3, 1), width 0.55s cubic-bezier(0.16, 1, 0.3, 1), opacity 0.4s ease, filter 0.3s ease;
  animation: hero-stack-in 1s cubic-bezier(0.16, 1, 0.3, 1) both;
  text-decoration: none;
}

.hero-stack-item:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  animation: none;

  --scale: 1.05;
  --rotate: 0deg;

  opacity: 1;
  z-index: 10;
}

.hero-stack-item-crop {
  position: absolute;
  inset: 0;
  border-radius: var(--radius);
  overflow: hidden;
  display: block;
}

.hero-stack-item-crop img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top;
  display: block;
}

/* ---------- fan: three panels spread left/center/right across the wide letterbox band ---------- */
.hero-stack .item-a {
  --left: 21%;
  --top: 52%;
  --rotate: -4deg;
  --card-width: 36%;

  z-index: 3;
  animation-delay: 0.6s;
}

.hero-stack .item-b {
  --left: 50%;
  --top: 58%;
  --rotate: 0deg;
  --card-width: 32%;
  --rest-opacity: 0.85;

  z-index: 2;
  animation-delay: 0.45s;
}

.hero-stack .item-c {
  --left: 79%;
  --top: 52%;
  --rotate: 4deg;
  --card-width: 36%;

  z-index: 3;
  animation-delay: 0.3s;
}

/* ---------- hover: rack-focus the other two back and mute them, bring the targeted panel forward ---------- */
@media (hover: hover) and (pointer: fine) {
  .hero-stack:hover .hero-stack-item {
    --scale: 0.96;

    filter: brightness(0.75) saturate(0.8);
  }

  .hero-stack .hero-stack-item:hover {
    --scale: 1.06;
    --rotate: 0deg;

    filter: none;
    opacity: 1;
    z-index: 6;
  }
}

.hero-stack.is-3d {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.hero-stack.is-3d .hero-stack-item {
  opacity: 0;
}

.hero-stack.is-3d .hero-stack-item:focus-visible {
  opacity: 1;
  pointer-events: auto;
  background: var(--bg);
  z-index: 20;
}

@media (max-width: 900px) {
  /* At 60vw the glow shrinks to a couple hundred px and sits mostly cropped
     off the top-right corner — present in the markup but barely visible
     against the desktop version's presence. */
  .hero::before {
    width: 90vw;
    height: 90vw;
    top: -30%;
    right: -20%;
  }

  .hero-visual {
    height: auto;
  }

  .hero-stack {
    width: 100%;
    height: clamp(220px, 60vw, 320px);
    max-width: 420px;
    margin: 0 auto;
  }

  .hero-scene {
    display: none;
  }

  /* ---------- mobile: back to a tall diagonal cascade, the box is portrait again ---------- */
  /* Cards were 78% wide with centers only 22-24% of the box apart —
     the overlap made it easy to tap the card underneath instead of the
     one on top. Narrower cards and wider vertical spacing keep the
     cascade look but give each one its own tappable area. */
  .hero-stack .item-a {
    --left: 64%;
    --top: 20%;
    --rotate: -3deg;
    --card-width: 68%;

    z-index: 3;
  }

  .hero-stack .item-b {
    --left: 38%;
    --top: 50%;
    --rotate: 2deg;
    --card-width: 68%;
    --rest-opacity: 0.92;

    z-index: 2;
  }

  .hero-stack .item-c {
    --left: 58%;
    --top: 80%;
    --rotate: -1.5deg;
    --card-width: 68%;
    --rest-opacity: 0.85;

    z-index: 1;
  }
}

/* ---------- work cards ---------- */
.work-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 28px;
  margin-top: 2.6em;
}

@media (max-width: 980px) {
  .work-grid {
    grid-template-columns: 1fr;
  }
}

.work-grid-single {
  grid-template-columns: 1fr;
  max-width: 420px;
  margin-left: auto;
  margin-right: auto;
}

.work-card {
  display: block;
  text-decoration: none;
  color: inherit;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  /* A resting shadow, not just a hover one — otherwise depth only shows up
     on a device that has hover at all, and every card looks flat on load. */
  box-shadow: var(--shadow-float);
  transform: rotate(var(--card-tilt, 0deg));
  transition: transform 0.18s ease, box-shadow 0.18s ease, border-color 0.18s ease;
}

/* A slight per-card tilt, same idea as the hero's fanned-out panels — the
   grid reads as a scattered set of prints instead of three identical,
   perfectly ruled boxes. */
.work-grid .work-card:nth-child(1) {
  --card-tilt: -1.1deg;
}

.work-grid .work-card:nth-child(2) {
  --card-tilt: 0.8deg;
}

.work-grid .work-card:nth-child(3) {
  --card-tilt: -0.6deg;
}

/* Touch has no real hover — without this guard, tapping a card to navigate
   flashed the tilt/lift transform first, which read as a stuck or laggy
   press rather than a link tap. */
/* --frame-tint (set by site.js from each card's own screenshot) adds a
   faint ambient glow sampled from the real image behind it — the frame
   reacting to what it holds — layered under the existing hover shadow,
   not replacing the lime border that stays the actual brand signal. */
@media (hover: hover) and (pointer: fine) {
  .work-card:hover {
    transform: translateY(-4px) rotate(var(--card-tilt, 0deg)) perspective(1000px) rotateX(var(--tilt-y, 0deg)) rotateY(var(--tilt-x, 0deg));
    border-color: var(--accent-soft-line);
    box-shadow: var(--shadow-hover), 0 0 60px -24px var(--frame-tint, transparent);
  }
}

.work-card .shot {
  aspect-ratio: 16 / 11;
  overflow: hidden;
  background: var(--bg-shade);
}

.work-card .shot img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top;
  transition: transform 0.5s ease;
}

@media (hover: hover) and (pointer: fine) {
  .work-card:hover .shot img {
    transform: scale(1.055);
  }
}

.work-card .body {
  padding: 22px 24px 26px;
}

.work-card h3 {
  margin-bottom: 0.3em;
  font-size: 1.35rem;
}

.work-card p {
  color: var(--ink-soft);
  font-size: 0.95rem;
}

.work-card.ghost {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  padding: 32px 28px;
  background: transparent;
  border-style: dashed;
  min-height: 100%;
}

.tag {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 0.4em 0.85em;
  border-radius: var(--radius-pill);
  background: var(--accent-soft);
  color: var(--accent-dark);
  margin-bottom: 0.9em;
  border: 1px solid var(--accent-soft-line);
}

.tag-outline {
  background: transparent;
  border: 1px solid var(--line);
  color: var(--ink-soft);
}

/* ---------- process ---------- */
.process {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 30px;
  margin-top: 2.6em;
}

@media (max-width: 860px) {
  .process {
    grid-template-columns: 1fr;
  }
}

.process-step {
  padding-top: 20px;
  border-top: 2px solid var(--accent);
}

.process-step .n {
  font-family: var(--font-display);
  font-size: 0.95rem;
  color: var(--accent);
  font-weight: 600;
  margin-bottom: 0.9em;
}

.process-step h3 {
  font-size: 1.3rem;
  margin-bottom: 0.4em;
}

.process-step p {
  color: var(--ink-soft);
  font-size: 0.98rem;
}

/* ---------- pricing ---------- */
.price-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  /* Default stretch forced every card to the height of the tallest one,
     leaving 30-60px of dead space at the bottom of the shorter cards. */
  align-items: start;
  gap: 22px;
  margin-top: 2.6em;
}

.price-grid.cols-4 {
  grid-template-columns: repeat(4, 1fr);
}

@media (max-width: 1080px) {
  .price-grid.cols-4 {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (max-width: 560px) {
  .price-grid.cols-4 {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 980px) {
  .price-grid {
    grid-template-columns: 1fr;
  }
}

.price-card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 30px 26px;
  position: relative;
  box-shadow: var(--shadow-float);
  transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
}

@media (hover: hover) and (pointer: fine) {
  .price-card:hover {
    transform: translateY(-4px) perspective(1000px) rotateX(var(--tilt-y, 0deg)) rotateY(var(--tilt-x, 0deg));
    border-color: var(--accent-soft-line);
    box-shadow: var(--shadow-hover);
  }
}

.price-card.featured {
  border-color: var(--accent);
  box-shadow: var(--shadow-accent);
}

@media (hover: hover) and (pointer: fine) {
  .price-card.featured:hover {
    /* Keep the featured tier's own glow as its identity instead of letting
       the generic hover shadow replace it. */
    box-shadow: var(--shadow-accent), var(--shadow-hover);
  }
}

.price-card .badge {
  position: absolute;
  top: -13px;
  left: 26px;
  background: var(--accent);
  color: var(--accent-ink);
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 0.4em 0.9em;
  border-radius: var(--radius-pill);
}

.price-card h3 {
  font-size: 1.3rem;
  margin-bottom: 0.2em;
}

.price-card .range {
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: 1.7rem;
  color: var(--accent);
  margin: 0.3em 0 0.7em;
}

.price-card ul {
  list-style: none;
  margin: 1.2em 0 0;
  padding: 0;
  border-top: 1px solid var(--line-soft);
  padding-top: 1.1em;
}

.price-card li {
  font-size: 0.92rem;
  color: var(--ink-soft);
  padding: 0.4em 0;
  padding-left: 1.3em;
  position: relative;
}

.price-card li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0.85em;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--accent-soft-line);
}

.care-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 22px;
  margin-top: 2em;
}

@media (max-width: 980px) {
  .care-grid {
    grid-template-columns: 1fr;
  }
}

.care-card {
  padding: 22px 24px;
  border: 1px solid var(--line);
  border-left: 3px solid var(--accent-soft-line);
  border-radius: var(--radius);
  background: var(--bg);
}

.care-card h3 {
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 1rem;
  margin-bottom: 0.3em;
}

.care-card .range {
  color: var(--accent);
  font-weight: 700;
  font-size: 0.94rem;
  margin-bottom: 0.6em;
  display: block;
}

.care-card p {
  color: var(--ink-soft);
  font-size: 0.9rem;
}

.addon-table {
  width: 100%;
  border-collapse: collapse;
  margin-top: 1.4em;
}

.addon-table th,
.addon-table td {
  text-align: left;
  padding: 14px 10px;
  border-bottom: 1px solid var(--line);
  font-size: 0.95rem;
}

.addon-table th {
  font-family: var(--font-body);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: 0.72rem;
  color: var(--ink-faint);
  font-weight: 700;
}

.addon-table td:last-child,
.addon-table th:last-child {
  text-align: right;
  color: var(--accent);
  font-family: var(--font-mono);
  font-weight: 600;
  white-space: nowrap;
}

@media (max-width: 560px) {
  /* A two-column table with a long left-hand label and a short right-hand
     price reflows awkwardly at phone widths — stack each row instead of
     shrinking the columns further. Order alone (name, then price) carries
     the header's meaning, so the header row is dropped rather than hidden
     text. */
  .addon-table thead {
    display: none;
  }

  .addon-table, .addon-table tbody, .addon-table tr, .addon-table td {
    display: block;
    width: 100%;
  }

  .addon-table tr {
    padding: 12px 0;
    border-bottom: 1px solid var(--line);
  }

  .addon-table td {
    border-bottom: none;
    padding: 2px 0;
  }

  .addon-table td:last-child {
    text-align: left;
  }
}

/* ---------- case study ---------- */
.case-hero-shot {
  margin-top: 2.4em;
  border-radius: var(--radius);
  overflow: hidden;
  border: 1px solid var(--line);
  box-shadow: var(--shadow-float);
  animation: case-hero-in 0.9s cubic-bezier(0.16, 1, 0.3, 1) both;
  animation-delay: 0.7s;
  position: relative;
}

/* ---------- signature: thirds grid toggle ---------- */
.thirds-toggle {
  position: absolute;
  top: 14px;
  right: 14px;
  z-index: 3;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: rgb(11, 12, 15, 0.7);
  border: 1px solid var(--accent-soft-line);
  color: var(--ink-soft);
  font-size: 1.05rem;
  line-height: 1;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: border-color 0.15s ease, color 0.15s ease;
}

.thirds-toggle:hover,
.thirds-toggle.is-active {
  border-color: var(--accent);
  color: var(--accent);
}

.case-hero-shot::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.2s ease;
  background-repeat: no-repeat;
  background-image:
    linear-gradient(var(--accent), var(--accent)),
    linear-gradient(var(--accent), var(--accent)),
    linear-gradient(90deg, var(--accent), var(--accent)),
    linear-gradient(90deg, var(--accent), var(--accent));
  background-size: 1px 100%, 1px 100%, 100% 1px, 100% 1px;
  background-position: 33.333% 0, 66.666% 0, 0 33.333%, 0 66.666%;
}

.case-hero-shot.is-thirds::after {
  opacity: 0.55;
}

@media print {
  .thirds-toggle {
    display: none !important;
  }
}

.case-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 18px;
  max-width: 46em;
}

.case-grid-wide {
  max-width: 52em;
}

.case-block {
  padding: 34px 0;
  border-top: 1px solid var(--line);
}

.case-block:first-child {
  border-top: none;
}

.case-block .eyebrow {
  margin-bottom: 0.8em;
}

.faq-list {
  max-width: 48em;
}

.faq-item {
  padding: 26px 0;
  border-top: 1px solid var(--line);
}

.faq-item:first-child {
  border-top: none;
}

.faq-item summary {
  cursor: pointer;
  list-style: none;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 20px;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.08rem;
  color: var(--ink);
}

.faq-item summary::-webkit-details-marker {
  display: none;
}

.faq-item summary::after {
  content: '+';
  flex: none;
  font-family: var(--font-mono);
  font-size: 1.4rem;
  line-height: 1;
  color: var(--accent);
}

.faq-item[open] summary::after {
  content: '\2212';
}

.faq-item p {
  margin: 1em 0 0;
  color: var(--ink-soft);
  max-width: 68ch;
}

.faq-item p a {
  color: var(--accent);
}

.pull {
  font-family: var(--font-display);
  font-size: clamp(1.35rem, 2.4vw, 1.85rem);
  line-height: 1.4;
  color: var(--ink);
  margin: 0.3em 0 1em;
}

.pull em {
  font-style: italic;
  color: var(--accent);
}

.shot-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 18px;
  margin-top: 2.6em;
}

@media (max-width: 760px) {
  .shot-grid {
    grid-template-columns: 1fr;
  }
}

.shot-grid figure {
  margin: 0;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  overflow: hidden;
}

.shot-grid figcaption {
  padding: 12px 14px;
  font-size: 0.84rem;
  color: var(--ink-faint);
  border-top: 1px solid var(--line);
}

.honest-note {
  background: var(--bg-shade);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 24px 26px;
  font-size: 0.96rem;
  color: var(--ink-soft);
}

.honest-note strong {
  color: var(--ink);
}

.case-nav {
  display: flex;
  justify-content: space-between;
  gap: 20px;
  padding-top: 40px;
  margin-top: 20px;
  border-top: 1px solid var(--line);
  flex-wrap: wrap;
}

/* ---------- contact layout ---------- */
.contact-layout {
  display: grid;
  grid-template-columns: 1.3fr 1fr;
  gap: 56px;
  align-items: start;
  margin-top: 2.4em;
}

.contact-layout .form-wrap {
  margin-top: 0;
  max-width: none;
}

@media (max-width: 900px) {
  .contact-layout {
    grid-template-columns: 1fr;
    gap: 40px;
  }
}

/* [hidden] is a UA-stylesheet rule with very low priority — any author
   "display" declaration for this element, even unrelated to [hidden],
   overrides it and shows the element regardless of the attribute. Scoping
   the flex layout to :not([hidden]) keeps [hidden] actually hiding it. */
.prefill-note:not([hidden]) {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  background: var(--accent-soft);
  border: 1px solid var(--accent-soft-line);
  color: var(--ink-soft);
  border-radius: var(--radius-sm);
  padding: 12px 16px;
  font-size: 0.86rem;
  margin-bottom: 24px;
}

.prefill-note span {
  color: var(--accent);
  font-weight: 700;
  flex: none;
}

.contact-aside {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 28px 26px;
  box-shadow: var(--shadow-float);
}

.contact-steps {
  list-style: none;
  margin: 1.4em 0 0;
  padding: 0;
}

.contact-steps li {
  display: flex;
  gap: 16px;
  padding: 16px 0;
  border-top: 1px solid var(--line-soft);
}

.contact-steps li:first-child {
  border-top: none;
  padding-top: 0;
}

.contact-steps .n {
  flex: none;
  font-family: var(--font-mono);
  font-size: 0.82rem;
  color: var(--accent);
  font-weight: 700;
  padding-top: 0.2em;
}

.contact-steps h3 {
  font-size: 1.02rem;
  margin-bottom: 0.3em;
}

.contact-steps p {
  color: var(--ink-soft);
  font-size: 0.88rem;
}

.contact-aside-note {
  margin-top: 1.6em;
  padding-top: 1.4em;
  border-top: 1px solid var(--line);
  font-size: 0.88rem;
  color: var(--ink-faint);
}

.form-success {
  display: none;
  margin-top: 1.4em;
  padding: 28px 30px;
  background: var(--accent-soft);
  border: 1px solid var(--accent-soft-line);
  border-radius: var(--radius);
}

.form-success .eyebrow {
  margin-bottom: 0.6em;
}

.form-success p {
  color: var(--ink-soft);
}

.form-wrap.is-sent .field,
.form-wrap.is-sent .field-row,
.form-wrap.is-sent .prefill-note,
.form-wrap.is-sent > .btn-primary,
.form-wrap.is-sent .form-note,
.form-wrap.is-sent .form-status {
  display: none;
}

.form-wrap.is-sent .form-success {
  display: block;
  animation: form-status-in 0.3s ease both;
}

/* ---------- form ---------- */
.form-wrap {
  max-width: 42em;
  margin-top: 2.4em;
}

.field {
  margin-bottom: 20px;
}

.field label {
  display: block;
  font-size: 0.86rem;
  font-weight: 600;
  color: var(--ink-soft);
  margin-bottom: 0.5em;
}

.optional-tag {
  font-weight: 400;
  color: var(--ink-faint);
}

.field-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 18px;
}

@media (max-width: 600px) {
  .field-row {
    grid-template-columns: 1fr;
  }
}

input, select, textarea {
  width: 100%;
  font-family: var(--font-body);
  font-size: 1rem;
  color: var(--ink);
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 0.85em 1em;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

textarea {
  resize: vertical;
  min-height: 130px;
}

input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgb(200, 255, 77, 0.15);
}

.field-hp {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.form-note {
  font-size: 0.84rem;
  color: var(--ink-faint);
  margin-top: 0.8em;
}

.care-grid + .form-note {
  margin-top: 1.6em;
  color: var(--ink-soft);
}

.form-status {
  margin-top: 18px;
  padding: 14px 18px;
  border-radius: var(--radius-sm);
  font-size: 0.94rem;
  display: none;
}

.form-status.show {
  display: block;
  animation: form-status-in 0.25s ease both;
}

@keyframes form-status-in {
  from {
    opacity: 0;
    transform: translateY(-6px);
  }

  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@media (prefers-reduced-motion: reduce) {
  .form-status.show {
    animation: none;
  }
}

/* Original values were a light-theme pastel pair (near-white backgrounds,
   dark-green/dark-red text) left over from before the dark-theme rewrite —
   they'd have rendered as bright white/pink boxes against the near-black
   page. Rebuilt from the same lime/orange accents already used elsewhere
   on the page instead of introducing new hues. */
.form-status.ok {
  background: rgb(200, 255, 77, 0.08);
  color: var(--accent);
  border: 1px solid var(--accent-soft-line);
}

.form-status.err {
  background: rgb(255, 90, 60, 0.1);
  color: var(--accent-2);
  border: 1px solid rgb(255, 90, 60, 0.35);
}

/* ---------- misc ---------- */
.divider {
  height: 1px;
  background: var(--line);
  border: none;
  margin: 0;
}

.center {
  text-align: center;
}

.narrow {
  max-width: 42em;
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.cta-banner {
  border-radius: var(--radius);
  padding: clamp(36px, 6vw, 64px);
  text-align: center;
}

/* The solid-lime .section-ink variant already reads as a banner. Without
   .section-ink the banner had no background of its own at all — just
   center-aligned text sitting in the page's own section, easy to mistake
   for a regular paragraph block instead of a call to action. */
.cta-banner:not(.section-ink) {
  background: linear-gradient(155deg, var(--card), var(--bg-shade));
  border: 1px solid var(--line);
}

.cta-banner .h2 {
  max-width: 20em;
  margin-left: auto;
  margin-right: auto;
}

.cta-banner .btn-row {
  justify-content: center;
}

/* Keyboard users' first tab stop — invisible until focused, then a
   clearly visible pill in the top-left corner. */
.skip-link {
  position: absolute;
  top: 10px;
  left: 10px;
  z-index: 200;
  padding: 10px 18px;
  background: var(--accent);
  color: var(--accent-ink);
  border-radius: 999px;
  font-weight: 700;
  text-decoration: none;
  transform: translateY(-300%);
}

.skip-link:focus {
  transform: none;
}

/* Who each pricing tier is for + how long it takes — sits between the
   price range and the feature list. */
.tier-fit {
  font-size: 0.85rem;
  color: var(--ink-soft);
  margin: 2px 0 10px;
}

/* Risk-reducer line under a banner's button. currentColor keeps it legible
   on both the lime .section-ink banner (dark text) and the dark card
   variant (light text) without a second color rule. */
.cta-note {
  margin-top: 14px;
  font-family: var(--font-mono, monospace);
  font-size: 0.78rem;
  letter-spacing: 0.04em;
  color: currentColor;
  opacity: 0.75;
}

.work-card.ghost h3 {
  font-size: 1.35rem;
  margin-bottom: 0.4em;
}

.work-card.ghost p {
  color: var(--ink-soft);
  font-size: 0.95rem;
  margin-bottom: 1.3em;
}

/* ---------- motion: hero text opens with the page, every hero on the site ---------- */
@keyframes word-in {
  from {
    opacity: 0;
    transform: translate3d(var(--word-x, 0), 22px, 0) rotateX(20deg) rotateY(var(--word-ry, 0deg));
    filter: blur(6px);
  }

  to {
    opacity: 1;
    transform: translate3d(0, 0, 0) rotateX(0deg) rotateY(0deg);
    filter: blur(0);
  }
}

@keyframes hero-text-in-left {
  from {
    opacity: 0;
    transform: translateX(-60px);
  }

  to {
    opacity: 1;
    transform: translateX(0);
  }
}

@keyframes hero-text-in-right {
  from {
    opacity: 0;
    transform: translateX(60px);
  }

  to {
    opacity: 1;
    transform: translateX(0);
  }
}

@keyframes hero-text-in-up {
  from {
    opacity: 0;
    transform: translateY(28px);
  }

  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.hero .eyebrow,
.hero .tag {
  animation: hero-text-in-left 0.65s cubic-bezier(0.16, 1, 0.3, 1) both;
}

.hero .lede {
  animation: hero-text-in-left 0.7s cubic-bezier(0.16, 1, 0.3, 1) both;
  animation-delay: 0.45s;
}

.hero .btn-row {
  animation: hero-text-in-up 0.6s cubic-bezier(0.16, 1, 0.3, 1) both;
  animation-delay: 0.55s;
}

.hero .hero-meta {
  animation: hero-text-in-right 0.7s cubic-bezier(0.16, 1, 0.3, 1) both;
  animation-delay: 0.65s;
}

@media (prefers-reduced-motion: reduce) {
  .hero .eyebrow,
  .hero .tag,
  .hero .lede,
  .hero .btn-row,
  .hero .hero-meta {
    animation: none;
    opacity: 1;
    clip-path: none;
  }

  .hero .h1 .word {
    animation: none;
    opacity: 1;
    transform: none;
    filter: none;
  }

  .hero-scene {
    display: none;
  }

  /* Higher-specificity override: without this, the .gnf-settle micro-pulse
     below (html.gnf-arrived.gnf-settle .hero ...) would beat the plain-class
     rules above on specificity alone and animate despite reduced-motion. */
  html.gnf-arrived.gnf-settle .hero .eyebrow,
  html.gnf-arrived.gnf-settle .hero .tag,
  html.gnf-arrived.gnf-settle .hero .lede,
  html.gnf-arrived.gnf-settle .hero .btn-row,
  html.gnf-arrived.gnf-settle .hero .hero-meta,
  html.gnf-arrived.gnf-settle .hero .h1 .word {
    animation: none;
    transform: none;
    filter: none;
  }
}

/* Arriving via internal nav: the iris is the reveal. Suppress the hero's own
   entrance animations (they run unsynchronized with the iris and otherwise pop
   the words in mid-wipe) so the iris opening onto already-settled text is the
   only motion, EXCEPT for a tiny synchronized "settle" pulse (hero-text-settle
   below) that's timed to finish well inside the safety margin before the iris
   uncovers the hero's outer elements. gnf-nav itself is removed within ~30ms so
   it can't scope this; gnf-arrived is set once and kept for the page's lifetime. */
html.gnf-arrived .hero .eyebrow,
html.gnf-arrived .hero .tag,
html.gnf-arrived .hero .lede,
html.gnf-arrived .hero .btn-row,
html.gnf-arrived .hero .hero-meta {
  animation: none;
  opacity: 1;
  clip-path: none;
}

html.gnf-arrived .hero .h1 .word {
  animation: none;
  opacity: 1;
  transform: none;
  filter: none;
}

/* Micro-settle on iris-reveal arrival: a single, tiny, opacity-safe pulse so the
   hero text doesn't read as a flat cut from hidden-under-disc to fully-static.
   No opacity/translate/blur/rotate — those are what made the original
   unsynchronized entrance look "unsettled" mid-wipe. Amplitude is kept small
   enough (0.8% scale, 6% brightness dip) that it reads as "just rendered" even
   if glimpsed mid-motion, not as popping in. Applied identically to every hero
   text element (no per-word stagger) so they all move as one coherent unit.
   Armed only via .gnf-settle, which JS adds in the same double-rAF tick that
   starts the iris opening, and removes 260ms later (see site.js). */
html.gnf-arrived.gnf-settle .hero .eyebrow,
html.gnf-arrived.gnf-settle .hero .tag,
html.gnf-arrived.gnf-settle .hero .lede,
html.gnf-arrived.gnf-settle .hero .btn-row,
html.gnf-arrived.gnf-settle .hero .hero-meta,
html.gnf-arrived.gnf-settle .hero .h1 .word {
  animation: hero-text-settle 0.22s cubic-bezier(0.11, 0.7, 0.24, 1) both;
}

@keyframes hero-text-settle {
  from {
    transform: scale(1.008);
    filter: brightness(0.94);
  }

  to {
    transform: scale(1);
    filter: brightness(1);
  }
}

/* .hero-stack-item's animationend (animationName === 'hero-stack-in') flips the
   hover-tilt "settled" flag in site.js — animation: none would never fire that
   event and permanently break hover-tilt on arrival. Collapse the timing instead
   so it still fires, just imperceptibly fast. Doesn't touch scale/filter/opacity,
   so it can't shadow the hover/focus/is-3d rules above despite the lower specificity. */
/* stylelint-disable-next-line no-descending-specificity */
html.gnf-arrived .hero-stack .hero-stack-item {
  animation-duration: 0.001s;
  animation-delay: 0s;
}

html.gnf-arrived .case-hero-shot {
  animation: none;
  opacity: 1;
  transform: none;
}

/* ---------- bold accent-block CTA: invert the primary button so it isn't lime-on-lime ---------- */
.section-ink .btn-primary {
  background: var(--accent-ink);
  color: var(--accent);
}

.section-ink .btn-primary:hover {
  background: var(--bg-shade);
}

/* ---------- page-transition iris (aperture close/open between pages) ---------- */
.page-iris {
  position: fixed;
  inset: 0;
  z-index: 9999;
  pointer-events: none;
  display: flex;
  align-items: center;
  justify-content: center;
}

.page-iris-disc {
  /* vw/vh (not vmax) so the disc's own aspect ratio matches the viewport's:
     a pure vmax circle reaches the top/bottom edges long before the left/right
     edges on a landscape viewport, leaving a visible gap on the sides mid-wipe. */
  width: 200vw;
  height: 200vh;
  flex-shrink: 0;
  border-radius: 50%;
  background: var(--bg);
  box-shadow: 0 0 0 2px rgb(200, 255, 77, 0.5) inset;
  transform: scale(0);
  will-change: transform;
}

.page-iris.is-animating .page-iris-disc {
  transition: transform 0.56s cubic-bezier(0.65, 0, 0.35, 1);
}

.page-iris.is-covered .page-iris-disc {
  transform: scale(1);
}

html.gnf-nav body {
  visibility: hidden;
}

@media (prefers-reduced-motion: reduce) {
  .page-iris {
    display: none;
  }
}

/* ---------- hero grid cursor-lens (magnified grid patch that follows the pointer) ---------- */
.hero-lens {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background-image:
    linear-gradient(var(--line-soft) 1px, transparent 1px),
    linear-gradient(90deg, var(--line-soft) 1px, transparent 1px);
  background-size: 78px 78px;
  opacity: 0.9;
  mask-image: radial-gradient(circle 170px at var(--lens-x, -999px) var(--lens-y, -999px), black 55%, transparent 100%);
}

@media (hover: none), (prefers-reduced-motion: reduce) {
  .hero-lens {
    display: none;
  }
}

/* ---------- footer wireframe cube (rotating, cycles the process words) ---------- */
.footer-brand-top {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 0.5em;
}

.footer-brand-top .wordmark {
  margin-bottom: 0;
}

.footer-cube {
  position: relative;
  width: 46px;
  height: 46px;
  flex: none;
  perspective: 600px;
  display: none;
}

.footer-cube-inner {
  position: absolute;
  inset: 0;
  transform-style: preserve-3d;
  animation: footer-cube-spin 16s linear infinite;
}

.footer-cube-face {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  /* A real border doubles up right where two faces meet edge-on mid-spin,
     showing as a visible seam. An inset shadow gives the same outline
     without adding geometry at that boundary. */
  box-shadow: inset 0 0 0 1px var(--accent-soft-line);
  background: rgb(200, 255, 77, 0.04);
  color: var(--accent);
  font-family: var(--font-mono);
  font-size: 0.5rem;
  letter-spacing: 0.05em;
  text-align: center;
  backface-visibility: hidden;
}

.footer-cube-face:nth-child(1) {
  transform: rotateY(0deg) translateZ(23px);
}

.footer-cube-face:nth-child(2) {
  transform: rotateY(90deg) translateZ(23px);
}

.footer-cube-face:nth-child(3) {
  transform: rotateY(180deg) translateZ(23px);
}

.footer-cube-face:nth-child(4) {
  transform: rotateY(270deg) translateZ(23px);
}

@keyframes footer-cube-spin {
  from {
    transform: rotateY(0deg);
  }

  to {
    transform: rotateY(360deg);
  }
}

@media (min-width: 640px) {
  .footer-cube {
    display: block;
  }
}

@media (prefers-reduced-motion: reduce) {
  .footer-cube-inner {
    animation: none;
  }
}

/* ---------- signature: instrument-panel scrollbar ---------- */
/* A page builder can't touch this, so every default Wix/Squarespace/Webflow
   site scrolls with the visitor's stock light-gray OS scrollbar — the most
   visible seam breaking dark-mode immersion the moment anyone scrolls. */
::-webkit-scrollbar {
  width: 10px;
  height: 10px;
}

::-webkit-scrollbar-track {
  background: var(--bg);
}

::-webkit-scrollbar-thumb {
  background: var(--accent-dark);
  border: 2px solid var(--bg);
}

::-webkit-scrollbar-thumb:hover {
  background: var(--accent);
}

html {
  scrollbar-color: var(--accent-dark) var(--bg);
  scrollbar-width: thin;
}

/* ---------- signature: autofocus-lock form fields ---------- */
/* Four corner brackets built from eight background gradients (a horizontal
   and vertical bar per corner) — no extra markup needed. Invisible at rest,
   snap inward on focus like a camera locking on; on a validation error they
   jitter loose in the site's warning color instead of a plain red outline. */
.field {
  position: relative;
}

.field::before {
  content: '';
  position: absolute;
  inset: -5px;
  pointer-events: none;
  opacity: 0;
  transform: scale(1.08);
  transition: opacity 0.15s ease, transform 0.15s cubic-bezier(0.34, 1.56, 0.64, 1);
  background-repeat: no-repeat;
  background-image:
    linear-gradient(var(--accent), var(--accent)), linear-gradient(var(--accent), var(--accent)),
    linear-gradient(var(--accent), var(--accent)), linear-gradient(var(--accent), var(--accent)),
    linear-gradient(var(--accent), var(--accent)), linear-gradient(var(--accent), var(--accent)),
    linear-gradient(var(--accent), var(--accent)), linear-gradient(var(--accent), var(--accent));
  background-size: 14px 2px, 2px 14px, 14px 2px, 2px 14px, 14px 2px, 2px 14px, 14px 2px, 2px 14px;
  background-position: top left, top left, top right, top right, bottom left, bottom left, bottom right, bottom right;
}

.field:focus-within::before {
  opacity: 1;
  transform: scale(1);
}

.field.has-error::before {
  opacity: 1;
  transform: scale(1);
  background-image:
    linear-gradient(var(--accent-2), var(--accent-2)), linear-gradient(var(--accent-2), var(--accent-2)),
    linear-gradient(var(--accent-2), var(--accent-2)), linear-gradient(var(--accent-2), var(--accent-2)),
    linear-gradient(var(--accent-2), var(--accent-2)), linear-gradient(var(--accent-2), var(--accent-2)),
    linear-gradient(var(--accent-2), var(--accent-2)), linear-gradient(var(--accent-2), var(--accent-2));
  animation: field-error-jitter 0.3s ease;
}

.field-error-msg {
  display: none;
  color: var(--accent-2);
  font-family: var(--font-mono);
  font-size: 0.78rem;
  margin-top: 0.5em;
}

.field.has-error .field-error-msg {
  display: block;
}

@keyframes field-error-jitter {
  0%, 100% { transform: scale(1) translateX(0); }
  25% { transform: scale(1.03) translateX(-3px); }
  75% { transform: scale(1.03) translateX(3px); }
}

@media (prefers-reduced-motion: reduce) {
  .field::before {
    transition: opacity 0.15s ease;
  }

  .field.has-error::before {
    animation: none;
  }
}

/* ---------- signature: viewfinder cursor ---------- */
/* Page builders never expose a custom cursor, so every template site runs
   the stock OS arrow untouched. Off on touch (no real cursor) and under
   reduced motion (it's driven by a mousemove listener).

   Previous build only ever drew 2 of 4 corners (both ::before/::after pairs
   used "top", so the bottom two never existed) AND never hid the real OS
   cursor — visitors saw the native arrow plus a stray two-corner shape
   trailing it, which reads as a rendering bug, not a custom cursor. Fixed
   both: real cursor is hidden via html.gnf-custom-cursor below, and all
   4 corners are drawn with the same 8-gradient technique used for the
   form-field focus brackets, rather than juggling pseudo-elements. */
/* Text fields keep the native I-beam, and the template-vs-real slider
   keeps the native ew-resize cursor — a static crosshair communicates
   neither "click to type" nor "drag this handle" the way the OS cursor
   does. */
html.gnf-custom-cursor,
html.gnf-custom-cursor *:not(input):not(textarea):not([contenteditable]) {
  cursor: none !important;
}

.viewfinder-cursor {
  position: fixed;
  top: 0;
  left: 0;
  width: 28px;
  height: 28px;
  pointer-events: none;
  z-index: 9998;
  transform: translate(-999px, -999px);
  opacity: 0;
  transition: opacity 0.2s ease, width 0.15s cubic-bezier(0.34, 1.56, 0.64, 1), height 0.15s cubic-bezier(0.34, 1.56, 0.64, 1);
  will-change: transform;
  background-repeat: no-repeat;
  background-image:
    linear-gradient(var(--accent), var(--accent)), linear-gradient(var(--accent), var(--accent)),
    linear-gradient(var(--accent), var(--accent)), linear-gradient(var(--accent), var(--accent)),
    linear-gradient(var(--accent), var(--accent)), linear-gradient(var(--accent), var(--accent)),
    linear-gradient(var(--accent), var(--accent)), linear-gradient(var(--accent), var(--accent));
  background-size: 9px 2px, 2px 9px, 9px 2px, 2px 9px, 9px 2px, 2px 9px, 9px 2px, 2px 9px;
  background-position: top left, top left, top right, top right, bottom left, bottom left, bottom right, bottom right;
}

.viewfinder-cursor.is-active {
  opacity: 1;
}

.viewfinder-cursor span {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 2px;
  height: 2px;
  border-radius: 50%;
  background: var(--accent);
  transform: translate(-50%, -50%);
}

.viewfinder-cursor.is-hover {
  width: 20px;
  height: 20px;
}

.viewfinder-cursor.is-text-field {
  opacity: 0;
}

@media (hover: none), (pointer: coarse), (prefers-reduced-motion: reduce) {
  .viewfinder-cursor {
    display: none;
  }
}

/* ---------- signature: shutter-click copy ---------- */
.copyable {
  position: relative;
  cursor: pointer;
}

.copyable::after {
  content: '';
  position: absolute;
  inset: -3px -6px;
  border: 1px solid var(--accent);
  opacity: 0;
  transform: scale(0.94);
  pointer-events: none;
  transition: opacity 0.15s ease, transform 0.15s cubic-bezier(0.34, 1.56, 0.64, 1);
}

.copyable.is-copied::after {
  opacity: 1;
  transform: scale(1);
}

.copy-tag {
  position: absolute;
  left: 50%;
  bottom: 100%;
  transform: translate(-50%, 4px);
  margin-bottom: 6px;
  font-family: var(--font-mono);
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--accent-ink);
  background: var(--accent);
  padding: 0.3em 0.6em;
  border-radius: var(--radius-pill);
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.2s ease, transform 0.4s cubic-bezier(0.16, 1, 0.3, 1);
}

.copyable.is-copied .copy-tag {
  opacity: 1;
  transform: translate(-50%, -6px);
}

/* ---------- signature: grid reveal blueprint mode ---------- */
/* Unlocked by typing "grid" anywhere on the page (see site.js) — no visible
   hint. A page builder's output has no real grid to reveal; this proves
   the layout is actually held together by one. */
html.gnf-blueprint body {
  background: var(--bg);
}

html.gnf-blueprint .section::before,
html.gnf-blueprint .hero::after {
  opacity: 1 !important;
}

.gnf-blueprint-overlay {
  position: fixed;
  inset: 0;
  z-index: 9997;
  pointer-events: none;
  display: none;
  font-family: var(--font-mono);
}

html.gnf-blueprint .gnf-blueprint-overlay {
  display: block;
}

.gnf-blueprint-tag {
  position: fixed;
  top: 14px;
  left: 14px;
  z-index: 9997;
  display: none;
  align-items: center;
  gap: 8px;
  background: var(--accent);
  color: var(--accent-ink);
  font-family: var(--font-mono);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  padding: 0.5em 0.9em;
  border-radius: var(--radius-pill);
  box-shadow: var(--shadow-float);
}

html.gnf-blueprint .gnf-blueprint-tag {
  display: flex;
}

.gnf-blueprint-tag button {
  background: none;
  border: none;
  color: inherit;
  font: inherit;
  cursor: pointer;
  text-decoration: underline;
  padding: 0;
}

.gnf-blueprint-marker {
  position: absolute;
  font-family: var(--font-mono);
  font-size: 0.62rem;
  color: var(--accent);
  background: rgb(11, 12, 15, 0.85);
  border: 1px solid var(--accent-soft-line);
  padding: 1px 5px;
  pointer-events: none;
  white-space: nowrap;
  z-index: 9996;
}

.gnf-grid-coord {
  position: fixed;
  bottom: 14px;
  right: 14px;
  z-index: 9997;
  display: none;
  font-family: var(--font-mono);
  font-size: 0.7rem;
  color: var(--accent);
  background: rgb(11, 12, 15, 0.85);
  border: 1px solid var(--accent-soft-line);
  padding: 0.4em 0.7em;
  border-radius: var(--radius-sm);
  pointer-events: none;
}

html.gnf-blueprint .gnf-grid-coord {
  display: block;
}

/* ---------- print: strip the dark theme to one usable page ---------- */
/* Almost no small-business site's own builder has ever hit Cmd+P on it.
   Printed as-is, a dark theme produces gray text on white paper with the
   hero sliced across three sheets — this reflows to one clean, real page. */
@media print {
  .site-header, .site-footer, .nav-toggle, .btn-row, .hero::before, .hero::after,
  .hero-visual, .section::before, .page-iris, .hero-lens, .footer-cube,
  .viewfinder-cursor, .gnf-blueprint-overlay, .gnf-blueprint-tag, .reveal-hint,
  .tvr-slider {
    display: none !important;
  }

  * {
    background: #fff !important;
    color: #111214 !important;
    box-shadow: none !important;
    text-shadow: none !important;
    animation: none !important;
    transform: none !important;
  }

  body {
    font-size: 11.5pt;
  }

  h1, h2, h3, h4 {
    color: #000 !important;
  }

  .price-card, .care-card, .work-card, .case-block, .honest-note {
    border: 1px solid #ccc !important;
    break-inside: avoid;
  }

  a {
    color: #111214 !important;
    text-decoration: underline;
  }

  .container {
    max-width: 100% !important;
    padding: 0 !important;
  }

  .print-footer {
    display: flex !important;
    justify-content: space-between;
    font-family: var(--font-mono);
    font-size: 9pt;
    color: #555 !important;
    border-top: 1px solid #ccc;
    padding-top: 10px;
    margin-top: 24px;
  }
}

.print-footer {
  display: none;
}

/* ---------- signature: public build log ---------- */
.changelog-list {
  max-width: 52em;
}

.changelog-date {
  font-family: var(--font-mono);
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--accent);
  margin: 2em 0 0.8em;
}

.changelog-date:first-child {
  margin-top: 0;
}

.changelog-row {
  display: flex;
  gap: 18px;
  align-items: baseline;
  padding: 10px 0;
  border-bottom: 1px solid var(--line-soft);
}

.changelog-hash {
  flex: none;
  font-family: var(--font-mono);
  font-size: 0.82rem;
  color: var(--ink-faint);
  width: 6ch;
}

.changelog-msg {
  color: var(--ink-soft);
  font-size: 0.95rem;
}

@media (max-width: 560px) {
  .changelog-row {
    flex-direction: column;
    gap: 2px;
  }

  .changelog-hash {
    width: auto;
  }
}

/* ---------- signature: scope builder ---------- */
.scope-builder {
  margin-top: 2.4em;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-float);
  overflow: hidden;
}

.scope-tiers {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  border-bottom: 1px solid var(--line);
}

.scope-tier-btn {
  background: none;
  border: none;
  border-right: 1px solid var(--line);
  color: var(--ink-soft);
  padding: 18px 12px;
  cursor: pointer;
  font-family: var(--font-body);
  text-align: center;
  transition: background 0.15s ease, color 0.15s ease;
}

.scope-tier-btn:last-child {
  border-right: none;
}

.scope-tier-btn:hover {
  background: rgb(200, 255, 77, 0.05);
}

.scope-tier-btn.is-active {
  background: var(--accent-soft);
  color: var(--accent);
}

.scope-tier-name {
  display: block;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.05rem;
  margin-bottom: 0.2em;
}

.scope-tier-pages {
  display: block;
  font-family: var(--font-mono);
  font-size: 0.76rem;
  color: var(--ink-faint);
}

.scope-tier-btn.is-active .scope-tier-pages {
  color: var(--accent-dark);
}

.scope-body {
  display: grid;
  grid-template-columns: 1.3fr 1fr;
}

.scope-addons {
  padding: 26px 28px;
  border-right: 1px solid var(--line);
}

.scope-addon {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 11px 0;
  border-bottom: 1px solid var(--line-soft);
  cursor: pointer;
}

.scope-addon:last-child {
  border-bottom: none;
}

.scope-addon input[type="checkbox"] {
  width: 18px;
  height: 18px;
  accent-color: var(--accent);
  flex: none;
}

.scope-addon-label {
  flex: 1;
  font-size: 0.92rem;
  color: var(--ink-soft);
}

.scope-addon-price {
  font-family: var(--font-mono);
  font-size: 0.82rem;
  color: var(--ink-faint);
  white-space: nowrap;
}

.scope-addon-stepper {
  cursor: default;
}

.scope-stepper {
  display: flex;
  align-items: center;
  gap: 10px;
  font-family: var(--font-mono);
}

.scope-stepper button {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  border: 1px solid var(--line);
  background: var(--bg);
  color: var(--ink);
  cursor: pointer;
  font-size: 0.9rem;
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
}

.scope-stepper button:hover {
  border-color: var(--accent);
  color: var(--accent);
}

.scope-total {
  padding: 26px 28px;
  background: var(--bg-shade);
  display: flex;
  flex-direction: column;
}

.scope-total-label {
  font-family: var(--font-mono);
  font-size: 0.76rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink-faint);
  margin-bottom: 0.4em;
}

.scope-total-number {
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: 2rem;
  color: var(--accent);
  margin-bottom: 0.7em;
}

.scope-itemized {
  list-style: none;
  margin: 0 0 1.2em;
  padding: 0.8em 0 0;
  border-top: 1px solid var(--line);
  flex: 1;
}

.scope-itemized li {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  font-size: 0.86rem;
  color: var(--ink-soft);
  padding: 0.4em 0;
}

.scope-itemized li span:last-child {
  font-family: var(--font-mono);
  color: var(--ink);
  white-space: nowrap;
}

.scope-not-included {
  font-size: 0.8rem;
  color: var(--ink-faint);
  margin-bottom: 1.2em;
}

@media (max-width: 760px) {
  .scope-tiers {
    grid-template-columns: repeat(2, 1fr);
  }

  .scope-tier-btn:nth-child(2) {
    border-right: none;
  }

  .scope-tier-btn:nth-child(1),
  .scope-tier-btn:nth-child(2) {
    border-bottom: 1px solid var(--line);
  }

  .scope-body {
    grid-template-columns: 1fr;
  }

  .scope-addons {
    border-right: none;
    border-bottom: 1px solid var(--line);
  }
}

/* ---------- signature: // view source panel ---------- */
.vs-toggle {
  background: none;
  border: 1px solid var(--line);
  color: var(--ink-faint);
  font-family: var(--font-mono);
  font-size: 0.68rem;
  padding: 0.35em 0.7em;
  border-radius: var(--radius-pill);
  cursor: pointer;
  white-space: nowrap;
  transition: border-color 0.15s ease, color 0.15s ease;
}

.vs-toggle:hover,
.vs-toggle.is-open {
  border-color: var(--accent-soft-line);
  color: var(--accent);
}

.vs-panel {
  display: none;
  margin-top: 16px;
  background: var(--bg-shade);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 16px 18px;
  max-width: 32em;
}

.vs-panel.is-open {
  display: block;
}

.vs-panel-label {
  font-family: var(--font-mono);
  font-size: 0.68rem;
  color: var(--ink-faint);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin-bottom: 0.8em;
}

.vs-panel pre {
  margin: 0;
  overflow-x: auto;
}

.vs-panel code {
  font-family: var(--font-mono);
  font-size: 0.76rem;
  line-height: 1.6;
  color: var(--ink-soft);
  white-space: pre;
}

.perf-hud-toggle {
  display: inline-block;
  margin-top: 16px;
}

.perf-hud-panel {
  max-width: 26em;
}

.perf-hud-panel .audit-line {
  border-bottom: 1px solid var(--line-soft);
  padding: 6px 0;
}

.perf-hud-panel .audit-line:last-child {
  border-bottom: none;
}

/* ---------- signature: site audit ---------- */
.audit-form {
  max-width: 42em;
  margin-top: 2.4em;
}

.audit-form label {
  display: block;
  font-size: 0.86rem;
  font-weight: 600;
  color: var(--ink-soft);
  margin-bottom: 0.5em;
}

.audit-input-row {
  display: flex;
  gap: 12px;
}

.audit-input-row input {
  flex: 1;
  font-family: var(--font-body);
  font-size: 1rem;
  color: var(--ink);
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 0.85em 1em;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.audit-input-row input:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgb(200, 255, 77, 0.15);
}

.audit-input-row .btn {
  flex: none;
}

@media (max-width: 560px) {
  .audit-input-row {
    flex-direction: column;
  }
}

.audit-status {
  max-width: 42em;
  margin-top: 1em;
  font-family: var(--font-mono);
  font-size: 0.86rem;
  color: var(--ink-faint);
  min-height: 1.4em;
}

.audit-status.is-error {
  color: var(--accent-2);
}

.audit-compare {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 22px;
  margin-top: 2.4em;
}

@media (max-width: 760px) {
  .audit-compare {
    grid-template-columns: 1fr;
  }
}

.audit-receipt {
  background: var(--bg-shade);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  font-family: var(--font-mono);
}

.audit-receipt-head {
  background: var(--accent-soft);
  color: var(--accent);
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  padding: 12px 20px;
  border-bottom: 1px dashed var(--accent-soft-line);
}

.audit-receipt-body {
  padding: 18px 20px;
}

.audit-line {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  font-size: 0.88rem;
  color: var(--ink-soft);
  padding: 8px 0;
  border-bottom: 1px dashed var(--line-soft);
}

.audit-line:last-child {
  border-bottom: none;
}

.audit-line span:last-child {
  color: var(--ink);
  white-space: nowrap;
}

.audit-line.is-warning span:last-child {
  color: var(--accent-2);
}

.audit-line.is-good span:last-child {
  color: var(--accent);
}

/* ---------- signature: real-cost calculator ---------- */
.cost-calc {
  margin-top: 2.4em;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 22px;
}

@media (max-width: 860px) {
  .cost-calc {
    grid-template-columns: 1fr;
  }
}

.cost-calc-inputs .field label {
  color: var(--ink);
}

.cost-calc-inputs input,
.cost-calc-inputs select {
  width: 100%;
  font-family: var(--font-body);
  font-size: 1rem;
  color: var(--ink);
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 0.75em 0.9em;
}

.cost-calc-result {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 26px 28px;
  box-shadow: var(--shadow-float);
}

.cost-calc-placeholder {
  color: var(--ink-faint);
  font-size: 0.94rem;
}

.cost-calc-headline {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.15rem;
  margin-bottom: 0.8em;
  color: var(--ink);
}

.cost-calc-headline strong {
  color: var(--accent);
}

.cost-calc-row {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  font-size: 0.92rem;
  color: var(--ink-soft);
  padding: 0.5em 0;
  border-top: 1px solid var(--line-soft);
}

.cost-calc-row span:last-child {
  font-family: var(--font-mono);
  color: var(--ink);
  white-space: nowrap;
}

/* ---------- signature: build slip (case-study receipt flip) ---------- */
.build-slip-toggle {
  display: inline-block;
  background: none;
  border: 1px solid var(--line);
  color: var(--ink-faint);
  font-family: var(--font-mono);
  font-size: 0.72rem;
  padding: 0.4em 0.8em;
  border-radius: var(--radius-pill);
  cursor: pointer;
  margin-top: 0.6em;
  transition: border-color 0.15s ease, color 0.15s ease;
}

.build-slip-toggle:hover,
.build-slip-toggle.is-open {
  border-color: var(--accent-soft-line);
  color: var(--accent);
}

.build-slip {
  display: none;
  margin-top: 16px;
  background: var(--bg-shade);
  border: 1px dashed var(--line);
  border-radius: var(--radius-sm);
  padding: 20px 22px;
  font-family: var(--font-mono);
  max-width: 32em;
}

.build-slip.is-open {
  display: block;
}

.build-slip-head {
  font-size: 0.8rem;
  font-weight: 700;
  color: var(--accent);
  letter-spacing: 0.03em;
}

.build-slip-sub {
  font-size: 0.74rem;
  color: var(--ink-faint);
  margin-bottom: 1em;
  padding-bottom: 1em;
  border-bottom: 1px dashed var(--line);
}

.build-slip-items {
  list-style: none;
  margin: 0 0 1em;
  padding: 0;
}

.build-slip-items li {
  font-size: 0.86rem;
  color: var(--ink-soft);
  padding: 0.3em 0;
}

.build-slip-items li::before {
  content: '✓ ';
  color: var(--accent);
}

.build-slip-total {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  font-size: 0.95rem;
  font-weight: 700;
  color: var(--ink);
  padding-top: 0.9em;
  border-top: 1px dashed var(--line);
  margin-bottom: 0.8em;
}

.build-slip-note {
  font-size: 0.76rem;
  color: var(--ink-faint);
  font-family: var(--font-body);
  margin: 0;
}

/* ---------- signature: template vs real slider ---------- */
/* A template-selling competitor can never run this comparison against
   itself — showing it is the one move that's self-incriminating for
   anyone else in this market. Real drag interaction, not two static
   screenshots side by side. */
.tvr-slider {
  margin-top: 2.4em;
}

/* A physical flip, not a static side-by-side — the point isn't to
   compare two designs sitting next to each other, it's for the same
   frame to actually become something else in front of you. */
.tvr-flip-frame {
  position: relative;
  aspect-ratio: 16 / 9;
  max-height: 460px;
  perspective: 2200px;
}

.tvr-flip-inner {
  position: relative;
  width: 100%;
  height: 100%;
  transform-style: preserve-3d;
  transition: transform 0.7s cubic-bezier(0.65, 0, 0.35, 1);
  border-radius: var(--radius);
  box-shadow: var(--shadow-float);
}

.tvr-flip-inner.is-flipped {
  transform: rotateY(180deg);
}

@media (prefers-reduced-motion: reduce) {
  .tvr-flip-inner {
    transition: none;
  }
}

.tvr-face {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  border-radius: var(--radius);
  overflow: hidden;
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
}

.tvr-face-template {
  background: linear-gradient(160deg, #fff6d9 0%, #ffe1e8 55%, #d9f0ff 100%);
}

.tvr-demo-template {
  text-align: center;
  width: 100%;
}

/* This is a real client's own identity, not a Grid & Frame reskin —
   deliberately not one CSS custom property from the site's own Bold
   Signal palette or type stack appears below. */
.tvr-face-real {
  background-color: #122a22;
  align-items: flex-end;
  transform: rotateY(180deg);
}

/* A real graphic mark, not a decoration so faint it doesn't register — a
   solid diagonal wedge bleeding off the corner, the kind of committed
   brand gesture a generic template never bothers with. */
.tvr-face-real::before {
  content: '';
  position: absolute;
  top: 0;
  right: 0;
  width: 220px;
  height: 220px;
  background: #f4b942;
  clip-path: polygon(100% 0, 100% 100%, 0 0);
  pointer-events: none;
}

.tvr-demo-real,
.tvr-demo-template {
  padding: clamp(24px, 5vw, 56px);
  max-width: 640px;
}

.tvr-demo-real {
  position: relative;
  z-index: 1;
}

.tvr-demo-tag {
  display: inline-block;
  font-family: 'Work Sans', -apple-system, sans-serif;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: #f4b942;
  padding-bottom: 0.5em;
  border-bottom: 2px solid #f4b942;
  margin-bottom: 1.1em;
}

.tvr-demo-headline {
  font-family: 'Zilla Slab', Georgia, 'Times New Roman', serif;
  font-weight: 700;
  font-size: clamp(2.1rem, 5.6vw, 3.5rem);
  line-height: 1.02;
  letter-spacing: -0.01em;
  color: #f6f1e4;
  margin: 0 0 0.4em;
}

.tvr-demo-copy {
  font-family: 'Work Sans', -apple-system, sans-serif;
  color: #b9c9c0;
  font-size: 0.94rem;
  margin: 0 0 1.3em;
  max-width: 34ch;
}

.tvr-demo-btn-real {
  display: inline-block;
  background: #f4b942;
  color: #122a22;
  font-family: 'Work Sans', -apple-system, sans-serif;
  font-weight: 700;
  font-size: 0.9rem;
  padding: 0.85em 1.7em;
  border-radius: 0;
  box-shadow: 6px 6px 0 0 #0a1a15;
}

/* templated (deliberately generic) side */
.tvr-demo-badge {
  display: inline-block;
  background: #ffe135;
  color: #d32f2f;
  font-family: Arial, Helvetica, sans-serif;
  font-size: 0.78rem;
  font-weight: 700;
  text-transform: uppercase;
  padding: 0.5em 1.1em;
  border: 2px dashed #d32f2f;
  border-radius: 999px;
  box-shadow: 0 4px 10px rgba(0, 0, 0, 0.25);
  transform: rotate(-4deg);
  margin-bottom: 1.1em;
}

.tvr-demo-headline-t {
  font-family: 'Times New Roman', Times, serif;
  font-weight: 700;
  font-style: italic;
  font-size: clamp(1.3rem, 3.4vw, 2.1rem);
  color: #1a3d8f;
  text-shadow: 2px 2px 3px rgba(0, 0, 0, 0.3), -1px -1px 0 rgba(255, 255, 255, 0.6);
  margin: 0 0 0.5em;
}

.tvr-demo-copy-t {
  font-family: Arial, Helvetica, sans-serif;
  color: #6b6255;
  font-size: 0.92rem;
  line-height: 1.75;
  text-align: justify;
  margin: 0 auto 1.3em;
  max-width: 30ch;
}

.tvr-demo-btn-t {
  display: inline-block;
  background: linear-gradient(180deg, #7ed957 0%, #4caf50 50%, #3d8b40 100%);
  color: #fff;
  font-family: Arial, Helvetica, sans-serif;
  font-weight: 700;
  font-size: 0.84rem;
  text-transform: uppercase;
  padding: 0.9em 1.5em;
  border: 1px solid #2d6b30;
  border-radius: 999px;
  text-shadow: 0 1px 1px rgba(0, 0, 0, 0.4);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.5), 0 4px 10px rgba(0, 0, 0, 0.3);
}

.tvr-demo-dots {
  display: flex;
  gap: 6px;
  margin-top: 1.6em;
  justify-content: center;
}

.tvr-demo-dots span {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #d8d0c0;
}

.tvr-demo-dots span:first-child {
  background: #c1592f;
}

.tvr-toggle-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  margin: 20px auto 0;
  background: none;
  border: none;
  padding: 8px;
  cursor: pointer;
  font-family: var(--font-mono);
  font-size: 0.8rem;
}

.tvr-toggle-label {
  color: var(--ink-faint);
  transition: color 0.2s ease;
}

.tvr-toggle-btn[aria-pressed="false"] .tvr-toggle-label-off,
.tvr-toggle-btn[aria-pressed="true"] .tvr-toggle-label-on {
  color: var(--ink);
  font-weight: 600;
}

.tvr-toggle-track {
  position: relative;
  width: 46px;
  height: 26px;
  border-radius: var(--radius-pill);
  background: var(--line);
  transition: background 0.3s ease;
  flex: none;
}

.tvr-toggle-btn[aria-pressed="true"] .tvr-toggle-track {
  background: var(--accent);
}

.tvr-toggle-knob {
  position: absolute;
  top: 3px;
  left: 3px;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: var(--ink);
  transition: transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1), background 0.3s ease;
}

.tvr-toggle-btn[aria-pressed="true"] .tvr-toggle-knob {
  background: var(--accent-ink);
  transform: translateX(20px);
}

@media (max-width: 620px) {
  .tvr-flip-frame {
    aspect-ratio: 3 / 4;
  }

  .tvr-demo-real,
  .tvr-demo-template {
    padding: 20px;
  }
}
