/* ============================================================
   components.css — everything with a name and a job

   Ordered roughly by where you meet it: brand → nav → buttons →
   cards → editorial → forms → page-specific.
   ============================================================ */

/* ============================================================
   Wordmark — "Dev" in the display face, "Crunch" in mono.
   The seam between the two faces is the brand detail.
   ============================================================ */

.wordmark {
  display: inline-flex;
  align-items: center;
  font-size: var(--fs-md);
  text-decoration: none;
  letter-spacing: -0.02em;
  white-space: nowrap;
}

/* Spacing goes on the mark rather than as a flex `gap`, which would also
   push "Dev" and "Crunch" apart and break the two-face seam that is the
   whole point of the wordmark. Sized in em so it tracks the font size
   wherever the wordmark is reused. */
.wordmark__mark {
  flex: none;
  width: 1.4em;
  height: 1.4em;
  margin-inline-end: 0.5em;
}

.wordmark:hover { color: var(--paper); }

.wordmark__dev {
  font-family: var(--font-display);
  font-weight: 700;
}

.wordmark__crunch {
  font-family: var(--font-mono);
  font-weight: 400;
  font-size: 0.86em;
  letter-spacing: 0;
  color: var(--signal);
}

/* ============================================================
   Primary nav
   ============================================================ */

.site-nav__list {
  display: flex;
  align-items: center;
  gap: var(--sp-8);
}

.site-nav__list a {
  position: relative;
  font-size: var(--fs-xs);
  font-weight: 500;
  letter-spacing: 0.01em;
  text-decoration: none;
  color: var(--slate);
  padding-block: var(--sp-2);
  transition: color var(--dur-fast) var(--ease-soft);
}

.site-nav__list a:hover { color: var(--paper); }

/* Active page: an amber tick under the label — the same signal
   vocabulary as the trace node, at nav scale. */
.site-nav__list a[aria-current]::after {
  content: "";
  position: absolute;
  inset-block-end: 0;
  inset-inline-start: 0;
  width: 100%;
  height: 1px;
  background: var(--signal);
}

.site-nav__list a[aria-current] { color: var(--paper); }

/* ---- Mobile drawer ----------------------------------------- */

/* Scoped to the drawer breakpoint rather than set unconditionally:
   components.css loads after layout.css, so an unscoped
   `display: grid` here would beat layout.css's min-width:1024px
   hide rule and leave the toggle visible on desktop. */
@media (max-width: 1023px) {
  .nav-toggle {
    display: grid;
    place-content: center;
    gap: 5px;
    width: 2.75rem;
    height: 2.75rem;
    margin-inline-end: calc(var(--sp-2) * -1);
    border-radius: var(--radius);
    cursor: pointer;
  }
}

@media (min-width: 1024px) {
  .nav-toggle { display: none; }
}

.nav-toggle__bar {
  display: block;
  width: 20px;
  height: 1.5px;
  background: var(--paper);
  transition: transform var(--dur) var(--ease-out),
              opacity var(--dur-fast) var(--ease-soft);
}

.nav-toggle[aria-expanded="true"] .nav-toggle__bar:first-child {
  transform: translateY(3.25px) rotate(45deg);
}

.nav-toggle[aria-expanded="true"] .nav-toggle__bar:last-child {
  transform: translateY(-3.25px) rotate(-45deg);
}

@media (max-width: 1023px) {
  .site-header[data-nav-open] .site-nav {
    display: block;
    position: absolute;
    inset-inline: 0;
    top: 100%;
    background: var(--ink);
    border-block: 1px solid var(--line);
    padding: var(--sp-4) var(--gutter) var(--sp-8);
  }

  .site-header[data-nav-open] .site-nav__list {
    flex-direction: column;
    align-items: stretch;
    gap: 0;
  }

  .site-header[data-nav-open] .site-nav__list a {
    display: block;
    font-family: var(--font-display);
    font-size: var(--fs-lg);
    font-weight: 600;
    letter-spacing: var(--track-display);
    color: var(--paper);
    padding-block: var(--sp-4);
    border-block-end: 1px solid var(--line);
  }

  .site-header[data-nav-open] .site-nav__list a[aria-current]::after { display: none; }
  .site-header[data-nav-open] .site-nav__list a[aria-current] { color: var(--signal); }
}

/* ============================================================
   Buttons
   --signal is a fill with --ink text (10.8:1). It is never text
   on a light surface, where it would fail at 1.5:1.
   ============================================================ */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  padding: var(--sp-3) var(--sp-6);
  border: 1px solid transparent;
  border-radius: var(--radius);
  font-family: var(--font-body);
  font-size: var(--fs-xs);
  font-weight: 500;
  letter-spacing: 0.01em;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: transform var(--dur-fast) var(--ease-out),
              background-color var(--dur-fast) var(--ease-soft),
              border-color var(--dur-fast) var(--ease-soft),
              color var(--dur-fast) var(--ease-soft);
}

.btn--lg {
  padding: var(--sp-4) var(--sp-8);
  font-size: var(--fs-sm);
}

.btn--signal {
  background: var(--signal);
  color: var(--ink);
  font-weight: 600;
}

.btn--signal:hover {
  background: color-mix(in srgb, var(--signal) 88%, #fff);
  color: var(--ink);
  transform: scale(1.03);
}

.btn--signal:active { transform: scale(0.99); }

.btn--ghost {
  border-color: var(--line-strong);
  color: var(--paper);
}

.btn--ghost:hover {
  border-color: var(--signal);
  color: var(--signal);
  transform: scale(1.02);
}

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

/* A button that reads as a link — used for "edit my details". */
.link-btn {
  font-size: var(--fs-xs);
  color: var(--slate);
  cursor: pointer;
  text-decoration: underline;
  text-decoration-color: var(--line-strong);
  text-underline-offset: 0.22em;
  transition: color var(--dur-fast) var(--ease-soft);
}

.link-btn:hover { color: var(--signal); }

/* ============================================================
   Tags / stack pills — mono, because the audience reads code
   ============================================================ */

.tags {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
}

.tag {
  font-family: var(--font-mono);
  font-size: 0.6875rem;              /* 11px — deliberately below the scale, this is an annotation */
  letter-spacing: var(--track-mono);
  text-transform: uppercase;
  color: var(--slate);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 0.3rem 0.7rem;
  white-space: nowrap;
  transition: border-color var(--dur-fast) var(--ease-soft),
              color var(--dur-fast) var(--ease-soft);
}

.tags--lg .tag {
  font-size: var(--fs-xs);
  padding: 0.4rem 0.9rem;
}

.tag--cat {
  color: var(--signal);
  border-color: color-mix(in srgb, var(--signal) 35%, transparent);
  background: var(--signal-wash);
}

/* ============================================================
   Status indicator — "Available for new projects"
   ============================================================ */

.status {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: 0.02em;
  color: var(--paper);
}

.status__dot {
  flex: none;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--signal);
}

