/* ==========================================================================
   Franco Roofing Co. premium build
   Design system. This file is the FROZEN SEAM: every page consumes it,
   no page invents a token, a radius, a colour or a size of its own.
   ========================================================================== */

/* --- Fonts (self hosted, works offline) --------------------------------- */
@font-face {
  font-family: 'Fraunces';
  src: url('../assets/fonts/fraunces-latin.woff2') format('woff2-variations');
  font-weight: 300 900;
  font-stretch: 100%;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Archivo';
  src: url('../assets/fonts/archivo-latin.woff2') format('woff2-variations');
  font-weight: 100 900;
  font-stretch: 62% 125%;
  font-style: normal;
  font-display: swap;
}

/* --- Tokens -------------------------------------------------------------- */
:root {
  /* colour: 60 paper / 30 ink+slate / 10 clay. Clay is sampled from the
     terracotta tile in Franco's own project photos. */
  --paper:      #F4F1EC;
  --paper-2:    #EBE6DE;
  --paper-3:    #FFFFFF;
  --ink:        #14181B;
  --ink-2:      #1C2226;
  --ink-3:      #2A3238;
  --slate:      #5C6266;
  --slate-2:    #6B7175;
  --clay:       #A8481F;
  --clay-deep:  #8C3A16;
  /* the same clay lifted for dark surfaces, where #A8481F only reaches 3.1:1 */
  --clay-onink: #CE7040;
  --clay-soft:  rgba(168, 72, 31, .10);
  --line:       rgba(20, 24, 27, .13);
  --line-soft:  rgba(20, 24, 27, .07);
  --line-dark:  rgba(244, 241, 236, .15);

  /* type */
  --f-display: 'Fraunces', 'Iowan Old Style', Georgia, serif;
  --f-sans: 'Archivo', ui-sans-serif, system-ui, 'Segoe UI', sans-serif;
  --t-eyebrow: .6875rem;
  --t-xs:      .8125rem;
  --t-sm:      .9375rem;
  --t-body:    1.0625rem;
  --t-lead:    clamp(1.125rem, .98rem + .6vw, 1.3125rem);
  --t-h4:      clamp(1.0625rem, 1rem + .25vw, 1.1875rem);
  --t-h3:      clamp(1.3125rem, 1.15rem + .7vw, 1.625rem);
  --t-h2:      clamp(1.9rem, 1.35rem + 2.3vw, 3rem);
  --t-h1:      clamp(2.55rem, 1.6rem + 4.1vw, 4.5rem);
  --t-stat:    clamp(2.4rem, 1.7rem + 3vw, 3.75rem);

  /* space */
  --s-1: 4px;  --s-2: 8px;  --s-3: 12px; --s-4: 16px; --s-5: 24px;
  --s-6: 32px; --s-7: 48px; --s-8: 64px; --s-9: 96px; --s-10: 128px;
  --pad-hero: clamp(84px, 10vw, 132px);
  --pad-lg:   clamp(76px, 8.5vw, 118px);
  --pad-md:   clamp(60px, 6.5vw, 90px);
  --pad-sm:   clamp(44px, 5vw, 64px);
  --gutter:   clamp(20px, 5vw, 40px);
  --maxw:     1180px;
  --measure:  68ch;

  /* shape */
  --r-lg: 20px; --r-md: 14px; --r-sm: 10px; --r-pill: 999px;
  --sh-1: 0 1px 2px rgba(20, 24, 27, .05);
  --sh-2: 0 2px 4px rgba(20, 24, 27, .04), 0 18px 40px -18px rgba(20, 24, 27, .24);
  --sh-3: 0 2px 6px rgba(20, 24, 27, .06), 0 32px 60px -24px rgba(20, 24, 27, .3);

  /* motion */
  --e-ui: cubic-bezier(.22, .61, .36, 1);
  --e-entrance: cubic-bezier(.32, .72, 0, 1);
  --d-ui: 240ms;
  --d-entrance: 760ms;
}

/* --- Reset --------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--f-sans);
  font-size: var(--t-body);
  line-height: 1.65;
  font-synthesis-weight: none;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: clip;
}

img, svg, video { display: block; max-width: 100%; }
img { height: auto; }
button, input, select, textarea { font: inherit; color: inherit; }
a { color: inherit; }

/* film grain: fixed layer only, never on a scrolling container */
body::after {
  content: '';
  position: fixed;
  inset: 0;
  z-index: 90;
  pointer-events: none;
  opacity: .05;
  mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.86' numOctaves='3'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
}

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

.skip-link {
  position: absolute;
  left: -9999px;
  top: 10px;
  z-index: 200;
  background: var(--ink);
  color: var(--paper);
  padding: 10px 18px;
  border-radius: var(--r-pill);
  font-size: var(--t-sm);
}
.skip-link:focus { left: 16px; }

/* --- Layout -------------------------------------------------------------- */
.wrap { width: 100%; max-width: var(--maxw); margin-inline: auto; padding-inline: var(--gutter); }
.section { padding-block: var(--pad-lg); }
.section--hero { padding-block: var(--pad-hero) var(--pad-lg); }
.section--tight { padding-block: var(--pad-md); }
.section--compact { padding-block: var(--pad-sm); }
.section--paper2 { background: var(--paper-2); }
.section--ink { background: var(--ink); color: var(--paper); }
.section--ink .lead, .section--ink p { color: rgba(244, 241, 236, .74); }
.section--ink .eyebrow { color: rgba(244, 241, 236, .62); }
.section--ink .step p { color: rgba(244, 241, 236, .74); }
.section--ink .dl dt { color: rgba(244, 241, 236, .68); }
.section--ink .tlink, .section--ink .step__n, .section--ink .card__num,
.section--ink .stars, .section--ink .clay { color: var(--clay-onink); }
.section--ink .faq__sign::before, .section--ink .faq__sign::after { background: var(--clay-onink); }

