/* ==========================================================================
   5NINE site styles
   --------------------------------------------------------------------------
   Uses ONLY the variables from tokens.css. Don't put raw colors or font
   names here; add a token instead.

   Sections:
   1. Base and reset
   2. Accessibility helpers (skip link, focus, visually hidden)
   3. Layout (container, sections, dark/accent themes)
   4. Buttons and links
   5. Header and mobile nav
   6. Homepage: hero, services cards, 5-9 explainer, about teaser, CTA band
   7. Inner pages (services, about, contact form, 404)
   8. Footer
   9. Placeholders ([BRACKETS] and image boxes)
   10. Reduced motion
   ========================================================================== */

/* 1. Base and reset ------------------------------------------------------ */

*,
*::before,
*::after {
  box-sizing: border-box;
}

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

body {
  margin: 0;
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-body);
  font-weight: var(--weight-body);
  font-size: var(--text-base);
  line-height: var(--leading-body);
  overflow-wrap: break-word;
}

h1,
h2,
h3 {
  margin: 0 0 var(--space-4);
  font-family: var(--font-heading);
  font-weight: var(--weight-heading);
  line-height: var(--leading-tight);
  letter-spacing: 0.01em;
}

h2 {
  font-size: var(--text-2xl);
}

h3 {
  font-size: var(--text-xl);
  font-weight: var(--weight-subheading);
  line-height: var(--leading-snug);
}

p {
  margin: 0 0 var(--space-4);
}

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

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

/* Real photos: give every <img> width/height attributes in the HTML too,
   so the browser reserves the space before the image loads. */
img {
  height: auto;
}

a {
  color: var(--color-link);
  text-decoration-thickness: 1px;
  text-underline-offset: 0.2em;
}

a:hover {
  text-decoration-thickness: 2px;
}

ul {
  margin: 0;
  padding: 0;
}

/* 2. Accessibility helpers ---------------------------------------------- */

:focus-visible {
  outline: var(--focus-width) solid var(--color-focus);
  outline-offset: 3px;
}

/* main gets focus from the skip link; no ring needed on the whole page */
main:focus {
  outline: none;
}

.skip-link {
  position: absolute;
  top: var(--space-2);
  left: var(--space-2);
  z-index: 100;
  padding: var(--space-3) var(--space-4);
  background: var(--color-white);
  color: var(--color-charcoal);
  font-weight: var(--weight-strong);
  border-radius: var(--radius-sm);
  transform: translateY(-200%);
}

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

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* 3. Layout ---------------------------------------------------------------- */

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

.section {
  padding-block: var(--section-padding);
}

.section__intro {
  max-width: 40rem;
  margin-bottom: var(--space-7);
}

.section__intro p {
  color: var(--color-text-muted);
  font-size: var(--text-lg);
}

/* Dark theme: re-points the color roles, so everything inside just works */
.theme-dark {
  --color-text: var(--color-dark-text);
  --color-text-muted: var(--color-dark-text-muted);
  --color-link: var(--color-dark-text);
  --color-label: var(--color-dark-label);
  --color-focus: var(--color-dark-focus);
  background: var(--color-dark-bg);
  color: var(--color-text);
}

/* Accent theme: orange band with charcoal text */
.theme-accent {
  --color-text: var(--color-on-accent);
  --color-text-muted: var(--color-on-accent);
  --color-link: var(--color-on-accent);
  --color-focus: var(--color-on-accent);
  background: var(--color-accent);
  color: var(--color-text);
}

.theme-white {
  background: var(--color-surface);
}

