/* ==========================================================================
   TAYLOR COMPANY
   General Contracting & Property Improvements — Cedar Rapids, Iowa

   Palette and mark taken from the company logo: black + olive #464720.
   --------------------------------------------------------------------------
     01  Tokens          06  Buttons
     02  Reset           07  Media & photo slots
     03  Typography      08  Components
     04  Layout          09  Sections
     05  Header/nav      10  Footer  11  Motion  12  Responsive
   ========================================================================== */


/* 01  TOKENS
   ========================================================================== */
:root {
  /* Brand */
  --ink:         #14150F;   /* near-black, faintly olive — body text   16.8:1 */
  --ink-soft:    #33342A;
  --olive:       #464720;   /* brand olive, from the logo               8.8:1 */
  --olive-mid:   #5C5E2C;   /* hover                                          */
  --olive-deep:  #2B2C14;   /* dark section grounds                           */
  --olive-lite:  #A9AB6E;   /* olive on dark grounds                    5.9:1 */
  --olive-pale:  #DCDEC0;   /* small text on the olive fill             7.0:1 */
  --olive-wash:  #EEEFE4;   /* tint fills                                     */

  /* Neutrals — warm, to sit with the olive */
  --sand:        #F6F5F0;   /* page ground                                    */
  --paper:       #FFFFFF;   /* raised surfaces                                */
  --sand-deep:   #EBE9E0;
  --muted:       #6A6A5E;   /* secondary text                           5.0:1 */
  --rule:        #DEDCD2;
  --rule-dark:   rgba(246,245,240,.17);

  --danger:      #A32E22;
  --ok:          #3F6B2E;

  /*  Type.
      Display is Archivo held at 112% width. The wide grotesque echoes the
      geometry of the logo wordmark without reaching for Montserrat, which is
      the geometric-sans equivalent of a default. Body is IBM Plex Sans —
      slightly technical, workmanlike, and a clear counterpoint in width.  */
  --font-display: 'Archivo', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --font-body:    'IBM Plex Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --display-wdth: 112%;

  --fs-display: clamp(2.25rem, 5.2vw, 4.25rem);
  --fs-h1:      clamp(2rem, 4.2vw, 3.25rem);
  --fs-h2:      clamp(1.6rem, 3vw, 2.4rem);
  --fs-h3:      clamp(1.15rem, 1.6vw, 1.375rem);
  --fs-lead:    clamp(1.05rem, 1.35vw, 1.25rem);
  --fs-body:    1.0625rem;
  --fs-sm:      0.9375rem;
  --fs-micro:   0.75rem;

  /* Spacing */
  --s1:.5rem; --s2:1rem; --s3:1.5rem; --s4:2rem;
  --s5:3rem;  --s6:4rem; --s7:6rem;
  --section: clamp(3.5rem, 8vw, 7rem);
  --gutter:  clamp(1.25rem, 4vw, 4rem);
  --maxw:    82rem;
  --measure: 40rem;

  --ease:     cubic-bezier(.22,.61,.36,1);
  --ease-out: cubic-bezier(.16,1,.3,1);
  --t-fast:   160ms;
  --t-base:   280ms;

  --z-nav: 300; --z-menu: 200;
}


/* 02  RESET
   ========================================================================== */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; scroll-padding-top: 6rem; }

body {
  background: var(--sand);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--fs-body);
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

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

/* Author `display` beats the UA [hidden] rule — make hiding reliable. */
[hidden] { display: none !important; }

button, input, textarea, select { font: inherit; color: inherit; }

:focus-visible { outline: 3px solid var(--olive); outline-offset: 3px; border-radius: 2px; }
.on-dark :focus-visible, .hero :focus-visible, body.menu-open :focus-visible {
  outline-color: var(--olive-lite);
}

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

.skip-link { position: absolute; left: -9999px; top: 0; z-index: 999;
  background: var(--olive); color: #fff; padding: var(--s2) var(--s3); }
.skip-link:focus { left: var(--s2); top: var(--s2); }

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


/* 03  TYPOGRAPHY
   ========================================================================== */
/*  Everything set in the display face is held at the expanded width.
    Grouped here so the width lives in one place, not scattered per component. */
h1, h2, h3, h4, .display, .overline, .btn, .card-meta, .tile .more, .acc-btn,
.step-num, .quote, .quote-attr, .trust, .breadcrumb, .site-footer h4,
.field label, .ph-kind, .file-drop strong, .mobile-menu > ul > li > a {
  font-stretch: var(--display-wdth);
}

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 700;
  line-height: 1.12;
  letter-spacing: -0.015em;
  text-wrap: balance;
}
.display { font-size: var(--fs-display); font-weight: 800; line-height: 1.04; letter-spacing: -0.03em; }
h1 { font-size: var(--fs-h1); }
h2 { font-size: var(--fs-h2); }
h3 { font-size: var(--fs-h3); line-height: 1.25; letter-spacing: -0.01em; }

.lead { font-size: var(--fs-lead); line-height: 1.55; color: var(--ink-soft);
  max-width: var(--measure); text-wrap: pretty; }

p { max-width: var(--measure); text-wrap: pretty; }
p + p { margin-top: var(--s3); }