.status__dot--muted { background: var(--slate); }

/* ============================================================
   Hero pipeline diagram
   ============================================================ */

.pipe { width: 100%; height: auto; }

.pipe__track { stroke: var(--line); stroke-width: 1; }

.pipe__flow {
  stroke: var(--trace);
  stroke-width: 1;
  /* Drawn in on load; see animations.css */
  stroke-dasharray: 600;
  stroke-dashoffset: 600;
}

.pipe__nodes circle {
  fill: var(--ink);
  stroke: var(--trace);
  stroke-width: 1.5;
}

.pipe__node--end { stroke: var(--signal); }

.pipe__pulse { fill: var(--signal); }

.pipe__labels text {
  fill: var(--slate);
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.08em;
}

.pipe__meta text {
  fill: var(--slate);
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.06em;
  opacity: 0.7;
}

/* ============================================================
   Stats & metrics — teal numerals, because teal means "measure"
   ============================================================ */

.stat__label,
.metric__label {
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  letter-spacing: var(--track-mono);
  text-transform: uppercase;
  color: var(--slate);
}

.stat__value {
  font-family: var(--font-display);
  font-size: var(--fs-lg);
  font-weight: 700;
  letter-spacing: var(--track-display);
  color: var(--trace);
  margin-block-start: var(--sp-2);
}

.metric__value {
  font-family: var(--font-display);
  font-size: var(--fs-xl);
  font-weight: 700;
  letter-spacing: var(--track-display);
  line-height: 1;
  color: var(--trace);
  margin-block-start: var(--sp-3);
}

.metric__note {
  margin-block-start: var(--sp-2);
  font-size: var(--fs-xs);
  color: var(--slate);
}

/* ============================================================
   Case study beat (homepage)
   ============================================================ */

.case__link {
  display: block;
  text-decoration: none;
  color: inherit;
}

.case__link:hover { color: inherit; }

.case__media {
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--surface);
  transition: border-color var(--dur) var(--ease-soft),
              transform var(--dur) var(--ease-out);
}

.case__media img { width: 100%; }

.case__link:hover .case__media,
.case__link:focus-visible .case__media { border-color: var(--line-strong); }

.case__index {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: var(--track-mono);
  color: var(--signal);
}

.case__client {
  margin-block-start: var(--sp-4);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: 0.04em;
  color: var(--paper);
}

.case__sector { color: var(--slate); }

.case__title {
  margin-block-start: var(--sp-3);
  font-size: var(--fs-h3);
}

.case__pitch {
  margin-block-start: var(--sp-4);
  color: var(--slate);
  max-width: 44ch;
}

.case__body .tags { margin-block-start: var(--sp-6); }

.case__stat {
  margin-block-start: var(--sp-6);
  padding-block-start: var(--sp-4);
  border-block-start: 1px solid var(--line);
  font-size: var(--fs-xs);
  color: var(--slate);
}

.case__stat-value {
  font-family: var(--font-display);
  font-size: var(--fs-md);
  font-weight: 700;
  color: var(--trace);
  margin-inline-end: var(--sp-2);
}

.case__cta {
  display: inline-block;
  margin-block-start: var(--sp-6);
  font-size: var(--fs-xs);
  font-weight: 500;
  color: var(--signal);
}

.case__cta::after {
  content: " \2192";
  display: inline-block;
  transition: transform var(--dur) var(--ease-out);
}

.case__link:hover .case__cta::after { transform: translateX(4px); }

/* ============================================================
   Work / post / product cards
   ============================================================ */

.work-card__link,
.post-card__link,
.post-row__link {
  display: block;
  text-decoration: none;
  color: inherit;
  border-radius: var(--radius-lg);
}

.work-card__link:hover,
.post-card__link:hover,
.post-row__link:hover { color: inherit; }

.work-card__media,
.post-card__media,
.post-row__media,
.product__media,
.case-hero__media,
.article-head__media {
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--surface);
  transition: border-color var(--dur) var(--ease-soft);
}

.work-card__media img,
.post-card__media img,
.post-row__media img,
.product__media img { width: 100%; }

.work-card__link:hover .work-card__media,
.post-card__link:hover .post-card__media,
.post-row__link:hover .post-row__media { border-color: var(--line-strong); }

.work-card__body,
.post-card__link > *:not(.post-card__media) { margin-block-start: var(--sp-5, 1.25rem); }

.work-card__body { margin-block-start: var(--sp-6); }

.work-card__meta,
.post-card__meta,
.post-row__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-2);
  margin-block-start: var(--sp-6);
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  letter-spacing: var(--track-mono);
  text-transform: uppercase;
  color: var(--slate);
}

.work-card__meta { margin-block-start: 0; }

.post-card__cat,
.post-row__cat { color: var(--signal); }

.post-row__status { color: var(--slate); font-style: normal; }

.work-card__title,
.post-card__title,
.post-row__title {
  margin-block-start: var(--sp-3);
  font-size: var(--fs-h3);
  transition: color var(--dur-fast) var(--ease-soft);
}

.post-card__title { font-size: var(--fs-md); }

.work-card__link:hover .work-card__title,
.post-card__link:hover .post-card__title,
.post-row__link:hover .post-row__title { color: var(--signal); }

.work-card__pitch,
.post-card__excerpt,
.post-row__excerpt {
  margin-block-start: var(--sp-3);
  color: var(--slate);
  font-size: var(--fs-xs);
  max-width: 50ch;
}

.post-row__excerpt { font-size: var(--fs-sm); }

