/* ==========================================================================
   Fackrell Masonry and Construction — fmandc.com
   Hand-written stylesheet. Replaces the 69 KB compiled Tailwind bundle left
   over from the retired React build, whose source no longer existed.

   Design direction "The Trade Sign": warm off-white ground, one brick-red
   accent used only where it means something, hairline rules instead of
   shadows, generous whitespace, editorial and slightly asymmetric. Nothing
   here should read as a template.

   Tokens come from the FMandC brand: brick red #BF1D1D, warm neutrals at a
   30-40 degree hue so every grey is brown-tinted like mortar. Never
   introduce a cool blue-grey.

   Organisation:
     1. Tokens
     2. Reset and base
     3. Typography
     4. Layout primitives
     5. Header and navigation
     6. Buttons and links
     7. Home page
     8. Service pages
     9. Project pages and galleries
    10. Reviews
    11. Footer
    12. Utilities, motion, print
   ========================================================================== */

/* 1. TOKENS ================================================================ */

@font-face {
  font-family: 'Inter';
  src: url('/assets/fonts/inter-var-latin.woff2') format('woff2');
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6,
    U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
    U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Montserrat';
  src: url('/assets/fonts/montserrat-var-latin.woff2') format('woff2');
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6,
    U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
    U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/*
 * Metric-matched fallbacks. Both faces are preloaded and same-origin, so they
 * almost always arrive before first paint — but on a cold, slow connection the
 * browser paints in a system font first and reflows when the real one lands,
 * which is measurable layout shift on pages with a lot of body copy.
 *
 * These overrides make the fallback occupy the same vertical space and roughly
 * the same width as the real face, so the swap is invisible rather than a jump.
 * The percentages are derived from each font's own metrics against Arial.
 */
@font-face {
  font-family: 'Inter Fallback';
  src: local('Arial');
  ascent-override: 90%;
  descent-override: 22.43%;
  line-gap-override: 0%;
  size-adjust: 107.12%;
}
@font-face {
  font-family: 'Montserrat Fallback';
  src: local('Arial');
  ascent-override: 84.95%;
  descent-override: 22.03%;
  line-gap-override: 0%;
  size-adjust: 113.95%;
}

:root {
  /* Colour */
  --red: #bf1d1d;
  --red-dark: #9a1717;
  --red-tint: #fdf3f2;
  --ground: #fcfaf8;
  --ground-alt: #f7f5f2;
  --card: #ffffff;
  --ink: #2a2622;
  --ink-soft: #544d45;
  --ink-faint: #7c7168;
  --rule: #e8e6e3;
  --rule-strong: #d6d1cb;
  --dark: #2a2622;
  --dark-soft: #3a352f;
  --on-dark: #ece7e1;
  --on-dark-soft: #b3aaa0;

  /* Type */
  --sans: 'Inter', 'Inter Fallback', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --display: 'Montserrat', 'Montserrat Fallback', 'Inter', system-ui, sans-serif;

  /* Fluid scale. Min is the 375px value, max the 1440px value. */
  --t--1: 0.8125rem;
  --t-0: 1rem;
  --t-1: clamp(1.0625rem, 0.99rem + 0.32vw, 1.1875rem);
  --t-2: clamp(1.1875rem, 1.07rem + 0.5vw, 1.375rem);
  --t-3: clamp(1.375rem, 1.2rem + 0.75vw, 1.75rem);
  --t-4: clamp(1.625rem, 1.32rem + 1.3vw, 2.25rem);
  --t-5: clamp(2rem, 1.5rem + 2.13vw, 3rem);
  --t-6: clamp(2.375rem, 1.5rem + 3.7vw, 4rem);

  /* Spacing, 8px scale */
  --s-1: 0.25rem;
  --s-2: 0.5rem;
  --s-3: 0.75rem;
  --s-4: 1rem;
  --s-5: 1.5rem;
  --s-6: 2rem;
  --s-7: 3rem;
  --s-8: 4rem;
  --s-9: 6rem;
  --s-10: 8rem;

  --radius: 0.5rem;
  --radius-sm: 0.375rem;
  --measure: 68ch;
  --page: 1140px;
  --gutter: clamp(1.25rem, 0.9rem + 1.5vw, 2.5rem);

  /* Height of the sticky site header, which is the tallest control in the bar
     plus its padding and rule: the quote button, not the logo. The project
     category bar sticks directly beneath it, and section headings offset
     their scroll target by both, so a jump link never parks a heading
     underneath the chrome. Measure the header again after changing the height
     of anything in it. */
  --header-h: 73px;
}
@media (max-width: 480px) {
  :root {
    --header-h: 69px;
  }
}

/* 2. RESET AND BASE ======================================================== */

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

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

body {
  margin: 0;
  background: var(--ground);
  color: var(--ink);
  font-family: var(--sans);
  font-size: var(--t-1);
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

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

/* Images always know their aspect ratio before they load, so nothing on the
   page jumps. Paired with width/height attributes in the markup. */
img {
  background-color: var(--ground-alt);
}

h1,
h2,
h3,
h4 {
  margin: 0;
  font-family: var(--display);
  font-weight: 800;
  letter-spacing: -0.022em;
  line-height: 1.12;
  text-wrap: balance;
}

p,
ul,
ol,
figure,
blockquote,
dl {
  margin: 0;
}

a {
  color: inherit;
}

:focus-visible {
  outline: 3px solid var(--red);
  outline-offset: 3px;
  border-radius: 2px;
}

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

/* 3. TYPOGRAPHY ============================================================ */

.eyebrow {
  display: block;
  font-family: var(--sans);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--red);
}

.lede {
  font-size: var(--t-2);
  line-height: 1.55;
  color: var(--ink-soft);
  max-width: 46ch;
}

/* Long-form body copy: project stories, service intros, the story page. */
.prose {
  max-width: var(--measure);
}
.prose > * + * {
  margin-top: var(--s-4);
}
.prose h2 {
  font-size: var(--t-3);
  margin-top: var(--s-7);
}
.prose h3 {
  font-size: var(--t-2);
  margin-top: var(--s-6);
}
.prose ul,
.prose ol {
  padding-left: 1.35em;
}
.prose li + li {
  margin-top: var(--s-2);
}
.prose li::marker {
  color: var(--red);
}
.prose a {
  color: var(--red);
  text-decoration: underline;
  text-underline-offset: 0.15em;
  text-decoration-thickness: 1px;
}
.prose a:hover {
  text-decoration-thickness: 2px;
}
.prose strong {
  font-weight: 600;
}

blockquote.pull {
  border-left: 3px solid var(--red);
  padding: var(--s-1) 0 var(--s-1) var(--s-5);
  font-size: var(--t-2);
  line-height: 1.6;
  color: var(--ink-soft);
  max-width: 58ch;
}
blockquote.pull cite {
  display: block;
  margin-top: var(--s-3);
  font-size: var(--t-0);
  font-style: normal;
  font-weight: 600;
  color: var(--ink);
}

/* 4. LAYOUT PRIMITIVES ===================================================== */

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

.section {
  padding-block: var(--s-8);
}
@media (min-width: 900px) {
  .section {
    padding-block: var(--s-9);
  }
}
.section--tight {
  padding-block: var(--s-7);
}
.section--alt {
  background: var(--ground-alt);
  border-block: 1px solid var(--rule);
}

.section-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--s-4);
  padding-bottom: var(--s-4);
  border-bottom: 2px solid var(--ink);
}
.section-head h2 {
  font-size: var(--t-4);
}
.section-head p {
  font-size: var(--t-0);
  color: var(--ink-soft);
  max-width: 42ch;
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  background: var(--red);
  color: #fff;
  padding: var(--s-3) var(--s-4);
  font-weight: 600;
  border-radius: 0 0 var(--radius-sm) 0;
}
.skip-link:focus {
  left: 0;
}