/* Small uppercase mono label above headings */
.eyebrow {
  display: block;
  margin-bottom: var(--space-3);
  color: var(--color-label);
  font-family: var(--font-mono);
  font-weight: var(--weight-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

/* 4. Buttons and links ---------------------------------------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: var(--tap-target);
  padding: var(--space-3) var(--space-5);
  border: 2px solid transparent;
  border-radius: var(--radius-sm);
  font-family: var(--font-heading-caps);
  font-weight: var(--weight-heading);
  font-size: var(--text-lg);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  text-decoration: none;
  line-height: 1.1;
}

/* Orange button, charcoal text (white on orange fails contrast) */
.btn--primary {
  background: var(--color-accent);
  color: var(--color-on-accent);
}

.btn--primary:hover {
  background: var(--color-dark-bg);
  color: var(--color-accent);
  border-color: var(--color-accent);
}

/* Charcoal button, for use on the orange CTA band */
.btn--dark {
  background: var(--color-dark-bg);
  color: var(--color-dark-text);
}

.btn--dark:hover {
  background: var(--color-surface);
  color: var(--color-text);
  border-color: var(--color-dark-bg);
}

/* Text link with an arrow, used for secondary actions */
.link-arrow {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: var(--tap-target);
  font-weight: var(--weight-strong);
  text-decoration-color: var(--color-accent);
}

.link-arrow span[aria-hidden] {
  text-decoration: none;
}

/* 5. Header and mobile nav ------------------------------------------------ */

.site-header {
  position: relative;
  z-index: 50;
  border-bottom: var(--border-width) solid var(--color-dark-line);
}

.site-header__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  min-height: var(--header-height);
}

/* Logo: Josh's current logo (tools/logo.py). Header = mark + name as text,
   footer = the full logo image. Swap both when the cleaned-up logo arrives. */
.brand {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  min-height: var(--tap-target);
  color: var(--color-text);
  text-decoration: none;
}

.brand__mark {
  width: 40px;
  height: 40px;
}

.brand__name {
  font-family: var(--font-heading);
  font-weight: var(--weight-heading);
  font-size: 1.5rem;
  line-height: 1;
  letter-spacing: 0.04em;
}

/* "Communications" sits under "5NINE" so the full name fits a 360px header */
.brand__sub {
  display: block;
  margin-top: 0.2rem;
  color: var(--color-text-muted);
  font-weight: var(--weight-subheading);
  font-size: 0.875rem;
  letter-spacing: 0.08em;
}

.brand__logo {
  width: 240px;
  height: auto;
}

.site-nav__list {
  display: flex;
  flex-wrap: wrap;
  list-style: none;
}

.site-nav__link {
  display: flex;
  align-items: center;
  min-height: var(--tap-target);
  padding-inline: var(--space-3);
  color: var(--color-text);
  font-family: var(--font-heading-caps);
  font-weight: var(--weight-subheading);
  font-size: 1.125rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  text-decoration: none;
}

.site-nav__link:hover,
.site-nav__link[aria-current="page"] {
  text-decoration: underline;
  text-decoration-color: var(--color-accent);
  text-decoration-thickness: 3px;
  text-underline-offset: 0.35em;
}

/* Menu button: hidden unless JS is running (html gets class "js") */
.nav-toggle {
  display: none;
  align-items: center;
  gap: var(--space-2);
  min-width: var(--tap-target);
  min-height: var(--tap-target);
  padding: 0 var(--space-3);
  margin-right: calc(var(--space-3) * -1);
  background: transparent;
  color: var(--color-text);
  border: 0;
  font-family: var(--font-heading-caps);
  font-weight: var(--weight-subheading);
  font-size: 1.125rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  cursor: pointer;
}

/* Three-bar icon that turns into an X when open */
.nav-toggle__icon,
.nav-toggle__icon::before,
.nav-toggle__icon::after {
  display: block;
  width: 20px;
  height: 2px;
  background: currentColor;
}

.nav-toggle__icon {
  position: relative;
}

.nav-toggle__icon::before,
.nav-toggle__icon::after {
  content: "";
  position: absolute;
  left: 0;
}

.nav-toggle__icon::before {
  top: -6px;
}

.nav-toggle__icon::after {
  top: 6px;
}

.nav-toggle[aria-expanded="true"] .nav-toggle__icon {
  background: transparent;
}

.nav-toggle[aria-expanded="true"] .nav-toggle__icon::before {
  top: 0;
  transform: rotate(45deg);
}

.nav-toggle[aria-expanded="true"] .nav-toggle__icon::after {
  top: 0;
  transform: rotate(-45deg);
}

/* Small screens with JS: the menu drops down OVER the page (absolute),
   so opening it never pushes content down. */
@media (max-width: 47.99em) {
  .js .nav-toggle {
    display: inline-flex;
  }

  .js .site-nav {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    background: var(--color-dark-bg);
    border-top: var(--border-width) solid var(--color-dark-line);
    box-shadow: var(--shadow-menu);
  }

  .js .nav-toggle[aria-expanded="true"] + .site-nav {
    display: block;
  }

  .js .site-nav__list {
    flex-direction: column;
    padding: var(--space-2) var(--container-gutter) var(--space-4);
  }

  .js .site-nav__link {
    padding-inline: 0;
    min-height: 3rem;
    border-bottom: var(--border-width) solid var(--color-dark-line);
  }
}

/* 6. Homepage -------------------------------------------------------------- */

/* Hero */
.hero {
  position: relative;
  overflow: hidden; /* keeps the decorative arcs from causing side-scroll */
  padding-block: clamp(4rem, 2.5rem + 7vw, 8rem);
}

.hero__content {
  position: relative;
  max-width: 44rem;
}

.hero__title {
  margin-bottom: var(--space-5);
  font-size: var(--text-hero);
  line-height: 0.95;
}

.hero__title .accent {
  color: var(--color-accent);
}

.hero__subhead {
  max-width: 36rem;
  margin-bottom: var(--space-6);
  color: var(--color-text-muted);
  font-size: var(--text-lg);
}

.hero__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-4) var(--space-6);
}

