/* ==========================================================================
   Components. Reusable UI shared across every page.
   ========================================================================== */

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

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-2);
  padding: 0.85em 1.6em;
  min-height: 48px; /* comfortable touch target */
  font-family: var(--font-display);
  font-size: var(--fs-sm);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  text-decoration: none;
  text-align: center;
  border: 2px solid transparent;
  border-radius: var(--radius);
  transition: background var(--t-fast), color var(--t-fast), border-color var(--t-fast),
    transform var(--t-fast);
}

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

.btn--primary {
  background: var(--red);
  border-color: var(--red);
  color: #fff;
}

.btn--primary:hover {
  background: var(--red-hover);
  border-color: var(--red-hover);
  color: #fff;
}

.btn--dark {
  background: var(--ink-900);
  border-color: var(--ink-900);
  color: #fff;
}

.btn--dark:hover {
  background: var(--ink-700);
  border-color: var(--ink-700);
  color: #fff;
}

.btn--ghost {
  background: transparent;
  border-color: var(--border-strong);
  color: var(--text);
}

.btn--ghost:hover {
  border-color: var(--ink-900);
  color: var(--ink-900);
}

/* On dark surfaces */
.btn--on-deep {
  background: transparent;
  border-color: rgba(255, 255, 255, 0.4);
  color: #fff;
}

.btn--on-deep:hover {
  background: #fff;
  border-color: #fff;
  color: var(--ink-900);
}

.btn--lg {
  font-size: var(--fs-base);
  padding: 1em 2em;
  min-height: 56px;
}

.btn--block {
  width: 100%;
}

.btn-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-3);
}

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

.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: var(--ink-900);
  border-bottom: 1px solid rgba(255, 255, 255, 0.09);
}

.site-header__inner {
  display: flex;
  align-items: center;
  gap: var(--s-5);
  min-height: var(--header-h);
  max-width: var(--container-wide);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

/* --------------------------------------------------------------------------
   The SC mark. Inlined from the supplied vector rather than loaded as an
   image, so the S can inherit currentColor and the same markup works on the
   dark header and on light surfaces. The C keeps the exact brand red.
   Aspect ratio is 2.4785 (viewBox 246.19 x 99.33).
   -------------------------------------------------------------------------- */

.sc-mark {
  flex: none;
  display: block;
  height: 26px;
  width: calc(26px * 2.4785);
  overflow: visible;
}

.sc-mark__s {
  fill: currentColor;
}

.sc-mark__c {
  fill: var(--red-brand);
}

.brand {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  flex: none;
  text-decoration: none;
  margin-right: auto;
  /* Sets the S. The C stays red. */
  color: #fff;
}

/* The global `a:hover` recolours every link to --red-deep, and the brand is a
   link. Here that colour is load bearing rather than decorative: it is what
   the mark's S inherits through currentColor. Left alone it dragged the S to a
   dark red on hover, and it would make the hover swap in motion.css trade the
   C for dark red instead of white. Pin it. */
.brand:hover,
.brand:focus-visible {
  color: #fff;
}

.brand__text {
  display: flex;
  flex-direction: column;
  gap: 1px;
  padding-left: var(--s-3);
  border-left: 1px solid rgba(255, 255, 255, 0.2);
}

.brand__name {
  font-family: var(--font-display);
  font-size: 0.9rem;
  font-weight: 700;
  letter-spacing: 0.055em;
  text-transform: uppercase;
  line-height: 1.1;
  color: #fff;
  white-space: nowrap;
}

.brand__sub {
  font-family: var(--font-body);
  font-size: 0.62rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  line-height: 1.1;
  color: var(--steel-300);
  white-space: nowrap;
}

@media (min-width: 600px) {
  .brand .sc-mark {
    height: 30px;
    width: calc(30px * 2.4785);
  }

  .brand__name {
    font-size: 1rem;
  }
}

/* Below 480px the mark, the wordmark and the menu button do not all fit:
   at 375px the set overflows by roughly 48px and pushes the toggle off the
   edge. Drop the wordmark and let the mark carry the header on phones. */
@media (max-width: 479px) {
  .brand__text {
    display: none;
  }

  .brand .sc-mark {
    height: 30px;
    width: calc(30px * 2.4785);
  }
}

.nav {
  display: flex;
  align-items: center;
  gap: var(--s-1);
}

.nav a {
  position: relative;
  padding: var(--s-3) var(--s-4);
  font-family: var(--font-display);
  font-size: var(--fs-sm);
  font-weight: 600;
  letter-spacing: 0.045em;
  text-transform: uppercase;
  text-decoration: none;
  color: rgba(255, 255, 255, 0.78);
  border-radius: var(--radius-sm);
  transition: color var(--t-fast);
}

.nav a:hover {
  color: #fff;
}

/* Red underline marks the current section. */
.nav a[aria-current='page']::after {
  content: '';
  position: absolute;
  left: var(--s-4);
  right: var(--s-4);
  bottom: 4px;
  height: 2px;
  background: var(--red);
}

.nav a[aria-current='page'] {
  color: #fff;
}

.nav__phone {
  display: none;
  align-items: center;
  gap: var(--s-2);
  margin-left: var(--s-3);
  padding: var(--s-3) var(--s-5);
  background: var(--red);
  color: #fff !important;
  border-radius: var(--radius);
  white-space: nowrap;
}

.nav__phone:hover {
  background: var(--red-hover);
}

.nav__phone::after {
  display: none !important;
}

.nav-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 46px;
  height: 46px;
  flex: none;
  color: #fff;
  border: 1px solid rgba(255, 255, 255, 0.22);
  border-radius: var(--radius);
}

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

  .nav__phone {
    display: inline-flex;
  }
}

