/* ==========================================================================
   CodeNova craft layer — loads after site.css and progressively refines it.

   Premise: the hero constellation stays exactly as it is. Everything below it
   is rebuilt to speak the same language — 1px lines, small bright nodes,
   sparse geometry on a single near-black ground. Structure carries the look;
   nothing glows, drifts or blurs.
   ========================================================================== */

/* ---------------------------------------------------------------- tokens */
:root {
  --font-text: 'Instrument Sans', ui-sans-serif, system-ui, -apple-system, sans-serif;
  --font-mark: 'Tektur', var(--font-text);

  /* one fluid engine, 360 -> 1440 */
  --fs--2: clamp(.75rem,   .729rem + .093vw, .8125rem);
  --fs--1: clamp(.875rem,  .854rem + .093vw, .9375rem);
  --fs-0:  clamp(1rem,     .979rem + .093vw, 1.0625rem);
  --fs-1:  clamp(1.125rem, 1.083rem + .185vw, 1.25rem);
  --fs-2:  clamp(1.25rem,  1.167rem + .370vw, 1.5rem);
  --fs-3:  clamp(1.5rem,   1.375rem + .556vw, 1.875rem);
  --fs-4:  clamp(1.875rem, 1.667rem + .926vw, 2.5rem);
  --fs-5:  clamp(2.375rem, 2.083rem + 1.296vw, 3.25rem);
  --fs-6:  clamp(2.75rem,  2.25rem + 2.222vw, 4.25rem);

  --lh-display: 1.06; --lh-tight: 1.15; --lh-snug: 1.35; --lh-body: 1.62;
  --track-xl: -.032em; --track-lg: -.022em; --track-caps: .14em;
  --measure: 66ch; --measure-tight: 52ch; --measure-wide: 74ch;

  --space-1: .25rem; --space-2: .5rem;  --space-3: .75rem; --space-4: 1rem;
  --space-5: 1.5rem; --space-6: 2rem;   --space-7: 3rem;   --space-8: 4rem;
  --pad-tight: clamp(2.75rem, 4vw, 3.75rem);
  --pad-base:  clamp(4.5rem, 7vw, 6rem);
  --pad-open:  clamp(6.5rem, 10vw, 9rem);
  --gutter: clamp(1.25rem, .75rem + 2.5vw, 2rem);
  --shell: 78rem;
  --tap: 2.75rem;

  /* surfaces — one ground, recesses instead of stripes */
  --surface-0: #030712;
  --surface-1: #0a1020;
  --surface-2: #111827;
  --surface-3: #1a2233;

  --text-1: #f3f4f6;
  --text-2: #d1d5db;
  --text-3: #9ca3af;
  --text-4: #9099ab;          /* replaces the failing #6b7280 — 6.19:1 */

  --line-1: rgba(156,163,175,.12);
  --line-2: rgba(156,163,175,.22);
  --line-3: rgba(156,163,175,.38);
  --line-field: #5a6675;      /* 3.03:1 — meets 1.4.11 */

  --accent-700: #1d4ed8; --accent-600: #2563eb;
  --accent-500: #3b82f6; --accent-400: #60a5fa;
  /* quoted verbatim from js/hero-particles.js so the static marks on the
     page and the moving marks in the hero are the same colours */
  --node-a: #3b82f6;   /* particle fill 1 */
  --node-b: #06b6d4;   /* particle fill 2 */
  --node-c: #93c5fd;   /* particle fill 3 — the headline accent */
  --link-near: #bfdbfe;
  --link-far:  #3b82f6;
  --cy-400: #06b6d4; --cy-300: #67e8f9;
  --focus: #7dd3fc;

  --r-xs: 4px; --r-sm: 8px; --r-md: 12px; --r-lg: 16px;

  --e1: 0 1px 2px rgba(2,6,23,.6);
  --e2: 0 2px 4px rgba(2,6,23,.5), 0 8px 16px -8px rgba(2,6,23,.7);
  --e3: 0 4px 8px rgba(2,6,23,.5), 0 16px 32px -12px rgba(2,6,23,.75);

  --dur-1: 120ms; --dur-2: 200ms;
  --ease-out: cubic-bezier(.2,.7,.2,1);
}