/* Light surfaces sitting inside an ink section keep light surface text.
   Without this the ink paragraph colour leaks into the white form card. */
.section--ink .formcard, .section--ink .card, .section--ink .review { color: var(--ink); }
.section--ink .formcard .lead, .section--ink .formcard p, .section--ink .card p { color: var(--slate); }
.section--ink .formcard .form__note { color: var(--slate); }
.section--ink .formcard .tlink { color: var(--clay); }
.section--ink .formcard .form__ok { color: var(--clay-deep); }

.grid { display: grid; gap: var(--s-6); }
.stack > * + * { margin-top: var(--s-4); }

/* --- Type ---------------------------------------------------------------- */
h1, h2, h3, h4 {
  font-family: var(--f-display);
  font-variation-settings: 'opsz' 96, 'SOFT' 0, 'WONK' 0;
  font-weight: 600;
  letter-spacing: -.015em;
  line-height: 1.06;
  margin: 0;
  text-wrap: balance;
}
h1 { font-size: var(--t-h1); font-variation-settings: 'opsz' 144, 'SOFT' 0, 'WONK' 0; }
h2 { font-size: var(--t-h2); }
h3 { font-size: var(--t-h3); line-height: 1.18; }
h4 { font-size: var(--t-h4); line-height: 1.3; font-weight: 600; }
/* these components sit under an h2, so their titles are h3 for a correct
   outline, but they keep the smaller h4 size visually. */
.tile h3, .step h3, .card__body h3, .review h3 { font-size: var(--t-h4); line-height: 1.3; }
p { margin: 0; max-width: var(--measure); }

.eyebrow {
  display: block;
  font-family: var(--f-sans);
  font-size: var(--t-eyebrow);
  font-weight: 600;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--slate);
  margin: 0 0 var(--s-4);
}
.eyebrow--clay { color: var(--clay); }

.lead { font-size: var(--t-lead); line-height: 1.6; color: var(--slate); }
.small { font-size: var(--t-sm); color: var(--slate); }
.xs { font-size: var(--t-xs); color: var(--slate-2); }
.serif-accent { font-family: var(--f-display); font-style: italic; font-variation-settings: 'opsz' 144, 'SOFT' 0, 'WONK' 1; }
.clay { color: var(--clay); }

/* section heading block */
.head { max-width: 720px; margin-bottom: var(--s-8); }
.head p { margin-top: var(--s-4); }
.head--center { margin-inline: auto; text-align: center; }
.head--center p { margin-inline: auto; }

/* the chalk line: our one repeating signature, a snapped line that draws in */
.rule {
  height: 1px;
  background: var(--clay);
  transform: scaleX(0);
  transform-origin: left center;
  margin-bottom: var(--s-5);
  width: 56px;
}
.rule--full { width: 100%; background: var(--line); }
.is-in .rule, .rule.is-in { transform: scaleX(1); transition: transform 900ms var(--e-entrance) 80ms; }

/* --- Buttons ------------------------------------------------------------- */
.btn {
  --btn-bg: var(--clay);
  --btn-fg: #FFF7F2;
  display: inline-flex;
  align-items: center;
  gap: var(--s-3);
  padding: 14px 16px 14px 26px;
  border: 0;
  border-radius: var(--r-pill);
  background: var(--btn-bg);
  color: var(--btn-fg);
  font-size: var(--t-sm);
  font-weight: 600;
  letter-spacing: .01em;
  text-decoration: none;
  cursor: pointer;
  transition: background var(--d-ui) var(--e-ui), transform var(--d-ui) var(--e-ui), box-shadow var(--d-ui) var(--e-ui);
  box-shadow: var(--sh-1);
}
.btn__ico {
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  border-radius: var(--r-pill);
  background: rgba(255, 255, 255, .16);
  transition: transform var(--d-ui) var(--e-ui), background var(--d-ui) var(--e-ui);
}
.btn__ico svg { width: 13px; height: 13px; }
.btn:hover { background: var(--clay-deep); box-shadow: var(--sh-2); }
.btn:hover .btn__ico { transform: translate(3px, -1px) scale(1.06); background: rgba(255, 255, 255, .26); }
.btn:active { transform: scale(.985); }

.btn--ghost {
  --btn-bg: transparent;
  --btn-fg: var(--ink);
  box-shadow: inset 0 0 0 1px var(--line);
  padding-left: 24px;
}
.btn--ghost .btn__ico { background: var(--clay-soft); color: var(--clay); }
.btn--ghost:hover { background: rgba(20, 24, 27, .04); box-shadow: inset 0 0 0 1px rgba(20, 24, 27, .22); }

.btn--onink {
  --btn-bg: transparent;
  --btn-fg: var(--paper);
  box-shadow: inset 0 0 0 1px var(--line-dark);
}
.btn--onink .btn__ico { background: rgba(244, 241, 236, .14); }
.btn--onink:hover { background: rgba(244, 241, 236, .08); box-shadow: inset 0 0 0 1px rgba(244, 241, 236, .34); }

