/* ==========================================================================
   Graham Cloud Services — shared stylesheet

   Colour discipline (the one rule that holds this design together):
     --signal (teal)  = action, or a fact the visitor can verify themselves.
     --cobalt (blue)  = structure, depth, and secondary emphasis.
   Teal never appears as decoration. When it shows up, something is either
   clickable or true. That is what makes the hero proof panel read as evidence
   rather than ornament.
   ========================================================================== */

@import url("/fonts/fonts.css?v=2");

:root {
  /* Surfaces — blue-shifted rather than neutral black, so the page reads as
     depth instead of void. */
  --ink: #06090f;
  --slate: #0b1017;
  --slate-2: #111823;
  --slate-3: #18212e;
  --line: #1b2533;
  --line-lit: #2b3a4d;

  --signal: #2ee6bd;
  --signal-soft: rgba(46, 230, 189, 0.12);
  --signal-edge: rgba(46, 230, 189, 0.32);
  --signal-glow: rgba(46, 230, 189, 0.35);
  --signal-ink: #04231e;

  --cobalt: #5b8cff;
  --cobalt-soft: rgba(91, 140, 255, 0.12);

  --text: #edf1f6;
  --text-2: #aab5c4;
  --muted: #78849a;

  --display: "Space Grotesk", "Segoe UI", sans-serif;
  --body: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;

  --max-width: 1120px;
  --gutter: 1.5rem;
  --radius: 12px;

  /* Vertical rhythm — one scale, used everywhere. */
  --band-y: 7rem;
  --stack: 1.25rem;

  /* Motion — one curve, three speeds. Every animation on the site uses
     these; tune the whole site's feel from here. */
  --ease-out: cubic-bezier(0.2, 0.7, 0.2, 1);
  --t-fast: 0.25s;
  --t-med: 0.7s;
  --t-slow: 0.9s;
}

* {
  box-sizing: border-box;
}

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

body {
  margin: 0;
  font-family: var(--body);
  font-size: 1rem;
  color: var(--text);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  background-color: var(--ink);
}

a {
  color: var(--signal);
  text-decoration: none;
}

a:hover {
  text-decoration: underline;
}

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

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

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

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--signal);
  color: var(--signal-ink);
  padding: 0.7rem 1.1rem;
  font-weight: 500;
  z-index: 200;
}

.skip-link:focus {
  left: 0;
  text-decoration: none;
}

/* --------------------------------------------------------------------------
   Type
   -------------------------------------------------------------------------- */

h1,
h2,
h3,
h4 {
  font-family: var(--display);
  font-weight: 700;
  letter-spacing: -0.03em;
  line-height: 1.05;
  margin: 0;
}

h1 {
  font-size: clamp(2.25rem, 4.4vw, 3.4rem);
  letter-spacing: -0.035em;
  line-height: 1.03;
}

h2 {
  font-size: clamp(1.95rem, 3.8vw, 2.85rem);
}

h3 {
  font-weight: 500;
  font-size: 1.18rem;
  letter-spacing: -0.018em;
  line-height: 1.28;
}

h4 {
  font-weight: 500;
  font-size: 1.05rem;
  letter-spacing: -0.015em;
}

p {
  margin: 0;
}

strong {
  color: var(--text);
  font-weight: 500;
}

/* A single, restrained section opener. Used sparingly — not on every band. */

.kicker {
  font-family: var(--mono);
  font-size: 0.7rem;
  font-weight: 500;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 1rem;
}

.band-head {
  max-width: 34rem;
  margin-bottom: 3.25rem;
}

.band-head .lede {
  color: var(--text-2);
  margin-top: 1.1rem;
  font-size: 1.06rem;
  line-height: 1.65;
}

.band-head--wide {
  max-width: 44rem;
}

/* Heading left, supporting text right. Used on alternate bands so the page
   doesn't settle into one repeated left-aligned rhythm. */
.band-head--split {
  max-width: none;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1rem 4rem;
  align-items: end;
}

.band-head--split .kicker {
  grid-column: 1;
  margin-bottom: 0.5rem;
}

.band-head--split h2 {
  grid-column: 1;
  max-width: 15ch;
}

.band-head--split .lede {
  grid-column: 2;
  margin-top: 0;
  max-width: 32rem;
}

/* Content awaiting a real value from the site owner. Deliberately loud:
   a visible placeholder is safer than a plausible invention. */

.todo {
  color: #f5b544;
  border-bottom: 1px dashed currentColor;
  font-style: normal;
}