.work-card__body .tags { margin-block-start: var(--sp-5, 1.25rem); }

.work-card__stat {
  margin-block-start: var(--sp-4);
  font-size: var(--fs-xs);
  color: var(--slate);
}

.work-card__stat-value {
  font-family: var(--font-display);
  font-weight: 700;
  color: var(--trace);
  margin-inline-end: var(--sp-2);
}

/* Journal list rows — media beside copy from 768px up. */
@media (min-width: 768px) {
  .post-row__link {
    display: grid;
    grid-template-columns: 18rem 1fr;
    gap: var(--sp-8);
    align-items: start;
  }
  .post-row__meta { margin-block-start: 0; }
}

@media (min-width: 1024px) {
  .post-row__link { grid-template-columns: 24rem 1fr; gap: var(--sp-12); }
}

/* Scheduled posts: present, dated, honestly not clickable yet. */
.post-row--scheduled .post-row__link { cursor: default; }
.post-row--scheduled .post-row__media { opacity: 0.4; }
.post-row--scheduled .post-row__title { color: var(--slate); }

.post-row--scheduled .post-row__status::before {
  content: "";
  display: inline-block;
  width: 5px;
  height: 5px;
  margin-inline-end: 0.4rem;
  border-radius: 50%;
  background: var(--slate);
  vertical-align: middle;
}

/* ============================================================
   Services (homepage grid)
   ============================================================ */

.service {
  padding: var(--sp-8);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--surface);
  transition: border-color var(--dur) var(--ease-soft),
              background-color var(--dur) var(--ease-soft);
}

.service:hover {
  border-color: var(--line-strong);
  background: var(--surface-alt);
}

.service__index {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: var(--track-mono);
  color: var(--signal);
}

.service__title { margin-block-start: var(--sp-6); font-size: var(--fs-md); }

.service__copy {
  margin-block-start: var(--sp-4);
  font-size: var(--fs-xs);
  color: var(--slate);
}

.service .tags { margin-block-start: var(--sp-6); }

/* Date line on the shorter "also shipped" entries. Mono and muted so it
   reads as metadata rather than competing with the title. */
.service__when {
  margin-block-start: var(--sp-5);
  padding-block-start: var(--sp-4);
  border-block-start: 1px solid var(--line);
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  letter-spacing: var(--track-mono);
  color: var(--slate);
}

/* ============================================================
   Expertise detail blocks
   ============================================================ */

.service-detail {
  padding-block-start: var(--sp-8);
  border-block-start: 1px solid var(--line);
}

.service-detail__index {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: var(--track-mono);
  color: var(--signal);
}

.service-detail__title { margin-block-start: var(--sp-4); font-size: var(--fs-h2); }

.service-detail__summary {
  margin-block-start: var(--sp-6);
  font-size: var(--fs-md);
  color: var(--slate);
  max-width: 58ch;
}

.service-detail__cols { margin-block-start: var(--sp-8); }

.service-detail__sub {
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: var(--track-mono);
  text-transform: uppercase;
  color: var(--slate);
  margin-block-end: var(--sp-4);
}

.service-detail__col > .service-detail__sub:not(:first-child) { margin-block-start: var(--sp-8); }

.service-detail__link { font-size: var(--fs-xs); }
.service-detail__link a { color: var(--signal); text-decoration: none; }
.service-detail__link a:hover { text-decoration: underline; }

/* Ticked list — the mono tick is the "status: done" motif */
.ticked { display: grid; gap: var(--sp-4); }

.ticked li {
  position: relative;
  padding-inline-start: var(--sp-6);
  font-size: var(--fs-xs);
  color: var(--slate);
}

.ticked li::before {
  content: "\2713";
  position: absolute;
  inset-inline-start: 0;
  color: var(--trace);
  font-family: var(--font-mono);
  font-size: 0.75rem;
}

.prose .ticked li { font-size: var(--fs-sm); }

/* ============================================================
   Products
   ============================================================ */

.product__label {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  letter-spacing: var(--track-mono);
  text-transform: uppercase;
  color: var(--signal);
  border: 1px solid color-mix(in srgb, var(--signal) 30%, transparent);
  background: var(--signal-wash);
  border-radius: 999px;
  padding: 0.25rem 0.65rem;
}

.product__title { margin-block-start: var(--sp-5, 1.25rem); font-size: var(--fs-h2); }

.product__tagline {
  margin-block-start: var(--sp-3);
  font-size: var(--fs-md);
  color: var(--paper);
}

.product__copy {
  margin-block-start: var(--sp-4);
  color: var(--slate);
  max-width: 52ch;
}

.product__body .tags { margin-block-start: var(--sp-6); }

.product__status {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  margin-block: var(--sp-6);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  color: var(--slate);
}

/* ============================================================
   Testimonials — carousel (homepage) and grid (page)
   ============================================================ */

.carousel { position: relative; }

.carousel__track {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: min(88%, 30rem);
  gap: var(--sp-6);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  padding-block-end: var(--sp-4);
  /* Firefox / standards scrollbar, kept subtle rather than hidden —
     a hidden scrollbar removes a real affordance. */
  scrollbar-width: thin;
  scrollbar-color: var(--line-strong) transparent;
}

.carousel__track::-webkit-scrollbar { height: 4px; }
.carousel__track::-webkit-scrollbar-thumb {
  background: var(--line-strong);
  border-radius: 999px;
}

.quote {
  scroll-snap-align: start;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: var(--sp-8);
  padding: var(--sp-8);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--surface);
}

.quote__body p,
.quote-card__body p {
  font-family: var(--font-display);
  font-size: var(--fs-md);
  font-weight: 500;
  line-height: 1.4;
  letter-spacing: -0.015em;
  text-wrap: pretty;
}

.quote__who,
.quote-card__who { display: flex; align-items: center; gap: var(--sp-3); }

.quote__name,
.quote-card__name {
  display: block;
  font-size: var(--fs-xs);
  font-weight: 600;
  color: var(--paper);
}

.quote__role,
.quote-card__role {
  display: block;
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  letter-spacing: 0.04em;
  color: var(--slate);
}

.carousel__controls {
  display: flex;
  align-items: center;
  gap: var(--sp-4);
  margin-block-start: var(--sp-6);
}