/* Mobile drawer */
@media (max-width: 999px) {
  .nav {
    position: fixed;
    inset: var(--header-h) 0 0 0;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    padding: var(--s-4) var(--gutter) var(--s-8);
    background: var(--ink-900);
    overflow-y: auto;
    transform: translateX(100%);
    visibility: hidden;
    transition: transform var(--t), visibility var(--t);
  }

  .nav[data-open='true'] {
    transform: translateX(0);
    visibility: visible;
  }

  .nav a {
    padding: var(--s-5) var(--s-2);
    font-size: var(--fs-lg);
    border-bottom: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 0;
  }

  .nav a[aria-current='page']::after {
    left: var(--s-2);
    right: auto;
    width: 24px;
    bottom: var(--s-3);
  }

  .nav__phone {
    display: flex;
    justify-content: center;
    margin: var(--s-5) 0 0;
    border-bottom: none;
    font-size: var(--fs-base);
  }
}

/* --------------------------------------------------------------------------
   Sticky mobile call bar. Phone is the primary conversion, so it is always
   one thumb-tap away. Hidden on desktop where the header phone shows.
   -------------------------------------------------------------------------- */

.callbar {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 90;
  display: grid;
  grid-template-columns: 1fr 1fr;
  background: var(--ink-900);
  border-top: 1px solid rgba(255, 255, 255, 0.12);
  padding-bottom: env(safe-area-inset-bottom);
}

.callbar a {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-2);
  min-height: 56px;
  font-family: var(--font-display);
  font-size: var(--fs-sm);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  text-decoration: none;
  color: #fff;
}

.callbar a:first-child {
  background: var(--red);
}

.callbar a:first-child:hover {
  background: var(--red-hover);
  color: #fff;
}

@media (min-width: 1000px) {
  .callbar {
    display: none;
  }
}

@media (max-width: 999px) {
  /* Keep the call bar from covering the end of the page. */
  body {
    padding-bottom: 56px;
  }
}

/* --------------------------------------------------------------------------
   Hero
   -------------------------------------------------------------------------- */

.hero {
  position: relative;
  display: flex;
  align-items: flex-end;
  min-height: clamp(460px, 72vh, 760px);
  background: var(--ink-900);
  overflow: hidden;
  isolation: isolate;
}

.hero__media {
  position: absolute;
  inset: 0;
  z-index: -2;
}

/* <picture> is a plain inline wrapper with auto height, so an img set to
   height:100% inside it resolves against the image's own height and
   collapses. The wrapper has to be stretched too. */
.hero__media picture {
  display: block;
  width: 100%;
  height: 100%;
}

.hero__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 62%;
}

/* Scrim. Keeps headline and body contrast past AA no matter what the photo
   underneath is doing. A flat wash carries the mid-tones, the gradient adds
   weight at the bottom where the copy sits. */