/* ------------------------------------------------------------------ base */
body {
  font-family: var(--font-text);
  font-size: var(--fs-0);
  line-height: var(--lh-body);
  color: var(--text-2);
  background: var(--surface-0);
  font-optical-sizing: auto;
  font-synthesis-weight: none;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

html { scroll-padding-top: 5.5rem; }

h1, h2, h3, h4 { font-family: var(--font-text); text-wrap: balance; }

.wordmark { font-family: var(--font-mark); letter-spacing: .01em; }

:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
::selection { background: rgba(6,182,212,.30); color: #fff; }

/* =====================================================================
   1. SINGLE GROUND — the zebra striping goes away.
   Every marketing section sits on --surface-0. Separation comes from a
   hairline and from rhythm, not from a change of darkness.
   ===================================================================== */
main section.bg-gray-900,
main section.bg-gray-950,
main header.bg-gray-950,
main div.bg-gray-900,
main div.bg-gray-950,
body.bg-gray-950 main > section,
body.bg-gray-950 main > header {
  background: var(--surface-0);
}

/* the Tailwind block borders go too — the hairline below replaces them */
main section.border-t { border-top: 0; }

/* every section after the first gets one drawn hairline, inset to the shell
   and weighted to the left, with a node at its origin. */
main > section + section,
main > div > section + section {
  position: relative;
}
main > section:not([class*="tools-"]) + section:not([class*="tools-"])::before,
main > div > section + section::before {
  content: '';
  position: absolute;
  top: 0;
  left: max(var(--gutter), calc(50% - var(--shell) / 2));
  right: max(var(--gutter), calc(50% - var(--shell) / 2));
  height: 1px;
  background: linear-gradient(90deg,
    rgba(59,130,246,.50) 0,
    rgba(59,130,246,.22) 12%,
    var(--line-1) 34%,
    transparent 78%);
  pointer-events: none;
}
main > section:not([class*="tools-"]) + section:not([class*="tools-"])::after,
main > div > section + section::after {
  content: '';
  position: absolute;
  top: -2px;
  left: max(var(--gutter), calc(50% - var(--shell) / 2));
  width: 5px; height: 5px;
  border-radius: 50%;
  background: var(--node-b);
  box-shadow: 0 0 0 3px rgba(6,182,212,.12);
  pointer-events: none;
}
/* the tools CTA draws its own top rule and node, so suppress the generic
   section rule on it and on whatever follows it */
main > section.tools-cta + section::before,
main > section.tools-cta + section::after,
main > section.tools-cta::before { display: none; }

/* one deliberate recess per page, applied by hand */
.band-recess {
  background: var(--surface-1);
  box-shadow: inset 0 1px 0 rgba(59,130,246,.20),
              inset 0 -1px 0 rgba(156,163,175,.07);
}

/* the section hairline: asymmetric, with a node at its left terminus.
   This is the constellation vocabulary expressed as structure. */
.rule-lead { position: relative; }
.rule-lead::before {
  content: '';
  position: absolute;
  top: 0;
  left: var(--gutter);
  right: var(--gutter);
  height: 1px;
  background: linear-gradient(90deg,
    rgba(59,130,246,.55) 0,
    rgba(59,130,246,.28) 14%,
    var(--line-1) 38%,
    transparent 72%);
}
.rule-lead::after {
  content: '';
  position: absolute;
  top: -2px;
  left: var(--gutter);
  width: 5px; height: 5px;
  border-radius: 50%;
  background: var(--node-b);
  box-shadow: 0 0 0 3px rgba(6,182,212,.12);
}

/* =====================================================================
   2. KILL LIST — the 2023 generated-landing-page effects.
   ===================================================================== */

/* drifting blurred blobs: gone, everywhere */
.hero-orb { display: none !important; }

/* clipped blue->cyan headline gradient: replaced by a solid brand tone.
   Keeps the accent the owner knows; drops the ornament everyone recognises. */
.text-gradient {
  background: none !important;
  -webkit-background-clip: border-box !important;
  background-clip: border-box !important;
  -webkit-text-fill-color: currentColor !important;
  color: var(--node-c) !important;
  font-weight: inherit;
}

/* glow-card: five simultaneous hover effects reduced to one honest one */
.glow-card::before,
.glow-card::after { display: none !important; }
.glow-card {
  position: relative;
  border: 1px solid var(--line-2);
  border-radius: var(--r-md);
  background: var(--surface-2);
  box-shadow: none;
  transition: border-color var(--dur-2) var(--ease-out),
              background-color var(--dur-2) var(--ease-out),
              transform var(--dur-2) var(--ease-out);
}
.glow-card:hover {
  transform: none;
  border-color: var(--line-3);
  background: var(--surface-3);
  box-shadow: none;
}
a.glow-card:hover { border-color: rgba(96,165,250,.55); }

/* glowing cyan bullet dots -> a drawn hairline marker */
.hero-assurances li::before {
  width: 14px; height: 1px;
  border-radius: 0;
  background: var(--accent-400);
  box-shadow: none;
}

/* =====================================================================
   3. TYPE — one scale, applied everywhere, no breakpoint patches.
   ===================================================================== */
.hero-title {
  font-size: var(--fs-6);
  line-height: var(--lh-display);
  letter-spacing: var(--track-xl);
  font-weight: 600;
  color: var(--text-1);
}
.page-hero h1 {
  font-size: var(--fs-5);
  line-height: var(--lh-display);
  letter-spacing: var(--track-lg);
  font-weight: 600;
}
.section-title {
  font-size: var(--fs-4);
  line-height: var(--lh-tight);
  letter-spacing: var(--track-lg);
  font-weight: 600;
  color: var(--text-1);
}
.hero-summary,
.section-summary,
.body-lead {
  font-size: var(--fs-1);
  line-height: var(--lh-body);
  color: var(--text-3);
  text-wrap: pretty;
}
.body-copy { color: var(--text-3); text-wrap: pretty; }

/* micro-labels: Tektur earns its keep here */
.section-eyebrow,
.service-kicker,
.tools-eyebrow {
  font-family: var(--font-mark);
  font-size: var(--fs--2);
  font-weight: 400;
  letter-spacing: var(--track-caps);
  color: var(--accent-400);
  text-transform: uppercase;
}

/* numerals are tabular wherever they are data */
.process-step > span,
.card-number,
.phase-heading > span {
  font-family: var(--font-mark);
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum' 1;
}

/* =====================================================================
   4. COMPOSITION — break the centred template.
   ===================================================================== */

/* section intros stop being centred and measure-locked at 760px */
.section-intro {
  max-width: 54ch;
  margin-inline: 0;
  margin-bottom: var(--section-gap, clamp(2.5rem, 5vw, 3.5rem));
  text-align: left;
}
.section-intro .section-summary { margin-inline: 0; max-width: 48ch; }

/* an opt-out for the few places centring is still right */
.section-intro.is-centred {
  max-width: 62ch;
  margin-inline: auto;
  text-align: center;
}
.section-intro.is-centred .section-summary { margin-inline: auto; }

/* three-tier vertical rhythm replaces one uniform pad */
.pad-tight { padding-block: var(--pad-tight); }
.pad-base  { padding-block: var(--pad-base); }
.pad-open  { padding-block: var(--pad-open); }

/* =====================================================================
   5. DETAIL — the small moves that read as craft.
   ===================================================================== */

/* the arrow glyph becomes a rule that extends on hover */
.card-link .cn-arrow,
.text-link .cn-arrow {
  display: inline-block;
  width: .9em; height: 1px;
  margin-left: .55em;
  vertical-align: .28em;
  background: currentColor;
  transition: width var(--dur-2) var(--ease-out);
}
a:hover .card-link .cn-arrow,
.text-link:hover .cn-arrow { width: 1.5em; }

/* checklists lose the ✓ glyph for a hanging hairline */
.check-list li,
.contact-assurances li {
  position: relative;
  padding-left: 1.5rem;
  gap: 0;
}
.check-list li > .cn-tick,
.contact-assurances li > .cn-tick {
  position: absolute;
  left: 0; top: .62em;
  width: .6rem; height: 1px;
  background: var(--accent-400);
}

/* accessible, calmer form controls */
.form-field input,
.form-field select,
.form-field textarea { border-color: var(--line-field); }
.form-field input:focus-visible,
.form-field select:focus-visible,
.form-field textarea:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 1px;
  border-color: var(--accent-400);
}

/* contrast repairs */
.field-help, .footer-bottom small, .media-caption small { color: var(--text-4); }

/* buttons: flatter, no coloured bloom */
.btn-primary {
  border-radius: var(--r-sm);
  box-shadow: none;
  font-weight: 600;
  letter-spacing: -.005em;
}
.btn-primary:hover { box-shadow: none; background: var(--accent-700); }
.btn-secondary {
  border-radius: var(--r-sm);
  border-color: var(--line-3);
  background: transparent;
  font-weight: 600;
}
.btn-secondary:hover { border-color: var(--accent-400); background: rgba(59,130,246,.10); }

/* the process row: a connector line with nodes, not four boxes */
.process-grid {
  display: grid;
  gap: 0;
  border: 0;
  border-radius: 0;
  background: none;
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
}
.process-step {
  position: relative;
  padding: var(--space-6) var(--space-5) var(--space-5) 0;
  background: none;
  border: 0;
  border-top: 1px solid var(--line-2);
}
.process-step::before {
  content: '';
  position: absolute;
  top: -3px; left: 0;
  width: 5px; height: 5px;
  border-radius: 50%;
  background: var(--node-b);
}
.process-step > span {
  display: block;
  margin-bottom: var(--space-3);
  color: var(--text-4);
  font-size: var(--fs--2);
  letter-spacing: var(--track-caps);
}
.process-step h3 { font-size: var(--fs-1); color: var(--text-1); margin-bottom: var(--space-2); }
.process-step p { color: var(--text-3); font-size: var(--fs--1); max-width: 30ch; }

/* FAQ: hairline rows, no panel boxes */
.faq-list { border: 0; background: none; border-radius: 0; }
.faq-list details {
  border: 0;
  border-top: 1px solid var(--line-1);
  background: none;
  border-radius: 0;
}
.faq-list details:last-of-type { border-bottom: 1px solid var(--line-1); }
.faq-list details + details { border-top: 1px solid var(--line-1); }
.faq-list summary { padding-inline: 0; color: var(--text-1); font-weight: 500; }
.faq-list details > p { padding-inline: 0; max-width: var(--measure); color: var(--text-3); text-wrap: pretty; }

/* trust cards -> a definition list, no boxes */
.promise-list { display: grid; gap: var(--space-5); margin: 0; max-width: 64ch; }
.promise-list dt {
  font-family: var(--font-mark);
  font-size: var(--fs--2);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--accent-400);
  margin-bottom: var(--space-2);
}
.promise-list dd { margin: 0; color: var(--text-2); max-width: 58ch; }