.btn--lg { padding: 17px 18px 17px 30px; font-size: 1rem; }
.btn--block { width: 100%; justify-content: center; }

/* text link with a drawn underline */
.tlink {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-weight: 600;
  font-size: var(--t-sm);
  color: var(--clay);
  text-decoration: none;
  position: relative;
}
.tlink::after {
  content: '';
  position: absolute;
  left: 0; right: 0; bottom: -3px;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform var(--d-ui) var(--e-ui);
}
.tlink:hover::after { transform: scaleX(1); }

/* --- Nav ----------------------------------------------------------------- */
.nav {
  position: fixed;
  inset: 0 0 auto;
  z-index: 100;
  transition: background var(--d-ui) var(--e-ui), box-shadow var(--d-ui) var(--e-ui);
}
.nav::before {
  content: '';
  position: absolute;
  inset: 0;
  background: rgba(244, 241, 236, .86);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  opacity: 0;
  transition: opacity var(--d-ui) var(--e-ui);
  border-bottom: 1px solid transparent;
}
.nav.is-stuck::before { opacity: 1; border-bottom-color: var(--line-soft); }
/* Over the full bleed hero the header sits on a dark photograph, so it has to
   invert until the page scrolls and the paper background comes in behind it. */
.nav--onhero:not(.is-stuck) .brand__name,
.nav--onhero:not(.is-stuck) .nav__link,
.nav--onhero:not(.is-stuck) .nav__phone { color: var(--paper); }
.nav--onhero:not(.is-stuck) .brand__sub { color: rgba(244, 241, 236, .62); }
.nav--onhero:not(.is-stuck) .nav__phone svg { color: var(--clay-onink); }
.nav--onhero:not(.is-stuck) .nav__link::after { background: var(--clay-onink); }
.nav--onhero:not(.is-stuck) .burger span { background: var(--paper); }
.nav--onhero:not(.is-stuck) .brand__mark rect { fill: rgba(244, 241, 236, .16); }
.nav__inner {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-5);
  height: 78px;
  transition: height var(--d-ui) var(--e-ui);
}
.nav.is-stuck .nav__inner { height: 66px; }

.brand { display: inline-flex; align-items: center; gap: 11px; text-decoration: none; }
.brand__mark { width: 34px; height: 34px; flex: none; }
.brand__txt { display: grid; line-height: 1; }
.brand__name {
  font-family: var(--f-display);
  font-variation-settings: 'opsz' 144, 'SOFT' 0, 'WONK' 0;
  font-weight: 600;
  font-size: 1.135rem;
  letter-spacing: -.005em;
}
.brand__sub {
  font-size: .5625rem;
  font-weight: 600;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--slate);
  margin-top: 4px;
}

.nav__links { display: flex; align-items: center; gap: var(--s-6); }
.nav__link {
  position: relative;
  font-size: var(--t-sm);
  font-weight: 500;
  text-decoration: none;
  color: var(--ink);
  padding-block: 4px;
}
.nav__link::after {
  content: '';
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 1px;
  background: var(--clay);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform var(--d-ui) var(--e-ui);
}
.nav__link:hover::after, .nav__link[aria-current='page']::after { transform: scaleX(1); }
.nav__link[aria-current='page'] { color: var(--clay); }

.nav__cta { display: flex; align-items: center; gap: var(--s-4); }
.nav__phone {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: var(--t-sm);
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
}
.nav__phone svg { width: 15px; height: 15px; color: var(--clay); }

/* hamburger that morphs to an X */
.burger {
  display: none;
  width: 44px; height: 44px;
  border: 0;
  background: transparent;
  border-radius: var(--r-pill);
  position: relative;
  cursor: pointer;
}
.burger span {
  position: absolute;
  left: 12px;
  width: 20px;
  height: 1.5px;
  background: var(--ink);
  border-radius: 2px;
  transition: transform 320ms var(--e-entrance), opacity 160ms linear;
}
.burger span:nth-child(1) { top: 17px; }
.burger span:nth-child(2) { top: 22px; }
.burger span:nth-child(3) { top: 27px; }
.burger[aria-expanded='true'] span:nth-child(1) { transform: translateY(5px) rotate(45deg); }
.burger[aria-expanded='true'] span:nth-child(2) { opacity: 0; }
.burger[aria-expanded='true'] span:nth-child(3) { transform: translateY(-5px) rotate(-45deg); }

.menu {
  position: fixed;
  inset: 0;
  z-index: 99;
  background: rgba(20, 24, 27, .96);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  display: grid;
  align-content: center;
  padding: 96px var(--gutter) var(--s-9);
  opacity: 0;
  visibility: hidden;
  transition: opacity 360ms var(--e-ui), visibility 360ms;
}
.menu.is-open { opacity: 1; visibility: visible; }
.menu a { color: var(--paper); text-decoration: none; }
.menu__list { display: grid; gap: var(--s-2); margin: 0 0 var(--s-7); padding: 0; list-style: none; }
.menu__list a {
  font-family: var(--f-display);
  font-variation-settings: 'opsz' 144, 'SOFT' 0, 'WONK' 0;
  font-weight: 500;
  font-size: clamp(2rem, 9vw, 2.75rem);
  line-height: 1.24;
  display: block;
  opacity: 0;
  transform: translateY(26px);
}
.menu.is-open .menu__list a {
  opacity: 1;
  transform: none;
  transition: opacity 460ms var(--e-entrance) calc(var(--i, 0) * 55ms + 90ms),
              transform 620ms var(--e-entrance) calc(var(--i, 0) * 55ms + 90ms);
}
.menu__foot { display: grid; gap: var(--s-4); border-top: 1px solid var(--line-dark); padding-top: var(--s-6); }
.menu__foot .btn { justify-self: start; }
.menu__phone { font-family: var(--f-display); font-size: 1.5rem; font-weight: 600; }