/* Uppercase micro-label with a short olive rule */
.overline {
  font-family: var(--font-display);
  font-size: var(--fs-micro);
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--muted);
  display: flex; align-items: center; gap: var(--s2);
}
.overline::before { content:''; width: 1.75rem; height: 2px; background: var(--olive); flex: none; }
.overline.no-rule::before { display: none; }
.on-dark .overline { color: #B6B8A6; }
.on-dark .overline::before { background: var(--olive-lite); }

.muted { color: var(--muted); }
.olive { color: var(--olive); }


/* 04  LAYOUT
   ========================================================================== */
.wrap { max-width: var(--maxw); margin-inline: auto; padding-inline: var(--gutter); }
.section { padding-block: var(--section); }
.section-tight { padding-block: clamp(2.5rem, 5vw, 4rem); }
.rule { height: 1px; background: var(--rule); border: 0; }

.grid { display: grid; gap: var(--s4); }
/* Grid items default to min-width:auto, which lets wide content (iframes,
   long strings) blow the track out past the viewport. Never allow that. */
.grid > * { min-width: 0; }
.g-2 { grid-template-columns: repeat(2, minmax(0,1fr)); }
.g-3 { grid-template-columns: repeat(3, minmax(0,1fr)); }
.g-4 { grid-template-columns: repeat(4, minmax(0,1fr)); }

/* Form page: wide column for the embed, narrow rail for details. */
.split-form {
  display: grid; align-items: start;
  grid-template-columns: minmax(0, 1.55fr) minmax(0, 1fr);
  gap: clamp(2rem, 5vw, 4.5rem);
}
.split-form > * { min-width: 0; }
@media (max-width: 940px) { .split-form { grid-template-columns: 1fr; } }

.stack { display: flex; flex-direction: column; }
.stack-2{gap:var(--s2)} .stack-3{gap:var(--s3)} .stack-4{gap:var(--s4)} .stack-5{gap:var(--s5)}

.cluster { display: flex; flex-wrap: wrap; gap: var(--s3); align-items: center; }

.section-head {
  display: flex; justify-content: space-between; align-items: flex-end;
  gap: var(--s4); flex-wrap: wrap; margin-bottom: var(--s5);
}

/*  Heading block + "see all" link + a grid of cards.
    Laid out with grid areas rather than flex so the link can sit top-right on
    desktop and drop below the cards on a phone, where an orphan link wedged
    between the intro and the first card just reads as clutter.               */
.head-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-areas: "head link" "cards cards";
  column-gap: var(--s4);
  align-items: end;
}
.hg-head  { grid-area: head; }
.hg-link  { grid-area: link; }
.hg-cards { grid-area: cards; margin-top: var(--s5); }

@media (max-width: 700px) {
  .head-grid {
    grid-template-columns: 1fr;
    grid-template-areas: "head" "cards" "link";
  }
  .hg-cards { margin-top: var(--s3); }
  .hg-link  { margin-top: var(--s4); }
  /* 88px of gap in a 317px block was most of the problem */
  .hg-head h2 + p { margin-top: var(--s2) !important; }
}

.split {
  display: grid;
  grid-template-columns: minmax(0,13rem) minmax(0,1fr);
  gap: clamp(1.5rem, 4vw, 4.5rem);
  align-items: start;
}
.split-head { position: sticky; top: 7rem; }