.hero::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(
      to top,
      rgba(11, 11, 12, 0.94) 0%,
      rgba(11, 11, 12, 0.78) 38%,
      rgba(11, 11, 12, 0.5) 72%,
      rgba(11, 11, 12, 0.58) 100%
    ),
    rgba(11, 11, 12, 0.18);
}

/* Portrait screens stack the copy over more of the image, so the wash has to
   do more work. */
@media (max-width: 640px) {
  .hero::after {
    background: linear-gradient(
        to top,
        rgba(11, 11, 12, 0.93) 0%,
        rgba(11, 11, 12, 0.82) 45%,
        rgba(11, 11, 12, 0.66) 100%
      ),
      rgba(11, 11, 12, 0.28);
  }
}

.hero__inner {
  position: relative;
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding: var(--s-9) var(--gutter) var(--s-8);
  color: #fff;
}

/* On a phone the hero would otherwise eat the whole screen and bury the
   fork. Tighten the vertical rhythm so the cards below still peek. */
@media (max-width: 640px) {
  .hero__inner {
    padding-top: var(--s-6);
    padding-bottom: var(--s-5);
  }

  .hero h1 {
    font-size: clamp(2.1rem, 8.4vw, 2.6rem);
    max-width: 14ch;
  }

  .hero .lede {
    margin-top: var(--s-4);
    font-size: var(--fs-base);
  }

  .hero .btn-row {
    margin-top: var(--s-5);
  }
}

.hero h1 {
  color: #fff;
  max-width: 17ch;
}

.hero .lede {
  color: rgba(255, 255, 255, 0.86);
  margin-top: var(--s-5);
  max-width: 52ch;
}

.hero .eyebrow {
  color: #fff;
}

.hero .btn-row {
  margin-top: var(--s-6);
}

.hero--compact {
  min-height: clamp(320px, 46vh, 460px);
}

/* Page header for interior pages with no photo. */
.page-head {
  background: var(--ink-900);
  color: #fff;
  padding-block: var(--s-8) var(--s-7);
}

.page-head h1 {
  color: #fff;
  max-width: 20ch;
}

.page-head .lede {
  color: rgba(255, 255, 255, 0.8);
  margin-top: var(--s-5);
}

/* --------------------------------------------------------------------------
   The fork: two paths from the home page.
   -------------------------------------------------------------------------- */

.fork {
  display: grid;
  gap: var(--s-5);
  grid-template-columns: 1fr;
}

@media (min-width: 800px) {
  .fork {
    grid-template-columns: 1fr 1fr;
  }
}

.fork__card {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  min-height: 340px;
  padding: var(--s-6);
  background: var(--ink-800);
  color: #fff;
  text-decoration: none;
  border-radius: var(--radius-lg);
  overflow: hidden;
  isolation: isolate;
  transition: transform var(--t);
}

.fork__card:hover {
  transform: translateY(-4px);
  color: #fff;
}

.fork__card img {
  position: absolute;
  inset: 0;
  z-index: -2;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform var(--t-slow);
}

.fork__card:hover img {
  transform: scale(1.045);
}

/* Bottom-weighted so the copy sits on near-solid ink while the top of the
   photo stays readable. Tuned against the short card height on phones,
   where a linear gradient otherwise swallows the whole image. */
.fork__card::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(
    to top,
    rgba(11, 11, 12, 0.96) 0%,
    rgba(11, 11, 12, 0.9) 30%,
    rgba(11, 11, 12, 0.55) 62%,
    rgba(11, 11, 12, 0.22) 100%
  );
}

.fork__card h2 {
  font-size: var(--fs-2xl);
  color: #fff;
}

.fork__card p {
  margin-top: var(--s-3);
  color: rgba(255, 255, 255, 0.82);
  font-size: var(--fs-base);
  max-width: 34ch;
}

.fork__go {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  margin-top: var(--s-5);
  font-family: var(--font-display);
  font-size: var(--fs-sm);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: #fff;
}

.fork__go svg {
  transition: transform var(--t-fast);
}

.fork__card:hover .fork__go svg {
  transform: translateX(5px);
}

/* --------------------------------------------------------------------------
   Cards
   -------------------------------------------------------------------------- */

.card {
  display: flex;
  flex-direction: column;
  padding: var(--s-6);
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
}

.card--flush {
  padding: 0;
  overflow: hidden;
}

.card__num {
  font-family: var(--font-display);
  font-size: var(--fs-sm);
  font-weight: 800;
  letter-spacing: var(--ls-caps);
  color: var(--accent-text);
  margin-bottom: var(--s-3);
}