/* 5. HEADER AND NAVIGATION ================================================= */

.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: color-mix(in srgb, var(--ground) 92%, transparent);
  backdrop-filter: saturate(1.4) blur(10px);
  border-bottom: 1px solid var(--rule);
}
.site-header__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-4);
  padding-block: var(--s-3);
}
.site-header__logo img {
  height: 42px;
  width: auto;
}

.nav {
  display: none;
}
.nav ul {
  display: flex;
  align-items: center;
  gap: var(--s-5);
  list-style: none;
  padding: 0;
}
.nav a {
  display: block;
  padding-block: var(--s-2);
  font-size: 0.9375rem;
  font-weight: 500;
  color: var(--ink-soft);
  text-decoration: none;
  border-bottom: 2px solid transparent;
}
.nav a:hover {
  color: var(--ink);
}
.nav a[aria-current='page'] {
  color: var(--ink);
  border-bottom-color: var(--red);
}
.nav a.nav__cta {
  padding: var(--s-2) var(--s-4);
  margin-left: var(--s-2);
  background: var(--red);
  color: #fff;
  border: 1.5px solid var(--red);
  border-radius: var(--radius-sm);
}
.nav a.nav__cta:hover {
  background: var(--red-dark);
  border-color: var(--red-dark);
  color: #fff;
}

.site-header__tools {
  display: flex;
  align-items: center;
  gap: var(--s-2);
}

.nav-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  padding: 0;
  background: none;
  border: 1px solid var(--rule-strong);
  border-radius: var(--radius-sm);
  color: var(--ink);
  cursor: pointer;
}
.nav-toggle svg {
  width: 22px;
  height: 22px;
}
.nav-toggle__close {
  display: none;
}
.nav-toggle[aria-expanded='true'] .nav-toggle__open {
  display: none;
}
.nav-toggle[aria-expanded='true'] .nav-toggle__close {
  display: block;
}

.nav-drawer {
  border-top: 1px solid var(--rule);
  background: var(--ground);
}
.nav-drawer[hidden] {
  display: none;
}
.nav-drawer ul {
  list-style: none;
  padding: var(--s-2) 0 var(--s-5);
  margin: 0;
}
.nav-drawer a {
  display: block;
  padding: var(--s-4) 0;
  font-size: var(--t-1);
  font-weight: 500;
  text-decoration: none;
  border-bottom: 1px solid var(--rule);
}
.nav-drawer a[aria-current='page'] {
  color: var(--red);
}
.nav-drawer .btn {
  margin-top: var(--s-5);
  width: 100%;
  text-align: center;
}

/* On a phone the header carries the logo, the Ask pill, the quote button and
   the menu toggle side by side. At 360px the quote button wrapped to two lines
   and crowded the logo, so it stays but gets compact here. It is not hidden:
   the quote is the page's job, and burying it behind the hamburger costs
   conversions. */
@media (max-width: 480px) {
  .site-header__bar {
    gap: var(--s-3);
  }
  .site-header__tools .btn {
    min-height: 44px;
    padding: var(--s-2) var(--s-3);
    font-size: 0.8125rem;
    white-space: nowrap;
  }
  .site-header__logo img {
    height: 38px;
  }
}

@media (min-width: 900px) {
  .nav {
    display: block;
    /* Pushes the links and the Ask pill together against the right edge
       instead of letting space-between strand the nav in the middle. */
    margin-left: auto;
  }
  .nav-toggle,
  .nav-drawer,
  .site-header__quote {
    display: none !important;
  }
  .site-header__logo img {
    height: 48px;
  }
}