@media (max-width: 940px) {
  .nav__links, .nav__cta .btn, .nav__cta .nav__phone span { display: none; }
  .burger { display: block; }
  .nav__cta { gap: var(--s-2); }
  /* the phone collapses to its icon here, so it needs a real tap target.
     Calling is the single most valuable action on a roofing site. */
  .nav__phone {
    min-width: 44px;
    min-height: 44px;
    justify-content: center;
    border-radius: var(--r-pill);
  }
  .nav__phone svg { width: 19px; height: 19px; }
}

/* --- Hero: pinned full bleed scroll stage ---------------------------------
   The section is a tall runway. Inside it a sticky stage holds the viewport
   for its whole length, so the hero sits still while the roof rebuilds and
   the camera pulls back. Only then does the page move on.
   `--p` runs 0 to 1 across the runway and is set by js/site.js. */
.heroPin {
  position: relative;
  height: 250vh;
  background: var(--ink);
}
.heroPin__stage {
  position: sticky;
  top: 0;
  height: 100svh;
  min-height: 520px;
  overflow: hidden;
  display: flex;
  align-items: flex-end;
  isolation: isolate;
}
.heroPin__media {
  position: absolute;
  inset: 0;
  z-index: 0;
  /* the pull back: starts pushed in, settles to full frame */
  transform: scale(calc(1.3 - var(--p, 0) * .3));
  transform-origin: 58% 42%;
  will-change: transform;
}
.heroPin__media video, .heroPin__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
/* scrim: the headline sits on top of a bright golden roof and needs ground */
.heroPin__scrim {
  position: absolute;
  inset: 0;
  z-index: 1;
  background:
    linear-gradient(to top, rgba(12, 15, 17, .84) 0%, rgba(12, 15, 17, .6) 26%, rgba(12, 15, 17, .1) 58%, rgba(12, 15, 17, .3) 100%);
  /* the scrim exists for the opening text. Once the text leaves, the film
     plays clean. Gone by roughly a third of the runway. */
  opacity: calc(1 - var(--p, 0) * 2.6);
  will-change: opacity;
}
.heroPin__inner {
  position: relative;
  z-index: 2;
  width: 100%;
  padding-bottom: clamp(64px, 9vh, 118px);
  padding-top: 96px;
  /* the copy belongs to the opening frame. Scroll hands the stage to the
     roof: faded out by a third of the runway, drifting up as it goes. */
  opacity: calc(1 - var(--p, 0) * 3.2);
  transform: translateY(calc(var(--p, 0) * -44px));
  will-change: opacity, transform;
}
.heroPin.is-cine .heroPin__inner, .heroPin.is-cine .heroPin__proof { pointer-events: none; }
.heroPin__inner .eyebrow { color: rgba(244, 241, 236, .72); }
.heroPin h1 { color: var(--paper); max-width: 15ch; }
.heroPin__sub {
  color: rgba(244, 241, 236, .84);
  font-size: var(--t-lead);
  line-height: 1.55;
  max-width: 46ch;
  margin-top: var(--s-5);
  text-shadow: 0 1px 24px rgba(12, 15, 17, .5);
}
.heroPin__actions { display: flex; flex-wrap: wrap; gap: var(--s-4); margin-top: var(--s-7); align-items: center; }
.heroPin__note {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  margin-top: var(--s-6);
  font-size: var(--t-sm);
  color: rgba(244, 241, 236, .8);
  max-width: 52ch;
}
.heroPin__note svg { width: 16px; height: 16px; color: var(--clay-onink); flex: none; margin-top: 4px; }

/* proof card, light on the dark stage */
.heroPin__proof {
  position: absolute;
  right: var(--gutter);
  bottom: clamp(64px, 9vh, 118px);
  z-index: 2;
  opacity: calc(1 - var(--p, 0) * 3.2);
  transform: translateY(calc(var(--p, 0) * -28px));
  will-change: opacity, transform;
  display: grid;
  gap: 3px;
  padding: 14px 20px;
  border-radius: var(--r-md);
  background: rgba(244, 241, 236, .95);
  box-shadow: var(--sh-2);
}
.heroPin__proof .n { font-family: var(--f-display); font-variation-settings: 'opsz' 144; font-size: 1.4rem; font-weight: 600; line-height: 1; }
.heroPin__proof .l { font-size: var(--t-xs); color: var(--slate); }

/* scrub affordance */
.heroPin__hint {
  position: absolute;
  left: 50%;
  bottom: 18px;
  z-index: 3;
  transform: translateX(-50%);
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: var(--t-xs);
  font-weight: 600;
  letter-spacing: .04em;
  color: rgba(244, 241, 236, .82);
  transition: opacity var(--d-ui) var(--e-ui);
}
.heroPin__hint svg { width: 13px; height: 13px; animation: hintNudge 1.9s var(--e-ui) infinite; }
@keyframes hintNudge { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(3px); } }
.heroPin.is-done .heroPin__hint { opacity: 0; }
.heroPin__bar {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  z-index: 3;
  height: 3px;
  background: rgba(244, 241, 236, .18);
}
.heroPin__bar i {
  position: absolute;
  inset: 0;
  transform-origin: left center;
  transform: scaleX(var(--p, 0));
  background: var(--clay-onink);
}
.heroPin.is-looping .heroPin__hint, .heroPin.is-looping .heroPin__bar { display: none; }

