/* ==========================================================================
   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. 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. */
  --header-h: 67px;
}
@media (max-width: 480px) {
  :root {
    --header-h: 63px;
  }
}
@media (min-width: 900px) {
  :root {
    --header-h: 73px;
  }
}

/* 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-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 quote button and the menu
   toggle side by side. At 360px the 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__actions .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;
  }
  .nav-toggle,
  .nav-drawer {
    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);
}

.checklist {
  list-style: none;
  padding: 0;
  display: grid;
  gap: var(--s-3);
}
@media (min-width: 700px) {
  .checklist {
    grid-template-columns: 1fr 1fr;
    column-gap: var(--s-6);
  }
}
.checklist li {
  position: relative;
  padding-left: 1.6em;
  line-height: 1.55;
}
.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);
}

.faq {
  display: grid;
  gap: 0;
}
.faq > div {
  padding-block: var(--s-5);
  border-top: 1px solid var(--rule);
}
.faq h3 {
  font-size: var(--t-2);
  margin-bottom: var(--s-3);
}
.faq p {
  max-width: var(--measure);
  color: var(--ink-soft);
}

.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;
  }
}
