/* assets/css/fonts.css */

/* fonts
   DM Sans, self-hosted. Google serves one variable file per unicode range for
   400, 500 and 600 alike, so there are two files rather than six, and the
   weight range is declared instead of a weight per face. */

@font-face {
  font-family: "DM Sans";
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url("../assets/fonts/dm-sans-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "DM Sans";
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url("../assets/fonts/dm-sans-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* assets/css/tokens.css */

/* Herzog Glass - design tokens
   Derived from the "Home" frame on the v2 page of the Working Figma file.
   Type, colour and ratio come from the comp. Spacing is a regularised 8pt
   scale, not lifted literally, because the comp is a flat artboard that was
   composed by eye rather than measured. */

:root {
  /* ---- brand colour ------------------------------------------------- */
  --purple:        #6c2471;   /* utility bar, CTA band, eyebrow label      */
  --magenta:       #c83a95;   /* eyebrow mark, middle bar                  */
  --cyan:          #3fc3d2;   /* eyebrow mark, right bar                   */
  --teal:          #267e8a;   /* buttons, inline links, footer ground      */
  --teal-accent:   #33b1c2;   /* list bullets, chip dots, Landmark tag     */
  /* The one teal that can carry white body text: 4.74:1 against the brand
     teal's 3.14:1. Same hue, 9% darker. Used where white sits on a teal
     fill rather than teal sitting on white.                              */
  --teal-deep:     #267e8a;

  /* ---- neutrals ----------------------------------------------------- */
  --white:         #ffffff;
  --ink:           #000000;
  --ink-muted:     rgba(0, 0, 0, .65);
  --chip:          #f4f6f7;
  /* the same chip, one step down, for a filled card under the cursor */
  --chip-deep:     #e7edef;
  --rule:          rgba(0, 0, 0, .16);
  --rule-onteal:   rgba(255, 255, 255, .28);
  --on-dark:       rgba(255, 255, 255, .85);
  --on-dark-muted: rgba(255, 255, 255, .65);

  /* ---- type --------------------------------------------------------- */
  --font: "DM Sans", ui-sans-serif, system-ui, -apple-system, "Segoe UI",
          Roboto, Helvetica, Arial, sans-serif;

  --fs-display: clamp(2.5rem, 1.2rem + 3.2vw, 4.5rem);   /* h1   72 */
  /* An interior page header is a label for the page, not the opening
     statement the home page makes, so it steps down one size: 56px against
     72px at the top end, 36px against 40px at the bottom. */
  --fs-display-inner: clamp(2.25rem, 1.15rem + 2.4vw, 3.5rem);  /* h1   56 */
  --fs-h2:      clamp(2rem, 1.3rem + 1.4vw, 3rem);       /* h2   48 */
  --fs-h3:      clamp(1.5rem, 1.15rem + 0.75vw, 2rem);   /* h3   32 */
  --fs-h4:      clamp(1.25rem, 1.1rem + 0.35vw, 1.5rem); /* tile 24 */
  --fs-body:    1.125rem;                                /* 18 */
  --fs-base:    1rem;                                    /* 16 */
  --fs-sm:      0.9375rem;                               /* 15 */
  --fs-xs:      0.875rem;                                /* 14 */
  --fs-eyebrow: 0.8125rem;                               /* 13 */
  --fs-tag:     0.75rem;                                 /* 12 */

  --lh-display: 1.04;
  --lh-h2:      1.1;
  --lh-tight:   1.3;
  --lh-body:    1.39;
  --lh-loose:   1.67;

  --ls-eyebrow: 0.03em;

  /* ---- spacing (8pt) ------------------------------------------------ */
  --s1: 8px;   --s2: 16px;  --s3: 24px;  --s4: 32px;
  --s5: 40px;  --s6: 48px;  --s7: 64px;  --s8: 80px;
  --s9: 96px;  --s10: 120px; --s11: 160px;

  /* ---- layout ------------------------------------------------------- */
  --container: 1800px;  /* outer box; the gutter lives inside it         */
  --gutter:    100px;   /* so content measures 1600px once past 1800px   */
  --gap:       20px;    /* card and tile gutter, straight from the comp  */
  --split-gap: 96px;
  --section-py: var(--s8);

  /* masthead sizing lives here because the mobile menu panel has to sit
     exactly below the bar, and both need to agree at every breakpoint */
  --head-h:    95px;   /* bar height at rest            */
  --head-h-sm: 72px;   /* bar height once stuck         */
  --logo-w:    218px;  /* logo width at rest            */
  --logo-w-sm: 168px;  /* logo width once stuck         */

  --btn-h:  44px;
  --btn-px: 28px;

  --focus: 3px solid var(--purple);
}

@media (max-width: 1100px) {
  :root { --gutter: 48px; --split-gap: 56px; --section-py: 72px; }
}
@media (max-width: 900px) {
  :root { --head-h: 72px; --head-h-sm: 60px; --logo-w: 176px; --logo-w-sm: 148px; }
}

@media (max-width: 640px) {
  :root { --gutter: 24px; --split-gap: 40px; --section-py: 56px; --gap: 16px; }
}

/* An AA-safe sibling of the brand teal, same hue, 9% darker. Not applied:
   the comp's #309fae is kept as drawn. Swapping these two lines raises every
   teal button, inline link and the footer ground to 4.74:1. See NOTES.md.
   --teal: #267e8a;
   --teal-accent: #267e8a; */

/* assets/css/base.css */

/* base */

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

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

body {
  margin: 0;
  font-family: var(--font);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  color: var(--ink);
  background: var(--white);
  -webkit-font-smoothing: antialiased;
}

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

img { height: auto; }

h1, h2, h3, h4, p, ul, figure { margin: 0; }

ul { padding: 0; list-style: none; }

a { color: inherit; }

:where(a, button, summary):focus-visible {
  outline: var(--focus);
  outline-offset: 3px;
}

.skip {
  position: absolute; left: -9999px; top: 0; z-index: 100;
  padding: var(--s2) var(--s3);
  background: var(--white); color: var(--ink);
}

.skip:focus { left: 0; }

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

.section { padding-block: var(--section-py); }

.surface-alt { background: var(--chip); }

.surface-alt + .surface-alt { padding-top: var(--s5); }

.surface-purple { background: var(--purple); }

.surface-teal { background: var(--teal); }

.surface-purple,
.surface-teal { color: var(--white); }

.surface-purple .h1, .surface-teal .h1,
.surface-purple .h2, .surface-teal .h2,
.surface-purple .h3, .surface-teal .h3,
.surface-purple .h4, .surface-teal .h4,
.surface-purple .eyebrow, .surface-teal .eyebrow { color: var(--white); }

.surface-purple .lede { color: var(--on-dark-muted); }

.surface-teal .lede { color: var(--white); }

.surface-purple .facts li, .surface-teal .facts li { border-bottom-color: var(--rule-onteal); }

.surface-purple .facts, .surface-teal .facts { border-top-color: var(--rule-onteal); }

.h1 {
  font-size: var(--fs-display);
  font-weight: 600;
  line-height: var(--lh-display);
  letter-spacing: -0.01em;
}

.h2 {
  font-size: var(--fs-h2);
  font-weight: 600;
  line-height: var(--lh-h2);
  letter-spacing: -0.005em;
}

.h3 { font-size: var(--fs-h3); font-weight: 600; line-height: var(--lh-tight); }

.h4 { font-size: var(--fs-h4); font-weight: 600; line-height: var(--lh-tight); }

.lede { color: var(--ink-muted); line-height: 1.39; }

:is(.h1, .h2, .h3) + .lede { margin-top: var(--s3); }

.lede + .lede { margin-top: var(--s3); }

:is(.lede, .facts, .group__list) + .alink { margin-top: var(--s5); }

.lede--onDark { color: var(--on-dark-muted); }

.eyebrow {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 12px;
  font-size: var(--fs-eyebrow);
  font-weight: 600;
  line-height: var(--lh-tight);
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
  color: var(--purple);
}

.eyebrow::before {
  content: "";
  flex: none;
  width: 19px;
  height: 9px;
  background:
    linear-gradient(var(--purple),  var(--purple))  0    0 / 5px 9px no-repeat,
    linear-gradient(var(--magenta), var(--magenta)) 7px  0 / 5px 9px no-repeat,
    linear-gradient(var(--cyan),    var(--cyan))    14px 0 / 5px 9px no-repeat;
}

.btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: var(--btn-h);
  padding-inline: var(--btn-px);
  font-size: var(--fs-sm);
  font-weight: 500;
  line-height: 1.3;
  /* Not nowrap. A long label used to push the button past the viewport at
     390px rather than wrapping, which broke the page instead of the line. The
     arrow is flex:none, so it holds its place beside a label that wraps. */
  max-width: 100%;
  text-decoration: none;
  border: 0;
  cursor: pointer;
  transition: background-color .18s ease, color .18s ease;
}

.btn--teal { background: var(--teal);  color: var(--white); }

.btn--white { background: var(--white); color: var(--ink); }

.btn--purple { background: var(--purple); color: var(--white); }

.btn--teal:hover { background: #1f6b76; }

.btn--white:hover { background: #ebeff0; }

.btn--purple:hover { background: #5c1f60; }

.alink {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: var(--fs-sm);
  font-weight: 500;
  line-height: 1.3;
  text-decoration: none;
  color: var(--teal);
}

.alink--onDark { color: var(--white); }

.alink__label {
  position: relative;
  display: inline-block;
}

.alink .alink__label::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -3px;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: right center;
  transition: transform .34s cubic-bezier(.22, .61, .36, 1);
}

.alink:hover .alink__label::after,
.alink:focus-visible .alink__label::after {
  transform: scaleX(1);
  transform-origin: left center;
}

.arrow {
  flex: none;
  width: 10px;
  height: 8px;
  transition: transform .18s ease;
}

.btn:hover .arrow,
.alink:hover .arrow { transform: translateX(3px); }

.section:has(> .wrap > .note) { padding-top: 0; }

.section:has(+ .section--note) { padding-bottom: 0; }

.section:has(.slider) {
  overflow-x: clip;
  overflow-y: visible;
}

@media (prefers-reduced-motion: reduce) {
  .alink .alink__label::after { transition: none; }
  .arrow { transition: none; }
  .btn:hover .arrow,
  .alink:hover .arrow { transform: none; }
  .js .nav__list li,
  .js .masthead__end {
    opacity: 1;
    transform: none;
    transition: none;
    transition-delay: 0s;
  }
}

.js [data-reveal] {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity .55s cubic-bezier(.22, .61, .36, 1),
              transform .55s cubic-bezier(.22, .61, .36, 1);
}

.js [data-reveal].is-in {
  opacity: 1;
  transform: none;
}

.js .hero__lede { transition-delay: .07s; }

.js .hero__actions { transition-delay: .14s; }

.js .cards > :nth-child(2) { transition-delay: .09s; }

.js .cards > :nth-child(3) { transition-delay: .18s; }

.js .cards > :nth-child(4) { transition-delay: .27s; }

.js .projects__row > :nth-child(2) { transition-delay: .09s; }

@media (prefers-reduced-motion: reduce) {
  .js [data-reveal] {
    opacity: 1;
    transform: none;
    transition: none;
    transition-delay: 0s;
  }
}

@media (max-width: 1100px) {
  .js .nav {
    visibility: hidden;
    opacity: 0;
    transition: opacity .25s ease, visibility 0s linear .25s;
  }
  .js .masthead.is-open .nav {
    visibility: visible;
    opacity: 1;
    transition: opacity .25s ease;
  }
  .js .nav__list li,
  .js .masthead__end {
    opacity: 0;
    transform: translateY(12px);
    transition: opacity .3s ease, transform .3s cubic-bezier(.22, .61, .36, 1);
  }
  .js .masthead.is-open .nav__list li,
  .js .masthead.is-open .masthead__end { opacity: 1; transform: none; }
  .js .masthead.is-open .nav__list li:nth-child(1) { transition-delay: .07s; }
  .js .masthead.is-open .nav__list li:nth-child(2) { transition-delay: .14s; }
  .js .masthead.is-open .nav__list li:nth-child(3) { transition-delay: .21s; }
  .js .masthead.is-open .nav__list li:nth-child(4) { transition-delay: .28s; }
  .js .masthead.is-open .nav__list li:nth-child(5) { transition-delay: .35s; }
  .js .masthead.is-open .masthead__end { transition-delay: .42s; }
}

/* assets/css/chrome.css */

/* chrome */

.utility {
  background: var(--purple);
  color: var(--white);
  text-align: center;
  padding-block: var(--s1);
}

.utility .alink { justify-content: center; }

.masthead {
  position: sticky;
  top: 0;
  z-index: 50;
  background: var(--white);
  /* the comp has no rule under the header, but once it floats over white
     sections it needs an edge or it dissolves into the page */
  box-shadow: 0 1px 0 rgba(0, 0, 0, .09);
}

.stickySentinel { height: 1px; }

.masthead__inner {
  display: flex;
  align-items: center;
  gap: var(--s5);
  min-height: var(--head-h);
  transition: min-height .22s ease;
}

.masthead__logo { flex: none; }

.masthead__logo img {
  width: var(--logo-w);
  height: auto;
  transition: width .22s ease;
}

.masthead.is-stuck .masthead__inner { min-height: var(--head-h-sm); }

.masthead.is-stuck .masthead__logo img { width: var(--logo-w-sm); }

.masthead.is-open .masthead__inner { min-height: var(--head-h); }

.masthead.is-open .masthead__logo img { width: var(--logo-w); }

.masthead.is-open .masthead__inner,
.masthead.is-open .masthead__logo img { transition: none; }

.nav {
  display: flex;
  align-items: center;
  gap: var(--s5);
  margin-left: auto;
}

.nav__list {
  display: flex;
  align-items: center;
  gap: var(--s5);
}

.nav__list a {
  font-size: var(--fs-base);
  font-weight: 500;
  text-decoration: none;
}

.nav__list a:hover { color: var(--teal); }

.masthead__end {
  display: flex;
  align-items: center;
  gap: var(--s4);
}

.masthead__rule {
  width: 1px;
  height: 29px;
  background: var(--ink);
  opacity: .25;
}

.masthead__tel {
  font-size: var(--fs-base);
  font-weight: 500;
  text-decoration: none;
  white-space: nowrap;
}

.navToggle { display: none; }

.navToggle span {
  position: absolute;
  left: 10px;
  right: 10px;
  height: 2px;
  background: var(--ink);
  transition: transform .25s ease, opacity .15s ease;
}

.navToggle span:nth-child(1) { top: 14px; }

.navToggle span:nth-child(2) { top: 21px; }

.navToggle span:nth-child(3) { top: 28px; }

.masthead.is-open .navToggle span:nth-child(1) { transform: translateY(7px) rotate(45deg); }

.masthead.is-open .navToggle span:nth-child(2) { opacity: 0; }

.masthead.is-open .navToggle span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

.is-navOpen { overflow: hidden; }

@media (prefers-reduced-motion: reduce) {
  .masthead__inner,
  .masthead__logo img,
  .navToggle span { transition: none; }
}

.footer {
  background: var(--teal);
  color: var(--white);
  padding-block: var(--s10) var(--s5);
}

.footer__top {
  display: grid;
  grid-template-columns: 300px repeat(4, minmax(0, 1fr));
  gap: var(--s5);
}

.footer__name {
  font-size: var(--fs-h4);
  font-weight: 600;
  line-height: var(--lh-tight);
}

.footer__addr {
  margin-top: var(--s3);
  font-style: normal;
  line-height: 1.5;
  color: var(--white);
}

.footer__addr a { text-decoration: none; }

.footer__addr a:hover { text-decoration: underline; }

.footer .btn { margin-top: var(--s6); }

.footer__colTitle {
  font-size: var(--fs-base);
  font-weight: 600;
  line-height: var(--lh-tight);
}

.footer__colTitle a { text-decoration: none; }

.footer__colTitle a:hover { text-decoration: underline; text-underline-offset: 3px; }

.footer__links { margin-top: 12px; }

.footer__links a {
  display: inline-block;
  padding-block: 3px;
  line-height: var(--lh-loose);
  text-decoration: none;
  color: var(--white);
}

.footer__links a:hover { text-decoration: underline; text-underline-offset: 3px; }

.footer__bottom {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--s3);
  margin-top: var(--s10);
  padding-top: var(--s3);
  border-top: 1px solid var(--rule-onteal);
  font-size: var(--fs-xs);
  line-height: 1.9;
}

@media (max-width: 1560px) {
  .footer__links a { font-size: var(--fs-base); }
}

@media (max-width: 1280px) {
  .footer__top { grid-template-columns: 280px repeat(4, minmax(0, 1fr)); gap: var(--s4); }
}

@media (max-width: 1100px) {
  .footer__top { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s8) var(--s5); }
  .footer__brand { grid-column: 1 / -1; }
}

@media (max-width: 1100px) {
  .masthead__rule { display: none; }
  .navToggle {
    position: relative;
    display: block;
    flex: none;
    width: var(--btn-h);
    height: var(--btn-h);
    /* no chrome, but keep the 44px tap target and pull the box out by its own
       inset so the bars line up with the container edge rather than float in */
    margin-left: auto;
    margin-right: -10px;
    padding: 0;
    background: none;
    border: 0;
    cursor: pointer;
  }
  .nav {
    position: fixed;
    top: calc(var(--nav-top, 0px) + var(--head-h));
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 60;
    display: block;
    margin: 0;
    padding: var(--s3) var(--gutter) var(--s9);
    background: var(--white);
    overflow-y: auto;
    overscroll-behavior: contain;
  }
  .nav__list { flex-direction: column; align-items: stretch; gap: 0; }
  .nav__list a {
    display: block;
    padding-block: var(--s3);
    font-size: var(--fs-h4);
    border-bottom: 1px solid var(--rule);
  }
  .masthead__end {
    flex-direction: column;
    align-items: flex-start;
    gap: var(--s4);
    margin-top: var(--s7);
  }
  .masthead__tel { font-size: var(--fs-h4); }
}

@media (max-width: 640px) {
  .masthead__end { flex: 1 1 100%; justify-content: space-between; }
  .footer__top { grid-template-columns: minmax(0, 1fr); gap: var(--s7); }
  .footer { padding-block: var(--s9) var(--s5); }
  .footer__bottom { margin-top: var(--s8); }
}


/* ---- floating emergency button ---------------------------------------- */

/* Chrome, not a section: one element, printed once by the footer, on every
   template. It sits below the mobile nav panel (z-index 60) on purpose, so an
   open menu covers it rather than the reverse.

   Purple rather than a louder brand colour. The emergency CTA now reads as one
   thing site-wide (top bar, hero, footer, here), and white on #6c2471 is 9.9:1,
   where white on the magenta is 4.7:1 and has nothing left for a hover state.
   What makes it stand out is the size, the shadow and the ring, not a new hue. */

.floatCta {
  position: fixed;
  right: var(--s3);
  bottom: var(--s3);
  z-index: 40;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-height: 56px;
  padding-inline: 22px;
  font-size: var(--fs-sm);
  font-weight: 600;
  line-height: 1.2;
  text-decoration: none;
  color: var(--white);
  background: var(--purple);
  box-shadow:
    0 10px 30px rgba(108, 36, 113, .38),
    0 2px 8px rgba(0, 0, 0, .18);
  transition: background-color .18s ease, box-shadow .18s ease;
}

.floatCta:hover {
  background: #5c1f60;
  box-shadow:
    0 14px 36px rgba(108, 36, 113, .46),
    0 3px 10px rgba(0, 0, 0, .2);
}

/* The global ring is var(--focus), which is purple on a purple pill. */
.floatCta:focus-visible {
  outline: 3px solid var(--ink);
  outline-offset: 3px;
}

.floatCta__icon { flex: none; width: 20px; height: 20px; }

/* The pulse lives on a pseudo-element, not the anchor, so that :hover keeps
   control of the anchor's own box-shadow: an animated property cannot be
   overridden by a rule. Nothing is painted inside the box, only the spread
   outside it, so the pill is never covered. */
.floatCta::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
}

/* Three runs on arrival, not a perpetual loop. The button reveals on scroll,
   so an animation started at load would have finished before anyone saw it,
   and motion that never stops is both an irritant on every page and the thing
   WCAG 2.2.2 is about. Change the 3 to "infinite" to have it never settle. */
.floatCta.is-in::after,
html:not(.js) .floatCta::after {
  animation: floatCtaPulse 2.8s ease-out 3;
}

@keyframes floatCtaPulse {
  0%   { box-shadow: 0 0 0 0 rgba(108, 36, 113, .55); }
  70%  { box-shadow: 0 0 0 18px rgba(108, 36, 113, 0); }
  100% { box-shadow: 0 0 0 0 rgba(108, 36, 113, 0); }
}

/* Hidden until the script says otherwise, and only when there is a script.
   Without one the button is simply present from the top of the page, which is
   a worse reveal but a working phone number. visibility rather than opacity
   alone, or the keyboard would tab into an invisible control. */
.js .floatCta {
  opacity: 0;
  visibility: hidden;
  transform: translateY(14px) scale(.94);
  transition: background-color .18s ease, box-shadow .18s ease,
              opacity .3s ease, transform .3s ease, visibility 0s linear .3s;
}

.js .floatCta.is-in {
  opacity: 1;
  visibility: visible;
  transform: none;
  transition: background-color .18s ease, box-shadow .18s ease,
              opacity .3s ease, transform .3s ease, visibility 0s;
}

@media (max-width: 640px) {
  .floatCta {
    right: var(--s2);
    bottom: var(--s2);
    min-height: 50px;
    padding-inline: 18px;
    font-size: var(--fs-xs);
  }
  .floatCta__icon { width: 18px; height: 18px; }
}

@media (prefers-reduced-motion: reduce) {
  /* Selectors mirrored exactly, not shortened. A media query adds no
     specificity, so a plainer .floatCta::after here would lose to the
     two-class rule above and the pulse would run anyway. */
  .floatCta.is-in::after,
  html:not(.js) .floatCta::after { animation: none; }
  .js .floatCta { transform: none; }
  .js .floatCta,
  .js .floatCta.is-in { transition: none; }
}

/* sections/hero/hero.css */

/* hero */

.hero {
  position: relative;
  display: flex;
  align-items: flex-end;
  min-height: clamp(520px, 47vw, 903px);
  isolation: isolate;
  color: var(--white);
}

.hero__img {
  position: absolute;
  inset: 0;
  z-index: -2;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 58%;
}

.hero::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(
    to top,
    rgba(0, 0, 0, .84) 0%,
    rgba(0, 0, 0, .66) 24%,
    rgba(0, 0, 0, .34) 52%,
    rgba(0, 0, 0, .08) 78%,
    rgba(0, 0, 0, 0) 100%);
}