/* Breadcrumbs */
.crumbs {
  padding-top: var(--s-5);
  font-size: 0.875rem;
  color: var(--ink-faint);
}
.crumbs ol {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2);
  list-style: none;
  padding: 0;
}
.crumbs li + li::before {
  content: '/';
  margin-right: var(--s-2);
  color: var(--rule-strong);
}
.crumbs a {
  text-decoration: none;
  color: var(--ink-soft);
}
.crumbs a:hover {
  color: var(--red);
  text-decoration: underline;
}

/* 6. BUTTONS AND LINKS ===================================================== */

.btn,
.btn-ghost {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-2);
  min-height: 48px;
  padding: var(--s-3) var(--s-5);
  font-family: var(--sans);
  font-size: var(--t-0);
  font-weight: 600;
  line-height: 1.2;
  text-decoration: none;
  border-radius: var(--radius-sm);
  transition: background-color 0.18s ease, color 0.18s ease,
    border-color 0.18s ease;
}
.btn {
  background: var(--red);
  color: #fff;
  border: 1.5px solid var(--red);
}
.btn:hover {
  background: var(--red-dark);
  border-color: var(--red-dark);
}
.btn-ghost {
  background: transparent;
  color: var(--ink);
  border: 1.5px solid var(--ink);
}
.btn-ghost:hover {
  background: var(--ink);
  color: var(--ground);
}
.actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-3);
}
@media (max-width: 479px) {
  .actions {
    display: grid;
  }
}

.arrow-link {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  font-weight: 600;
  color: var(--red);
  text-decoration: none;
}
.arrow-link:hover {
  text-decoration: underline;
  text-underline-offset: 0.2em;
}

/* 7. HOME PAGE ============================================================= */

.hero {
  padding-block: var(--s-8) var(--s-7);
}
@media (min-width: 900px) {
  .hero {
    padding-block: var(--s-9) var(--s-8);
  }
}
.hero__grid {
  display: grid;
  gap: var(--s-7);
}
@media (min-width: 1000px) {
  .hero__grid {
    grid-template-columns: minmax(0, 1.6fr) minmax(0, 0.9fr);
    gap: var(--s-8);
    align-items: start;
  }
}
.hero h1 {
  font-size: var(--t-6);
  line-height: 1.02;
  margin-block: var(--s-4) var(--s-5);
}
.hero h1 em {
  font-style: normal;
  color: var(--red);
}
.hero .lede {
  margin-bottom: var(--s-6);
}

/* Credentials panel — the red top rule is the only heavy colour on the page. */
.credentials {
  background: var(--card);
  border: 1px solid var(--rule);
  border-top: 4px solid var(--red);
  border-radius: var(--radius-sm);
  padding: var(--s-5);
}
.credentials h2 {
  font-size: 0.8125rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  margin-bottom: var(--s-4);
}
.credentials dl {
  display: grid;
  gap: 0;
}
.credentials div {
  display: flex;
  justify-content: space-between;
  gap: var(--s-4);
  padding-block: var(--s-3);
  border-bottom: 1px dotted var(--rule-strong);
  font-size: 0.9375rem;
}
.credentials div:last-child {
  border-bottom: 0;
}
.credentials dt {
  color: var(--ink-soft);
}
.credentials dd {
  margin: 0;
  font-weight: 600;
  text-align: right;
}
.credentials .verify {
  display: inline-block;
  margin-top: var(--s-4);
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--red);
}

/* Proof strip — six recent jobs, small, as evidence rather than a gallery. */
.proof {
  background: var(--ground-alt);
  border-block: 1px solid var(--rule);
  padding-block: var(--s-5);
}
.proof__head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s-3);
  margin-bottom: var(--s-4);
}
.proof__head h2 {
  font-size: 0.8125rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}
.proof__strip {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--s-3);
}
@media (min-width: 600px) {
  .proof__strip {
    grid-template-columns: repeat(3, 1fr);
  }
}
@media (min-width: 1000px) {
  .proof__strip {
    grid-template-columns: repeat(6, 1fr);
  }
}
.proof__strip a {
  display: block;
  border-radius: var(--radius-sm);
  overflow: hidden;
  border: 1px solid var(--rule);
  text-decoration: none;
}
.proof__strip img {
  aspect-ratio: 1 / 1;
  object-fit: cover;
  width: 100%;
  transition: transform 0.25s ease;
}
.proof__strip a:hover img {
  transform: scale(1.04);
}
/* The label under each thumbnail is visible on purpose: six words of plain
   English do more to explain the range of the work than six photographs
   alone, and a visitor scanning the strip should not have to guess. */
.proof__strip span {
  display: block;
  padding: var(--s-3) var(--s-3) var(--s-3);
  background: var(--card);
  border-top: 1px solid var(--rule);
  font-size: 0.75rem;
  font-weight: 600;
  line-height: 1.35;
  letter-spacing: 0.01em;
  color: var(--ink);
  text-wrap: balance;
}
.proof__strip a:hover span {
  color: var(--red);
}

/* The numbered service index — the signature element of this design. */
.index {
  display: grid;
  gap: 0;
}
@media (min-width: 860px) {
  .index {
    grid-template-columns: 1fr 1fr;
    column-gap: var(--s-8);
  }
}
.index a {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: baseline;
  gap: var(--s-4);
  padding-block: var(--s-4);
  border-bottom: 1px solid var(--rule);
  text-decoration: none;
  transition: color 0.15s ease;
}
.index a:hover {
  color: var(--red);
}
.index__n {
  font-family: var(--display);
  font-weight: 800;
  font-size: 0.8125rem;
  color: var(--red);
  font-variant-numeric: tabular-nums;
}
.index__t {
  font-family: var(--display);
  font-weight: 700;
  font-size: var(--t-2);
  letter-spacing: -0.015em;
}
.index__t small {
  display: block;
  margin-top: var(--s-1);
  font-family: var(--sans);
  font-weight: 400;
  font-size: 0.9375rem;
  line-height: 1.5;
  letter-spacing: 0;
  color: var(--ink-soft);
}
.index__ar {
  color: var(--red);
  opacity: 0;
  transition: opacity 0.15s ease, transform 0.15s ease;
}
.index a:hover .index__ar,
.index a:focus-visible .index__ar {
  opacity: 1;
  transform: translateX(3px);
}