/* footer */
.site-footer { background: var(--surface-1); border-top: 1px solid var(--line-1); }

/* nav */
[data-site-header] { background: rgba(3,7,18,.78); border-bottom: 1px solid var(--line-1); }
[data-site-header].is-scrolled { background: rgba(3,7,18,.94); box-shadow: none; border-bottom-color: var(--line-2); }
.desktop-nav > li > a:not(.nav-project-link) {
  text-transform: none;
  letter-spacing: 0;
  font-size: var(--fs--1);
  color: var(--text-3);
}
.desktop-nav > li > a:not(.nav-project-link):hover,
.desktop-nav > li > a:not(.nav-project-link)[aria-current='page'] { color: var(--text-1); }

/* =====================================================================
   TOOLS CTA
   This block was invisible: page-coloured ground, a 12%-alpha hairline, a
   body-weight lede and the faintest control on the page. It now sits on its
   own surface with an accent anchor, so it reads as an offer rather than as
   more page — without becoming a second primary button. The filled blue
   stays reserved for the contact CTA directly beneath it.
   ===================================================================== */
.tools-cta {
  position: relative;
  padding-block: clamp(2.5rem, 3.8vw, 3.25rem);
  padding-inline: var(--gutter);
  /* lit from the left, where the text and the accent bar are, so the strip
     reads as one object rather than as two things at opposite edges */
  background:
    linear-gradient(90deg, rgba(37,99,235,.14) 0%, rgba(37,99,235,.04) 38%, transparent 64%),
    var(--surface-2);
  border-top: 1px solid rgba(59,130,246,.40);
  border-bottom: 1px solid var(--line-2);
  box-shadow: inset 0 1px 0 rgba(59,130,246,.16);
}
/* the same node that terminates every section rule, so the emphasis is
   spoken in the site's own vocabulary */
.tools-cta::after {
  content: '';
  position: absolute;
  top: -3px;
  left: max(var(--gutter), calc(50% - var(--shell) / 2));
  width: 5px; height: 5px;
  border-radius: 50%;
  background: var(--node-b);
  box-shadow: 0 0 0 3px rgba(6,182,212,.14);
}
.tools-cta-inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-5) var(--space-6);
  max-width: var(--shell);
  margin-inline: auto;
}
/* a short accent bar hangs the text off the left edge and gives the block
   something to be anchored to across the width */
.tools-cta-inner > div:first-child {
  position: relative;
  padding-left: 1.15rem;
}
.tools-cta-inner > div:first-child::before {
  content: '';
  position: absolute;
  left: 0; top: .15rem; bottom: .15rem;
  width: 3px;
  border-radius: 2px;
  background: linear-gradient(180deg, var(--node-b), rgba(59,130,246,.35));
}
.tools-cta-lede {
  font-family: var(--font-mark);
  font-size: var(--fs-3);
  font-weight: 400;
  line-height: 1.2;
  letter-spacing: -.01em;
  color: var(--text-1);
  margin: 0 0 .4rem;
}
.tools-cta-lede .n { color: var(--cy-300); }
/* scoped off the lede, which is a <p> too and was losing on specificity */
.tools-cta p:not(.tools-cta-lede) {
  color: var(--text-3);
  margin: 0;
  max-width: 64ch;
  font-size: var(--fs-0);
  text-wrap: pretty;
}
.tools-cta .tools-button {
  display: inline-flex; align-items: center; gap: .55rem;
  min-height: 3rem;
  padding: .8rem 1.5rem;
  border: 1px solid rgba(96,165,250,.75);
  border-radius: var(--r-sm);
  color: #fff;
  background: rgba(37,99,235,.20);
  font-weight: 600;
  font-size: var(--fs-0);
  white-space: nowrap;
  text-decoration: none;
  transition: border-color var(--dur-2) var(--ease-out),
              background-color var(--dur-2) var(--ease-out);
}
.tools-cta .tools-button:hover {
  border-color: var(--accent-400);
  background: rgba(37,99,235,.36);
}
.tools-cta .tools-button:hover .cn-arrow { width: 1.5em; }