.hero__inner { padding-block: var(--s9) var(--s11); }

.hero .h1 { max-width: 13.5em; }

.hero__lede {
  max-width: 68ch;
  margin-top: var(--s3);
  color: var(--on-dark);
}

.hero__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s3);
  margin-top: var(--s6);
}

.hero--compact { min-height: clamp(360px, 30vw, 560px); }

.hero--compact .hero__inner { padding-block: var(--s9) var(--s9); }

.hero--compact::after {
  background: rgba(0, 0, 0, .55);
}

.hero--compact .h1 { max-width: 14em; font-size: var(--fs-display-inner); }

.hero--compact .hero__lede { max-width: 58ch; }

.hero__contact {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s4) var(--s8);
  margin-top: var(--s6);
}

.hero__contact dt {
  font-size: var(--fs-eyebrow);
  font-weight: 600;
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
  color: var(--on-dark-muted);
}

.hero__contact dd {
  /* the UA gives dd a 40px inline start margin, which indents every value
     under its own label */
  margin: 6px 0 0;
  font-size: var(--fs-h4);
  line-height: var(--lh-tight);
}

.hero__contact a { color: var(--white); text-decoration: none; }

.hero__contact a:hover {
  text-decoration: underline;
  text-underline-offset: 4px;
}

@media (max-width: 900px) {
  .hero__contact { gap: var(--s4) var(--s7); }
  .hero__inner { padding-block: var(--s8) var(--s9); }
  .hero__actions { gap: var(--s3); margin-top: var(--s6); }
}