/* --------------------------------------------------------------------------
   Header / nav
   -------------------------------------------------------------------------- */

.site-header {
  background: rgba(6, 9, 15, 0.78);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--line);
  position: sticky;
  top: 0;
  z-index: 100;
}

.nav-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.95rem var(--gutter);
  max-width: var(--max-width);
  margin: 0 auto;
}

.brand {
  font-family: var(--display);
  font-size: 1rem;
  font-weight: 700;
  letter-spacing: -0.025em;
  color: var(--text);
  display: flex;
  align-items: center;
  gap: 0.6rem;
  flex-shrink: 0;
  transition: color 0.15s ease;
}

.brand:hover {
  text-decoration: none;
  color: var(--signal);
}

.brand-mark {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--signal);
  box-shadow: 0 0 0 3px var(--signal-soft);
  flex-shrink: 0;
}

.nav-toggle {
  display: none;
  background: none;
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 0.45rem 0.6rem;
  cursor: pointer;
}

.nav-toggle-bar {
  display: block;
  width: 18px;
  height: 1.5px;
  background: var(--text);
  margin: 4px 0;
}

.nav-links {
  display: flex;
  align-items: center;
  gap: 1.9rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

.nav-links a {
  color: var(--muted);
  font-size: 0.89rem;
  font-weight: 500;
  transition: color 0.15s ease;
  position: relative;
}

.nav-links a:hover,
.nav-links a.active {
  color: var(--text);
  text-decoration: none;
}

.nav-links a.active {
  color: var(--signal);
}

.nav-links a::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -4px;
  height: 2px;
  background: var(--signal);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform var(--t-fast) var(--ease-out);
}

.nav-links a:hover::after,
.nav-links a:focus-visible::after,
.nav-links a.active::after {
  transform: scaleX(1);
}

/* The mobile sheet and the CTA button don't take the underline. */
.nav-cta a::after {
  display: none;
}

@media (max-width: 768px) {
  .nav-links a::after {
    display: none;
  }
}

.nav-cta {
  margin-left: 0.4rem;
}

/* --------------------------------------------------------------------------
   Buttons
   -------------------------------------------------------------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding: 0.8rem 1.5rem;
  border-radius: 9px;
  font-family: var(--body);
  font-weight: 500;
  font-size: 0.92rem;
  line-height: 1.2;
  cursor: pointer;
  border: 1px solid transparent;
  transition: background var(--t-fast) var(--ease-out),
    border-color var(--t-fast) var(--ease-out),
    color var(--t-fast) var(--ease-out),
    transform var(--t-fast) var(--ease-out),
    box-shadow var(--t-fast) var(--ease-out);
}

.btn:hover {
  text-decoration: none;
}

.btn-primary {
  background: var(--signal);
  color: var(--signal-ink);
}

.btn-primary:hover {
  background: #55f0cd;
  transform: translateY(-2px) scale(1.03);
  box-shadow: 0 8px 24px var(--signal-glow);
}

.btn-outline {
  background: transparent;
  color: var(--text);
  border-color: var(--line-lit);
}

.btn-outline:hover {
  border-color: var(--signal-edge);
  color: var(--signal);
  background: var(--signal-soft);
  transform: translateY(-1px);
}

.btn-small {
  padding: 0.55rem 1.05rem;
  font-size: 0.85rem;
}

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

/* Text link with a moving arrow — used to leave a band. */

.arrow-link {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  font-weight: 500;
  font-size: 0.94rem;
}

.arrow-link::after {
  content: "→";
  transition: transform 0.2s ease;
}

.arrow-link:hover {
  text-decoration: none;
}

.arrow-link:hover::after {
  transform: translateX(4px);
}

/* --------------------------------------------------------------------------
   Bands (page sections)

   Class-based rather than element-based, so modifiers never lose a
   specificity fight with the base rule.
   -------------------------------------------------------------------------- */

.band {
  padding: var(--band-y) 0;
  position: relative;
}

.band--tight {
  padding: 4.5rem 0;
}

.band--edge {
  border-top: 1px solid var(--line);
}

.band--raised {
  background: var(--slate);
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}

/* --------------------------------------------------------------------------
   Hero — asymmetric. Claim on the left, evidence on the right.
   -------------------------------------------------------------------------- */

