/* ==========================================================================
   Granite Hills Group — Design System
   Palette sampled from the GHG brand: navy #17406E, cyan #1EBBF0,
   pale blue #BDCFEB, light gray #F3F4F4.
   ========================================================================== */

:root{
  /* Navy — the brand spine */
  --navy-950:#071726;
  --navy-900:#0B2239;
  --navy-800:#102F4F;
  --navy-700:#17406E;   /* brand primary */
  --navy-600:#1D5289;
  --navy-500:#2A6BAF;

  /* Cyan — brand accent */
  --cyan-600:#0F9BCC;
  --cyan-500:#1EBBF0;   /* brand accent */
  --cyan-400:#4ACBF5;
  --cyan-300:#8ADDF9;

  /* Blue tints */
  --blue-200:#BDCFEB;   /* brand tint */
  --blue-100:#DEE7F4;

  /* Neutrals — cool, to sit under navy */
  --gray-50:#FAFBFC;
  --gray-100:#F3F4F4;   /* brand */
  --gray-200:#E6E9ED;
  --gray-300:#D2D7DE;
  --gray-400:#A8B1BC;

  /* Ink */
  --ink-950:#0A121B;
  --ink-900:#111C28;
  --ink-800:#1B2836;
  --ink-700:#33414F;
  --ink-600:#5A6875;
  --ink-500:#7C8894;

  --white:#FFFFFF;

  /* Semantic */
  --bg:var(--white);
  --bg-alt:var(--gray-100);
  --ink:var(--ink-950);
  --ink-soft:var(--ink-600);
  --rule:var(--gray-200);
  --accent:var(--navy-700);

  /* Type */
  --font-display:"Inter Tight",-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;
  --font-body:"Inter",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;
  --font-serif:"Cormorant Garamond",Georgia,"Times New Roman",serif;

  /* Space */
  --gutter:clamp(1.25rem,5vw,4rem);
  --section:clamp(4.5rem,10vw,8.5rem);
  --maxw:1400px;
  --maxw-narrow:820px;

  /* Sharper geometry — squared corners throughout */
  --r:0px;

  --ease:cubic-bezier(.22,1,.36,1);
}

/* ---------- 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}
  *,*::before,*::after{animation-duration:.01ms!important;transition-duration:.01ms!important}
}
body{
  margin:0;
  background:var(--bg);
  color:var(--ink);
  font-family:var(--font-body);
  font-size:1.0625rem;
  line-height:1.6;
  -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;
}
img,svg,video{display:block;max-width:100%;height:auto}
a{color:inherit}
button{font:inherit;color:inherit}

/* ---------- Typography ---------- */
h1,h2,h3,h4{
  font-family:var(--font-display);
  font-weight:700;
  line-height:1.02;
  letter-spacing:-.035em;
  margin:0;
  text-wrap:balance;
}
h1{font-size:clamp(2.7rem,6.4vw,5.25rem);letter-spacing:-.02em;line-height:1.1}
h2{font-size:clamp(2rem,4.5vw,3.6rem);letter-spacing:-.038em}
h3{font-size:clamp(1.3rem,2.1vw,1.75rem);letter-spacing:-.028em}
h4{font-size:1.0625rem;letter-spacing:-.018em;line-height:1.28}
p{margin:0 0 1.1em}
p:last-child{margin-bottom:0}

.eyebrow{
  font-family:var(--font-body);
  font-size:.6875rem;
  font-weight:600;
  letter-spacing:.18em;
  text-transform:uppercase;
  color:var(--navy-600);
  margin:0 0 1.35rem;
  display:flex;align-items:center;gap:.75rem;
}
.eyebrow::before{
  content:"";width:1.5rem;height:1px;background:var(--cyan-500);flex:none;
}
.eyebrow--plain::before{display:none}
.eyebrow--light{color:var(--cyan-400)}
.eyebrow--light::before{background:var(--cyan-500)}

.lede{
  font-size:clamp(1.0625rem,1.6vw,1.3125rem);
  line-height:1.55;
  color:var(--ink-soft);
  max-width:60ch;
  text-wrap:pretty;
}
.lede--light{color:rgba(255,255,255,.7)}

.serif-quote{
  font-family:var(--font-serif);
  font-weight:400;font-style:italic;letter-spacing:-.01em;
}

/* ---------- Layout ---------- */
.wrap{width:100%;max-width:var(--maxw);margin-inline:auto;padding-inline:var(--gutter)}
.wrap--narrow{max-width:var(--maxw-narrow)}
.section{padding-block:var(--section)}
.section--tight{padding-block:clamp(3rem,6vw,5rem)}
.section--dark{background:var(--navy-950);color:var(--white)}
.section--green{background:var(--navy-800);color:var(--white)}
.section--alt{background:var(--bg-alt)}
.section--dark .lede,.section--green .lede{color:rgba(255,255,255,.7)}

.section-head{max-width:64ch;margin-bottom:clamp(2.5rem,5vw,4rem)}
.section-head--center{margin-inline:auto;text-align:center}
.section-head--center .eyebrow{justify-content:center}
.section-head h2 + .lede{margin-top:1.5rem}

.grid{display:grid;gap:clamp(1rem,2vw,1.75rem)}
.grid-2{grid-template-columns:repeat(2,1fr)}
.grid-3{grid-template-columns:repeat(3,1fr)}
.grid-4{grid-template-columns:repeat(4,1fr)}
@media (max-width:1000px){
  .grid-4{grid-template-columns:repeat(2,1fr)}
  .grid-3{grid-template-columns:repeat(2,1fr)}
}
@media (max-width:680px){
  .grid-2,.grid-3,.grid-4{grid-template-columns:1fr}
}

/* ---------- Buttons — squared, tight, precise ---------- */
.btn{
  display:inline-flex;align-items:center;gap:.65rem;
  padding:.95rem 1.7rem;
  border-radius:var(--r);
  border:1px solid transparent;
  font-family:var(--font-body);
  font-size:.875rem;font-weight:600;letter-spacing:.005em;
  text-decoration:none;cursor:pointer;
  transition:background .22s var(--ease),color .22s var(--ease),border-color .22s var(--ease);
}
.btn svg{flex:none;transition:transform .3s var(--ease)}
.btn:hover svg{transform:translateX(3px)}

.btn--primary{background:var(--navy-700);color:var(--white)}
.btn--primary:hover{background:var(--navy-800)}

.btn--accent{background:var(--cyan-500);color:var(--navy-950)}
.btn--accent:hover{background:var(--cyan-400)}

.btn--ghost{border-color:var(--gray-300);color:var(--ink);background:transparent}
.btn--ghost:hover{border-color:var(--navy-700);background:var(--navy-700);color:var(--white)}

.btn--ghost-light{border-color:rgba(255,255,255,.3);color:var(--white);background:transparent}
.btn--ghost-light:hover{background:var(--white);color:var(--navy-900);border-color:var(--white)}

.btn-row{display:flex;flex-wrap:wrap;gap:.75rem;margin-top:2rem}

.tlink{
  display:inline-flex;align-items:center;gap:.5rem;
  font-weight:600;font-size:.875rem;letter-spacing:.005em;text-decoration:none;
  color:var(--navy-700);
  padding-bottom:2px;
  border-bottom:1px solid transparent;
  transition:border-color .22s var(--ease),gap .22s var(--ease);
}
.tlink:hover{border-color:var(--cyan-500);gap:.8rem}
.tlink--light{color:var(--cyan-400)}
.tlink--light:hover{border-color:var(--cyan-400)}

/* White text on a dark/green card — plain .tlink defaults to navy-700,
   which is unreadable on a dark background. .tlink--light (cyan-400) is
   a different look (used as its own accent elsewhere); this is for a
   value-card CTA that needs to read as white with only the hover
   underline as a blue accent. */
.tlink--white{color:var(--white)}
.tlink--white:hover{border-color:var(--cyan-400)}

/* ==========================================================================
   Header
   ========================================================================== */
.topbar{
  background:var(--navy-950);color:rgba(255,255,255,.68);
  font-size:.75rem;letter-spacing:.02em;
}
.topbar .wrap{display:flex;align-items:center;justify-content:space-between;gap:1rem;min-height:38px}
.topbar a{text-decoration:none;transition:color .2s}
.topbar a:hover{color:var(--cyan-400)}
.topbar-left{display:flex;align-items:center;gap:.5rem}
.topbar-right{display:flex;align-items:center;gap:1.5rem}
@media (max-width:820px){.topbar-left{display:none}.topbar .wrap{justify-content:center}}

.site-header{
  position:sticky;top:0;z-index:100;
  background:rgba(255,255,255,.9);
  backdrop-filter:saturate(180%) blur(16px);
  -webkit-backdrop-filter:saturate(180%) blur(16px);
  border-bottom:1px solid var(--rule);
  transition:box-shadow .3s var(--ease);
}
.site-header.is-stuck{box-shadow:0 1px 20px rgba(7,23,38,.09)}
.nav{display:flex;align-items:center;justify-content:space-between;gap:2rem;min-height:76px}

/* ---------- Logo ----------
   GHG's own wide lockup, re-inked from the 1200x485 source (see
   assets/brand-source/). At 208px displayed that is ~5.8x pixel density, so it
   stays crisp on retina — the old 186px cap is gone. */
.logo{display:flex;align-items:center;text-decoration:none;flex:none}
.logo img{width:208px;height:auto;display:block}

/* ---------- Nav ---------- */
.nav-links{display:flex;align-items:center;gap:.15rem;list-style:none;margin:0;padding:0}
/* No position:relative here — mega panels must resolve against .site-header
   so they can span the full viewport width. */
.nav-links > li > a{
  display:block;padding:.6rem .8rem;
  font-size:.875rem;font-weight:500;letter-spacing:.005em;
  text-decoration:none;color:var(--ink-800);
  transition:color .2s;
  position:relative;
}
.nav-links > li > a::after{
  content:"";position:absolute;left:.8rem;right:.8rem;bottom:.15rem;
  height:1.5px;background:var(--cyan-500);
  transform:scaleX(0);transform-origin:left;
  transition:transform .28s var(--ease);
}
.nav-links > li > a:hover{color:var(--navy-700)}
.nav-links > li > a:hover::after{transform:scaleX(1)}
.nav-links > li > a[aria-current="page"]{color:var(--navy-700);font-weight:600}
.nav-links > li > a[aria-current="page"]::after{transform:scaleX(1)}

/* Section marker on a mega-menu parent (it is a section, not the page) */
.nav-links > li > a.is-section{color:var(--navy-700);font-weight:600}
.nav-links > li > a.is-section::after{transform:scaleX(1)}

.has-mega > a .caret{
  display:inline-block;width:.36em;height:.36em;margin-left:.45em;
  border-right:1.4px solid currentColor;border-bottom:1.4px solid currentColor;
  transform:rotate(45deg) translateY(-2px);opacity:.45;
  transition:transform .25s var(--ease),opacity .2s;
}
.has-mega:hover > a .caret,.has-mega:focus-within > a .caret{
  opacity:.9;transform:rotate(225deg) translateY(2px);
}
/* The parent li must not be a containing block, so the panel can resolve
   against .site-header and span the full viewport width. */
.has-mega{position:static}

/* ==========================================================================
   Mega-menu panel
   ========================================================================== */
.mega{
  position:absolute;top:100%;left:0;right:0;z-index:99;
  background:var(--navy-700);
  border-top:1px solid rgba(255,255,255,.14);
  box-shadow:0 26px 50px rgba(7,23,38,.28);
  padding-block:clamp(1.5rem,2.5vw,2.25rem);
  opacity:0;visibility:hidden;transform:translateY(-8px);
  transition:opacity .22s var(--ease),transform .22s var(--ease),visibility .22s;
}
.has-mega:hover > .mega,
.has-mega:focus-within > .mega{opacity:1;visibility:visible;transform:translateY(0)}
.mega[hidden]{display:none}

.mega-grid{
  display:grid;grid-template-columns:repeat(4,1fr);
  gap:.5rem;
}
.mega-item{
  display:flex;flex-direction:column;align-items:center;justify-content:flex-start;
  text-align:center;gap:.9rem;
  padding:1.4rem .9rem 1.2rem;
  text-decoration:none;color:var(--white);
  border:1px solid transparent;
  transition:background .22s var(--ease),border-color .22s var(--ease);
}
.mega-item:hover,.mega-item:focus-visible{
  background:rgba(255,255,255,.08);border-color:rgba(255,255,255,.2);
}
.mega-item svg{
  width:40px;height:40px;flex:none;
  color:var(--white);opacity:.92;
  transition:color .22s var(--ease),transform .3s var(--ease);
}
.mega-item:hover svg{color:var(--cyan-300);transform:translateY(-2px)}
.mega-item span{
  font-family:var(--font-body);
  font-size:.8125rem;font-weight:500;line-height:1.35;letter-spacing:.01em;
  max-width:16ch;
}

.nav-cta{display:flex;align-items:center;gap:.65rem;flex:none}
.nav-cta .btn{padding:.7rem 1.25rem;font-size:.8125rem}

.nav-toggle{
  display:none;width:42px;height:42px;border:1px solid var(--rule);
  background:transparent;border-radius:var(--r);cursor:pointer;
  align-items:center;justify-content:center;flex:none;
}
.nav-toggle span{
  display:block;width:17px;height:1.5px;background:var(--navy-900);position:relative;
  transition:background .2s;
}
.nav-toggle span::before,.nav-toggle span::after{
  content:"";position:absolute;left:0;width:17px;height:1.5px;background:var(--navy-900);
  transition:transform .28s var(--ease),top .28s var(--ease);
}
.nav-toggle span::before{top:-5.5px}
.nav-toggle span::after{top:5.5px}
.nav-toggle[aria-expanded="true"] span{background:transparent}
.nav-toggle[aria-expanded="true"] span::before{top:0;transform:rotate(45deg)}
.nav-toggle[aria-expanded="true"] span::after{top:0;transform:rotate(-45deg)}

@media (max-width:1120px){
  .nav-toggle{display:flex}
  /* Anchored to the header so it stays aligned whether the topbar is on
     screen or the header has stuck to the top. */
  .nav-links{
    position:absolute;top:100%;left:0;right:0;
    flex-direction:column;align-items:stretch;gap:0;
    background:var(--white);border-bottom:1px solid var(--rule);
    padding:.75rem var(--gutter) 1.5rem;
    max-height:75dvh;overflow-y:auto;overscroll-behavior:contain;
    transform:translateY(-10px);opacity:0;visibility:hidden;
    transition:opacity .24s var(--ease),transform .24s var(--ease),visibility .24s;
    box-shadow:0 22px 42px rgba(7,23,38,.11);
  }
  .nav-links.is-open{opacity:1;visibility:visible;transform:translateY(0)}
  .nav-links > li > a{padding:.9rem .25rem;border-bottom:1px solid var(--gray-100)}
  .nav-links > li > a::after{content:none}
  .has-mega > a .caret{display:none}
  .nav-cta .btn--ghost{display:none}

  /* Panel flows inline inside the open drawer. Icons kept, 2-up, on the navy
     card so it still reads as a distinct group rather than a flat link list. */
  .mega{
    position:static;opacity:1;visibility:inherit;transform:none;
    transition:none;
    box-shadow:none;border-top:0;
    background:var(--navy-700);
    padding:.4rem;margin:.5rem 0 1.1rem;
  }
  /* Inherit, never force visible: an explicit visibility:visible overrides
     the closed drawer's visibility:hidden, leaving the panels invisible but
     still tappable over the page. Also beats the desktop hover/focus rule.
     No transition: it would hold the panels tappable ~.2s past the drawer. */
  .has-mega:hover > .mega,
  .has-mega:focus-within > .mega{visibility:inherit}
  .mega .wrap{padding-inline:0;max-width:none}
  .mega-grid{grid-template-columns:repeat(2,1fr);gap:.25rem}
  .mega-item{padding:1rem .6rem;gap:.6rem}
  .mega-item svg{width:30px;height:30px}
  .mega-item span{font-size:.75rem;max-width:none}
}
/* The header carries mark + wordmark + CTA + toggle. Below ~560px that
   runs out of room, so the lockup tightens in two steps rather than
   overflowing the viewport. */