/* =====================================================================
   6. MOTION — one settle per section, not one per card.
   ===================================================================== */
.reveal-enabled [data-reveal]:not(.revealed),
.reveal-enabled [data-reveal='left']:not(.revealed),
.reveal-enabled [data-reveal='right']:not(.revealed) {
  opacity: 0;
  transform: translateY(4px);
}
[data-reveal] { transition: opacity 160ms var(--ease-out), transform 160ms var(--ease-out); }
[data-reveal].revealed { opacity: 1; transform: none !important; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
  [data-reveal] { opacity: 1 !important; transform: none !important; }
}

/* Windows High Contrast: the disclosure control must not vanish */
@media (forced-colors: active) {
  .faq-list summary > span::after,
  .faq-list summary > span::before { forced-color-adjust: none; background: CanvasText; }
  .glow-card { border: 1px solid CanvasText; }
  .rule-lead::after, .process-step::before { background: CanvasText; }
}

/* =====================================================================
   7. ONE SHELL — every section shares a left edge.
   The page had max-w-4xl / 6xl / 7xl mixed down its length, so nothing
   lined up vertically. One container, one edge, measure controlled on
   the text itself rather than on the box.
   ===================================================================== */
main section > div[class*="max-w-"],
main header > div[class*="max-w-"] {
  max-width: var(--shell);
}
main section.final-cta > div[class*="max-w-"] { max-width: var(--shell); }

/* the hero keeps its own centred measure — it sits over the animation */
main header.cn-hero > div[class*="max-w-"] { max-width: 62rem; }

/* three-tier rhythm replaces the single uniform pad */
main > section.section-pad:nth-of-type(odd)  { padding-block: var(--pad-base); }
main > section.section-pad:nth-of-type(even) { padding-block: var(--pad-tight); }
main > section.section-pad:first-of-type     { padding-block: var(--pad-open) var(--pad-base); }

/* the closer stops being centred */
.final-cta { padding-block: var(--pad-open); }
.final-cta > div { text-align: left; max-width: var(--shell); }
.final-cta .section-title { max-width: 20ch; }
.final-cta .section-summary { margin-inline: 0; max-width: 46ch; }
.final-cta .hero-actions { justify-content: flex-start; }

/* trust cards: strip the boxes, let them read as a ruled ledger */
.trust-card {
  min-height: 0;
  padding: var(--space-5) 0 0;
  background: none;
  border: 0;
  border-top: 1px solid var(--line-2);
  border-radius: 0;
}
.trust-card h3 {
  font-family: var(--font-mark);
  font-size: var(--fs--2);
  font-weight: 400;
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--accent-400);
  margin-bottom: var(--space-3);
}
.trust-card p { color: var(--text-2); font-size: var(--fs-0); max-width: 34ch; }

/* service cards on the home grid: hairline top, no filled panel */
.service-group {
  background: none;
  border: 0;
  border-top: 1px solid var(--line-2);
  border-radius: 0;
  padding: var(--space-5) var(--space-5) var(--space-5) 0;
}
.service-group:hover { background: none; border-top-color: var(--accent-400); }
.service-group h3 { font-size: var(--fs-2); color: var(--text-1); margin: var(--space-3) 0 var(--space-3); }
.service-group p { color: var(--text-3); font-size: var(--fs--1); max-width: 34ch; }

/* =====================================================================
   8. THE INDEX LIST — services as a table of contents, not a card grid.
   Full-bleed rows on hairlines: number, name, description, terminal rule.
   ===================================================================== */