.hero {
  position: relative;
  overflow: hidden;
  padding: 5.5rem 0 4.5rem;
  border-bottom: 1px solid var(--line);
  background:
    radial-gradient(80% 60% at 78% 8%, rgba(91, 140, 255, 0.13), transparent 60%),
    radial-gradient(70% 55% at 12% 30%, rgba(46, 230, 189, 0.09), transparent 62%),
    linear-gradient(180deg, #0a121a 0%, var(--ink) 78%);
}

/* Faint engineering grid — structure, not sparkle. */
.hero::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(to right, rgba(255, 255, 255, 0.028) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(255, 255, 255, 0.028) 1px, transparent 1px);
  background-size: 64px 64px;
  mask-image: radial-gradient(120% 90% at 50% 0%, #000 10%, transparent 72%);
  -webkit-mask-image: radial-gradient(120% 90% at 50% 0%, #000 10%, transparent 72%);
  pointer-events: none;
}

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

.hero-grid {
  display: grid;
  grid-template-columns: 1.06fr 0.94fr;
  gap: 4rem;
  align-items: center;
}

.hero-claim h1 {
  margin-bottom: 1.5rem;
}

.hero-claim h1 em {
  font-style: normal;
  color: var(--signal);
}

.hero-sub {
  font-size: 1.12rem;
  color: var(--text-2);
  max-width: 30rem;
  margin-bottom: 2rem;
  line-height: 1.62;
}

.hero-actions {
  display: flex;
  gap: 0.75rem;
  flex-wrap: wrap;
  margin-bottom: 2.25rem;
}

.hero-note {
  font-size: 0.88rem;
  color: var(--muted);
  display: flex;
  align-items: center;
  gap: 0.55rem;
}

.hero-note .dot {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--signal);
  flex-shrink: 0;
}

/* --------------------------------------------------------------------------
   SIGNATURE: the live proof panel.

   Every number in here is measured in the visitor's own browser from the
   Performance API on page load. Nothing is hardcoded, which is the whole
   point — the site is the portfolio.
   -------------------------------------------------------------------------- */

.proof {
  background: linear-gradient(180deg, var(--slate-2) 0%, #0a0f16 100%);
  border: 1px solid var(--line);
  border-radius: 14px;
  overflow: hidden;
  box-shadow: 0 24px 60px -30px rgba(0, 0, 0, 0.9);
}

.proof-head {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.85rem 1.15rem;
  border-bottom: 1px solid var(--line);
  background: rgba(255, 255, 255, 0.018);
}

.proof-live {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  font-family: var(--mono);
  font-size: 0.66rem;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--signal);
}

.proof-pulse {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--signal);
  box-shadow: 0 0 0 0 var(--signal-edge);
  animation: pulse 2.4s ease-out infinite;
}

@keyframes pulse {
  0% { box-shadow: 0 0 0 0 var(--signal-edge); }
  70% { box-shadow: 0 0 0 7px rgba(46, 230, 189, 0); }
  100% { box-shadow: 0 0 0 0 rgba(46, 230, 189, 0); }
}

.proof-title {
  font-family: var(--mono);
  font-size: 0.72rem;
  color: var(--muted);
  margin-left: auto;
  letter-spacing: 0.02em;
}

.proof-rows {
  padding: 0.35rem 0;
}

.proof-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.72rem 1.15rem;
}

.proof-row + .proof-row {
  border-top: 1px solid rgba(255, 255, 255, 0.035);
}

.proof-label {
  font-size: 0.87rem;
  color: var(--text-2);
}

.proof-value {
  font-family: var(--mono);
  font-size: 1.28rem;
  font-weight: 500;
  color: var(--signal);
  letter-spacing: -0.02em;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

.proof-value .unit {
  font-size: 0.74rem;
  color: var(--muted);
  margin-left: 0.18rem;
  letter-spacing: 0.04em;
}

/* Measuring state, before the Performance API reports. */
.proof-value[data-pending="true"] {
  color: var(--muted);
}

/* Shown only by the <noscript> block on the homepage. */
.proof-noscript {
  display: none;
  padding: 1.1rem 1.15rem;
  font-size: 0.9rem;
  color: var(--text-2);
  line-height: 1.6;
}

.proof-foot {
  border-top: 1px solid var(--line);
  padding: 0.95rem 1.15rem 1.05rem;
  background: rgba(0, 0, 0, 0.25);
}

.proof-stack {
  font-family: var(--mono);
  font-size: 0.7rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-2);
  margin-bottom: 0.45rem;
}

.proof-check {
  font-size: 0.79rem;
  color: var(--muted);
  line-height: 1.5;
}

/* --------------------------------------------------------------------------
   Credentials bar — full-bleed done properly.

   The old version had a full-width background with 1140px-wide dividers,
   which left the rules ending in mid-air. Here the background and the
   divided track are the same element, so the seams always line up.
   -------------------------------------------------------------------------- */