@media (max-width:560px){
  .nav{min-height:64px;gap:.75rem}
  .nav-cta{gap:.5rem}
  .nav-cta .btn{padding:.6rem .85rem;font-size:.6875rem}
  .logo img{width:156px}
  .nav-toggle{width:38px;height:38px}
}
@media (max-width:400px){
  .logo img{width:132px}
  .nav-cta .btn--primary{padding:.55rem .7rem;font-size:.625rem}
}

/* ==========================================================================
   Media — graceful placeholders until real photography lands
   ========================================================================== */
.media{position:relative;overflow:hidden;background:var(--navy-900);border-radius:var(--r)}
.media img{
  width:100%;height:100%;object-fit:cover;display:block;
  transition:transform .8s var(--ease);
}
.media--zoom:hover img{transform:scale(1.04)}
.media.is-missing{
  background:
    linear-gradient(135deg,rgba(30,187,240,.12),transparent 55%),
    linear-gradient(210deg,var(--navy-800),var(--navy-950) 72%);
}
.media.is-missing img{display:none}
.media.is-missing::after{
  content:attr(data-label);
  position:absolute;inset:0;display:flex;align-items:center;justify-content:center;
  padding:1.5rem;text-align:center;
  font-family:var(--font-body);font-size:.625rem;font-weight:600;
  letter-spacing:.18em;text-transform:uppercase;
  color:rgba(255,255,255,.36);
}
.media.is-missing::before{
  content:"";position:absolute;inset:0;opacity:.5;
  background-image:
    linear-gradient(rgba(255,255,255,.04) 1px,transparent 1px),
    linear-gradient(90deg,rgba(255,255,255,.04) 1px,transparent 1px);
  background-size:28px 28px;
}
.ratio-hero{aspect-ratio:16/9}
.ratio-wide{aspect-ratio:3/2}
.ratio-square{aspect-ratio:1/1}
.ratio-tall{aspect-ratio:4/5}
.ratio-portrait{aspect-ratio:3/4}

/* ==========================================================================
   Hero
   ========================================================================== */
.hero{position:relative;background:var(--navy-950);color:var(--white);overflow:hidden}
.hero-media{position:absolute;inset:0;z-index:0}
.hero-media img{width:100%;height:100%;object-fit:cover}
.hero-media.is-missing{
  background:
    radial-gradient(120% 90% at 78% 15%,rgba(30,187,240,.26),transparent 62%),
    linear-gradient(160deg,var(--navy-800) 0%,var(--navy-950) 64%);
}
.hero-media.is-missing img{display:none}
/* ---------- Hero overlay system ------------------------------------
   One shading recipe for every hero (homepage slider + all page heroes).
   Two layers on .hero-media::after:
     1. A horizontal blue-charcoal gradient: darkest behind the
        left-aligned copy, easing through the middle, nearly clear on
        the far side so the photograph stays vibrant.
     2. A faint top/bottom vignette for depth and to seat the header
        and the next section.
   Tuning knobs (set on .hero-media, inherited by ::after):
     --hero-shade-text  darkness behind the copy      (default .72)
     --hero-shade-mid   darkness through the middle    (default .40)
     --hero-shade-far   darkness on the far side       (default .08)
   Stop positions move per breakpoint because the copy runs wider on
   tablets and full-width on phones. Per-photo adjustments live at the
   end of this block, keyed to the image file. */
.hero-media{
  --hero-tint:9,27,45;
  --hero-shade-text:.72;--hero-shade-mid:.42;--hero-shade-far:.08;
  --hero-stop-text:36%;--hero-stop-mid:62%;--hero-stop-ease:80%;
  --hero-vignette-top:.14;--hero-vignette-bottom:.22;
}
.hero-media::after,
.page-hero .hero-media::after{
  content:"";position:absolute;inset:0;
  background:
    linear-gradient(180deg,
      rgba(var(--hero-tint),var(--hero-vignette-top)) 0%,
      rgba(var(--hero-tint),0) 24%,
      rgba(var(--hero-tint),0) 70%,
      rgba(var(--hero-tint),var(--hero-vignette-bottom)) 100%),
    linear-gradient(90deg,
      rgba(var(--hero-tint),var(--hero-shade-text)) 0%,
      rgba(var(--hero-tint),calc(var(--hero-shade-text) * .94)) var(--hero-stop-text),
      rgba(var(--hero-tint),var(--hero-shade-mid)) var(--hero-stop-mid),
      rgba(var(--hero-tint),calc((var(--hero-shade-mid) + var(--hero-shade-far)) / 2)) var(--hero-stop-ease),
      rgba(var(--hero-tint),var(--hero-shade-far)) 100%);
}
/* Tablet: the copy runs to ~70-90% of the width, so hold the dark zone longer. */
@media (max-width:1023px){
  .hero-media{
    --hero-shade-mid:.56;--hero-shade-far:.26;
    --hero-stop-text:40%;--hero-stop-mid:68%;--hero-stop-ease:86%;
  }
}
/* Phone: the copy spans the full width, so shade evenly enough to read
   everywhere, but lighter than the old flat scrim and still falling off
   to the right; the vignette carries more of the depth. */
@media (max-width:640px){
  .hero-media{
    --hero-shade-text:.70;--hero-shade-mid:.60;--hero-shade-far:.44;
    --hero-stop-text:45%;--hero-stop-mid:75%;--hero-stop-ease:90%;
    --hero-vignette-top:.10;--hero-vignette-bottom:.26;
  }
}
/* Per-photo adjustments. Bright subjects sitting directly behind the copy
   (white truck, pale pavers, hi-vis vests, sunlit glass) get a little more
   depth under the text only; the far side stays as light as the default. */
@media (min-width:1024px){
  .hero-media:has(img[src$="service-ipm.jpg"]),
  .hero-media:has(img[src$="service-hardscape.jpg"]),
  .hero-media:has(img[src$="hero-about.jpg"]),
  .hero-media:has(img[src$="triangle-team-huddle.jpg"]),
  .hero-media:has(img[src$="snow-skid-steer-plow.jpg"]){--hero-shade-text:.78;--hero-shade-mid:.54}
}
@media (min-width:641px) and (max-width:1023px){
  .hero-media:has(img[src$="market-office-wide.jpg"]){--hero-shade-text:.78;--hero-shade-mid:.64}
}
/* Services hero (Griffith Lakes entrance, 3:2). A full-bleed cover crop in
   the wide hero cuts off the flower beds and puts the sign behind the
   headline, so on desktop the photo sits full-height on the right (never
   scaled past its ratio) and fades into the navy under the copy, same
   treatment as the Arbor hero. Narrower screens keep cover, favouring the
   planting. */