@media (max-width: 880px) {
  .heroPin { height: 220vh; }
  .heroPin__hint { white-space: nowrap; font-size: .75rem; bottom: 14px; }
}

/* Short viewports (embedded panes, landscape phones): the top anchored proof
   card and the bottom anchored copy meet in the middle. The rating is
   restated in the reviews section, so the card yields. */
@media (max-width: 880px) and (max-height: 719px) {
  .heroPin__proof { display: none; }
  .heroPin__inner { padding-bottom: clamp(40px, 6vh, 64px); }
  .heroPin h1 { font-size: clamp(2rem, 6.5vh, 3.4rem); }
  .heroPin__sub { font-size: 1rem; margin-top: var(--s-4); }
  .heroPin__note { margin-top: var(--s-4); }
  .heroPin__proof { right: auto; left: var(--gutter); bottom: auto; top: 92px; padding: 10px 14px; }
  .heroPin__proof .n { font-size: 1.0625rem; }
  .heroPin h1 { max-width: 13ch; }
  .heroPin__actions .btn { flex: 1 1 100%; justify-content: center; }
}

/* The same collision arriving by WIDTH instead of height. At phone width the
   note under the buttons wraps to three lines and lands exactly where the
   bottom anchored proof card sits, so on a tall modern phone the card printed
   straight over the guarantee line. The rule above only caught short
   viewports. The card yields here for the same reason: the rating is restated
   in the reviews section. */
@media (max-width: 760px) {
  .heroPin__proof { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  /* no runway, no pin, no scrub: one still frame of the finished roof,
     with the copy held on screen since there is no film to hand over to */
  .heroPin { height: auto; }
  .heroPin__stage { position: relative; height: auto; min-height: 0; }
  .heroPin__media { position: absolute; transform: none; }
  .heroPin__inner { padding-top: 168px; opacity: 1; transform: none; }
  .heroPin__proof { opacity: 1; transform: none; }
  .heroPin__scrim { opacity: 1; }
  .heroPin__hint, .heroPin__bar { display: none; }
}

/* --- Figures and reveals ------------------------------------------------- */
.figure {
  position: relative;
  overflow: hidden;
  border-radius: var(--r-md);
  background: var(--paper-2);
  margin: 0;
}
.figure img { width: 100%; height: 100%; object-fit: cover; }
.figure--reveal img { clip-path: inset(0 0 100% 0); transform: scale(1.06); }
.figure--reveal img.is-in {
  clip-path: inset(0 0 0 0);
  transform: scale(1);
  transition: clip-path 1050ms var(--e-entrance), transform 1400ms var(--e-entrance);
}
.figure figcaption {
  font-size: var(--t-xs);
  color: var(--slate-2);
  margin-top: var(--s-3);
}

.reveal { opacity: 0; transform: translateY(20px); }
.reveal.is-in {
  opacity: 1;
  transform: none;
  transition: opacity 680ms var(--e-entrance) calc(var(--i, 0) * 70ms),
              transform var(--d-entrance) var(--e-entrance) calc(var(--i, 0) * 70ms);
}

/* --- Trust strip --------------------------------------------------------- */
.trust {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 1px;
  background: var(--line-soft);
  border-block: 1px solid var(--line-soft);
}
.trust__item { background: var(--paper); padding: var(--s-6) var(--s-5); text-align: center; }
.trust__n {
  font-family: var(--f-display);
  font-variation-settings: 'opsz' 144, 'SOFT' 0, 'WONK' 0;
  font-size: var(--t-stat);
  font-weight: 600;
  line-height: 1;
  letter-spacing: -.02em;
}
.trust__l { font-size: var(--t-xs); color: var(--slate); margin-top: var(--s-3); letter-spacing: .02em; }
@media (max-width: 720px) { .trust { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

/* --- Cards --------------------------------------------------------------- */
.cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(276px, 1fr)); gap: var(--s-5); }
.card {
  position: relative;
  display: flex;
  flex-direction: column;
  text-decoration: none;
  color: inherit;
  background: var(--paper-3);
  border-radius: var(--r-lg);
  box-shadow: inset 0 0 0 1px var(--line-soft), var(--sh-1);
  overflow: hidden;
  transition: transform var(--d-ui) var(--e-ui), box-shadow var(--d-ui) var(--e-ui);
}
.card--link:hover { transform: translateY(-3px); box-shadow: inset 0 0 0 1px var(--line-soft), var(--sh-2); }
.card__media { position: relative; overflow: hidden; aspect-ratio: 4 / 3; background: var(--paper-2); }
.card__media img { width: 100%; height: 100%; object-fit: cover; transition: transform 900ms var(--e-entrance); }
.card--link:hover .card__media img { transform: scale(1.035); }
.card__body { padding: var(--s-5) var(--s-5) var(--s-6); display: grid; gap: var(--s-3); }
.card__body p { font-size: var(--t-sm); color: var(--slate); }
/* Numerals use the sans face on purpose: Fraunces draws a flat topped 3 that
   reads as a 5 at small sizes. Display face stays on the large stat numbers. */
.card__num {
  font-family: var(--f-sans);
  font-size: var(--t-xs);
  font-weight: 700;
  color: var(--clay);
  letter-spacing: .14em;
  font-variant-numeric: tabular-nums;
}
.card__foot { margin-top: auto; padding: 0 var(--s-5) var(--s-5); }

/* quiet card, no photo */
a.tile { text-decoration: none; color: inherit; }
.tile {
  background: var(--paper-3);
  border-radius: var(--r-lg);
  padding: var(--s-6);
  display: grid;
  gap: var(--s-3);
  box-shadow: inset 0 0 0 1px var(--line-soft), var(--sh-1);
}
.tile__ico { width: 26px; height: 26px; color: var(--clay); margin-bottom: var(--s-2); }
.tile p { font-size: var(--t-sm); color: var(--slate); }
.section--ink .tile {
  background: var(--ink-2);
  box-shadow: inset 0 0 0 1px var(--line-dark);
}
.section--ink .tile p { color: rgba(244, 241, 236, .7); }

/* --- Process steps ------------------------------------------------------- */
.steps { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: var(--s-6); }
.step { display: grid; gap: var(--s-3); align-content: start; }
.step__n {
  font-family: var(--f-sans);
  font-size: var(--t-xs);
  font-weight: 700;
  letter-spacing: .14em;
  font-variant-numeric: tabular-nums;
  color: var(--clay);
  padding-top: var(--s-4);
  border-top: 1px solid var(--line);
}
.section--ink .step__n { border-top-color: var(--line-dark); }
.step p { font-size: var(--t-sm); color: var(--slate); }

/* --- Reviews ------------------------------------------------------------- */
.reviews { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: var(--s-5); }
.review {
  background: var(--paper-3);
  border-radius: var(--r-lg);
  padding: var(--s-6);
  display: grid;
  gap: var(--s-4);
  align-content: start;
  box-shadow: inset 0 0 0 1px var(--line-soft), var(--sh-1);
}
.stars { display: inline-flex; gap: 3px; color: var(--clay); }
.stars svg { width: 14px; height: 14px; }
.review blockquote {
  margin: 0;
  font-size: var(--t-sm);
  line-height: 1.7;
  color: var(--ink-3);
}
.review__who { display: flex; align-items: center; gap: var(--s-3); margin-top: var(--s-2); }
.review__avatar {
  width: 36px; height: 36px;
  border-radius: var(--r-pill);
  background: var(--clay-soft);
  color: var(--clay);
  display: grid;
  place-items: center;
  font-weight: 700;
  font-size: var(--t-sm);
  flex: none;
}
.review__name { font-size: var(--t-sm); font-weight: 600; }
.review__src { font-size: var(--t-xs); color: var(--slate-2); }
.review__more {
  background: none;
  border: 0;
  padding: 0;
  color: var(--clay);
  font-size: var(--t-xs);
  font-weight: 600;
  cursor: pointer;
  justify-self: start;
}
.review__text.is-clamped {
  display: -webkit-box;
  -webkit-line-clamp: 6;
  line-clamp: 6;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.ratingbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-4);
  padding: var(--s-5) var(--s-6);
  background: var(--paper-3);
  border-radius: var(--r-lg);
  box-shadow: inset 0 0 0 1px var(--line-soft);
  margin-bottom: var(--s-7);
}
.ratingbar__score { font-family: var(--f-display); font-size: 1.75rem; font-weight: 600; line-height: 1; }