.index-list { list-style: none; margin: 0; padding: 0; }
.index-list > li { border-top: 1px solid var(--line-2); }
.index-list > li:last-child { border-bottom: 1px solid var(--line-2); }
.index-list a {
  display: grid;
  grid-template-columns: 4rem minmax(0, 23rem) minmax(0, 1fr) 2.5rem;
  align-items: start;
  gap: var(--space-5);
  padding: var(--space-6) 0;
  text-decoration: none;
  color: inherit;
  transition: background-color var(--dur-2) var(--ease-out);
}
.index-list a:hover { background: linear-gradient(90deg, rgba(59,130,246,.07), transparent 60%); }
.index-num {
  font-family: var(--font-mark);
  font-variant-numeric: tabular-nums;
  font-size: var(--fs--2);
  letter-spacing: var(--track-caps);
  color: var(--text-4);
}
.index-name {
  font-size: var(--fs-2);
  font-weight: 500;
  color: var(--text-1);
  letter-spacing: -.012em;
  text-wrap: balance;
}
.index-desc { color: var(--text-3); font-size: var(--fs--1); max-width: 52ch; text-wrap: pretty; }
.index-go { justify-self: end; align-self: center; color: var(--accent-400); }
.index-list a:hover .index-name { color: #fff; }
.index-list a:hover .cn-arrow { width: 1.6em; }

@media (max-width: 860px) {
  .index-list a {
    grid-template-columns: 3rem 1fr;
    grid-template-areas: 'num name' '.  desc' '.  go';
    gap: var(--space-2) var(--space-4);
    padding: var(--space-5) 0;
  }
  .index-num  { grid-area: num; }
  .index-name { grid-area: name; }
  .index-desc { grid-area: desc; margin-top: var(--space-2); }
  .index-go   { grid-area: go; justify-self: start; margin-top: var(--space-3); }
}

/* left-aligned section actions replace the centred "View all" links */
.section-action-left { margin: var(--space-6) 0 0; }
.section-action-left .text-link,
.text-link {
  display: inline-flex;
  align-items: center;
  min-height: var(--tap);
  color: var(--accent-400);
  font-size: var(--fs--1);
  font-weight: 500;
  text-decoration: none;
}
.text-link:hover { color: var(--cy-300); }
.section-action { text-align: left; margin-top: var(--space-6); }

/* promise list becomes a ruled ledger in the right column */
.promise-list > div {
  border-top: 1px solid var(--line-2);
  padding-top: var(--space-4);
  padding-bottom: var(--space-2);
}
.promise-list dd { font-size: var(--fs-0); line-height: 1.6; max-width: 56ch; }

/* contact assurances on the closer */
.contact-assurances { margin-top: 0; align-content: start; }
.contact-assurances li { color: var(--text-3); font-size: var(--fs--1); }

/* the recess band needs its hairline suppressed — it separates itself */
.band-recess::before, .band-recess::after { display: none !important; }
.band-recess + section::before, .band-recess + section::after { display: none !important; }

/* the process track: one continuous rule with nodes hung off it */
.band-recess .process-grid { margin-top: var(--space-4); }

/* =====================================================================
   9. ASYMMETRIC SPLITS
   The prebuilt tailwind.css only ships grid-cols-1..4, so the site had no
   way to express an off-centre column pair. These are the real ratios.
   ===================================================================== */
.cn-split { display: grid; gap: clamp(2rem, 4vw, 4rem); }
@media (min-width: 768px) {
  .cn-split-lead   { grid-template-columns: 1.05fr .95fr; }
  .cn-split-ledger { grid-template-columns: .8fr 1.2fr; }
  .cn-split-close  { grid-template-columns: 1.1fr .9fr; }
}

/* utilities the prebuilt sheet is missing but the markup already assumes */
.pointer-events-none { pointer-events: none; }
.mb-9 { margin-bottom: 2.25rem; }

/* the hero's bottom fade — the Tailwind gradient stops were never compiled,
   so express it directly and let the constellation sit under it untouched. */
.cn-hero > .absolute.inset-0:not(#heroParticleCanvas) {
  background: linear-gradient(to bottom,
    rgba(23,37,84,.22) 0%,
    rgba(3,7,18,0) 38%,
    rgba(3,7,18,.62) 86%,
    var(--surface-0) 100%);
}

/* prose wrappers on the service pages: give them a real measure */
.prose, .prose-invert { max-width: 64ch; }
.prose > p + p, .prose-invert > p + p { margin-top: 1.1em; }
.prose p, .prose-invert p { color: var(--text-3); text-wrap: pretty; }

/* index-list optical alignment: the name sets the baseline, the description
   hangs from the same cap-height rather than from the row box. */
.index-list .index-num  { padding-top: .55rem; }
.index-list .index-desc { padding-top: .5rem; }
.index-list .index-name { line-height: 1.25; }

/* =====================================================================
   10. INTERIOR PAGES
   The home hero stays centred over the animation — that is the one place
   the symmetry is earned. Every interior hero is left-aligned on the same
   shell edge as the sections beneath it, so the whole site has one spine.
   ===================================================================== */
.page-hero { min-height: 0; padding-top: 4rem; }
.page-hero-inner {
  max-width: var(--shell);
  margin-inline: auto;
  padding: clamp(6rem, 11vw, 8.5rem) var(--gutter) clamp(3.5rem, 6vw, 5rem);
  text-align: left;
}
.page-hero h1 { margin: 0 0 1.25rem; max-width: 19ch; }
.page-hero p:not(.section-eyebrow) { margin: 0; max-width: 56ch; color: var(--text-3); font-size: var(--fs-1); }
.page-hero .hero-actions { justify-content: flex-start; margin-top: 2.25rem; }

/* a real breadcrumb, above the h1, where one belongs */
.crumb { margin: 0 0 1.5rem; }
.crumb ol { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; margin: 0; padding: 0; list-style: none; }
.crumb li { display: flex; align-items: center; gap: .5rem; font-size: var(--fs--2); color: var(--text-4); }
.crumb li + li::before { content: '/'; color: var(--line-3); }
.crumb a { color: var(--text-3); text-decoration: none; }
.crumb a:hover { color: var(--accent-400); }
.crumb [aria-current='page'] { color: var(--text-2); }

/* a plain bordered plate — what glow-card content-card now means */
.content-card {
  padding: var(--space-5);
  border: 1px solid var(--line-2);
  border-radius: var(--r-md);
  background: var(--surface-2);
}
.content-card h3 { font-size: var(--fs-1); color: var(--text-1); margin: 0 0 var(--space-2); }
.content-card p  { font-size: var(--fs--1); color: var(--text-3); margin: 0; text-wrap: pretty; }

/* the numbered phase list — kept on our-approach only. The gradient circle
   is gone; the numeral is a quiet typographic element in a left column. */
.phase-rail { display: grid; gap: 0; margin: 0; padding: 0; list-style: none; }
.phase-row {
  display: grid;
  grid-template-columns: 5.5rem 1fr;
  gap: var(--space-5);
  padding: var(--space-6) 0;
  border-top: 1px solid var(--line-1);
}
.phase-row:last-child { border-bottom: 1px solid var(--line-1); }
.phase-row > .phase-n {
  font-family: var(--font-mark);
  font-variant-numeric: tabular-nums;
  font-size: clamp(2.25rem, 4vw, 3.25rem);
  line-height: 1;
  color: rgba(96,165,250,.26);
}
.phase-row h3 { font-size: var(--fs-2); color: var(--text-1); margin: 0 0 var(--space-3); }
.phase-row p { color: var(--text-3); max-width: 58ch; margin: 0 0 var(--space-3); }
.phase-deliverable {
  display: flex; flex-wrap: wrap; gap: .6rem;
  align-items: baseline;
  font-size: var(--fs--1);
  color: var(--text-2);
}
.phase-deliverable > span {
  font-family: var(--font-mark);
  font-size: var(--fs--2);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--accent-400);
}
@media (max-width: 700px) {
  .phase-row { grid-template-columns: 1fr; gap: var(--space-3); }
  .phase-row > .phase-n { font-size: 2rem; }
}

/* the service-page FAQ used a different accordion from the hub pages.
   One component now: hairline rows with a drawn chevron. */