/* Family / story band */
.story-band__grid {
  display: grid;
  gap: var(--s-6);
  align-items: center;
}
@media (min-width: 900px) {
  .story-band__grid {
    grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr);
    gap: var(--s-8);
  }
}
.story-band figure img {
  width: 100%;
  border-radius: var(--radius-sm);
  border: 1px solid var(--rule);
  object-fit: cover;
}
.story-band figcaption {
  margin-top: var(--s-2);
  font-size: 0.875rem;
  color: var(--ink-soft);
}
.story-band h2 {
  font-size: var(--t-4);
  margin-block: var(--s-3) var(--s-4);
}

/* 8. SERVICE PAGES ========================================================= */

.page-head {
  padding-block: var(--s-6) var(--s-7);
}
.page-head h1 {
  font-size: var(--t-5);
  margin-block: var(--s-3) var(--s-4);
}
/* The direct answer. Deliberately the first prose on the page: this is the
   sentence a search engine or an assistant quotes. */
.answer {
  font-size: var(--t-2);
  line-height: 1.55;
  color: var(--ink);
  max-width: 58ch;
}
.page-head .actions {
  margin-top: var(--s-6);
}

.facts {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  border: 1px solid var(--rule);
  border-radius: var(--radius-sm);
  background: var(--card);
  overflow: hidden;
  margin-top: var(--s-6);
}
@media (min-width: 780px) {
  .facts {
    grid-template-columns: repeat(4, 1fr);
  }
}
.facts > div {
  padding: var(--s-4);
  border-right: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
}
.facts dt {
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin-bottom: var(--s-2);
}
.facts dd {
  margin: 0;
  font-family: var(--display);
  font-weight: 700;
  font-size: var(--t-1);
  letter-spacing: -0.015em;
}
.facts dd small {
  display: block;
  margin-top: var(--s-1);
  font-family: var(--sans);
  font-weight: 400;
  font-size: 0.8125rem;
  letter-spacing: 0;
  color: var(--ink-soft);
}

/* Two columns of a grid line up row by row, so a one-line item sitting beside
   a six-line item inherits the taller one's row height and leaves a hole under
   it. These lists are deliberately uneven, so they use multi-column instead:
   the items pack tight and flow into the next column when the first is full.
   break-inside keeps a single bullet from being split across the two columns. */
.checklist {
  list-style: none;
  padding: 0;
}
.checklist li {
  position: relative;
  padding-left: 1.6em;
  line-height: 1.55;
  break-inside: avoid;
  -webkit-column-break-inside: avoid;
  page-break-inside: avoid;
}
.checklist li + li {
  margin-top: var(--s-3);
}
@media (min-width: 700px) {
  .checklist {
    column-count: 2;
    column-gap: var(--s-6);
  }
  /* In columns, the item at the top of the second column is still an `li + li`,
     so it would carry a margin the first column's top item does not have and
     the two columns would start at different heights. */
  .checklist li {
    margin-top: 0;
    margin-bottom: var(--s-3);
  }
  .checklist li + li {
    margin-top: 0;
  }
}
.checklist li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0.62em;
  width: 0.5em;
  height: 0.5em;
  background: var(--red);
  border-radius: 1px;
  transform: rotate(45deg);
}

/* The Ask pill and its panel. The header keeps one small, quiet control
   instead of a search bar spanning the whole width, and the questions open in
   a native <dialog> over the page.

   Two things depend on it being a real <dialog>: the browser puts it in the
   top layer, so nothing on the page can cover it whatever the z-index, and it
   traps focus and handles Escape without a line of script. Never swap it for
   a positioned div. */
.ask-open,
.portal-open {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  min-height: 44px;
  padding: var(--s-2) var(--s-4);
  border: 1px solid var(--rule-strong);
  border-radius: 999px;
  background: none;
  font-family: var(--sans);
  font-size: 0.9375rem;
  font-weight: 500;
  line-height: 1;
  color: var(--ink-soft);
  text-decoration: none;
  cursor: pointer;
  transition: color 160ms ease-out, border-color 160ms ease-out,
    background-color 160ms ease-out;
}
.ask-open:hover,
.portal-open:hover {
  background: var(--red-tint);
  border-color: var(--red);
  color: var(--red);
}
.ask-open svg,
.portal-open svg {
  width: 1rem;
  height: 1rem;
}

/* Below 900px the header has no room left, so the portal link is carried by the
   menu drawer and the footer instead. Keep it out of the bar rather than
   shrinking it to a third icon beside Ask and the menu toggle. */
.portal-open {
  display: none;
}
@media (min-width: 900px) {
  .portal-open {
    display: inline-flex;
  }
}

.ask {
  /* The drop from the top is also what the height has to give back, so it is
     a variable rather than two numbers that can drift apart and let the panel
     hang off the bottom of a short window. */
  --ask-top: clamp(var(--s-6), 12vh, var(--s-9));

  width: min(36rem, calc(100vw - var(--s-6)));
  max-height: calc(100dvh - var(--ask-top) - var(--s-6));
  margin: var(--ask-top) auto var(--s-6);
  padding: 0;
  border: 1px solid var(--rule-strong);
  border-radius: var(--radius);
  background: var(--card);
  color: var(--ink);
  box-shadow: 0 32px 64px -24px rgb(42 38 34 / 40%);
  overflow: hidden;
}
.ask::backdrop {
  background: rgb(42 38 34 / 45%);
  backdrop-filter: blur(3px);
}
.ask[open] {
  animation: ask-rise 180ms ease-out;
}
.ask[open]::backdrop {
  animation: ask-fade 180ms ease-out;
}
@keyframes ask-rise {
  from {
    opacity: 0;
    transform: translateY(-0.5rem);
  }
}
@keyframes ask-fade {
  from {
    opacity: 0;
  }
}