/* --- Chips (service area) ------------------------------------------------ */
.chips { display: flex; flex-wrap: wrap; gap: var(--s-2); list-style: none; padding: 0; margin: 0; }
.chips li {
  font-size: var(--t-sm);
  padding: 7px 15px;
  border-radius: var(--r-pill);
  background: var(--paper-3);
  box-shadow: inset 0 0 0 1px var(--line-soft);
  color: var(--slate);
}
.section--ink .chips li { background: var(--ink-2); box-shadow: inset 0 0 0 1px var(--line-dark); color: rgba(244, 241, 236, .78); }

/* --- Split band (image + text) ------------------------------------------- */
.split {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: clamp(32px, 5vw, 64px);
  align-items: center;
}
.split--wide { grid-template-columns: minmax(0, 1.1fr) minmax(0, .9fr); }
@media (max-width: 860px) { .split--wide { grid-template-columns: 1fr; } }
/* Figure lead: the photograph carries the section, so it must come first once the
   split stacks. .split drops to one column below 753px, where 2x320 plus the fluid
   gap no longer fits the content width. Measured, not guessed. */
@media (max-width: 752px) { .split--figlead > figure { order: -1; } }

/* --- FAQ ----------------------------------------------------------------- */
.faq { border-top: 1px solid var(--line); max-width: 860px; }
.faq__item { border-bottom: 1px solid var(--line); }
.faq__q {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-5);
  background: none;
  border: 0;
  padding: var(--s-5) 0;
  text-align: left;
  cursor: pointer;
  font-family: var(--f-display);
  font-variation-settings: 'opsz' 96, 'SOFT' 0, 'WONK' 0;
  font-size: var(--t-h4);
  font-weight: 600;
  line-height: 1.35;
}
.faq__sign { position: relative; width: 16px; height: 16px; flex: none; }
.faq__sign::before, .faq__sign::after {
  content: '';
  position: absolute;
  background: var(--clay);
  transition: transform var(--d-ui) var(--e-ui);
}
.faq__sign::before { inset: 7.5px 0 auto; height: 1.5px; }
.faq__sign::after { inset: 0 7.5px auto; width: 1.5px; height: 16px; }
.faq__q[aria-expanded='true'] .faq__sign::after { transform: scaleY(0); }
.faq__a { overflow: hidden; height: 0; }
.faq__a > div { padding-bottom: var(--s-5); }
.faq__a p { font-size: var(--t-sm); color: var(--slate); max-width: 62ch; }