.faq-list summary svg,
details.group summary svg { color: var(--accent-400); }
details.group {
  padding: var(--space-4) 0;
  border: 0;
  border-top: 1px solid var(--line-1);
  border-radius: 0;
  background: none;
}
details.group:last-of-type { border-bottom: 1px solid var(--line-1); }
details.group > summary { color: var(--text-1); font-weight: 500; }
details.group > p { color: var(--text-3); max-width: var(--measure); text-wrap: pretty; }

/* a two-column comparison plate, for "browser vs local machine" style blocks */
.compare { display: grid; gap: var(--space-5); }
@media (min-width: 720px) { .compare { grid-template-columns: 1fr 1fr; } }
.compare > div { border-top: 1px solid var(--line-2); padding-top: var(--space-4); }
.compare h3 {
  font-family: var(--font-mark);
  font-size: var(--fs--2);
  font-weight: 400;
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--accent-400);
  margin: 0 0 var(--space-3);
}
.compare ul { margin: 0; padding: 0; list-style: none; display: grid; gap: var(--space-3); }
.compare li { position: relative; padding-left: 1.5rem; color: var(--text-2); font-size: var(--fs--1); }
.compare li::before {
  content: ''; position: absolute; left: 0; top: .62em;
  width: .6rem; height: 1px; background: var(--accent-400);
}

/* a narrow prose measure for the "is this for me" blocks */
.prose-narrow { max-width: 62ch; }
.prose-narrow p { color: var(--text-3); margin: 0 0 1.1em; text-wrap: pretty; }
.prose-narrow p:last-child { margin-bottom: 0; }
.prose-narrow strong { color: var(--text-1); font-weight: 600; }

/* =====================================================================
   11. CASCADE REPAIRS
   site.css centres several text blocks with margin-inline:auto. With the
   page now left-aligned those blocks drifted to the middle of the shell.
   ===================================================================== */
.section-summary,
.hero-summary,
.page-hero p:not(.section-eyebrow) { margin-inline: 0; }
.section-intro.is-centred .section-summary,
.cn-hero .hero-summary { margin-inline: auto; }

/* the service pages ship an SVG chevron in the summary; site.css also draws
   a +/− pseudo-element. Two disclosure markers on one control is a defect. */
.faq-list summary:has(svg) > span::before,
.faq-list summary:has(svg) > span::after,
details.group > summary > span::before,
details.group > summary > span::after { content: none; display: none; }

/* the service-page summary is a flex row, so it needs no right padding
   reserved for a pseudo-marker */
.faq-list summary:has(svg) { padding-right: 0; padding-left: 0; }

/* closers on the service pages: give them the same left two-column shape
   as the homepage rather than a stacked centre block */
section.section-pad > div.relative.max-w-7xl > .section-title { max-width: 22ch; }
section.section-pad > div.relative.max-w-7xl > .btn-primary { margin-top: var(--space-5); }

/* =====================================================================
   12. WIDE ROWS — two full-width entries, used once, on the services hub.
   A third shape so the three service groups do not read as one grid.
   ===================================================================== */
.wide-rows { display: grid; gap: 0; }
.wide-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: start;
  gap: var(--space-5);
  padding: var(--space-6) 0;
  border-top: 1px solid var(--line-2);
}
.wide-rows .wide-row:last-child { border-bottom: 1px solid var(--line-2); }
.wide-row h3 { font-size: var(--fs-2); font-weight: 500; margin: 0 0 var(--space-3); letter-spacing: -.012em; }
.wide-row h3 a { color: var(--text-1); text-decoration: none; }
.wide-row h3 a:hover { color: #fff; }
.wide-row p { color: var(--text-3); margin: 0; max-width: 62ch; }
.wide-row .text-link { white-space: nowrap; }
@media (max-width: 700px) {
  .wide-row { grid-template-columns: 1fr; gap: var(--space-3); }
}

/* the remaining service cards lose the counter slot they were built around */
.service-card .card-number { display: none; }
.service-card {
  background: none;
  border: 0;
  border-top: 1px solid var(--line-2);
  border-radius: 0;
  padding: var(--space-5) var(--space-5) var(--space-5) 0;
}
.service-card:hover { background: none; border-top-color: var(--accent-400); }
.service-card h3 { font-size: var(--fs-2); color: var(--text-1); margin: 0 0 var(--space-3); font-weight: 500; }
.service-card p { color: var(--text-3); font-size: var(--fs--1); max-width: 34ch; }

/* the phase rail's kicker — a quiet label above the phase title */
.phase-kicker {
  font-family: var(--font-mark);
  font-size: var(--fs--2);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--text-4);
  margin: 0 0 var(--space-2);
}
.phase-row .phase-deliverable { margin-top: var(--space-4); }

/* =====================================================================
   13. RANKED EXAMPLES — one lead, the rest smaller. Used once, on
   /ai-solutions, so the page states a priority instead of tiling four
   equally-weighted boxes.
   ===================================================================== */
.lead-example { display: grid; gap: clamp(2rem, 4vw, 3.5rem); }
@media (min-width: 860px) { .lead-example { grid-template-columns: .95fr 1.05fr; } }
.lead-example-main { border-top: 1px solid rgba(59,130,246,.45); padding-top: var(--space-4); }
.lead-example-main h3 { font-size: var(--fs-3); color: var(--text-1); margin: 0 0 var(--space-4); letter-spacing: -.018em; }
.lead-example-main p { color: var(--text-2); max-width: 46ch; }
.lead-example-rest { display: grid; gap: 0; align-content: start; }
.stack-item { border-top: 1px solid var(--line-1); padding: var(--space-4) 0; }
.lead-example-rest .stack-item:last-child { border-bottom: 1px solid var(--line-1); }
.stack-item h3 { font-size: var(--fs-1); color: var(--text-1); margin: 0 0 var(--space-2); font-weight: 500; }
.stack-item p { color: var(--text-3); font-size: var(--fs--1); margin: 0; max-width: 54ch; }

/* buttons follow the page's spine; only the home hero centres them */
.hero-actions { justify-content: flex-start; }
.cn-hero .hero-actions { justify-content: center; }