.creds {
  border-bottom: 1px solid var(--line);
  background: var(--slate);
}

.creds-inner {
  max-width: var(--max-width);
  margin: 0 auto;
  padding: 0 var(--gutter);
  display: grid;
  grid-template-columns: repeat(3, 1fr);
}

.cred {
  padding: 1.5rem 1.5rem 1.5rem 0;
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
}

.cred + .cred {
  padding-left: 1.75rem;
  border-left: 1px solid var(--line);
}

.cred-value {
  font-family: var(--display);
  font-size: 1.32rem;
  font-weight: 700;
  letter-spacing: -0.025em;
  color: var(--text);
}

.cred-label {
  font-size: 0.85rem;
  color: var(--muted);
  line-height: 1.45;
}

/* --------------------------------------------------------------------------
   Service cards — information, not stock photography.
   -------------------------------------------------------------------------- */

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

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

.card {
  background: var(--slate-2);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 1.6rem 1.5rem 1.7rem;
  display: flex;
  flex-direction: column;
  transition: border-color var(--t-fast) var(--ease-out),
    background var(--t-fast) var(--ease-out),
    transform var(--t-fast) var(--ease-out),
    box-shadow var(--t-fast) var(--ease-out);
}

.card:hover {
  border-color: var(--signal-edge);
  background: var(--slate-3);
  transform: translateY(-4px);
  box-shadow: 0 14px 34px rgba(0, 0, 0, 0.5), 0 0 0 1px var(--signal-edge);
}

.card-icon {
  width: 34px;
  height: 34px;
  border-radius: 9px;
  display: grid;
  place-items: center;
  background: var(--cobalt-soft);
  border: 1px solid rgba(91, 140, 255, 0.22);
  margin-bottom: 1.15rem;
}

.card-icon svg {
  width: 17px;
  height: 17px;
  stroke: var(--cobalt);
  fill: none;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.card h3 {
  margin-bottom: 0.55rem;
}

.card > p {
  color: var(--text-2);
  font-size: 0.94rem;
  line-height: 1.6;
}

.card-list {
  list-style: none;
  margin: 1.15rem 0 0;
  padding: 1.15rem 0 0;
  border-top: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.card-list li {
  font-size: 0.86rem;
  color: var(--muted);
  padding-left: 1.1rem;
  position: relative;
}

.card-list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.55em;
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: var(--line-lit);
}

/* --------------------------------------------------------------------------
   Process — the one place numbering is honest, because the steps really
   do happen in order.
   -------------------------------------------------------------------------- */

.steps {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 0;
  border-top: 1px solid var(--line);
}

.step {
  padding: 1.9rem 1.6rem 1.9rem 0;
  position: relative;
}

.step + .step {
  padding-left: 1.6rem;
  border-left: 1px solid var(--line);
}

.step-n {
  font-family: var(--mono);
  font-size: 0.7rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  color: var(--signal);
  display: block;
  margin-bottom: 0.85rem;
}

.step h3 {
  margin-bottom: 0.5rem;
}

.step p {
  color: var(--muted);
  font-size: 0.9rem;
  line-height: 1.58;
}

/* --------------------------------------------------------------------------
   Checklist — "what every build includes"
   -------------------------------------------------------------------------- */

.checklist {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0.1rem 2.5rem;
}

.checklist li {
  display: flex;
  align-items: flex-start;
  gap: 0.7rem;
  padding: 0.78rem 0;
  border-bottom: 1px solid var(--line);
  font-size: 0.93rem;
  color: var(--text-2);
}

.checklist svg {
  width: 15px;
  height: 15px;
  flex-shrink: 0;
  margin-top: 0.24rem;
  stroke: var(--signal);
  fill: none;
  stroke-width: 2.2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* --------------------------------------------------------------------------
   Spec table — plain facts, mono-set
   -------------------------------------------------------------------------- */

.spec {
  border-top: 1px solid var(--line);
}

.spec-row {
  display: grid;
  grid-template-columns: 13rem 1fr;
  gap: 1.5rem;
  padding: 1.1rem 0;
  border-bottom: 1px solid var(--line);
  align-items: baseline;
}

.spec-key {
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--muted);
}

.spec-val {
  color: var(--text-2);
  font-size: 0.95rem;
  line-height: 1.6;
}

.spec-val strong {
  color: var(--text);
}

/* --------------------------------------------------------------------------
   Pricing
   -------------------------------------------------------------------------- */

.price-group + .price-group {
  margin-top: 3.75rem;
}

.price-group-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  padding-bottom: 0.9rem;
  border-bottom: 1px solid var(--line-lit);
  margin-bottom: 0.25rem;
}