.ask__panel {
  display: flex;
  flex-direction: column;
  max-height: inherit;
  padding: var(--s-5);
}
.ask__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s-4);
}
.ask__title {
  margin: 0;
  font-size: var(--t--1);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink-faint);
}
.ask__close {
  flex: none;
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  margin: -0.6rem -0.6rem -0.6rem 0;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: none;
  color: var(--ink-faint);
  cursor: pointer;
}
.ask__close:hover {
  background: var(--ground-alt);
  color: var(--ink);
}
.ask__close svg {
  width: 1.1rem;
  height: 1.1rem;
}

.ask__form {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  margin-top: var(--s-3);
  padding-bottom: var(--s-3);
  border-bottom: 2px solid var(--rule-strong);
  transition: border-color 160ms ease-out;
}
.ask__form:focus-within {
  border-bottom-color: var(--red);
}
.ask__icon {
  flex: none;
  width: 1.25rem;
  height: 1.25rem;
  color: var(--ink-faint);
}
.ask__input {
  flex: 1 1 auto;
  min-width: 0;
  padding: 0;
  border: 0;
  background: none;
  font-family: var(--display);
  font-size: var(--t-2);
  font-weight: 500;
  color: var(--ink);
}
.ask__input::placeholder {
  font-weight: 400;
  color: var(--ink-faint);
}
.ask__input:focus {
  outline: none;
}
.ask__input::-webkit-search-cancel-button {
  display: none;
}
.ask__clear,
.ask__mic {
  flex: none;
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: none;
  color: var(--ink-faint);
  cursor: pointer;
}
.ask__clear svg {
  width: 1rem;
  height: 1rem;
}
.ask__mic svg {
  width: 1.25rem;
  height: 1.25rem;
}
.ask__clear:hover,
.ask__mic:hover {
  background: var(--ground-alt);
  color: var(--ink);
}
/* `hidden` is a UA display rule, and the display above outranks it. Without
   this the clear cross sits in an empty box and the mic shows in a browser
   that cannot listen. */
.ask__clear[hidden],
.ask__mic[hidden] {
  display: none;
}
/* Listening is the one state on the site that keeps moving on its own, so it
   is the one place a pulse is worth the attention it takes. */
.ask.is-listening .ask__mic {
  background: var(--red);
  color: #fff;
  animation: ask-pulse 1.4s ease-out infinite;
}
@keyframes ask-pulse {
  from {
    box-shadow: 0 0 0 0 rgb(191 29 29 / 45%);
  }
  to {
    box-shadow: 0 0 0 0.75rem rgb(191 29 29 / 0%);
  }
}

.ask__hint {
  margin: var(--s-3) 0 0;
  font-size: var(--t--1);
  color: var(--ink-faint);
}
.ask.is-listening .ask__hint {
  color: var(--red);
}

.ask__seeds {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2);
  margin-top: var(--s-4);
}
.ask__seeds[hidden] {
  display: none;
}
.ask__seed {
  padding: 0.35rem var(--s-3);
  border: 1px solid var(--rule);
  border-radius: 999px;
  background: var(--ground-alt);
  font: inherit;
  font-size: var(--t--1);
  color: var(--ink-soft);
  cursor: pointer;
}
.ask__seed:hover {
  border-color: var(--red);
  background: var(--red-tint);
  color: var(--red);
}