/* =====================================================================
   14. TOOLS SUITE
   The tools are a product surface, not a marketing one, so the cards stay
   cards — they are real click targets. What changes is that they now share
   the marketing pages' spine, type and palette instead of reading as a
   bolted-on second system.
   ===================================================================== */
.tools-wrap { max-width: var(--shell); padding-inline: var(--gutter); }

/* the hub hero drops the centred axis and the radial wash */
.tools-hero {
  padding: clamp(6rem, 11vw, 8.5rem) 0 clamp(2.5rem, 4vw, 3.5rem);
  background: none;
  text-align: left;
}
.tools-hero > .tools-wrap { text-align: left; }
.tools-hero h1 {
  font-size: var(--fs-5);
  font-weight: 600;
  line-height: var(--lh-display);
  letter-spacing: var(--track-lg);
  color: var(--text-1);
  max-width: 19ch;
  margin: .9rem 0 1.1rem;
}
.tools-hero p { color: var(--text-3); max-width: 58ch; font-size: var(--fs-1); line-height: var(--lh-body); }
.tools-hero .tools-desktop-break { display: none; }

.tools-eyebrow {
  font-family: var(--font-mark);
  font-weight: 400;
  font-size: var(--fs--2);
  letter-spacing: var(--track-caps);
  color: var(--accent-400);
}

/* search, badges and filters sit on the same left edge */
.tools-search { margin-inline: 0; max-width: 46rem; }
.tools-badges { justify-content: flex-start; }
.tools-input { border-color: var(--line-field); border-radius: var(--r-sm); }
.tools-input:focus-visible { outline: 2px solid var(--focus); outline-offset: 1px; border-color: var(--accent-400); }

/* cards keep their affordance, lose the borrowed glow */
.tools-card,
.tools-task-card,
.tools-panel {
  border: 1px solid var(--line-2);
  border-radius: var(--r-md);
  background: var(--surface-2);
  box-shadow: none;
  transition: border-color var(--dur-2) var(--ease-out), background-color var(--dur-2) var(--ease-out);
}
.tools-card:hover,
.tools-task-card:hover { border-color: rgba(96,165,250,.55); background: var(--surface-3); transform: none; box-shadow: none; }
.tools-card h3, .tools-task-card h3 { color: var(--text-1); font-weight: 500; letter-spacing: -.008em; }
.tools-card p, .tools-task-card p { color: var(--text-3); }

/* category drawers become hairline rows, matching the marketing accordions */
.tools-category {
  border: 0;
  border-top: 1px solid var(--line-1);
  border-radius: 0;
  background: none;
}
.tools-category:last-of-type { border-bottom: 1px solid var(--line-1); }
.tools-category > summary { padding-inline: 0; color: var(--text-1); }
.tools-category-count { color: var(--text-4); font-variant-numeric: tabular-nums; }

/* section headings match the marketing scale */
.tools-catalog h2 { font-size: var(--fs-3); font-weight: 600; letter-spacing: var(--track-lg); color: var(--text-1); }
.tools-privacy h2 { font-size: var(--fs-2); }
.tools-breadcrumb { color: var(--text-4); font-size: var(--fs--2); }
.tools-breadcrumb a { color: var(--text-3); }
.tools-breadcrumb a:hover { color: var(--accent-400); }

/* buttons align with the marketing set */
.tools-button {
  border-radius: var(--r-sm);
  box-shadow: none;
  font-weight: 600;
}
.tools-button-secondary { border-radius: var(--r-sm); border-color: var(--line-3); }

/* tools.css centres the hub hero and its children explicitly; override each */
.tools-hub-hero { text-align: left; }
.tools-hub-hero p { margin-inline: 0; }
.tools-hub-hero .tools-search { margin: 1.75rem 0 1rem; }
.tools-hub-hero .tools-examples { justify-content: flex-start; }
.tools-hub-hero .tools-badges { justify-content: flex-start; }
.tools-tool-hero { text-align: left; }
.tools-tool-hero p { margin-inline: 0; }

/* =====================================================================
   15. PROJECT INTAKE FLOW
   The old modal was one long form of seven fields. It is now four short
   questions and a thank-you, styled on the same tokens as the pages.
   ===================================================================== */
.cn-flow.contact-modal {
  width: min(680px, calc(100vw - 2rem));
  max-height: calc(100dvh - 2rem);
  padding: 0;
  border: 1px solid var(--line-2);
  border-radius: var(--r-lg);
  background: var(--surface-2);
  box-shadow: var(--e3);
  color: var(--text-2);
}
.cn-flow.contact-modal::backdrop { background: rgba(3,7,18,.72); backdrop-filter: blur(3px); }
.cn-flow .contact-modal-shell { padding: clamp(1.5rem, 3vw, 2.25rem); }

.cn-flow .contact-modal-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-4);
  padding: 0 0 var(--space-5);
  border: 0;
}
.cn-flow .contact-modal-header h2 {
  font-size: var(--fs-3);
  font-weight: 600;
  line-height: var(--lh-tight);
  letter-spacing: var(--track-lg);
  color: var(--text-1);
  margin: .35rem 0 .5rem;
  max-width: 22ch;
}
.cn-flow .contact-modal-header p:last-child { color: var(--text-3); font-size: var(--fs--1); margin: 0; max-width: 46ch; }
.cn-flow .contact-modal-header p:last-child:empty { display: none; }
.cn-flow .contact-modal-close {
  flex: 0 0 auto;
  width: 2.5rem; height: 2.5rem;
  border: 1px solid var(--line-2);
  border-radius: var(--r-sm);
  background: transparent;
}
.cn-flow .contact-modal-close:hover { border-color: var(--line-3); background: var(--surface-3); }

/* progress — the constellation rule, filling as you go */
.cn-progress { display: flex; align-items: center; gap: var(--space-4); margin-bottom: var(--space-5); }
.cn-progress-track { position: relative; flex: 1; height: 2px; background: var(--line-1); border-radius: 2px; overflow: hidden; }
.cn-progress-fill {
  display: block; height: 100%; width: 25%;
  background: linear-gradient(90deg, var(--link-far), var(--node-b));
  transition: width var(--dur-2) var(--ease-out);
}
.cn-progress-count {
  font-family: var(--font-mark);
  font-variant-numeric: tabular-nums;
  font-size: var(--fs--2);
  letter-spacing: .08em;
  color: var(--text-4);
}