/* Decorative signal arcs behind the hero text */
.hero__arcs {
  position: absolute;
  right: -6rem;
  bottom: -6rem;
  width: 28rem;
  height: 28rem;
  color: var(--color-accent);
  opacity: 0.18;
  pointer-events: none;
}

@media (min-width: 48em) {
  .hero__arcs {
    right: -2rem;
    bottom: -4rem;
    width: 34rem;
    height: 34rem;
    opacity: 0.35;
  }
}

/* Hero photo (images.json "full-lineup"), under the hero text */
.hero__media {
  position: relative; /* paints above the decorative arcs */
  margin-top: var(--space-7);
}

.hero__media .media,
.hero__media .img-placeholder {
  border-radius: var(--radius-md);
}

.hero__media .img-placeholder {
  aspect-ratio: 16 / 9;
}

/* Wide screens: the same 16:9 file shown at 21:9. CSS trims sky and grass;
   object-position keeps the kits in frame. */
@media (min-width: 64em) {
  .hero__media .media {
    aspect-ratio: 21 / 9;
    object-position: 50% 70%;
  }
}

/* Product and service cards */
.card-grid {
  display: grid;
  gap: var(--space-5);
  list-style: none;
}

@media (min-width: 40em) {
  .card-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (min-width: 64em) {
  .card-grid {
    grid-template-columns: repeat(3, 1fr);
  }
}

.card {
  display: flex;
  flex-direction: column;
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-line);
  border-radius: var(--radius-md);
  overflow: hidden;
}

.card__body {
  display: flex;
  flex: 1;
  flex-direction: column;
  padding: var(--space-5);
}

.card__body p {
  color: var(--color-text-muted);
}

.card__link {
  margin-top: auto;
  padding-top: var(--space-3);
}

.card__note {
  font-size: var(--text-sm);
}

.card__body .eyebrow {
  margin-bottom: var(--space-2);
}

/* Product cards: "Request a quote" button + details link */
.card__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3) var(--space-5);
}

/* "Custom quote · Specs coming soon" (homepage cards and services.html) */
.price-line,
.card__body .price-line {
  color: var(--color-text);
  font-weight: var(--weight-strong);
}

/* In a card, the price line and buttons sit at the bottom, level across the row */
.card__body .price-line {
  margin-top: auto;
  padding-top: var(--space-2);
}

/* FCC note + "Also available" line under the product cards */
.products__footer {
  max-width: 40rem;
  margin-top: var(--space-6);
}

.products__footer p {
  color: var(--color-text-muted);
}

.products__note {
  font-size: var(--text-sm);
}