.hero-media img[src$="hero-slide-griffith-lakes.jpg"]{object-position:62% 80%}
@media (min-width:1024px){
  .hero-media:has(img[src$="hero-slide-griffith-lakes.jpg"]){--hero-shade-mid:.18;--hero-shade-far:.04}
  .hero-media img[src$="hero-slide-griffith-lakes.jpg"]{
    position:absolute;top:0;right:0;height:100%;width:50%;
    object-fit:cover;object-position:80% 72%;
    -webkit-mask-image:linear-gradient(90deg,transparent 0,#000 22%);
    mask-image:linear-gradient(90deg,transparent 0,#000 22%);
  }
}
/* Snow & Ice: on phones the centred crop cuts the skid steer in half;
   shift left so the cab, wheels and front of the pusher stay in frame. */
@media (max-width:640px){
  .hero-media img[src$="snow-skid-steer-plow.jpg"]{object-position:35% 50%}
}
/* Arbor Services: a 4:3 shot of a worker in a lift bucket. Full-bleed cover
   crops off the bucket and parks the worker behind the headline, so on
   desktop the photo sits full-height on the right (never scaled past its
   ratio) and fades into the navy under the copy. Narrower screens keep
   cover, which already shows the full height, pinned toward the bucket. */
.hero-media img[src$="hero-arbor-services.jpg"]{object-position:0% 12%}
@media (min-width:1024px){
  .hero-media:has(img[src$="hero-arbor-services.jpg"]){--hero-shade-mid:.18;--hero-shade-far:.04}
  .hero-media img[src$="hero-arbor-services.jpg"]{
    position:absolute;top:0;right:0;height:100%;width:auto;min-width:58%;aspect-ratio:4/3;
    object-position:30% 18%;
    -webkit-mask-image:linear-gradient(90deg,transparent 0,#000 30%);
    mask-image:linear-gradient(90deg,transparent 0,#000 30%);
  }
}
.hero-inner{position:relative;z-index:1;padding-block:clamp(5.5rem,13vw,10rem);max-width:62rem}
.hero h1{color:var(--white)}
.hero h1 em{
  font-family:var(--font-serif);font-style:italic;font-weight:600;
  color:var(--cyan-400);letter-spacing:-.01em;
}
.hero .lede{margin-top:1.75rem;font-size:clamp(1.0625rem,1.8vw,1.375rem);color:rgba(255,255,255,.74)}
/* Homepage hero: the lead-in answers "something bigger" — same face, just
   semibold and full white against the softer supporting copy. */
.hero .lede strong{font-weight:600;color:var(--white)}
@media (max-width:820px){
  .hero-break{display:none}
}

/* ---------- Hero image rotation -----------------------------------
   5 authentic photos crossfade slowly behind the hero copy — a plain
   opacity crossfade only, no zoom/pan/Ken Burns. The gradient scrim
   (.hero-media::after) and the stat bar sit above this as separate
   layers, so this stack can be replaced with a single <video> later
   without touching anything else in the hero. No JS: the first image
   (marked .is-active in markup) is simply the hero photo.

   Per-image cropping: each <img> sets its own --hero-pos custom
   property inline (e.g. style="--hero-pos:50% 30%") instead of every
   photo defaulting to center center. Add --hero-pos-mobile the same
   way on any image that needs a different crop under 640px. */
.hero-media.is-rotating img{
  position:absolute;inset:0;opacity:0;
  object-position:var(--hero-pos,50% 50%);
  transition:opacity 1.25s ease;
}
.hero-media.is-rotating img.is-active{opacity:1}
@media (max-width:640px){
  .hero-media.is-rotating img{object-position:var(--hero-pos-mobile,var(--hero-pos,50% 50%))}
}
@media (prefers-reduced-motion:reduce){
  .hero-media.is-rotating img{transition:none}
}

.page-hero{position:relative;background:var(--navy-950);color:var(--white);overflow:hidden}
.page-hero-inner{position:relative;z-index:1;padding-block:clamp(3.5rem,8vw,6rem);max-width:56rem}
.page-hero h1{color:var(--white)}
/* Who We Serve: on wide monitors the hero was a shallow strip showing mostly
   the campus parking lots. From 1440px it grows with the viewport (capped),
   copy stays vertically centred in its usual column, and the crop favours
   the pond and lawns in the lower half of the photo. */
@media (min-width:1440px){
  .page-hero--wws{display:flex;align-items:center;min-height:min(40vw,820px)}
  .page-hero--wws .hero-media img{object-position:50% 78%}
}
.page-hero .lede{margin-top:1.5rem;color:rgba(255,255,255,.74)}

.crumbs{
  display:flex;flex-wrap:wrap;align-items:center;gap:.5rem;
  font-size:.75rem;letter-spacing:.03em;color:rgba(255,255,255,.5);margin-bottom:1.5rem;
}
.crumbs a{text-decoration:none;transition:color .2s}
.crumbs a:hover{color:var(--cyan-400)}
.crumbs span{opacity:.45}

/* ==========================================================================
   Stat bar
   ========================================================================== */
.statbar{
  border-top:1px solid rgba(255,255,255,.16);
  position:relative;z-index:1;
  background:rgba(7,18,30,.62);
  backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);
}
.statbar-grid{display:grid;grid-template-columns:repeat(4,1fr)}
.stat{padding:2.25rem 1.5rem 2.25rem 0;border-right:1px solid rgba(255,255,255,.14)}
.stat:last-child{border-right:0}
.stat:not(:first-child){padding-left:1.75rem}
.stat-num{
  font-family:var(--font-display);font-weight:700;
  font-size:clamp(2rem,3.6vw,3rem);letter-spacing:-.05em;line-height:1;
  color:var(--white);
}
.stat-num .unit{color:var(--cyan-400)}
.stat-title{
  margin-top:.75rem;font-family:var(--font-body);font-size:.75rem;font-weight:700;
  color:var(--white);letter-spacing:.14em;text-transform:uppercase;
}
.stat-label{
  margin-top:.35rem;font-size:.75rem;line-height:1.45;
  color:rgba(255,255,255,.6);letter-spacing:.015em;max-width:30ch;
}
@media (max-width:820px){
  .statbar-grid{grid-template-columns:repeat(2,1fr)}
  .stat{border-bottom:1px solid rgba(255,255,255,.14);padding-block:1.75rem}
  .stat:nth-child(2n){border-right:0}
  .stat:nth-child(2n+1){padding-left:0}
  .stat:nth-child(2n){padding-left:1.5rem}
  .stat:nth-last-child(-n+2){border-bottom:0}
}
@media (max-width:480px){
  .statbar-grid{grid-template-columns:1fr}
  .stat{border-right:0;padding-left:0!important}
  .stat:nth-last-child(2){border-bottom:1px solid rgba(255,255,255,.14)}
}
.statbar--light{
  border-top-color:var(--rule);
  background:transparent;backdrop-filter:none;-webkit-backdrop-filter:none;
}
.statbar--light .stat{border-right-color:var(--rule);border-bottom-color:var(--rule)}
.statbar--light .stat-num{color:var(--navy-800)}
.statbar--light .stat-num .unit{color:var(--cyan-600)}
.statbar--light .stat-title{color:var(--navy-800)}

/* Homepage hero stat bar only — three equal columns, more generous
   spacing than the shared four-stat layout. Scoped to this modifier (and
   written as a compound selector so it wins over the shared 820px/480px
   rules regardless of source order) so the four-stat bars on about.html /
   market pages — same base .statbar/.statbar-grid/.stat
   classes — are unaffected. */
.statbar-grid.statbar-grid--3{grid-template-columns:repeat(3,1fr)}
.statbar-grid--3 .stat{padding-block:2.75rem}
.statbar-grid--3 .stat:not(:first-child){padding-left:2.25rem}
@media (max-width:820px){
  .statbar-grid.statbar-grid--3{grid-template-columns:repeat(3,1fr)}
}
@media (max-width:640px){
  .statbar-grid.statbar-grid--3{grid-template-columns:1fr}
  .statbar-grid--3 .stat{border-right:0;border-bottom:1px solid rgba(255,255,255,.14);padding:1.75rem 0}
  .statbar-grid--3 .stat:last-child{border-bottom:0}
}
.statbar--light .stat-label{color:var(--ink-soft)}

/* ==========================================================================
   Service cards
   ========================================================================== */
.svc-card{
  position:relative;display:flex;flex-direction:column;
  background:var(--white);border:1px solid var(--rule);border-radius:var(--r);
  overflow:hidden;text-decoration:none;color:inherit;
  transition:border-color .3s var(--ease),box-shadow .3s var(--ease);
}
.svc-card::after{
  content:"";position:absolute;top:0;left:0;right:0;height:2px;
  background:var(--cyan-500);transform:scaleX(0);transform-origin:left;
  transition:transform .4s var(--ease);z-index:2;
}
.svc-card:hover{border-color:var(--navy-600);box-shadow:0 22px 50px rgba(7,23,38,.12)}
.svc-card:hover::after{transform:scaleX(1)}
.svc-card .media{border-radius:0}
.svc-card-body{padding:clamp(1.5rem,2.6vw,2.25rem);display:flex;flex-direction:column;flex:1}
.svc-card h3{margin-bottom:.85rem}
.svc-card p{color:var(--ink-soft);font-size:.9375rem;margin-bottom:1.5rem}
.svc-card ul{list-style:none;padding:0;margin:0 0 1.75rem;display:flex;flex-wrap:wrap;gap:.4rem}
.svc-card ul li{
  font-size:.6875rem;font-weight:600;letter-spacing:.06em;text-transform:uppercase;
  padding:.4rem .7rem;border:1px solid var(--gray-200);
  color:var(--navy-700);background:var(--gray-50);
}
.svc-card .tlink{margin-top:auto;align-self:flex-start}

/* ==========================================================================
   Market tiles
   ========================================================================== */
.market{
  position:relative;display:block;text-decoration:none;color:var(--white);
  border-radius:var(--r);overflow:hidden;
}
.market .media{border-radius:0;aspect-ratio:4/5}
.market::after{
  content:"";position:absolute;inset:0;z-index:1;
  background:linear-gradient(to top,rgba(7,23,38,.92) 0%,rgba(7,23,38,.34) 55%,rgba(7,23,38,.08) 100%);
  transition:background .35s var(--ease);
}
.market:hover::after{
  background:linear-gradient(to top,rgba(16,47,79,.95) 0%,rgba(23,64,110,.55) 60%,rgba(7,23,38,.14) 100%);
}
.market-label{position:absolute;left:0;right:0;bottom:0;z-index:2;padding:1.5rem 1.35rem}
.market-label h4{color:var(--white);font-size:1.0625rem;position:relative;padding-bottom:.65rem}
.market-label h4::after{
  content:"";position:absolute;left:0;bottom:0;width:1.75rem;height:2px;
  background:var(--cyan-500);transition:width .35s var(--ease);
}
.market:hover .market-label h4::after{width:3.25rem}
.market-label p{
  font-size:.8125rem;color:rgba(255,255,255,.7);margin:.35rem 0 0;line-height:1.45;
  opacity:0;max-height:0;overflow:hidden;
  transition:opacity .35s var(--ease),max-height .35s var(--ease);
}
.market:hover .market-label p,.market:focus-within .market-label p{opacity:1;max-height:6rem}

/* ==========================================================================
   Capability cards
   ========================================================================== */
.cap{
  position:relative;
  padding:clamp(1.5rem,2.4vw,2rem);
  background:var(--white);border:1px solid var(--rule);border-radius:var(--r);
  transition:border-color .3s var(--ease),box-shadow .3s var(--ease);
}
.cap:hover{border-color:var(--navy-600);box-shadow:0 16px 38px rgba(7,23,38,.09)}
.cap-icon{
  width:42px;height:42px;margin-bottom:1.35rem;
  display:flex;align-items:center;justify-content:center;
  background:var(--navy-700);color:var(--cyan-400);
}
.cap-icon svg{width:21px;height:21px}
.cap h3{font-size:1.1875rem;margin-bottom:.85rem}
.cap ul{list-style:none;padding:0;margin:1rem 0 0}
.cap ul li{
  position:relative;padding-left:1.15rem;margin-bottom:.5rem;
  font-size:.9375rem;color:var(--ink-soft);line-height:1.5;
}
.cap ul li:last-child{margin-bottom:0}
.cap ul li::before{
  content:"";position:absolute;left:0;top:.68em;
  width:5px;height:5px;background:var(--cyan-500);
}

/* Whole-card-clickable variant of .cap — the "Our Services" grid on
   services.html. Same icon chip and card shell, no bullet list: one
   description line, then a subtle arrow that shifts right on hover. */
a.cap{display:flex;flex-direction:column;text-decoration:none;color:inherit}
.cap-desc{color:var(--ink-soft);font-size:.9375rem;line-height:1.5;margin:0;flex:1}
.cap-arrow{
  display:block;margin-top:1.35rem;color:var(--gray-300);
  transition:transform .25s var(--ease),color .25s var(--ease);
}
a.cap:hover .cap-arrow{transform:translateX(4px);color:var(--cyan-500)}

/* Plain (non-link) capability chips — services.html "Landscape
   Development" pillar section, deliberately not clickable links so it
   reads differently from the six .tlink rows in the Management pillar
   beside it. */
.chip-list{display:flex;flex-wrap:wrap;gap:.5rem;list-style:none;padding:0;margin:0}
.chip-list li{
  font-size:.6875rem;font-weight:600;letter-spacing:.06em;text-transform:uppercase;
  padding:.5rem .85rem;border:1px solid var(--gray-200);
  color:var(--navy-700);background:var(--gray-50);
}

/* Scannable capability list — individual service landing pages
   (landscape-maintenance.html etc., see tools/service-page.js). Two-up,
   one line each, no paragraphs, so 6-8 items read in a glance rather
   than as another card grid. */
.check-list{
  display:grid;grid-template-columns:repeat(2,1fr);gap:.85rem 2.5rem;
  list-style:none;padding:0;margin:0;
}
.check-list li{
  position:relative;padding-left:1.5rem;
  font-size:1rem;font-weight:500;color:var(--ink);line-height:1.4;
}
.check-list li::before{
  content:"";position:absolute;left:0;top:.5em;
  width:8px;height:8px;background:var(--cyan-500);
}
.section--dark .check-list li,.section--green .check-list li{color:var(--white)}
@media (max-width:640px){
  .check-list{grid-template-columns:1fr}
}

/* ==========================================================================
   Split
   ========================================================================== */
.split{display:grid;grid-template-columns:1fr 1fr;gap:clamp(2rem,5vw,4.5rem);align-items:center}
.split--reverse .split-media{order:2}
@media (max-width:900px){
  .split{grid-template-columns:1fr;gap:2.5rem}
  .split--reverse .split-media{order:0}
}

/* ==========================================================================
   Testimonials
   ========================================================================== */
.quote-card{
  display:flex;flex-direction:column;
  padding:clamp(1.75rem,3vw,2.5rem);
  background:var(--white);border:1px solid var(--rule);border-radius:var(--r);
  border-top:2px solid var(--navy-700);
  transition:border-color .3s var(--ease),box-shadow .3s var(--ease);
}
.quote-card:hover{box-shadow:0 18px 42px rgba(7,23,38,.09);border-top-color:var(--cyan-500)}
.quote-mark{
  font-family:var(--font-serif);font-size:3.5rem;line-height:.55;
  color:var(--cyan-500);margin-bottom:1.15rem;
}
.quote-card blockquote{
  margin:0 0 1.75rem;font-size:1.0625rem;line-height:1.6;
  color:var(--ink-800);flex:1;text-wrap:pretty;
}
.quote-attr{border-top:1px solid var(--rule);padding-top:1.15rem}
.quote-attr .name{font-weight:600;font-size:.9375rem;display:block}
.quote-attr .role{
  font-size:.6875rem;color:var(--ink-soft);margin-top:.25rem;display:block;
  letter-spacing:.1em;text-transform:uppercase;
}

.section--dark .quote-card,.section--green .quote-card{
  background:rgba(255,255,255,.04);border-color:rgba(255,255,255,.13);
  border-top-color:var(--cyan-500);
}
.section--dark .quote-card:hover,.section--green .quote-card:hover{
  box-shadow:none;background:rgba(255,255,255,.07);
}
.section--dark .quote-card blockquote,.section--green .quote-card blockquote{color:rgba(255,255,255,.9)}
.section--dark .quote-attr,.section--green .quote-attr{border-top-color:rgba(255,255,255,.13)}
.section--dark .quote-attr .role,.section--green .quote-attr .role{color:rgba(255,255,255,.55)}

/* ==========================================================================
   Testimonial cards — homepage "What Our Customers Say" and the market
   pages' "What … Customers Are Saying". Deliberately
   a separate component from .quote-card (used elsewhere for testimonials
   in dark/green sections and on the vertical landing pages) so this
   redesign doesn't touch those. 3x2 on desktop, 2-up on tablet, a native
   scroll-snap carousel on mobile — no JS required for the swipe itself;
   js/site.js only adds the optional pagination dots on top.
   ========================================================================== */
.testimonial-grid{
  display:grid;grid-template-columns:repeat(3,1fr);
  gap:clamp(1.25rem,2vw,1.75rem);
}
.testimonial-card{
  display:flex;flex-direction:column;height:100%;
  background:var(--white);border:1px solid var(--rule);border-radius:10px;
  padding:clamp(1.5rem,2.4vw,2rem);
  box-shadow:0 2px 14px rgba(7,23,38,.05);
  transition:box-shadow .25s var(--ease),border-color .25s var(--ease);
}
.testimonial-card:hover{box-shadow:0 10px 28px rgba(7,23,38,.08);border-color:var(--gray-300)}
.testimonial-stars{display:flex;gap:.2rem;color:var(--cyan-500);margin-bottom:1.1rem}
.testimonial-stars svg{width:14px;height:14px;flex:none}
.testimonial-card blockquote{
  margin:0 0 1.5rem;font-size:.9375rem;line-height:1.65;color:var(--ink-800);
  flex:1;text-wrap:pretty;
}
.testimonial-attr{margin-top:auto}
.testimonial-attr .name{display:block;font-weight:700;font-size:.9375rem;color:var(--ink)}
.testimonial-attr .role{display:block;margin-top:.25rem;font-size:.8125rem;line-height:1.4;color:var(--ink-soft)}

.testimonial-dots{display:none;justify-content:center;gap:.6rem;margin-top:1.75rem}
.testimonial-dot{
  width:32px;height:32px;padding:0;border:0;background:none;cursor:pointer;
  display:flex;align-items:center;justify-content:center;
}
.testimonial-dot::before{
  content:"";width:8px;height:8px;border-radius:50%;background:var(--gray-300);
  transition:background .2s,transform .2s;
}
.testimonial-dot.is-active::before{background:var(--navy-700);transform:scale(1.25)}

@media (max-width:900px){
  .testimonial-grid{grid-template-columns:repeat(2,1fr)}
}
@media (max-width:640px){
  .testimonial-grid{
    display:flex;grid-template-columns:none;overflow-x:auto;
    scroll-snap-type:x mandatory;-webkit-overflow-scrolling:touch;
    gap:1rem;margin:0 -1.25rem;padding:0 1.25rem 4px;
    scrollbar-width:none;
  }
  .testimonial-grid::-webkit-scrollbar{display:none}
  .testimonial-card{flex:0 0 86%;scroll-snap-align:center}
  .testimonial-dots{display:flex}
}
/* A single testimonial (market pages): one centered card at every width,
   no carousel. */
.testimonial-grid--solo,
.testimonial-grid.testimonial-grid--solo{
  display:grid;grid-template-columns:minmax(0,36rem);justify-content:center;
  overflow:visible;margin:0;padding:0;
}
/* Two testimonials: a balanced centred pair. Three (--stack): the normal
   three-up row. Neither becomes a carousel; both stack on phones, and a
   three-card row stacks at tablet width rather than leaving a 2 + 1 orphan. */
.testimonial-grid.testimonial-grid--pair{grid-template-columns:repeat(2,minmax(0,26rem));justify-content:center}
/* --feature: two short reviews side by side, the long one full width
   beneath them, so no card carries a block of empty space. */
.testimonial-grid.testimonial-grid--feature{grid-template-columns:repeat(2,minmax(0,1fr));max-width:60rem;margin-inline:auto}
.testimonial-grid--feature > .testimonial-card:last-of-type{grid-column:1 / -1}
@media (max-width:900px){
  .testimonial-grid.testimonial-grid--stack,
  .testimonial-grid.testimonial-grid--feature{grid-template-columns:minmax(0,36rem);justify-content:center}
  .testimonial-grid--feature > .testimonial-card:last-of-type{grid-column:auto}
}
@media (max-width:640px){
  .testimonial-grid.testimonial-grid--pair,
  .testimonial-grid.testimonial-grid--feature,
  .testimonial-grid.testimonial-grid--stack{
    display:grid;grid-template-columns:minmax(0,1fr);overflow:visible;margin:0;padding:0;
  }
  .testimonial-grid--pair .testimonial-card,
  .testimonial-grid--feature .testimonial-card,
  .testimonial-grid--stack .testimonial-card{flex:none}
}

/* ==========================================================================
   Difference split — a dominant local-leadership image on one side (text
   overlaid, market-label style), an understated list of Granite Hills
   capabilities on the other (reuses .step's hairline+accent, not boxed
   cards), closed by one full-width statement. Market-specific copy lives
   in tools/market-page.js.
   ========================================================================== */
.diff-split{display:grid;grid-template-columns:1fr 1.05fr;border-radius:var(--r);overflow:hidden}

.diff-media{position:relative;min-height:460px}
.diff-media .media{position:absolute;inset:0;height:100%;border-radius:0}
.diff-media-label{
  position:absolute;left:0;right:0;bottom:0;z-index:2;
  padding:clamp(1.75rem,4vw,3rem);
  background:linear-gradient(180deg,transparent,rgba(7,23,38,.94) 70%);
  color:var(--white);
}
.diff-media-label p{margin:.85rem 0 0;font-size:1rem;line-height:1.55;color:rgba(255,255,255,.88);max-width:26rem}

.diff-panel{
  background:var(--bg-alt);
  padding:clamp(2.5rem,5vw,4rem) clamp(2rem,4.5vw,3.5rem);
  display:flex;flex-direction:column;gap:clamp(1.75rem,3vw,2.25rem);
  justify-content:center;
}
.diff-panel .step{padding-top:1.75rem}
.diff-panel .step h3{font-size:1.0625rem}
.diff-panel .step p{font-size:.875rem}

.diff-kicker{
  font-size:.6875rem;font-weight:700;letter-spacing:.12em;text-transform:uppercase;
  color:var(--cyan-400);
}

.diff-statement{
  margin:clamp(3rem,6vw,4.5rem) auto 0;padding-top:clamp(2rem,4vw,3rem);
  border-top:1px solid var(--rule);max-width:50rem;text-align:center;
  font-family:var(--font-serif);font-style:italic;font-weight:500;
  font-size:clamp(1.25rem,2.2vw,1.625rem);line-height:1.45;color:var(--navy-800);
}
/* Careers closing line: sans, medium, wide enough to sit on one line at
   desktop; balance keeps any wrap from stranding a single word. */
.diff-statement--sans{
  font-family:var(--font-display);font-style:normal;font-weight:500;
  letter-spacing:-.015em;max-width:72rem;text-wrap:balance;
}

@media (max-width:800px){
  .diff-split{grid-template-columns:1fr}
  .diff-media{min-height:340px}
}
/* Market pages only (.diff-split--market): Local Leadership | Backed by
   Granite Hills. services.html uses the base .diff-split and is unaffected.
   Both halves open with the same small uppercase label (cyan on the navy
   photo side, navy on the light side) so the pairing reads at a glance.
   The photo side sits on navy so a missing team photo still reads as a
   deliberate panel; swap photos by replacing the <img> in the market page.
   On phones the photo gets its own 4:3 frame and the leadership copy moves
   into a navy band beneath it, so the photo is never a cropped strip. */
.diff-split--market{grid-template-columns:1fr 1fr}
.diff-split--market .diff-media{min-height:520px;background:var(--navy-900)}
.diff-split--market .diff-media-label{
  padding:clamp(2rem,4vw,3rem);
  background:linear-gradient(180deg,rgba(7,23,38,0),rgba(7,23,38,.9) 55%);
}
.diff-split--market .diff-kicker{margin:0;display:flex;align-items:center;gap:.75rem;font-size:.75rem;letter-spacing:.14em}
.diff-split--market .diff-kicker::before{content:"";width:1.75rem;height:1px;background:var(--cyan-500)}
.diff-split--market .diff-media-label p:not(.diff-kicker){margin-top:.9rem;font-size:clamp(1.0625rem,1.4vw,1.1875rem);line-height:1.55;color:var(--white);max-width:28rem}
.diff-split--market .diff-panel{gap:0;padding:clamp(2.5rem,4.5vw,3.75rem) clamp(2rem,4.5vw,3.75rem)}
.diff-split--market .diff-panel .eyebrow{margin-bottom:clamp(1.5rem,2.5vw,2rem);font-size:.75rem;letter-spacing:.14em;color:var(--navy-800)}
.diff-split--market .diff-panel .step{padding-block:1.35rem 1.4rem}
.diff-split--market .diff-panel .step:last-child{padding-bottom:0}
.diff-split--market .diff-panel .step h3{font-size:clamp(1.125rem,1.5vw,1.25rem);letter-spacing:-.015em;margin-bottom:.45rem}
.diff-split--market .diff-panel .step p{font-size:.9375rem;line-height:1.55}
@media (max-width:800px){
  .diff-split--market{grid-template-columns:1fr}
  .diff-split--market .diff-media{min-height:0;display:flex;flex-direction:column}
  .diff-split--market .diff-media .media{position:relative;inset:auto;height:auto;aspect-ratio:4/3}
  .diff-split--market .diff-media-label{position:static;background:var(--navy-900);padding:1.75rem clamp(1.25rem,5vw,2rem) 2rem}
}
/* Wide group photos (Greensboro): at every width the photo keeps its own
   proportions at the top of the navy panel and the copy sits beneath it,
   so nobody at either end of the group is cropped off. */
.diff-split--photo-top .diff-media{min-height:0;display:flex;flex-direction:column}
.diff-split--photo-top .diff-media .media{position:relative;inset:auto;height:auto;aspect-ratio:1269/931}
.diff-split--photo-top .diff-media .media img{object-position:50% 50%}
.diff-split--photo-top .diff-media-label{position:static;flex:1;background:var(--navy-900)}

/* ==========================================================================
   Branch map
   Map on one side, the six branch cards on the other; hovering or selecting
   either half lights up its twin. Markup is generated — see tools/build.js
   branchMap() — and geometry comes from tools/branch-map.json.

   Pins are plain links to their card, so the whole thing still works with JS
   off; js/site.js §9 only upgrades them to highlight in place.
   ========================================================================== */
.bmap{
  display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);
  gap:clamp(2rem,4vw,4rem);align-items:center;
}

.bmap-canvas{position:relative}
.bmap-shape{
  display:block;width:100%;height:auto;overflow:visible;
  filter:drop-shadow(0 14px 28px rgba(23,64,110,.16));
}
.bmap-state{
  fill:var(--navy-700);stroke:rgba(214,224,238,.42);stroke-width:1px;vector-effect:non-scaling-stroke;
  stroke-linejoin:round;transition:fill .35s var(--ease);
}
.bmap.is-engaged .bmap-state{fill:var(--navy-800)}

/* Pin. The 44px box is the tap target; the visible mark is .bmap-dot.
   --x/--y are percentages written inline by the generator. */
.bmap-pin{
  position:absolute;left:var(--x);top:var(--y);
  transform:translate(-50%,-50%);
  width:44px;height:44px;z-index:2;
  display:flex;align-items:center;justify-content:center;
  text-decoration:none;
}
.bmap-dot{
  --map-pin-icon:url("../assets/ghg-map-pin-white.png");
  position:relative;width:36px;height:36px;background:transparent;
  box-shadow:none;overflow:visible;
  transition:transform .25s var(--ease),background .25s var(--ease);
}
.bmap-icon{
  position:absolute;inset:0;
  background-image:var(--map-pin-icon);
  background-size:contain;background-repeat:no-repeat;background-position:center;
  filter:drop-shadow(0 0 1.5px rgba(7,23,38,.55)) drop-shadow(0 3px 6px rgba(7,23,38,.2));
}
.bmap-pin--hq .bmap-dot{width:42px;height:42px}
.bmap-pin:hover .bmap-dot,
.bmap-pin:focus-visible .bmap-dot,
.bmap-pin.is-active .bmap-dot{transform:scale(1.22)}

/* Only the pin you actually clicked pulses — hovering down the card list
   would otherwise set off six of them in a row. */
.bmap-pin.is-picked .bmap-dot::before{
  content:"";position:absolute;inset:-3px;border:2px solid var(--cyan-500);
  animation:bmap-ping 1.6s var(--ease) infinite;
}
@keyframes bmap-ping{
  from{transform:scale(1);opacity:.85}
  to{transform:scale(2.6);opacity:0}
}

.bmap-tip{
  position:absolute;top:50%;white-space:nowrap;
  background:var(--navy-900);color:var(--white);
  font-size:.75rem;font-weight:600;line-height:1.2;
  padding:.4rem .625rem;
  opacity:0;pointer-events:none;
  transition:opacity .2s var(--ease),transform .2s var(--ease);
}
.bmap-pin[data-side="right"] .bmap-tip{left:calc(50% + 15px);transform:translate(-6px,-50%)}
.bmap-pin[data-side="left"] .bmap-tip{right:calc(50% + 15px);transform:translate(6px,-50%)}
.bmap-pin:hover .bmap-tip,
.bmap-pin:focus-visible .bmap-tip,
.bmap-pin.is-active .bmap-tip{opacity:1;transform:translate(0,-50%)}

/* Card list — the branch grid these three pages used to carry, stacked into
   one column so it sits alongside the map. */
.bmap-list{
  display:grid;gap:1px;background:var(--rule);border:1px solid var(--rule);
}
.bmap-card{
  background:var(--white);padding:1.1rem clamp(1.1rem,1.8vw,1.5rem);
  border-left:2px solid transparent;
  scroll-margin-top:7.5rem;
  transition:background .3s var(--ease),border-left-color .3s var(--ease);
}
.bmap-card:hover,.bmap-card.is-active,.bmap-card:target{
  background:var(--gray-50);border-left-color:var(--cyan-500);
}
.bmap-region{
  font-size:.625rem;font-weight:600;letter-spacing:.18em;text-transform:uppercase;
  color:var(--navy-600);margin-bottom:.7rem;
}
.bmap-card h4{font-size:1.0625rem;margin-bottom:.4rem}
.bmap-card p{font-size:.875rem;color:var(--ink-soft);margin:0}
.bmap-card-tel{margin-top:.65rem}

/* Compact card — homepage "Where We Work" only (build.js mapCard's
   `compact` branch). The whole card is now a real <a>, so it needs its
   own display/link-reset; everything else (background, hover, border,
   scroll-margin) is inherited from .bmap-card above, untouched for the
   other pages that still render the original <article> version. */
.bmap-card-lite{display:block;text-decoration:none;color:inherit}
.bmap-card-lite .tlink{margin-top:.6rem}

@media (max-width:1000px){
  .bmap{grid-template-columns:1fr;gap:2.5rem}
  .bmap-figure{max-width:440px;margin-inline:auto;width:100%}
}
/* Phone: the map is ~320px across, so 44px tap targets start colliding and a
   side-set label runs off the screen for the westernmost pins. Tighten the
   target and stand the label up over the pin instead. */
@media (max-width:700px){
  .bmap-pin{width:34px;height:34px}
  .bmap-tip{font-size:.6875rem;padding:.3rem .5rem}
  .bmap-pin[data-side] .bmap-tip{
    left:50%;right:auto;top:auto;bottom:calc(50% + 13px);
    transform:translate(-50%,6px);
  }
  .bmap-pin:hover .bmap-tip,
  .bmap-pin:focus-visible .bmap-tip,
  .bmap-pin.is-active .bmap-tip{transform:translate(-50%,0)}
}
@media (prefers-reduced-motion:reduce){
  .bmap-pin.is-picked .bmap-dot::before{animation:none;opacity:0}
  .bmap-dot,.bmap-tip,.bmap-state,.bmap-card{transition:none}
}

/* ==========================================================================
   Steps
   ========================================================================== */
.step{position:relative;padding-top:2.25rem}
.step::before{content:"";position:absolute;top:0;left:0;right:0;height:1px;background:var(--gray-200)}
.step::after{content:"";position:absolute;top:0;left:0;width:2.5rem;height:1px;background:var(--cyan-500)}
.step-num{
  font-family:var(--font-body);font-size:.625rem;font-weight:600;
  letter-spacing:.2em;color:var(--navy-600);margin-bottom:.85rem;
}
.step h3{font-size:1.1875rem;margin-bottom:.7rem}
.step p{font-size:.9375rem;color:var(--ink-soft);margin:0}
.section--dark .step::before,.section--green .step::before{background:rgba(255,255,255,.18)}
.section--dark .step::after,.section--green .step::after{background:var(--cyan-500)}
.section--dark .step p,.section--green .step p{color:rgba(255,255,255,.66)}
.section--dark .step-num,.section--green .step-num{color:var(--cyan-400)}

/* ==========================================================================
   Partnership history — "Built Through Partnership" on partnerships.html.
   A stacked list, not a card grid: date + a small quiet logo in a narrow
   left column, the story in a wide right column, with the TODAY line
   carrying more visual weight than the logo — that's the point of the
   section (see CLAUDE.md "Partnership history"). Needs a light section
   background; the legacy logos are full-color on transparent PNGs, not
   white-outline treated, so they only read correctly on light.
   ========================================================================== */
.history-list{max-width:54rem;margin-inline:auto}
.history-item{
  display:grid;grid-template-columns:13.5rem 1fr;gap:clamp(1.5rem,3vw,2.5rem);
  padding-block:clamp(2rem,4vw,2.75rem);border-bottom:1px solid var(--rule);
}
.history-item:last-child{border-bottom:0}
.history-date{
  display:block;font-size:.6875rem;font-weight:700;letter-spacing:.1em;
  text-transform:uppercase;color:var(--navy-600);margin-bottom:.9rem;
}
/* Logos are trimmed to their ink, so one box fits every shape: very wide
   wordmarks hit the width cap, taller marks the height cap. */
.history-logo{display:block;max-height:76px;max-width:100%;width:auto;height:auto}
.history-item h3{font-size:1.1875rem;margin-bottom:.15rem}
.history-market{color:var(--ink-soft);font-weight:500}
.history-item p.history-story{color:var(--ink-soft);font-size:.9375rem;margin:.6rem 0 1.15rem}
.history-today{display:flex;align-items:center;gap:.9rem}
.history-avatar{
  width:56px;height:56px;border-radius:50%;object-fit:cover;object-position:50% 22%;flex:none;
  box-shadow:0 0 0 2px var(--white),0 0 0 3px var(--rule);
}
/* Two people in one entry: each photo carries its own name. */
.history-people{display:flex;gap:.9rem;flex:none}
.history-person{margin:0;display:flex;flex-direction:column;align-items:center;gap:.4rem}
.history-person figcaption{font-size:.75rem;font-weight:600;color:var(--navy-800);line-height:1.2;white-space:nowrap}
.history-today span{font-size:.9375rem;font-weight:600;color:var(--navy-800);line-height:1.4}
.history-today span strong{color:var(--cyan-600)}
@media (max-width:640px){
  .history-item{grid-template-columns:1fr;gap:.6rem}
  .history-logo{max-width:15rem;max-height:72px;margin-bottom:.6rem}
  .history-today:has(.history-people){flex-wrap:wrap;row-gap:.75rem}
}

/* Proof numeral — "People Are Our Strongest Proof" on partnerships.html.
   An asymmetric split, not a centered stat block: the "4" dominates the
   left column at real scale, the two supporting facts sit in a narrower
   right column with a quiet cyan rule marking each one (the same accent
   language as .value, without the card/box treatment). */
.proof-split{
  display:grid;grid-template-columns:minmax(0,.85fr) minmax(0,1.15fr);
  gap:clamp(2.5rem,6vw,5rem);align-items:start;
  max-width:56rem;margin-inline:auto;
}
.proof-num{
  font-family:var(--font-display);font-weight:700;letter-spacing:-.045em;
  line-height:.9;font-size:clamp(6rem,14vw,9.5rem);color:var(--navy-800);
}
.proof-label{
  margin-top:.35rem;font-size:.8125rem;font-weight:700;letter-spacing:.1em;
  text-transform:uppercase;color:var(--navy-700);
}
.proof-caption{margin-top:.85rem;color:var(--ink-soft);font-size:.9375rem;max-width:24ch}
.proof-facts{display:flex;flex-direction:column;gap:1.5rem;padding-top:clamp(1.5rem,3vw,2.5rem)}
.proof-fact{
  padding-left:1.15rem;border-left:2px solid var(--cyan-500);
  font-size:1.0625rem;line-height:1.55;color:var(--ink-800);
}
.proof-closing{
  margin-top:clamp(2.5rem,5vw,3.5rem);max-width:36rem;margin-inline:auto;
  text-align:center;color:var(--ink-700);
  font-family:var(--font-serif);font-style:italic;font-weight:500;
  font-size:clamp(1.0625rem,1.6vw,1.25rem);
}
@media (max-width:720px){
  .proof-split{grid-template-columns:1fr;gap:2rem}
  .proof-facts{padding-top:0}
}

/* Owner paths — "What Comes Next" on partnerships.html. Deliberately not
   .value cards: three calm columns divided by a hairline rule instead of
   boxes, so all three read as equally weighted options rather than
   competing tiles. */
.paths{display:grid;grid-template-columns:repeat(3,1fr);gap:0}
.path{padding-inline:clamp(1.5rem,3vw,2.5rem);border-left:1px solid var(--rule)}
.path:first-child{border-left:0;padding-left:0}
.path:last-child{padding-right:0}
.path h3{font-size:clamp(1.25rem,1.8vw,1.4375rem);letter-spacing:-.02em;margin-bottom:.65rem}
.path p{color:var(--ink-soft);font-size:.9375rem;line-height:1.55;margin:0}
@media (max-width:780px){
  .paths{grid-template-columns:1fr;gap:2rem}
  .path{border-left:0;padding-inline:0;border-top:1px solid var(--rule);padding-top:1.75rem}
  .path:first-child{border-top:0;padding-top:0}
}

/* Careers page only (careers.html). Every selector below is used on that
   page alone, so restyling here never reaches another page. */

/* "Why we grow": one connected, centred thought in the site sans only.
   Headline is scoped down from the global h2 so it holds one line on
   desktop; supporting lines step down in size; the closing line is
   emphasised by weight and navy, not a second typeface. */
.careers-bridge-inner{max-width:52rem;margin-inline:auto;text-align:center}
.careers-bridge .eyebrow{justify-content:center}
.careers-bridge h2{font-size:clamp(2.125rem,4.4vw,3.75rem);line-height:1;letter-spacing:-.03em;text-wrap:balance}
.careers-bridge-lead{margin:1.25rem auto 0;max-width:48rem;font-size:clamp(1.125rem,1.6vw,1.3125rem);line-height:1.5;color:var(--ink)}
.careers-bridge-proof{margin:.85rem auto 0;max-width:46rem;font-size:clamp(1rem,1.3vw,1.125rem);line-height:1.6;color:var(--ink-soft)}
.careers-bridge-close{margin-top:1.25rem;font-size:clamp(1.0625rem,1.4vw,1.1875rem);font-weight:600;color:var(--navy-700)}

/* Career paths: "There isn't one path here." A navy band (one step lighter
   than .section--dark's navy-950, so it reads as its own moment beside the
   dark expectations section further down) with four weighty cards. Each
   card is a simple stepped flow; the last step, where the path leads, is
   the brightest block. The payoff line closes the section at headline size. */
.careers-paths{background:var(--navy-900)}
.careers-paths .section-head{max-width:46rem}
.careers-paths-note{margin-top:1.1rem;color:rgba(255,255,255,.82);font-size:1.0625rem;font-weight:600;line-height:1.55}
.entry-grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:clamp(1rem,2vw,1.5rem)}
.entry-card{
  display:flex;flex-direction:column;
  background:rgba(255,255,255,.05);border:1px solid rgba(255,255,255,.12);border-top:3px solid var(--cyan-500);
  padding:clamp(1.5rem,2.6vw,2rem);
}
.entry-card h3{font-size:clamp(1.25rem,1.7vw,1.4375rem);letter-spacing:-.02em;color:var(--white);margin-bottom:1.35rem}
.entry-flow{display:flex;flex-direction:column;gap:.45rem}
.entry-flow span:not(.entry-arrow){
  display:block;font-size:1rem;font-weight:600;color:var(--white);line-height:1.35;
  padding:.9rem 1rem;background:rgba(255,255,255,.08);
}
.entry-flow span:last-child{background:var(--white);color:var(--navy-900);font-weight:700}
.entry-arrow{display:block;text-align:center;color:var(--cyan-400);line-height:1;font-size:1.125rem;padding-block:.15rem}
.careers-ceiling{
  margin:clamp(3rem,6vw,4.5rem) auto 0;padding-top:clamp(2rem,4vw,3rem);max-width:52rem;
  border-top:1px solid rgba(255,255,255,.14);text-align:center;
  font-size:clamp(1.625rem,3.4vw,2.5rem);font-weight:700;letter-spacing:-.025em;line-height:1.2;color:var(--white);text-wrap:balance;
}
@media (max-width:1000px){
  .entry-grid{grid-template-columns:repeat(2,minmax(0,1fr))}
}
@media (max-width:640px){
  .entry-grid{grid-template-columns:1fr}
  .entry-card h3{margin-bottom:1rem}
  .entry-flow span:not(.entry-arrow){padding:.75rem .9rem}
}

/* Real career stories: "People have built careers here." The started ->
   today strip is the point of each card, so Today gets the weight. */
.story-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(1.75rem,3vw,2.5rem)}
.story-card .media{margin-bottom:1.25rem}
.story-card h3{font-size:1.25rem;margin-bottom:.2rem}
.story-market{font-size:.875rem;color:var(--ink-soft);margin-bottom:1.1rem}
.story-progress{display:flex;align-items:stretch;background:var(--bg-alt)}
.story-stage{display:flex;flex-direction:column;justify-content:center;gap:.3rem;padding:1rem 1.1rem;flex:1 1 0;min-width:0}
.story-stage--today{background:var(--navy-800);flex-basis:0;flex-grow:1.25}
.story-stage-label{font-size:.625rem;font-weight:700;letter-spacing:.12em;text-transform:uppercase;color:var(--navy-600)}
.story-stage--today .story-stage-label{color:var(--cyan-400)}
.story-stage-role{font-size:.9375rem;font-weight:600;color:var(--ink-soft);line-height:1.3}
.story-stage-role--today{color:var(--white);font-weight:700;font-size:1.0625rem}
.story-arrow{flex:none;align-self:center;color:var(--cyan-500);font-size:1.25rem;line-height:1;padding-inline:.6rem}
@media (max-width:1000px){
  .story-grid{grid-template-columns:1fr;max-width:24rem;margin-inline:auto;gap:2.5rem}
}