.ask__results {
  flex: 1 1 auto;
  overflow-y: auto;
  margin: var(--s-4) calc(var(--s-5) * -1) calc(var(--s-5) * -1);
  border-top: 1px solid var(--rule);
}
.ask__hit {
  display: grid;
  gap: 0.15rem;
  padding: var(--s-3) var(--s-5);
  border-top: 1px solid var(--rule);
  color: inherit;
  text-decoration: none;
}
.ask__hit:first-child {
  border-top: 0;
}
.ask__hit:hover,
.ask__hit[aria-selected='true'] {
  background: var(--red-tint);
}
.ask__hit-q {
  font-family: var(--display);
  font-weight: 600;
  color: var(--ink);
}
.ask__hit-where {
  font-size: var(--t--1);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--red);
}
.ask__hit-snip {
  font-size: var(--t--1);
  color: var(--ink-faint);
  /* Two lines of the answer is enough to recognise it and short enough that
     eight results still fit on a phone screen. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
/* Database answers have no page to jump to, so they open right in the list.
   The hit is a <button>, not a link, and clicking it swaps the two-line
   snippet for the full answer. */
.ask__hit--extra {
  width: 100%;
  border-left: 0;
  border-right: 0;
  border-bottom: 0;
  background: none;
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.ask__hit--extra .ask__hit-full {
  display: none;
}
.ask__hit--extra.is-open .ask__hit-snip {
  display: none;
}
.ask__hit--extra.is-open .ask__hit-full {
  display: block;
  font-size: var(--t-0);
  line-height: 1.55;
  color: var(--ink-soft);
  white-space: pre-line;
}
.ask__hit--extra.is-open {
  background: var(--red-tint);
}

/* The AI helper's answer. Deliberately set apart from Brad's own answers:
   muted ground, and the not-checked-by-FMandC label always attached. */
.ask__ai {
  display: grid;
  gap: var(--s-2);
  padding: var(--s-4) var(--s-5);
  background: var(--ground-alt);
  border-top: 1px solid var(--rule);
}
.ask__ai-a {
  margin: 0;
  font-size: var(--t-0);
  line-height: 1.55;
  color: var(--ink-soft);
}
.ask__ai .ask__hit-where {
  color: var(--ink-faint);
}
.ask__ai-note {
  margin: 0;
  font-size: var(--t--1);
  color: var(--ink-soft);
}
.ask__ai-note a,
.ask__empty a {
  color: var(--red);
  font-weight: 600;
  text-decoration: none;
}

.ask__related-note {
  margin: 0;
  padding: var(--s-3) var(--s-5) var(--s-1);
  border-top: 1px solid var(--rule);
  font-size: var(--t--1);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--ink-faint);
}

.ask__checking {
  margin: 0;
  padding: 0 var(--s-5) var(--s-4);
  font-size: var(--t--1);
  color: var(--ink-faint);
}

.ask__empty {
  padding: var(--s-4) var(--s-5);
  font-size: var(--t--1);
  color: var(--ink-soft);
}


/* At 375px the pill sits between the logo and the quote button, so it drops
   its label and keeps the icon. The word is back as soon as there is room. */
@media (max-width: 560px) {
  .ask-open {
    width: 44px;
    padding: 0;
    justify-content: center;
  }
  .ask-open span {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }
  .ask {
    --ask-top: var(--s-5);
  }
  .ask__panel {
    padding: var(--s-4);
  }
  .ask__results {
    margin-inline: calc(var(--s-4) * -1);
  }
  .ask__hit,
  .ask__empty {
    padding-inline: var(--s-4);
  }
}

@media (prefers-reduced-motion: reduce) {
  .ask[open],
  .ask[open]::backdrop,
  .ask.is-listening .ask__mic {
    animation: none;
  }
}

/* The questions read as a scannable list and each answer opens on click. The
   markup is <details>/<summary>, so this is styling native behaviour rather
   than rebuilding it: no JavaScript is involved in opening an answer. */
.faq {
  display: grid;
  gap: 0;
}
.faq__item {
  border-top: 1px solid var(--rule);
}
.faq__item:last-child {
  border-bottom: 1px solid var(--rule);
}

.faq__q {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--s-4);
  padding-block: var(--s-4);
  cursor: pointer;
  list-style: none;
  /* A closed question is a tap target on a phone, so the whole row highlights
     rather than just the words. */
  transition: color 0.15s ease;
}
/* Safari draws its own disclosure triangle and ignores list-style on summary. */
.faq__q::-webkit-details-marker {
  display: none;
}
.faq__q:hover,
.faq__item[open] > .faq__q {
  color: var(--red);
}
.faq__q:focus-visible {
  outline: 2px solid var(--red);
  outline-offset: 2px;
  border-radius: var(--radius);
}
.faq__q h3 {
  font-size: var(--t-2);
  /* Inherit the row's hover and open colour instead of staying dark. */
  color: inherit;
}

.faq__chevron {
  flex: none;
  width: 1.25rem;
  height: 1.25rem;
  margin-top: 0.2em;
  color: var(--ink-faint);
  transition: transform 0.2s ease, color 0.15s ease;
}
.faq__q:hover .faq__chevron,
.faq__item[open] .faq__chevron {
  color: var(--red);
}
.faq__item[open] .faq__chevron {
  transform: rotate(180deg);
}

.faq__a {
  padding-bottom: var(--s-5);
}
.faq p {
  max-width: var(--measure);
  color: var(--ink-soft);
}
/* A long answer is written in paragraphs and has to read as paragraphs. The
   reset zeroes margins, so without this the blank lines in the source collapse
   and five paragraphs stack into one wall of text. */
.faq p + p {
  margin-top: var(--s-3);
}
/* The one clause in an answer the reader must not miss. It carries a tint as
   well as weight, because bold alone disappears in a long answer. */
.faq__a strong {
  color: var(--ink);
  background: var(--red-tint);
  box-shadow: 0 0 0 0.15em var(--red-tint);
  border-radius: 2px;
}

/* An answer arrived at from search or a shared link is opened by script and
   briefly marked, so the reader can see which one of twelve they landed on. */
.faq__item:target,
.faq__item.is-found {
  scroll-margin-top: 5rem;
}
.faq__item.is-found > .faq__q {
  animation: faq-found 2.4s ease;
}
@keyframes faq-found {
  0%,
  70% {
    background: var(--red-tint);
  }
  100% {
    background: transparent;
  }
}
@media (prefers-reduced-motion: reduce) {
  .faq__chevron,
  .faq__q {
    transition: none;
  }
  .faq__item.is-found > .faq__q {
    animation: none;
  }
}
.faq a,
.checklist a,
.service-hero figcaption a {
  color: var(--red);
  text-decoration: underline;
  text-underline-offset: 0.15em;
  text-decoration-thickness: 1px;
}
.faq a:hover,
.checklist a:hover,
.service-hero figcaption a:hover {
  text-decoration-thickness: 2px;
}

/* The photograph at the top of a service page says what it is, so the picture
   and the paragraphs under it are talking about the same job. */
.service-hero figcaption {
  margin-top: var(--s-3);
  font-size: 0.9375rem;
  line-height: 1.6;
  color: var(--ink-soft);
  max-width: 62ch;
}
/* Same for a review the customer wrote in more than one paragraph. */
.review__text + .review__text {
  margin-top: var(--s-3);
}

.service-grid {
  display: grid;
  gap: 1px;
  background: var(--rule);
  border: 1px solid var(--rule);
  border-radius: var(--radius-sm);
  overflow: hidden;
}
@media (min-width: 640px) {
  .service-grid {
    grid-template-columns: 1fr 1fr;
  }
}
@media (min-width: 1000px) {
  .service-grid {
    grid-template-columns: repeat(3, 1fr);
  }
}
.service-grid a {
  display: block;
  background: var(--card);
  padding: var(--s-5);
  text-decoration: none;
  transition: background-color 0.15s ease;
}
.service-grid a:hover {
  background: var(--red-tint);
}
.service-grid h2,
.service-grid h3 {
  font-size: var(--t-1);
  font-weight: 700;
  margin-bottom: var(--s-2);
}
.service-grid p {
  font-size: 0.9375rem;
  line-height: 1.55;
  color: var(--ink-soft);
}
.service-grid .arrow-link {
  margin-top: var(--s-3);
  font-size: 0.9375rem;
}