.card h3 {
  margin-bottom: var(--s-3);
}

.card p {
  color: var(--text-muted);
  font-size: var(--fs-base);
}

.section--deep .card {
  background: rgba(255, 255, 255, 0.04);
  border-color: var(--border-on-deep);
}

.section--deep .card p {
  color: var(--text-on-deep-muted);
}

/* --------------------------------------------------------------------------
   Numbered process steps
   -------------------------------------------------------------------------- */

.steps {
  counter-reset: step;
  display: grid;
  gap: var(--s-5);
}

.step {
  position: relative;
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--s-5);
  align-items: start;
  padding-bottom: var(--s-5);
  border-bottom: 1px solid var(--border);
}

.step:last-child {
  border-bottom: 0;
  padding-bottom: 0;
}

.step::before {
  counter-increment: step;
  content: counter(step, decimal-leading-zero);
  font-family: var(--font-display);
  font-size: var(--fs-xl);
  font-weight: 800;
  line-height: 1;
  color: var(--red);
  min-width: 2.4ch;
}

.step h3 {
  margin-bottom: var(--s-2);
}

.step p {
  color: var(--text-muted);
  font-size: var(--fs-base);
}

/* --------------------------------------------------------------------------
   Facts, stats, spec lists
   -------------------------------------------------------------------------- */

.stats {
  display: grid;
  gap: var(--s-5);
  grid-template-columns: repeat(auto-fit, minmax(min(190px, 100%), 1fr));
}

.stat__n {
  display: block;
  font-family: var(--font-display);
  font-size: var(--fs-2xl);
  font-weight: 800;
  line-height: 1.05;
  letter-spacing: var(--ls-tight);
  color: var(--text);
}

.section--deep .stat__n {
  color: #fff;
}

.stat__l {
  display: block;
  margin-top: var(--s-2);
  font-size: var(--fs-sm);
  color: var(--text-muted);
}

.section--deep .stat__l {
  color: var(--text-on-deep-muted);
}

/* Definition-style spec table for capabilities. */
.specs {
  display: grid;
  gap: 0;
  margin: 0;
}

.specs > div {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--s-1);
  padding: var(--s-4) 0;
  border-bottom: 1px solid var(--border);
}

@media (min-width: 700px) {
  .specs > div {
    grid-template-columns: 15rem 1fr;
    gap: var(--s-5);
    align-items: baseline;
  }
}

.specs dt {
  font-family: var(--font-display);
  font-size: var(--fs-sm);
  font-weight: 700;
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: var(--text-muted);
}

.specs dd {
  margin: 0;
  font-size: var(--fs-base);
}

.section--deep .specs > div {
  border-color: var(--border-on-deep);
}

.section--deep .specs dt {
  color: var(--steel-300);
}

/* --------------------------------------------------------------------------
   License badge. Contractors routinely omit this; putting it forward is
   free credibility, especially for commercial buyers.
   -------------------------------------------------------------------------- */

.license {
  display: inline-flex;
  align-items: center;
  gap: var(--s-4);
  padding: var(--s-4) var(--s-5);
  background: var(--bg-alt);
  border: 1px solid var(--border);
  border-left: 3px solid var(--red);
  border-radius: var(--radius);
}

.license__mark {
  flex: none;
  color: var(--red);
}

.license__t {
  font-family: var(--font-display);
  font-size: var(--fs-sm);
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  line-height: 1.3;
}

.license__s {
  display: block;
  margin-top: 2px;
  font-family: var(--font-body);
  font-size: var(--fs-sm);
  font-weight: 400;
  letter-spacing: 0;
  text-transform: none;
  color: var(--text-muted);
}

.section--deep .license {
  background: rgba(255, 255, 255, 0.05);
  border-color: var(--border-on-deep);
  border-left-color: var(--red);
}

.section--deep .license__s {
  color: var(--text-on-deep-muted);
}

/* --------------------------------------------------------------------------
   Note callout

   Sends somebody to a page they are about to want. On /contact/ it points at
   the pricing explanation, because "what will it cost" is the question behind
   most inquiries and the answer is longer than a form field.
   -------------------------------------------------------------------------- */

.note {
  display: block;
  padding: var(--s-5);
  background: var(--bg-alt);
  border: 1px solid var(--border);
  border-left: 3px solid var(--red);
  border-radius: var(--radius);
}