/* "Find where you fit": six job families. Deliberately plainer than the
   career-path cards above: a line of description and one examples line. */
.fit-card p{color:var(--ink-soft);font-size:.9375rem;line-height:1.5;margin:0}
.fit-card h3{font-size:1.1875rem;margin-bottom:.6rem}
.fit-card .fit-examples{margin-top:1rem;padding-top:.9rem;border-top:1px solid var(--rule);font-size:.875rem;font-weight:600;color:var(--navy-800)}
.fit-examples span{display:block;margin-bottom:.3rem;font-size:.625rem;font-weight:700;letter-spacing:.12em;text-transform:uppercase;color:var(--ink-soft)}
.fit-cta{justify-content:center;margin-top:clamp(2rem,4vw,2.75rem)}

/* ==========================================================================
   CTA band
   ========================================================================== */
.cta-band{position:relative;overflow:hidden;background:var(--navy-800);color:var(--white)}
.cta-band::before{
  content:"";position:absolute;inset:0;
  background:radial-gradient(90% 130% at 88% 8%,rgba(30,187,240,.24),transparent 62%);
}
.cta-inner{
  position:relative;display:grid;grid-template-columns:1.35fr 1fr;
  gap:clamp(2rem,5vw,4rem);align-items:center;
  padding-block:clamp(3.5rem,7vw,5.5rem);
}
@media (max-width:860px){.cta-inner{grid-template-columns:1fr;gap:2rem}}
.cta-inner h2{color:var(--white)}
.cta-inner .lede{margin-top:1.25rem}
.cta-actions{display:flex;flex-direction:column;gap:.75rem;align-items:flex-start}
@media (min-width:861px){.cta-actions{align-items:stretch}}
.cta-actions .btn{justify-content:center}
.cta-phone{
  display:block;text-decoration:none;
  font-family:var(--font-display);font-weight:700;font-size:1.4375rem;
  letter-spacing:-.035em;color:var(--white);padding-top:.6rem;
  transition:color .2s;
}
.cta-phone:hover{color:var(--cyan-400)}
.cta-phone small{
  display:block;font-family:var(--font-body);font-size:.625rem;font-weight:600;
  letter-spacing:.18em;text-transform:uppercase;color:rgba(255,255,255,.5);
  margin-bottom:.4rem;
}