@media (max-width: 640px) {
  .hero__actions { flex-direction: column; align-items: flex-start; }
}

/* sections/prose/prose.css */

/* prose */

.prose {
  display: grid;
  grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr);
  gap: var(--split-gap);
  align-items: start;
}

.prose__body { max-width: 62ch; }

.prose > .note { grid-column: 2; }

.prose__mark {
  width: 132px;
  height: auto;
  margin-top: var(--s5);
}

.prose__body p + p { margin-top: var(--s3); }

.prose__body .btn { margin-top: var(--s7); }

@media (max-width: 900px) {
  .prose { grid-template-columns: minmax(0, 1fr); gap: var(--s5); }
  .prose__body { max-width: none; }
  .prose > .note { grid-column: auto; }
}

@media (max-width: 640px) {
  .prose__body .btn { margin-top: var(--s6); }
}

/* sections/intro/intro.css */

/* intro */

.intro { max-width: 62ch; }

/* sections/accordion/accordion.css */

/* accordion */

.acc {
  margin-top: var(--s5);
  border-top: 1px solid var(--rule);
}

.acc__item { border-bottom: 1px solid var(--rule); }

.acc__q {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--s4);
  padding-block: var(--s3);
  font-size: var(--fs-base);
  font-weight: 600;
  line-height: var(--lh-tight);
  cursor: pointer;
  list-style: none;
}