.note__t {
  display: block;
  font-family: var(--font-display);
  font-size: var(--fs-lg);
  font-weight: 700;
  line-height: 1.25;
}

.note p {
  margin-top: var(--s-3);
  color: var(--text-muted);
  font-size: var(--fs-sm);
}

a.note {
  text-decoration: none;
  color: inherit;
  transition: border-color var(--t-fast), background var(--t-fast);
}

a.note:hover {
  background: var(--bg);
  border-color: var(--border-strong);
  border-left-color: var(--red);
}

a.note .note__t {
  color: var(--accent-text);
}

/* --------------------------------------------------------------------------
   Split media + text
   -------------------------------------------------------------------------- */

.split {
  display: grid;
  gap: var(--s-6);
  align-items: center;
}

@media (min-width: 860px) {
  .split {
    grid-template-columns: 1fr 1fr;
    gap: var(--s-8);
  }

  .split--wide-media {
    grid-template-columns: 1.25fr 1fr;
  }

  .split__media--first {
    order: -1;
  }
}

.split__media img {
  width: 100%;
  border-radius: var(--radius-lg);
  aspect-ratio: 4 / 3;
  object-fit: cover;
}

/* Portrait orientation, for the owner photo.

   A 4:5 portrait is much taller than the text beside it, which left a large
   block of dead space under the copy. The media column is narrowed and the
   row is centered so the two sides balance instead of the text hanging off
   the top. */
.split__media.portrait img {
  aspect-ratio: 4 / 5;
}

@media (min-width: 860px) {
  .split--portrait {
    grid-template-columns: 1.45fr 1fr;
    align-items: center;
  }
}

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

.cta {
  background: var(--red);
  color: #fff;
}

.cta h2 {
  color: #fff;
  max-width: 20ch;
}

.cta p {
  color: rgba(255, 255, 255, 0.9);
  margin-top: var(--s-4);
  max-width: 52ch;
}

.cta .btn--ghost {
  border-color: rgba(255, 255, 255, 0.55);
  color: #fff;
}

.cta .btn--ghost:hover {
  background: #fff;
  border-color: #fff;
  color: var(--red);
}

.cta .btn--dark:hover {
  background: #fff;
  border-color: #fff;
  color: var(--red-hover);
}

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

.form {
  display: grid;
  gap: var(--s-5);
}

@media (min-width: 700px) {
  .form__row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--s-5);
    /* Bottom-align the pair so the inputs sit on one line even when one
       label carries a hint and the other does not. */
    align-items: end;
  }
}

.field {
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
}

.field label {
  font-family: var(--font-display);
  font-size: var(--fs-sm);
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.field .req {
  color: var(--red-ink);
}

/* The hint sits on its own line under the label. As an inline span it ran on
   from the uppercase label text and wrapped mid-phrase, which also pushed
   the input down and knocked it out of line with the field beside it. */
.field .hint {
  display: block;
  margin-top: 3px;
  font-family: var(--font-body);
  font-size: var(--fs-xs);
  font-weight: 400;
  line-height: 1.4;
  letter-spacing: 0;
  text-transform: none;
  color: var(--text-muted);
}

.field input,
.field select,
.field textarea {
  width: 100%;
  padding: 0.85em 1em;
  min-height: 50px;
  background: var(--white);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  transition: border-color var(--t-fast), box-shadow var(--t-fast);
}

/* A select computes line-height: normal while a text input inherits the
   body's 1.62, so the two controls in a row ended up 5px apart. Pin the
   height of every single-line control instead of leaving it to intrinsics. */
.field input:not([type='file']),
.field select {
  height: 54px;
  line-height: 1.3;
}

.field textarea {
  min-height: 150px;
  line-height: 1.5;
  resize: vertical;
}

/* File inputs size to their own button chrome; forcing a height clips it. */
.field input[type='file'] {
  height: auto;
  padding: 0.7em 1em;
  line-height: 1.5;
  cursor: pointer;
}

.field input:focus,
.field select:focus,
.field textarea:focus {
  outline: none;
  border-color: var(--red);
  box-shadow: var(--ring);
}

.field input:user-invalid,
.field textarea:user-invalid {
  border-color: var(--red-deep);
}

/* Radio pills for project type: bigger tap targets than native radios. */
.choice {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-3);
}