.carousel__btn {
  display: grid;
  place-content: center;
  width: 2.75rem;
  height: 2.75rem;
  border: 1px solid var(--line-strong);
  border-radius: 50%;
  color: var(--paper);
  cursor: pointer;
  transition: border-color var(--dur-fast) var(--ease-soft),
              color var(--dur-fast) var(--ease-soft),
              transform var(--dur-fast) var(--ease-out);
}

.carousel__btn:hover:not([disabled]) {
  border-color: var(--signal);
  color: var(--signal);
  transform: scale(1.06);
}

.carousel__btn[disabled] { opacity: 0.35; cursor: default; }

.carousel__status {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: var(--track-mono);
  color: var(--slate);
}

/* ---- Testimonial grid cards -------------------------------- */

.quote-card {
  display: flex;
  flex-direction: column;
  gap: var(--sp-6);
  padding: var(--sp-8);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--surface);
  transition: border-color var(--dur) var(--ease-soft);
}

.quote-card:hover { border-color: var(--line-strong); }

.quote-card figure { display: flex; flex-direction: column; gap: var(--sp-6); flex: 1; }
.quote-card__body { flex: 1; }
.quote-card__link { font-size: var(--fs-xs); }
.quote-card__link a { color: var(--signal); text-decoration: none; }
.quote-card__link a:hover { text-decoration: underline; }

/* Monogram avatar — works with no image asset, and is the fallback
   slot if real headshots are added later. */
.avatar {
  flex: none;
  display: grid;
  place-content: center;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: 50%;
  border: 1px solid var(--line-strong);
  background: var(--surface-alt);
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  letter-spacing: 0.05em;
  color: var(--slate);
}

/* ============================================================
   Filter (journal)
   ============================================================ */

.filter { margin-block-end: clamp(2.5rem, 5vw, 3.5rem); }

.filter__label {
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  font-weight: 400;
  letter-spacing: var(--track-mono);
  text-transform: uppercase;
  color: var(--slate);
  margin-block-end: var(--sp-4);
}

.filter__row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
}

.filter__btn {
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  letter-spacing: var(--track-mono);
  text-transform: uppercase;
  color: var(--slate);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 0.45rem 0.85rem;
  cursor: pointer;
  transition: border-color var(--dur-fast) var(--ease-soft),
              color var(--dur-fast) var(--ease-soft),
              background-color var(--dur-fast) var(--ease-soft);
}

.filter__btn:hover { border-color: var(--line-strong); color: var(--paper); }

.filter__btn.is-active {
  background: var(--signal);
  border-color: var(--signal);
  color: var(--ink);
  font-weight: 500;
}

.filter__count {
  margin-block-start: var(--sp-4);
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  letter-spacing: 0.04em;
  color: var(--slate);
}

.filter__empty {
  padding-block: var(--sp-12);
  text-align: center;
  color: var(--slate);
}

.filter__empty a { color: var(--signal); }

/* ============================================================
   Editorial: code, tables, pull quotes
   ============================================================ */

/* Structured for a syntax highlighter to be dropped in later:
   token spans (.tok-kw, .tok-str, …) can be added inside <code>
   without touching this rule set. */
.code {
  position: relative;
  overflow-x: auto;
  padding: var(--sp-6);
  padding-block-start: var(--sp-8);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: #080C11;
  font-size: var(--fs-xs);
  line-height: 1.7;
  tab-size: 2;
}

.code code {
  display: block;
  min-width: max-content;
  color: color-mix(in srgb, var(--paper) 85%, var(--slate));
  white-space: pre;
}

/* The language label, in the same mono annotation voice as `// case-study` */
.code[data-lang]::before {
  content: "// " attr(data-lang);
  position: absolute;
  inset-block-start: var(--sp-3);
  inset-inline-start: var(--sp-6);
  font-family: var(--font-mono);
  font-size: 0.625rem;
  letter-spacing: var(--track-mono);
  text-transform: uppercase;
  color: var(--slate);
  opacity: 0.7;
}

.pull-quote {
  margin-block: var(--sp-12) !important;
  padding-inline-start: var(--sp-8);
  border-inline-start: 2px solid var(--signal);
}

.pull-quote p {
  font-family: var(--font-display);
  font-size: var(--fs-h3);
  font-weight: 500;
  line-height: 1.35;
  letter-spacing: -0.02em;
  color: var(--paper);
  text-wrap: pretty;
}

/* Wide content scrolls inside its own box; the page body never does. */
.table-scroll {
  overflow-x: auto;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  scrollbar-width: thin;
  scrollbar-color: var(--line-strong) transparent;
}

.data-table {
  width: 100%;
  min-width: 34rem;
  font-size: var(--fs-xs);
}

.data-table caption {
  padding: var(--sp-4) var(--sp-5, 1.25rem);
  text-align: start;
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  letter-spacing: 0.04em;
  color: var(--slate);
  border-block-end: 1px solid var(--line);
}

.data-table th,
.data-table td {
  padding: var(--sp-3) var(--sp-5, 1.25rem);
  text-align: start;
  border-block-end: 1px solid var(--line);
}

.data-table thead th {
  font-family: var(--font-mono);
  font-size: 0.625rem;
  font-weight: 500;
  letter-spacing: var(--track-mono);
  text-transform: uppercase;
  color: var(--slate);
}

.data-table tbody th {
  font-weight: 500;
  color: var(--paper);
}

.data-table tbody td { color: var(--trace); font-family: var(--font-mono); }
.data-table tbody tr:last-child th,
.data-table tbody tr:last-child td { border-block-end: none; }

/* ============================================================
   Case study page furniture
   ============================================================ */

.crumb {
  padding-block: var(--sp-6);
  border-block-end: 1px solid var(--line);
}

.crumb ol {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-2);
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  letter-spacing: 0.04em;
  color: var(--slate);
}

.crumb li + li::before { content: "/ "; color: var(--line-strong); }
.crumb a { text-decoration: none; }
.crumb [aria-current] { color: var(--paper); }

.case-fact dt {
  font-family: var(--font-mono);
  font-size: 0.625rem;
  letter-spacing: var(--track-mono);
  text-transform: uppercase;
  color: var(--slate);
}