@media (min-width: 72em) {
  .card-grid--four h3 {
    font-size: var(--text-lg);
  }
}

/* Homepage: 4 product-group cards (2 across, 4 across once they fit) */
@media (min-width: 64em) {
  .card-grid--four,
  .card-grid--two {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (min-width: 72em) {
  .card-grid--four {
    grid-template-columns: repeat(4, 1fr);
  }
}

/* "What's 5-9?" explainer */
.signal {
  display: grid;
  gap: var(--space-7);
  align-items: center;
}

@media (min-width: 56em) {
  .signal {
    grid-template-columns: 1fr 1fr;
  }
}

.signal__copy p {
  color: var(--color-text-muted);
  font-size: var(--text-lg);
}

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

.signal-report {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-5);
  margin: 0;
}

.signal-report__item {
  padding: var(--space-5);
  border: var(--border-width) solid var(--color-dark-line);
  border-radius: var(--radius-md);
}

.signal-report__number {
  margin: 0;
  color: var(--color-accent);
  font-family: var(--font-heading);
  font-weight: var(--weight-heading);
  font-size: clamp(4.5rem, 3rem + 6vw, 7.5rem);
  line-height: 1;
}

.signal-report__label {
  margin: 0;
  font-family: var(--font-mono);
  font-weight: var(--weight-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--color-label);
}

.signal-report__meaning {
  margin: var(--space-2) 0 0;
  color: var(--color-text-muted);
}

/* About teaser */
.about-teaser {
  display: grid;
  gap: var(--space-6);
  align-items: center;
}

@media (min-width: 48em) {
  .about-teaser {
    grid-template-columns: 5fr 6fr;
    gap: var(--space-7);
  }
}

/* CTA band */
.cta-band__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-5);
}

.cta-band h2 {
  margin-bottom: var(--space-2);
}

.cta-band p {
  max-width: 34rem;
  font-size: var(--text-lg);
}

/* 7. Inner pages ------------------------------------------------------------ */

.page-header {
  padding-block: clamp(3rem, 2rem + 4vw, 5rem);
}

.page-header h1 {
  font-size: var(--text-2xl);
  margin-bottom: var(--space-3);
}

.page-header p {
  max-width: 40rem;
  color: var(--color-text-muted);
  font-size: var(--text-lg);
}

.page-header .page-header__note {
  margin-top: var(--space-3);
  font-size: var(--text-sm);
}

/* Services page: one block per service. Photo first in the HTML (so it sits
   on top on phones); from 48em up, every other block puts it on the right. */
.service {
  display: grid;
  gap: var(--space-6);
  align-items: center;
}

@media (min-width: 48em) {
  .service {
    grid-template-columns: 5fr 6fr;
    gap: var(--space-7);
  }

  .service--flip {
    grid-template-columns: 6fr 5fr;
  }

  .service--flip > :first-child {
    order: 2;
  }
}

.service .img-placeholder,
.service .media {
  border-radius: var(--radius-md);
}

/* Product gallery: one large photo with two small ones under it */
.gallery {
  display: grid;
  gap: var(--space-3);
}

.gallery__thumbs {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-3);
}

.service h3 {
  margin: var(--space-5) 0 var(--space-3);
  font-size: var(--text-lg);
}

/* Bulleted list with small orange markers (role="list" in the HTML keeps
   it announced as a list in Safari once the bullets are removed) */
.checklist {
  display: grid;
  gap: var(--space-2);
  margin-bottom: var(--space-5);
  list-style: none;
}

.checklist li {
  position: relative;
  padding-left: var(--space-5);
}

.checklist li::before {
  content: "";
  position: absolute;
  top: 0.6em;
  left: 0;
  width: 0.5rem;
  height: 0.5rem;
  background: var(--color-accent);
  border-radius: 50%;
}

/* Services: the Pelican section (2nd group) is rendered, and its lazy photos
   fetched, only as it nears the screen. Without this, Chrome under Lighthouse
   fetches that gallery before the first paint and the bytes count against the
   page's LCP (94 -> 98). Later sections are too far down to matter, so they
   render normally. The size estimates are the section's measured height
   (2026-10-20); they matter only until it has been on screen once ("auto"
   remembers the real size). Keep them close: Safari has no scroll anchoring, so
   a bad estimate would make the page jump when scrolling up after an anchor
   jump past it. Re-measure if the Pelican section's content changes a lot. */