/* Project category bar. Sticks under the site header so the categories stay
   reachable from anywhere on a very long page. Scrolls horizontally on a
   phone rather than wrapping into a wall of buttons. */
.jumpbar {
  position: sticky;
  top: var(--header-h);
  z-index: 40;
  background: color-mix(in srgb, var(--ground) 94%, transparent);
  backdrop-filter: saturate(1.4) blur(10px);
  border-block: 1px solid var(--rule);
}
.jumpbar__inner {
  display: flex;
  align-items: center;
  gap: var(--s-4);
}
.jumpbar__label {
  flex: none;
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--ink-faint);
}
.jumpbar ul {
  display: flex;
  gap: var(--s-2);
  list-style: none;
  margin: 0;
  padding: var(--s-3) 0;
  overflow-x: auto;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
  /* Fade both ends so a half-scrolled button reads as "there is more this
     way" rather than as a clipped, broken label. */
  -webkit-mask-image: linear-gradient(
    to right,
    transparent 0,
    #000 14px,
    #000 calc(100% - 14px),
    transparent 100%
  );
  mask-image: linear-gradient(
    to right,
    transparent 0,
    #000 14px,
    #000 calc(100% - 14px),
    transparent 100%
  );
}
.jumpbar ul::-webkit-scrollbar {
  display: none;
}
.jumpbar li {
  flex: none;
}
.jumpbar a {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  min-height: 40px;
  padding: var(--s-2) var(--s-4);
  border: 1px solid var(--rule-strong);
  border-radius: 999px;
  background: var(--card);
  font-size: 0.875rem;
  font-weight: 600;
  white-space: nowrap;
  text-decoration: none;
  transition: background-color 0.15s ease, border-color 0.15s ease,
    color 0.15s ease;
}
.jumpbar a:hover {
  background: var(--red);
  border-color: var(--red);
  color: #fff;
}
.jumpbar a span {
  font-size: 0.75rem;
  font-weight: 500;
  color: var(--ink-faint);
  font-variant-numeric: tabular-nums;
}
.jumpbar a:hover span {
  color: rgba(255, 255, 255, 0.8);
}
@media (max-width: 600px) {
  .jumpbar__label {
    display: none;
  }
}

/*
 * Above phone width the categories WRAP instead of scrolling sideways.
 *
 * A horizontal scroller is fine on a touchscreen, where you flick it, and
 * useless with a mouse: there is no drag gesture, and the scrollbar was
 * hidden. On anything with room for two rows the buttons simply all show at
 * once, which is what a pointer user needs. Sideways scrolling survives only
 * on narrow screens, where wrapping ten categories would push the page
 * content off the bottom of the screen.
 */
@media (min-width: 700px) {
  .jumpbar__inner {
    align-items: flex-start;
  }
  .jumpbar__label {
    padding-top: calc(var(--s-3) + 10px);
  }
  .jumpbar ul {
    flex-wrap: wrap;
    overflow-x: visible;
    -webkit-mask-image: none;
    mask-image: none;
  }
}

/* Offset the jump target by the header plus the category bar, so a heading
   never lands underneath the pinned chrome. The bar is one row on a phone and
   two or three where it wraps, so its height is measured at runtime and
   published as --jumpbar-h; the fallback here is a safe over-estimate for the
   wrapped case, which costs a little extra space and never hides anything. */
.project-group h2 {
  scroll-margin-top: calc(var(--header-h) + var(--jumpbar-h, 170px) + 12px);
}

/* 9. PROJECT PAGES AND GALLERIES =========================================== */

.card-grid {
  display: grid;
  gap: var(--s-5);
}
@media (min-width: 620px) {
  .card-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}
@media (min-width: 1000px) {
  .card-grid--3 {
    grid-template-columns: repeat(3, 1fr);
  }
}

.card {
  display: flex;
  flex-direction: column;
  background: var(--card);
  border: 1px solid var(--rule);
  border-radius: var(--radius-sm);
  overflow: hidden;
  text-decoration: none;
  transition: border-color 0.18s ease, transform 0.18s ease;
}
.card:hover {
  border-color: var(--rule-strong);
  transform: translateY(-2px);
}
.card__media {
  overflow: hidden;
}
.card__media img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  transition: transform 0.3s ease;
}
.card:hover .card__media img {
  transform: scale(1.035);
}
.card__body {
  padding: var(--s-4) var(--s-4) var(--s-5);
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
  flex: 1;
}
.card__kicker {
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--red);
}
.card h3 {
  font-size: var(--t-1);
  font-weight: 700;
}
.card p {
  font-size: 0.9375rem;
  line-height: 1.55;
  color: var(--ink-soft);
}
.card__meta {
  margin-top: auto;
  padding-top: var(--s-2);
  font-size: 0.8125rem;
  color: var(--ink-faint);
}

/* Project gallery: one column of large figures, each with its own caption.
   Deliberately not a lightbox — the captions are the content. */
.gallery {
  display: grid;
  gap: var(--s-7);
}
.gallery figure {
  max-width: 900px;
}
.gallery img {
  width: 100%;
  border-radius: var(--radius-sm);
  border: 1px solid var(--rule);
}
.gallery figcaption {
  margin-top: var(--s-3);
  font-size: 0.9375rem;
  line-height: 1.6;
  color: var(--ink-soft);
  max-width: 62ch;
}

.project-meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2) var(--s-5);
  padding-block: var(--s-4);
  border-block: 1px solid var(--rule);
  font-size: 0.9375rem;
  color: var(--ink-soft);
}
.project-meta strong {
  color: var(--ink);
  font-weight: 600;
}