.on-dark { background: var(--olive-deep); color: var(--sand); }
/* Two dark sections in a row would otherwise read as one undifferentiated slab. */
.on-dark + .on-dark { border-top: 1px solid var(--rule-dark); }
.on-dark h1, .on-dark h2, .on-dark h3 { color: var(--paper); }
.on-dark .lead { color: #D2D4C6; }
.on-dark .muted { color: #A8AA9A; }
.on-dark .rule { background: var(--rule-dark); }


/* 05  HEADER / NAV
   ========================================================================== */
.site-header {
  position: fixed; inset: 0 0 auto 0; z-index: var(--z-nav);
  transition: box-shadow var(--t-base) var(--ease);
}
.site-header::after {
  content:''; position: absolute; inset: 0; background: var(--sand);
  opacity: 0; transition: opacity var(--t-base) var(--ease); z-index: -1;
}
.site-header.is-stuck::after { opacity: 1; }
.site-header.is-stuck { box-shadow: 0 1px 0 var(--rule); }

/*  Promo banner.
    Lives inside the fixed header rather than above it, which avoids having to
    offset the header by the banner's height. Collapsing it on scroll gives the
    same felt behaviour as "scrolls away" with none of the layout maths.       */
.promo {
  background: var(--olive); color: #fff;
  overflow: hidden; max-height: 6rem;
  transition: max-height 320ms var(--ease), opacity 220ms var(--ease);
}
.site-header.is-stuck .promo { max-height: 0; opacity: 0; }
body.promo-dismissed .promo { display: none; }
body.menu-open .promo { display: none; }

.promo-inner {
  display: flex; align-items: center; justify-content: center;
  gap: var(--s2) var(--s3); flex-wrap: wrap;
  padding-block: .6rem; position: relative;
  text-align: center;
}
.promo-label {
  font-family: var(--font-display); font-stretch: var(--display-wdth);
  font-weight: 700; font-size: .6875rem; letter-spacing: .14em;
  text-transform: uppercase; color: var(--olive-pale);
  white-space: nowrap;
}
.promo-msg { font-size: var(--fs-sm); color: rgba(255,255,255,.94); max-width: none; }
.promo-cta {
  font-family: var(--font-display); font-stretch: var(--display-wdth);
  font-weight: 700; font-size: .6875rem; letter-spacing: .1em; text-transform: uppercase;
  color: #fff; text-decoration: none; white-space: nowrap;
  display: inline-flex; align-items: center; gap: .4rem;
  border-bottom: 1.5px solid rgba(255,255,255,.5); padding-bottom: 2px;
  transition: border-color var(--t-fast), gap var(--t-fast);
}
.promo-cta:hover { border-color: #fff; gap: .6rem; }
.promo-x {
  position: absolute; right: 0; top: 50%; transform: translateY(-50%);
  /* 44px — the touch-target floor. The glyph inside stays small. */
  width: 2.75rem; height: 2.75rem; display: grid; place-items: center;
  background: none; border: 0; cursor: pointer; color: rgba(255,255,255,.7);
  border-radius: 2px; transition: color var(--t-fast);
}
.promo-x:hover { color: #fff; }
/* Fill-in copy that still needs real numbers — obvious on sight */
.promo-fill { border-bottom: 1px dashed rgba(255,255,255,.6); padding-bottom: 1px; }

@media (max-width: 860px) {
  .promo-inner { padding-right: 2.75rem; gap: .35rem var(--s2); }
  .promo-msg { font-size: .8125rem; }
}
@media (max-width: 520px) {
  .promo-label { display: none; }
}
@media (prefers-reduced-motion: reduce) { .promo { transition: none; } }

.nav {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s3);
  padding-block: clamp(.75rem, 1.6vw, 1.25rem);
  transition: padding var(--t-base) var(--ease);
}
.site-header.is-stuck .nav { padding-block: .625rem; }

.brand { display: block; line-height: 0; flex: none; }
.brand img { height: clamp(2.5rem, 4.4vw, 3.5rem); width: auto; transition: height var(--t-base) var(--ease); }
.site-header.is-stuck .brand img { height: clamp(2.25rem, 3.4vw, 2.75rem); }
.brand .logo-light { display: none; }
.header-over .brand .logo-light { display: block; }
.header-over .brand .logo-dark  { display: none; }
.site-header.is-stuck.header-over .brand .logo-light { display: none; }
.site-header.is-stuck.header-over .brand .logo-dark  { display: block; }
body.menu-open .brand .logo-light { display: block; }
body.menu-open .brand .logo-dark  { display: none; }

.nav-right { display: flex; align-items: center; gap: clamp(1rem, 2vw, 2rem); }

.nav-links { display: flex; align-items: center; gap: clamp(.9rem, 1.8vw, 1.9rem);
  list-style: none; padding: 0; }
.nav-links > li { position: relative; }
.nav-links a {
  font-size: var(--fs-sm); font-weight: 500; color: var(--ink);
  text-decoration: none; padding-block: .3rem; display: inline-block; position: relative;
}
.nav-links a::after {
  content:''; position: absolute; left: 0; bottom: 0; width: 100%; height: 2px;
  background: var(--olive); transform: scaleX(0); transform-origin: right;
  transition: transform var(--t-base) var(--ease-out);
}
.nav-links a:hover::after, .nav-links a[aria-current="page"]::after {
  transform: scaleX(1); transform-origin: left;
}
.nav-links a[aria-current="page"] { color: var(--olive); }

/* The dropdown trigger is a <button>, so it needs recolouring alongside the links. */
.header-over .nav-links a { color: var(--paper); }
.header-over .nav-links a::after { background: var(--olive-lite); }
.site-header.is-stuck.header-over .nav-links a { color: var(--ink); }
.site-header.is-stuck.header-over .nav-links a::after { background: var(--olive); }

/*  Services dropdown — CSS only.
    The trigger is a real link to the services hub, so clicking it navigates
    (what people expect) instead of fighting the hover state. Revealed on
    hover for mice and :focus-within for keyboards; no JS, no stale ARIA.  */
.has-menu > a { display: inline-flex; align-items: center; gap: .35rem; }
.has-menu > a .chev { transition: transform var(--t-base) var(--ease); }
.has-menu:hover > a .chev,
.has-menu:focus-within > a .chev { transform: rotate(180deg); }

/* Invisible bridge so the pointer can cross the gap without the menu closing */
.has-menu::after {
  content: ''; position: absolute; top: 100%; left: 0; right: 0; height: .85rem;
}

.submenu {
  position: absolute; top: calc(100% + .75rem); left: -1rem;
  background: var(--paper); border: 1px solid var(--rule);
  min-width: 17rem; padding: .5rem; list-style: none;
  box-shadow: 0 12px 32px rgba(20,21,15,.10);
  opacity: 0; visibility: hidden; transform: translateY(-6px);
  transition: opacity var(--t-base) var(--ease), transform var(--t-base) var(--ease), visibility var(--t-base);
}
.has-menu:hover .submenu,
.has-menu:focus-within .submenu { opacity: 1; visibility: visible; transform: translateY(0); }
.submenu a {
  display: block; padding: .6rem .75rem; font-size: var(--fs-sm);
  color: var(--ink) !important; border-radius: 2px;
}
.submenu a::after { display: none; }
.submenu a:hover { background: var(--olive-wash); color: var(--olive) !important; }

.menu-btn {
  display: none; background: none; border: 0; cursor: pointer;
  width: 3rem; height: 3rem; padding: .75rem; margin-right: -.75rem;
  align-items: center; justify-content: center; flex-direction: column; gap: 5px;
}
.menu-btn span { display: block; width: 22px; height: 2px; background: var(--ink);
  transition: transform var(--t-base) var(--ease), opacity var(--t-fast); }
.header-over .menu-btn span { background: var(--paper); }
.site-header.is-stuck.header-over .menu-btn span { background: var(--ink); }
body.menu-open .menu-btn span { background: var(--paper); }
.menu-btn[aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.menu-btn[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.menu-btn[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

body.menu-open .site-header::after { opacity: 0; }
body.menu-open .site-header { box-shadow: none; }

/* Mobile drawer */
.mobile-menu {
  position: fixed; inset: 0; z-index: var(--z-menu);
  background: var(--olive-deep); color: var(--sand);
  padding: 6rem var(--gutter) var(--s5);
  display: flex; flex-direction: column; justify-content: space-between; gap: var(--s4);
  overflow-y: auto;
  transform: translateY(-100%); visibility: hidden;
  transition: transform 520ms var(--ease-out), visibility 520ms;
}
.mobile-menu.is-open { transform: translateY(0); visibility: visible; }
.mobile-menu ul { list-style: none; padding: 0; }
.mobile-menu > ul > li + li { margin-top: .1rem; }
.mobile-menu > ul > li > a {
  font-family: var(--font-display); font-weight: 700;
  font-size: clamp(1.5rem, 6.5vw, 2rem);
  color: var(--paper); text-decoration: none; display: block; padding-block: .45rem;
}
.mobile-menu > ul > li > a:hover { color: var(--olive-lite); }
.mobile-sub { padding-left: 0 !important; margin: .25rem 0 .5rem; }
.mobile-sub li { margin: 0; }
.mobile-sub a {
  display: block; padding: .4rem 0; font-size: var(--fs-sm);
  color: #B6B8A6; text-decoration: none;
}
.mobile-sub a:hover { color: var(--olive-lite); }
.mobile-foot { font-size: var(--fs-sm); color: #A8AA9A; }
.mobile-foot a { color: var(--paper); text-decoration: none; font-weight: 500; }


/* 06  BUTTONS
   ========================================================================== */
.btn {
  --bg: var(--olive); --fg: #fff;
  display: inline-flex; align-items: center; justify-content: center; gap: .55rem;
  min-height: 3.25rem; padding: .85rem 1.75rem;
  background: var(--bg); color: var(--fg);
  border: 2px solid var(--bg); border-radius: 2px;
  font-family: var(--font-display); font-size: var(--fs-sm); font-weight: 600;
  letter-spacing: .01em; text-decoration: none; cursor: pointer;
  position: relative; overflow: hidden; isolation: isolate;
  transition: color var(--t-base) var(--ease), border-color var(--t-base) var(--ease);
}
.btn::before {
  content:''; position: absolute; inset: 0; background: var(--ink);
  transform: scaleY(0); transform-origin: bottom; z-index: -1;
  transition: transform var(--t-base) var(--ease-out);
}
.btn:hover::before { transform: scaleY(1); }
.btn:hover { border-color: var(--ink); }
.btn:active { transform: translateY(1px); }

.btn-ghost { --bg: transparent; --fg: var(--ink); border-color: var(--ink); }
.btn-ghost:hover { color: var(--sand); }

.btn-sm { min-height: 2.75rem; padding: .55rem 1.15rem; font-size: .875rem; }

.on-dark .btn, .hero .btn { --bg: var(--paper); --fg: var(--olive-deep); }
.on-dark .btn::before, .hero .btn::before { background: var(--olive-lite); }
.on-dark .btn:hover, .hero .btn:hover { color: var(--olive-deep); border-color: var(--olive-lite); }
.on-dark .btn-ghost, .hero .btn-ghost {
  --bg: transparent; --fg: var(--paper); border-color: rgba(255,255,255,.55);
}
.on-dark .btn-ghost::before, .hero .btn-ghost::before { background: var(--paper); }
.on-dark .btn-ghost:hover, .hero .btn-ghost:hover { color: var(--olive-deep); border-color: var(--paper); }

.link {
  color: var(--ink); text-decoration: none; font-weight: 600; font-size: var(--fs-sm);
  display: inline-flex; align-items: center; gap: .45rem; padding-bottom: .15rem;
  background-image: linear-gradient(var(--olive), var(--olive));
  background-size: 0% 2px; background-repeat: no-repeat; background-position: left bottom;
  transition: background-size var(--t-base) var(--ease-out), color var(--t-fast);
}
.link:hover { background-size: 100% 2px; color: var(--olive); }
.link .arw { transition: transform var(--t-base) var(--ease-out); }
.link:hover .arw { transform: translateX(3px); }
.on-dark .link { color: var(--paper); background-image: linear-gradient(var(--olive-lite), var(--olive-lite)); }
.on-dark .link:hover { color: var(--olive-lite); }


/* 07  MEDIA & PHOTO SLOTS
   ========================================================================== */
.media { position: relative; overflow: hidden; background: var(--sand-deep); border-radius: 2px; }
.media img { width: 100%; height: 100%; object-fit: cover; }

.r-wide {aspect-ratio:21/9} .r-hero {aspect-ratio:16/9} .r-land {aspect-ratio:4/3}
.r-square {aspect-ratio:1/1} .r-portrait {aspect-ratio:3/4} .r-tall {aspect-ratio:2/3}

.media-zoom img { transition: transform 900ms var(--ease-out); }
.card:hover .media-zoom img { transform: scale(1.04); }

/*  Photo slot awaiting a real image. Deliberately plain — this site does not
    use stock photography, so an empty slot reads as "not yet", not as filler.
    Replace the whole .ph block with:
      <img src="images/projects/name.jpg" alt="…" width="1200" height="900" loading="lazy">  */
.ph {
  position: absolute; inset: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: .5rem; text-align: center; padding: var(--s3);
  background:
    repeating-linear-gradient(45deg, transparent 0 12px, rgba(70,71,32,.035) 12px 24px),
    var(--sand-deep);
  color: var(--muted);
}
.ph::before { content:''; width: 2rem; height: 2px; background: var(--olive); opacity: .4; }
.ph-kind { font-family: var(--font-display); font-size: .625rem; font-weight: 700;
  letter-spacing: .16em; text-transform: uppercase; color: var(--olive); opacity: .8; }
.ph-label { font-size: var(--fs-micro); letter-spacing: .06em; max-width: 26ch; line-height: 1.5; }
.on-dark .ph {
  background: repeating-linear-gradient(45deg, transparent 0 12px, rgba(255,255,255,.03) 12px 24px), #35361A;
  color: #A8AA9A;
}
.on-dark .ph::before, .on-dark .ph-kind { color: var(--olive-lite); background: var(--olive-lite); }
.on-dark .ph-kind { background: none; }

/*  An empty hero slot should read as a deliberate dark ground, not as a pale
    box sitting behind a scrim. Stops applying once a real hero.jpg exists.  */
.hero-media .ph {
  background:
    repeating-linear-gradient(45deg, transparent 0 14px, rgba(255,255,255,.022) 14px 28px),
    linear-gradient(150deg, #3D3E1D 0%, #2B2C14 55%, #191A0E 100%);
  color: rgba(255,255,255,.42);
  align-items: flex-end; justify-content: flex-start;
  text-align: right; padding: 7rem var(--gutter) var(--gutter);
}
.hero-media .ph::before { background: var(--olive-lite); opacity: .5; align-self: flex-end; }
.hero-media .ph-kind { color: var(--olive-lite); opacity: .8; }
@media (max-width: 860px) {
  .hero-media .ph-kind, .hero-media .ph::before { display: none; }
}

figcaption { margin-top: var(--s2); font-size: var(--fs-sm); color: var(--muted); }

/* Before / after comparison */
.ba { position: relative; overflow: hidden; border-radius: 2px; background: var(--sand-deep); }
.ba img, .ba .ph { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.ba-after { clip-path: inset(0 0 0 var(--pos, 50%)); }
.ba-range {
  position: absolute; inset: 0; width: 100%; height: 100%;
  margin: 0; opacity: 0; cursor: ew-resize; z-index: 3;
}
.ba-handle {
  position: absolute; top: 0; bottom: 0; left: var(--pos, 50%);
  width: 2px; background: var(--paper); z-index: 2; pointer-events: none;
  box-shadow: 0 0 0 1px rgba(20,21,15,.2);
}
.ba-handle::after {
  content:''; position: absolute; top: 50%; left: 50%;
  width: 2.75rem; height: 2.75rem; transform: translate(-50%,-50%);
  border: 2px solid var(--paper); border-radius: 50%;
  background: rgba(43,44,20,.35); backdrop-filter: blur(2px);
}
.ba-tag {
  position: absolute; bottom: .75rem; z-index: 2;
  font-family: var(--font-display); font-size: .625rem; font-weight: 700;
  letter-spacing: .14em; text-transform: uppercase;
  background: rgba(20,21,15,.72); color: #fff; padding: .35rem .6rem; border-radius: 2px;
}
.ba-tag.is-before { left: .75rem; }
.ba-tag.is-after  { right: .75rem; }


/* 08  COMPONENTS
   ========================================================================== */
.card { display: block; text-decoration: none; color: inherit; }
.card-body { padding-top: var(--s3); }
.card h3 { transition: color var(--t-fast); }
.card:hover h3 { color: var(--olive); }
.card-meta { display: flex; gap: var(--s2); flex-wrap: wrap; margin-top: .5rem;
  font-family: var(--font-display); font-size: var(--fs-micro); font-weight: 600;
  letter-spacing: .1em; text-transform: uppercase; color: var(--muted); }

/*  Service tile.
    Three stacked layers behind the content, hence the explicit z-indexes —
    same-z pseudo-elements paint in DOM order and the scrim would otherwise
    cover the wipe:
      -3  .tile-bg   project photo, when one exists
      -2  ::after    scrim, only on photo cards, so text stays readable
      -1  ::before   olive wipe, rises on hover                              */
.tile {
  position: relative; isolation: isolate; overflow: hidden;
  display: flex; flex-direction: column; gap: var(--s3);
  background: var(--paper); border: 1px solid var(--rule); border-radius: 2px;
  padding: clamp(1.5rem, 2.6vw, 2.25rem);
  text-decoration: none; color: inherit; height: 100%;
  transition: border-color var(--t-base) var(--ease), transform var(--t-base) var(--ease);
}
.tile::before {
  content: ''; position: absolute; inset: 0; z-index: -1;
  background: var(--olive);
  transform: scaleY(0); transform-origin: bottom;
  transition: transform 420ms var(--ease-out);
}
.tile:hover::before, .tile:focus-visible::before { transform: scaleY(1); }
.tile:hover, .tile:focus-visible { border-color: var(--olive); transform: translateY(-2px); }

.tile-icon { width: 2.5rem; height: 2.5rem; color: var(--olive);
  transition: color var(--t-base) var(--ease); }
.tile h3 { font-size: var(--fs-h3); transition: color var(--t-base) var(--ease); }
.tile p { font-size: var(--fs-sm); color: var(--muted); flex: 1;
  transition: color var(--t-base) var(--ease); }
.tile .more { font-family: var(--font-display); font-size: var(--fs-micro); font-weight: 700;
  letter-spacing: .1em; text-transform: uppercase; color: var(--olive);
  display: inline-flex; align-items: center; gap: .4rem;
  transition: color var(--t-base) var(--ease); }
.tile .arw { transition: transform var(--t-base) var(--ease-out); }
.tile:hover .more .arw { transform: translateX(3px); }

/* Everything reads light once the olive has risen */
.tile:hover h3, .tile:focus-visible h3 { color: var(--paper); }
.tile:hover p, .tile:focus-visible p { color: rgba(255,255,255,.85); }
/*  Pale rather than --olive-lite: light olive on the olive fill measures
    4.0:1, under the 4.5:1 floor for small text. The icon keeps --olive-lite
    because a 2.5rem graphic only needs 3:1.  */
.tile:hover .more, .tile:focus-visible .more { color: var(--olive-pale); }
.tile:hover .tile-icon, .tile:focus-visible .tile-icon { color: var(--olive-lite); }

/*  Photo state — add images/projects/service-<slug>.jpg and build.py wires
    this class on automatically. Nothing here needs editing by hand.          */
.tile-bg { position: absolute; inset: 0; z-index: -3; background: var(--sand-deep); }
.tile-bg img {
  width: 100%; height: 100%; object-fit: cover;
  transform: scale(1.01);
  transition: transform 900ms var(--ease-out);
}
.tile:hover .tile-bg img { transform: scale(1.07); }

.tile.has-photo { border-color: transparent; background: var(--olive-deep); }
.tile.has-photo::after {
  content: ''; position: absolute; inset: 0; z-index: -2;
  background: linear-gradient(180deg, rgba(20,21,15,.35) 0%, rgba(20,21,15,.80) 100%);
}
.tile.has-photo h3 { color: var(--paper); }
.tile.has-photo p { color: rgba(255,255,255,.82); }
.tile.has-photo .more, .tile.has-photo .tile-icon { color: var(--olive-lite); }
/* On a photo card the wipe is a translucent wash, so the work stays visible */
.tile.has-photo::before { background: rgba(70,71,32,.86); }

@media (prefers-reduced-motion: reduce) {
  .tile::before { transition: none; }
  .tile-bg img, .tile:hover .tile-bg img { transition: none; transform: none; }
}

/* Checklist */
.checks { list-style: none; padding: 0; margin: 0; }
.checks li { position: relative; padding: .55rem 0 .55rem 1.75rem; font-size: var(--fs-sm);
  border-top: 1px solid var(--rule); }
.checks li:first-child { border-top: 0; }
.checks li::before {
  content:''; position: absolute; left: 0; top: 1.05rem;
  width: .75rem; height: 2px; background: var(--olive);
}
.on-dark .checks li { border-top-color: var(--rule-dark); }
.on-dark .checks li::before { background: var(--olive-lite); }

/* Numbered step */
.step { display: grid; grid-template-columns: 3.5rem 1fr; gap: var(--s3);
  padding-block: var(--s4); border-top: 1px solid var(--rule); align-items: start; }
.step:last-child { border-bottom: 1px solid var(--rule); }
.on-dark .step { border-top-color: var(--rule-dark); }
.on-dark .step:last-child { border-bottom-color: var(--rule-dark); }
.step-num { font-family: var(--font-display); font-weight: 800; font-size: 1.5rem;
  color: var(--olive); line-height: 1; font-variant-numeric: tabular-nums; }
.on-dark .step-num { color: var(--olive-lite); }

/* Trust bar */
.trust { display: flex; flex-wrap: wrap; gap: var(--s2) clamp(1.25rem,3.5vw,3rem); align-items: center;
  font-family: var(--font-display); font-size: var(--fs-micro); font-weight: 600;
  letter-spacing: .1em; text-transform: uppercase; color: var(--muted); }
.trust span { display: flex; align-items: center; gap: .5rem; }
.trust svg { color: var(--olive); flex: none; }

/* Accordion */
.acc { border-top: 1px solid var(--rule); }
.acc-item { border-bottom: 1px solid var(--rule); }
.acc-btn {
  width: 100%; background: none; border: 0; text-align: left;
  padding: var(--s3) 3rem var(--s3) 0; cursor: pointer; position: relative;
  font-family: var(--font-display); font-weight: 600; font-size: 1.0625rem;
  line-height: 1.35; color: var(--ink); transition: color var(--t-fast);
}
.acc-btn:hover { color: var(--olive); }
.acc-btn::before, .acc-btn::after {
  content:''; position: absolute; right: 12px; top: 50%; background: var(--olive);
  transition: transform var(--t-base) var(--ease-out), opacity var(--t-base);
}
.acc-btn::before { width: 15px; height: 2px; transform: translate(50%,-50%); }
.acc-btn::after  { width: 2px; height: 15px; transform: translate(50%,-50%); }
.acc-btn[aria-expanded="true"]::after { transform: translate(50%,-50%) rotate(90deg); opacity: 0; }
.acc-panel { display: grid; grid-template-rows: 0fr;
  transition: grid-template-rows var(--t-base) var(--ease-out); }
.acc-panel > div { overflow: hidden; }
.acc-item.is-open .acc-panel { grid-template-rows: 1fr; }
.acc-panel p { padding-bottom: var(--s3); color: var(--muted); font-size: var(--fs-sm); }

/* Testimonial shell — stays empty until a real review exists */
.quote { font-family: var(--font-display); font-weight: 600;
  font-size: clamp(1.15rem,2vw,1.5rem); line-height: 1.4; letter-spacing: -.01em;
  max-width: 34ch; }
.quote-attr { margin-top: var(--s3); font-size: var(--fs-micro); font-weight: 600;
  letter-spacing: .12em; text-transform: uppercase; color: var(--muted);
  font-family: var(--font-display); }

/* Area list */
.area-list { columns: 2; column-gap: var(--s5); list-style: none; padding: 0; }
.area-list li { padding: .55rem 0; border-bottom: 1px solid var(--rule);
  font-size: var(--fs-sm); break-inside: avoid; }
.on-dark .area-list li { border-bottom-color: var(--rule-dark); }

/* ---- Estimate form -------------------------------------------------------
   Native form, styled as part of the page. Submissions handled by the host.  */
.form-card { background: var(--paper); border: 1px solid var(--rule); border-radius: 2px;
  padding: clamp(1.5rem, 3vw, 2.5rem); }

.field { display: flex; flex-direction: column; gap: .45rem; }
.field + .field, .field-row + .field, .field + .field-row { margin-top: var(--s3); }
.field-row { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s3); align-items: start; }
/* The stacked-sibling margin above must not apply to columns inside a row,
   or the second field drops below the first. */
.field-row > .field + .field { margin-top: 0; }
@media (max-width: 640px) { .field-row { grid-template-columns: 1fr; gap: var(--s3); } }

.field label {
  font-family: var(--font-display); font-size: var(--fs-micro); font-weight: 700;
  letter-spacing: .1em; text-transform: uppercase; color: var(--ink);
}
.field .req { color: var(--olive); }
.field .opt { color: var(--muted); font-weight: 600; letter-spacing: .06em; }

.field input[type="text"], .field input[type="email"], .field input[type="tel"],
.field textarea, .field select {
  width: 100%;
  background: var(--sand);
  border: 1.5px solid var(--rule);
  border-radius: 2px;
  padding: .8rem .9rem;
  min-height: 3.1rem;
  font-size: 1rem;              /* >=16px keeps iOS from zooming on focus */
  font-family: var(--font-body);
  transition: border-color var(--t-fast), box-shadow var(--t-fast), background var(--t-fast);
}
.field textarea { min-height: 8.5rem; resize: vertical; line-height: 1.6; }
.field select { appearance: none; cursor: pointer;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath d='M2.5 4.5 6 8l3.5-3.5' fill='none' stroke='%236A6A5E' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right .9rem center; padding-right: 2.5rem; }
.field input:focus, .field textarea:focus, .field select:focus {
  outline: none; background: var(--paper);
  border-color: var(--olive); box-shadow: 0 0 0 3px var(--olive-wash);
}
.field .hint { font-size: var(--fs-sm); color: var(--muted); }
.field .err { font-size: var(--fs-sm); color: var(--danger); font-weight: 500; display: none; }
.field.is-invalid .err { display: block; }
.field.is-invalid input, .field.is-invalid textarea, .field.is-invalid select {
  border-color: var(--danger); background: #FCF6F5;
}

/* File input — styled as a drop target rather than a bare browser control */
.field-file input[type="file"] { position: absolute; opacity: 0; width: .1px; height: .1px; }
/*  .file-drop is a <label>, so it inherits the uppercase field-label styling
    above. Reset it — this one is body copy, not a field label.  */
.field .file-drop {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: .5rem; text-align: center;
  border: 1.5px dashed var(--rule); border-radius: 2px;
  padding: var(--s4) var(--s3); cursor: pointer; background: var(--sand);
  transition: border-color var(--t-fast), background var(--t-fast);
  font-family: var(--font-body); font-weight: 400;
  text-transform: none; letter-spacing: normal; color: var(--ink);
}
.file-drop:hover, .field-file input:focus-visible + .file-drop { border-color: var(--olive); background: var(--olive-wash); }
.file-drop svg { color: var(--olive); }
.file-drop strong { font-family: var(--font-display); font-size: var(--fs-sm); font-weight: 600; }
.file-drop span { font-size: var(--fs-sm); color: var(--muted); }
.file-list { margin-top: var(--s2); font-size: var(--fs-sm); color: var(--muted); }
.file-list li { padding: .25rem 0; }

.form-error-summary {
  display: none; margin-bottom: var(--s3);
  background: #FCF6F5; border-left: 3px solid var(--danger);
  padding: var(--s3); font-size: var(--fs-sm);
}
.form-error-summary.is-visible { display: block; }
.form-error-summary ul { margin: .5rem 0 0; padding-left: 1.1rem; }
.form-error-summary a { color: var(--danger); font-weight: 600; }

/* Contact rows */
.contact-row { display: flex; justify-content: space-between; gap: var(--s2);
  padding: .7rem 0; border-bottom: 1px solid var(--rule); font-size: var(--fs-sm); }
.on-dark .contact-row { border-bottom-color: var(--rule-dark); }

/* Callout */
.callout { background: var(--olive-wash); border-left: 3px solid var(--olive);
  padding: var(--s3) var(--s4); border-radius: 2px; }
.callout p { max-width: none; font-size: var(--fs-sm); }


/* 09  SECTIONS
   ========================================================================== */
/*  Scroll-reveal hero.
    A tall runway holds a sticky panel; the media inside opens from a centred
    window to full bleed and eases out of a slight zoom as you scroll.
    Driven by one custom property (--p, 0→1) set in site.js. Only clip-path
    and transform animate, so it stays on the compositor.
    Runway is deliberately short — this is a lead-gen site and the estimate
    CTA should not sit 1500px down the page.  */
.hero-scroll {
  --runway: 640px;
  --clip-max: 17%;
  --zoom-max: .18;
  --p: 0;
  position: relative;
  height: calc(var(--runway) + 100svh);
  background: var(--olive-deep);
}
.hero {
  position: sticky; top: 0;
  height: 100svh;
  display: flex; align-items: flex-end;
  padding: 9rem 0 clamp(2.5rem,6vh,4.5rem);
  overflow: hidden; background: var(--olive-deep);
}
.hero-media {
  position: absolute; inset: 0; z-index: 0;
  clip-path: inset(calc(var(--clip-max) * (1 - var(--p))));
  background: var(--olive-deep);
}
.hero-media img, .hero-media video, .hero-media .ph {
  width: 100%; height: 100%; object-fit: cover;
  transform: scale(calc(1 + var(--zoom-max) * (1 - var(--p))));
  transform-origin: center;
}

/* Shorter runway and a gentler window on phones */
@media (max-width: 860px) {
  .hero-scroll { --runway: 380px; --clip-max: 10%; --zoom-max: .12; }
}

/* No runway, no clip, no zoom — just a normal hero */
@media (prefers-reduced-motion: reduce) {
  .hero-scroll { height: auto; --p: 1; }
  .hero { position: relative; }
}
/*  Weighted toward the bottom, where the headline, lead and buttons sit.
    The old curve was lightest at 42% and only darkened at the very bottom,
    which left the overline stranded on whatever the photo happened to show.  */
.hero-media::after {
  content:''; position: absolute; inset: 0;
  background: linear-gradient(180deg,
    rgba(20,21,15,.58) 0%,
    rgba(20,21,15,.30) 32%,
    rgba(20,21,15,.72) 68%,
    rgba(20,21,15,.88) 100%);
}
/*  The hero sits on imagery but carries no .on-dark class, so the overline was
    inheriting --muted and its rule --olive: two dark values on a photograph.  */
.hero .overline { color: rgba(255,255,255,.86); }
.hero .overline::before { background: var(--olive-lite); }
.hero .wrap { position: relative; z-index: 1; width: 100%; }
.hero-title { color: var(--paper); max-width: 19ch; }
.hero-sub { color: rgba(255,255,255,.88); max-width: 46ch; margin-top: var(--s3); }
.hero-actions { margin-top: var(--s4); }
.hero-meta { margin-top: clamp(2rem,5vh,3.5rem); padding-top: var(--s3);
  border-top: 1px solid rgba(255,255,255,.22);
  display: flex; gap: clamp(1rem,3vw,2.75rem); flex-wrap: wrap;
  font-family: var(--font-display); font-size: var(--fs-micro); font-weight: 600;
  letter-spacing: .11em; text-transform: uppercase; color: rgba(255,255,255,.78); }

.page-hero { padding-top: clamp(8rem,14vh,11rem); padding-bottom: var(--section);
  border-bottom: 1px solid var(--rule); }
.page-hero.on-dark { border-bottom: 0; }

.breadcrumb { display: flex; gap: .5rem; flex-wrap: wrap; list-style: none; padding: 0;
  font-size: var(--fs-micro); color: var(--muted); margin-bottom: var(--s3);
  font-family: var(--font-display); font-weight: 600; letter-spacing: .08em;
  text-transform: uppercase; }
.breadcrumb a { color: var(--muted); text-decoration: none; }
.breadcrumb a:hover { color: var(--olive); }
.breadcrumb li + li::before { content: '/'; margin-right: .5rem; opacity: .5; }

.cta-band { text-align: center; }
.cta-band .wrap { display: flex; flex-direction: column; align-items: center; gap: var(--s3); }
.cta-band h2 { max-width: 20ch; }
.cta-band .lead { text-align: center; }


/* 10  FOOTER
   ========================================================================== */
.site-footer { background: var(--ink); color: var(--sand); }
.footer-top { display: grid; grid-template-columns: 1.5fr 1fr 1fr 1.1fr;
  gap: var(--s5); padding-block: var(--section) var(--s5); }
.site-footer h4 { font-family: var(--font-display); font-size: var(--fs-micro);
  font-weight: 700; letter-spacing: .14em; text-transform: uppercase;
  color: #8E8E80; margin-bottom: var(--s3); }
.site-footer ul { list-style: none; padding: 0; }
.site-footer li + li { margin-top: .6rem; }
.site-footer a { color: rgba(246,245,240,.84); text-decoration: none; font-size: var(--fs-sm);
  transition: color var(--t-fast); }
.site-footer a:hover { color: var(--olive-lite); }
.footer-brand img { height: 3.25rem; width: auto; }
.footer-social { display: flex; gap: .75rem; margin-top: var(--s3); }
.footer-social a { display: grid; place-items: center; width: 2.5rem; height: 2.5rem;
  border: 1px solid rgba(246,245,240,.22); border-radius: 2px; }
.footer-social a:hover { border-color: var(--olive-lite); }
.footer-bottom { border-top: 1px solid rgba(246,245,240,.14);
  padding-block: var(--s3) var(--s5); display: flex; justify-content: space-between;
  gap: var(--s3); flex-wrap: wrap; font-size: var(--fs-sm); color: rgba(246,245,240,.55); }


/* 11  MOTION
   Deliberately restrained per brief: a single short fade-up, nothing else.
   ========================================================================== */
.reveal {
  opacity: 0; transform: translate3d(0, 14px, 0);
  transition: opacity 520ms var(--ease-out), transform 520ms var(--ease-out);
  transition-delay: var(--d, 0ms);
}
.reveal.is-in { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .001ms !important; animation-iteration-count: 1 !important;
    transition-duration: .001ms !important; scroll-behavior: auto !important;
  }
  .reveal { opacity: 1; transform: none; }
  .media-zoom img { transition: none; }
  .card:hover .media-zoom img { transform: none; }
}


/* 12  RESPONSIVE
   ========================================================================== */
@media (max-width: 1080px) {
  .footer-top { grid-template-columns: 1fr 1fr; gap: var(--s5) var(--s4); }
  .split { grid-template-columns: 1fr; gap: var(--s4); }
  .split-head { position: static; }
  .g-4 { grid-template-columns: repeat(2, minmax(0,1fr)); }
}
@media (max-width: 940px) {
  .nav-links { display: none; }
  .nav-right > .btn { display: none; }
  .menu-btn { display: flex; }
  .g-3 { grid-template-columns: repeat(2, minmax(0,1fr)); }
}
@media (max-width: 640px) {
  :root { --fs-body: 1rem; }
  .g-2, .g-3, .g-4 { grid-template-columns: 1fr; }
  .section-head { align-items: flex-start; }
  .step { grid-template-columns: 1fr; gap: var(--s1); }
  .area-list { columns: 1; }
  .footer-top { grid-template-columns: 1fr; }
  .hero { min-height: auto; padding-top: 7.5rem; }
  .hero-actions .btn { width: 100%; }
  .btn { width: 100%; }
  .cluster > .btn { width: 100%; }
  .ph-label { display: none; }
}


/* ==========================================================================
   MOBILE PASS
   Measured at 375px, not guessed. Three problems this solves:
     1. HIDE   — content duplicated within one screen of itself
     2. TIGHTEN— spacing tuned for desktop that reads as dead air on a phone
     3. RESIZE — tap targets under the 44px floor
   ========================================================================== */
@media (max-width: 700px) {

  /* ---- 1. HIDE ---------------------------------------------------------- */

  /*  The hero meta row ("Insured · Locally owned · Free estimates") sits one
      scroll above the trust bar, which says the same thing with icons. On
      desktop they're far apart; on a phone they're near-adjacent and it reads
      as a stutter. Keep the trust bar, drop the duplicate.                   */
  .hero-meta { display: none; }

  /*  The windowed hero reveal doesn't survive a narrow viewport — it shrinks
      the photo to a strip and drags a hard edge through the headline. Full
      bleed from the start; the slow zoom carries the motion instead.          */
  .hero-scroll { --clip-max: 0%; --zoom-max: .10; --runway: 300px; }


  /* ---- 2. TIGHTEN ------------------------------------------------------- */

  :root { --section: 3.25rem; }

  /* "General Contracting & Property Improvements" wrapped to four lines at
     36px. Down a step it's three, which buys back most of a screen. */
  .hero-title { font-size: clamp(1.85rem, 8.4vw, 2.25rem); letter-spacing: -.028em; }
  .hero { padding-top: 6.75rem; padding-bottom: 2.25rem; }
  .hero-sub { margin-top: var(--s2); }
  .hero-actions { margin-top: var(--s3); }
  .hero-actions .cluster { gap: .625rem; }

  /* Stacked cards don't need a desktop column gutter between them */
  .grid { gap: 1.125rem; }
  .tile { padding: 1.375rem; gap: .875rem; }
  .tile-icon { width: 2rem; height: 2rem; }

  .section-head { margin-bottom: var(--s4); }
  .split { gap: var(--s3); }

  /* Banner ran to 67px with the CTA on its own line */
  .promo-inner { padding-block: .45rem; }
  .promo-msg { font-size: .8125rem; line-height: 1.4; }


  /* ---- 3. RESIZE — 44px tap targets ------------------------------------- */

  /*  Measured under 44px: standalone .link CTAs (27px), footer links (19px),
      drawer sub-links (38px), the banner CTA (21px) and the wordmark (36px).
      min-height beats padding here — padding depends on the line-height it's
      added to, so it needs re-measuring every time the type changes.          */
  .link { min-height: 2.75rem; }
  .site-footer a { display: inline-flex; align-items: center; min-height: 2.75rem; }
  .site-footer li + li { margin-top: 0; }
  .footer-social a { width: 2.75rem; height: 2.75rem; }
  .mobile-sub a { min-height: 2.75rem; display: flex; align-items: center; padding-block: 0; }
  .mobile-foot a { display: inline-flex; align-items: center; min-height: 2.75rem; }
  .promo-cta { min-height: 2.75rem; }
  .brand { display: flex; align-items: center; min-height: 2.75rem; }
  .breadcrumb a { display: inline-flex; align-items: center; min-height: 2.75rem; }

  /* Two adjacent taps need 8px of daylight between them */
  .cluster { gap: .75rem; }
}

/* Very narrow phones — 320px and up */
@media (max-width: 380px) {
  :root { --gutter: 1rem; }
  .hero-title { font-size: 1.75rem; }
  .tile { padding: 1.25rem; }
}
@media (max-height: 520px) and (orientation: landscape) {
  .hero { min-height: auto; padding-block: 6.5rem 2.5rem; }
}
@media print {
  .site-header, .mobile-menu, .cta-band { display: none; }
  .reveal { opacity: 1; transform: none; }
  body { background: #fff; }
}
