
@font-face{font-family:"Myrid Pro";src:url("/fonts/MYRIADPRO-REGULAR.f2288b3151.woff2") format("woff2");font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:"Myrid Pro";src:url("/fonts/MYRIADPRO-IT.cc06fe7a98.woff2") format("woff2");font-weight:400;font-style:italic;font-display:swap}
@font-face{font-family:"Myrid Pro";src:url("/fonts/MYRIADPRO-SEMIBOLD.f4ca3d37d6.woff2") format("woff2");font-weight:600;font-style:normal;font-display:swap}
@font-face{font-family:"Myrid Pro";src:url("/fonts/MYRIADPRO-SEMIBOLDIT.7e88dbf95d.woff2") format("woff2");font-weight:600;font-style:italic;font-display:swap}
@font-face{font-family:"Myrid Pro";src:url("/fonts/MYRIADPRO-BOLD.000d06bd70.woff2") format("woff2");font-weight:700;font-style:normal;font-display:swap}
@font-face{font-family:"Myrid Pro";src:url("/fonts/MYRIADPRO-BOLDIT.2b934cb590.woff2") format("woff2");font-weight:700;font-style:italic;font-display:swap}
*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;overflow-x:clip}
body{margin:0;background:#FFFFFF;color:#3F3F3F;font:17.5px/1.62 "Myrid Pro","Myriad Pro","Segoe UI",system-ui,Arial,sans-serif}
img{max-width:100%;height:auto}
a{color:#0B87C2}
a:focus-visible,button:focus-visible,summary:focus-visible{outline:3px solid #11ADF3;outline-offset:2px}
.wrap{max-width:1280px;margin:0 auto;padding:0 20px}
/* Header and footer run the full width of the window. Body copy does not -
   a 3000px line of text is unreadable - so only these two opt in. */
.wrap.full{max-width:none;padding:0 34px}
.skip{position:absolute;left:-9999px}
.skip:focus{left:8px;top:8px;position:fixed;z-index:99;background:#fff;padding:10px 16px}

/* Everything that sticks or scrolls into view has to clear the sticky
   header. That distance was hard-coded at 78px and the header has since
   grown to 125px, so the contents list, the quote form and every anchored
   heading were landing 47px underneath it. One variable now, measured from
   the real header at runtime; these values are only the fallback. */
:root{--hdr:125px;--stick:calc(var(--hdr) + 14px)}
@media(max-width:900px){:root{--hdr:104px}}
@media(max-width:640px){:root{--hdr:96px}}
header.site{position:sticky;top:0;z-index:40;box-shadow:0 2px 16px rgba(16,25,60,.28)}
.topbar{background:#2749CB;color:#fff}
.tb{display:flex;align-items:center;justify-content:center;position:relative;padding:8px 0;min-height:42px}
.tb .tagline{font-size:15.5px;font-weight:600;letter-spacing:.01em}
.tb .login{position:absolute;left:20px;top:50%;transform:translateY(-50%);
  display:inline-flex;align-items:center;gap:8px;color:#fff;text-decoration:none;
  padding:6px 8px;font-size:14.5px;font-weight:600}
.tb .login::before{content:none}
.tb .login:hover{text-decoration:underline;text-underline-offset:4px}
.tb .ls{position:absolute;right:20px;top:50%;transform:translateY(-50%)}
.mainbar{background:linear-gradient(135deg,#1B2B66 0%,#20337A 100%)}
.bar{display:flex;align-items:center;gap:20px;flex-wrap:wrap}
.wrap.full.bar{padding:14px 34px}
.brand{margin-top:-16.5px}
/* The live logo sits on a bright blue slab whose right edge is cut on the
   brand diagonal, taller than the bar, hanging down over the hero. The
   slant is the box's own shape - a clip, not a picture of a slant - so it
   holds at any size and the transparent wordmark sits straight on it. */
.brand{background:#11ADF3;clip-path:polygon(0 0,100% 0,calc(100% - 24px) 100%,0 100%);
  padding:22px 52px 22px 34px;line-height:0;margin-right:auto;flex:none;text-decoration:none;
  align-self:flex-start;margin-bottom:-26px;position:relative;z-index:5;
  margin-left:-34px} /* flush to the window edge, as live: cancel the wrap's padding */
.brand img{height:40px;width:auto;display:block}
nav.main ul{display:flex;gap:8px;list-style:none;margin:0;padding:0;flex-wrap:wrap}
nav.main li{position:relative}
nav.main a{color:#fff;text-decoration:none;font-weight:600;font-size:16.5px;
  text-transform:uppercase;letter-spacing:.02em;display:inline-flex;align-items:center;
  gap:7px;padding:14px 10px}
nav.main a:hover{color:#9EDCFF}
.caret{width:0;height:0;border-left:4.5px solid transparent;border-right:4.5px solid transparent;
  border-top:5px solid currentColor;display:inline-block}
nav.main .sub{display:none;position:absolute;top:100%;left:0;min-width:250px;z-index:60;
  background:#fff;box-shadow:0 12px 32px rgba(16,25,60,.22);
  padding:8px 0;margin:0;list-style:none;flex-direction:column;gap:0}
nav.main li:hover>.sub,nav.main li:focus-within>.sub{display:flex}
nav.main .sub a{color:#26324B;font-size:15.5px;font-weight:600;text-transform:none;
  letter-spacing:0;padding:9px 20px;display:block}
nav.main .sub a:hover{background:#F2F6FD;color:#2749CB}
nav.main .sub-all a{border-top:1px solid #E3E9EE;color:#2749CB;margin-top:6px;padding-top:12px}
/* The Services menu is the mega panel: two columns of thumbnail + name +
   one-line blurb, anchored under its menu item. */
nav.main .mega-panel{width:min(680px,calc(100vw - 48px));left:50%;transform:translateX(-50%);
  padding:12px;grid-template-columns:1fr 1fr;gap:2px}
nav.main li:hover>.mega-panel,nav.main li:focus-within>.mega-panel{display:grid}
nav.main .mega-panel a{display:flex;align-items:center;gap:13px;padding:9px 12px;
  text-transform:none;letter-spacing:0}
nav.main .mega-panel a:hover{background:#F2F6FD}
nav.main .mega-panel img{width:64px;height:64px;object-fit:cover;flex:none}
.mm-t{min-width:0}
.mm-t b{display:block;font-size:15.5px;color:#26324B;line-height:1.25}
.mm-t small{display:block;font-size:13px;color:#5A6B7A;font-weight:500;line-height:1.35;margin-top:2px}
nav.main .mega-panel .sub-all{grid-column:1/-1}
@media (hover:none) and (min-width:1025px){nav.main .sub{display:none!important}}
/* The brand's buttons lean: the box is a parallelogram skewed 10 degrees,
   drawn by a ::before layer so the label stays upright. Fill and border
   live on that layer; hover restyles it. */
.skew{position:relative;z-index:0}
.skew::before{content:"";position:absolute;inset:0;z-index:-1;transform:skewX(-10deg);
  }
.bar .cta{text-transform:uppercase;letter-spacing:.02em}
.cta{color:#fff;text-decoration:none;font-weight:700;padding:12px 24px;
  font-size:15.5px;white-space:nowrap;display:inline-block}
.cta::before{background:#2749CB}
.cta:hover{color:#fff}
.cta:hover::before{background:#11ADF3}
.tel{font-weight:600;color:#fff;text-decoration:none;white-space:nowrap;text-transform:uppercase;
  letter-spacing:.02em;padding:11px 20px;display:inline-flex;align-items:center;gap:8px;font-size:15px}
.tel::before{border:1px solid #11ADF3;background:transparent}
.tel:hover::before{background:rgba(17,173,243,.18)}
/* the live language buttons: sky-outlined, flag beside the name, same lean */
.ls{display:inline-flex;gap:14px;font-size:13.5px;line-height:1;flex:none}
.ls a,.ls .ls-on{padding:6px 2px;text-decoration:none;font-weight:600;white-space:nowrap;
  display:inline-flex;align-items:center;gap:7px}
.ls img{display:block}
.ls a{color:rgba(255,255,255,.82)}
.ls a::before,.ls .ls-on::before{content:none}
.ls a:hover{color:#fff}
.ls .ls-on{color:#fff;cursor:default;font-weight:800}

.crumbs{font-size:13.5px;color:#5A6B7A;padding:12px 0}
.crumbs a{color:#5A6B7A;text-decoration:none}
.crumbs a:hover{color:#0B87C2}

.hero{background:linear-gradient(160deg,#1B2B66 0%,#23398C 60%,#2749CB 140%);padding:42px 0 38px;color:#fff}
/* A service page stands on its own photograph, under a brand-tinted scrim
   heavy enough to keep white type legible over any of them. */
/* the service hero centers on its photograph, as the live page does */
.svchero{text-align:center}
/* The line under the rating pill was 19px, the same size as the hero's own
   lede on the home page, and on a phone it ran to 185px - a third of the
   first screen spent on a sentence the reader is scrolling past to reach
   the article. */
.svchero .lede{margin-left:auto;margin-right:auto;font-size:16.5px;line-height:1.55;
  max-width:78ch}
.svchero .hcta{justify-content:center;margin-top:20px}
/* A row of buttons, not a paragraph of links. Without this the row is a
   block, justify-content is inert, and the phone number wraps across the
   quote button - taking its skewed background with it, which is where the
   stray outlined parallelogram came from. */
.svchero .hcta{display:flex;gap:22px;flex-wrap:wrap}
/* the badge card is pulled up 64px over the hero, so the hero's own
   content has to end clear of it rather than behind it */
.hero.haspic,.hero.hero-badged{padding:58px 0 108px}
.hero.haspic{background-image:linear-gradient(160deg,rgba(20,32,78,.88) 0%,
  rgba(27,43,102,.80) 55%,rgba(35,62,150,.70) 100%),var(--herobg);
  background-size:cover;background-position:center;background-repeat:no-repeat}
h1{font-size:clamp(30px,4.2vw,48px);line-height:1.12;margin:0;letter-spacing:-.01em;text-wrap:balance;
  font-style:italic;font-weight:700}
.hero .lede{color:#E7EEFF}
.lede{color:#5A6B7A;font-size:19px;margin-top:12px;max-width:70ch}

.cols{display:grid;grid-template-columns:minmax(0,1fr);gap:34px;padding:34px 0}
@media(min-width:960px){.cols.has-toc{grid-template-columns:250px minmax(0,1fr)}}
/* A service page runs contents | article | quote form. Below 1180px the
   form drops under the article; below 960 the contents list goes too. */
@media(min-width:1180px){
  /* The article needs room for long-form measure, so this layout used to run
     wider than the standard container at 1260px. The container is 1280px now
     and gives it more than that exception ever did, so the exception is gone
     and only the trimmed side columns remain. */
  .cols.svc3.has-toc{grid-template-columns:236px minmax(0,1fr) 284px;gap:30px}
  .cols.svc3:not(.has-toc){grid-template-columns:minmax(0,1fr) 284px;gap:30px}

}
@media(max-width:1179px){.svcform{grid-column:1/-1}}
.svcform{align-self:start;min-width:0}
@media(min-width:1180px){.svcform{position:sticky;top:var(--stick)}}
/* With no padding the inputs ran the full width of a bordered box, so every
   input border read as a table rule. Inset them and give the panel a ground
   of its own; the inputs stay white and now read as fields. */
.svcform .quote,.svcform section.quote{margin:0;background:#F2F6FD;
  border:1px solid #E3E9EE;padding:22px 20px}
.svcform .quote>.wrap{padding:0;max-width:none}
.svcform .quote h2{font-size:20px;margin:0 0 6px}
.svcform .quote .sub{font-size:14px;margin:0 0 16px;color:#5A6B7A}
.svcform .fields{gap:12px}
.svcform .submit{width:100%;justify-content:center}
.svcform .formnote{font-size:12.5px;margin-top:12px}

/* Two silos close a service page: every service in this town, then every
   town served. Alternating grounds so they read as separate blocks. */
/* The closing run alternates: questions on soft, the town's services on
   white, every area on soft, the writing on white, then the royal band. */
.silo{background:#fff;padding:44px 0;margin-top:0}
.silo.areas{background:#F2F6FD;margin-top:0}
.silo h2{margin:0 0 6px;font-size:clamp(19px,2.1vw,24px);color:#1B2B66}
.silosub{margin:0 0 18px;color:#5A6B7A;font-size:14.5px;max-width:76ch}
.silolist{list-style:none;margin:16px 0 0;padding:0;display:grid;gap:9px 22px;
  grid-template-columns:1fr 1fr}
@media(min-width:760px){.silolist.svc{grid-template-columns:repeat(4,1fr)}
  .silolist.area{grid-template-columns:repeat(5,1fr)}}
/* Two across on a phone. Twenty-five towns in one column is twenty-five
   rows of a two-word link with the rest of the line empty; the names are
   short enough to pair. The services list keeps one column - those names
   run to three words. */
@media(max-width:520px){.silolist{grid-template-columns:1fr}
  .silolist.area{grid-template-columns:1fr 1fr}}
.silo a,.silo .here span{color:#3F3F3F;text-decoration:none;font-size:14.5px;display:flex;
  align-items:flex-start;gap:10px;line-height:1.4}
.silo a::before,.silo .here span::before{content:"";display:inline-flex;width:17px;height:15px;
  flex:none;margin-top:2px;
  background:#2749CB url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 12'%3E%3Cpath d='M1.5 1.5l5 4.5-5 4.5' stroke='white' stroke-width='2.2' fill='none'/%3E%3C/svg%3E") center/6px no-repeat;
  transform:skewX(-10deg)}
.silo a:hover{color:#0B87C2}
/* the page you are on is named, not linked back to itself */
.silo .here{display:flex;align-items:baseline;gap:8px;flex-wrap:wrap}
.silo .here span{color:#1B2B66;font-weight:700}
.silo .here span::before{background-color:#11ADF3}
.silo .here i{font-style:normal;font-size:11.5px;color:#5A6B7A;letter-spacing:.03em}

/* The blog index: two columns of cards, each its own photograph, category
   and date. The capture listed every title twice with its taxonomy links
   pointing at pages that are not rebuilt; this is that list, said once. */
.blogwrap{display:grid;gap:34px;grid-template-columns:1fr;align-items:start}
@media(min-width:980px){.blogwrap{grid-template-columns:232px minmax(0,1fr)}}
.catbar{align-self:start}
@media(min-width:980px){.catbar{position:sticky;top:var(--stick)}}
/* The quote box that sits at the top of a blog sidebar, named after
   whatever the reader is reading about. */
.sidecta{background:#1B2B66;color:#fff;padding:20px 20px 22px;margin:0 0 24px}
.sidecta b{display:block;font-size:17px;line-height:1.3;margin-bottom:8px}
.sidecta p{margin:0 0 14px;font-size:13.5px;line-height:1.5;color:#D9E2FF}
/* display set here rather than inherited: the button was only filling its
   box because the contents-list rule was making every link in the aside a
   block, which is exactly the leak that broke its color */
.sidecta .cta{display:flex;width:100%;justify-content:center;align-items:center;
  font-size:14.5px;color:#1B2B66;text-align:center}
.sidecta .cta::before{background:#fff}
.sidecta .cta:hover{color:#1B2B66}
.sidecta .cta:hover::before{background:#E7EEFF}
.sidecta .sc-tel{display:block;margin-top:12px;color:#fff;font-weight:700;font-size:15px;
  text-decoration:none}
.sidecta .sc-tel:hover{color:#11ADF3}
.sidecta .sc-more{display:block;margin-top:8px;color:#11ADF3;font-size:13px;
  text-decoration:none;font-weight:600}
.sidecta .sc-more:hover{text-decoration:underline}
.sidestack{margin-top:26px}
.sidestack .catgroup h2{font-size:12px;letter-spacing:.1em;text-transform:uppercase;
  color:#5A6B7A;margin:0 0 10px}
.sidestack .catgroup ul{list-style:none;margin:0;padding:0;display:flex;
  flex-direction:column;gap:6px}
.sidestack .catgroup a{display:flex;align-items:center;justify-content:space-between;gap:10px;
  text-decoration:none;color:#3F3F3F;font-size:14px;padding:8px 12px;background:#F2F6FD;
  border-left:3px solid transparent}
.sidestack .catgroup a:hover{border-left-color:#11ADF3;color:#0B87C2}
.sidestack .catgroup i{font-style:normal;font-size:12px;color:#5A6B7A}
.catgroup+.catgroup{margin-top:26px}
.catbar h2{font-size:12px;letter-spacing:.1em;text-transform:uppercase;color:#5A6B7A;
  margin:0 0 10px}
/* a place that is one of our service areas is marked; the rest are regions */
.catbar li.area a{border-left-color:#11ADF3}
.hublink{margin:18px 0 0}
.catbar ul{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:6px}
.catbar a,.catbar .here span{display:flex;align-items:center;justify-content:space-between;
  gap:10px;text-decoration:none;color:#3F3F3F;font-size:14.5px;line-height:1.35;
  padding:8px 12px;background:#F2F6FD;border-left:3px solid transparent}
.catbar a:hover{border-left-color:#11ADF3;color:#0B87C2}
.catbar .here span{border-left-color:#2749CB;color:#1B2B66;font-weight:700}
.catbar i{font-style:normal;font-size:12px;color:#5A6B7A;flex:none}
.bloglist{display:grid;gap:26px;grid-template-columns:1fr;margin:6px 0 8px}
@media(min-width:720px){.bloglist{grid-template-columns:1fr 1fr}}
/* A third column once there is room for one. Two columns beside the sidebar
   put each card 465px wide, and with the square picture above it that is a
   465px photograph per post - a poster, not a card. Three brings it back to
   about 300. */
@media(min-width:1040px){.bloglist{grid-template-columns:repeat(3,1fr);gap:20px}}
.pcard2{display:flex;flex-direction:column;text-decoration:none;color:#3F3F3F;
  background:#fff;border:1px solid #E3E9EE;transition:box-shadow .15s ease,transform .15s ease}
.pcard2:hover{box-shadow:0 6px 24px rgba(17,173,243,.16);transform:translateY(-2px);
  border-color:#11ADF3}
/* Square, for the same reason the service cards are: the photographs are
   not widescreen and this box was. At 337x196 the crop ran from 2% of one
   picture to 72% of a square 1200x1200 one, which left a horizontal band
   out of its middle. A 1:1 box costs the index some height and keeps the
   pictures. */
.pcard2 img{width:100%;aspect-ratio:1/1;height:auto;object-fit:cover;display:block;margin:0}
.pcard2 .pbody{padding:16px 18px 20px;display:block}
.pcard2 .pmeta{display:flex;gap:10px;align-items:center;flex-wrap:wrap;margin-bottom:8px}
.pcard2 .cat{background:#2749CB;color:#fff;font-size:11.5px;font-weight:700;
  letter-spacing:.03em;text-transform:uppercase;padding:4px 11px;transform:skewX(-10deg)}
.pcard2 .cat{display:inline-block}
.pcard2 .date{color:#5A6B7A;font-size:12.5px}
.pcard2 b{display:block;font-size:17px;line-height:1.35;color:#1B2B66}
.pcard2:hover b{color:#0B87C2}

/* Every post is published by the company rather than a named person, so the
   box at the foot says who and how to reach them - the same thing the
   article schema states, in a form a reader can act on. */
.authorbox{display:flex;gap:18px;align-items:flex-start;margin:38px 0 0;padding:22px 24px;
  background:#F2F6FD;border-left:4px solid #11ADF3}
.authorbox .ab-mark{width:54px;height:54px;flex:none;display:inline-flex;align-items:center;
  justify-content:center;background:#2749CB;color:#fff;font-weight:800;font-size:19px;
  transform:skewX(-6deg)}
.authorbox .ab-label{display:block;font-size:11.5px;letter-spacing:.08em;text-transform:uppercase;
  color:#5A6B7A;margin-bottom:3px}
.authorbox b{display:block;font-size:17px;color:#1B2B66;margin-bottom:6px}
.authorbox p{margin:0 0 8px;color:#5A6B7A;font-size:14.5px;line-height:1.55;max-width:70ch}
.authorbox a{color:#0B87C2;font-weight:600;font-size:14.5px}
@media(max-width:560px){.authorbox{padding:18px}.authorbox .ab-mark{width:44px;height:44px;
  font-size:16px}}

/* the town's own writing */
.related{background:#fff;margin-top:0}
.pcards{display:grid;gap:16px;grid-template-columns:1fr}
/* Three across from tablet width up. On a phone the row holds two - a
   third card there is 100px of picture and a headline in four lines - so
   the third is left out rather than squeezed in or stranded on a row of
   its own. It is the oldest of the three. */
@media(min-width:760px){.pcards{grid-template-columns:repeat(3,1fr)}}
@media(max-width:759px){.pcards{grid-template-columns:1fr 1fr;gap:12px}
  .pcards>:nth-child(3){display:none}}
/* square, like the service and blog cards: the photographs are not
   widescreen and a 150px letterbox cut the middle out of them */
.pcard img{width:100%;aspect-ratio:1/1;height:auto;object-fit:cover;display:block;margin:0}
.pcard>span{display:block;padding:16px 18px 18px}
.pcard{display:block;padding:0;background:#F2F6FD;color:#1B2B66;overflow:hidden;
  text-decoration:none;border-left:4px solid #11ADF3;transition:transform .15s ease}
.pcard:hover{transform:translateY(-2px);color:#0B87C2}
.pcard b{font-size:15.5px;line-height:1.35;font-weight:700}
.related .more{margin:22px 0 0}
/* the article's opening heading starts level with the contents list
   beside it, rather than a heading's top margin lower */
.cols article>:first-child{margin-top:0}
.toc{align-self:start}
@media(min-width:960px){.toc{position:sticky;top:var(--stick);max-height:calc(100vh - var(--hdr) - 40px);overflow:auto}}
/* The contents list scrolls when the article is long, and the platform's own
   scrollbar is wider and darker than anything else in that column. Thin it,
   tint it to the rule color, and let it show itself only on hover - the
   standard properties for browsers that take them, the WebKit ones for the
   rest. Both are ignored where unsupported, which leaves the default. */
.toc{scrollbar-width:thin;scrollbar-color:transparent transparent}
.toc:hover,.toc:focus-within{scrollbar-color:#E3E9EE transparent}
.toc::-webkit-scrollbar{width:6px}
.toc::-webkit-scrollbar-track{background:transparent}
.toc::-webkit-scrollbar-thumb{background:transparent;border-radius:0}
.toc:hover::-webkit-scrollbar-thumb,.toc:focus-within::-webkit-scrollbar-thumb{
  background:#E3E9EE}
.toc:hover::-webkit-scrollbar-thumb:hover{background:#5A6B7A}
.toc h2{font-size:12px;letter-spacing:.1em;text-transform:uppercase;color:#5A6B7A;margin:0 0 10px}
.toc ol{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:7px}
.toc ol a{color:#3F3F3F;text-decoration:none;font-size:14.5px;line-height:1.4;display:block;
  border-left:2px solid #E3E9EE;padding-left:11px}
.toc ol a:hover{border-color:#11ADF3;color:#0B87C2}
/* sub-headings sit a level in, lighter, so the list reads as a structure
   rather than one flat run of links */
.toc li.l3{margin-left:13px}
.toc li.l3 a{font-size:13px;color:#5A6B7A;line-height:1.35}
.toc li.l3 a:hover{color:#0B87C2}
/* Where the reader is now. A contents list of seventeen sections says which
   section is on screen or it is only a list of links; the rule at the left
   is the same one hover uses, filled in rather than tinted. */
.toc ol a.here{border-color:#11ADF3;color:#0B87C2;font-weight:600}
/* On a phone the contents list runs the height of the screen - 21 sections
   on the Corvallis air duct page, 766px of links on a 780px window - so the
   article begins below a screenful of its own table of contents. Collapsed
   to about five entries, with the rest a tap away. The button is hidden
   where the list is a sticky column beside the article and costs nothing. */
.tocmore{display:none}
@media(max-width:959px){
  .toc ol{max-height:196px;overflow:hidden}
  .toc.open ol{max-height:none}
  .toc:not(.open) ol{-webkit-mask-image:linear-gradient(#000 60%,transparent);
    mask-image:linear-gradient(#000 60%,transparent)}
  .tocmore{display:inline-flex;align-items:center;gap:6px;margin-top:10px;
    background:none;border:0;padding:6px 0;min-height:44px;
    font:600 14px inherit;color:#0B87C2;cursor:pointer}
  .tocmore::after{content:"";width:7px;height:7px;border-right:2px solid currentColor;
    border-bottom:2px solid currentColor;transform:rotate(45deg) translateY(-2px)}
  .toc.open .tocmore::after{transform:rotate(-135deg) translateY(-2px)}
}
.toc li.l3 a.here{color:#0B87C2}
@media(prefers-reduced-motion:no-preference){.toc ol a{transition:border-color .18s,color .18s}}

/* A before-and-after pair: side by side on a desktop, stacked on a phone.
   The columns are in proportion to the two pictures' shapes - one landscape,
   one portrait - so both stand the same height and neither is cropped. */
.beforeafter{margin:30px 0}
.beforeafter .balabel{font-weight:700;font-size:15px;color:#3F3F3F;margin:0 0 10px}
.beforeafter .baimgs{display:grid;grid-template-columns:1fr;gap:14px}
@media(min-width:700px){.beforeafter .baimgs{grid-template-columns:1.332fr .751fr;
  align-items:start}}
.beforeafter figure{margin:0}
.beforeafter img{display:block;width:100%;height:auto;border-radius:6px;margin:0}
.beforeafter figure figcaption{font-size:13.5px;color:#5A6B7A;margin-top:6px;line-height:1.4}

/* The source list that closes an article: quieter and smaller than the
   writing above it, and boxed, so the eye knows to stop reading there. */
.cites{background:#F2F6FD;border:1px solid #E3E9EE;border-radius:6px;
  padding:18px 22px 6px;margin:34px 0 8px}
.cites h2{font-size:18px;margin:0 0 8px;letter-spacing:0}
.cites p,.cites li{font-size:13.5px;line-height:1.6;color:#5A6B7A}
.cites ol,.cites ul{margin:0 0 14px;padding-left:20px}
.cites li{margin:0 0 5px}
.cites a{word-break:break-word}

/* The contact box that closes a service page, in place of the five loose
   lines the captured pages ended with. Address, telephone and email are
   links because each is a thing to act on; the service areas and the
   credentials are facts, so they are not. */
.svccontact{margin:34px 0 8px}
.svccontact h2{text-align:left;margin:0 0 16px}
.sccard{background:#F2F6FD;border:1px solid #E3E9EE;border-radius:6px;padding:22px}
.scrows{display:grid;grid-template-columns:1fr;gap:12px}
@media(min-width:700px){.scrows{grid-template-columns:1fr 1fr}
  .scrows>:first-child{grid-column:1/-1}}
.scrow,.scfact{display:flex;align-items:flex-start;gap:12px;
  background:#fff;border:1px solid #E3E9EE;border-radius:6px;padding:13px 15px}
.scrow{text-decoration:none;color:#3F3F3F;transition:border-color .15s,box-shadow .15s}
.scrow:hover{border-color:#11ADF3;box-shadow:0 4px 14px rgba(16,25,60,.09);
  color:#0B87C2}
.scrow svg,.scfact svg{width:16px;height:16px;color:#11ADF3;flex:none;margin-top:3px}
.scrow span,.scfact span{display:block;font-size:15.5px;line-height:1.45}
.scrow b,.scfact b{display:block;font-size:11.5px;font-weight:700;letter-spacing:.08em;
  text-transform:uppercase;color:#5A6B7A;margin-bottom:2px}
.scfacts{display:grid;grid-template-columns:1fr;gap:12px;margin-top:12px}
.scfact span{color:#3F3F3F}
.scserving{margin:16px 0 18px;font-size:15.5px;color:#5A6B7A}
.sccard .cta{font-size:16px}

article h2{font-size:clamp(22px,2.6vw,29px);line-height:1.25;margin:38px 0 12px;letter-spacing:-.01em;
  scroll-margin-top:var(--stick);text-wrap:balance}
article h3{font-size:20px;margin:26px 0 8px;scroll-margin-top:var(--stick)}
article h4{font-size:17px;margin:20px 0 6px}
article p{margin:0 0 15px;max-width:72ch}
/* the 404's link lists: columns, so two dozen towns do not become two dozen
   lines of scrolling on the page somebody landed on by accident */
ul.fourofour{list-style:none;padding:0;margin:0 0 22px;display:grid;
  grid-template-columns:repeat(auto-fill,minmax(190px,1fr));gap:2px 18px}
ul.fourofour li{margin:0}
ul.fourofour a{display:block;padding:7px 0;border-bottom:1px solid #E3E9EE}
/* The floating reCAPTCHA badge is a fixed box over the bottom-right of every
   page a form appears on. Hidden, with the attribution Google requires in
   its place inside the form itself. */
.grecaptcha-badge{visibility:hidden}
.recap{margin:12px 0 0;font-size:12px;line-height:1.5;color:#5A6B7A}
.recap a{color:inherit;text-decoration:underline}
/* a clause set entirely in capitals, kept that way because it has to be and
   made readable because it does not have to be painful: capitals need more
   letter-spacing and more leading than lower case, and a rule down the side
   says "this is the shouted part" faster than the capitals themselves do */
article p.caps{font-size:.93em;letter-spacing:.02em;line-height:1.75;
  border-left:3px solid #E3E9EE;padding:2px 0 2px 16px;margin:22px 0;
  color:#5A6B7A}
/* Source lists carry the bare URL as their own link text, and one of those
   is wider than a phone screen. Long unbroken strings break rather than
   pushing the whole page sideways. */
article{overflow-wrap:break-word}
article a{overflow-wrap:anywhere}
article ul,article ol{margin:0 0 16px;padding-left:22px;max-width:72ch}
article li{margin:0 0 7px}
article img{margin:18px 0;display:block}
article table{width:100%;border-collapse:collapse;margin:18px 0;font-size:15.5px}
article th,article td{border:1px solid #E3E9EE;padding:10px 12px;text-align:left}
article th{background:#F2F6FD}
blockquote{margin:20px 0;padding:14px 20px;border-left:4px solid #11ADF3;background:#F2F6FD;
  }
.tblwrap{overflow-x:auto}

.cards{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:16px;margin:26px 0}
.card{border:1px solid #E3E9EE;padding:18px 20px;background:#fff;
  text-decoration:none;color:#3F3F3F;display:block}
.card:hover{border-color:#11ADF3;box-shadow:0 4px 18px rgba(17,173,243,.16)}
.card b{display:block;font-size:17px;margin-bottom:4px}
.card span{color:#5A6B7A;font-size:14.5px}

.band{background:#2749CB;color:#fff;padding:64px 0;margin-top:44px;text-align:center}
/* no white gap when the section above already runs edge to edge */
.band.flush{margin-top:0}
.band h2{margin:0 0 10px;font-size:clamp(21px,2.4vw,27px);font-style:italic}
.band p{margin:0 0 28px;opacity:.94}
/* the two buttons sit as a centered pair rather than an inline run */
.band .wrap{display:flex;flex-direction:column;align-items:center}
.band .ctas{display:flex;gap:14px;flex-wrap:wrap;justify-content:center}
.band .cta{color:#2749CB}
.band .cta::before{background:#fff}
.band .cta:hover{color:#2749CB}
.band .cta:hover::before{background:#E7EEFF}

.quote{border:1px solid #E3E9EE;padding:22px;background:#F2F6FD;margin:34px 0}
.quote h2{margin:0 0 4px;font-size:22px}
.quote p.sub{color:#5A6B7A;margin:0 0 16px;font-size:15.5px}
.fields{display:grid;grid-template-columns:1fr 1fr;gap:13px}
.field{display:flex;flex-direction:column;gap:5px}
.field.full{grid-column:1/-1}
label{font-size:13.5px;font-weight:600}
input,select,textarea{font:inherit;font-size:15.5px;padding:10px 12px;border:1px solid #E3E9EE;
  background:#fff;color:#3F3F3F;width:100%}
textarea{min-height:110px;resize:vertical}
button.submit{margin-top:14px;color:#fff;border:0;background:transparent;
  padding:12px 26px;font-weight:700;font-size:16px;cursor:pointer}
button.submit::before{background:#2749CB}
button.submit:hover::before{background:#11ADF3}
.formnote{font-size:13.5px;color:#5A6B7A;margin-top:10px}
.hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}
.formmsg{margin-top:12px;padding:11px 14px;font-size:15px;line-height:1.5;
  border:1px solid}
.formmsg.ok{background:#E9F6EF;border-color:#BFE6D2;color:#1c6b41}
.formmsg.err{background:#FCEBEB;border-color:#F3CFCF;color:#a41b1b}
.apply fieldset{border:0;border-top:1px solid #E3E9EE;margin:22px 0 0;padding:18px 0 0}
.apply fieldset:first-of-type{border-top:0;margin-top:0;padding-top:0}
.apply legend{font-size:12px;font-weight:800;letter-spacing:.09em;text-transform:uppercase;
  color:#5A6B7A;padding:0}
.apply .hint{font-size:13px;color:#5A6B7A;margin:6px 0 0}
.apply .cert{font-size:13.5px;line-height:1.6;color:#5A6B7A;background:#fff;
  border:1px solid #E3E9EE;padding:14px 16px;max-height:190px;overflow:auto;
  margin:10px 0 14px}
.apply .check label{display:flex;gap:10px;align-items:flex-start;font-size:15px;font-weight:500;
  cursor:pointer;line-height:1.45}
.apply .check input{width:auto;flex:none;margin-top:3px}
.apply input[type=file]{padding:9px 10px;background:#fff}

footer.site{background:rgba(60,91,208,.92);background-size:cover;background-position:center;
  color:#fff;padding:46px 0 24px;margin-top:0}
.fcols{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:30px}
.fcol h2{font-size:19px;font-weight:700;color:#fff;margin:0 0 12px;letter-spacing:0;text-transform:none}
.fcol.office h2{font-size:24px}
.fcol ul{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:8px}
.fcol a{color:#fff;text-decoration:none;font-size:15.5px}
.fcol a:hover{color:#BFE3FF;text-decoration:underline}
.fcol address{font-style:normal;font-size:15.5px;color:rgba(255,255,255,.92);line-height:1.6}
/* Address, telephone and email as three marked rows. The address opens the
   office's Business Profile - the listing with the hours, the photographs
   and the reviews - which is where "View on Google" used to go; Salem has
   no profile of its own and falls back to the point on the map. */
.fcol address .frow{display:flex;align-items:flex-start;gap:9px;margin:0 0 7px;
  color:rgba(255,255,255,.92);text-decoration:none;line-height:1.45}
.fcol address .frow:hover{color:#BFE3FF;text-decoration:underline}
.fcol address .frow svg{flex:none;width:15px;height:15px;margin-top:3px;opacity:.85}
/* The office map, where the "View on Google" link used to be. Sized to
   the column and kept in the footer's own frame rather than Google's. */
.fmap{margin:12px 0 10px;max-width:320px;aspect-ratio:16/10;border-radius:6px;
  overflow:hidden;border:1px solid rgba(255,255,255,.28);background:rgba(255,255,255,.08)}
.fmap iframe{display:block;width:100%;height:100%;border:0}
.fbrand img{height:34px;width:auto;margin:0 0 12px;display:block}
.fmission{font-size:15px;color:rgba(255,255,255,.9);margin:0 0 14px;max-width:34ch;line-height:1.55}
.fsoc{display:flex;gap:14px;flex-wrap:wrap;align-items:center}
.fsoc a{color:#fff;display:inline-flex;padding:4px}
.fsoc a:hover{color:#9EDCFF;text-decoration:none}
.fhours{margin:16px 0 0;font-size:14.5px;color:rgba(255,255,255,.92);line-height:1.55}
.floc{margin-top:10px}
.legal{border-top:1px solid rgba(255,255,255,.28);margin-top:32px;padding-top:16px;font-size:14px;
  color:rgba(255,255,255,.88);display:flex;gap:16px;flex-wrap:wrap;justify-content:space-between}
.legal a{color:rgba(255,255,255,.88);text-decoration:none}
.legal a:hover{color:#fff;text-decoration:underline}

.badges{display:flex;gap:14px;align-items:center;flex-wrap:wrap;margin:20px 0}
.badges img{height:46px;width:auto;margin:0}

/* One accordion, everywhere: a skewed royal chevron that turns as the
   answer opens - drawn as an SVG, so no font has to carry the glyph. */
.faq{background:#F2F6FD;padding:22px 26px;margin:26px 0}
.faq details{border:0;border-bottom:1px solid #E3E9EE;margin:0;background:none}
.faq details:last-child{border-bottom:0}
.faq summary{display:flex;align-items:flex-start;gap:14px;padding:11px 0;font-size:16px;
  color:#26324B;font-weight:700;cursor:pointer;list-style:none;line-height:1.4;min-height:48px}
.faq summary::-webkit-details-marker{display:none}
.faq summary::before{content:"";display:inline-flex;width:27px;height:23px;flex:none;
  background:#2749CB url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 12'%3E%3Cpath d='M1.5 1.5l5 4.5-5 4.5' stroke='white' stroke-width='2.2' fill='none'/%3E%3C/svg%3E") center/9px no-repeat;
  transform:skewX(-10deg);transition:transform .15s ease}
.faq summary::after{content:none}
.faq details[open] summary::before{transform:skewX(-10deg) rotate(90deg)}
.faq .ans{padding:0 0 12px 41px;color:#5A6B7A}
.faq .ans p{margin:0 0 10px}

@media(max-width:1024px){.tb .tagline{display:none}.tb{justify-content:space-between;
  min-height:0}.tb .login,.tb .ls{position:static;transform:none}
  .brand{align-self:flex-start;margin-bottom:0;padding:12px 30px 12px 18px}
  .bar{flex-wrap:nowrap}
  .bar .tel{margin-left:auto}}
/* The header bars and the footer share this gutter; 14px sits a shade
   wider than the 12px the article uses, which keeps the logo and the
   footer's columns off the very edge. The brand's pull matches it or the
   logo stops being flush. */
@media(max-width:640px){.wrap.full{padding:0 14px}.brand{margin-left:-14px}}
/* ------------------------------------------------------- homepage */
.hhero{background-image:url('/img/home-hero-sm.fae67f02de.jpg');
  background-size:cover;background-position:center;color:#fff;padding:74px 0 120px;
  position:relative;overflow:hidden}
.hhero::before{content:"";position:absolute;inset:0;z-index:1;
  background:linear-gradient(rgba(16,25,60,.5),rgba(16,25,60,.72))}
.hhero>.wrap{position:relative;z-index:2}
@media(min-width:900px){.hhero{background-image:url('/img/home-hero.1461f5e530.jpg')}}
.vidbg{position:absolute;inset:0;z-index:0;pointer-events:none}
.vidbg iframe{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);
  width:max(100vw,178vh);height:max(56.25vw,100vh);border:0}
@media (prefers-reduced-motion:reduce){.vidbg{display:none}}
@media print{.vidbg{display:none}}
.hero-badge-link{display:inline-block;line-height:0}
.hhero .stars{color:#F5B82E;font-size:24px;letter-spacing:5px}
/* The rating badge, and a way through to the profile it comes from. The
   slab leans on the site's angle while the mark and the type stay upright,
   which is what .skew::before is for. The count sits under the stars and is
   set smaller so the two lines together stand the same height as the mark
   beside them. */
.hhero .grate{display:flex;width:max-content;max-width:100%;align-items:center;
  gap:13px;margin:0 0 16px;padding:8px 24px 8px 12px;color:#fff;text-decoration:none}
.hhero .grate::before{background:rgba(11,20,48,.62);
  border:1px solid rgba(255,255,255,.5)}
.hhero .grate:hover::before{background:rgba(17,173,243,.3);border-color:#fff}
.hhero .gmark{width:38px;height:38px;background:#fff;flex:none;
  display:inline-flex;align-items:center;justify-content:center}
.hhero .gmark img{width:23px;height:23px;margin:0;display:block}
.hhero .gnums{display:flex;flex-direction:column;gap:2px;line-height:1.1}
.hhero .grow{display:flex;align-items:center;gap:8px}
.hhero .grate .stars{font-size:16px;letter-spacing:2px}
.hhero .grate b{font-size:15px;font-weight:800;color:#fff;letter-spacing:.01em}
.hhero .gcount{font-size:12.5px;font-weight:600;color:rgba(255,255,255,.92)}
/* the homepage headline runs larger than the rest of the site's h1s, which
   stay at 48px - it carries the page on its own */
.hhero h1{max-width:19ch;font-size:clamp(32px,5.2vw,60px)}
.hhero .lede{color:#E7EEFF;font-size:19px;max-width:60ch;font-style:italic;font-weight:600}
.hhero .hcta{display:flex;gap:22px;margin-top:26px;flex-wrap:wrap}
.hhero .ghost,.svchero .ghost{font-weight:700;color:#fff;text-decoration:none;padding:12px 24px;font-size:15.5px;
  text-transform:uppercase;letter-spacing:.02em;display:inline-block;white-space:nowrap}
.hhero .ghost::before,.svchero .ghost::before{border:1px solid #11ADF3;background:rgba(16,25,60,.35)}
.hhero .ghost:hover::before,.svchero .ghost:hover::before{background:rgba(17,173,243,.25)}
/* The rating under a service-page H1. Reads on the photographic hero the
   service pages carry and on the flat one the hubs use, so it paints its own
   ground rather than trusting whatever is behind it. */
.svcrate{display:inline-flex;align-items:center;justify-content:center;
  gap:9px;margin:12px 0 0;line-height:1;
  padding:7px 16px;border-radius:999px;text-decoration:none;
  background:rgba(11,20,48,.62);border:1px solid rgba(255,255,255,.28);
  backdrop-filter:blur(3px)}
.svcrate:hover{background:rgba(17,173,243,.32);border-color:#fff}
.svcrate .gmark{width:16px;height:16px;flex:none;display:block}
.svcrate .srow{width:70px;height:13.5px;flex:none;display:block;fill:#F5B82E}
/* Set solid at line-height:1 so each item's box is exactly its own font-size
   tall, and the drawn stars centre against the figure rather than against
   whatever leading the font asked for. */
.svcrate b{color:#fff;font-weight:800;font-size:15px}
.svcrate span{color:rgba(255,255,255,.88);font-size:13px}
@media (max-width:560px){
  .svcrate{gap:7px;padding:6px 12px}
  .svcrate .gmark{width:14px;height:14px}
  .svcrate .srow{width:60px;height:11.5px}
  .svcrate span{font-size:12px}
}

.hbadges{margin-top:-64px;position:relative;z-index:5}
.hbadges .card{display:flex;gap:clamp(16px,2.4vw,34px);align-items:center;justify-content:center;
  flex-wrap:nowrap;position:relative;z-index:0;background:none;border:0;box-shadow:none;
  /* The white slab is the card's own box, so at the content width it ran a
     long way past the last mark on either side. It takes the width of the
     marks it holds instead, and stays centered under the hero. */
  width:max-content;max-width:100%;margin-left:auto;margin-right:auto;
  /* The slab is inset:0 on this box, so with no padding it hugged the marks
     and the row read as cramped. The horizontal figure is larger than the
     vertical on purpose: the slab is skewed 6 degrees, so its left and right
     edges lean IN over the first and last mark, and the padding has to clear
     the lean as well as leave a margin. */
  padding:24px clamp(34px,4.6vw,62px)}
@media(max-width:700px){
  .hbadges .card{display:grid;grid-template-columns:1fr 1fr;justify-items:center;
    align-items:center;gap:22px 16px;padding:26px 20px;width:auto}
  .hbadges .nadca-smart{grid-column:1/-1}
}

.hbadges .card::before{content:"";position:absolute;inset:0;z-index:-1;transform:skewX(-6deg);
  background:#fff;border:1px solid #E3E9EE;box-shadow:0 20px 48px rgba(16,25,60,.26)}
.hbadges img{margin:0}
section.hs{padding:52px 0}
section.hs h2{font-size:clamp(26px,3vw,36px);font-style:italic;margin:0 0 6px;text-align:center;
  color:#1B2B66}
section.hs .hsub{text-align:center;color:#5A6B7A;margin:0 0 26px}
/* Square, because the photographs are square. All eight service pictures
   are 500x500; the card showed them 292 wide by 170 tall, so a third of
   every one was cropped away - and what a photograph of a job puts in the
   middle is the work, so the middle is what went. A 1:1 box shows each one
   whole at any column width. */
.svcgrid .card img{aspect-ratio:1/1;height:auto;object-fit:cover;display:block;
  margin:-18px -20px 14px;max-width:none;width:calc(100% + 40px)}
.svcgrid .card b{font-size:17.5px}
.svcgrid .card span{display:block;margin-top:5px}
.hpull{background:#2749CB;color:#fff;padding:52px 0}
/* 105ch, not the 68ch a column of body text wants. This is 33px centred
   display type, and at 68ch the quote ran eight lines and pushed the name
   and date most of a screen down. 105ch is the point where it stops
   helping: 105 and 125 both settle on five lines, so the extra width buys
   longer lines and nothing else. */
.hpull blockquote{border:0;background:none;margin:0;padding:0;max-width:105ch;margin:0 auto;
  text-align:center}
.hpull .q{font-size:clamp(23px,3vw,33px);font-style:italic;font-weight:700;line-height:1.35}
/* The platform's mark opens the card; the portrait now closes it, sitting
   directly above the name so the face and the person read as one unit. */
.hpull .pplat{display:block;margin:0 auto 14px;object-fit:contain}
.hpull .pav{width:64px;height:64px;object-fit:cover;display:flex;margin:28px auto 10px}
/* The photograph takes the same lean as the initials chip beside it, cut
   rather than skewed - a skewX on a portrait warps the face. */
.hpull img.pav{clip-path:polygon(11% 0,100% 0,89% 100%,0 100%)}
/* a real portrait is shown whole - the skew would cut across the face */
.hpull img.pav.rpic{clip-path:none;object-fit:contain}
.hpull span.pav{align-items:center;justify-content:center;background:#11ADF3;color:#fff;
  font-weight:800;font-size:22px;transform:skewX(-6deg)}
.hpull .a{margin:0;opacity:.9;font-weight:600}
/* The date sits under the name, quieter than it. It is not decoration: a
   review the reader can date is a review they can weigh, and without it the
   card could be a testimonial from any year. Opacity rather than a grey,
   because the ground here is the brand navy and #5A6B7A is for paper. */
.hpull .pd{margin:3px 0 0;opacity:.62;font-size:13px;letter-spacing:.04em}
.hpull .stars{color:#F5B82E;font-size:22px;letter-spacing:4px}
.hcommit{background:#fff}
.htesti{background:#F2F6FD}
.cgrid{display:grid;gap:36px;align-items:center}
@media(min-width:920px){.cgrid{grid-template-columns:1fr 1fr}}
section.hs .cgrid h2,section.hs .cgrid .hsub{text-align:left}
.cgrid>img{width:100%;height:auto;margin:0}
.hcommit .hfeat{grid-template-columns:repeat(2,1fr)}
/* the section headings in the two-column blocks are royal italic, as live */
.cgrid h2{color:#2749CB;font-size:clamp(26px,3vw,36px)}
.cgrid .blead{color:#2749CB}
/* the section photographs carry the brand diagonal: commitment cut on its
   right edge, the FAQ photo cut on its left - opposite, as asked */
.cgrid>img.cut-r{clip-path:polygon(0 0,100% 0,calc(100% - 58px) 100%,0 100%);
  height:100%;min-height:440px;object-fit:cover}
.cgrid>img.cut-l{clip-path:polygon(58px 0,100% 0,100% 100%,0 100%);
  height:100%;min-height:440px;object-fit:cover}
/* commitment features: the live row style - rosette check + bold italic text */
.hfeat div{padding:6px 0;display:flex;align-items:center;gap:12px;
  font-style:italic;font-weight:700;font-size:18px;color:#26324B}
.hfeat img{margin:0;flex:none}
/* faq: bare rows with the skewed chevron bullet */
.hfaq{background:#fff}
/* the hero centers on its axis - headline, subtitle, then the
   accreditation badge - and the subtitle runs its full width so it holds
   one line on a desktop */
.hubhero{display:flex;flex-direction:column;align-items:center;text-align:center;gap:20px}
.hubhero>div{min-width:0;width:100%}
.hubhero .lede{max-width:none;margin-left:auto;margin-right:auto}
.hero-badge,.hero-badges img{max-height:84px;width:auto;flex:none;margin:0}
.hero-badges{display:flex;gap:22px;align-items:center;justify-content:center;flex-wrap:wrap}
@media(max-width:900px){.hubhero{gap:16px}
  .hero-badge,.hero-badges img{max-height:56px}.hero-badges{gap:14px}}
/* the copy above the service list centers with it */
.hubintro{margin:0 0 10px;text-align:center}
.hubintro p{max-width:78ch;margin-left:auto;margin-right:auto}
.hubintro img{max-height:76px;width:auto;margin:14px auto 0;display:block}
/* The FAQ is a full-bleed band, like the homepage sections: the soft ground
   runs edge to edge while the copy stays at the content width, and the
   heading and standfirst sit inside the panel rather than above it. */
.hubfaqs{margin:44px 0 0;background:#F2F6FD;padding:52px 0}
.hubfaqs .faq.hubfaq{background:none;margin:0;padding:0}
.hubfaq>h2{margin:0 0 6px;font-size:clamp(21px,2.3vw,27px)}
.hubfaq .faqsub{margin:0 0 20px;color:#5A6B7A;max-width:78ch}
@media(max-width:700px){.hubfaqs{padding:34px 0}}

/* ---- phones: give the writing the screen -------------------------------
   Measured on a 375px window. The page gutter was 20px a side and the FAQ
   box added 26px of its own, so a question was set in 283px - and every
   question then ran to two or three lines, which is what made that section
   look like nothing but air. Half the gutter and half the box's padding
   puts the same question in 341px.

   The line height goes with it. 1.62 is right for a 72-character measure
   on a desktop; in a phone column it opens gaps the eye has to jump, and
   the FAQ answers - the same size as body copy - showed it worst. */
@media(max-width:700px){
  .wrap{padding:0 14px}
  .faq{padding:16px 13px;margin:20px 0}
  section.hs{padding:34px 0}
  body{line-height:1.4}
  article p,article li,.faq .ans{line-height:1.4}
  article p{margin-bottom:13px}
}
/* the chips filter in place; nothing is fetched and nothing is removed */
.faqfilter{display:flex;flex-wrap:wrap;gap:9px;margin:6px 0 22px}
.fchip{font:inherit;font-size:13.5px;font-weight:700;cursor:pointer;border:1px solid #E3E9EE;
  background:#fff;color:#3F3F3F;padding:9px 15px;transform:skewX(-10deg);min-height:40px;
  display:inline-flex;align-items:center;gap:7px}
.fchip>*{transform:skewX(10deg)}
.fchip i{font-style:normal;font-size:11.5px;color:#5A6B7A;font-weight:600}
.fchip:hover{border-color:#11ADF3;color:#0B87C2}
.fchip.on{background:#2749CB;border-color:#2749CB;color:#fff}
.fchip.on i{color:#C9D6FF}
/* a service page's own questions, and the line back from a single question */
.faqback{display:flex;align-items:center;justify-content:space-between;gap:18px;
  flex-wrap:wrap;margin:34px 0 0;padding:20px 24px;background:#F2F6FD;
  border-left:4px solid #11ADF3}
.faqback span{color:#5A6B7A;font-size:14.5px}
.faqback b{color:#1B2B66;font-size:16px;display:block;margin-top:2px}
/* About Us reads as bands like the rest of the site, alternating ground. */
.abintro{background:#fff}
.abmission{background:#F2F6FD}
/* the pair reads as a spread: copy and photograph swapping sides, each
   photograph cut on the edge that faces its text */
.abintro .cgrid,.abmission .cgrid{align-items:center}
.abintro .cgrid h2,.abmission .cgrid h2{margin-top:0}
.abintro .cgrid h3{font-size:19px;color:#1B2B66;margin:14px 0 8px}
.abintro .cgrid p,.abmission .cgrid p{color:#5A6B7A;line-height:1.7;margin:0 0 14px;
  max-width:56ch}
.abmission .more{margin:18px 0 0}
@media(max-width:919px){
  /* stacked, the diagonal would slice the top of the photograph */
  .abintro .cgrid>img,.abmission .cgrid>img{clip-path:none;min-height:0;height:auto}
  .abmission .cgrid>img{order:2}
}
.absvc{background:#fff}
.abwhy{background:#F2F6FD}
.abareas{background:#fff}
.aboffices{background:#F2F6FD}
.abcopy{max-width:78ch}
.abcopy h3{font-size:19px;color:#1B2B66;margin:22px 0 6px}
.abcopy h3:first-child{margin-top:0}
.abcopy p{margin:0 0 12px;color:#5A6B7A;line-height:1.7}
.abcopy ul{margin:0 0 12px;padding-left:20px;color:#5A6B7A}
.wgrid{display:grid;gap:20px;grid-template-columns:1fr;margin-top:8px}
@media(min-width:760px){.wgrid{grid-template-columns:repeat(3,1fr)}}
.wcard{background:#fff;padding:24px;border-left:4px solid #11ADF3}
.wcard img{width:52px;height:52px;object-fit:contain;margin:0 0 12px;display:block}
.wcard b{display:block;font-size:17px;color:#1B2B66;margin-bottom:8px}
.wcard p{margin:0;color:#5A6B7A;font-size:14.5px;line-height:1.6}
.abareas .silolist{margin-top:14px}
.abareas .more{margin-top:22px;text-align:center}
.ogrid{display:grid;gap:18px;grid-template-columns:1fr;margin-top:8px}
@media(min-width:620px){.ogrid{grid-template-columns:1fr 1fr}}
@media(min-width:1000px){.ogrid{grid-template-columns:repeat(5,1fr)}}
.ocard{background:#fff;padding:20px;border-top:3px solid #2749CB}
.ocard b{display:block;font-size:16px;color:#1B2B66;margin-bottom:6px}
.ocard p{margin:0 0 8px;color:#5A6B7A;font-size:14px;line-height:1.5}
.ocard a{color:#0B87C2;font-weight:700;font-size:15px;text-decoration:none}
.ocard a:hover{text-decoration:underline}

/* the reviews index: one card per reviewer, in their own words */
.reviewgrid{display:grid;gap:18px;grid-template-columns:1fr;margin:10px 0 0}
@media(min-width:700px){.reviewgrid{grid-template-columns:1fr 1fr}}
@media(min-width:1100px){.reviewgrid{grid-template-columns:repeat(3,1fr)}}
.rcard{background:#fff;border:1px solid #E3E9EE;padding:20px;display:flex;
  flex-direction:column;gap:12px}
/* [hidden] is a UA rule and loses to the display above, so the filter has
   to say it here or nothing disappears */
.rcard[hidden]{display:none}
.rcard .thead{display:flex;align-items:flex-start;gap:11px}
/* portraits are circular as their platform supplies them; the brand's skew
   would slice the face, so they are shown whole */
.rcard .rpic{width:48px;height:48px;flex:none;object-fit:contain;margin:0}
.rcard .rdate{color:#5A6B7A;font-size:12px;opacity:.85;line-height:1.25}
/* Photographs the reviewer attached to their own review. Square-cropped to
   a strip so a card with three keeps the shape of one with none; each opens
   the full frame. */
.rshots{display:flex;gap:8px;margin:12px 0 0;flex-wrap:wrap}
.rshots a{display:block;line-height:0;border:1px solid #E3E9EE}
.rshots a:hover{border-color:#11ADF3}
.rshots img{width:74px;height:74px;object-fit:cover;margin:0;display:block}
.rshots a{cursor:zoom-in}
/* The lightbox is a native <dialog>, so the browser supplies the modal
   focus trap and Escape and the script only has to move between
   photographs. With JavaScript off the thumbnails stay ordinary links to
   the full image, which is what they were before. */
.lbox{border:0;padding:0;background:none;max-width:96vw;max-height:96vh;
  overflow:visible;color:#fff}
.lbox::backdrop{background:rgba(11,20,48,.94)}
.lbwrap{position:relative}
.lbfig{display:flex;flex-direction:column;align-items:center;gap:12px;margin:0}
.lbox img{display:block;margin:0;max-width:min(1080px,92vw);max-height:80vh;
  width:auto;height:auto;background:#0B1430}
.lbbar{display:flex;align-items:center;gap:14px;font-size:14px;min-height:40px}
.lbcap{margin:0;color:#C9D6EC;min-width:5ch;text-align:center}
.lbox button{font:inherit;color:#fff;background:rgba(255,255,255,.12);
  border:1px solid rgba(255,255,255,.34);width:40px;height:40px;cursor:pointer;
  line-height:1;font-size:20px;padding:0}
.lbox button:hover{background:rgba(255,255,255,.26)}
.lbox button:focus-visible{outline:2px solid #11ADF3;outline-offset:2px}
.lbclose{position:absolute;top:-50px;right:0}
@media(max-width:640px){.lbclose{top:-46px}.lbox img{max-height:70vh}}
/* the platform's mark, which is the way back to the review it came from */
.rcard .rplatl{margin:0 0 0 auto;flex:none;display:block;line-height:0}
.rcard .rplatl .rplat{margin:0}
.rcard .rplatl:hover{opacity:.72}
.rcard .rplatl:focus-visible{outline:2px solid #11ADF3;outline-offset:3px}
/* Reviews arrive a screenful at a time. Every one of them is in the page -
   this hides the rest rather than fetching anything - so a reader without
   JavaScript, and anything reading the HTML, still gets all of them. */
.rload{display:block;margin:28px auto 0;font:inherit;font-size:14px;
  font-weight:700;cursor:pointer;background:#fff;color:#0B87C2;
  border:1px solid #E3E9EE;padding:12px 26px}
.rload[hidden]{display:none}
.rload:hover{border-color:#11ADF3;background:#2749CB;color:#fff}
.rload:focus-visible{outline:2px solid #11ADF3;outline-offset:2px}
.rload i{font-style:normal;font-weight:600;opacity:.7;margin-left:7px}
/* The contact page. Call first, then the offices, then the form: the page it
   replaces gave five branches a heading and a street address each and not one
   telephone number between them, and put the form last of all. */
.chero .lede{max-width:58ch}
.cacts{display:flex;flex-wrap:wrap;align-items:center;gap:12px 22px;margin-top:22px}
.chours{font-size:14.5px;color:#DCE8F6}
.chours b{color:#fff;font-weight:700}
.crate{display:inline-flex;align-items:center;gap:9px;font-size:13.5px;color:#fff;
  border:1px solid rgba(255,255,255,.34);padding:7px 14px}
.crate .stars{color:#F5B82E;letter-spacing:2px;font-size:14px}
.crate b{font-weight:800}
.cbranch{padding:32px 0 4px}
.cbhead{display:flex;align-items:baseline;gap:14px;flex-wrap:wrap;margin:0 0 16px}
.cbhead h2{margin:0;font-size:22px}
.cbhead p{margin:0;color:#5A6B7A;font-size:14.5px}
/* The offices as a map and a numbered list, the numbers shared between them.
   Drawn rather than embedded - see the contact page's office_map for why. */
.cmapduo{display:grid;gap:26px;align-items:start}
/* One split for both rows, so the form below sits exactly under the map. */
@media(min-width:900px){.cmapduo,.cduo{grid-template-columns:1fr 1fr}}
/* The map is a picture we host, with the pins placed over it. It carries a
   real basemap because a drawn one cannot show roads, water or the towns
   either side - see office_map and tools/fetch_map.py. */
.cmap{margin:0;border:1px solid #E3E9EE;background:#fff;padding:9px}
.cmapimg{position:relative;line-height:0}
.cmapimg img{display:block;width:100%;height:auto;margin:0}
/* Corvallis and Albany are fifteen miles apart, which is 27px at this zoom,
   so the pins are sized to sit beside each other rather than overlap.

   Every rule below is scoped to .cmapimg, and has to stay that way. The
   drawn map on /services-areas/ calls its pins .mpin too, and an unscoped
   .mpin{transform:translate(-50%,-50%)} reached them: inside an SVG those
   percentages resolve against the viewBox, so all 25 towns moved 590 by 450
   user units up and left, off the map and into the ocean. Nothing errored
   and the page still scored fine; it just showed the wrong Oregon. */
.cmapimg .mpin{position:absolute;transform:translate(-50%,-50%);width:21px;height:21px;
  border-radius:50%;display:flex;align-items:center;justify-content:center;
  background:#11ADF3;color:#fff;font-size:11.5px;font-weight:800;line-height:1;
  text-decoration:none;box-shadow:0 0 0 1.5px #fff,0 1px 4px rgba(11,20,48,.45)}
.cmapimg .mpin.hq{background:#2749CB}
.cmapimg .mpin:hover{background:#1B2B66;z-index:2}
.cmapimg .mpin:focus-visible{outline:2px solid #1B2B66;outline-offset:3px;z-index:2}
.cmap figcaption{margin:8px 2px 0;font-size:11.5px;color:#5A6B7A;line-height:1.3}
/* the card a pin opens: the same details as its row in the list */
.cmapimg .mpop{position:absolute;z-index:4;width:238px;max-width:78%;background:#fff;
  border:1px solid #E3E9EE;box-shadow:0 10px 28px rgba(11,20,48,.3);
  padding:12px 14px 13px;line-height:1.45;
  transform:translate(-50%,calc(-100% - 17px))}
.cmapimg .mpop.below{transform:translate(-50%,17px)}
.cmapimg .mpop[hidden]{display:none}
.cmapimg .mpop::after{content:"";position:absolute;left:50%;width:11px;height:11px;background:#fff;
  transform:translateX(-50%) rotate(45deg)}
.cmapimg .mpop:not(.below)::after{bottom:-6.5px;border-right:1px solid #E3E9EE;
  border-bottom:1px solid #E3E9EE}
.cmapimg .mpop.below::after{top:-6.5px;border-left:1px solid #E3E9EE;border-top:1px solid #E3E9EE}
.cmapimg .mpop .bphone{min-height:0;font-size:16.5px}
.cmapimg .mpop address{font-style:normal;font-size:13px;color:#5A6B7A;margin:4px 0 7px;
  line-height:1.45}
.cmapimg .mpopx{position:absolute;top:3px;right:5px;background:none;border:0;font:inherit;
  font-size:18px;line-height:1;color:#5A6B7A;cursor:pointer;padding:3px 5px}
.cmapimg .mpopx:hover{color:#1B2B66}
.cmapimg .mpopx:focus-visible{outline:2px solid #11ADF3;outline-offset:1px}
.branchlist{list-style:none;margin:0;padding:0;display:flex;flex-direction:column}
/* number | city and phone | address | directions, aligned down the list */
/* Each row is its own grid, so the city column is a fixed width rather than
   sized to its content: "Corvallis HEAD OFFICE" is wider than "Albany", and
   auto widths would step the addresses in and out down the list. */
.brow{display:grid;grid-template-columns:26px 158px minmax(0,1fr) auto;
  gap:4px 14px;align-items:center;padding:12px 0;border-bottom:1px solid #E3E9EE}
.brow:first-child{padding-top:0}
.brow:last-child{border-bottom:0}
.bnum{grid-row:span 1;width:26px;height:26px;display:inline-flex;align-items:center;
  justify-content:center;background:#11ADF3;color:#fff;font-size:13.5px;font-weight:800}
.brow.hq .bnum{background:#2749CB}
.binfo{display:flex;flex-direction:column;gap:1px;min-width:0}
.bline{display:flex;align-items:baseline;gap:8px;flex-wrap:wrap}
.bcity{font-size:16.5px;color:#1B2B66}
.brow address{font-style:normal;font-size:13.5px;color:#5A6B7A;line-height:1.4;min-width:0}
.hqtag{font-size:10.5px;font-weight:800;letter-spacing:.09em;text-transform:uppercase;
  color:#2749CB}
/* the number is the point of the row, and on a phone it has to be big enough
   to hit: a bare link of text was 28px tall */
.bphone{font-size:16.5px;font-weight:800;color:#0B87C2;text-decoration:none;
  display:inline-flex;align-items:center;min-height:30px}
.bphone:hover{text-decoration:underline}
.bdir{font-size:13px;font-weight:700;color:#2749CB;text-decoration:none;white-space:nowrap}
.bdir::after{content:" ›"}
.bdir:hover{text-decoration:underline}
.cmapnote{margin:18px 0 0;font-size:14.5px;color:#5A6B7A}
.cmapnote a{color:#0B87C2;font-weight:700;text-decoration:none}
.cmapnote a:hover{text-decoration:underline}
@media(max-width:700px){
  .bphone{min-height:44px;font-size:18px}
  .brow{grid-template-columns:26px 1fr;gap:2px 10px;align-items:start}
  .brow address,.brow .bdir{grid-column:2}
  .bdir{justify-self:start;margin-top:3px}
}
.cduo{display:grid;gap:26px;padding:28px 0 12px;align-items:start}
.cform .quote{margin:0}
.cside{display:flex;flex-direction:column;gap:14px}
.cpanel{border:1px solid #E3E9EE;background:#F2F6FD;padding:16px 17px}
.cpanel h2{margin:0 0 9px;font-size:11.5px;font-weight:800;letter-spacing:.09em;
  text-transform:uppercase;color:#2749CB}
.cpanel p{margin:0 0 6px;font-size:14.5px;color:#5A6B7A}
.cpanel p:last-child{margin-bottom:0}
.cpanel a{color:#0B87C2;font-weight:700;text-decoration:none}
.cpanel a:hover{text-decoration:underline}
.csoc{display:flex;gap:9px;margin-top:2px}
.csoc a{width:36px;height:36px;display:inline-flex;align-items:center;justify-content:center;
  background:#2749CB;color:#fff}
.csoc a:hover{background:#11ADF3}
/* a reviewer's own page: the rating, where it was left, and the way back */
.rvbar{display:flex;align-items:center;gap:16px;flex-wrap:wrap;margin:0 0 18px;
  padding-bottom:16px;border-bottom:1px solid #E3E9EE}
.rvbar .stars{color:#F5B82E;font-size:19px;letter-spacing:2px}
.rvbar .rvon{display:inline-flex;align-items:center;gap:7px;color:#5A6B7A;font-size:14px}
.rvbar .rvon img{margin:0;object-fit:contain}
.rvbar .rvdate{color:#5A6B7A;font-size:14px}
.rvback{margin:26px 0 0}
.rvback a{color:#0B87C2;font-weight:600;text-decoration:none}
.rvback a:hover{text-decoration:underline}
/* align-items defaults to stretch, so one chip that wraps made every chip
   as tall as itself */
.revfilter{display:flex;flex-wrap:wrap;gap:9px;margin:6px 0 22px;justify-content:center;
  align-items:center}
.revfilter .fchip{min-height:0;padding:7px 14px;font-size:13px;white-space:nowrap}
/* the site's default img margin is 18px top and bottom, which inside a chip
   made it twice the height of the one without a logo */
.revfilter .fchip img{width:14px;height:14px;object-fit:contain;margin:0}
/* The filter and the sort share one bar, which ships hidden and is revealed
   by the script that drives them. Neither does anything without JavaScript,
   and a control that does nothing is worse than no control at all. */
.revbar{display:flex;flex-wrap:wrap;align-items:center;justify-content:center;
  gap:8px 20px;margin:6px 0 22px}
.revbar[hidden]{display:none}
.revbar .revfilter{margin:0}
.revsort{display:inline-flex;align-items:center;gap:8px;font-size:13px;
  font-weight:700;color:#5A6B7A;white-space:nowrap}
.revsort select{font:inherit;font-size:13px;font-weight:700;color:#1B2B66;
  background:#fff;border:1px solid #E3E9EE;padding:7px 10px;cursor:pointer}
.revsort select:hover{border-color:#11ADF3}
.revsort select:focus-visible{outline:2px solid #11ADF3;outline-offset:2px}
.rcard .rplat{margin:0 0 0 auto;flex:none;width:26px;height:26px;object-fit:contain}
.rcard .tinit{width:48px;height:48px;flex:none;display:inline-flex;align-items:center;
  justify-content:center;background:#2749CB;color:#fff;font-weight:800;font-size:17px;
  transform:skewX(-6deg)}
.rcard .twho{display:flex;flex-direction:column;gap:1px;line-height:1.25}
.rcard .twho b{font-size:15.5px;color:#1B2B66;line-height:1.2}
.rcard .stars{color:#F5B82E;letter-spacing:2px;font-size:14px;line-height:1.15}
.rcard p{margin:0;color:#5A6B7A;font-size:14.5px;line-height:1.6;flex:1}
/* a rating and a price, with nothing written - labeled as such */
.rcard .rprice{display:flex;align-items:center;gap:10px;flex-wrap:wrap;color:#3F3F3F;
  font-size:14.5px}
.rcard .rplabel{background:#F2F6FD;color:#5A6B7A;font-size:11.5px;font-weight:700;
  letter-spacing:.04em;text-transform:uppercase;padding:4px 10px;transform:skewX(-10deg)}
.rcard .rprice b{color:#1B2B66}
.rcard .rmore{color:#0B87C2;font-weight:600;font-size:13.5px;text-decoration:none}
.rcard .rmore:hover{text-decoration:underline}
/* The whole review is in the card. A long one is clamped so the cards keep a
   common shape, and the button under it opens the review whole. The clamp
   arrives with the script: with JavaScript off nothing is cut off, and the
   button that would open it never appears. */
.rcard .rtext.clamp{display:-webkit-box;-webkit-line-clamp:7;
  -webkit-box-orient:vertical;overflow:hidden}
.rfull{font:inherit;font-size:13.5px;font-weight:600;color:#0B87C2;
  background:none;border:0;padding:0;cursor:pointer;align-self:flex-start}
.rfull:hover{text-decoration:underline}
.rfull:focus-visible{outline:2px solid #11ADF3;outline-offset:2px}
/* One review, opened whole. A native <dialog> as the lightbox is, so the
   browser supplies the focus trap and Escape. Its body carries .rcard, so
   the head, text and photographs cloned out of the card are styled by the
   card's own rules rather than by a second set that could drift from them. */
.rbox{border:0;padding:0;background:none;max-width:min(660px,92vw);color:#1B2B66}
.rbox::backdrop{background:rgba(11,20,48,.88)}
.rbwrap{position:relative}
.rbox .rbbody{padding:26px;gap:14px;max-height:76vh;overflow:auto}
.rbox .rtext{font-size:15px;flex:none}
.rbclose{position:absolute;top:-46px;right:0;font:inherit;font-size:20px;line-height:1;
  width:40px;height:40px;padding:0;cursor:pointer;color:#fff;
  background:rgba(255,255,255,.12);border:1px solid rgba(255,255,255,.34)}
.rbclose:hover{background:rgba(255,255,255,.26)}
.rbclose:focus-visible{outline:2px solid #11ADF3;outline-offset:2px}
@media(max-width:640px){.rbclose{top:-42px}.rbox .rbbody{padding:20px;max-height:70vh}}
.faqindex{margin:8px 0 0}
.faqindex .faqmore{margin:8px 0 0}
.faqindex .faqmore a{color:#0B87C2;font-weight:600;font-size:14px}
.hfaq .faq{background:none;padding:0;margin:0}
.hfaq .faq summary,.hubfaq summary{display:flex;align-items:flex-start;gap:14px;padding:9px 0;font-size:16px;
  color:#26324B;font-weight:700;line-height:1.4}
.hfaq .faq summary::before{margin-top:0}
.hfaq .faq summary::before,.hubfaq summary::before{content:"";display:inline-flex;width:27px;height:23px;flex:none;
  background:#2749CB url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 12'%3E%3Cpath d='M1.5 1.5l5 4.5-5 4.5' stroke='white' stroke-width='2.2' fill='none'/%3E%3C/svg%3E") center/9px no-repeat;
  transform:skewX(-10deg);transition:transform .15s ease}
.hfaq .faq summary::after,.hubfaq summary::after{content:none}
.hfaq .faq details[open] summary::before,.hubfaq details[open] summary::before{transform:skewX(-10deg) rotate(90deg)}
.hfaq .faq .ans,.hubfaq .ans{padding:2px 0 12px 41px;color:#5A6B7A}
/* the NADCA smart badge, served and verified by Yoshki */
.nadca-smart{width:200px;max-width:100%;flex:none}
.nadca-smart>div{position:relative;padding-bottom:71.3%;height:0;overflow:hidden}
.nadca-smart iframe{position:absolute;top:0;left:0;width:100%;height:100%;
  border:0;margin:0;padding:0;background:transparent}
.hbadges img{max-height:clamp(46px,5.4vw,84px);width:auto;height:auto;flex:none}
.hfeat{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:16px;margin-top:26px}

.htesti .cards{grid-template-columns:repeat(auto-fit,minmax(270px,1fr))}
.htesti .card{display:flex;flex-direction:column;gap:13px;padding:20px 22px}
.htesti .thead{display:flex;align-items:center;gap:12px}
.htesti .thead img{width:48px;height:48px;object-fit:cover;margin:0;flex:none;
  clip-path:polygon(11% 0,100% 0,89% 100%,0 100%)}
.htesti .tinit{width:48px;height:48px;flex:none;display:inline-flex;align-items:center;
  justify-content:center;background:#2749CB;color:#fff;font-weight:800;font-size:17px;
  transform:skewX(-6deg)}
.htesti .twho{display:flex;flex-direction:column;gap:3px}
.htesti .twho b{font-size:15px;color:#1B2B66;margin:0}
.htesti .stars{color:#F5B82E;font-size:15px;letter-spacing:2px}
.htesti .rpic{width:48px;height:48px;flex:none;object-fit:contain;margin:0;clip-path:none}
/* Every card ends the same way. Three reviews of very different lengths -
   35 characters and 228 - left ragged amounts of nothing under the text;
   now the quote takes the room it needs and the attribution sits on the
   floor, so the cards line up along the bottom as well as the top. The
   minimum on the quote keeps a one-line review from looking like a
   mistake. */
.htesti p{min-height:4.65em}
.htesti .tfoot{margin-top:auto;padding-top:12px;border-top:1px solid #E3E9EE;
  display:flex;align-items:center;gap:8px;color:#5A6B7A;font-size:12.5px}
.htesti p{color:#3F3F3F;font-size:15px;line-height:1.55;margin:0}
.htesti .more{text-align:center;margin-top:22px}
.hsvc .more{text-align:center;margin-top:26px}
.htesti .tplat{width:15px;height:15px;margin:0;flex:none;object-fit:contain}
section.hs.hvalley{background:#F2F6FD;padding:0;position:relative}
.hvalley .maph{position:absolute;top:36px;left:50%;transform:translateX(-50%);z-index:3;
  margin:0;white-space:nowrap;padding:14px 34px;color:#2749CB}
.hvalley .maph::before{content:"";position:absolute;inset:0;z-index:-1;transform:skewX(-10deg);
  background:#fff;box-shadow:0 10px 30px rgba(16,25,60,.18)}
.areamap{display:block;width:100%;height:auto;margin:0}
.areamap .mland{fill:#EDF2FB}
.areamap .msea{fill:#B7DDF2}
.areamap .mriver{fill:none;stroke:#8FC6EA;stroke-width:5;stroke-linejoin:round;stroke-linecap:round}
.areamap .mroad{fill:none;stroke:#fff;stroke-width:5;stroke-linejoin:round}
.areamap .mband{fill:#2749CB;fill-opacity:.12;stroke:#2749CB;stroke-opacity:.4;stroke-width:2.5}
.areamap .msealbl,.areamap .mrvlbl{font:700 13px "Myrid Pro","Segoe UI",sans-serif;fill:#5E9EC4;
  letter-spacing:.22em}
.areamap .mi5{font:800 12px "Myrid Pro","Segoe UI",sans-serif;fill:#9AA5C4}
.areamap .minset polygon{fill:#fff;stroke:#9AA5C4;stroke-width:1.5}
.areamap .minset rect{fill:#2749CB;fill-opacity:.18;stroke:#2749CB;stroke-width:1.5}
.areamap .minset text{font:700 12px "Myrid Pro","Segoe UI",sans-serif;fill:#8A93B4;letter-spacing:.14em}
.areamap .mpin rect{fill:#2749CB}
.areamap .mpin circle{fill:#fff}
.areamap .mpin text{font:600 17px "Myrid Pro","Segoe UI",sans-serif;fill:#1B2B66}
.areamap .mpin:hover rect{fill:#11ADF3}
.areamap .mpin:hover text{fill:#2749CB;text-decoration:underline}
.areamap .mco{font:italic 700 15px "Myrid Pro","Segoe UI",sans-serif;fill:#8A93B4;
  letter-spacing:.06em;text-transform:uppercase}

.hcontact .cwrap{display:grid;gap:34px;align-items:stretch}
@media(min-width:920px){.hcontact .cwrap{gap:0}}
@media(min-width:920px){.hcontact .cwrap{grid-template-columns:1fr 1fr}}
.hcontact .cbox{background:#F2F6FD;padding:36px 66px 34px 44px;height:100%;
  clip-path:polygon(0 0,100% 0,calc(100% - 58px) 100%,0 100%)}
.hcontact .cbox .hsub{margin-bottom:6px}
.hcontact .quote{margin:8px 0 0;background:none;border:0;padding:0;height:auto}
.cphoto{position:relative;display:flex;min-height:420px}
.cphoto img{width:100%;height:100%;object-fit:cover;margin:0;
  clip-path:polygon(58px 0,100% 0,100% 100%,0 100%)}
.ccard{position:absolute;left:36px;bottom:32px;padding:18px 30px;color:#26324B}
.ccard::before{background:#fff;box-shadow:0 12px 34px rgba(16,25,60,.24)}
.ccard b{display:block;color:#2749CB;font-size:19px;margin-bottom:4px}
.ccard address{font-style:normal;font-size:14.5px;line-height:1.65}
.ccard a{color:#26324B;text-decoration:none;font-weight:600}
.ccard a:hover{color:#2749CB;text-decoration:underline}

/* the live site's fixed Call Now, bottom left on every page - its transform
   matrix (0.1763 shear) is exactly the 10deg the button system uses */
.callfab{position:fixed;left:25px;bottom:15px;z-index:45;color:#fff;text-decoration:none;
  font-weight:700;font-size:15.5px;text-transform:uppercase;letter-spacing:.02em;
  padding:12px 22px;display:inline-flex;align-items:center;gap:8px}
.callfab::before{background:#2749CB;box-shadow:0 6px 20px rgba(16,25,60,.35)}
.callfab:hover::before{background:#11ADF3}
/* It sits out the first screenful and steps aside at the very bottom.
   The .fabjs class is added by the script, so with JavaScript off the
   button simply stays where it has always been rather than never
   appearing at all. */
.callfab{transition:opacity .22s ease,transform .22s ease,visibility .22s}
html.fabjs .callfab{opacity:0;visibility:hidden;transform:translateY(14px);
  pointer-events:none}
html.fabjs .callfab.on{opacity:1;visibility:visible;transform:none;pointer-events:auto}
@media print{.callfab{display:none}}
/* ------------------------------------------------ tablet and phones */
@media(max-width:919px){
  /* stacked full-width sections go straight-edged; the lean stays on
     buttons, the badge slab, the logo chip, avatars and bullets */
  .cgrid>img.cut-r,.cgrid>img.cut-l,.cphoto img{clip-path:none}
  .hcontact .cbox{clip-path:none;padding:30px 28px}
  /* section photographs bleed to the viewport edges and touch the
     neighboring section; the FAQ image moves on top of its questions */
  .cgrid>img{width:100vw;max-width:100vw;margin-left:calc(50% - 50vw)}
  section.hs.hcommit,section.hs.hfaq{padding-top:0}
  .hfaq .cgrid>img{order:-1}
  .hs .cgrid{gap:30px}
  /* the contact halves pair up edge to edge, corners touching */
  section.hs.hcontact{padding-bottom:0}
  .hcontact .cwrap{width:100vw;margin-left:calc(50% - 50vw);gap:0}
}
@media(max-width:919px) and (min-width:640px){
  .hcontact .cwrap{grid-template-columns:46fr 54fr}
  .hcontact .cbox{padding:30px 34px}
  .cphoto{min-height:380px}
}
.burger,.fly-head,.navtoggle{display:none}
@media(max-width:1024px){
  .burger{display:inline-flex;flex-direction:column;justify-content:center;gap:5px;
    cursor:pointer;padding:12px;margin-left:4px}
  .burger span{display:block;width:24px;height:2.5px;background:#fff}
  nav.main{position:fixed;top:0;right:0;bottom:0;width:min(380px,92vw);z-index:80;
    display:block;background:linear-gradient(180deg,#16224F,#1D2E6E);
    transform:translateX(105%);transition:transform .25s ease;overflow-y:auto}
  .navtoggle:checked~nav.main{transform:none;box-shadow:-16px 0 50px rgba(0,0,0,.45)}
  html:has(.navtoggle:checked){overflow:hidden}
  .fly-head{display:flex;align-items:center;justify-content:space-between;
    background:#11ADF3;padding:14px 18px}
  .fly-head img{height:32px;width:auto}
  .fly-close{color:#fff;font-size:32px;line-height:1;cursor:pointer;padding:2px 10px}
  nav.main ul{display:block;padding:10px 10px 26px;margin:0}
  nav.main li{position:static}
  nav.main>ul>li>a{display:block;font-size:12.5px;letter-spacing:.12em;color:#9EDCFF;
    padding:16px 14px 6px;pointer-events:none}
  .caret{display:none}
  nav.main .sub,nav.main li:hover>.sub,nav.main li:focus-within>.sub,
  nav.main li:hover>.mega-panel{display:block;position:static;width:auto;min-width:0;
    background:none;box-shadow:none;padding:0;transform:none}
  nav.main .sub a,nav.main .mega-panel a{display:block;color:#fff;font-size:16.5px;
    font-weight:600;padding:10px 22px;text-transform:none;letter-spacing:0}
  nav.main .sub a:hover{background:rgba(255,255,255,.08);color:#fff}
  nav.main .mega-panel img{display:none}
  .mm-t b{color:#fff;font-size:16.5px}
  .mm-t small{display:none}
  nav.main .sub-all a{border-top:1px solid rgba(255,255,255,.16);color:#9EDCFF;
    margin-top:8px;padding-top:14px}
}
/* ------------------------------------------------------------ phones */
@media(max-width:640px){
  /* the bar carried 641px of content into a 390px viewport; every piece
     slims: smaller chip, icon-only call, tight quote, all one row */
  .bar{gap:8px}
  /* 14px, the gutter the footer and the top bar use on a phone */
  .wrap.full.bar{padding:16px 14px}
  .brand{margin-top:-16px}
  .brand{padding:8px 18px 8px 12px;margin-left:-14px}
  /* The bar cannot wrap here, so anything that does not fit gets cut off
     the right edge - which is what happened to the burger at 375px. The
     logo is the one piece that can give: it holds its size while there is
     room and shrinks only when squeezed, so nothing is ever clipped. */
  .bar .brand{flex:0 1 auto;min-width:0}
  .brand img{width:148px;max-width:100%;height:auto}
  /* Calling is already one tap away: CALL NOW is fixed to the bottom left
     of every page on a phone. A second phone button in the bar bought a
     duplicate at the price of the menu, so on phones the bar keeps the
     logo, the quote and the menu. */
  .bar .tel{display:none}
  .bar .cta{font-size:12px;padding:9px 9px;letter-spacing:0;margin-left:auto}
  .burger{padding:7px;margin-left:0}
  .tb .login{position:static;transform:none}
  .tb{justify-content:space-between;padding:3px 0;min-height:0}
  .tb .login,.ls a,.ls .ls-on{font-size:13px;padding:4px 2px}
  /* the hero breathes less on a phone */
  section.hhero{padding:46px 0 96px}
  .hhero .stars{font-size:19px}
  .hhero .grate{gap:11px;padding:7px 20px 7px 10px;margin-bottom:14px}
  .hhero .grate .stars{font-size:15px;letter-spacing:1px}
  .hhero .gmark{width:34px;height:34px}
  .hhero .gmark img{width:21px;height:21px}
  .hhero .lede{font-size:16.5px}
  /* the map keeps its size and pans instead of shrinking to 6px labels */
  section.hs.hvalley{padding-top:12px;overflow:hidden}
  .hvalley .maph{position:static;transform:none;white-space:normal;text-align:center;
    margin:0 16px 10px;padding:8px 16px;display:block}
  .areamap{width:100%;min-width:0}
  .areamap .mpin text{font:600 27px "Myrid Pro","Segoe UI",sans-serif}
  .areamap .mpin rect{width:20px;height:20px}
  .areamap .mco,.areamap .msealbl,.areamap .mrvlbl,.areamap .mi5{display:none}
  .cphoto{min-height:300px}
  /* services two-up, compact */
  .svcgrid{grid-template-columns:1fr 1fr;gap:12px}
  .svcgrid .card{padding:12px}
  .svcgrid .card img{margin:-12px -12px 10px;width:calc(100% + 24px)}
  .svcgrid .card b{font-size:14.5px}
  .svcgrid .card span{font-size:12.5px;line-height:1.45}
  /* Touch targets: a finger needs about 44px, and several controls were
     half that. Padding grows rather than type, so nothing reflows. */
  .ls a,.ls .ls-on{min-height:44px;padding:8px 10px}
  .tb .login{min-height:44px}
  /* A 36px line box gave every footer link 36px of leading, and a column
     of them read as a list with the air of a menu. The target stays 36px;
     it is made of padding now, so the words sit at their own height and
     wrapped links keep their lines together. */
  .fcol a,.legal a{display:inline-block;min-height:36px;line-height:1.35;
    padding:7px 0}
  .fcol ul{gap:0}
  .fcol address{line-height:1.45}
  address a{display:inline-block;min-height:32px;line-height:1.35;padding:5px 0}
  .fsoc a{min-width:44px;min-height:44px;align-items:center;justify-content:center}
  nav.main .sub a,nav.main .mega-panel a{min-height:48px;display:flex;align-items:center}
  .hfaq .faq summary,.hubfaq summary{min-height:48px}
  .fly-close{min-width:44px;min-height:44px;display:flex;align-items:center;
    justify-content:center}
  .skip{min-height:44px}
  /* every section's call to action centers on a phone */
  .hhero .hcta,.svchero .hcta{justify-content:center;gap:14px}
  .hhero .hcta .cta,.hhero .hcta .ghost,
  .svchero .hcta .cta,.svchero .hcta .ghost{font-size:14.5px;padding:12px 18px}
  .hs p:has(>.cta){text-align:center}
  button.submit{display:block;margin-left:auto;margin-right:auto}
    }
@media(max-width:380px){
  .brand{padding:8px 14px 8px 10px}
  .bar .cta{font-size:11.5px;padding:9px 8px}
  .burger{padding:6px}
}
@media (prefers-reduced-motion:reduce){*{transition:none!important;animation:none!important}}