.case-fact dd {
  margin-block-start: var(--sp-2);
  margin-inline-start: 0;
  font-size: var(--fs-xs);
  color: var(--paper);
}

.case-hero__media figcaption,
.article-head__media figcaption,
.product__media figcaption {
  margin-block-start: var(--sp-3);
  font-size: var(--fs-xs);
  color: var(--slate);
  max-width: 60ch;
}

/* figcaption sits outside the bordered media box */
.case-hero__media,
.article-head__media {
  border: none;
  background: none;
  border-radius: 0;
}

.case-hero__media img,
.article-head__media img {
  width: 100%;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--surface);
}

.case-quote {
  margin-block-start: clamp(3rem, 7vw, 5rem);
  padding: clamp(var(--sp-8), 4vw, var(--sp-12));
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--surface);
  max-width: 60rem;
}

.case-quote blockquote p {
  font-family: var(--font-display);
  font-size: var(--fs-h3);
  font-weight: 500;
  line-height: 1.35;
  letter-spacing: -0.02em;
  text-wrap: pretty;
}

.case-quote figcaption {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  margin-block-start: var(--sp-8);
}

.case-quote__name {
  display: block;
  font-size: var(--fs-xs);
  font-weight: 600;
}

.case-quote__role {
  display: block;
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  color: var(--slate);
}

.case-next { border-block-start: 1px solid var(--line); }

.case-next__link {
  display: block;
  padding-block: clamp(2.5rem, 5vw, 4rem);
  text-decoration: none;
  color: inherit;
}

.case-next__link:hover { color: inherit; }

.case-next__label {
  display: block;
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  letter-spacing: var(--track-mono);
  text-transform: uppercase;
  color: var(--signal);
}

.case-next__title {
  display: block;
  margin-block-start: var(--sp-4);
  font-family: var(--font-display);
  font-size: var(--fs-h2);
  font-weight: 700;
  letter-spacing: var(--track-display);
  line-height: var(--lh-snug);
  max-width: 20ch;
  transition: color var(--dur-fast) var(--ease-soft);
}

.case-next__link:hover .case-next__title { color: var(--signal); }

.case-next__meta {
  display: block;
  margin-block-start: var(--sp-4);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  color: var(--slate);
}

/* ============================================================
   Article page
   ============================================================ */

/* Reading progress — the trace idea at article scale.
   Sits above the sticky header (z-index 100), not behind it — the
   header's backdrop is opaque enough to swallow a 2px bar. */
.read-progress {
  position: fixed;
  inset-block-start: 0;
  inset-inline: 0;
  height: 2px;
  z-index: 101;
  background: transparent;
  pointer-events: none;
}

.read-progress > span {
  display: block;
  height: 100%;
  width: 0;                  /* set by blog.js */
  background: var(--trace);
  transform-origin: left;
}

.article-head__cat { margin-block-end: var(--sp-6); }

.article-head__title {
  font-size: var(--fs-h1-page);
  max-width: 20ch;
}

.article-head__standfirst {
  margin-block-start: var(--sp-6);
  font-size: var(--fs-md);
  color: var(--slate);
  max-width: 54ch;
}

.article-head__meta {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  margin-block-start: var(--sp-8);
  padding-block-start: var(--sp-6);
  border-block-start: 1px solid var(--line);
}

.article-head__author { font-size: var(--fs-xs); font-weight: 600; }

.article-head__sub {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  letter-spacing: 0.04em;
  color: var(--slate);
}

.article-cta {
  margin-block-start: clamp(3rem, 7vw, 4.5rem);
  padding: clamp(var(--sp-8), 4vw, var(--sp-12));
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--surface);
}

.article-cta__title { margin-block-start: var(--sp-4); font-size: var(--fs-h3); }

.article-cta__lead {
  margin-block: var(--sp-4) var(--sp-8);
  color: var(--slate);
  max-width: 48ch;
}

/* ============================================================
   Closing CTA block
   ============================================================ */

.section--cta { border-block-start: 1px solid var(--line); }

.cta-block { max-width: 44rem; }
.cta-block__title { margin-block-start: var(--sp-4); font-size: var(--fs-h2); }

.cta-block__lead {
  margin-block: var(--sp-6) var(--sp-8);
  font-size: var(--fs-md);
  color: var(--slate);
}

.cta-block__aside {
  margin-block-start: var(--sp-6);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  color: var(--slate);
}

.cta-block__aside a { color: var(--signal); }

/* ============================================================
   About page
   ============================================================ */

.fact-card {
  padding: var(--sp-8);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--surface);
}

.fact-card__title {
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: var(--track-mono);
  text-transform: uppercase;
  color: var(--slate);
}

.fact-list { display: grid; gap: var(--sp-4); margin-block-start: var(--sp-6); }

.fact {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--sp-3);
  padding-block-end: var(--sp-4);
  border-block-end: 1px solid var(--line);
}

.fact:last-child { border-block-end: none; padding-block-end: 0; }

.fact dt { font-size: var(--fs-xs); color: var(--slate); }

.fact dd {
  margin-inline-start: 0;
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  color: var(--paper);
  text-align: end;
}

.fact-card__note {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  margin-block: var(--sp-6);
  font-size: var(--fs-xs);
  color: var(--slate);
}

.fact-card__note a { color: var(--signal); }

.wont-list { display: grid; gap: var(--sp-8); }

@media (min-width: 768px) { .wont-list { grid-template-columns: repeat(2, 1fr); gap: var(--sp-12); } }

.wont {
  padding-block-start: var(--sp-6);
  border-block-start: 1px solid var(--line);
}

.wont__title { font-size: var(--fs-md); }
.wont p { margin-block-start: var(--sp-3); color: var(--slate); font-size: var(--fs-xs); }

/* ============================================================
   Booking flow
   ============================================================ */

/* Stepper — trace vocabulary (node, rail, amber = here) at component scale. */
.stepper {
  display: flex;
  gap: var(--sp-8);
  margin-block-end: var(--sp-12);
  padding-block-end: var(--sp-6);
  border-block-end: 1px solid var(--line);
}

.stepper__step {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--sp-3);
}

/* The connector between the two step nodes. */
.stepper__step:not(:last-child)::after {
  content: "";
  position: absolute;
  inset-inline-start: 100%;
  inset-block-start: 50%;
  width: var(--sp-8);
  height: 1px;
  background: var(--line);
}

