/* Ampify — site styles.
   Electric cyan and silver on near-black: derived from the client's real
   logo (an "A" mountain mark with a lightning bolt, cyan wordmark, silver
   gradient). --brand is the text-safe cyan (a darkened same-hue cyan used
   for body text, links and borders — the raw logo cyan fails contrast on
   white); --brand-bright is the logo's true electric cyan, reserved for
   marks, fills and focus rings where it doesn't have to carry small text.
   They are different on purpose.

   Re-theming starts and ends in the three token blocks directly below:
     1. :root                                            — light palette (default)
     2. @media (prefers-color-scheme: dark) :root:not([data-theme="light"])  — system dark
     3. :root[data-theme="dark"]                          — explicit user choice
   Nothing past this comment should ever hardcode a color. */

:root {
  color-scheme: light;

  --brand: #007A9E;
  --brand-bright: #00ABEC;
  --brand-fill: #00708F;
  --brand-hover: #005E79;
  --brand-soft: #E3F4FA;
  --on-brand: #FFFFFF;

  --bg: #F7F9FA;
  --bg-subtle: #EDF1F3;
  --surface: #FFFFFF;
  --surface-raised: #FFFFFF;

  --ink: #0E171D;
  --ink-muted: #4A5A63;
  --ink-faint: #74858E;
  --ink-inverse: #F7F9FA;

  --border: #DDE4E8;
  --border-strong: #C3CED4;

  --scrim: rgba(6, 15, 20, 0.76);
  --shadow: 0 1px 2px rgba(6,15,20,.06), 0 8px 24px rgba(6,15,20,.08);
  --focus: #00ABEC;
  --star: #F2B01E;

  /* Always-dark zones (trust bar, footer, .section--dark) stay near-black in
     both themes. In light theme they borrow the dark ink/bg values directly;
     in dark theme --ondark-bg sits one step lighter than --bg so these
     sections read as a distinct, slightly raised panel rather than melting
     into the page. */
  --ondark-bg: #0B1116;
  --ondark-ink: #EAF0F3;
  --ondark-muted: #9EAEB8;

  --font-heading: "Montserrat", system-ui, sans-serif;
  --font-body: "Open Sans", system-ui, sans-serif;

  --container: 1140px;
  --radius: 10px;
  --radius-sm: 6px;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;

    --brand: #3FC3F2;
    --brand-bright: #00ABEC;
    --brand-fill: #00ABEC;
    --brand-hover: #5CCDF5;
    --brand-soft: #06212C;
    --on-brand: #06131A;

    --bg: #0B1116;
    --bg-subtle: #101820;
    --surface: #151C22;
    --surface-raised: #1D262E;

    --ink: #EAF0F3;
    --ink-muted: #9EAEB8;
    --ink-faint: #74858E;
    --ink-inverse: #0B1116;

    --border: #232E37;
    --border-strong: #33404A;

    --scrim: rgba(3, 8, 11, 0.80);
    --shadow: 0 1px 2px rgba(0,0,0,.45), 0 8px 24px rgba(0,0,0,.55);
    --focus: #3FC3F2;
    --star: #F5C542;

    --ondark-bg: #151C22;
  }

  :root:not([data-theme="light"]) .theme-toggle__icon--sun { display: inline-block; }
  :root:not([data-theme="light"]) .theme-toggle__icon--moon { display: none; }
}

:root[data-theme="dark"] {
  color-scheme: dark;

  --brand: #3FC3F2;
  --brand-bright: #00ABEC;
  --brand-fill: #00ABEC;
  --brand-hover: #5CCDF5;
  --brand-soft: #06212C;
  --on-brand: #06131A;

  --bg: #0B1116;
  --bg-subtle: #101820;
  --surface: #151C22;
  --surface-raised: #1D262E;

  --ink: #EAF0F3;
  --ink-muted: #9EAEB8;
  --ink-faint: #74858E;
  --ink-inverse: #0B1116;

  --border: #232E37;
  --border-strong: #33404A;

  --scrim: rgba(3, 8, 11, 0.80);
  --shadow: 0 1px 2px rgba(0,0,0,.45), 0 8px 24px rgba(0,0,0,.55);
  --focus: #3FC3F2;
  --star: #F5C542;

  --ondark-bg: #151C22;
}