.price-group-head h3 {
  font-size: 1.3rem;
  font-weight: 700;
}

.price-group-note {
  font-family: var(--mono);
  font-size: 0.7rem;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--muted);
}

.price-row {
  display: grid;
  grid-template-columns: 1.05fr 1.5fr auto 7rem;
  align-items: center;
  gap: 1.5rem;
  padding: 1.4rem 0.75rem;
  margin: 0 -0.75rem;
  border-bottom: 1px solid var(--line);
  border-radius: 8px;
  transition: background 0.2s ease;
}

.price-row:hover {
  background: rgba(255, 255, 255, 0.02);
}

.price-row h4 {
  margin: 0;
}

.price-row .desc {
  color: var(--muted);
  font-size: 0.91rem;
  line-height: 1.55;
}

.price-tag {
  font-family: var(--mono);
  font-size: 1.4rem;
  font-weight: 500;
  color: var(--text);
  white-space: nowrap;
  letter-spacing: -0.025em;
  font-variant-numeric: tabular-nums;
  justify-self: end;
}

.price-tag span {
  font-size: 0.74rem;
  color: var(--muted);
  letter-spacing: 0.06em;
}

.price-row .btn {
  white-space: nowrap;
  justify-self: stretch;
}

.price-foot {
  margin-top: 1.5rem;
  font-size: 0.89rem;
  color: var(--muted);
  line-height: 1.6;
}

/* --------------------------------------------------------------------------
   FAQ — objection handling, in the visitor's own words
   -------------------------------------------------------------------------- */

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

.faq details {
  border-bottom: 1px solid var(--line);
}

.faq summary {
  list-style: none;
  cursor: pointer;
  padding: 1.35rem 2.5rem 1.35rem 0;
  position: relative;
  font-family: var(--display);
  font-weight: 500;
  font-size: 1.05rem;
  letter-spacing: -0.015em;
  color: var(--text);
  transition: color 0.15s ease;
}

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

.faq summary:hover {
  color: var(--signal);
}

.faq summary::after {
  content: "";
  position: absolute;
  right: 0.4rem;
  top: 50%;
  width: 9px;
  height: 9px;
  border-right: 1.6px solid var(--muted);
  border-bottom: 1.6px solid var(--muted);
  transform: translateY(-70%) rotate(45deg);
  transition: transform 0.22s ease, border-color 0.22s ease;
}

.faq details[open] summary::after {
  transform: translateY(-30%) rotate(225deg);
  border-color: var(--signal);
}

.faq-body {
  padding: 0 3rem 1.5rem 0;
  color: var(--text-2);
  font-size: 0.96rem;
  line-height: 1.68;
  max-width: 46rem;
}

/* --------------------------------------------------------------------------
   About
   -------------------------------------------------------------------------- */

.about-layout {
  display: grid;
  grid-template-columns: 0.8fr 1.2fr;
  gap: 3.5rem;
  align-items: start;
}

.about-photo {
  border-radius: var(--radius);
  overflow: hidden;
  border: 1px solid var(--line);
  aspect-ratio: 4 / 5;
  background: var(--slate-2);
}

/* Heavily desaturated on purpose: the current image is stock, and this keeps
   it quiet until a real photograph replaces it. Drop the filter then. */
.about-photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: grayscale(0.9) contrast(1.05) brightness(0.9);
}

.about-lede {
  font-family: var(--display);
  font-weight: 500;
  font-size: 1.45rem;
  line-height: 1.38;
  letter-spacing: -0.022em;
  margin-bottom: 2rem;
}

.about-block + .about-block {
  margin-top: 1.6rem;
}

.about-block h3 {
  margin-bottom: 0.45rem;
}

.about-block p {
  color: var(--text-2);
  line-height: 1.68;
}

/* --------------------------------------------------------------------------
   Forms
   -------------------------------------------------------------------------- */

.form-field {
  margin-bottom: 1.1rem;
  display: flex;
  flex-direction: column;
}

.form-field label {
  font-size: 0.86rem;
  font-weight: 500;
  color: var(--text-2);
  margin-bottom: 0.45rem;
}

.form-field .req {
  color: var(--muted);
  font-weight: 400;
}