.stepper__node {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  border: 1px solid var(--line-strong);
  background: var(--ink);
  transition: background-color var(--dur) var(--ease-soft),
              border-color var(--dur) var(--ease-soft);
}

.stepper__step.is-active .stepper__node,
.stepper__step.is-done .stepper__node {
  background: var(--signal);
  border-color: var(--signal);
}

.stepper__num,
.stepper__label {
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  letter-spacing: var(--track-mono);
  text-transform: uppercase;
  color: var(--slate);
  transition: color var(--dur) var(--ease-soft);
}

.stepper__step.is-active .stepper__label,
.stepper__step.is-active .stepper__num { color: var(--paper); }

/* ---- Form -------------------------------------------------- */

.form__group { border: none; padding: 0; }
.form__group + .form__group { margin-block-start: var(--sp-12); }

.form__legend {
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  letter-spacing: var(--track-mono);
  text-transform: uppercase;
  color: var(--signal);
  padding: 0;
  margin-block-end: var(--sp-6);
}

.field + .field,
.field-row + .field,
.field + .field-row { margin-block-start: var(--sp-6); }

.field-row { display: grid; gap: var(--sp-6); }
@media (min-width: 480px) { .field-row { grid-template-columns: repeat(2, 1fr); } }

.field__label {
  display: block;
  font-size: var(--fs-xs);
  font-weight: 500;
  margin-block-end: var(--sp-2);
}

.field__req { color: var(--signal); }

.field__optional {
  font-family: var(--font-mono);
  font-size: 0.625rem;
  letter-spacing: var(--track-mono);
  text-transform: uppercase;
  color: var(--slate);
  font-weight: 400;
}

.field__help {
  font-size: var(--fs-xs);
  color: var(--slate);
  margin-block-end: var(--sp-3);
  max-width: 52ch;
}

.field__input {
  width: 100%;
  padding: var(--sp-3) var(--sp-4);
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  color: var(--paper);
  font-size: var(--fs-sm);
  transition: border-color var(--dur-fast) var(--ease-soft),
              background-color var(--dur-fast) var(--ease-soft);
}

.field__input::placeholder { color: var(--slate); }
.field__input:hover { border-color: var(--slate); }
.field__textarea { resize: vertical; min-height: 8rem; line-height: 1.6; }

/* Native select arrow removed and redrawn so it matches on every OS. */
.field__select-wrap { position: relative; }

.field__select {
  appearance: none;
  -webkit-appearance: none;
  padding-inline-end: var(--sp-12);
  cursor: pointer;
}

.field__select-wrap::after {
  content: "";
  position: absolute;
  inset-inline-end: var(--sp-4);
  inset-block-start: 50%;
  width: 8px;
  height: 8px;
  margin-block-start: -6px;
  border-inline-end: 1.5px solid var(--slate);
  border-block-end: 1.5px solid var(--slate);
  transform: rotate(45deg);
  pointer-events: none;
}

/* Options inherit the OS dropdown surface, so set both explicitly. */
.field__select option { background: var(--ink); color: var(--paper); }

/* ---- Validation states ------------------------------------- */

.field__input[aria-invalid="true"] {
  border-color: #FF7B72;
  background: rgba(255, 123, 114, 0.06);
}

.field__error {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  margin-block-start: var(--sp-2);
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  letter-spacing: 0.02em;
  color: #FF9C94;                    /* 6.4:1 on --ink */
}

.field__error::before { content: "!"; font-weight: 500; }

.field__foot {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--sp-3);
}

.field__count {
  margin-block-start: var(--sp-2);
  margin-inline-start: auto;
  font-family: var(--font-mono);
  font-size: 0.625rem;
  letter-spacing: 0.04em;
  color: var(--slate);
}

.form__alert {
  margin-block-start: var(--sp-8);
  padding: var(--sp-4) var(--sp-5, 1.25rem);
  border: 1px solid rgba(255, 123, 114, 0.4);
  background: rgba(255, 123, 114, 0.08);
  border-radius: var(--radius);
  font-size: var(--fs-xs);
  color: #FF9C94;
}

.form__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-6);
  margin-block-start: var(--sp-12);
}

.form__note {
  font-size: var(--fs-xs);
  color: var(--slate);
  max-width: 28ch;
}

/* ---- Step 2 / success -------------------------------------- */

.booking-step__title { font-size: var(--fs-h2); }

.booking-step__lead {
  margin-block: var(--sp-4) var(--sp-8);
  color: var(--slate);
  max-width: 52ch;
}

/* Calendly inline widget mount.

   Two things this rule has to get right:

   1. A DEFINITE height, not min-height. Calendly's stylesheet sizes its
      iframe with `height: 100%`, which resolves to zero against an
      auto-height parent — the iframe collapses to its 150px default and
      leaves a void below it. min-height does not satisfy a percentage
      height; only an explicit height does.

   2. A transparent background. The embed URL passes background_color,
      so the widget renders dark to match the page. Any colour set here
      shows through as a border of the wrong shade around the iframe.

   Mobile-first: Calendly stacks the month and the times on narrow
   screens and needs substantially more room than the desktop layout. */
/* Calendly inline embed mount.

   THE WIDTH IS LOAD-BEARING. Calendly's booking card is a fixed 644px
   and it centres itself in whatever space the iframe gives it, painting
   the leftover in white. That white sits inside a cross-origin iframe,
   so it cannot be styled away from here — but capping the container at
   the card's own width means there is no leftover to paint. Measured
   from the rendered embed: 644px card + 1px borders each side.

   Widen this and white gutters reappear down both edges. Verified at
   646px there is no white anywhere, top or sides.

   Two other requirements:
   - A DEFINITE height. Calendly sizes its iframe with `height: 100%`,
     which resolves to zero against an auto-height parent; the iframe
     then falls back to its intrinsic 150px and leaves a void below.
     min-height does not satisfy a percentage height — only height does.
   - position: relative, to anchor Calendly's absolutely-positioned
     loading spinner inside the container rather than the page. */
.schedule-embed {
  position: relative;
  max-width: 646px;
  height: 1120px;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: transparent;
  overflow: hidden;
}