.cn-step { display: grid; gap: var(--space-5); }
/* Several of these elements set an explicit display, which beats the
   hidden attribute's UA rule. Restate it for everything in the flow. */
.cn-flow [hidden] { display: none !important; }
.cn-step:focus { outline: none; }
.cn-flow .form-field label { color: var(--text-2); font-weight: 500; font-size: var(--fs--1); }
.cn-flow .form-field label span { color: var(--text-4); font-weight: 400; }
.cn-flow input, .cn-flow textarea {
  width: 100%;
  padding: .8rem .9rem;
  border: 1px solid var(--line-field);
  border-radius: var(--r-sm);
  background: var(--surface-0);
  color: var(--text-1);
  font: inherit;
}
.cn-flow textarea { resize: vertical; min-height: 8.5rem; line-height: 1.6; }
.cn-flow input::placeholder, .cn-flow textarea::placeholder { color: var(--text-4); }
.cn-flow input:focus-visible, .cn-flow textarea:focus-visible {
  outline: 2px solid var(--focus); outline-offset: 1px; border-color: var(--accent-400);
}
.cn-flow .field-help { color: var(--text-4); font-size: var(--fs--2); margin: .5rem 0 0; }
.cn-flow .field-error { color: var(--danger); font-size: var(--fs--2); margin: .5rem 0 0; }
.cn-flow .form-row { display: grid; gap: var(--space-4); }
@media (min-width: 560px) { .cn-flow .form-row { grid-template-columns: 1fr 1fr; } }

/* option cards — a real radio underneath, so keyboard and SR behaviour is free */
.cn-choices { display: grid; gap: .6rem; }
@media (min-width: 560px) { .cn-choices { grid-template-columns: 1fr 1fr; } }
.cn-choice { position: relative; display: block; cursor: pointer; }
.cn-choice input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.cn-choice-body {
  display: block;
  padding: .9rem 1rem;
  border: 1px solid var(--line-2);
  border-radius: var(--r-md);
  background: var(--surface-0);
  transition: border-color var(--dur-1) var(--ease-out), background-color var(--dur-1) var(--ease-out);
}
.cn-choice:hover .cn-choice-body { border-color: var(--line-3); }
.cn-choice input:focus-visible + .cn-choice-body { outline: 2px solid var(--focus); outline-offset: 2px; }
.cn-choice input:checked + .cn-choice-body {
  border-color: rgba(96,165,250,.85);
  background: rgba(37,99,235,.16);
}
.cn-choice-label { display: block; color: var(--text-1); font-weight: 500; font-size: var(--fs--1); }
.cn-choice-hint  { display: block; color: var(--text-4); font-size: var(--fs--2); margin-top: .25rem; line-height: 1.45; }

/* pills for the two quick optional questions */
.cn-fieldset { border: 0; padding: 0; margin: 0; }
.cn-fieldset legend { padding: 0; color: var(--text-2); font-weight: 500; font-size: var(--fs--1); margin-bottom: .7rem; }
.cn-pills { display: flex; flex-wrap: wrap; gap: .5rem; }
.cn-pill { position: relative; }
.cn-pill input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.cn-pill span {
  display: inline-flex; align-items: center;
  min-height: 2.5rem;
  padding: .45rem .9rem;
  border: 1px solid var(--line-2);
  border-radius: 999px;
  background: var(--surface-0);
  color: var(--text-2);
  font-size: var(--fs--1);
  cursor: pointer;
  transition: border-color var(--dur-1) var(--ease-out), background-color var(--dur-1) var(--ease-out);
}
.cn-pill:hover span { border-color: var(--line-3); }
.cn-pill input:focus-visible + span { outline: 2px solid var(--focus); outline-offset: 2px; }
.cn-pill input:checked + span { border-color: rgba(96,165,250,.85); background: rgba(37,99,235,.18); color: #fff; }

/* actions */
.cn-actions {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-4);
  margin-top: var(--space-6);
  padding-top: var(--space-5);
  border-top: 1px solid var(--line-1);
}
.cn-actions-end { display: flex; align-items: center; gap: var(--space-3); margin-left: auto; }
.cn-flow .btn-primary, .cn-flow .btn-secondary { min-height: 2.9rem; padding: .7rem 1.4rem; font-size: var(--fs--1); }
.cn-skip {
  border: 0; background: none;
  color: var(--text-4);
  font: inherit; font-size: var(--fs--1);
  text-decoration: underline; text-underline-offset: 3px;
  cursor: pointer;
  min-height: 2.9rem; padding: 0 .4rem;
}
.cn-skip:hover { color: var(--text-2); }
.cn-actions-note { color: var(--text-4); font-size: var(--fs--2); margin: .75rem 0 0; }

/* the close */
.cn-done { text-align: left; padding: var(--space-4) 0 var(--space-2); }
.cn-done:focus { outline: none; }
.cn-done-mark {
  display: block; width: 2.5rem; height: 2.5rem;
  margin-bottom: var(--space-4);
  border-radius: 50%;
  background: rgba(6,182,212,.16);
  border: 1px solid rgba(6,182,212,.55);
  position: relative;
}
.cn-done-mark::after {
  content: ''; position: absolute; left: 50%; top: 46%;
  width: .95rem; height: .5rem;
  border-left: 2px solid var(--node-b);
  border-bottom: 2px solid var(--node-b);
  transform: translate(-50%, -50%) rotate(-45deg);
}
.cn-done-lead { color: var(--text-2) !important; font-size: var(--fs-1); }
.cn-done p { color: var(--text-3); max-width: 48ch; margin: 0 0 var(--space-3); }
.cn-done-meta { color: var(--text-4); font-size: var(--fs--1); }
.cn-done .btn-secondary { margin-top: var(--space-3); }

@media (prefers-reduced-motion: reduce) {
  .cn-progress-fill, .cn-choice-body, .cn-pill span { transition: none; }
}

/* Keep the footer description readable on the dark footer surface. */
.site-footer .footer-grid p { color: var(--text-3); }