:root[data-theme="dark"] .theme-toggle__icon--sun { display: inline-block; }
:root[data-theme="dark"] .theme-toggle__icon--moon { display: none; }

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

body {
  margin: 0;
  font-family: var(--font-body);
  font-size: 1rem;
  line-height: 1.6;
  color: var(--ink);
  background: var(--bg);
}

h1,
h2,
h3 {
  font-family: var(--font-heading);
  font-weight: 700;
  line-height: 1.2;
  color: var(--ink);
  margin: 0 0 0.5em;
}

h1 { font-size: clamp(2rem, 5vw, 3.25rem); }
h2 { font-size: clamp(1.5rem, 3vw, 2.25rem); }
h3 { font-size: 1.125rem; }

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

a {
  color: var(--brand);
}

a:hover {
  color: var(--brand-hover);
}

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

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

.container {
  max-width: var(--container);
  margin: 0 auto;
  padding: 0 1.25rem;
}

/* line-height is explicit because <button> does not inherit the body's 1.6 the way
   <a class="button"> does — it falls back to `normal` (~1.2). That one difference had
   the Subscribe and Send buttons rendering 43px tall while the hero's anchor buttons
   were 50px: visibly inconsistent, and 1px under the 44px floor. */
.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  line-height: 1.6;
  min-height: 44px;
  padding: 0.75rem 2rem;
  background: var(--brand-fill);
  color: var(--on-brand);
  font-family: var(--font-heading);
  font-weight: 700;
  text-decoration: none;
  border: none;
  border-radius: var(--radius);
  cursor: pointer;
  font-size: 1rem;
  transition: background 0.2s ease, transform 0.2s ease;
}

/* The color re-declaration is load-bearing, not redundant. `a:hover` is specificity
   (0,1,1) and `.button` is (0,1,0), so on hover an anchor button took its text color
   from the generic link rule — which resolves to --brand-hover, the exact token the
   background switches to on the same event. Text and fill became the same color:
   1.00:1, and the label vanished. <button> was never affected, because `a:hover`
   cannot match it, which is why only "Get Started", "View Services" and "Go" showed
   it while "Subscribe" and "Send" looked fine. */
.button:hover,
.button:focus,
.button:active {
  background: var(--brand-hover);
  color: var(--on-brand);
}

/* Header */
.site-header {
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  position: sticky;
  top: 0;
  z-index: 10;
}

.site-header .container {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding-top: 1rem;
  padding-bottom: 1rem;
}

.site-logo {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  min-width: 44px;
  gap: 0.5rem;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 1.25rem;
  color: var(--ink);
  text-decoration: none;
}

.site-logo__mark {
  height: 34px;
  width: auto;
  flex-shrink: 0;
  display: block;
}

.site-logo__word {
  height: 19px;
  width: auto;
  display: block;
}

@media (max-width: 400px) {
  .site-logo__word {
    display: none;
  }
}

.nav-toggle {
  display: none;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  padding: 0;
  background: transparent;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--ink);
  cursor: pointer;
}

.nav-toggle__bars {
  position: relative;
  display: block;
  width: 20px;
  height: 2px;
  background: currentColor;
  border-radius: 1px;
  transition: background 0.2s ease;
}

.nav-toggle__bars::before,
.nav-toggle__bars::after {
  content: "";
  position: absolute;
  left: 0;
  width: 20px;
  height: 2px;
  background: currentColor;
  border-radius: 1px;
  transition: transform 0.2s ease;
}

.nav-toggle__bars::before { top: -6px; }
.nav-toggle__bars::after { top: 6px; }

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

.nav-toggle[aria-expanded="true"] .nav-toggle__bars::before {
  transform: translateY(6px) rotate(45deg);
}

.nav-toggle[aria-expanded="true"] .nav-toggle__bars::after {
  transform: translateY(-6px) rotate(-45deg);
}

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

.site-nav a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 0.9375rem;
  color: var(--ink-muted);
  text-decoration: none;
  transition: color 0.2s ease;
}

.site-nav a:hover,
.site-nav a[aria-current="page"] {
  color: var(--brand);
}