/* Supplied here rather than by adding Calendly's own
   `calendly-inline-widget` class to the mount — see the comment on the
   mount element in contact.html for why that class cannot be used. */
.schedule-embed iframe {
  display: block;
  width: 100%;
  height: 100%;
  border: 0;
}

@media (min-width: 768px) {
  .schedule-embed { height: 760px; }
}

/* Deliberately no `:empty { height: 0 }` rule here. Calendly measures the
   container when it initialises, and a zero-height parent makes it inject
   nothing at all. The mount lives inside the step-2 panel, which is
   hidden until the form succeeds, so an empty sized box is never on
   screen anyway. */

.booking-fallback {
  padding: var(--sp-8);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--surface);
}

.booking-fallback__title {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  font-family: var(--font-display);
  font-size: var(--fs-md);
  font-weight: 600;
  letter-spacing: -0.015em;
}

.booking-fallback__copy {
  margin-block-start: var(--sp-4);
  font-size: var(--fs-xs);
  color: var(--slate);
  max-width: 48ch;
}

.booking-fallback__copy a { color: var(--signal); }

.booking-step__back { margin-block-start: var(--sp-8); }

.booking-success {
  padding: clamp(var(--sp-8), 4vw, var(--sp-12));
  border: 1px solid color-mix(in srgb, var(--signal) 30%, var(--line));
  border-radius: var(--radius-lg);
  background: var(--surface);
}

.booking-success__mark {
  display: grid;
  place-content: center;
  width: 2.75rem;
  height: 2.75rem;
  border-radius: 50%;
  background: var(--signal);
  color: var(--ink);
  font-size: var(--fs-md);
  font-weight: 700;
}

.booking-success__title { margin-block-start: var(--sp-6); font-size: var(--fs-h2); }

.booking-success__copy {
  margin-block-start: var(--sp-4);
  color: var(--slate);
  max-width: 50ch;
}

.booking-success__copy a { color: var(--signal); }
.booking-success__actions { margin-block-start: var(--sp-8); }

/* ---- "What happens next" ----------------------------------- */

.next-list { display: grid; gap: var(--sp-6); margin-block-start: var(--sp-6); }

.next { display: flex; gap: var(--sp-4); }

.next__num {
  flex: none;
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  letter-spacing: var(--track-mono);
  color: var(--signal);
  padding-block-start: 0.15rem;
}

.next__title { font-size: var(--fs-xs); font-weight: 600; font-family: var(--font-body); letter-spacing: 0; }
.next p { margin-block-start: var(--sp-2); font-size: var(--fs-xs); color: var(--slate); }

/* ============================================================
   Footer
   ============================================================ */

.site-footer__brand { display: grid; gap: var(--sp-4); align-content: start; }

.site-footer__brand .wordmark { margin-inline-end: 0; justify-self: start; }

.site-footer__blurb {
  font-size: var(--fs-xs);
  color: var(--slate);
  max-width: 34ch;
}

.site-footer__heading {
  font-family: var(--font-mono);
  font-size: 0.625rem;
  font-weight: 500;
  letter-spacing: var(--track-mono);
  text-transform: uppercase;
  color: var(--slate);
  margin-block-end: var(--sp-4);
}

.site-footer__col ul { display: grid; gap: var(--sp-3); }

.site-footer__col a {
  font-size: var(--fs-xs);
  text-decoration: none;
  color: var(--paper);
}

.site-footer__col a:hover { color: var(--signal); }

.site-footer__plain { font-size: var(--fs-xs); color: var(--slate); }

.site-footer__mono {
  font-family: var(--font-mono);
  letter-spacing: 0.04em;
}

/* ============================================================
   404
   ============================================================ */

.broken-trace { width: 100%; max-width: 30rem; margin-block: var(--sp-8); }
.broken-trace__live { stroke: var(--trace); stroke-width: 1.5; }
.broken-trace__dead { stroke: var(--line-strong); stroke-width: 1.5; }
.broken-trace__node { fill: var(--ink); stroke: var(--trace); stroke-width: 1.5; }
.broken-trace__dead-node { fill: var(--ink); stroke: var(--line-strong); stroke-width: 1.5; }
.broken-trace__break { stroke: var(--signal); stroke-width: 1.5; stroke-linecap: round; }

.error-page__title { font-size: var(--fs-h1-page); }

.error-page__lead {
  margin-block-start: var(--sp-6);
  font-size: var(--fs-md);
  color: var(--slate);
  max-width: 46ch;
}

.error-page__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-4);
  margin-block-start: var(--sp-8);
}

.error-page__links {
  margin-block-start: clamp(3rem, 6vw, 4rem);
  padding-block-start: var(--sp-8);
  border-block-start: 1px solid var(--line);
}

.error-page__links-title {
  font-family: var(--font-mono);
  font-size: 0.625rem;
  font-weight: 500;
  letter-spacing: var(--track-mono);
  text-transform: uppercase;
  color: var(--slate);
  margin-block-end: var(--sp-4);
}

.error-page__links ul { display: grid; gap: var(--sp-3); }
.error-page__links a { font-weight: 500; text-decoration: none; color: var(--paper); }
.error-page__links a:hover { color: var(--signal); }
.error-page__hint { font-size: var(--fs-xs); color: var(--slate); }

/* ============================================================
   Trace marks — only rendered as a labelled spine ≥1200px
   ============================================================ */

@media (min-width: 1200px) {
  .trace { pointer-events: none; }

  .trace__mark a {
    pointer-events: auto;
    display: flex;
    align-items: center;
    gap: var(--sp-3);
    padding: var(--sp-2) var(--sp-3);
    margin-inline-start: calc(var(--sp-3) * -1);
    border-radius: var(--radius-sm);
    text-decoration: none;
    white-space: nowrap;
  }

  .trace__num,
  .trace__label {
    font-family: var(--font-mono);
    font-size: 0.625rem;
    letter-spacing: var(--track-mono);
    text-transform: uppercase;
    color: var(--slate);
    transition: color var(--dur) var(--ease-soft);
  }

  .trace__num { color: var(--line-strong); }

  /* A tick on the rail for each mark. */
  .trace__mark a::before {
    content: "";
    position: absolute;
    inset-inline-start: calc(var(--sp-3) * -1);
    inset-block-start: 50%;
    width: 7px;
    height: 1px;
    margin-inline-start: -3px;
    background: var(--line-strong);
    transition: background-color var(--dur) var(--ease-soft),
                width var(--dur) var(--ease-out);
  }

  .trace__mark a:hover .trace__label,
  .trace__mark a:focus-visible .trace__label { color: var(--paper); }

  .trace__mark.is-active .trace__label { color: var(--signal); }
  .trace__mark.is-active .trace__num { color: var(--slate); }
  .trace__mark.is-active a::before { background: var(--signal); width: 11px; }
}