.acc__q::-webkit-details-marker { display: none; }

.acc__q:hover { color: var(--teal); }

.acc__q::after {
  content: "";
  flex: none;
  width: 12px;
  height: 12px;
  margin-top: 5px;
  background-image:
    linear-gradient(currentColor, currentColor),
    linear-gradient(currentColor, currentColor);
  background-position: center, center;
  background-repeat: no-repeat;
  background-size: 100% 1.6px, 1.6px 100%;
  transition: background-size .2s ease;
}

.acc__item[open] .acc__q::after { background-size: 100% 1.6px, 1.6px 0; }

.acc__panel {
  overflow: hidden;
  transition: height .28s cubic-bezier(.22, .61, .36, 1);
}

.acc__a {
  padding-bottom: var(--s3);
  font-size: var(--fs-sm);
  color: var(--ink-muted);
  line-height: 1.45;
}

.acc__a p + p { margin-top: var(--s2); }

.acc__a .facts {
  max-width: none;
  margin-top: var(--s3);
}

.acc__a .facts + p { margin-top: var(--s3); }

/* sections/list/list.css */

/* list */

.blocks--marked .block__title {
  display: flex;
  align-items: baseline;
  gap: var(--s2);
}

.blocks--marked .block__title::before {
  content: "";
  flex: none;
  width: 9px;
  height: 9px;
  background: var(--teal-accent);
  transform: translateY(-1px);
}

/* sections/categories/categories.css */

/* categories */

/* The section's own link, below the grid. Matches .groups__closing's offset so
   a section with both reads as one block rather than two stacked afterthoughts. */
.categories__foot { margin-top: var(--s6); }

.block__img {
  width: 100%;
  aspect-ratio: 16 / 6;
  object-fit: cover;
  margin-bottom: var(--s3);
}

/* sections/compare/compare.css */

/* compare */

.blocks--1 {
  --blocks-cols: 1;
  gap: var(--s5);
}

/* sections/steps/steps.css */

/* steps */

.blocks {
  display: grid;
  /* A count, not auto-fit. Auto-fit chose four for a set of five and left one
     block alone on a second row, reading as a mistake. */
  grid-template-columns: repeat(var(--blocks-cols, 3), minmax(0, 1fr));
  gap: var(--s7) var(--s6);
  margin-top: var(--s6);
}

.blocks:has(.block--boxed) { gap: 20px; }

.blocks--2 { --blocks-cols: 2; }

.blocks--4 { --blocks-cols: 4; }

.block { border-top: 1px solid var(--rule); padding-top: var(--s3); }

.block--boxed {
  height: 100%;
  padding: var(--s5);
  border: 1px solid var(--rule);
}

.block--fill {
  border-color: transparent;
  background: var(--teal-deep);
  color: var(--white);
}

.block--fill .block__title,
.block--fill .block__body,
.block--fill .block__icon { color: inherit; }

.blocks--steps { counter-reset: step; }

.blocks--steps .block { counter-increment: step; }

.block--plain {
  border-top: 0;
  padding-top: 0;
}

.block__step {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  margin-bottom: var(--s3);
  border-radius: 50%;
  background: var(--teal-deep);
  color: var(--white);
  font-size: var(--fs-sm);
  font-weight: 600;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}

.block__step::before { content: counter(step); }

.block:has(.block__img) {
  border-top: 0;
  padding-top: 0;
}

.block__icon {
  display: block;
  width: 28px;
  height: 28px;
  margin-bottom: var(--s5);
  color: var(--teal-accent);
}

.block--boxed .block__icon { width: 40px; height: 40px; }

.block__title {
  font-size: var(--fs-h4);
  font-weight: 600;
  line-height: var(--lh-tight);
}

.block__body {
  margin-top: var(--s2);
  /* Body copy, so the body size. It was --fs-sm, which is the size for a
     caption or a list row, not for the paragraph a reader is meant to read. */
  font-size: var(--fs-body);
  color: var(--ink-muted);
  line-height: 1.45;
}

.block__body p + p { margin-top: var(--s2); }

.block .facts {
  max-width: none;
  margin-top: var(--s3);
}

.steps {
  /* One source for the gap between steps, because the connector is sized to
     fill it exactly. Set the two separately and the line stops short of the
     next dot at one breakpoint and overshoots at another. */
  --step-gap: var(--s8);
  /* The <ol> stays an <ol> so the order is in the markup, but its own markers
     are suppressed: the dots already carry the numbers, and the previous
     layout hid the markers only as a side effect of display:grid on the item. */
  list-style: none;
  max-width: 720px;
  margin-top: var(--s6);
  margin-inline: auto;
  text-align: center;
  counter-reset: step;
}

.step {
  position: relative;
  padding-bottom: var(--step-gap);
}

.step:last-child { padding-bottom: 0; }

.step::before {
  content: "";
  position: absolute;
  left: 50%;
  bottom: 0;
  width: 1px;
  height: var(--step-gap);
  margin-left: -0.5px;
  background: var(--rule);
}

.step:last-child::before { content: none; }

.step__dot {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  margin-bottom: var(--s3);
  border-radius: 50%;
  /* teal-deep, not the brand teal: the numeral is 14px text and white on
     --teal is 3.14:1. This is 4.74:1. */
  background: var(--teal-deep);
  color: var(--white);
  font-size: var(--fs-sm);
  font-weight: 600;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}

.step__dot::before { counter-increment: step; content: counter(step); }

.step__title {
  font-size: var(--fs-h4);
  font-weight: 600;
  line-height: var(--lh-tight);
}

.step__body {
  max-width: 56ch;
  margin-top: var(--s2);
  margin-inline: auto;
  color: var(--ink-muted);
  line-height: 1.45;
}

.step__body p + p { margin-top: var(--s2); }

.step__list {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0 var(--s5);
  max-width: 52ch;
  margin-top: var(--s3);
  margin-inline: auto;
  text-align: left;
}

.step__list li {
  display: flex;
  align-items: baseline;
  gap: var(--s2);
  padding-block: 6px;
  font-size: var(--fs-sm);
  line-height: var(--lh-tight);
}

.step__list li::before {
  content: "";
  flex: none;
  width: 9px;
  height: 9px;
  background: var(--teal-accent);
  transform: translateY(-1px);
}

.block--boxed:has(.alink) {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}

.block--boxed .alink { margin-top: auto; padding-top: var(--s4); }

.block--boxed .alink + .alink { margin-top: 0; padding-top: var(--s2); }

@media (max-width: 1100px) {
  .blocks:not(.blocks--1) { --blocks-cols: 2; }
}

