/* Elliott Electric. Concept "Lights on", ported from the Lovable build 2026-09-02.
   See PORT-NOTES.md. Every contrast pair here was computed, not eyeballed, and
   build/consistency.py recomputes them across BOTH palette states and fails on a regression.
   No blue anywhere: blue is the category default and the reason every electrician site looks
   like the last one. */

@font-face{font-family:'Barlow Condensed';font-style:normal;font-weight:600;font-display:swap;
  src:url('assets/fonts/barlow-condensed-normal-600-latin.woff2') format('woff2')}
@font-face{font-family:'Barlow Condensed';font-style:normal;font-weight:700;font-display:swap;
  src:url('assets/fonts/barlow-condensed-normal-700-latin.woff2') format('woff2')}
@font-face{font-family:'IBM Plex Sans';font-style:normal;font-weight:400 600;font-display:swap;
  src:url('assets/fonts/ibm-plex-sans-normal-400-600-latin.woff2') format('woff2')}

:root{
  --char:#14161A;      /* base charcoal */
  --char-2:#1B1E24;    /* panel face */
  --char-3:#07080A;    /* the dark the lights come up from */
  --lit:#F3EEE4;       /* warm off white */
  --amber:#F2A93B;     /* the one accent */
  --amber-ember:#C98A2E;
  --copper:#B87333;
  --copper-deep:#8F5722;
  --danger:#E4572E;    /* RESERVED for the no-power button. Nothing else. */
  /* The green comes from the badge, lifted to survive the charcoal. The artwork's own sage is
     #789060, which reads at 3.1:1 on this ground and fails. #8FAA6E is the same hue family at
     7.0:1 on --bg and 6.5:1 on --char-2. It is an ACCENT and not a second brand colour: amber
     stays the call-to-action, green marks the secondary path (text rather than call) and the
     badge's own family. consistency.py recomputes both in both palette states. */
  --sage:#8FAA6E;
  --sage-deep:#6E8C4E;

  --bg:var(--char);
  --ink:#D6CFC2;
  --ink-strong:var(--lit);
  --ink-mute:#9C948A;
  --glow:var(--amber);
  --hair:rgba(184,115,51,.42);

  --disp:'Barlow Condensed',Oswald,'Arial Narrow',system-ui,sans-serif;
  --body:'IBM Plex Sans',system-ui,-apple-system,'Segoe UI',Roboto,sans-serif;

  /* Tight rhythm. Scrolling is a cost, not a canvas. */
  --sec:clamp(34px,4.4vw,54px);
  --gut:clamp(18px,4.5vw,32px);
  --maxw:1080px;
}

/* Lights off. This is the state the page loads in for about a second, while the bulb in the hero
   video warms; site.js then takes the class off and the room comes up with the filament. There is
   no manual control, because the video is the switch (Dustin, 2026-09-02).
   The come-up changes the ENVIRONMENT, never the INFORMATION: the headline, the phone number and
   the licence line are all legible in both states, so a visitor who arrives mid-fade has already
   been shown everything that converts. See PORT-NOTES.md. */
html.dim{
  --bg:var(--char-3);
  --char-2:#111318;
  --ink:#9A9389;
  --ink-strong:#C9C2B6;
  --ink-mute:#918B81;
  --glow:var(--amber-ember);
  --sage:#7E9A5E;
  --hair:rgba(184,115,51,.20);
}

*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{margin:0;background:var(--bg);color:var(--ink);font-family:var(--body);
  font-size:17px;line-height:1.55;
  transition:background 1.4s cubic-bezier(.22,.61,.36,1),color 1.4s cubic-bezier(.22,.61,.36,1)}
img,video{max-width:100%;height:auto}

h1,h2,h3{font-family:var(--disp);font-weight:700;letter-spacing:-.02em;line-height:.95;
  color:var(--ink-strong);margin:0;transition:color .9s cubic-bezier(.22,.61,.36,1)}
h2{font-size:clamp(34px,5.4vw,56px);text-transform:none}
h3{font-size:clamp(19px,2.4vw,23px);letter-spacing:0;font-weight:600}
p{margin:0 0 .85em}
a{color:var(--glow)}
:focus-visible{outline:3px solid var(--amber);outline-offset:3px;border-radius:2px}