/* --- Form ---------------------------------------------------------------- */
.formcard {
  background: var(--paper-3);
  border-radius: var(--r-lg);
  padding: clamp(24px, 3.4vw, 40px);
  box-shadow: inset 0 0 0 1px var(--line-soft), var(--sh-2);
}
.form { display: grid; gap: var(--s-5); }
.form__row { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: var(--s-5); }
.field { display: grid; gap: 7px; }
.field label { font-size: var(--t-xs); font-weight: 600; letter-spacing: .06em; text-transform: uppercase; color: var(--slate); }
.field input, .field select, .field textarea {
  width: 100%;
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--line);
  border-radius: 0;
  padding: 10px 2px;
  font-size: var(--t-body);
  transition: border-color var(--d-ui) var(--e-ui);
  appearance: none;
}
.field select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8' fill='none' stroke='%235C6266' stroke-width='1.4'%3E%3Cpath d='M1 1.5 6 6.5l5-5'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 4px center;
  background-size: 12px;
  padding-right: 26px;
}
.field textarea { min-height: 116px; resize: vertical; }
.field input:focus, .field select:focus, .field textarea:focus {
  outline: none;
  border-bottom-color: var(--clay);
}
.field input:focus-visible, .field select:focus-visible, .field textarea:focus-visible { outline: none; }
.field.is-invalid input, .field.is-invalid select, .field.is-invalid textarea { border-bottom-color: #B3261E; }
.field__err { font-size: var(--t-xs); color: #B3261E; display: none; text-transform: none; letter-spacing: 0; }
.field.is-invalid .field__err { display: block; }
.form__note { font-size: var(--t-xs); color: var(--slate-2); }
.form__ok {
  display: none;
  gap: var(--s-3);
  align-items: flex-start;
  padding: var(--s-5);
  border-radius: var(--r-md);
  background: var(--clay-soft);
  color: var(--clay-deep);
  font-size: var(--t-sm);
}
.form__ok svg { width: 18px; height: 18px; flex: none; margin-top: 2px; }
.form.is-sent .form__ok { display: flex; }
.form.is-sent .form__body { display: none; }
/* honeypot: real visitors never see it, bots fill it and the worker drops them */
.hp { position: absolute !important; left: -9999px; top: auto; width: 1px; height: 1px; overflow: hidden; }
.btn.is-busy { opacity: .55; pointer-events: none; }
.form__fail { font-size: var(--t-xs); color: #B3261E; }
.form__fail[hidden] { display: none; }

/* contact detail list */
.dl { display: grid; gap: var(--s-5); margin: 0; }
.dl div { display: grid; gap: 3px; }
.dl dt { font-size: var(--t-xs); font-weight: 600; letter-spacing: .08em; text-transform: uppercase; color: var(--slate-2); }
.dl dd { margin: 0; font-size: var(--t-body); }
.dl a { text-decoration: none; }
.dl a:hover { color: var(--clay); }

/* --- Gallery ------------------------------------------------------------- */
.gal { columns: 3; column-gap: var(--s-5); }
@media (max-width: 900px) { .gal { columns: 2; } }
@media (max-width: 560px) { .gal { columns: 1; } }
.gal__item {
  break-inside: avoid;
  margin: 0 0 var(--s-5);
  padding: 0;
  border: 0;
  background: none;
  display: block;
  width: 100%;
  cursor: zoom-in;
  border-radius: var(--r-md);
  overflow: hidden;
  position: relative;
}
.gal__item img { width: 100%; transition: transform 900ms var(--e-entrance), filter var(--d-ui) var(--e-ui); }
.gal__item:hover img { transform: scale(1.03); }
.gal__cap {
  position: absolute;
  inset: auto 0 0;
  padding: 28px 16px 14px;
  background: linear-gradient(to top, rgba(20, 24, 27, .78), transparent);
  color: #fff;
  font-size: var(--t-xs);
  text-align: left;
  opacity: 0;
  transform: translateY(6px);
  transition: opacity var(--d-ui) var(--e-ui), transform var(--d-ui) var(--e-ui);
}
.gal__item:hover .gal__cap, .gal__item:focus-visible .gal__cap { opacity: 1; transform: none; }

.lightbox {
  position: fixed;
  inset: 0;
  z-index: 120;
  display: grid;
  place-items: center;
  padding: clamp(16px, 4vw, 48px);
  background: rgba(20, 24, 27, .94);
  /* pack the rows to the middle. place-items alone centres each row inside a
     stretched track, which leaves the caption stranded below the photo. */
  align-content: center;
  justify-items: center;
  gap: var(--s-4);
  opacity: 0;
  visibility: hidden;
  transition: opacity 300ms var(--e-ui), visibility 300ms;
}
.lightbox.is-open { opacity: 1; visibility: visible; }
.lightbox img { max-width: min(1100px, 100%); max-height: 78vh; border-radius: var(--r-md); object-fit: contain; }
.lightbox__cap { color: rgba(244, 241, 236, .78); font-size: var(--t-sm); text-align: center; }
.lightbox__btn {
  position: absolute;
  width: 46px; height: 46px;
  border-radius: var(--r-pill);
  border: 1px solid rgba(244, 241, 236, .3);
  /* the prev and next controls sit over the photograph on a phone, so they
     need their own solid ground or they vanish into the image */
  background: rgba(20, 24, 27, .72);
  color: var(--paper);
  display: grid;
  place-items: center;
  cursor: pointer;
  transition: background var(--d-ui) var(--e-ui);
}
.lightbox__btn:hover { background: rgba(20, 24, 27, .92); }
.lightbox__btn svg { width: 16px; height: 16px; }
.lightbox__close { top: 20px; right: 20px; }
.lightbox__prev { left: clamp(10px, 3vw, 32px); top: 50%; transform: translateY(-50%); }
.lightbox__next { right: clamp(10px, 3vw, 32px); top: 50%; transform: translateY(-50%); }

/* --- CTA band ------------------------------------------------------------ */
.ctaband { background: var(--ink); color: var(--paper); border-radius: var(--r-lg); padding: clamp(36px, 5vw, 64px); }
.ctaband h2 { max-width: 16ch; }
.ctaband p { color: rgba(244, 241, 236, .74); margin-top: var(--s-4); }
.ctaband .eyebrow { color: rgba(244, 241, 236, .55); }
.ctaband .rule { background: var(--clay); }
.ctaband__actions { display: flex; flex-wrap: wrap; gap: var(--s-4); margin-top: var(--s-6); }
.ctaband .btn--onink { --btn-fg: var(--paper); }

/* --- Footer -------------------------------------------------------------- */
.foot { background: var(--ink); color: var(--paper); padding-block: var(--pad-md) var(--s-6); }
.foot__grid {
  display: grid;
  grid-template-columns: minmax(0, 1.4fr) repeat(2, minmax(0, 1fr));
  gap: var(--s-7);
  padding-bottom: var(--s-7);
  border-bottom: 1px solid var(--line-dark);
}
@media (max-width: 760px) { .foot__grid { grid-template-columns: 1fr 1fr; } .foot__brandcol { grid-column: 1 / -1; } }
.foot .brand__name, .foot .brand__sub { color: var(--paper); }
.foot .brand__sub { color: rgba(244, 241, 236, .5); }
.foot h3 { font-family: var(--f-sans); font-size: var(--t-xs); letter-spacing: .14em; text-transform: uppercase; color: rgba(244, 241, 236, .5); margin-bottom: var(--s-4); font-weight: 600; }
.foot ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 11px; }
.foot li { color: rgba(244, 241, 236, .78); font-size: var(--t-sm); }
.foot a { color: rgba(244, 241, 236, .78); text-decoration: none; font-size: var(--t-sm); }
.foot a:hover { color: var(--paper); }
.foot__blurb { color: rgba(244, 241, 236, .62); font-size: var(--t-sm); margin-top: var(--s-4); max-width: 38ch; }
.foot__bar {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-4);
  justify-content: space-between;
  padding-top: var(--s-5);
  font-size: var(--t-xs);
  color: rgba(244, 241, 236, .5);
}

/* --- Touch targets -------------------------------------------------------
   Small text links keep their visual size but get an invisible 44px hit area
   from a pseudo element, so nothing in the layout or the underline moves. */
.tlink::before, .review__more::before {
  content: '';
  position: absolute;
  inset: -13px -8px;
}
.review__more { position: relative; }

@media (max-width: 700px) {
  .foot ul { gap: 2px; }
  .foot li { display: flex; }
  .foot li a, .foot li { min-height: 42px; align-items: center; }
  .foot li a { display: inline-flex; align-items: center; width: 100%; }
}

/* --- Mobile sticky call bar ---------------------------------------------- */
.callbar {
  position: fixed;
  inset: auto 0 0;
  z-index: 95;
  display: none;
  gap: 10px;
  padding: 10px 12px calc(10px + env(safe-area-inset-bottom));
  background: rgba(244, 241, 236, .94);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-top: 1px solid var(--line-soft);
  transform: translateY(110%);
  transition: transform 380ms var(--e-entrance);
}
.callbar.is-up { transform: none; }
.callbar .btn { flex: 1; justify-content: center; padding-inline: 14px; }
@media (max-width: 700px) {
  .callbar { display: flex; }
  body { padding-bottom: 74px; }
}

/* --- Small phones (320px and similar) -------------------------------------
   Every auto-fit track wider than the available content box pushed the page
   past the viewport, and `overflow-x: clip` hid the excess instead of letting
   it scroll. Below 420px every multi column grid collapses to one. */
@media (max-width: 420px) {
  .split, .split--wide, .cards, .reviews, .steps, .form__row, .gal {
    grid-template-columns: minmax(0, 1fr);
    columns: 1;
  }
  .foot__grid { grid-template-columns: minmax(0, 1fr); }
  .trust { grid-template-columns: minmax(0, 1fr); }
  .ratingbar { padding: var(--s-5); }
}


/* --- Reduced motion ------------------------------------------------------ */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
  .reveal, .figure--reveal img { opacity: 1; transform: none; clip-path: none; }
  .rule { transform: scaleX(1); }
  .menu__list a { opacity: 1; transform: none; }
  /* the call bar keeps its hidden position: forcing transform none pinned it
     over the bottom of the page from the very first paint. It still appears
     on scroll via .is-up, it just snaps instead of sliding. */
}

/* --- Print --------------------------------------------------------------- */
@media print {
  .nav, .callbar, .menu, .lightbox { display: none !important; }
  body { background: #fff; }
  body::after { display: none; }
}