.site-nav__theme {
  margin-left: 0.5rem;
  padding-left: 1rem;
  border-left: 1px solid var(--border);
}

.theme-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  min-width: 44px;
  gap: 0.4rem;
  padding: 0.4rem 0.75rem;
  background: transparent;
  border: 1px solid var(--border);
  border-radius: 999px;
  color: var(--ink-muted);
  font: inherit;
  font-size: 0.8125rem;
  cursor: pointer;
  transition: border-color 0.2s ease, color 0.2s ease;
}

.theme-toggle:hover {
  border-color: var(--brand);
  color: var(--ink);
}

.theme-toggle__icon {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
}

/* Default (light) state: show the moon (click to go dark). The dark-mode
   blocks at the top of this file flip these to show the sun instead. */
.theme-toggle__icon--sun { display: none; }
.theme-toggle__icon--moon { display: inline-block; }

.theme-toggle__label {
  display: none;
}

/* Hero */
.hero {
  position: relative;
  display: flex;
  align-items: center;
  min-height: 420px;
  background-size: cover;
  background-position: center;
  color: var(--ondark-ink);
}

.hero::before {
  content: "";
  position: absolute;
  inset: 0;
  /* Weighted toward the bottom: the hero is followed by an always-dark section
     (.trust-bar / .section--dark), so it must NOT fade toward --bg — in light theme
     that painted a white band between the photo and the near-black bar, and dropped
     white hero text onto a near-white ground. */
  background: linear-gradient(to bottom,
              var(--scrim) 0%,
              var(--scrim) 55%,
              var(--ondark-bg) 100%);
}

.hero .container {
  position: relative;
  padding-top: 4rem;
  padding-bottom: 4rem;
}

.hero h1 {
  color: var(--ondark-ink);
  max-width: 22ch;
}

.hero p {
  max-width: 55ch;
  font-size: 1.125rem;
  color: var(--ondark-muted);
}

.hero--home { background-image: url("../images/hero-home.jpg"); }
.hero--services { background-image: url("../images/hero-services.jpg"); }
.hero--projects { background-image: url("../images/hero-projects.jpg"); }

.hero--plain {
  background: var(--ondark-bg);
  min-height: 220px;
}

/* Sections */
.section {
  padding: 4rem 0;
}

.section--tint {
  background: var(--bg-subtle);
}

.section--dark {
  background: var(--ondark-bg);
}

.section--dark h2,
.section--dark p {
  color: var(--ondark-ink);
}

.section-intro {
  max-width: 60ch;
  margin-bottom: 2.5rem;
}

/* Trust bar */
.trust-bar {
  background: var(--ondark-bg);
  color: var(--ondark-muted);
  text-align: center;
  padding: 1.5rem 0;
}

.trust-bar .stars {
  color: var(--star);
  font-size: 1.25rem;
  letter-spacing: 0.2em;
  margin: 0 0 0.25rem;
}

.trust-bar .brands {
  font-family: var(--font-heading);
  font-weight: 600;
  color: var(--ondark-ink);
  margin: 0;
}

/* Card grids */
.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 2rem;
}

.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  box-shadow: var(--shadow);
  transition: transform 0.2s ease, box-shadow 0.2s ease;
}

.card:hover {
  transform: translateY(-4px);
}

/* aspect-ratio is what makes object-fit mean anything here. Without it the card
   takes its height from whatever the photo happens to be, so a 500x550 source sits
   10% taller than a 500x500 one and the whole grid row stretches to match, leaving
   the shorter cards padded out underneath. Fixing the ratio means a replacement
   photo can be any shape and the row still lines up. Same treatment as
   .gallery-grid img below. */
.card img {
  width: 100%;
  aspect-ratio: 1;
  object-fit: cover;
}

.card h2,
.card h3 {
  margin: 1rem 1.25rem 0;
  font-size: 1.375rem;
}

.card p {
  margin: 0.5rem 1.25rem 1.25rem;
}

/* Gallery */
.gallery-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 1rem;
}

.gallery-grid img {
  width: 100%;
  aspect-ratio: 1;
  object-fit: cover;
  border-radius: var(--radius);
  border: 1px solid var(--border);
  display: block;
}