.form-field input,
.form-field select,
.form-field textarea {
  background: var(--ink);
  border: 1px solid var(--line-lit);
  border-radius: 9px;
  padding: 0.78rem 0.9rem;
  color: var(--text);
  font-family: var(--body);
  font-size: 0.95rem;
  width: 100%;
  transition: border-color var(--t-fast) var(--ease-out),
    box-shadow var(--t-fast) var(--ease-out);
}

.form-field textarea {
  resize: vertical;
  min-height: 9rem;
}

.form-field select {
  appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, var(--muted) 50%),
    linear-gradient(135deg, var(--muted) 50%, transparent 50%);
  background-position: calc(100% - 18px) calc(50% + 1px),
    calc(100% - 13px) calc(50% + 1px);
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  padding-right: 2.4rem;
}

.form-field input::placeholder,
.form-field textarea::placeholder {
  color: #55606f;
}

.form-field input:focus,
.form-field select:focus,
.form-field textarea:focus {
  outline: none;
  border-color: var(--signal);
  box-shadow: 0 0 0 3px var(--signal-soft);
}

.form-field input:focus-visible,
.form-field select:focus-visible,
.form-field textarea:focus-visible {
  outline: 2px solid var(--signal);
  outline-offset: 2px;
}

.form-hint {
  font-size: 0.82rem;
  color: var(--muted);
  margin-top: 0.4rem;
}

.form-foot {
  display: flex;
  align-items: center;
  gap: 1rem;
  flex-wrap: wrap;
  margin-top: 1.4rem;
}

.form-foot p {
  font-size: 0.84rem;
  color: var(--muted);
}

/* Honeypot — off-screen but not display:none, so bots still fill it. */
.hp-field {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.contact-layout {
  display: grid;
  grid-template-columns: 1.3fr 1fr;
  gap: 3.5rem;
  align-items: start;
}

.side-card {
  background: var(--slate-2);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 1.6rem;
}

.side-card + .side-card {
  margin-top: 1rem;
}

.side-card h3 {
  margin-bottom: 0.55rem;
}

.side-card p {
  color: var(--text-2);
  font-size: 0.93rem;
  line-height: 1.62;
}

.side-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.7rem;
}

.side-list li {
  display: flex;
  gap: 0.65rem;
  align-items: flex-start;
  font-size: 0.92rem;
  color: var(--text-2);
}

.side-list svg {
  width: 15px;
  height: 15px;
  flex-shrink: 0;
  margin-top: 0.22rem;
  stroke: var(--signal);
  fill: none;
  stroke-width: 2.2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.contact-email {
  font-family: var(--mono);
  font-size: 0.95rem;
  display: inline-block;
  margin-top: 1rem;
  padding-top: 1rem;
  border-top: 1px solid var(--line);
  width: 100%;
  word-break: break-all;
}

/* --------------------------------------------------------------------------
   CTA band
   -------------------------------------------------------------------------- */

.cta-band {
  text-align: center;
  border-top: 1px solid var(--line);
  background:
    radial-gradient(70% 130% at 50% 0%, rgba(46, 230, 189, 0.09) 0%, transparent 62%),
    linear-gradient(180deg, var(--slate) 0%, var(--ink) 100%);
}

.cta-band h2 {
  max-width: 17ch;
  margin: 0 auto 1rem;
}

.cta-band .lede {
  color: var(--text-2);
  max-width: 40ch;
  margin: 0 auto 2rem;
  font-size: 1.04rem;
}

.cta-actions {
  display: flex;
  gap: 0.75rem;
  justify-content: center;
  flex-wrap: wrap;
}

/* --------------------------------------------------------------------------
   Footer
   -------------------------------------------------------------------------- */

.site-footer {
  border-top: 1px solid var(--line);
  padding: 3rem 0 2.5rem;
  color: var(--muted);
  font-size: 0.87rem;
  background: var(--slate);
}

.footer-top {
  max-width: var(--max-width);
  margin: 0 auto;
  padding: 0 var(--gutter) 2rem;
  display: grid;
  grid-template-columns: 1.4fr 1fr 1fr;
  gap: 2.5rem;
}

.footer-brand .brand {
  margin-bottom: 0.8rem;
}

.footer-brand p {
  max-width: 26rem;
  line-height: 1.6;
}

.footer-col h4 {
  font-family: var(--mono);
  font-size: 0.68rem;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--text-2);
  margin-bottom: 0.9rem;
}

.footer-col ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
}

.footer-col a {
  color: var(--muted);
  font-size: 0.88rem;
}

.footer-col a:hover {
  color: var(--text);
  text-decoration: none;
}