.choice label {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 1 1 12rem;
  min-height: 52px;
  padding: var(--s-3) var(--s-5);
  background: var(--white);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  cursor: pointer;
  text-transform: none;
  letter-spacing: 0;
  font-family: var(--font-body);
  font-size: var(--fs-base);
  font-weight: 500;
  transition: border-color var(--t-fast), background var(--t-fast);
}

.choice input {
  position: absolute;
  opacity: 0;
  width: 1px;
  height: 1px;
}

.choice label:hover {
  border-color: var(--steel-300);
}

.choice input:checked + span {
  font-weight: 600;
}

.choice label:has(input:checked) {
  border-color: var(--red);
  background: var(--red-wash);
  box-shadow: inset 0 0 0 1px var(--red);
}

.choice label:has(input:focus-visible) {
  outline: 3px solid var(--red);
  outline-offset: 2px;
}

/* Honeypot: bots fill it, humans never see it. */
.hp {
  position: absolute !important;
  left: -9999px;
  opacity: 0;
  height: 0;
  overflow: hidden;
}

.form__note {
  font-size: var(--fs-sm);
  color: var(--text-muted);
}

/* --------------------------------------------------------------------------
   FAQ

   Native <details> so it works with no JS, is keyboard operable and is
   readable by crawlers whether open or closed. build.js reads this markup to
   generate the FAQPage schema, so the structure matters: do not change the
   class names without updating faqSchema() in build.js.
   -------------------------------------------------------------------------- */

.faq {
  margin-top: var(--s-6);
  border-top: 1px solid var(--border);
}

.faq__item {
  border-bottom: 1px solid var(--border);
}

.faq__item > summary {
  display: flex;
  align-items: flex-start;
  gap: var(--s-4);
  padding: var(--s-5) 0;
  cursor: pointer;
  list-style: none;
  font-family: var(--font-display);
  font-size: var(--fs-lg);
  font-weight: 700;
  line-height: var(--lh-snug);
  letter-spacing: var(--ls-flat);
  transition: color var(--t-fast);
}

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

.faq__item > summary:hover {
  color: var(--accent-text);
}

/* Plus sign that becomes a minus when open. */
.faq__item > summary::after {
  content: '';
  flex: none;
  width: 16px;
  height: 16px;
  margin-left: auto;
  margin-top: 0.35em;
  background:
    linear-gradient(var(--red), var(--red)) center / 100% 2px no-repeat,
    linear-gradient(var(--red), var(--red)) center / 2px 100% no-repeat;
  transition: transform var(--t);
}

.faq__item[open] > summary::after {
  transform: rotate(90deg);
  background: linear-gradient(var(--red), var(--red)) center / 100% 2px no-repeat;
}

.faq__a {
  padding-bottom: var(--s-5);
  color: var(--text-muted);
  max-width: 62ch;
}

/* --------------------------------------------------------------------------
   Contact rail
   -------------------------------------------------------------------------- */

.contact-rail {
  display: grid;
  gap: var(--s-5);
}

.contact-item {
  padding: var(--s-5);
  background: var(--bg-alt);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
}

.contact-item__l {
  display: block;
  font-family: var(--font-display);
  font-size: var(--fs-xs);
  font-weight: 700;
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: var(--text-muted);
  margin-bottom: var(--s-2);
}

.contact-item__v {
  font-family: var(--font-display);
  font-size: var(--fs-lg);
  font-weight: 700;
  letter-spacing: var(--ls-flat);
  text-decoration: none;
  color: var(--text);
  word-break: break-word;
}

a.contact-item__v:hover {
  color: var(--red-ink);
}

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

.site-footer {
  background: var(--ink-900);
  color: var(--text-on-deep-muted);
  padding-block: var(--s-8) var(--s-6);
  font-size: var(--fs-sm);
}

.site-footer__grid {
  display: grid;
  gap: var(--s-6);
  grid-template-columns: 1fr;
}

@media (min-width: 760px) {
  .site-footer__grid {
    grid-template-columns: 1.4fr 1fr 1fr;
    gap: var(--s-7);
  }
}

.footer-brand {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  margin-bottom: var(--s-5);
  color: #fff;
}

.footer-brand .sc-mark {
  height: 32px;
  width: calc(32px * 2.4785);
}