/* Each photo is a real link to its full-size file, so the gallery still works
   with the script blocked. The radius is repeated here because the focus ring
   follows the link box, not the image inside it. */
.gallery-item {
  display: block;
  border-radius: var(--radius);
  transition: transform 0.2s ease;
}

.gallery-item:hover {
  transform: translateY(-2px);
}

/* gallery.js pages the grid by setting `hidden`. .gallery-item sets display,
   which would otherwise beat the UA stylesheet's [hidden] rule and leave every
   photo on screen. */
.gallery-item[hidden] {
  display: none;
}

/* Pager and lightbox controls are both built in JS, so nothing here is styling
   markup a visitor without JS can see. */
.gallery-pager {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.5rem;
  margin-top: 2rem;
}

.gallery-pager-btn {
  min-width: 44px;
  min-height: 44px;
  padding: 0 0.75rem;
  font: inherit;
  font-family: var(--font-heading);
  color: var(--ink-muted);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: color 0.2s ease, border-color 0.2s ease, background 0.2s ease;
}

.gallery-pager-btn:hover:not(:disabled) {
  color: var(--brand);
  border-color: var(--brand);
}

/* The current page is marked with aria-current rather than disabled, so it keeps
   its place in the tab order and still announces which page you are on. */
.gallery-pager-btn[aria-current="true"] {
  background: var(--brand-fill);
  border-color: var(--brand-fill);
  color: var(--on-brand);
}

.gallery-pager-btn:disabled {
  opacity: 0.4;
  cursor: default;
}

.gallery-count {
  margin: 0.75rem 0 0;
  text-align: center;
  font-size: 0.875rem;
  color: var(--ink-muted);
}

/* Lightbox. --scrim is already defined in all three theme blocks for the hero
   overlay, so the backdrop needs no new token. */
.lightbox {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding: 1rem;
  background: var(--scrim);
}

.lightbox[hidden] {
  display: none;
}

/* Set on <html> while the viewer is open: without it a scroll gesture over the
   backdrop moves the article underneath instead of doing nothing. */
.has-lightbox {
  overflow: hidden;
}

.lightbox-figure {
  margin: 0;
  max-width: min(100%, 900px);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.75rem;
}

.lightbox-figure img {
  max-width: 100%;
  /* Leave room for the caption and the padding, or a tall photo pushes its own
     caption off the bottom of the viewport. */
  max-height: calc(100vh - 8rem);
  object-fit: contain;
  border-radius: var(--radius);
}

.lightbox-figure figcaption {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.5rem 1rem;
  text-align: center;
  font-size: 0.875rem;
  color: var(--ondark-ink);
}

.lightbox-counter {
  color: var(--ondark-muted);
  font-variant-numeric: tabular-nums;
}

.lightbox-close,
.lightbox-nav {
  flex: none;
  min-width: 44px;
  min-height: 44px;
  font-size: 1.5rem;
  line-height: 1;
  color: var(--ondark-ink);
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: color 0.2s ease, border-color 0.2s ease;
}

.lightbox-close:hover,
.lightbox-nav:hover {
  color: var(--brand-bright);
  border-color: var(--brand-bright);
}

.lightbox-close {
  position: absolute;
  top: 1rem;
  right: 1rem;
}

/* Below this the arrows would squeeze the photo into a sliver between them, so
   they move to sit over the bottom corners instead. */
@media (max-width: 600px) {
  .lightbox-nav {
    position: absolute;
    bottom: 1rem;
  }

  .lightbox-nav[data-rel="prev"] {
    left: 1rem;
  }

  .lightbox-nav[data-rel="next"] {
    right: 1rem;
  }

  .lightbox-figure img {
    max-height: calc(100vh - 12rem);
  }
}

/* Testimonial */
.testimonial {
  display: flex;
  gap: 2rem;
  align-items: center;
  max-width: 800px;
  margin: 0 auto;
}

.testimonial img {
  width: 120px;
  height: 120px;
  object-fit: cover;
  border-radius: 50%;
  flex-shrink: 0;
  box-shadow: var(--shadow);
}

.testimonial blockquote {
  margin: 0;
  font-size: 1.25rem;
  font-style: italic;
}