.footer-inner {
  max-width: var(--max-width);
  margin: 0 auto;
  padding: 1.6rem var(--gutter) 0;
  border-top: 1px solid var(--line);
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
  flex-wrap: wrap;
}

.footer-inner .mono {
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

/* --------------------------------------------------------------------------
   Reduced motion
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  .proof-pulse {
    animation: none;
  }

  .btn,
  .card,
  .arrow-link::after,
  .faq summary::after,
  .nav-links a::after,
  .nav-links {
    transition: none;
  }

  .btn-primary:hover,
  .btn-outline:hover,
  .card:hover {
    transform: none;
  }

  /* Motion system: kill every entrance and reveal in one place. */
  .js .hero-claim > *,
  .js .proof,
  .js .band-head,
  .hero-claim h1 .w,
  .js main > .band:first-of-type .kicker,
  .js main > .band:first-of-type h2,
  .js main > .band:first-of-type .lede,
  .js main > .band:first-of-type .cta-actions {
    animation: none !important;
    opacity: 1 !important;
    transform: none !important;
    filter: none !important;
  }

  * {
    animation-timeline: initial !important;
  }
}

/* --------------------------------------------------------------------------
   Responsive
   -------------------------------------------------------------------------- */

@media (max-width: 1000px) {
  .hero-grid {
    grid-template-columns: 1fr;
    gap: 3rem;
  }

  .hero-sub {
    max-width: 34rem;
  }

  .proof {
    max-width: 30rem;
  }

  .steps {
    grid-template-columns: repeat(2, 1fr);
  }

  .step:nth-child(odd) {
    padding-left: 0;
    border-left: 0;
  }

  .step:nth-child(n + 3) {
    border-top: 1px solid var(--line);
  }

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

  .band-head--split {
    grid-template-columns: 1fr;
    gap: 1rem;
    align-items: start;
  }

  .band-head--split h2,
  .band-head--split .lede {
    grid-column: 1;
    max-width: 34rem;
  }

  .contact-layout,
  .about-layout {
    grid-template-columns: 1fr;
    gap: 2.5rem;
  }

  .about-photo {
    max-width: 20rem;
  }

  .footer-top {
    grid-template-columns: 1fr 1fr;
  }

  .footer-brand {
    grid-column: 1 / -1;
  }
}

@media (max-width: 860px) {
  :root {
    --band-y: 4.75rem;
  }

  .nav-toggle {
    display: block;
  }

  .nav-links {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    background: var(--ink);
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    max-height: 0;
    overflow: hidden;
    transition: max-height var(--t-fast) var(--ease-out);
    border-bottom: 1px solid var(--line);
  }

  .nav-links.open {
    max-height: 24rem;
  }

  .nav-links li {
    border-top: 1px solid var(--line);
  }

  .nav-links a {
    display: block;
    padding: 0.9rem var(--gutter);
  }

  .nav-cta {
    margin: 0;
  }

  .nav-links .btn {
    border-radius: 0;
    border: 0;
    justify-content: flex-start;
  }

  .grid-3,
  .grid-2 {
    grid-template-columns: 1fr;
  }

  .creds-inner {
    grid-template-columns: 1fr;
  }

  .cred {
    padding: 1.15rem 0;
  }

  .cred + .cred {
    padding-left: 0;
    border-left: 0;
    border-top: 1px solid var(--line);
  }

  .price-row {
    grid-template-columns: 1fr auto;
    gap: 0.4rem 1.25rem;
    align-items: start;
  }

  .price-row h4 {
    grid-column: 1;
  }

  .price-tag {
    grid-column: 2;
    grid-row: 1;
  }

  .price-row .desc {
    grid-column: 1 / -1;
    grid-row: 2;
  }

  .price-row .btn {
    grid-column: 1 / -1;
    grid-row: 3;
    justify-self: start;
    margin-top: 0.7rem;
  }

  .spec-row {
    grid-template-columns: 1fr;
    gap: 0.4rem;
  }

  .footer-inner {
    justify-content: center;
    text-align: center;
  }
}

@media (max-width: 620px) {
  .hero {
    padding: 3.5rem 0 3.5rem;
  }

  .steps {
    grid-template-columns: 1fr;
  }

  .step {
    padding: 1.5rem 0;
    border-left: 0;
  }

  .step + .step {
    padding-left: 0;
    border-left: 0;
    border-top: 1px solid var(--line);
  }

  .checklist {
    grid-template-columns: 1fr;
  }

  .about-lede {
    font-size: 1.22rem;
  }

  .footer-top {
    grid-template-columns: 1fr;
    gap: 2rem;
  }

  .faq-body {
    padding-right: 1rem;
  }
}