.site-footer h2 {
  font-size: var(--fs-xs);
  font-weight: 700;
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: #fff;
  margin-bottom: var(--s-4);
}

.site-footer ul {
  list-style: none;
  padding: 0;
}

.site-footer li + li {
  margin-top: var(--s-3);
}

.site-footer a {
  color: var(--text-on-deep-muted);
  text-decoration: none;
}

.site-footer a:hover {
  color: #fff;
  text-decoration: underline;
}

.site-footer__license {
  display: flex;
  align-items: baseline;
  gap: var(--s-2);
  flex-wrap: wrap;
  margin-top: var(--s-4);
  padding-top: var(--s-4);
  border-top: 1px solid var(--border-on-deep);
  color: #fff;
  font-weight: 600;
}

.site-footer__bottom {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-3) var(--s-5);
  justify-content: space-between;
  align-items: center;
  margin-top: var(--s-7);
  padding-top: var(--s-5);
  border-top: 1px solid var(--border-on-deep);
  font-size: var(--fs-xs);
}

.site-footer__bottom p {
  margin: 0;
}

/* --------------------------------------------------------------------------
   Utilities

   These exist for one reason: the production CSP in netlify.toml sets
   `style-src 'self'`, which blocks every `style="..."` attribute. Chrome
   drops the whole declaration, so a page that leans on inline styles for
   spacing renders correctly in `npm run dev` (no CSP headers there) and
   collapses on Netlify. Keep layout in classes, never in a style attribute.
   `build.js` fails the build if one comes back.
   -------------------------------------------------------------------------- */

.mt-2 { margin-top: var(--s-2); }
.mt-3 { margin-top: var(--s-3); }
.mt-4 { margin-top: var(--s-4); }
.mt-5 { margin-top: var(--s-5); }
.mt-6 { margin-top: var(--s-6); }
.mt-7 { margin-top: var(--s-7); }
.mb-6 { margin-bottom: var(--s-6); }
.pt-0 { padding-top: 0; }

/* Column width caps for the step lists, which read badly at full container
   width. Named for what they are rather than for a scale position. */
.w-60 { max-width: 60rem; }
.w-62 { max-width: 62rem; }

/* .grid reads --min per instance. */
.grid--260 { --min: 260px; }
.grid--280 { --min: 280px; }
.grid--380 { --min: 380px; }

/* .stack reads --flow per instance. */
.flow-5 { --flow: var(--s-5); }

.text-muted { color: var(--text-muted); }
.text-sm { font-size: var(--fs-sm); }

/* Body copy on a dark hero or page head, one step brighter than the lede. */
.text-soft-on-deep { color: rgba(255, 255, 255, 0.72); }

/* An h2 that is a section label rather than the page's main statement. */
.h-2xl { font-size: var(--fs-2xl); }

/* The whole card is the link. */
.card--link {
  text-decoration: none;
  color: inherit;
}

/* An eyebrow that links back to its parent section keeps the eyebrow colour
   rather than picking up the global link colour. */
.eyebrow a {
  color: inherit;
}

/* Vertical alignment for the two-column split. */
.split--center { align-items: center; }
.split--top { align-items: start; }

/* The CTA band pairs a text block with buttons; the buttons center against
   the copy rather than sitting on the baseline. */
.cta .btn-row {
  align-items: center;
}

/* A fieldset used purely to group radios, with no visible box. The legend
   carries the same label treatment as .field label. */
.fieldset-plain {
  border: 0;
  padding: 0;
  margin: 0;
}

.fieldset-plain > legend {
  padding: 0;
}

.legend-label {
  font-family: var(--font-display);
  font-size: var(--fs-sm);
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

/* An error under a form control. Set by src/js/form.js, which is the only
   thing that uses it, so it starts hidden via the `hidden` attribute rather
   than a class. */
.form__error {
  margin-top: var(--s-2);
  font-size: var(--fs-sm);
  color: var(--red-ink);
  font-weight: 500;
}

.field input[aria-invalid='true'] {
  border-color: var(--red);
}

/* The privacy link rides along with the copyright line rather than taking a
   column of its own in the footer grid. */
.site-footer__bottom a {
  margin-left: var(--s-3);
}

/* Locks the page behind the open mobile drawer. Set from JS as a class rather
   than as an inline style, because the CSP drops inline styles. */
html.is-nav-open,
html.is-nav-open body {
  overflow: hidden;
}