@media (max-width: 640px) {
  .blocks:not(.blocks--1) { --blocks-cols: 1; gap: var(--s5); }
  .blocks:has(.block--boxed) { gap: 20px; }
  .steps { --step-gap: var(--s7); }
  .step__list { grid-template-columns: minmax(0, 1fr); }
}

/* sections/slider/slider.css */

/* slider */

.slider { margin-top: var(--s6); }

.slider__track {
  /* One source for the gap, because the column width is derived from it. Set
     the two separately and three cards stop filling the row exactly. Off the
     8px scale on purpose: Big Matt asked for 20px here. */
  --slider-gap: 20px;
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: calc((100% - 2 * var(--slider-gap)) / 3);
  gap: var(--slider-gap);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  /* bleed past the container to the viewport edge, then pad the same amount
     back so the first card still lines up with everything above it */
  margin-right: calc(50% - 50vw);
  padding-right: calc(50vw - 50%);
  scrollbar-width: none;
}

.slider__track::-webkit-scrollbar { display: none; }

.slider__cell {
  scroll-snap-align: start;
  display: flex;
}

.slider__foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--s3) var(--s5);
  margin-top: var(--s5);
}

.slider__nav {
  display: flex;
  gap: var(--s2);
  margin-top: var(--s5);
}

.slider__foot .slider__nav { margin-top: 0; }

.slider__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  background: none;
  border: 1px solid var(--rule);
  color: inherit;
  cursor: pointer;
  transition: border-color .18s ease, opacity .18s ease;
}

.slider__btn:hover:not(:disabled) { border-color: currentColor; }

.slider__btn:disabled { opacity: .3; cursor: default; }

.slider__btn .arrow { width: 14px; height: 10px; }

.slider__btn--prev .arrow { transform: rotate(180deg); }

.slider__btn:hover .arrow { transform: none; }

.slider__btn--prev:hover .arrow { transform: rotate(180deg); }

@media (max-width: 1100px) {
  .slider__track { grid-auto-columns: calc((100% - var(--slider-gap)) / 2); }
}

@media (max-width: 640px) {
  .slider__track { grid-auto-columns: 78%; }
}

/* sections/note/note.css */

/* note */

.note {
  max-width: 76ch;
  margin-top: var(--s5);
  padding-top: var(--s3);
  border-top: 1px solid var(--rule);
  font-size: var(--fs-xs);
  color: var(--ink-muted);
  line-height: 1.5;
}

.note p + p { margin-top: var(--s2); }

.note a { color: inherit; text-decoration: underline; }

/* sections/groups/groups.css */

/* groups */

.groups {
  display: grid;
  /* auto-fit, not a fixed 4. With three groups a hard four-column grid left
     a quarter of the row empty and the set read as though something had
     failed to load. Four groups still make four columns. */
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: var(--s7) var(--s6);
  margin-top: var(--s6);
}

.group { border-top: 1px solid var(--rule); padding-top: var(--s3); }

.groups__closing {
  max-width: 62ch;
  margin-top: var(--s6);
}

.group__title {
  font-size: var(--fs-base);
  font-weight: 600;
  line-height: var(--lh-tight);
}

.group__list { margin-top: var(--s3); }

.group__list li {
  display: flex;
  align-items: baseline;
  gap: var(--s2);
  padding-block: 6px;
  font-size: var(--fs-sm);
  line-height: 1.4;
  color: var(--ink-muted);
}

.group__list li::before {
  content: "";
  flex: none;
  width: 6px;
  height: 6px;
  background: var(--teal-accent);
  transform: translateY(-1px);
}

@media (max-width: 900px) {
  .groups { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 640px) {
  .groups { grid-template-columns: minmax(0, 1fr); gap: var(--s5); }
}

/* sections/faq/faq.css */

/* faq */

.faq__head {
  max-width: 940px;
  margin-inline: auto;
  text-align: center;
}

.faq__head .eyebrow { justify-content: center; }

.faq {
  max-width: 940px;
  margin-top: var(--s7);
  margin-inline: auto;
  border-top: 1px solid var(--rule);
}

.faq__item { border-bottom: 1px solid var(--rule); }

.faq__q {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--s5);
  padding-block: var(--s3);
  font-size: var(--fs-h4);
  font-weight: 600;
  line-height: var(--lh-tight);
  cursor: pointer;
  list-style: none;
}

.faq__q::-webkit-details-marker { display: none; }

.faq__q:hover { color: var(--teal); }

.faq__q::after {
  content: "";
  flex: none;
  width: 9px;
  height: 9px;
  margin-top: 9px;
  border-right: 1.6px solid currentColor;
  border-bottom: 1.6px solid currentColor;
  transform: rotate(45deg);
  transition: transform .2s ease;
}

.faq__item[open] .faq__q::after { transform: rotate(-135deg) translate(-2px, -2px); }

.faq__panel {
  overflow: hidden;
  transition: height .28s cubic-bezier(.22, .61, .36, 1);
}

.faq__a { padding-bottom: var(--s4); }

.faq__a p + p { margin-top: var(--s3); }

@media (prefers-reduced-motion: reduce) {
  .faq__q::after,
  .faq__panel { transition: none; }
}

@media (max-width: 900px) {
  .faq__q { font-size: var(--fs-body); gap: var(--s3); }
}

/* sections/split/split.css */

/* split */

.split {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, .88fr);
  gap: var(--split-gap);
  align-items: center;
}

.split--mediaLeft {
  grid-template-columns: minmax(0, .98fr) minmax(0, 1fr);
}

.split--mediaLeft .split__media { order: -1; }

.split__body { max-width: 44em; }

.split__body .lede { margin-top: var(--s3); }

.facts {
  max-width: 36em;
  margin-top: var(--s6);
  border-top: 1px solid var(--rule);
}

.facts li {
  display: flex;
  align-items: baseline;
  gap: var(--s2);
  padding-block: var(--s2);
  font-size: var(--fs-base);
  line-height: var(--lh-tight);
  border-bottom: 1px solid var(--rule);
}

.facts--2 {
  max-width: none;
  columns: 2;
  column-gap: var(--s6);
}

.facts--2 li { break-inside: avoid; }

.facts--rows {
  max-width: none;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  column-gap: var(--s6);
}

.facts li::before {
  content: "";
  flex: none;
  width: 9px;
  height: 9px;
  background: var(--teal-accent);
  transform: translateY(-1px);
}

.facts + p { margin-top: var(--s5); }

.split__body .btn { margin-top: var(--s7); }

.plate { position: relative; }

.plate__main {
  width: 100%;
  aspect-ratio: 653 / 743;
  object-fit: cover;
}

.plate__inset {
  position: absolute;
  left: -20%;
  bottom: -12%;
  width: 64%;
  aspect-ratio: 417 / 289;
  object-fit: cover;
  border: 10px solid var(--white);
}

.plate__inset--portrait {
  width: 42%;
  aspect-ratio: 3 / 4;
}

.plate:has(.plate__inset) { margin-bottom: 13.7%; }

.plate--wide:has(.plate__inset) { margin-bottom: 11%; }

.plate--wide .plate__main { aspect-ratio: 789 / 723; }

.plate--wide .plate__inset { left: -9%; }

.plate--panorama .plate__main { aspect-ratio: 16 / 9; }

.plate--map .plate__main {
  aspect-ratio: 788 / 632;
  border: 1px solid var(--rule);
}

@media (max-width: 900px) {
  .split, .split--mediaLeft { grid-template-columns: minmax(0, 1fr); }
  .split--mediaLeft .split__media { order: 0; }
  .split__media { order: -1; }
  .split__body { max-width: none; }
  .plate__main, .plate--wide .plate__main { aspect-ratio: 16 / 11; }
  .plate__inset { left: 0; right: auto; bottom: -48px; width: 54%; }
  .plate__inset--portrait { width: 38%; }
  .plate:has(.plate__inset) { margin-bottom: 48px; }
}