/* --------------------------------------------------------------------------
   Motion

   Entrances hide content only under html.js (set by one inline line in each
   page's head), so a no-JS visit shows everything immediately. Scroll
   reveals live inside @supports (animation-timeline: view()) — they are
   scrubbed by scroll position, not observer-fired, so scrolling fast just
   plays them faster; there is no blank-section failure mode. Browsers
   without support simply show a static page.
   -------------------------------------------------------------------------- */

/* Hero choreography — words first, then sub, actions, note. All gated on
   html.js; without JavaScript nothing here applies and the hero is simply
   visible. */

.hero-claim h1 .w {
  display: inline-block;
  opacity: 0;
  animation: word-in var(--t-med) var(--ease-out) forwards;
  animation-delay: calc(var(--w-i, 0) * 70ms);
}

.js .hero-claim .hero-sub,
.js .hero-claim .hero-actions,
.js .hero-claim .hero-note {
  opacity: 0;
  animation: rise-in var(--t-med) var(--ease-out) forwards;
}

.js .hero-claim .hero-sub     { animation-delay: 0.55s; }
.js .hero-claim .hero-actions { animation-delay: 0.75s; }
.js .hero-claim .hero-note    { animation-delay: 0.8s; }

@keyframes rise-in {
  from { opacity: 0; transform: translateY(18px); }
  to   { opacity: 1; transform: none; }
}

@keyframes word-in {
  from { opacity: 0; transform: translateY(0.6em) rotate(2deg); filter: blur(6px); }
  to   { opacity: 1; transform: none; filter: blur(0); }
}

@keyframes card-in {
  from { opacity: 0; transform: translateY(34px) scale(0.96); filter: blur(3px); }
  to   { opacity: 1; transform: none; filter: blur(0); }
}

@keyframes panel-in {
  from { opacity: 0; transform: translateY(24px) scale(0.96); }
  to   { opacity: 1; transform: none; }
}

.js .proof {
  opacity: 0;
  animation: panel-in var(--t-slow) var(--ease-out) 0.35s forwards;
}

/* Scroll-driven reveals. Scrubbed by scroll position (view-timeline), so
   fast scrolling plays them faster instead of leaving blanks. Browsers
   without support skip this whole block and show everything statically. */

@supports (animation-timeline: view()) {
  .band-head,
  .card,
  .step,
  .about-block,
  .side-card,
  .faq,
  .creds-inner > * {
    animation: card-in linear both;
    animation-timeline: view();
    animation-range: entry 0% entry 70%;
  }

  /* Stagger grid children so rows cascade instead of thudding in at once.
     view-timeline has no delay concept, so the stagger comes from shifting
     each child's range start. */
  .grid-2 > :nth-child(2n),
  .grid-3 > :nth-child(3n - 1),
  .steps > :nth-child(2n) {
    animation-range: entry 8% entry 78%;
  }

  .grid-3 > :nth-child(3n) {
    animation-range: entry 16% entry 86%;
  }

  /* First-band headers already have their own load entrance (see the
     page-header rules below) — on short viewports the scroll reveal would
     otherwise first-paint them mid-animation. */
  main > .band:first-of-type .band-head {
    animation: none;
  }

  /* Price tags land a beat after their row, with a small pop. Markup check:
     .price-tag is always a descendant of .price-row (services.html), never
     .card — targeting .price-row here, not the brief's literal .card,
     so the rule actually matches (see task-5-report.md). */
  .price-row .price-tag {
    animation: panel-in linear both;
    animation-timeline: view();
    animation-range: entry 15% entry 85%;
  }
}

/* Page headers on inner pages get the hero's stagger, without the word
   split. Gated on html.js like the hero. Inner pages use h2 (not h1) for
   their title — see markup check in task-4-report.md — so the selector
   targets h2 rather than the brief's literal h1. */
.js main > .band:first-of-type .kicker,
.js main > .band:first-of-type h2,
.js main > .band:first-of-type .lede,
.js main > .band:first-of-type .cta-actions {
  opacity: 0;
  animation: rise-in var(--t-med) var(--ease-out) forwards;
}

.js main > .band:first-of-type h2   { animation-delay: 0.12s; }
.js main > .band:first-of-type .lede { animation-delay: 0.28s; }
.js main > .band:first-of-type .cta-actions { animation-delay: 0.44s; }