.skip{position:absolute;left:-9999px;top:0;background:var(--amber);color:var(--char);
  padding:10px 16px;font-weight:600;z-index:60}
.skip:focus{left:8px;top:8px}

section{padding:var(--sec) var(--gut);max-width:var(--maxw);margin:0 auto}

.ico{width:22px;height:22px;flex:none;display:block}
.ico-copper{color:var(--copper);width:24px;height:24px}

/* Unknown facts. Deliberately loud: a placeholder that looks like content is how a placeholder
   reaches a live page. build/facts-gate.py counts these in the built HTML. */
.tbd{display:inline-block;font-family:var(--body);font-size:.72em;font-weight:600;
  letter-spacing:.06em;text-transform:uppercase;color:var(--char);background:var(--amber);
  padding:.15em .5em;border-radius:2px;vertical-align:middle;white-space:nowrap}
.is-tbd{opacity:.9}
.preview-banner{margin:0;padding:11px 16px;background:var(--danger);color:#F3EEE4;
  font-weight:600;font-size:14.5px;text-align:center}

/* ---------------------------------------------------------------- hero */
.hero{position:relative;overflow:hidden;border-bottom:1px solid var(--hair);
  transition:border-color .9s ease}
.hero-video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  opacity:.34;filter:saturate(.75);pointer-events:none;transition:opacity 1.4s ease}
/* DESKTOP: pin the video to the right instead of steering it with object-position.
   object-position only bites while cover is cropping HORIZONTALLY, and which axis it crops
   flips with the viewport: at 1100x900 the source was wider so 0% pushed the bulb right, and at
   1440x820 it still crops horizontally but shows enough of the frame that the bulb lands back
   over the headline. Steering a full-bleed video is viewport-dependent by construction. Giving
   it its own box on the right is not: the copy column is clear at every width above 880.
   The mask feathers the left edge so it reads as light falling off, not a video in a rectangle. */