.testimonial cite {
  display: block;
  margin-top: 0.75rem;
  font-family: var(--font-heading);
  font-weight: 600;
  font-style: normal;
}

/* CTA */
.cta {
  text-align: center;
}

.cta p {
  max-width: 55ch;
  margin-left: auto;
  margin-right: auto;
}

.cta .button {
  margin-top: 1.5rem;
}

/* Contact */
.contact-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 3rem;
  align-items: start;
}

.contact-grid img {
  border-radius: var(--radius);
}

/* A paragraph whose entire content is one link is a call to action, not prose, so it
   takes the same 44px floor as the nav. Scoped to .card deliberately: inflating a link
   that sits mid-sentence would distort the line box around it, and the footer's own
   links are handled by their own rule. */
.card p > a:only-child {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
}

.form-field {
  margin-bottom: 1.25rem;
}

.form-field label {
  display: block;
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 0.875rem;
  margin-bottom: 0.375rem;
}

.form-field input,
.form-field textarea {
  width: 100%;
  padding: 0.75rem;
  font: inherit;
  background: var(--surface);
  color: var(--ink);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  transition: border-color 0.2s ease, box-shadow 0.2s ease;
}

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

/* The box itself is 24px, not 44 — a 44px checkbox looks like a bug. The row is the
   target instead: it is 44px tall, and the <label> is bound to the input by `for`, so
   the whole line toggles it. That is the honest way to hit the floor here. */
.form-field--checkbox {
  display: flex;
  gap: 0.6rem;
  align-items: center;
  min-height: 44px;
}

.form-field--checkbox input {
  width: 24px;
  height: 24px;
  flex: none;
  accent-color: var(--brand-fill);
}

/* gap, not a space character: making the label a flex container drops the whitespace
   text node between "the" and the link, so the two words ran together. */
.form-field--checkbox label {
  display: flex;
  align-items: center;
  gap: 0.3em;
  min-height: 44px;
  cursor: pointer;
}

/* Its own target, separate from the checkbox — it navigates rather than toggling. It
   sits inside the 44px row, so this adds no height. */
.form-field--checkbox label a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
}

.form-field--checkbox label {
  font-family: var(--font-body);
  font-weight: 400;
  margin: 0;
}

/* Footer */
.site-footer {
  background: var(--ondark-bg);
  color: var(--ondark-muted);
  padding: 3rem 0 1.5rem;
}

.site-footer h3 {
  color: var(--ondark-ink);
  font-size: 1rem;
  margin-bottom: 0.75rem;
}

/* The logo is the grid's first column, sitting left of Menu, rather than a banner
   above the whole row. Stacked it left a wide empty band to its right; as a column
   it balances the four text columns and the footer reads as one row. align-self
   keeps its top on the same line as the h3s instead of stretching to row height. */
.footer-logo {
  display: block;
  max-width: 190px;
  height: auto;
}