#pelican {
  content-visibility: auto;
  contain-intrinsic-size: auto 1200px;
}

@media (min-width: 40em) {
  #pelican {
    contain-intrinsic-size: auto 1450px;
  }
}

@media (min-width: 48em) {
  #pelican {
    contain-intrinsic-size: auto 780px;
  }
}

/* Product groups and cards (made by tools/products.py from products.json) */
.service + .product-grid {
  margin-top: var(--space-7);
}

.group__intro {
  color: var(--color-text-muted);
  font-size: var(--text-lg);
}

.service .product {
  margin-top: var(--space-6);
}

/* Product photos are on white, so they sit flush on the white card */
.product .img-placeholder {
  aspect-ratio: 1 / 1;
}

.card__body .product__price {
  margin-bottom: var(--space-3);
  color: var(--color-text);
  font-family: var(--font-heading);
  font-weight: var(--weight-heading);
  font-size: var(--text-xl);
  line-height: 1.1;
}

.product h3 {
  margin: 0 0 var(--space-1);
  font-size: var(--text-lg);
}

/* "What's included": collapsed until tapped (native <details>, no JS).
   margin-top: auto keeps the rows (and buttons) level across a row of cards. */
.product__included {
  margin-top: auto;
  margin-bottom: var(--space-5);
  border-top: var(--border-width) solid var(--color-line);
  border-bottom: var(--border-width) solid var(--color-line);
}

.product__included summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: var(--tap-target);
  color: var(--color-link);
  font-weight: var(--weight-strong);
  cursor: pointer;
  list-style: none;
}

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

/* Plus sign that turns into a minus when open */
.product__included summary::after {
  content: "+";
  font-family: var(--font-heading);
  font-weight: var(--weight-heading);
  font-size: var(--text-xl);
  line-height: 1;
}

.product__included[open] summary::after {
  content: "\2212";
}

.product__included .checklist {
  margin: var(--space-2) 0 var(--space-4);
}

.product__included li {
  color: var(--color-text-muted);
}

.product__cta {
  align-self: flex-start;
}

/* Licensing line under each product group's intro */
.license-note,
.section__intro .license-note {
  margin-top: var(--space-4);
  padding-left: var(--space-4);
  border-left: 4px solid var(--color-accent);
  font-size: var(--text-sm);
}

.travel-note {
  max-width: 40rem;
  margin-top: var(--space-6);
}

/* "How it works" numbered steps (dark section) */
.steps {
  display: grid;
  gap: var(--space-5);
  margin: 0 0 var(--space-6);
  padding: 0;
  list-style: none;
  counter-reset: step;
}

@media (min-width: 48em) {
  .steps {
    grid-template-columns: repeat(3, 1fr);
  }
}

.steps li {
  padding: var(--space-5);
  border: var(--border-width) solid var(--color-dark-line);
  border-radius: var(--radius-md);
  counter-increment: step;
}

.steps li::before {
  content: counter(step, decimal-leading-zero);
  display: block;
  margin-bottom: var(--space-3);
  color: var(--color-accent);
  font-family: var(--font-heading);
  font-weight: var(--weight-heading);
  font-size: var(--text-2xl);
  line-height: 1;
}

.steps h3 {
  margin-bottom: var(--space-2);
  font-size: var(--text-lg);
}

.steps p {
  color: var(--color-text-muted);
}

/* About page: highlighted line and Josh's quote */
.callout {
  padding: var(--space-3) var(--space-4);
  background: var(--color-surface);
  border-left: 4px solid var(--color-accent);
  border-radius: var(--radius-sm);
}

.quote {
  margin: var(--space-6) 0 0;
  padding-left: var(--space-5);
  border-left: 4px solid var(--color-accent);
}

.quote blockquote {
  margin: 0 0 var(--space-3);
  font-size: var(--text-lg);
}

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