/* ============================================================
   Landing page (/ai-receptionist/)

   A conversion page for a different audience than the rest of the
   site: local business owners arriving from cold outreach, mostly on
   a phone. Same tokens and components, fewer of them, and no nav —
   every extra link is a way to leave without converting.
   ============================================================ */

/* Nav is absent here by design, so the CTA carries the right edge
   alone and must show at every width — unlike the main header, where
   it shares space with the menu. */
.lp-header__cta { display: inline-flex; }

.lp-hero {
  padding-block: clamp(3rem, 9vw, 6rem) clamp(2.5rem, 6vw, 4rem);
  border-block-end: 1px solid var(--line);
}

.lp-hero__title {
  margin-block-start: var(--sp-6);
  font-size: var(--fs-h1);
  max-width: 17ch;
}

.lp-hero__lead {
  margin-block-start: var(--sp-6);
  font-size: var(--fs-md);
  color: var(--slate);
  max-width: 50ch;
}

.lp-hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-4);
  margin-block-start: var(--sp-8);
}

.lp-hero__note {
  margin-block-start: var(--sp-4);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  color: var(--slate);
}

.lp-hero__note a { color: var(--signal); }

.lp-steps { max-width: 44rem; gap: var(--sp-8); }

/* ---- FAQ: native <details>, so it works with no JS ---------- */

.faq {
  border-block-start: 1px solid var(--line);
  max-width: 44rem;
}

.faq__item { border-block-end: 1px solid var(--line); }

.faq__q {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-4);
  padding-block: var(--sp-5);
  font-family: var(--font-display);
  font-size: var(--fs-md);
  font-weight: 600;
  letter-spacing: -0.015em;
  cursor: pointer;
  list-style: none;
}

/* Remove the default marker in every engine, then draw our own. */
.faq__q::-webkit-details-marker { display: none; }

.faq__q::after {
  content: "+";
  flex: none;
  font-family: var(--font-mono);
  font-size: var(--fs-md);
  color: var(--signal);
  transition: transform var(--dur) var(--ease-out);
}

.faq__item[open] .faq__q::after { content: "2"; }

.faq__q:focus-visible {
  outline: 2px solid var(--signal);
  outline-offset: 2px;
}

.faq__a { padding-block-end: var(--sp-6); }

.faq__a p {
  color: var(--slate);
  max-width: 58ch;
}

/* ---- Closing CTA ------------------------------------------- */

.lp-cta {
  display: grid;
  gap: clamp(2.5rem, 6vw, 4rem);
  align-items: start;
}

@media (min-width: 900px) {
  .lp-cta { grid-template-columns: 1fr 22rem; }
}

.lp-cta__form {
  padding: var(--sp-8);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--surface);
}

.lp-form__title {
  font-size: var(--fs-md);
  margin-block-end: var(--sp-6);
}

.lp-cta__form .form__actions { margin-block-start: var(--sp-8); }
.lp-cta__form .btn { width: 100%; }

.lp-footer { border-block-start: none; }

/* ============================================================
   Samples gallery (/samples/)

   Cards are generated by scripts/build-samples.py from whatever sits in
   work-samples/, so this has to look right for media of any aspect ratio
   and any count. Frames use a fixed 16:10 box with object-fit: cover
   rather than honouring intrinsic ratios — a grid of mismatched heights
   reads as broken, and these are all screen recordings where a little
   crop costs nothing.
   ============================================================ */

.sample-grid {
  display: grid;
  gap: clamp(2rem, 4vw, 3rem);
  grid-template-columns: 1fr;
}

@media (min-width: 860px) {
  .sample-grid { grid-template-columns: repeat(2, 1fr); }
}

.sample__frame {
  position: relative;
  aspect-ratio: 16 / 10;
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--surface);
  transition: border-color var(--dur) var(--ease-soft);
}

.sample:hover .sample__frame { border-color: var(--line-strong); }

.sample__media {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Sits over the media, so it needs its own contrast rather than relying
   on whatever frame happens to be underneath it. */
.sample__toggle {
  position: absolute;
  inset-block-end: var(--sp-3);
  inset-inline-end: var(--sp-3);
  z-index: 1;
  padding: 0.4rem 0.8rem;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  background: var(--ink-veil);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  letter-spacing: var(--track-mono);
  text-transform: uppercase;
  color: var(--paper);
  cursor: pointer;
  opacity: 0;
  transition: opacity var(--dur) var(--ease-soft),
              border-color var(--dur-fast) var(--ease-soft),
              color var(--dur-fast) var(--ease-soft);
}

/* Hidden until wanted on a pointer device, but always present for keyboard
   and touch — a control that only exists on hover is not a control. */
.sample:hover .sample__toggle,
.sample__toggle:focus-visible { opacity: 1; }

@media (hover: none) {
  .sample__toggle { opacity: 1; }
}

.sample__toggle:hover {
  border-color: var(--signal);
  color: var(--signal);
}

.sample__body { margin-block-start: var(--sp-5); }

.sample__title { font-size: var(--fs-md); }

.sample__blurb {
  margin-block-start: var(--sp-3);
  font-size: var(--fs-xs);
  color: var(--slate);
  max-width: 52ch;
}

.sample__body .tags { margin-block-start: var(--sp-4); }

.sample--empty {
  grid-column: 1 / -1;
  padding: var(--sp-12);
  border: 1px dashed var(--line-strong);
  border-radius: var(--radius-lg);
  text-align: center;
  color: var(--slate);
}

.sample--empty code {
  font-family: var(--font-mono);
  color: var(--trace);
}

@media (prefers-reduced-motion: reduce) {
  .sample__toggle { opacity: 1; }
}