.tagline {
  display: block;
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 0.75rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

/* The hero is an always-dark zone regardless of theme, so anything sitting on it
   takes an --ondark-* token. --ink-faint here rendered dark-grey-on-photo. */
.hero .tagline {
  color: var(--ondark-muted);
}

.site-footer .tagline {
  color: var(--ondark-muted);
}

/* Two grids, not one, and the nesting is the whole point.

   The outer grid holds exactly two things: the logo and the block of text columns.
   align-items: end bottom-aligns those two against each other, so the columns hang
   from the line under "PRECISION TERMINATION".

   The inner grid holds the three columns and is left alone, so they keep their tops
   level with each other and the headings stay in one row. Bottom-aligning the
   columns individually would instead push each heading down by however little
   content its column has — Contacts, with two lines, ended up about 70px below
   Menu. Aligning the group rather than its members is what avoids that. */
.footer-grid {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 2rem;
  margin-bottom: 2.5rem;
  align-items: end;
}

/* Columns sized to their content, kept together as a group at the end of the row.

   This used to be justify-content: space-between, which was right for four
   columns and wrong for three. space-between hands every pixel of slack to the
   gaps, and losing the newsletter both freed more slack and left one fewer gap to
   absorb it — so the same rule that had produced comfortable spacing produced
   ~480px voids, with Socials stranded against the right edge a long way from
   anything.

   A fixed gap and justify-content: end instead. The leftover width collects in
   one place, between the logo and the columns, where it reads as the layout
   having two sides rather than as three columns adrift. The clamp keeps the gap
   from getting tight before the 900px breakpoint hands over to auto-fit.

   The tracks stay max-content for the original reason: equal 1fr tracks made
   every column as wide as the widest, so a 85px Menu list sat in a 196px box and
   the space piled up inside each column instead of between them. */
.footer-columns {
  display: grid;
  grid-template-columns: repeat(3, max-content);
  justify-content: end;
  gap: clamp(2rem, 5vw, 4.5rem);
}

/* Content-sized tracks cannot shed columns the way auto-fit does, and they stop
   fitting beside the logo at about 900px. Hand back to the equal-width auto-fit
   layout there; below 720px the footer stacks entirely anyway. */
@media (max-width: 900px) {
  .footer-columns {
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    justify-content: normal;
  }
}

/* Trailing margins would hold the block off that line by whatever the tallest
   column happens to end with — 8px under a list, 16px under a paragraph. Zero them
   so what lands on the baseline is the last line of text, not the box around it. */
.footer-columns > div > :last-child,
.footer-columns li:last-child {
  margin-bottom: 0;
}

/* The outer grid is the one thing here that cannot resolve itself: two explicit
   tracks stay two tracks however narrow the viewport gets, so the logo would sit
   in a squeezed column beside the text. Collapse it at the same 720px the nav
   uses. The inner grid needs no such help — auto-fit already sheds columns. */
@media (max-width: 720px) {
  .footer-grid {
    grid-template-columns: 1fr;
    align-items: start;
  }
}

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

.site-footer li {
  margin-bottom: 0;
}

/* Footer links are the most-tapped thing on the site's most-scrolled-to region, and
   at 22px they were half the 44px floor — "X" was 9px wide, essentially unhittable.
   The height comes from the link box rather than the list item's margin, so the
   target grows without the column gaining an equal amount of dead space. min-width
   is what rescues the single-character links. */
.site-footer a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  min-width: 44px;
  color: var(--ondark-muted);
  text-decoration: none;
}

.site-footer a:hover {
  color: var(--brand-bright);
}

/* Status line under the contact form: "Sending…", then success or failure.
   Neutral by default because the first thing it says is neither. */
.form-note {
  margin: 0.75rem 0 0;
  font-size: 0.875rem;
  line-height: 1.5;
  color: var(--ink-muted);
}

/* Colour is not the only signal — the wording carries the outcome on its own, so
   these read the same to anyone who cannot tell the two apart. */
.form-note--ok {
  color: var(--brand);
}

.form-note--error {
  color: var(--ink);
  font-weight: 600;
}

/* Honeypot. Off-screen rather than display:none, which the more careful bots
   check for and skip. aria-hidden and tabindex="-1" in the markup keep it away
   from screen readers and the keyboard, so nobody real ever meets it. */
.form-honeypot {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.footer-bottom {
  border-top: 1px solid var(--ondark-muted);
  padding-top: 1.5rem;
  text-align: center;
  font-size: 0.875rem;
}

@media (max-width: 720px) {
  .nav-toggle {
    display: inline-flex;
  }

  .site-nav {
    flex-basis: 100%;
    display: none;
  }

  .site-nav.is-open {
    display: block;
  }

  .site-nav ul {
    flex-direction: column;
    align-items: stretch;
    gap: 0;
  }

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

  .site-nav li:first-child {
    border-top: none;
  }

  .site-nav a {
    display: block;
    padding: 0.875rem 0;
  }

  .site-nav__theme {
    margin-left: 0;
    padding-left: 0;
    border-left: none;
  }

  .theme-toggle {
    width: 100%;
    justify-content: flex-start;
    padding: 0.875rem 0;
    border: none;
    border-radius: 0;
  }

  .theme-toggle__label {
    display: inline;
  }

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

  .testimonial {
    flex-direction: column;
    text-align: center;
  }
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    transition: none !important;
    animation: none !important;
  }
}