/* About page: the bio is long, so the photo stays beside it while scrolling */
.about-story {
  align-items: start;
}

@media (min-width: 48em) {
  .about-story > :first-child {
    position: sticky;
    top: var(--space-6);
  }
}

/* About page: mission + who we serve */
.mission {
  display: grid;
  gap: var(--space-7);
}

@media (min-width: 48em) {
  .mission {
    grid-template-columns: 3fr 2fr;
  }
}

.mission__statement {
  font-size: var(--text-lg);
}

.mission .checklist {
  margin-bottom: 0;
}

/* Contact page: form card + contact details */
.contact-layout {
  display: grid;
  gap: var(--space-7);
}

@media (min-width: 56em) {
  .contact-layout {
    grid-template-columns: 2fr 1fr;
    align-items: start;
  }
}

.form-card {
  padding: var(--space-5);
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-line);
  border-radius: var(--radius-md);
}

@media (min-width: 40em) {
  .form-card {
    padding: var(--space-6);
  }
}

.form-card > h2,
.contact-details > h2 {
  font-size: var(--text-xl);
  margin-bottom: var(--space-2);
}

.form-note {
  margin-bottom: var(--space-5);
  color: var(--color-text-muted);
  font-size: var(--text-sm);
}

.field {
  margin-bottom: var(--space-5);
}

.field label {
  display: block;
  margin-bottom: var(--space-2);
  font-weight: var(--weight-strong);
}

.field__optional {
  color: var(--color-text-muted);
  font-weight: var(--weight-body);
}

.field input,
.field select,
.field textarea {
  display: block;
  width: 100%;
  min-height: var(--tap-target);
  padding: var(--space-2) var(--space-3);
  background: var(--color-surface);
  color: var(--color-text);
  border: var(--border-width) solid var(--color-input-border);
  border-radius: var(--radius-sm);
  font: inherit;
}

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

/* Invalid: thicker red edge via box-shadow so nothing shifts */
.field [aria-invalid="true"] {
  border-color: var(--color-error);
  box-shadow: inset 0 0 0 1px var(--color-error);
}

.field__error {
  margin: 0 0 var(--space-2);
  color: var(--color-error);
  font-size: var(--text-sm);
  font-weight: var(--weight-strong);
}

.field__error:empty {
  display: none;
}

.field__hint {
  margin: 0 0 var(--space-2);
  color: var(--color-text-muted);
  font-size: var(--text-sm);
}

/* Turnstile spam check (drawn by contact.js on first interaction). The
   widget's height is reserved so nothing below it moves when it appears. */
.turnstile {
  min-height: 72px;
  margin-bottom: var(--space-5);
}

/* Under 24em the form is narrower than the 300px "flexible" widget, so
   contact.js draws the compact one (same breakpoint there) */
@media (max-width: 23.99em) {
  .turnstile {
    min-height: 150px;
  }
}

html:not(.js) .turnstile {
  display: none;
}

.form-noscript {
  margin-bottom: var(--space-5);
  font-weight: var(--weight-strong);
}

/* "Sending…" state */
.btn[aria-disabled="true"] {
  opacity: 0.7;
  cursor: progress;
}

/* The form's result message gets focus after a submit; no extra ring needed */
.form-status:focus {
  outline: none;
}

/* Plain result page for a no-JavaScript post (functions/api/_page.js) */
.result-page h1 {
  font-size: var(--text-2xl);
}

.result-page .container {
  max-width: 40rem;
}

/* Honeypot: off-screen and hidden from screen readers. People never see it;
   bots that fill every field do. */