@media(min-width:880px){
  .hero-video{left:auto;right:0;width:58%;object-position:50% 50%;opacity:.85;
    -webkit-mask-image:linear-gradient(90deg,transparent 0,#000 26%,#000 100%);
            mask-image:linear-gradient(90deg,transparent 0,#000 26%,#000 100%)}
}
html.dim .hero-video{opacity:.12}
@media(min-width:880px){html.dim .hero-video{opacity:.24}}
/* The light pool is a flat radial wash, not a decorative gradient blob: it is the pool a single
   work light throws, and it brightens with the room. */
.light-pool{position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(58% 48% at 32% 42%,rgba(242,169,59,.16),transparent 72%);
  transition:opacity .9s ease}
html.dim .light-pool{opacity:.28}
/* Legibility scrim. The hero copy sits over a VIDEO, and the contrast census measures text
   tokens against the flat --bg token, which is not what is behind these words. That is a real
   blind spot in the gate and this is the mitigation: a flat, controlled ground under the copy
   column so the measured ratios are the ones that actually apply. It is not a decorative
   gradient, it is the reason the licence line stays readable when the filament flares. */
.hero::after{content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(90deg,var(--bg) 0%,var(--bg) 30%,rgba(20,22,26,.70) 52%,transparent 80%);
  transition:background 1.4s ease}
/* Above 880 the copy no longer overlaps the video at all, so the scrim stops being a legibility
   device and starts being a veil over the one photograph on the page. Keep only a short fade to
   join the two halves. */
@media(min-width:880px){
  .hero::after{background:linear-gradient(90deg,var(--bg) 0%,var(--bg) 34%,transparent 56%)}
}
.hero-inner{position:relative;z-index:1;max-width:var(--maxw);margin:0 auto;
  padding:calc(var(--sec) + 10px) var(--gut) var(--sec);
  display:grid;gap:clamp(24px,4vw,44px);grid-template-columns:1fr;align-items:center;
  min-height:clamp(520px,74svh,760px)}
@media(min-width:880px){.hero-copy{max-width:58%}}

.hero-logo{width:min(320px,74%);height:auto;display:block;margin:0 0 clamp(14px,2.4vw,22px)}
.hero-h1{font-size:clamp(64px,13vw,132px);line-height:.84;letter-spacing:-.035em;
  text-transform:none}
/* The tungsten glow on "on.". This is a filament warming and cooling, not a flicker: the
   original port replaced it with an opacity pulse, which reads as a fault rather than as heat.
   Two shadows because one is the close halo and one is the room it throws. Restored from the
   Lovable build's `tungsten` keyframe, converted from oklch to the amber this sheet already
   uses. (Dustin, 2026-09-04.) */
.hum{color:var(--glow);transition:color .9s ease}
html.lit .hum{animation:tungsten 4.5s ease-in-out infinite}
@keyframes tungsten{
  0%,100%{text-shadow:0 0 18px rgba(242,169,59,.40), 0 0 46px rgba(242,169,59,.16)}
  50%    {text-shadow:0 0 30px rgba(242,169,59,.66), 0 0 68px rgba(242,169,59,.26)}
}
/* Lights down: a cold filament throws nothing. */
html.dim .hum{animation:none;text-shadow:none}
.hero-h2{font-family:var(--body);font-weight:400;font-size:clamp(17px,2.1vw,20px);
  line-height:1.5;letter-spacing:0;color:var(--ink);max-width:34ch;
  margin:clamp(16px,2.4vw,24px) 0 0;text-transform:none}
.hero-sub{font-size:clamp(16px,1.9vw,18px);max-width:36ch;margin:.5em 0 0;color:var(--ink-mute)}
.hero-cta{display:flex;flex-wrap:wrap;gap:12px;margin-top:clamp(20px,3vw,30px)}

.btn{display:inline-flex;align-items:center;gap:10px;font-family:var(--disp);font-weight:600;
  font-size:22px;letter-spacing:.04em;padding:14px 24px;border-radius:2px;text-decoration:none;
  border:1.5px solid transparent}
.btn-call{background:var(--amber);color:var(--char);border-color:var(--amber);
  transition:background .9s ease,border-color .9s ease,transform .12s ease}
.btn-call:hover{transform:translateY(-2px)}
html.dim .btn-call{background:var(--amber-ember);border-color:var(--amber-ember)}
/* The secondary path is GREEN, the primary stays amber. Two calls to action in the same accent
   made them compete; in the badge's own green the text option reads as a real alternative to
   calling rather than a weaker version of it, and it ties the page to the logo. */
.btn-ghost{color:var(--ink-strong);border-color:var(--sage)}
.btn-ghost .ico{color:var(--sage)}
.btn-ghost:hover{background:var(--sage);color:var(--char)}
.btn-ghost:hover .ico{color:var(--char)}
.glow{animation:ember 4.6s ease-in-out infinite}
html.dim .glow{animation-duration:6.4s}
@keyframes ember{0%,100%{box-shadow:0 0 0 0 rgba(242,169,59,0)}
                 50%{box-shadow:0 0 24px 2px rgba(242,169,59,.30)}}

/* ---------------------------------------------------------------- circuit directory */
.panel{position:relative}
.panel::before{content:"";position:absolute;inset:0;pointer-events:none;opacity:.04;
  background-image:linear-gradient(var(--copper) 1px,transparent 1px),
                   linear-gradient(90deg,var(--copper) 1px,transparent 1px);
  background-size:74px 74px,74px 74px}
.panel-head{position:relative;display:flex;align-items:flex-end;justify-content:space-between;
  gap:20px;flex-wrap:wrap;margin-bottom:clamp(16px,2.4vw,24px)}
.panel-sub{margin:0 0 4px;color:var(--ink-mute);font-size:15px;font-family:var(--disp);
  letter-spacing:.14em;text-transform:uppercase;font-weight:600}
.panel-box{position:relative;border:1px solid var(--hair);border-radius:4px;
  background:var(--char-3);transition:background .9s ease}
.panel-bar{display:flex;justify-content:space-between;padding:11px 16px;
  border-bottom:1px solid var(--hair);font-family:var(--disp);font-weight:600;font-size:12px;
  letter-spacing:.3em;color:var(--copper)}
.brk-list{list-style:none;margin:0;padding:0}
.brk{border-bottom:1px solid var(--hair)}
.brk:last-child{border-bottom:0}
.brk-btn{width:100%;display:grid;grid-template-columns:34px 24px 1fr auto;align-items:center;
  gap:14px;background:none;border:0;padding:16px;cursor:pointer;text-align:left;
  font-family:inherit;border-left:3px solid transparent;transition:background .2s ease}
.brk-btn:hover{background:var(--char-2)}
.brk-label{font-family:var(--disp);font-weight:700;font-size:clamp(21px,2.7vw,27px);
  letter-spacing:-.01em;color:var(--ink-strong)}
.brk-amp{font-family:var(--disp);font-weight:600;font-size:13px;letter-spacing:.18em;
  color:var(--copper);transition:color .2s ease}
.brk-toggle{display:block;width:34px;height:20px;background:#0B0D10;border-radius:2px;
  border:1px solid var(--hair);position:relative}
.brk-nub{position:absolute;top:2px;left:2px;width:14px;height:14px;background:#8E887D;
  border-radius:1px;transition:transform .2s cubic-bezier(.34,1.3,.5,1),background .2s ease}
.brk-btn[aria-expanded="true"] .brk-nub{transform:translateX(14px);background:var(--amber)}
.brk-btn[aria-expanded="true"]{border-left-color:var(--amber);background:var(--char-2)}
.brk-btn[aria-expanded="true"] .brk-amp{color:var(--amber)}
.brk-ico{display:flex}
.brk-body{padding:0 16px 18px 90px;max-width:74ch}
.brk-body p{color:var(--ink);margin:0 0 14px}
.brk-call{display:inline-flex;gap:8px;align-items:center;font-family:var(--disp);font-weight:600;
  font-size:15px;letter-spacing:.14em;text-transform:uppercase;color:var(--amber);
  text-decoration:none;border:1px solid var(--amber);padding:9px 16px;border-radius:2px}
.brk-call:hover{background:var(--amber);color:var(--char)}
@media(max-width:600px){.brk-body{padding-left:16px}
  .brk-btn{grid-template-columns:34px 24px 1fr;gap:10px}
  .brk-amp{display:none}}

/* ---------------------------------------------------------------- what you get */
.why-sub{color:var(--ink);margin:.7em 0 0;max-width:62ch;font-size:clamp(16px,1.9vw,18px)}
.why-list{list-style:none;margin:clamp(22px,3vw,34px) 0 0;padding:0;display:grid;
  gap:clamp(18px,2.6vw,28px);grid-template-columns:1fr}
@media(min-width:620px){.why-list{grid-template-columns:repeat(2,1fr)}}
@media(min-width:980px){.why-list{grid-template-columns:repeat(4,1fr)}}
.why-pt{border-top:1px solid var(--hair);padding-top:16px;transition:border-color .9s ease}
.why-n{font-family:var(--disp);font-weight:600;font-size:13px;letter-spacing:.3em;
  color:var(--copper)}
.why-pt h3{margin:10px 0 8px;color:var(--ink-strong)}
.why-pt p{margin:0;color:var(--ink-mute);font-size:15.5px;line-height:1.6}

/* ---------------------------------------------------------------- who you get
   This sits where the founding-customer offer used to, which is the right slot: the page has
   just finished arguing that you get the owner, so this is the owner. Photo first on mobile,
   because the face is the argument and a paragraph is not.
   No max-width override on .bio itself: section already carries --maxw and narrowing it here
   would indent the heading away from every other section, which consistency.py fails on. */
/* Overlapping boxes rather than two columns side by side. The photograph sits in a frame that
   is offset from a sage outline behind it, and the copy card laps over the photo's inner edge,
   so the two read as one composed object instead of an image next to a paragraph.
   THE OVERLAP ONLY EXISTS ABOVE 900px. Below that everything is a plain stack: negative margins
   on a narrow screen do not read as art direction, they read as a bug, and the photo would be
   sitting under text at the exact width where most of this site's visitors are. */
.bio-grid{display:grid;gap:clamp(20px,4vw,36px);grid-template-columns:1fr;align-items:center}
.bio-shot{display:block;position:relative}
.bio-shot img{display:block;width:100%;height:auto;border-radius:3px;
  border:1px solid var(--hair);filter:saturate(.94) contrast(1.02);
  transition:border-color .9s ease}
.bio-eyebrow{font-family:var(--disp);font-weight:600;font-size:12px;letter-spacing:.34em;
  text-transform:uppercase;color:var(--sage);margin:0 0 12px}
.bio-copy h2{max-width:18ch}
.bio-lede{margin:16px 0 0;max-width:54ch;color:var(--ink-strong);
  font-size:clamp(16.5px,1.9vw,18.5px);line-height:1.5}
.bio-body{margin:13px 0 0;max-width:58ch;color:var(--ink);font-size:clamp(15px,1.75vw,16.5px)}
.bio-sign{margin:16px 0 0;font-family:var(--disp);font-weight:600;letter-spacing:.06em;
  text-transform:uppercase;font-size:13px;color:var(--ink-mute)}
.bio-sign::before{content:"";display:inline-block;width:26px;height:1px;background:var(--sage);
  vertical-align:middle;margin-right:10px}

@media(min-width:900px){
  .bio-grid{grid-template-columns:minmax(0,46fr) minmax(0,54fr);align-items:center;gap:0}
  /* the offset outline, drawn behind the photo and pulled out to the page edge side */
  .bio-shot::before{content:"";position:absolute;inset:0;
    transform:translate(-16px,16px);border:1px solid var(--sage);border-radius:3px;
    opacity:.55;pointer-events:none}
  .bio-shot img{position:relative;z-index:1}
  .bio-copy{position:relative;z-index:2;margin-left:-56px;
    background:var(--char-2);border:1px solid var(--hair);border-left:3px solid var(--sage);
    border-radius:3px;padding:clamp(26px,3vw,40px);
    box-shadow:0 18px 40px rgba(0,0,0,.38);transition:background .9s ease}
}
@media(min-width:1180px){
  .bio-copy{margin-left:-84px}
}

/* ---------------------------------------------------------------- service area */
.area-sub{color:var(--ink);margin:.7em 0 0;max-width:52ch}
.cities{list-style:none;margin:clamp(20px,2.8vw,30px) 0 16px;padding:0;display:grid;gap:8px;
  grid-template-columns:repeat(2,1fr)}
@media(min-width:620px){.cities{grid-template-columns:repeat(3,1fr)}}
@media(min-width:900px){.cities{grid-template-columns:repeat(4,1fr)}}
.cities li{font-family:var(--disp);font-weight:600;font-size:18px;letter-spacing:.04em;
  color:var(--ink-strong);border:1px solid var(--hair);border-radius:2px;padding:11px 14px;
  transition:border-color .2s ease}
.cities li:hover{border-color:var(--amber)}
.area-foot{color:var(--ink-mute);font-size:15.5px;max-width:52ch;margin:0}

/* ---------------------------------------------------------------- footer */
.foot{border-top:1px solid var(--hair);background:var(--char-2);transition:background .9s ease,border-color .9s ease}
.foot-inner{max-width:var(--maxw);margin:0 auto;padding:clamp(28px,4vw,44px) var(--gut)
  calc(clamp(28px,4vw,44px) + 70px);display:grid;gap:clamp(20px,3vw,32px);grid-template-columns:1fr}
@media(min-width:720px){.foot-inner{grid-template-columns:1fr auto;padding-bottom:clamp(28px,4vw,44px)}
  .foot-right{text-align:right}}
.foot-logo{width:200px;height:auto;display:block;margin:0 0 14px}
.foot p,.foot-addr{margin:0 0 .4em;font-size:15px;color:var(--ink-mute);font-style:normal;line-height:1.6}
.foot-lic{font-family:var(--disp);font-weight:600;font-size:14px;letter-spacing:.22em;
  color:var(--copper)}
.foot-tel{display:inline-flex;gap:8px;align-items:center;color:var(--glow);font-weight:600;
  text-decoration:none}
.foot-hours{margin-top:14px;font-size:14px}
.foot-emergency{font-size:14px;color:var(--ink)}

/* ---------------------------------------------------------------- Narrows credit
   The standard backlink on every site we build: strategy/Brand-Footer-Credit.md. The markup is the
   vendored brand/narrows-credit.html, never retyped. Colours are the standard's DARK-ground set,
   re-measured on THIS footer because the standard measured navy, not --char-2: lockup #CFD8E4 at
   11.6:1 lit and 12.9:1 dim; WEB #E8579B at 4.98 and 5.55, where the brand magenta would fail as
   11px text at 3.51; the mark's magenta stroke is non-text and clears 3:1 at 3.51. This site loads
   no mono face, so the lockup uses the system mono stack rather than fetching one.
   Selectors start from footer on purpose: the standard records a pass lost on greatcopiers when a
   more specific `footer a` rule blockified the flex anchor and killed align-items. */
.foot-credit{grid-column:1/-1;border-top:1px solid var(--hair);padding-top:14px}
footer .foot-credit a.nwc{display:inline-flex;align-items:center;gap:9px;color:#CFD8E4;
  text-decoration:none;padding:4px 0}
footer .foot-credit a.nwc svg{width:26px;height:auto;flex:none}
footer .foot-credit a.nwc .lo{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,"Liberation Mono",monospace;
  font-size:11px;letter-spacing:.06em;text-transform:none}
footer .foot-credit a.nwc .lo b{color:#E8579B;font-weight:700}
footer .foot-credit a.nwc:hover{color:#FFFFFF}

/* ---------------------------------------------------------------- sticky call bar
   Mobile is the real site. The no-power button is the only safety orange on the page and it
   exists only because client.json says after-hours calls get answered. */
/* The bar adapts to how many cells the page actually puts in it, and that is not cosmetic.
   `grid-template-columns:1fr 1fr` was hardcoded for the HOME page, which has two cells: the call
   link and the after-hours line. Every service-area page and the 404 page has ONE, so on all
   fifteen the tap target sat in the left half and the right half was an empty translucent strip
   over the page content, with the phone number wrapping onto two lines inside it. Measured on the
   deployed preview 2026-09-07 at 375px: bar 375px, link 187px. Mobile is the real site and this
   is the primary call to action on it. `grid-auto-flow:column` with `grid-auto-columns:1fr` sizes
   to the children instead of asserting how many there will be. */
.callbar{position:fixed;left:0;right:0;bottom:0;z-index:50;display:grid;
  grid-auto-flow:column;grid-auto-columns:minmax(max-content,1fr);gap:1px;
  background:rgba(0,0,0,.35);border-top:1px solid rgba(0,0,0,.3)}
/* Equal halves also wrapped the phone number on the home page, on every common phone and not
   only the narrow ones: the call cell needs 207px of single line and "Text a photo" needs 134,
   while 1fr each gives 187 at 375px, 196 at 393 and 215 at 430. So the number broke onto a
   second line and the bar stood 99px tall on an iPhone 15 as much as on an SE. minmax lets the
   call cell take the room it needs and 1fr still spreads what is left, which is the actual
   intent: two cells of EQUAL IMPORTANCE, not of equal width. Below 360px the content genuinely
   does not fit, and there wrapping is correct and a horizontal scrollbar is not. */
@media(max-width:359px){.callbar{grid-auto-columns:minmax(0,1fr)}}
.callbar-link{display:flex;align-items:center;justify-content:center;gap:10px;padding:15px 12px;
  background:var(--amber);color:var(--char);text-decoration:none;font-family:var(--disp);
  font-weight:600;font-size:17px;letter-spacing:.06em;transition:background .9s ease}
html.dim .callbar-link{background:var(--amber-ember)}
.callbar-link strong{font-family:var(--disp);font-weight:700;font-size:19px}
.callbar-text{display:flex;align-items:center;justify-content:center;gap:8px;padding:15px 12px;
  background:var(--char-2);color:var(--ink-strong);text-decoration:none;font-family:var(--disp);
  font-weight:600;font-size:16px;letter-spacing:.05em;text-align:center;
  box-shadow:inset 0 2px 0 var(--sage);
  transition:background .9s ease}
.callbar-text .ico{color:var(--sage)}
.callbar .is-tbd{display:flex;align-items:center;justify-content:center;gap:9px;padding:15px 12px;
  background:var(--char-2);color:var(--ink-strong);font-weight:600}
.callbar .tbd{background:var(--char);color:var(--amber)}
@media(min-width:720px){.callbar{display:none}}

@media(prefers-reduced-motion:reduce){
  *,*::before,*::after{transition-duration:.01ms!important;animation-duration:.01ms!important;
    animation-iteration-count:1!important}
  .hero-video{display:none}
  /* Hold the glow at its warm resting state rather than at whatever frame the animation
     stopped on. Someone who asked for less motion should still get the design. */
  .hum{text-shadow:0 0 18px rgba(242,169,59,.40), 0 0 46px rgba(242,169,59,.16)}
}

/* No JS: every breaker body is in the DOM behind [hidden]. Show them all rather than shipping a
   services section that cannot be opened. This is the same instinct as the lights defaulting on. */
.foot-legal{margin-top:10px;font-size:13.5px;color:var(--ink-mute)}

/* ---------------------------------------------------------------- service area pages
   Deliberately quieter than the home page. These are answer pages: someone has searched a town
   plus "electrician" and wants to know he covers it and who inspects the work. No video, no
   breaker panel, no offer block. The unique material sits at the top where it is read. */
body.city{background:var(--bg)}
.city-top{display:flex;align-items:center;justify-content:space-between;gap:16px;flex-wrap:wrap;
  max-width:var(--maxw);margin:0 auto;padding:18px var(--gut);border-bottom:1px solid var(--hair)}
.city-home{display:block;line-height:0}
.city-home img{width:150px;height:auto}
.city-call{display:inline-flex;align-items:center;gap:9px;background:var(--amber);color:var(--char);
  text-decoration:none;font-family:var(--disp);font-weight:600;font-size:18px;letter-spacing:.04em;
  padding:11px 18px;border-radius:2px}
.city-main{max-width:var(--maxw);margin:0 auto;padding:var(--sec) var(--gut) calc(var(--sec) + 70px)}
@media(min-width:720px){.city-main{padding-bottom:var(--sec)}}
.crumbs{font-family:var(--disp);font-weight:600;font-size:14px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--ink-mute);margin-bottom:clamp(14px,2vw,20px)}
.crumbs a{color:var(--copper);text-decoration:none}
.crumbs a:hover{color:var(--amber)}
.city-main h1{font-size:clamp(38px,6.4vw,68px);line-height:.92;letter-spacing:-.03em;
  text-wrap:balance;margin:0 0 .35em}
.city-lead{font-size:clamp(17px,2.1vw,20px);line-height:1.55;color:var(--ink);max-width:60ch;
  margin:0 0 clamp(26px,4vw,40px)}
.city-main section{padding:clamp(22px,3vw,30px) 0;border-top:1px solid var(--hair)}
.city-main h2{font-size:clamp(24px,3vw,32px);margin:0 0 .5em;letter-spacing:-.01em}
.city-main section p{max-width:64ch;color:var(--ink)}
.city-permit{border-left:3px solid var(--copper);padding-left:clamp(16px,2.4vw,24px)!important}
.city-auth{font-weight:600}
.city-authphone{font-family:var(--disp);font-size:16px;letter-spacing:.06em;color:var(--ink-mute)}
.city-svclist{list-style:none;margin:0 0 14px;padding:0;display:grid;gap:8px;
  grid-template-columns:1fr}
@media(min-width:560px){.city-svclist{grid-template-columns:repeat(2,1fr)}}
@media(min-width:900px){.city-svclist{grid-template-columns:repeat(3,1fr)}}
.city-svclist li{font-family:var(--disp);font-weight:600;font-size:18px;letter-spacing:.03em;
  color:var(--ink-strong);border:1px solid var(--hair);border-radius:2px;padding:11px 14px}
.city-cta .btn{margin-top:10px}
.city-otherlist{list-style:none;margin:0;padding:0;display:grid;gap:8px;
  grid-template-columns:repeat(2,1fr)}
@media(min-width:700px){.city-otherlist{grid-template-columns:repeat(3,1fr)}}
.city-otherlist a{display:block;font-family:var(--disp);font-weight:600;font-size:17px;
  letter-spacing:.03em;color:var(--ink-strong);text-decoration:none;border:1px solid var(--hair);
  border-radius:2px;padding:10px 13px;transition:border-color .2s ease}
.city-otherlist a:hover{border-color:var(--amber);color:var(--amber)}