@media (max-width: 640px) {
  .facts--rows { grid-template-columns: minmax(0, 1fr); }
  .facts--2 { columns: 1; }
  .facts { margin-top: var(--s6); }
  .split__body .btn { margin-top: var(--s6); }
  .plate__inset { width: 62%; bottom: -36px; border-width: 6px; }
  .plate__inset--portrait { width: 36%; }
  .plate:has(.plate__inset) { margin-bottom: 36px; }
}

/* sections/services/services.css */

/* services */

.cards {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--gap);
  margin-top: var(--s6);
}

.cards--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s7) var(--split-gap); }

.cards--2 .card__img { aspect-ratio: 2 / 1; }

.cards--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }

.card {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}

.card__img {
  width: 100%;
  aspect-ratio: 519 / 410;
  object-fit: cover;
}

.card__title { margin-top: var(--s3); }

.card .card__body { margin-top: var(--s2); }

.card .alink { margin-top: auto; padding-top: var(--s4); }

.cards--press .card {
  position: relative;
  padding: var(--s3);
  background: var(--chip);
  transition: background .2s ease;
}

.cards--press .card:hover { background: var(--chip-deep); }

.cards--press .card__img { aspect-ratio: 16 / 9; }

.cards--press .card__title {
  margin-top: var(--s4);
  font-size: var(--fs-h4);
}

.card__foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s3);
  width: 100%;
  margin-top: auto;
  padding-top: var(--s6);
}

.card__date {
  font-size: var(--fs-eyebrow);
  font-weight: 600;
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
  color: var(--purple);
}

.card__go {
  display: inline-flex;
  flex: none;
  color: var(--teal-deep);
}

.card__go .arrow { width: 18px; height: 14px; }

.card__go::after {
  content: "";
  position: absolute;
  inset: 0;
}

.cards--press .card:hover .arrow { transform: translateX(4px); }

.cards--press .card:has(.card__go:focus-visible) {
  outline: var(--focus);
  outline-offset: 4px;
}

.card__go:focus-visible { outline: none; }

@media (prefers-reduced-motion: reduce) {
  .cards--press .card { transition: none; }
  .cards--press .card:hover .arrow { transform: none; }
}

@media (max-width: 1100px) {
  .cards { grid-template-columns: repeat(2, minmax(0, 1fr)); row-gap: var(--s7); }
}

@media (max-width: 900px) {
  .cards--2, .cards--4 { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s7) var(--s5); }
}

@media (max-width: 640px) {
  .cards, .cards--2, .cards--4 { grid-template-columns: minmax(0, 1fr); }
}

/* sections/work/work.css */

/* work */

.section__head {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: var(--s6);
  align-items: end;
}

.section__head .lede { margin-top: var(--s3); max-width: 62ch; }

.section__head--split {
  grid-template-columns: repeat(2, minmax(0, 1fr));
  align-items: start;
}

.section__head--split > :first-child { grid-column: 1 / -1; }

.section__head--split .lede { margin-top: 0; max-width: none; }

.section__head--split .btn { justify-self: start; }

.projects { margin-top: var(--s7); display: grid; gap: var(--gap); }

.projects__row {
  display: grid;
  gap: var(--gap);
  grid-template-columns: minmax(0, 519fr) minmax(0, 1057fr);
}

.projects__row--flip {
  grid-template-columns: minmax(0, 1057fr) minmax(0, 519fr);
}

.tile {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  color: var(--white);
  text-decoration: none;
}

.tile__img {
  width: 100%;
  height: 100%;
  min-height: 518px;
  object-fit: cover;
  transition: transform .5s ease;
}

.tile::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(
    to top,
    rgba(0, 0, 0, .78) 0%,
    rgba(0, 0, 0, .3) 26%,
    rgba(0, 0, 0, 0) 55%);
}

.tile__cap {
  position: absolute;
  left: 36px;
  bottom: 30px;
  right: 36px;
  z-index: 1;
}

.tile__tag {
  margin-top: 3px;
  font-size: var(--fs-tag);
  font-weight: 600;
  line-height: var(--lh-tight);
  text-transform: uppercase;
  letter-spacing: var(--ls-eyebrow);
  color: var(--teal-accent);
}

a.tile:hover .tile__img { transform: scale(1.03); }

@media (prefers-reduced-motion: reduce) {
  .tile__img { transition: none; }
  a.tile:hover .tile__img { transform: none; }
}

@media (max-width: 1280px) {
  .tile__img { min-height: 420px; }
}

@media (max-width: 900px) {
  .section__head { grid-template-columns: minmax(0, 1fr); }
  .section__head .btn { justify-self: start; }
  .projects__row,
  .projects__row--flip { grid-template-columns: minmax(0, 1fr); }
  .tile__img { min-height: 320px; }
}

@media (max-width: 640px) {
  .tile__cap { left: 24px; right: 24px; bottom: 24px; }
}

/* sections/areas/areas.css */

/* areas */

@media (prefers-reduced-motion: reduce) {
  .areas__county::after { transition: none; }
  .areas__panel { transition: none; }
}

.chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s1);
  margin-top: var(--s4);
}

.chips li {
  display: flex;
  align-items: center;
  gap: var(--s1);
  min-height: 32px;
  padding-inline: 12px;
  background: var(--chip);
  font-size: var(--fs-sm);
  line-height: 1.3;
}

.chips li::before {
  content: "";
  flex: none;
  width: 6px;
  height: 6px;
  background: var(--teal-accent);
}

.areas__note {
  margin-top: var(--s4);
  font-size: var(--fs-sm);
  color: var(--ink-muted);
}

.areas__set {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--s6) var(--split-gap);
  align-items: start;
  margin-top: var(--s8);
}

.areas__county {
  /* it is a <summary> now, so the default disclosure triangle has to go */
  list-style: none;
  font-size: var(--fs-eyebrow);
  font-weight: 600;
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
  color: var(--ink-muted);
}

.areas__county::-webkit-details-marker { display: none; }

.areas__panel {
  overflow: hidden;
  transition: height .28s cubic-bezier(.22, .61, .36, 1);
}

.areas__panel .chips { margin-top: var(--s3); }

.areas__set + .areas__note { max-width: 62ch; margin-top: var(--s7); }

@media (max-width: 900px) {
  .areas__set { grid-template-columns: minmax(0, 1fr); gap: 0; margin-top: var(--s7); }
  .areas__group { border-top: 1px solid var(--rule); }
  .areas__group:last-child { border-bottom: 1px solid var(--rule); }
  .areas__county {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--s3);
    /* a real tap target, not a 13px line of text */
    min-height: 56px;
    cursor: pointer;
    /* a control, so it takes the ink colour rather than the muted label one */
    color: var(--ink);
  }
  .areas__county::after {
    content: "";
    flex: none;
    width: 12px;
    height: 12px;
    background-image:
      linear-gradient(currentColor, currentColor),
      linear-gradient(currentColor, currentColor);
    background-position: center, center;
    background-repeat: no-repeat;
    background-size: 100% 1.6px, 1.6px 100%;
    transition: background-size .2s ease;
  }
  .areas__group[open] .areas__county::after { background-size: 100% 1.6px, 1.6px 0; }
  .areas__panel .chips { margin-top: 0; padding-bottom: var(--s4); }
}

/* sections/cta/cta.css */

/* cta */

.cta {
  position: relative;
  isolation: isolate;
  padding-block: var(--s9);
  text-align: center;
}

.cta__inner { margin-inline: auto; }

.cta .lede { max-width: 44em; margin-inline: auto; margin-top: var(--s4); }

.cta__actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: var(--s6);
  margin-top: var(--s6);
}

/* assets/css/contact.css */

/* contact */

.contact {
  display: grid;
  grid-template-columns: minmax(0, 2.2fr) minmax(0, 1fr);
  gap: var(--split-gap);
  align-items: start;
  margin-top: var(--s6);
}

.embed {
  position: relative;
  margin-top: var(--s2);
  background: var(--chip);
}

/* Shown until the form paints over it. */
.embed[data-loading]::before {
  content: attr(data-loading);
  position: absolute;
  top: var(--s7);
  left: 0;
  right: 0;
  text-align: center;
  font-size: var(--fs-sm);
  color: var(--ink-muted);
}

.embed__frame { position: relative; }