.form-hp {
  position: absolute;
  left: -10000px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.error-summary {
  margin-bottom: var(--space-5);
  padding: var(--space-4) var(--space-5);
  border: 2px solid var(--color-error);
  border-radius: var(--radius-sm);
}

.error-summary h3 {
  margin-bottom: var(--space-2);
  color: var(--color-error);
  font-size: var(--text-lg);
}

.error-summary ul {
  list-style: none;
}

.error-summary a {
  display: inline-flex;
  align-items: center;
  min-height: var(--tap-target);
  color: var(--color-error);
  font-weight: var(--weight-strong);
}

/* Success / error message after submit. The box only shows once it has text;
   the element itself is always there so screen readers hear the update. */
.form-status:not(:empty) {
  margin-top: var(--space-5);
  padding: var(--space-4) var(--space-5);
  border: 2px solid currentColor;
  border-radius: var(--radius-sm);
  font-weight: var(--weight-strong);
}

.form-status--success {
  color: var(--color-success);
}

.form-status--error {
  color: var(--color-error);
}

.contact-details h3 {
  margin: var(--space-5) 0 var(--space-1);
  color: var(--color-label);
  font-family: var(--font-mono);
  font-weight: var(--weight-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.contact-link {
  display: inline-flex;
  align-items: center;
  min-height: var(--tap-target);
  font-weight: var(--weight-strong);
}

.link-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4) var(--space-6);
  align-items: center;
  margin-top: var(--space-6);
}

/* 8. Footer ------------------------------------------------------------------ */

.site-footer {
  padding-block: var(--space-7) var(--space-5);
  font-size: var(--text-sm);
}

.site-footer__grid {
  display: grid;
  gap: var(--space-6);
}

@media (min-width: 40em) {
  .site-footer__grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (min-width: 64em) {
  .site-footer__grid {
    grid-template-columns: 1.6fr 1.2fr 1.4fr 0.9fr 0.9fr;
  }
}

.site-footer__tagline {
  margin-top: var(--space-2);
  color: var(--color-text-muted);
}

.site-footer h2 {
  margin-bottom: var(--space-2);
  line-height: 1.4;
  color: var(--color-label);
  font-family: var(--font-mono);
  font-weight: var(--weight-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.site-footer__note {
  color: var(--color-text-muted);
}

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

.site-footer__links a {
  display: inline-flex;
  align-items: center;
  min-height: var(--tap-target);
}

.site-footer__legal {
  margin-top: var(--space-7);
  padding-top: var(--space-5);
  border-top: var(--border-width) solid var(--color-dark-line);
  color: var(--color-text-muted);
}

/* 9. Placeholders ------------------------------------------------------------ */

/* Inline [PLACEHOLDER] text: tinted so it's easy to spot on review */
.todo {
  padding: 0 0.25em;
  background: var(--color-todo-bg);
  border-radius: var(--radius-sm);
  font-family: var(--font-mono);
  font-weight: var(--weight-mono);
  font-size: 0.85em;
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
}

/* Image placeholder box. The aspect ratio is fixed, so a real photo
   (with matching width/height attributes) drops in without any shift. */
.img-placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  aspect-ratio: 4 / 3;
  margin: 0;
  padding: var(--space-4);
  background: var(--color-placeholder);
  color: var(--color-muted);
  font-family: var(--font-mono);
  font-weight: var(--weight-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.04em;
  text-align: center;
  border: 2px dashed var(--color-line);
}

/* Real photos (tools/images.py). Their width/height attributes set the
   aspect ratio, so they load without any layout shift. */
.media {
  display: block;
  width: 100%;
  height: auto;
  object-fit: cover;
}

.card .img-placeholder {
  border-width: 0 0 2px;
}

.about-teaser .img-placeholder,
.about-teaser .media {
  border-radius: var(--radius-md);
}

/* A placeholder waiting for its photo can be hidden (the founders' photo):
   .img-placeholder's display: flex would otherwise beat the hidden attribute.
   Its text column then takes the whole row. */
.img-placeholder[hidden] {
  display: none;
}

.about-teaser > .img-placeholder[hidden] + * {
  grid-column: 1 / -1;
  max-width: 44rem;
}

/* 10. Reduced motion ---------------------------------------------------------- */

/* Motion is minimal already (hover colors only). Turn transitions on only
   for people who haven't asked for reduced motion. */
@media (prefers-reduced-motion: no-preference) {
  .btn,
  .skip-link,
  a {
    transition: color 0.15s ease, background-color 0.15s ease,
      border-color 0.15s ease, transform 0.15s ease;
  }
}