.pager {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--s-4);
  padding-top: var(--s-6);
  border-top: 1px solid var(--rule);
}
.pager a {
  text-decoration: none;
  font-weight: 600;
  color: var(--red);
  max-width: 22ch;
}
.pager span {
  display: block;
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

/* 10. REVIEWS ============================================================== */

/* Reviews are held in build/data/reviews.json and rendered into the HTML, not
   fetched from Google. Nothing here may link to Google Maps: that lands a
   prospect on a map of competing contractors. The only outbound link is an
   invitation to leave a review. */
.reviews {
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  background: var(--card);
  padding: var(--s-5);
}
@media (min-width: 800px) {
  .reviews {
    padding: var(--s-6);
  }
}
.reviews__top {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-4);
}
.reviews__top:not(:only-child) {
  padding-bottom: var(--s-4);
  border-bottom: 1px solid var(--rule);
}
.reviews__score {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  flex-wrap: wrap;
}
.reviews__score b {
  font-family: var(--display);
  font-size: var(--t-4);
  font-weight: 800;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
.reviews__count {
  font-size: 0.9375rem;
  color: var(--ink-soft);
}
.reviews__leave {
  min-height: 44px;
  padding: var(--s-2) var(--s-4);
  font-size: 0.9375rem;
}
.reviews__empty {
  color: var(--ink-soft);
}
.stars {
  display: inline-flex;
  gap: 2px;
  color: var(--red);
}
.stars svg {
  width: 1em;
  height: 1em;
  fill: currentColor;
}
.stars--muted {
  color: var(--rule-strong);
}

.review-list {
  display: grid;
  gap: var(--s-4);
  margin-top: var(--s-5);
}
.review {
  border: 1px solid var(--rule);
  border-radius: var(--radius-sm);
  padding: var(--s-4);
  background: var(--ground);
}
.review[hidden] {
  display: none;
}
/* One at a time on the home page. A fixed minimum height stops the section
   jumping as the rotator moves between a short review and a long one. */
.review-list--rotating {
  min-height: 11rem;
}
.review__who {
  margin-bottom: var(--s-3);
}
.review__name {
  display: block;
  font-weight: 600;
  font-size: 0.9375rem;
}
.review__when {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  margin-top: var(--s-1);
  font-size: 0.8125rem;
  color: var(--ink-faint);
}
.review__text {
  font-size: 0.9375rem;
  line-height: 1.6;
  color: var(--ink-soft);
}
.review__job {
  margin-top: var(--s-2);
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--red);
}

.review-dots {
  display: flex;
  gap: var(--s-2);
  margin-top: var(--s-4);
}
.review-dots button {
  width: 28px;
  height: 28px;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  display: grid;
  place-items: center;
}
.review-dots button::before {
  content: '';
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--rule-strong);
  transition: background-color 0.15s ease, width 0.15s ease;
}
.review-dots button[aria-current]::before {
  background: var(--red);
  width: 22px;
  border-radius: 4px;
}
.reviews__more {
  margin-top: var(--s-3);
  font-size: 0.9375rem;
}
.reviews__more a {
  font-weight: 600;
  color: var(--red);
}

/* 11. FOOTER =============================================================== */

.site-footer {
  background: var(--dark);
  color: var(--on-dark);
  padding-block: var(--s-8) var(--s-6);
  margin-top: var(--s-9);
}
.site-footer a {
  color: var(--on-dark-soft);
  text-decoration: none;
}
.site-footer a:hover {
  color: #fff;
  text-decoration: underline;
}
.site-footer__grid {
  display: grid;
  gap: var(--s-6);
}
@media (min-width: 700px) {
  .site-footer__grid {
    grid-template-columns: 1.4fr 1fr 1fr;
  }
}
@media (min-width: 1000px) {
  .site-footer__grid {
    grid-template-columns: 1.6fr 1fr 1fr 1.2fr;
  }
}
.site-footer h2 {
  font-size: 0.8125rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: #fff;
  margin-bottom: var(--s-4);
  padding-bottom: var(--s-2);
  border-bottom: 1px solid rgba(255, 255, 255, 0.14);
}
.site-footer ul {
  list-style: none;
  padding: 0;
  display: grid;
  gap: var(--s-3);
  font-size: 0.9375rem;
}
.site-footer p {
  font-size: 0.9375rem;
  color: var(--on-dark-soft);
}
.site-footer__brand strong {
  display: block;
  font-family: var(--display);
  font-size: var(--t-1);
  color: #fff;
  margin-bottom: var(--s-3);
}
.site-footer__badge {
  margin-top: var(--s-4);
  padding: var(--s-4);
  background: var(--dark-soft);
  border-radius: var(--radius-sm);
  font-size: 0.875rem;
}
.site-footer__badge b {
  color: #fff;
}
.site-footer__social {
  display: flex;
  gap: var(--s-3);
  margin-top: var(--s-4);
}
.site-footer__social a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: var(--radius-sm);
  background: rgba(255, 255, 255, 0.08);
}
.site-footer__social a:hover {
  background: var(--red);
  color: #fff;
}
.site-footer__social svg {
  width: 20px;
  height: 20px;
  fill: currentColor;
}
.site-footer__bar {
  margin-top: var(--s-7);
  padding-top: var(--s-5);
  border-top: 1px solid rgba(255, 255, 255, 0.14);
  font-size: 0.8125rem;
  color: var(--on-dark-soft);
  display: grid;
  gap: var(--s-2);
}

/* 12. UTILITIES, MOTION, PRINT ============================================= */

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

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
}

@media print {
  .site-header,
  .site-footer,
  .nav-toggle,
  .actions,
  .proof {
    display: none !important;
  }
  body {
    background: #fff;
    font-size: 11pt;
  }
  a[href^='http']::after {
    content: ' (' attr(href) ')';
    font-size: 0.85em;
    color: #555;
  }
}