.embed__frame {
  display: block;
  width: 100%;
  /* Heights measured 2026-10-01 against the live form at each frame width the
     layout produces (2238 to 2534px of content). A little headroom, so the
     form scrolls with the page and not inside itself. */
  height: 2300px;
  border: 0;
}

.embed__note {
  max-width: 62ch;
  margin-top: var(--s5);
  font-size: var(--fs-sm);
  color: var(--ink-muted);
}

.sidecard {
  display: grid;
  gap: var(--s4);
  align-content: start;
  padding: var(--s5);
  border: 1px solid var(--rule);
}

.sidecard__title {
  font-size: var(--fs-h4);
  font-weight: 600;
  line-height: var(--lh-tight);
}

.sidecard__label {
  font-size: var(--fs-sm);
  font-weight: 500;
}

.sidecard__value {
  margin-top: var(--s1);
  font-size: var(--fs-sm);
  font-style: normal;
  color: var(--ink-muted);
  line-height: var(--lh-body);
}

.sidecard .btn { justify-self: start; }

.callout {
  padding: var(--s5);
  background: var(--teal-deep);
  color: var(--white);
}

.callout__title {
  font-size: var(--fs-h4);
  font-weight: 600;
  line-height: var(--lh-tight);
}

.callout p {
  margin-top: var(--s2);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
}

.callout a { color: var(--white); }

.callout p a { white-space: nowrap; }

.callout .alink { margin-top: var(--s4); }

.contact__aside {
  display: grid;
  align-content: start;
  gap: var(--s7);
}

.visit {
  display: grid;
  gap: var(--s5);
  margin-top: var(--s5);
}

.visit__pair {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--s5) var(--gap);
}

.visit__label {
  font-size: var(--fs-eyebrow);
  font-weight: 600;
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
  color: var(--ink-muted);
}

.visit__value {
  margin-top: var(--s1);
  font-size: var(--fs-body);
  font-style: normal;
  line-height: var(--lh-loose);
}

.visit + .lede { margin-top: var(--s6); }

@media (max-width: 1279px) {
  .embed__frame { height: 2480px; }   /* frame under 677px wide: fields stack */
}

@media (max-width: 1100px) {
  .sidecard { display: none; }
  .embed__frame { height: 2300px; }
  .contact { grid-template-columns: minmax(0, 1fr); gap: var(--s6); }
  .contact__aside { display: contents; }
  .callout { order: 1; }
  .contact__main { order: 2; }
}

@media (max-width: 760px) {
  .embed__frame { height: 2480px; }
}

@media (max-width: 640px) {
  .embed__frame { height: 2600px; }
  .visit__pair { grid-template-columns: minmax(0, 1fr); }
}

/* assets/css/article.css */

/* article */

.article__inner {
  max-width: 880px;
  margin-inline: auto;
}

.article__title { margin-top: var(--s2); }

.article__meta {
  margin-top: var(--s3);
  font-size: var(--fs-sm);
  color: var(--ink-muted);
}

.article__media { margin-top: var(--s7); }

.article__media .plate__main {
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
}

.article__body {
  max-width: 68ch;
  margin-top: var(--s7);
  font-size: var(--fs-body);
  line-height: var(--lh-loose);
}

.article__body p + p { margin-top: var(--s3); }

.article__foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s4) var(--s6);
  margin-top: var(--s8);
  padding-top: var(--s5);
  border-top: 1px solid var(--rule);
}

@media (max-width: 640px) {
  .article__foot { gap: var(--s4); }
  .article__foot .btn { width: 100%; justify-content: center; }
}

/* assets/css/project.css */

/* project */

.project__head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--s4) var(--s6);
  padding-bottom: var(--s5);
  border-bottom: 1px solid var(--rule);
}

.project__title { margin-top: var(--s2); }

.project__tag {
  display: inline-block;
  padding: 10px 16px;
  background: var(--chip);
  font-size: var(--fs-tag);
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
  white-space: nowrap;
}

.project__count {
  font-size: var(--fs-sm);
  color: var(--ink-muted);
}

.gallery {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  grid-auto-rows: clamp(150px, 19vw, 360px);
  gap: var(--s2);
  margin-top: var(--s7);
}

.gallery__item {
  position: relative;
  display: block;
  grid-column: span 3;
  grid-row: span 2;
  overflow: hidden;
  background: var(--chip);
  border: 0;
  padding: 0;
  cursor: zoom-in;
}

.gallery__item:nth-child(5n + 1) { grid-column: span 4; grid-row: span 2; }

.gallery__item:nth-child(5n + 2) { grid-column: span 2; grid-row: span 1; }

.gallery__item:nth-child(5n + 3) { grid-column: span 2; grid-row: span 1; }

.gallery__item:nth-child(5n + 4) { grid-column: span 2; grid-row: span 2; }

.gallery__item:nth-child(5n + 5) { grid-column: span 4; grid-row: span 2; }

.gallery__item:last-child:nth-child(5n + 1) { grid-column: span 6; }

.gallery__item:last-child:nth-child(5n + 2) { grid-row: span 2; }

.gallery__item:last-child:nth-child(5n + 4) { grid-column: span 6; }

.gallery__img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transition: transform .5s cubic-bezier(.2, .7, .3, 1);
}

.gallery__item:hover .gallery__img,
.gallery__item:focus-visible .gallery__img { transform: scale(1.04); }

.gallery__item:focus-visible { outline: 3px solid var(--teal-deep); outline-offset: 3px; }

.lightbox {
  /* The frame the photograph has to fit inside, named once. The stage pads by
     these and the image sizes against them, so the two cannot drift apart. */
  --lb-side: clamp(16px, 9vw, 112px);
  --lb-top: 72px;
  --lb-bottom: 88px;

  width: 100vw;
  max-width: 100vw;
  height: 100dvh;
  max-height: 100dvh;
  padding: 0;
  border: 0;
  background: rgba(0, 0, 0, .94);
  color: var(--white);
  overflow: hidden;
}

.lightbox::backdrop { background: rgba(0, 0, 0, .9); }

.is-lightboxOpen {
  overflow: hidden;
  /* iOS ignores overflow on the root, so pin it as well */
  touch-action: none;
}

.lightbox__stage {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  /* The bottom figure clears the caption bar rather than sitting under it. A
     scrim would also work, but the caption is grey-on-black by design and only
     reads that way against the ground, not against whatever the photograph
     happens to be doing at its bottom edge. */
  padding: var(--lb-top) var(--lb-side) var(--lb-bottom);
}

.lightbox__img {
  max-width: calc(100vw - 2 * var(--lb-side));
  max-height: calc(100dvh - var(--lb-top) - var(--lb-bottom));
  width: auto;
  height: auto;
  object-fit: contain;
}

.lightbox__bar {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s3);
  padding: var(--s3) clamp(16px, 4vw, 40px);
  font-size: var(--fs-sm);
  color: var(--on-dark-muted);
}