/* ==========================================================================
   Forms
   ========================================================================== */
.form-card{
  background:var(--white);border:1px solid var(--rule);border-radius:var(--r);
  border-top:2px solid var(--navy-700);
  padding:clamp(1.75rem,3.5vw,3rem);
}
.field{margin-bottom:1.35rem}
.field > label{
  display:block;font-size:.6875rem;font-weight:600;letter-spacing:.1em;
  text-transform:uppercase;margin-bottom:.55rem;color:var(--ink-700);
}
.field .req{color:var(--cyan-600)}
.field .opt{font-weight:500;letter-spacing:.04em;text-transform:none;color:var(--ink-soft)}
/* General contact form (contact.html): property name and service address
   only apply to current customers, so they appear once that reason is
   picked. Without :has() support they simply stay visible (optional). */
@supports selector(:has(a)){
  .contact-form .contact-customer{display:none}
  .contact-form:has(#r-customer:checked) .contact-customer{display:block}
}
.field input,.field select,.field textarea{
  width:100%;padding:.85rem 1rem;
  font-family:var(--font-body);font-size:.9375rem;color:var(--ink);
  background:var(--gray-50);
  border:1px solid var(--gray-300);border-radius:var(--r);
  transition:border-color .2s,background .2s,box-shadow .2s;
}
.field input:focus,.field select:focus,.field textarea:focus{
  outline:none;border-color:var(--navy-700);background:var(--white);
  box-shadow:0 0 0 3px rgba(23,64,110,.14);
}
.field textarea{resize:vertical;min-height:130px}
.field select{
  appearance:none;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath fill='none' stroke='%235A6875' stroke-width='1.6' d='M1 1.5 6 6.5l5-5'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right 1rem center;padding-right:2.5rem;
}
.field-row{display:grid;grid-template-columns:1fr 1fr;gap:1.35rem}
@media (max-width:600px){.field-row{grid-template-columns:1fr}}
.form-note{font-size:.75rem;color:var(--ink-soft);margin-top:1.25rem;line-height:1.5}
.form-card .btn--submit{width:100%;justify-content:center}

.pillset{display:flex;flex-wrap:wrap;gap:.5rem}
.pillset input{position:absolute;opacity:0;width:0;height:0}
.pillset label{
  margin:0;padding:.65rem 1.1rem;cursor:pointer;
  border:1px solid var(--gray-300);background:var(--white);
  font-size:.8125rem;font-weight:500;
  transition:border-color .2s,background .2s,color .2s;
}
.pillset label:hover{border-color:var(--navy-600)}
.pillset input:checked + label{background:var(--navy-700);border-color:var(--navy-700);color:var(--white)}
.pillset input:focus-visible + label{box-shadow:0 0 0 3px rgba(23,64,110,.25)}

.form-success{
  display:none;padding:1.15rem 1.35rem;
  background:rgba(30,187,240,.1);border:1px solid var(--cyan-500);
  border-left-width:3px;
  font-size:.9375rem;margin-bottom:1.5rem;
  /* Own colour: forms sit inside dark sections (.section--green sets white),
     and inherited white text vanishes on this pale box. */
  color:var(--navy-700);
}
.form-success.is-visible{display:block}

/* ==========================================================================
   Projects
   ========================================================================== */
.project{
  position:relative;display:block;text-decoration:none;color:inherit;
  border:1px solid var(--rule);border-radius:var(--r);overflow:hidden;background:var(--white);
  transition:border-color .3s var(--ease),box-shadow .3s var(--ease);
}
.project::after{
  content:"";position:absolute;top:0;left:0;right:0;height:2px;
  background:var(--cyan-500);transform:scaleX(0);transform-origin:left;
  transition:transform .4s var(--ease);z-index:2;
}
.project:hover{border-color:var(--navy-600);box-shadow:0 22px 48px rgba(7,23,38,.11)}
.project:hover::after{transform:scaleX(1)}
/* A gallery-trigger card covers its own .media with an invisible button
   (see .person-trigger reuse in tools/market-page.js), so the direct
   .media--zoom:hover never fires — hover the parent card instead. */
.project:hover .media--zoom img{transform:scale(1.04)}
.project .media{border-radius:0}
.project-body{padding:1.5rem}
.project-meta{
  display:flex;flex-wrap:wrap;gap:.45rem;margin-bottom:.9rem;
  font-size:.625rem;font-weight:600;letter-spacing:.16em;text-transform:uppercase;
  color:var(--navy-600);
}
.project-meta span:not(:last-child)::after{content:"\002F";margin-left:.45rem;color:var(--gray-400)}
.project h3{font-size:1.1875rem;margin-bottom:.6rem}
.project p{font-size:.9063rem;color:var(--ink-soft);margin:0}
/* Market-page Featured Work: an earned award sits on the photo (top-left),
   so the card body is identical with or without one. One format everywhere:
   "NALP Award of Excellence • Gold • 2026". Above the gallery trigger. */
.project-award{
  position:absolute;top:.85rem;left:.85rem;z-index:2;max-width:calc(100% - 1.7rem);
  padding:.45rem .75rem;background:rgba(11,34,57,.9);color:var(--white);
  font-size:.625rem;letter-spacing:.1em;line-height:1.35;text-decoration:none;
  border-left:2px solid var(--cyan-500);
}
a.project-award:hover{background:var(--navy-900)}
/* One featured property on a market page: an image-led spotlight rather
   than a lone card from a 3-up grid. Stacks as a normal card on phones. */
@media (min-width:900px){
  .project--spotlight{display:grid;grid-template-columns:minmax(0,1.55fr) minmax(0,1fr)}
  .project--spotlight .media.ratio-wide{aspect-ratio:auto;height:100%;min-height:26rem}
  .project--spotlight .project-body{display:flex;flex-direction:column;justify-content:center;padding:clamp(2rem,3.5vw,3rem)}
  .project--spotlight h3{font-size:clamp(1.75rem,2.4vw,2.25rem);letter-spacing:-.02em;margin-bottom:.85rem}
  .project--spotlight p{font-size:1rem;line-height:1.6}
}

.filters{display:flex;flex-wrap:wrap;gap:.5rem;margin-bottom:2.5rem}
.filter-btn{
  padding:.6rem 1.15rem;border:1px solid var(--gray-300);border-radius:var(--r);
  background:var(--white);cursor:pointer;font-size:.8125rem;font-weight:500;
  letter-spacing:.01em;
  transition:border-color .2s,background .2s,color .2s;
}
.filter-btn:hover{border-color:var(--navy-600)}
.filter-btn.is-active{background:var(--navy-700);border-color:var(--navy-700);color:var(--white)}
.is-hidden{display:none!important}

/* ==========================================================================
   People
   ========================================================================== */
.person{position:relative}
.person .media{margin-bottom:1.1rem}
/* Leadership page: one headshot shot slightly brighter/warmer than the set.
   A light display-only balance (the image file itself is untouched). */
.person img.headshot-tone-soften{filter:brightness(.96) saturate(.92)}
.person h4{font-size:1.0625rem;margin-bottom:.3rem}
.person .role{
  font-size:.6875rem;color:var(--navy-600);font-weight:600;
  letter-spacing:.1em;text-transform:uppercase;
}
.person p{font-size:.9063rem;color:var(--ink-soft);margin-top:.75rem}

.person-trigger{
  position:absolute;inset:0;z-index:1;
  width:100%;padding:0;margin:0;border:0;background:none;cursor:pointer;
}
.person-trigger:focus-visible{outline:2px solid var(--navy-600);outline-offset:4px}
.person-linkedin{
  position:relative;z-index:2;display:inline-flex;align-items:center;gap:.4rem;
  margin-top:.6rem;color:var(--navy-600);text-decoration:none;
  font-size:.8125rem;font-weight:600;
}
.person-linkedin svg{width:18px;height:18px}
.person-linkedin:hover{color:var(--cyan-500)}
/* Visible email on a person card, stacked above .person-linkedin. Lifted
   over .person-trigger (z-index:1) like the LinkedIn link so it stays
   clickable on cards that open a bio popup. */
.person-email{position:relative;z-index:2;margin-top:.6rem}

/* Leadership hero closing line ("Different strengths. Shared values.
   One Granite Hills team.") — set apart from the two body paragraphs
   above it without a card, rule, or icon, just weight and an italic
   serif to give it the last word. */
.leadership-statement{
  margin-top:1.75rem;font-family:var(--font-serif);font-style:italic;
  font-weight:600;font-size:1.0625rem;letter-spacing:-.01em;color:var(--white);
}

/* Leadership groups (Executive, Corporate) — one continuous section,
   not two, so the groups read as one team with a hierarchy rather than
   a split page. The rule above "Corporate leadership" is the only
   separator; everything else (card size, image ratio, type, spacing)
   is identical between groups on purpose.
   .people-grid is flexbox, not .grid-3, specifically so a group whose
   count isn't a multiple of three (five, not six) centers its last row
   instead of leaving a blank grid cell trailing off to the right. */
.leadership-group+.leadership-group{
  margin-top:clamp(3rem,5vw,4rem);padding-top:clamp(2.5rem,4vw,3.25rem);
  border-top:1px solid var(--rule);
}
.people-grid{
  display:flex;flex-wrap:wrap;justify-content:center;
  gap:clamp(1.75rem,3vw,2.5rem) clamp(1.5rem,2.5vw,2.25rem);
  margin-top:clamp(1.75rem,3vw,2.25rem);
}
.people-grid .person{flex:0 0 calc((100% - 2*clamp(1.5rem,2.5vw,2.25rem))/3)}
@media (max-width:1000px){
  .people-grid .person{flex:0 0 calc((100% - clamp(1.5rem,2.5vw,2.25rem))/2)}
}
@media (max-width:680px){
  .people-grid .person{flex:0 0 100%;max-width:22rem}
}

.person-dialog{
  border:0;padding:0;max-width:640px;width:calc(100% - 2.5rem);
  border-radius:var(--r);box-shadow:0 30px 70px rgba(7,23,38,.28);
  background:var(--white);color:var(--ink);
}
.person-dialog::backdrop{background:rgba(7,23,38,.6)}
.person-dialog-inner{position:relative;display:grid;grid-template-columns:220px 1fr}
.person-dialog-close{
  position:absolute;top:.85rem;right:.85rem;z-index:2;
  width:34px;height:34px;display:flex;align-items:center;justify-content:center;
  border:0;background:var(--white);border-radius:50%;cursor:pointer;color:var(--ink);
  box-shadow:0 4px 14px rgba(7,23,38,.18);
}
.person-dialog-close svg{width:16px;height:16px}
.person-dialog-media{aspect-ratio:3/4;overflow:hidden;background:var(--navy-900)}
.person-dialog-media img{width:100%;height:100%;object-fit:cover;display:block}
.person-dialog-body{padding:1.75rem}
.person-dialog-body h3{font-size:1.375rem;margin-bottom:.3rem}
.person-dialog-body .role{
  font-size:.6875rem;color:var(--navy-600);font-weight:600;
  letter-spacing:.1em;text-transform:uppercase;
}
.person-dialog-links{display:flex;flex-wrap:wrap;align-items:center;gap:1.1rem;margin-top:.85rem}
.person-dialog-linkedin{
  display:inline-flex;align-items:center;gap:.4rem;
  color:var(--navy-600);text-decoration:none;font-size:.8125rem;font-weight:600;
}
.person-dialog-linkedin svg{width:18px;height:18px}
.person-dialog-linkedin:hover{color:var(--cyan-500)}
.person-dialog-email{color:var(--navy-600);text-decoration:none;font-size:.8125rem;font-weight:600}
.person-dialog-email:hover{color:var(--cyan-500)}
.person-dialog-bio{margin-top:1.1rem;font-size:.9375rem;color:var(--ink-soft);line-height:1.6}
.person-dialog-bio p+p{margin-top:.9em}

@media (max-width:640px){
  .person-dialog-inner{grid-template-columns:1fr}
  .person-dialog-media{aspect-ratio:16/9}
}

/* Photo gallery dialog — same native <dialog> pattern as the person bio
   popup above, reused for project photo sets (see js/site.js §11). */
.gallery-dialog{
  border:0;padding:0;max-width:960px;width:calc(100% - 2.5rem);
  background:var(--navy-950);box-shadow:0 30px 70px rgba(7,23,38,.35);
}
.gallery-dialog::backdrop{background:rgba(7,23,38,.8)}
.gallery-dialog-inner{position:relative}
.gallery-dialog-inner img{width:100%;aspect-ratio:3/2;object-fit:cover;display:block}
.gallery-dialog-close,
.gallery-dialog-prev,
.gallery-dialog-next{
  position:absolute;z-index:2;
  display:flex;align-items:center;justify-content:center;
  border:0;border-radius:50%;cursor:pointer;
}
.gallery-dialog-close{
  top:.85rem;right:.85rem;width:34px;height:34px;
  background:var(--white);color:var(--ink);box-shadow:0 4px 14px rgba(7,23,38,.18);
}
.gallery-dialog-close svg{width:16px;height:16px}
.gallery-dialog-prev,
.gallery-dialog-next{
  top:50%;transform:translateY(-50%);width:44px;height:44px;
  background:rgba(7,23,38,.55);color:var(--white);font-size:1.5rem;line-height:1;
  transition:background .2s;
}
.gallery-dialog-prev:hover,
.gallery-dialog-next:hover{background:rgba(7,23,38,.85)}
.gallery-dialog-prev{left:.85rem}
.gallery-dialog-next{right:.85rem}
.gallery-dialog-count{
  position:absolute;bottom:.85rem;right:1rem;z-index:2;
  padding:.3rem .65rem;background:rgba(7,23,38,.55);color:rgba(255,255,255,.85);
  font-size:.75rem;font-weight:600;letter-spacing:.05em;
}

/* ==========================================================================
   Value cards
   ========================================================================== */
.value{padding:clamp(1.5rem,2.4vw,2rem);border-left:2px solid var(--cyan-500);background:var(--white)}
.value h3{font-size:1.125rem;margin-bottom:.7rem}
.value p{font-size:.9375rem;color:var(--ink-soft);margin:0}
.section--dark .value,.section--green .value{background:rgba(255,255,255,.04)}
.section--dark .value p,.section--green .value p{color:rgba(255,255,255,.66)}
/* Homepage Careers / Partner cards: content anchored 12px up and left, the
   12px moved to the bottom/right so the card size is unchanged. Desktop only;
   smaller screens keep the standard even padding. */
@media (min-width:1024px){.cta-pair > .value{padding:calc(2rem - 12px) calc(2rem + 12px) calc(2rem + 12px) calc(2rem - 12px)}}
/* .value p zeroes every paragraph margin, including the label's; give the
   label back a little room above the headline. */
.cta-pair > .value > .eyebrow{margin-bottom:10px}

/* ==========================================================================
   Badges — small reusable marketing atom (award callouts on project
   cards). Kept separate from .pillset, which is a form control, not a
   label.
   ========================================================================== */
.badge{
  display:inline-flex;align-items:center;gap:.4rem;
  padding:.4rem .8rem;
  background:var(--navy-700);color:var(--cyan-400);
  font-size:.6875rem;font-weight:700;letter-spacing:.08em;text-transform:uppercase;
  transition:background .2s;
}
a.badge:hover{background:var(--navy-800)}

/* ==========================================================================
   Benefits
   ========================================================================== */
.benefits{
  list-style:none;padding:0;margin:0;display:grid;gap:1px;
  background:var(--rule);border:1px solid var(--rule);
}
.benefits li{background:var(--white);padding:1.35rem 1.5rem;display:flex;gap:1rem;align-items:flex-start}
.benefits .tick{
  flex:none;width:20px;height:20px;margin-top:.2rem;
  background:var(--navy-700);color:var(--cyan-400);
  display:flex;align-items:center;justify-content:center;
}
.benefits .tick svg{width:11px;height:11px}
.benefits strong{display:block;font-size:.9688rem;margin-bottom:.2rem}
.benefits span{font-size:.875rem;color:var(--ink-soft);line-height:1.5}

/* ==========================================================================
   Accordion
   ========================================================================== */
.acc{border-top:1px solid var(--rule)}
.acc-item{border-bottom:1px solid var(--rule)}
.acc-btn{
  width:100%;display:flex;align-items:center;justify-content:space-between;gap:1.5rem;
  padding:1.5rem 0;background:none;border:0;cursor:pointer;text-align:left;
  font-family:var(--font-display);font-weight:700;font-size:1.0625rem;
  letter-spacing:-.025em;color:var(--ink);
  transition:color .2s;
}
.acc-btn:hover{color:var(--navy-700)}
.acc-icon{flex:none;width:20px;height:20px;position:relative}
.acc-icon::before,.acc-icon::after{
  content:"";position:absolute;background:var(--cyan-600);
  transition:transform .3s var(--ease),opacity .3s var(--ease);
}
.acc-icon::before{top:9.25px;left:1px;width:18px;height:1.5px}
.acc-icon::after{top:1px;left:9.25px;width:1.5px;height:18px}
.acc-btn[aria-expanded="true"] .acc-icon::after{transform:rotate(90deg);opacity:0}
.acc-panel{overflow:hidden;max-height:0;opacity:0;transition:max-height .38s var(--ease),opacity .3s var(--ease)}
.acc-panel.is-open{opacity:1}
.acc-panel-inner{padding:0 0 1.75rem;max-width:70ch;color:var(--ink-soft);font-size:.9688rem}

/* ==========================================================================
   Footer
   ========================================================================== */
.site-footer{background:var(--navy-950);color:rgba(255,255,255,.6);font-size:.875rem}
.footer-main{
  display:grid;grid-template-columns:1.5fr 1fr 1fr 1fr;
  gap:clamp(2rem,4vw,3.5rem);
  padding-block:clamp(3.5rem,6vw,5rem);
}
@media (max-width:960px){.footer-main{grid-template-columns:1fr 1fr}}
@media (max-width:560px){.footer-main{grid-template-columns:1fr;gap:2.5rem}}
.footer-brand .logo{margin-bottom:.25rem}
.footer-brand p{margin-top:1.35rem;max-width:34ch;line-height:1.65;font-size:.875rem}
.footer-col h4{
  color:var(--white);font-size:.625rem;font-weight:600;
  letter-spacing:.18em;text-transform:uppercase;margin-bottom:1.25rem;
  font-family:var(--font-body);
}
.footer-col ul{list-style:none;padding:0;margin:0}
.footer-col li{margin-bottom:.7rem}
.footer-col a{text-decoration:none;transition:color .2s}
.footer-col a:hover{color:var(--cyan-400)}
.footer-bottom{
  border-top:1px solid rgba(255,255,255,.12);
  padding-block:1.75rem;
  display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:1rem;
  font-size:.75rem;color:rgba(255,255,255,.44);
}
.footer-bottom a{text-decoration:none}
.footer-bottom a:hover{color:var(--cyan-400)}
.social{display:flex;gap:.5rem}
.social a{
  width:32px;height:32px;border:1px solid rgba(255,255,255,.18);
  display:flex;align-items:center;justify-content:center;
  transition:background .25s,border-color .25s,color .25s;
}
.social a:hover{background:var(--cyan-500);border-color:var(--cyan-500);color:var(--navy-950)}
.social svg{width:14px;height:14px}

/* ==========================================================================
   Utilities
   ========================================================================== */
.reveal{opacity:0;transform:translateY(16px);transition:opacity .5s var(--ease),transform .5s var(--ease)}
.reveal.is-in{opacity:1;transform:none}
@media (prefers-reduced-motion:reduce){.reveal{opacity:1;transform:none}}

.skip-link{
  position:absolute;left:-9999px;top:0;z-index:999;
  padding:.85rem 1.5rem;background:var(--navy-700);color:var(--white);
  text-decoration:none;font-weight:600;font-size:.875rem;
}
.skip-link:focus{left:0}

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

.mt-0{margin-top:0}
.text-center{text-align:center}
.divider{height:1px;background:var(--rule);border:0;margin:0}

/* ==========================================================================
   Customer Portal entry point — topbar, upper right. New selectors only;
   nothing above is changed. Text label from 560px up, icon-only on phones.
   Below 360px the topbar has no room, so the link moves into the menu
   drawer (.nav-login) instead.
   ========================================================================== */
.topbar-login{display:inline-flex;align-items:center;gap:.4rem;color:var(--white);font-weight:600}
.topbar-login svg{width:14px;height:14px;flex:none;color:var(--cyan-400)}
@media (min-width:821px){.topbar-login{padding-left:1.5rem;border-left:1px solid rgba(255,255,255,.18)}}
@media (max-width:559px){.topbar-login span{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}}
@media (max-width:359px){.topbar-login{display:none}}
.nav-links > li.nav-login{display:none}
@media (max-width:359px){.nav-links > li.nav-login{display:block}}
/* Team Member Login sits just left of Customer Login with a little less
   weight (regular, muted, no icon). Phones: the topbar has no room for its
   label, so it moves into the menu drawer (.nav-team), next to Customer
   Login's drawer item. */
.topbar-team{color:rgba(255,255,255,.72)}
@media (min-width:821px){.topbar-team{padding-left:1.5rem;border-left:1px solid rgba(255,255,255,.18)}}
@media (max-width:559px){.topbar-team{display:none}}
.nav-links > li.nav-team{display:none}
@media (max-width:559px){.nav-links > li.nav-team{display:block}}

/* ==========================================================================
   Team Member Hub (team-member-hub.html). New selectors only.
   ========================================================================== */
.hub-hero .page-hero-inner{padding-block:clamp(3rem,6vw,4.5rem) clamp(4.5rem,8vw,6rem)}
/* Photo row overlaps the bottom of the navy hero so it reads as part of it */
.hub-photos{margin-top:clamp(-4rem,-6vw,-3rem);position:relative;z-index:1}
.hub-photo-row{
  display:grid;gap:clamp(.5rem,1vw,.75rem);
  grid-template-columns:1fr 1.6fr 1fr 1.6fr 1fr;height:clamp(13rem,22vw,19rem);
}
.hub-photo{height:100%;border-radius:0}
@media (max-width:900px){.hub-photo-row{height:clamp(10rem,24vw,13rem)}}
/* Phones: one wide photo over two square ones, kept compact so the
   resources start close to the top. */
@media (max-width:560px){
  .hub-photo-row{grid-template-columns:1fr 1fr;height:auto}
  .hub-photo{aspect-ratio:1/1;height:auto}
  .hub-photo--wide{grid-column:1 / -1;aspect-ratio:2/1;order:-1}
  .hub-photo--wide + .hub-photo--tall + .hub-photo--wide,
  .hub-photo--extra{display:none}
}
.hub-resources{padding-top:clamp(3.5rem,7vw,5.5rem)}
.hub-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:clamp(1rem,2vw,1.5rem)}
@media (max-width:900px){.hub-grid{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (max-width:560px){.hub-grid{grid-template-columns:minmax(0,1fr)}}
.hub-card{display:flex;flex-direction:column;background:var(--white);border:1px solid var(--rule);border-top:2px solid var(--cyan-500)}
.hub-card-body{display:flex;flex-direction:column;flex:1;padding:clamp(1.4rem,2.4vw,1.85rem)}
.hub-card h3{font-size:1.1875rem;margin:0 0 .6rem}
.hub-card p{margin:0 0 1.35rem;color:var(--ink-soft);font-size:.9688rem;line-height:1.6}
.hub-card .tlink,.hub-soon{margin-top:auto;align-self:flex-start}
.hub-soon{font-size:.6875rem;font-weight:600;letter-spacing:.12em;text-transform:uppercase;color:var(--ink-soft)}

/* Customer Portal call-to-action (HOA and Markets pages). New selector only. */
.portal-cta{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:1.25rem 2.5rem;
  background:var(--white);border:1px solid var(--rule);border-left:4px solid var(--cyan-500);
  padding:clamp(1.25rem,3vw,2rem) clamp(1.25rem,3vw,2.25rem)}
.portal-cta > div{flex:1 1 420px;max-width:62ch}
.portal-cta h3{margin:.35rem 0 .5rem}
.portal-cta p:last-child{margin:0;color:var(--ink-soft)}

/* Three-photo layout (Landscape Maintenance page): tall lead image beside two
   stacked 3:2 images; single column on phones. New selectors only. */
.photo-trio{display:grid;gap:clamp(.5rem,1.2vw,.875rem);max-width:64rem;margin-inline:auto}
.photo-trio-lead{aspect-ratio:3/4}
@media (min-width:720px){
  .photo-trio{grid-template-columns:1fr 1fr}
  .photo-trio-lead{grid-row:span 2;aspect-ratio:auto}
}

/* Photo strip (Snow & Ice page): one wide image plus two portrait images.
   Phones: wide on top, portraits side by side. Desktop: one row, the wide
   image between the two portraits, all the same height. New selectors only. */
.photo-strip{display:grid;grid-template-columns:1fr 1fr;gap:clamp(.5rem,1.2vw,.875rem);max-width:64rem;margin-inline:auto}
.photo-strip-wide{grid-column:1 / -1;aspect-ratio:2/1}
.photo-strip-tall{aspect-ratio:3/4}
@media (min-width:720px){
  .photo-strip{grid-template-columns:3fr 8.2fr 3fr}
  .photo-strip-wide{grid-column:2;grid-row:1;aspect-ratio:auto}
}

/* Five-photo mosaic (Landscape Development page): tall lead image beside a
   2x2 grid; phones show the lead full width over a 2x2 grid. New selectors only. */
.photo-mosaic{display:grid;grid-template-columns:1fr 1fr;gap:clamp(.5rem,1.2vw,.875rem);max-width:64rem;margin-inline:auto}
.photo-mosaic > .media{aspect-ratio:4/3}
.photo-mosaic > .photo-mosaic-lead{grid-column:1 / -1}
@media (min-width:720px){
  .photo-mosaic{grid-template-columns:repeat(3,1fr)}
  .photo-mosaic > .photo-mosaic-lead{grid-column:auto;grid-row:span 2;aspect-ratio:auto}
}

/* Four-column .paths row (Industrial page). Two columns on tablets, one on
   phones — the base .paths rule already stacks at 780px. */
.paths--4{grid-template-columns:repeat(4,1fr)}
@media (max-width:1100px) and (min-width:781px){
  .paths--4{grid-template-columns:repeat(2,1fr);row-gap:2rem}
  .paths--4 .path:nth-child(odd){border-left:0;padding-left:0}
}
@media (max-width:780px){.paths--4{grid-template-columns:1fr}}

/* ==========================================================================
   Who We Serve vertical pages (HOA, Multifamily, Office, Retail,
   Institutional, Industrial, Senior Living): tighter section rhythm and a
   large editorial photo gallery. New selectors only; used only on those
   seven pages.
   ========================================================================== */
.section--snug{padding-block:clamp(3.25rem,6.5vw,5.5rem)}
.section--snug .section-head{margin-bottom:clamp(1.75rem,3.5vw,2.75rem)}
.section--snug .section-head:last-child{margin-bottom:0}
.section--gallery{padding-block:clamp(2.75rem,5vw,4.25rem)}
.section--gallery > .wrap > .eyebrow{margin-bottom:clamp(1rem,2vw,1.4rem)}

.vgallery{display:grid;grid-template-columns:1fr;gap:clamp(.5rem,1vw,.875rem)}
.vgallery-item{position:relative;margin:0;overflow:hidden;background:var(--navy-900);aspect-ratio:3/2}
.vgallery--wide .vgallery-item{aspect-ratio:16/9}
.vgallery-item img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:center;display:block}
.vgallery-cap{
  position:absolute;left:0;right:0;bottom:0;z-index:1;
  display:flex;flex-wrap:wrap;align-items:flex-end;justify-content:space-between;gap:.6rem 1rem;
  padding:clamp(2.25rem,5vw,3.25rem) clamp(1rem,2vw,1.4rem) clamp(.9rem,1.6vw,1.2rem);
  background:linear-gradient(180deg,rgba(7,23,38,0),rgba(7,23,38,.85));
  color:rgba(255,255,255,.82);font-size:.8125rem;line-height:1.35;
}
.vgallery-cap strong{display:block;color:var(--white);font-family:var(--font-display);font-size:clamp(1rem,1.4vw,1.1875rem);font-weight:700;letter-spacing:-.01em}
.vgallery-cap .badge{text-decoration:none}
.vgallery-note{margin:1rem 0 0;text-align:center;color:var(--ink-soft);font-size:.875rem}
.vgallery-more{margin-top:1.5rem;text-align:center}
@media (min-width:640px){
  .vgallery--2,.vgallery--3{grid-template-columns:1fr 1fr}
  .vgallery--3 .vgallery-item--lead{grid-column:1 / -1;aspect-ratio:16/9}
}
@media (min-width:960px){
  .vgallery--3{grid-template-columns:2fr 1fr}
  .vgallery--3 .vgallery-item--lead{grid-column:auto;grid-row:span 2;aspect-ratio:auto}
}

/* ==========================================================================
   News & Recognition (news/*.html only). New selectors only.
   ========================================================================== */
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
.news-hero{background:var(--bg-alt);padding-block:clamp(3rem,6vw,4.75rem) clamp(2rem,4vw,3rem)}
.news-hero h1{font-size:clamp(2.4rem,5.2vw,4.25rem);margin:.5rem 0 1rem}
.news-hero .lede{max-width:44rem}
.news-archive{padding-top:clamp(2.25rem,4.5vw,3.5rem)}
.news-meta{display:flex;flex-wrap:wrap;gap:.35rem .9rem;margin:0 0 .6rem;font-size:.75rem;font-weight:600;letter-spacing:.08em;text-transform:uppercase;color:var(--ink-soft)}
.news-cat{color:var(--navy-600)}
.news-card-link{position:absolute;inset:0;z-index:1}

/* Featured story */
.news-feature{position:relative;display:grid;gap:0;background:var(--white);border:1px solid var(--rule);margin-bottom:clamp(2.5rem,5vw,3.5rem)}
.news-feature:hover{border-color:var(--navy-600)}
.news-feature-body{padding:clamp(1.5rem,3vw,2.5rem);display:flex;flex-direction:column;justify-content:center}
.news-feature h2{font-size:clamp(1.6rem,3vw,2.4rem);line-height:1.12;letter-spacing:-.025em;margin:0 0 .9rem}
.news-feature .lede{font-size:1rem;margin:0 0 1.5rem}
.news-feature .btn{align-self:flex-start}
@media (min-width:900px){.news-feature{grid-template-columns:minmax(0,7fr) minmax(0,5fr)}.news-feature .news-media{min-height:100%}}
.news-archive:not([data-news-filter="all"]) .news-feature{display:none}
.news-archive[data-news-filter="all"] .news-card--featured{display:none}

/* Filters */
.news-filters{display:flex;flex-wrap:wrap;gap:.5rem;margin:0 0 clamp(1.5rem,3vw,2.25rem)}
.news-filter{font:inherit;font-size:.8125rem;font-weight:600;padding:.5rem .9rem;border:1px solid var(--gray-300);background:transparent;color:var(--ink);cursor:pointer;transition:background .2s,color .2s,border-color .2s}
.news-filter:hover{border-color:var(--navy-700)}
.news-filter.is-active{background:var(--navy-700);border-color:var(--navy-700);color:var(--white)}

/* Year groups + card grid */
.news-year + .news-year{margin-top:clamp(2.5rem,5vw,3.5rem)}
.news-year-label{font-size:.8125rem;font-family:var(--font-body);font-weight:700;letter-spacing:.14em;color:var(--ink-soft);margin:0 0 1rem;padding-bottom:.6rem;border-bottom:1px solid var(--rule)}
.news-grid{display:grid;gap:clamp(1rem,2vw,1.5rem);grid-template-columns:minmax(0,1fr)}
@media (min-width:640px){.news-grid{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (min-width:1024px){.news-grid{grid-template-columns:repeat(3,minmax(0,1fr))}}
.news-card{position:relative;display:flex;flex-direction:column;background:var(--white);border:1px solid var(--rule);transition:border-color .2s,box-shadow .2s}
.news-card:hover{border-color:var(--navy-600);box-shadow:0 16px 36px rgba(7,23,38,.08)}
.news-card-body{display:flex;flex-direction:column;flex:1;padding:1.25rem 1.35rem 1.4rem}
.news-card h3{font-size:1.125rem;line-height:1.28;letter-spacing:-.01em;margin:0 0 .6rem}
.news-excerpt{font-size:.9063rem;color:var(--ink-soft);margin:0 0 1rem;display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}
.news-card .tlink{margin-top:auto}
.news-empty{color:var(--ink-soft)}

/* Image treatments */
.news-media{position:relative;overflow:hidden;background:var(--navy-900);aspect-ratio:3/2}
.news-media--hero{aspect-ratio:16/9}
.news-media.media img,.news-media .media img{width:100%;height:100%;object-fit:cover;object-position:var(--pos,center);display:block}
.news-media.news-media--contain img{object-fit:contain}
.news-people{display:flex;gap:6px;height:100%;background:var(--white)}
.news-media.news-people{padding:0}
.news-person{flex:1 1 0;min-width:0;margin:0;position:relative;overflow:hidden}
.news-person img{width:100%;height:100%;object-fit:cover;object-position:center 22%;display:block}
.news-people.news-people--1{justify-content:center;background:linear-gradient(135deg,var(--navy-800),var(--navy-950))}
.news-people--1 .news-person{flex:0 0 auto;width:auto;height:100%;aspect-ratio:3/4}
.news-person figcaption{position:absolute;left:0;right:0;bottom:0;padding:1.5rem .9rem .7rem;font-size:.8125rem;font-weight:600;color:var(--white);background:linear-gradient(180deg,transparent,rgba(7,23,38,.8))}
.news-partner{display:flex;background:var(--gray-100)}
.news-partner .news-people{flex:0 0 42%}
.news-logos{flex:1;min-width:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:clamp(.5rem,1.5vw,1rem);padding:clamp(1rem,3vw,2rem)}
.news-logo{max-width:82%;max-height:36%;width:auto;height:auto;min-height:0;object-fit:contain}
.news-logo--ghg{max-width:64%;max-height:26%}
.news-logos--solo .news-logo{max-width:72%;max-height:78%}
.news-plus{font-family:var(--font-display);font-size:clamp(1.25rem,2.5vw,1.75rem);color:var(--gray-400);line-height:1}
.news-gallery{display:grid;grid-template-columns:minmax(0,2fr) minmax(0,1fr) minmax(0,1fr);grid-template-rows:minmax(0,1fr) minmax(0,1fr);gap:3px}
.news-gallery .media{border-radius:0}
.news-gallery .media:first-child{grid-row:span 2}

/* Article */
.news-article-head{background:var(--bg-alt);padding-block:clamp(2rem,4vw,3rem) clamp(4rem,8vw,6rem)}
.news-article-head h1{font-size:clamp(2rem,4.4vw,3.4rem);line-height:1.08;letter-spacing:-.03em;max-width:52rem;margin:0}
.news-article-head .lede{margin-top:1rem;max-width:44rem}
.news-back{display:inline-block;margin-bottom:1.25rem;font-size:.875rem;font-weight:600;color:var(--navy-700);text-decoration:none}
.news-back:hover{color:var(--cyan-600)}
.news-article-media{max-width:64rem;margin:calc(-1 * clamp(3rem,6vw,4.5rem)) auto 0}
.news-article-body{max-width:44rem;margin:clamp(2rem,4vw,3rem) auto clamp(3rem,6vw,4.5rem);font-size:1.0625rem;line-height:1.7;color:var(--ink-700)}
.news-article-body p{margin:0 0 1.1em}
.news-article-body ul{margin:0 0 1.1em;padding-left:1.2rem}
.news-lines{font-family:var(--font-display);font-weight:600;color:var(--navy-700);line-height:1.6}
.news-quote{margin:1.75rem 0;padding:.25rem 0 .25rem 1.25rem;border-left:3px solid var(--cyan-500)}
.news-quote p{font-family:var(--font-serif);font-style:italic;font-size:clamp(1.25rem,2.4vw,1.5rem);line-height:1.4;color:var(--ink);margin:0 0 .5rem}
.news-quote cite{font-style:normal;font-size:.875rem;font-weight:600;color:var(--ink-soft)}
.news-external{margin:2rem 0 0;padding:1.5rem;background:var(--bg-alt);border-left:3px solid var(--navy-700)}
.news-external-source{margin:0 0 1rem!important;font-size:.9375rem;color:var(--ink-soft)}
.news-external .btn{white-space:normal;text-align:left}
.news-back-foot{margin-top:2.5rem!important}
.news-related{padding-block:clamp(3rem,6vw,4.5rem)}
.news-related .eyebrow{margin-bottom:1.25rem}
.news-media--hero.news-people--1{justify-content:center;background:linear-gradient(135deg,var(--navy-800),var(--navy-950))}
.news-media--hero.news-people--1 .news-person{flex:0 0 auto;width:auto;height:100%;aspect-ratio:3/4}
@media (min-width:640px){
  .news-media--hero.news-people--2 .news-person,.news-media--hero.news-people--3 .news-person{flex:0 0 auto;height:100%;aspect-ratio:3/4}
  .news-media--hero.news-people--2,.news-media--hero.news-people--3{justify-content:center;background:linear-gradient(135deg,var(--navy-800),var(--navy-950))}
}

/* ==========================================================================
   Our Story (our-story.html only). Institutional memory in three acts:
   I The Foundation (dated, quiet, spacious), II Becoming Granite Hills
   (the identity emerges: navy statement, the name), III Still Building
   (undated, confident, human). Type carries the page; the few design
   devices are an act label, a year marker, a hairline and a cyan rule.
   .story-artifact frames real archival material without enlarging it.
   Every selector is .story-* so nothing here reaches another page.
   ========================================================================== */
.story-hero-kicker{margin-top:1.25rem;font-family:var(--font-display);font-weight:700;font-size:clamp(1.125rem,1.8vw,1.375rem);line-height:1.35;color:var(--white)}

/* Act label: the only structural signpost */
.story-act-label{
  display:flex;align-items:center;gap:1.25rem;margin:0 0 clamp(2.25rem,4.5vw,3.5rem);
  font-size:.8125rem;font-weight:600;letter-spacing:.22em;text-transform:uppercase;color:var(--navy-600);
}
.story-act-label::after{content:"";flex:1;height:1px;background:var(--rule)}
.story-act-label--light{color:var(--cyan-400)}
.story-act-label--light::after{background:rgba(255,255,255,.16)}

/* Dated chapters */
.story-chapter{display:grid;grid-template-columns:minmax(0,1fr);gap:1.5rem}
.story-chapter + .story-chapter{margin-top:clamp(3.5rem,7vw,5.5rem)}
@media (min-width:900px){
  .story-chapter{grid-template-columns:minmax(16rem,4fr) minmax(0,8fr);gap:clamp(2.5rem,4.5vw,4.5rem);align-items:start}
  .story-marker{position:sticky;top:7rem}
}
/* One style for every year label, single years and ranges alike. Sized so
   the longest ("2021–2022") fits the marker column on one line. */
.story-year{
  display:inline-block;padding-top:1rem;border-top:2px solid var(--cyan-500);white-space:nowrap;
  font-family:var(--font-display);font-weight:700;letter-spacing:-.02em;line-height:.9;
  font-size:clamp(2.75rem,5vw,4.5rem);color:var(--navy-700);
}
.story-marker-title{display:block;margin-top:.9rem;font-size:.875rem;font-weight:600;letter-spacing:.12em;text-transform:uppercase;color:var(--ink-soft)}

/* Body copy: comfortable editorial measure */
.story-body h2,.story-heads-copy h2,.story-next-body h2{margin-bottom:1.5rem}
.story-body > p,.story-name-part > p:not(.story-name-word),.story-heads-copy > p,.story-next-copy > p,.story-keep-copy p{
  font-size:clamp(1.1875rem,.95rem + .35vw,1.3125rem);line-height:1.7;margin:0 0 1em;max-width:40rem;color:var(--ink-700);
}
.story-keep-copy p{color:rgba(255,255,255,.82)}
.story-beat{
  font-family:var(--font-display);font-weight:700;letter-spacing:-.015em;text-wrap:balance;
  font-size:clamp(1.3rem,2vw,1.625rem)!important;line-height:1.3!important;color:var(--navy-800)!important;
  margin:1.6rem 0!important;
}
.section--dark .story-beat{color:var(--white)!important}
.story-better{padding-left:1.25rem;border-left:2px solid var(--cyan-500);font-weight:500;line-height:1.7!important;color:var(--ink)!important;margin-block:1.5rem!important}

/* Act II: the company before the brand, then the name */
.story-turn{padding-block:clamp(4rem,8vw,6.5rem)}
.story-turn .story-act-label{margin-bottom:clamp(2.5rem,5vw,3.5rem)}
.story-statement{
  margin:0;max-width:64rem;font-size:clamp(2.75rem,7vw,6rem);line-height:.98;letter-spacing:-.04em;color:var(--white);text-wrap:balance;
}
@media (max-width:640px){.story-statement br{display:none}}
/* Logo and the Granite / Hills meanings read as one composition: the logo
   sits on a hairline directly above the two columns it explains. */
.story-logo{margin:clamp(2.5rem,5vw,3.5rem) 0 clamp(1.75rem,3.5vw,2.5rem);padding-top:clamp(1.5rem,3vw,2rem);border-top:1px solid var(--rule)}
.story-logo-frame{position:relative;width:min(42rem,92%);margin:0 auto;container-type:inline-size}
.story-logo-img{display:block;width:100%;height:auto}
/* G + H animation. The PNG is always the finished frame; the letters are
   type laid over the mark's position (~21% across, mid-height) and are
   hidden unless the page script adds .is-ready (motion allowed, JS on).
   ~2s once: letters appear apart, meet at the mark, then the real logo is
   revealed over them, mark first, wordmark sweeping in left to right. */
.story-logo-letter{
  position:absolute;top:50%;left:21.5%;opacity:0;pointer-events:none;
  font-family:var(--font-serif);font-weight:600;font-size:20cqw;line-height:1;color:#1a4270;
  transform:translate(-50%,-52%);
}
.story-logo.is-ready .story-logo-img{opacity:0;clip-path:polygon(0 0,36.5% 0,36.5% 44%,34.6% 44%,34.6% 100%,0 100%)}
.story-logo.is-playing .story-logo-img{animation:story-logo-img 2s cubic-bezier(.4,0,.2,1) forwards}
.story-logo.is-playing .story-logo-g{animation:story-logo-g 2s cubic-bezier(.4,0,.2,1) forwards}
.story-logo.is-playing .story-logo-h{animation:story-logo-h 2s cubic-bezier(.4,0,.2,1) forwards}
@keyframes story-logo-g{
  0%{opacity:0;transform:translate(-125%,-52%)}
  22%{opacity:1;transform:translate(-125%,-52%)}
  50%{opacity:1;transform:translate(-68%,-52%)}
  66%{opacity:0;transform:translate(-68%,-52%)}
  100%{opacity:0;transform:translate(-68%,-52%)}
}
@keyframes story-logo-h{
  0%{opacity:0;transform:translate(25%,-52%)}
  22%{opacity:1;transform:translate(25%,-52%)}
  50%{opacity:1;transform:translate(-32%,-52%)}
  66%{opacity:0;transform:translate(-32%,-52%)}
  100%{opacity:0;transform:translate(-32%,-52%)}
}
@keyframes story-logo-img{
  0%,44%{opacity:0;clip-path:polygon(0 0,36.5% 0,36.5% 44%,34.6% 44%,34.6% 100%,0 100%)}
  64%{opacity:1;clip-path:polygon(0 0,36.5% 0,36.5% 44%,34.6% 44%,34.6% 100%,0 100%)}
  100%{opacity:1;clip-path:polygon(0 0,100% 0,100% 44%,100% 44%,100% 100%,0 100%)}
}
/* Safety net: the page script adds .is-done after 2.1s, so the finished
   logo is guaranteed even if animations are throttled or interrupted. */
.story-logo.is-done .story-logo-img{opacity:1;clip-path:none;animation:none}
.story-logo.is-done .story-logo-letter{display:none}
@media (prefers-reduced-motion:reduce){
  .story-logo .story-logo-img{opacity:1!important;clip-path:none!important;animation:none!important}
  .story-logo .story-logo-letter{display:none}
}
.story-name{display:grid;grid-template-columns:minmax(0,1fr);gap:clamp(2.5rem,5vw,4.5rem)}
@media (min-width:900px){.story-name{grid-template-columns:repeat(2,minmax(0,1fr))}}
.story-name-part{padding-top:1.5rem;border-top:2px solid var(--cyan-500);display:flex;flex-direction:column}
/* Closing lines sit on a shared baseline when the columns are side by side */
.story-name-part > .story-beat{margin-top:auto!important;padding-top:.4rem;margin-bottom:0!important}
.story-name-word{font-family:var(--font-display);font-weight:800;letter-spacing:-.05em;line-height:.9;font-size:clamp(3rem,6vw,5rem);color:var(--navy-800);margin:0 0 1.25rem}
.story-closing{max-width:46rem;margin:clamp(3.5rem,7vw,5.5rem) auto 0;text-align:center;font-family:var(--font-display);font-weight:700;font-size:clamp(1.5rem,2.8vw,2.25rem);line-height:1.25;letter-spacing:-.025em;color:var(--navy-800);text-wrap:balance}

/* Act III: undated, confident, human */
.story-heads{display:grid;grid-template-columns:minmax(0,1fr);gap:clamp(2.5rem,5vw,4rem)}
@media (min-width:900px){
  .story-heads{grid-template-columns:minmax(0,7fr) minmax(0,5fr);align-items:start}
  .story-heads-media{position:sticky;top:7rem}
}
/* "We were heads down building." leads straight into the block below it */
.story-beat.story-beat--lead{margin:2rem 0 1rem!important}
.story-build{
  list-style:none;margin:0 0 1.75rem;padding:.25rem 0 .25rem 1.25rem;max-width:36rem;
  border-left:2px solid var(--cyan-500);
  display:grid;grid-template-columns:minmax(0,1fr);gap:.35rem 2rem;
}
@media (min-width:640px){.story-build{grid-template-columns:repeat(2,max-content);column-gap:2.5rem}}
.story-build li{font-family:var(--font-display);font-weight:600;font-size:clamp(1.0625rem,1.4vw,1.1875rem);line-height:1.45;color:var(--navy-800)}
.story-heads-copy > p.story-growth{
  font-family:var(--font-display);font-weight:700;letter-spacing:-.01em;
  font-size:clamp(1.125rem,1.6vw,1.3rem);line-height:1.4;color:var(--cyan-600);margin:0 0 1rem;
}

.story-keep-head{max-width:56rem;margin-bottom:clamp(2rem,4vw,3rem)}
.story-keep-head h2{color:var(--white)}
.story-keep-intro{display:grid;grid-template-columns:minmax(0,1fr);gap:clamp(2rem,4vw,3.5rem)}
@media (min-width:900px){.story-keep-intro{grid-template-columns:minmax(0,5fr) minmax(0,7fr);align-items:center}}
.story-keep-lead{margin:clamp(2.75rem,5vw,3.75rem) 0 1rem;font-family:var(--font-display);font-weight:600;font-size:clamp(1.125rem,1.8vw,1.375rem);color:var(--cyan-400)}
.story-keep{list-style:none;padding:0;margin:0;display:grid;grid-template-columns:minmax(0,1fr);column-gap:clamp(2rem,5vw,4rem)}
@media (min-width:760px){.story-keep{grid-template-columns:repeat(2,minmax(0,1fr))}}
.story-keep li{padding:1.1rem 0;border-top:1px solid rgba(255,255,255,.14);font-family:var(--font-display);font-weight:700;font-size:clamp(1.25rem,2vw,1.625rem);line-height:1.25;letter-spacing:-.02em;color:var(--white);text-wrap:balance}
.story-keep-close{max-width:40rem;margin:clamp(2.25rem,4vw,3rem) 0 0;font-size:clamp(1.1875rem,.95rem + .35vw,1.3125rem);line-height:1.7;color:rgba(255,255,255,.82)}

.story-next{padding-bottom:clamp(4.5rem,9vw,7rem)}
/* Heading on the left, copy on the right on desktop (same split as the
   dated chapters) so the ending isn't one narrow column in white space. */
.story-next-body{display:grid;grid-template-columns:minmax(0,1fr);gap:.25rem}
@media (min-width:900px){.story-next-body{grid-template-columns:minmax(16rem,4fr) minmax(0,8fr);gap:clamp(2.5rem,4.5vw,4.5rem);align-items:start}}
.story-next-copy > p:last-child{margin-bottom:0}
/* Closing statement: the page ends on type. Impact from scale and space. */
.story-final{text-align:center;margin:clamp(3.5rem,7vw,5.5rem) auto 0;padding-top:clamp(3rem,6vw,4.5rem);border-top:1px solid var(--rule);max-width:64rem}
.story-final-line{margin:0 auto;max-width:22ch;font-family:var(--font-display);font-weight:800;text-transform:uppercase;letter-spacing:-.01em;font-size:clamp(2rem,5.4vw,4.5rem);line-height:1.02;color:var(--navy-800);text-wrap:balance}
.story-final-sub{margin:clamp(1.25rem,2.5vw,1.75rem) 0 0;font-family:var(--font-display);font-weight:700;letter-spacing:-.015em;font-size:clamp(1.5rem,3.2vw,2.625rem);line-height:1.15;color:var(--cyan-600);text-wrap:balance}

/* Photographs: support the story, never compete with it */
.story-photo{margin:2rem 0 2.25rem}
.story-applied{display:grid;grid-template-columns:minmax(0,1fr);gap:clamp(2rem,4vw,3rem);margin-top:clamp(3rem,6vw,4.5rem);align-items:center}
.story-applied-media{max-width:26rem}
.story-applied .story-closing{margin:0;text-align:left;max-width:34rem}
@media (min-width:900px){
  .story-applied{grid-template-columns:minmax(0,5fr) minmax(0,7fr);gap:clamp(3rem,6vw,5.5rem)}
  .story-applied-media{max-width:none}
}

/* Archival material: small, framed, dated, unretouched */
.story-artifact{margin:1.75rem 0 0;max-width:20rem;padding:.6rem .6rem .8rem;background:var(--white);border:1px solid var(--rule);box-shadow:0 1px 2px rgba(7,23,38,.06)}
.story-artifact img{display:block;width:auto;max-width:100%;height:auto}
.story-artifact figcaption{margin-top:.65rem;font-size:.875rem;line-height:1.45;color:var(--ink-soft)}
.story-artifact figcaption span{display:block;margin-top:.15rem;font-weight:600;letter-spacing:.08em;color:var(--navy-700)}

/* Homepage hero: secondary audience links (careers, business owners)
   beneath the two customer CTAs — quiet text links, not buttons, so the
   proposal/services buttons stay dominant. Stack on phones, with enough
   vertical padding to stay comfortably tappable. */
.hero-links{display:flex;flex-wrap:wrap;gap:.5rem 2.25rem;margin-top:1.75rem}
.hero-links .tlink{font-size:.9375rem;padding-block:.45rem .3rem;color:rgba(255,255,255,.9)}
.hero-links .tlink:hover{color:var(--white)}
.hero-links-arrow{color:var(--cyan-400)}
@media (max-width:640px){
  .hero-links{flex-direction:column;align-items:flex-start;gap:.15rem;margin-top:1.5rem}
}

/* Bio dialog review fixes: wider on desktop for longer bios; long
   emails wrap instead of overflowing; faces stay in frame on phones. */
.person-dialog{max-width:900px}
.person-dialog-inner{grid-template-columns:220px minmax(0,1fr)}
.person-dialog-body{min-width:0}
.person-dialog-email{overflow-wrap:anywhere}
@media (max-width:640px){
  .person-dialog-inner{grid-template-columns:1fr}
  .person-dialog-media img{object-position:center top}
}

/* Form send failure (js/site.js §7): same box as .form-success, navy
   accent instead of cyan so it doesn't read as a confirmation. */
.form-error{
  display:none;padding:1.15rem 1.35rem;
  background:var(--gray-50);border:1px solid var(--navy-600);
  border-left-width:3px;
  font-size:.9375rem;margin-bottom:1.5rem;
}
.form-error.is-visible{display:block}
.form-error a{color:var(--navy-700);font-weight:600}

/* ==========================================================================
   Team Member Hub sign-in (team-member-login.html, js/team-hub/) and the
   private hub page's gate + session bar. New selectors only; same split
   navy layout as the Customer Portal sign-in, built on site tokens.
   ========================================================================== */
.tm-auth-page{background:var(--white)}
.tm-auth{display:grid;min-height:100vh;grid-template-rows:auto 1fr}
@media (min-width:960px){.tm-auth{grid-template-columns:1.05fr 1fr;grid-template-rows:none}}
.tm-auth-brand{background:var(--navy-900);color:var(--white);padding:28px 20px 30px;display:flex;flex-direction:column;gap:22px;position:relative;overflow:hidden}
.tm-auth-brand::after{content:"";position:absolute;right:-180px;bottom:-220px;width:520px;height:520px;border:1px solid rgba(138,221,249,.16);border-radius:50%;pointer-events:none}
@media (min-width:960px){.tm-auth-brand{padding:48px 56px;justify-content:space-between}}
.tm-auth-logo img{height:48px;width:auto}
.tm-auth-brand-copy{display:none}
@media (min-width:960px){.tm-auth-brand-copy{display:block}}
.tm-auth-headline{font-size:clamp(1.6rem,4vw,2.6rem);line-height:1.1;color:var(--white);margin:.5rem 0 1rem;letter-spacing:-.02em;max-width:18ch}
.tm-auth-headline em{font-family:var(--font-serif);font-style:italic;font-weight:600;color:var(--cyan-300)}
.tm-auth-lede{color:rgba(255,255,255,.8);max-width:46ch;margin:0}
.tm-auth-back{color:rgba(255,255,255,.65);font-size:.8125rem;text-decoration:none}
.tm-auth-back:hover{color:var(--white)}
.tm-auth-panel{display:flex;align-items:flex-start;justify-content:center;padding:28px 16px 48px}
@media (min-width:960px){.tm-auth-panel{align-items:center}}
.tm-auth-card{width:100%;max-width:420px}
.tm-auth-card h2{font-size:1.8rem;margin:.2rem 0 1.2rem;letter-spacing:-.02em}
.tm-auth-note{color:var(--ink-soft);font-size:.9375rem;margin:-.4rem 0 1.25rem}
.tm-auth-actions{margin-top:1.5rem}
.tm-auth-card .btn--block{width:100%;justify-content:center}
.tm-form .field{margin-bottom:1.1rem}
.tm-form input{width:100%}
.tm-auth-hint{font-size:.75rem;color:var(--ink-soft);margin:.4rem 0 0}
.tm-auth-error{color:#9B1C1C;font-size:.875rem;font-weight:600;margin:0 0 1rem}
.tm-auth-msg{padding:.9rem 1.1rem;margin:0 0 1.25rem;font-size:.875rem;color:var(--navy-700);background:var(--blue-100);border-left:3px solid var(--navy-700)}
.tm-link{display:block;margin:14px 0 0;padding:0;border:0;background:none;font:inherit;font-size:.875rem;font-weight:600;color:var(--navy-700);text-decoration:underline;text-underline-offset:3px;cursor:pointer}
.tm-link:hover{color:var(--navy-500)}
.tm-link[hidden]{display:none}
.tm-auth-foot{font-size:.8125rem;color:var(--ink-soft);margin-top:22px;border-top:1px solid var(--rule);padding-top:16px}

.hub-gate{min-height:50vh}
.hub-gate-msg{color:var(--ink-soft);margin:0}
.hub-gate-card{max-width:560px;background:var(--white);border:1px solid var(--rule);border-top:2px solid var(--navy-700);padding:clamp(1.75rem,3.5vw,2.5rem)}
.hub-gate-title{font-size:clamp(1.6rem,3vw,2.1rem);margin:.4rem 0 .9rem;letter-spacing:-.02em}
.hub-gate-card p{color:var(--ink-soft)}
.hub-gate-card .btn{margin-top:.75rem}
.hub-session{background:var(--navy-950);color:rgba(255,255,255,.78);font-size:.8125rem}
.hub-session .wrap{display:flex;justify-content:flex-end;align-items:center;gap:1rem;min-height:40px}
.hub-session strong{color:var(--white);font-weight:600}
.hub-signout{padding:.3rem .8rem;border:1px solid rgba(255,255,255,.3);background:none;color:var(--white);font:inherit;font-weight:600;cursor:pointer}
.hub-signout:hover{border-color:var(--cyan-400)}