.lightbox__caption {
  max-width: 62ch;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.lightbox__btn {
  display: grid;
  place-items: center;
  width: 52px;
  height: 52px;
  border: 0;
  background: rgba(255, 255, 255, .12);
  color: var(--white);
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
  transition: background .2s;
}

.lightbox__btn:hover { background: rgba(255, 255, 255, .26); }

.lightbox__btn:focus-visible { outline: 3px solid var(--white); outline-offset: 2px; }

.lightbox__btn[disabled] { opacity: .3; cursor: default; }

.lightbox__prev,
.lightbox__next {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
}

.lightbox__prev { left: clamp(8px, 2vw, 24px); }

.lightbox__next { right: clamp(8px, 2vw, 24px); }

.lightbox__close { position: absolute; top: clamp(8px, 2vw, 24px); right: clamp(8px, 2vw, 24px); }

@media (max-width: 900px) {
  .gallery { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .gallery__item:nth-child(n) { grid-column: span 2; grid-row: span 1; }
  .gallery__item:last-child:nth-child(n) { grid-column: span 2; grid-row: span 1; }
  .gallery__item:nth-child(3n + 1) { grid-column: span 4; grid-row: span 2; }
  .gallery__item:last-child:nth-child(3n + 1) { grid-column: span 4; grid-row: span 2; }
  .gallery__item:last-child:nth-child(3n + 2) { grid-column: span 4; }
  .project__head { align-items: flex-start; }
}

@media (max-width: 640px) {
  .gallery { grid-template-columns: minmax(0, 1fr); grid-auto-rows: auto; gap: var(--s1); }
  .gallery__item:nth-child(n) { grid-column: auto; grid-row: auto; aspect-ratio: 4 / 3; }
  .gallery__item:last-child:nth-child(n) { grid-column: auto; grid-row: auto; }
  .gallery__item:nth-child(3n + 2) { aspect-ratio: 1 / 1; }
  .lightbox { --lb-side: 8px; --lb-top: 64px; --lb-bottom: 84px; }
  .lightbox__btn { width: 44px; height: 44px; }
  .lightbox__caption { display: none; }
}

/* assets/css/extras.css */

/* extras
   Rules the theme needs that the static build never had: fallbacks for an
   unconfigured setting, and the projects archive, which has no comp yet.
   Kept in their own file so build/split-css.py can regenerate the section
   stylesheets from the approved static sheet without clobbering them, and so
   check-css-parity.py reports exactly this list as "added by the theme". */

/* Shown instead of the logo when Site Settings has no image yet. */
.masthead__name {
  font-size: var(--fs-h4);
  font-weight: 600;
  line-height: var(--lh-tight);
}

/* The projects archive at /gallery/. Plain on purpose: the gallery page has
   not been designed, so this reuses the tile and nothing else. */
.projects--grid {
  display: grid;
  gap: var(--gap);
  grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
}

.projects--grid .tile__img { min-height: 380px; }

.pagination {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s2);
  margin-top: var(--s7);
  font-size: var(--fs-sm);
}

.pagination .page-numbers {
  display: inline-flex;
  align-items: center;
  min-height: 40px;
  padding-inline: var(--s2);
  text-decoration: none;
  background: var(--chip);
}

.pagination .page-numbers.current { background: var(--teal); color: var(--white); }

/* A project tile with no case study behind it. Same box, no pointer, no hover
   lift, because there is nowhere for it to go. */
.tile--static { cursor: default; }

/* ---- nav dropdowns ------------------------------------------------------
   Not in the comp: the comp's nav is one flat row, and the sitemap gives three
   of the six items children. Kept here rather than in chrome.css so that
   build/split-css.py can keep regenerating chrome.css from the approved static
   sheet, and so check-css-parity.py reports this as an addition. */

/* The link and its chevron are one row. Without this the button is an inline
   sibling of the link and drops to a second line, which pushed every chevron
   below its own nav item. */
.nav__item {
  position: relative;
  display: flex;
  align-items: center;
}

.nav__sub {
  margin: 0;
  padding: 0;
  list-style: none;
}

/* The disclosure button. On desktop it is a hint rather than the only way in:
   the submenu also opens on hover and on focus-within, so a mouse never has to
   click it and a keyboard never has to find it. */
.nav__toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  background: none;
  border: 0;
  color: inherit;
  cursor: pointer;
}

.nav__chevron {
  width: 10px;
  height: 6px;
  transition: transform .2s ease;
}

@media (min-width: 1101px) {
  .nav__item > a { white-space: nowrap; }
  .nav__item--parent > a { padding-right: 2px; }

  .nav__toggle {
    width: 24px;
    height: 24px;
    margin-left: 0;
    vertical-align: middle;
  }

  .nav__sub {
    position: absolute;
    top: 100%;
    left: -20px;
    z-index: 70;
    min-width: 268px;
    padding: var(--s2) 0;
    background: var(--white);
    box-shadow: 0 12px 28px rgba(0, 0, 0, .13), 0 1px 0 rgba(0, 0, 0, .07);
    opacity: 0;
    visibility: hidden;
    transform: translateY(-6px);
    transition: opacity .18s ease, transform .18s ease, visibility 0s linear .18s;
  }

  /* A gap between the link and the panel would drop the hover on the way
     down. This bridges it without moving anything. */
  .nav__item--parent::after {
    content: "";
    position: absolute;
    top: 100%;
    left: 0;
    width: 100%;
    height: 14px;
  }

  .nav__item--parent:hover > .nav__sub,
  .nav__item--parent:focus-within > .nav__sub {
    opacity: 1;
    visibility: visible;
    transform: none;
    transition: opacity .18s ease, transform .18s ease;
  }

  .nav__item--parent:hover > .nav__toggle .nav__chevron,
  .nav__item--parent:focus-within > .nav__toggle .nav__chevron {
    transform: rotate(180deg);
  }

  .nav__sub a {
    display: block;
    padding: 10px 24px;
    font-size: var(--fs-sm);
    font-weight: 400;
    line-height: 1.35;
    text-decoration: none;
  }

  /* Colour only. A filled row reads as a selected state rather than a hover,
     and nothing else on the site fills on hover. */
  .nav__sub a:hover,
  .nav__sub a:focus-visible { color: var(--teal); }
}

/* Six nav items, a phone number and a button is a full row at 1600. The gap
   tightens before anything is allowed to wrap. */
@media (max-width: 1500px) {
  .nav__list { gap: var(--s4); }
  .masthead__end { gap: var(--s3); }
}

@media (max-width: 1240px) {
  .nav__list { gap: var(--s3); }
  .nav__item > a { font-size: var(--fs-sm); }
}

/* Mobile: the panel is a list, so the submenu is an accordion and the button
   is the only way in, because tapping the parent link navigates. */
@media (max-width: 1100px) {
  /* The rule belongs to the row, not to the link. With the parent laid out as
     a grid the link and its button each occupy one cell, so a border on the
     link stopped short and the button drew a second stub beside it. */
  .nav__list > .nav__item { border-bottom: 1px solid var(--rule); }
  .nav__list > .nav__item > a { border-bottom: 0; flex: 1 1 auto; }

  .nav__item--parent {
    display: grid;
    grid-template-columns: 1fr auto;
    align-items: center;
  }

  .nav__item--parent > a { grid-column: 1; }

  .nav__toggle {
    grid-column: 2;
    width: var(--btn-h);
    height: var(--btn-h);
    border: 0;
  }

  .nav__sub {
    grid-column: 1 / -1;
    display: none;
    background: var(--chip);
    border-top: 1px solid var(--rule);
  }

  .nav__item--parent.is-open > .nav__sub { display: block; }
  .nav__item--parent.is-open > .nav__toggle .nav__chevron { transform: rotate(180deg); }

  .nav__sub li + li > a { border-top: 1px solid var(--rule); }

  .nav__sub a {
    display: block;
    padding: var(--s2) var(--s3);
    font-size: var(--fs-base);
    border-bottom: 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  .nav__sub,
  .nav__chevron { transition: none; }
}

/* ---- footer legal row ---------------------------------------------------
   Noindex utility pages, beside the copyright rather than in a column with the
   same visual weight as the service pages. */

.footer__legal {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s2) var(--s4);
  margin: 0;
  padding: 0;
  list-style: none;
  margin-top: var(--s10);
  padding-top: var(--s3);
  border-top: 1px solid var(--rule-onteal);
  font-size: var(--fs-xs);
}

.footer__legal a {
  text-decoration: none;
  color: var(--white);
}

.footer__legal a:hover { text-decoration: underline; text-underline-offset: 3px; }

/* The legal row already draws the rule the bottom bar used to. */
.footer__legal + .footer__bottom {
  margin-top: var(--s3);
  padding-top: 0;
  border-top: 0;
}


/* ---- plain text pages (legal notices): post content, no sections -------- */

.article__body h2 { margin-top: var(--s5); font-size: var(--fs-h4); font-weight: 600; line-height: var(--lh-tight); }

.article__body h3 { margin-top: var(--s4); font-size: var(--fs-body); font-weight: 600; }

.article__body h2 + p, .article__body h3 + p, .article__body h2 + ul, .article__body h3 + ul { margin-top: var(--s2); }

.article__body ul { margin-top: var(--s3); padding-left: 1.25em; list-style: disc; }

.article__body li + li { margin-top: var(--s1); }

.article__body p + ul, .article__body ul + p { margin-top: var(--s3); }
