/* my.allsolarenergy.com
 *
 * Brand taken from allsolarenergy.com's own Elementor global kit, not guessed:
 *   accent #F1592A · dark #262A2B · text #58585A · headings Monda · body Inter
 *
 * Fonts are SELF-HOSTED, latin subset only, 70KB for both. This gets opened on
 * a phone outdoors on bad signal, so a blocking call to a font CDN is the wrong
 * trade. It is ALSO opened on a desktop, so the layout goes properly wide
 * instead of staying a phone column — one grid, three breakpoints.
 */

@font-face{font-family:'Monda';src:url('/fonts/monda.woff2?v=20260801m') format('woff2');
  font-weight:400 700;font-display:swap;font-style:normal}
@font-face{font-family:'InterVar';src:url('/fonts/inter.woff2?v=20260801m') format('woff2');
  font-weight:100 900;font-display:swap;font-style:normal}

:root{
  --orange:#F1592A; --orange-dark:#C7411A; --orange-soft:#FEF0EA;
  --ink:#000000; --dark:#262A2B; --text:#58585A; --muted:#7E8285;
  --rule:#E4E5E7; --sand:#F4F5F6; --paper:#FFFFFF; --page:#FAFAFB;
  --leaf:#1F7A4C; --leaf-soft:#E8F4EE;
  --disp:'Monda','Segoe UI',system-ui,sans-serif;
  --body:'InterVar',-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;
  --shell:1180px;   /* full page width on a desktop — the MARKETING page only */
  --shell-app:1080px; /* the signed-in dashboard. Narrowing this to 760px (an
    earlier pass) was the wrong fix for the wasted-space complaint — on a wide
    monitor a narrow centered column just moves the empty space from inside
    the cards to outside them. The real fix is the equipment TILE GRID below:
    it's wide because auto-fill actually uses that width, adding columns
    instead of stretching gaps. */
  --measure:64ch;   /* prose never exceeds this, however wide the shell */
}
@media (prefers-color-scheme:dark){
  :root{--orange:#FF6B3D;--orange-dark:#FF8A61;--orange-soft:#2B1810;
    --ink:#F2F3F4;--dark:#F2F3F4;--text:#B6BABD;--muted:#8A9095;--rule:#2C3133;
    --sand:#1B1F21;--paper:#15191B;--page:#0E1112;--leaf:#5FBF8F;--leaf-soft:#0F2419}
}
:root[data-theme="dark"]{--orange:#FF6B3D;--orange-dark:#FF8A61;--orange-soft:#2B1810;
  --ink:#F2F3F4;--dark:#F2F3F4;--text:#B6BABD;--muted:#8A9095;--rule:#2C3133;
  --sand:#1B1F21;--paper:#15191B;--page:#0E1112;--leaf:#5FBF8F;--leaf-soft:#0F2419}
:root[data-theme="light"]{--orange:#F1592A;--orange-dark:#C7411A;--orange-soft:#FEF0EA;
  --ink:#000000;--dark:#262A2B;--text:#58585A;--muted:#7E8285;--rule:#E4E5E7;
  --sand:#F4F5F6;--paper:#FFFFFF;--page:#FAFAFB;--leaf:#1F7A4C;--leaf-soft:#E8F4EE}

*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth}
body{margin:0;background:var(--page);color:var(--text);font-family:var(--body);
  font-size:17px;font-weight:300;line-height:1.65;-webkit-font-smoothing:antialiased}

h1,h2,h3,h4{font-family:var(--disp);color:var(--dark);margin:0;line-height:1.16;text-wrap:balance}
h1{font-size:clamp(31px,4.6vw,52px);font-weight:700;letter-spacing:-.018em}
h2{font-size:clamp(24px,2.8vw,34px);font-weight:600;letter-spacing:-.01em}
h3{font-size:clamp(18px,1.5vw,21px);font-weight:600}
p{margin:0;max-width:var(--measure)}
strong{font-weight:600;color:var(--dark)}
a{color:var(--orange-dark);text-underline-offset:2px}
a:focus-visible,button:focus-visible,input:focus-visible,summary:focus-visible{
  outline:3px solid var(--orange);outline-offset:2px}

.wrap{max-width:var(--shell);margin:0 auto;padding:0 24px}
/* Element+class beats a bare class regardless of source order, so this always
   wins over .wrap on the one element it's meant to narrow: <main> on the
   signed-in dashboard (app.html). The header stays the wide marketing shell
   on that page too — only the account content itself needs to be narrow. */
main.wrap-app{max-width:var(--shell-app)}
.stack{display:flex;flex-direction:column;gap:16px}
.stack-lg{display:flex;flex-direction:column;gap:clamp(38px,5vw,64px)}
/* The greeting ("Hello, Ed") sits directly above the first card with nothing
 * else in between, so it doesn't need the same big section-break gap every
 * other direct child of #root gets — pulled in to a normal .stack rhythm. */
.hero-head{margin-bottom:clamp(-46px,-4.2vw,-20px)}

/* ── Header ─────────────────────────────────────────────────────────────── */
.top{background:var(--paper);border-bottom:1px solid var(--rule);
  padding:14px 0;position:sticky;top:0;z-index:20}
.top .wrap{display:flex;align-items:center;justify-content:space-between;gap:16px}
.logo{display:block;height:46px;width:auto}
.top nav{display:flex;align-items:center;gap:22px}
.top nav a{font-family:var(--disp);font-weight:600;font-size:15px;
  color:var(--dark);text-decoration:none}
.top nav a:hover{color:var(--orange-dark)}
.top .tel{white-space:nowrap}
@media(max-width:640px){ .top nav .hide-sm{display:none} .logo{height:38px} }

/* ── Hero: two columns on desktop, stacked on phone ─────────────────────── */
.hero{padding:clamp(34px,5vw,64px) 0 0}
.hero-grid{display:grid;gap:clamp(28px,3.5vw,52px);align-items:start}
@media(min-width:900px){
  .hero-grid{grid-template-columns:minmax(0,1.15fr) minmax(380px,.85fr)}
  .signin-col{position:sticky;top:88px}
}
.kicker{display:inline-block;align-self:flex-start;font-family:var(--disp);
  font-size:12px;font-weight:700;letter-spacing:.12em;text-transform:uppercase;
  color:var(--orange-dark);background:var(--orange-soft);padding:6px 12px}
.lede{font-size:clamp(17px,1.35vw,20px);color:var(--text)}

/* Trust bar — canonical figures, identical across every AllSolar property */
.trust{display:grid;grid-template-columns:repeat(2,1fr);gap:1px;
  background:var(--rule);border:1px solid var(--rule);margin-top:6px}
@media(min-width:560px){.trust{grid-template-columns:repeat(4,1fr)}}
.trust div{background:var(--paper);padding:15px 16px}
.trust b{display:block;font-family:var(--disp);font-size:clamp(21px,2vw,27px);
  font-weight:700;color:var(--dark);line-height:1.2}
.trust span{font-size:13.5px;color:var(--muted)}

/* ── Cards & grids ──────────────────────────────────────────────────────── */
.card{background:var(--paper);border:1px solid var(--rule);
  padding:clamp(22px,2.4vw,32px);box-shadow:0 1px 2px rgba(38,42,43,.05)}
.card-accent{border-top:3px solid var(--orange)}

.grid-3{display:grid;gap:18px;grid-template-columns:1fr}
@media(min-width:720px){.grid-3{grid-template-columns:repeat(2,1fr)}}
@media(min-width:1000px){.grid-3{grid-template-columns:repeat(3,1fr)}}

.grid-2{display:grid;gap:18px;grid-template-columns:1fr}
@media(min-width:760px){.grid-2{grid-template-columns:repeat(2,1fr)}}

.who .one{background:var(--paper);border:1px solid var(--rule);
  border-top:3px solid var(--orange);padding:22px 24px;height:100%;
  display:flex;flex-direction:column;gap:9px}
.who .one p{font-size:15.5px;max-width:none}
.tagline{font-family:var(--disp);font-size:11.5px;font-weight:700;
  letter-spacing:.11em;text-transform:uppercase;color:var(--orange-dark)}

.steps{counter-reset:s;display:grid;gap:20px;margin:0;padding:0;list-style:none;
  grid-template-columns:1fr}
@media(min-width:820px){.steps{grid-template-columns:repeat(3,1fr)}}
.steps li{counter-increment:s;display:flex;flex-direction:column;gap:9px}
.steps li::before{content:counter(s);width:38px;height:38px;border-radius:50%;
  background:var(--orange);color:#fff;display:grid;place-items:center;
  font-family:var(--disp);font-weight:700;font-size:17px}
.steps strong{display:block;color:var(--dark)}
.steps span{font-size:15.5px}

.perks{list-style:none;margin:0;padding:0;display:grid;gap:18px;grid-template-columns:1fr}
@media(min-width:760px){.perks{grid-template-columns:repeat(2,1fr)}}
.perks li{display:grid;grid-template-columns:24px 1fr;gap:13px;align-items:start}
.perks .tick{width:21px;height:21px;border-radius:50%;margin-top:3px;
  background:var(--orange-soft);color:var(--orange-dark);
  display:grid;place-items:center;font-size:12px;font-weight:700}
.perks strong{display:block;color:var(--dark)}
.perks span{font-size:15.5px}
.perks li > span{max-width:46ch}

/* ── Forms ──────────────────────────────────────────────────────────────── */
label{display:block;font-family:var(--disp);font-weight:600;margin-bottom:7px;
  font-size:15px;color:var(--dark)}
input[type=email],input[type=text],input[type=tel],input[type=password]{width:100%;min-height:54px;
  padding:13px 15px;font-size:17px;font-family:var(--body);font-weight:400;
  color:var(--dark);background:var(--paper);border:2px solid var(--rule);border-radius:2px}
input:focus{border-color:var(--orange)}
.code-input{font-size:30px;letter-spacing:10px;text-align:center;
  font-variant-numeric:tabular-nums;font-weight:600}
.btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;width:100%;
  min-height:56px;padding:15px 24px;font-family:var(--disp);font-size:17px;font-weight:700;
  color:#fff;background:var(--orange);border:none;border-radius:2px;cursor:pointer;
  transition:background .12s ease;text-decoration:none}
.btn:hover{background:var(--orange-dark)}
.btn:disabled{opacity:.55;cursor:default}
.btn-quiet{background:transparent;color:var(--dark);border:2px solid var(--rule);font-weight:600}
.btn-quiet:hover{background:var(--sand)}
.btn-inline{width:auto;min-height:50px;padding:12px 30px}
.hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden;opacity:0}

/* ── Notes ──────────────────────────────────────────────────────────────── */
.note{padding:15px 17px;border-left:3px solid var(--rule);background:var(--sand);font-size:15.5px}
.note-ok{background:var(--leaf-soft);border-left-color:var(--leaf)}
.note-warn{background:var(--orange-soft);border-left-color:var(--orange)}
.note-bad{background:#FDEBE9;border-left-color:#B3261E;color:#8A1F19}
@media (prefers-color-scheme:dark){.note-bad{background:#2A1513;color:#F0776B}}
.muted{color:var(--muted);font-size:15px}

/* Same red as .note-bad — one emergency palette across the whole app rather
   than a second one invented just for this card. */
.help-urgent{border-color:#B3261E;background:#FDEBE9}
.help-urgent h2,.help-urgent .btn{background-color:transparent}
.help-urgent h2{color:#8A1F19}
.help-urgent .btn{background:#B3261E}
.help-urgent .btn:hover{background:#8A1F19}
@media (prefers-color-scheme:dark){
  .help-urgent{border-color:#7A2A22;background:#2A1513}
  .help-urgent h2{color:#F0776B}
}
:root[data-theme="dark"] .help-urgent{border-color:#7A2A22;background:#2A1513}
:root[data-theme="dark"] .help-urgent h2{color:#F0776B}

/* ── Live status pills (appointments) ────────────────────────────────────
 * One family, one meaning each. Only these buckets ever reach the browser —
 * see server/lib/portal-status.js on the SPX side, which maps every internal
 * status by hand so nothing office-facing (like "Dead Run") lands here. */
.pill{display:inline-flex;align-items:center;gap:6px;font-family:var(--disp);
  font-size:13px;font-weight:700;padding:5px 12px;border-radius:20px;line-height:1.3;
  white-space:nowrap}
.pill::before{content:'';width:7px;height:7px;border-radius:50%;flex:none}
.pill-booked{background:var(--sand);color:var(--dark)}
.pill-booked::before{background:var(--muted)}
.pill-pending,.pill-waiting{background:var(--orange-soft);color:var(--orange-dark)}
.pill-pending::before,.pill-waiting::before{background:var(--orange)}
.pill-hold{background:#FDEBE9;color:#8A1F19}
.pill-hold::before{background:#B3261E}
@media (prefers-color-scheme:dark){.pill-hold{background:#2A1513;color:#F0776B}}
.pill-active,.pill-on-way,.pill-on-site{background:var(--leaf-soft);color:var(--leaf)}
.pill-active::before,.pill-on-way::before,.pill-on-site::before{background:var(--leaf)}
.pill-done,.pill-cancelled{background:var(--sand);color:var(--muted)}
.pill-done::before,.pill-cancelled::before{background:var(--muted)}
/* Production status (lib/production-status.js on the SPX side) — separate
   states from the appointment set above even though a couple visually
   overlap, because the two vocabularies mean different things and must stay
   free to diverge. */
.pill-ok{background:var(--leaf-soft);color:var(--leaf)}
.pill-ok::before{background:var(--leaf)}
.pill-info{background:var(--sand);color:var(--dark)}
.pill-info::before{background:var(--muted)}
.pill-attention{background:var(--orange-soft);color:var(--orange-dark)}
.pill-attention::before{background:var(--orange)}
@media (prefers-reduced-motion:no-preference){
  .pill-on-way::before{animation:pill-pulse 1.6s ease-in-out infinite}
}
@keyframes pill-pulse{0%,100%{opacity:1}50%{opacity:.35}}

/* ── Live production ──────────────────────────────────────────────────────
 * Numbers shown directly, not just a link out — a customer should never have
 * to leave the portal to see whether their system is producing right now.
 * .prod-live is the ONE glow moment on the whole page (Ed 2026-08-01: "should
 * look exciting and amazing") — spent here and nowhere else, so it still
 * means something when it shows up. Everything else on the page stays calm. */
.prod{border-top:1px solid var(--rule);padding:14px 0 16px;display:flex;
  flex-direction:column;gap:10px;margin-bottom:2px}
/* Elevated hero treatment (Ed 2026-08-02: wants the portal's live-production
 * moment to look like a real app, not a webpage — deeper gradient, a visible
 * glowing edge, more air around the numbers). Still the ONE glow spent on the
 * whole page; every value inside remains a real field, nothing decorative. */
.prod-live{border:none;border-radius:14px;padding:26px 28px;margin:2px 0 6px;
  background:linear-gradient(155deg,var(--paper) 0%,var(--orange-soft) 145%);
  box-shadow:0 0 0 1px rgba(241,89,42,.28),0 16px 40px -16px rgba(241,89,42,.45),
    inset 0 1px 0 rgba(255,255,255,.05)}
.prod-row{display:flex;flex-wrap:wrap;align-items:center;gap:32px}
.prod-stats{display:flex;flex-wrap:wrap;gap:28px}
.prod-stat{display:flex;flex-direction:column;gap:2px}
.prod-num{font-family:var(--disp);font-size:28px;font-weight:700;color:var(--dark);
  font-variant-numeric:tabular-nums;line-height:1.15}
.prod-label{font-size:12px;color:var(--muted);text-transform:uppercase;letter-spacing:.07em}

/* Half-circle arc: current output against the system's own nameplate size
 * (real fields, current_power_w over system_size) — never a fabricated max. */
.gauge{display:flex;flex-direction:column;align-items:center;min-width:150px}
.gauge-svg{width:152px;height:auto;overflow:visible}
.gauge-track{fill:none;stroke:var(--rule);stroke-width:10;stroke-linecap:round}
.gauge-fill{fill:none;stroke:url(#gaugeGradient);stroke-width:10;stroke-linecap:round;
  filter:drop-shadow(0 0 8px rgba(241,89,42,.65));transition:stroke-dasharray .5s ease}
.gauge-value{font-family:var(--disp);font-size:29px;font-weight:700;color:var(--dark);
  margin-top:-34px;font-variant-numeric:tabular-nums}
.gauge-label{font-size:12px;color:var(--muted);margin-top:2px}

/* ── Weather badge ─────────────────────────────────────────────────────────
 * Real conditions at the property's own zip (client-side, keyless APIs).
 * Empty span until it resolves, or forever if either call fails — decorative
 * context only, never worth a loading state or an error message. */
.card-head-row{display:flex;align-items:center;justify-content:space-between;gap:10px}
.weather-badge{font-family:var(--disp);font-size:12px;font-weight:600;color:var(--text);
  background:var(--sand);border:1px solid var(--rule);padding:5px 12px 5px 10px;
  border-radius:20px;display:inline-flex;align-items:center;gap:6px}

/* ── Equipment tile icons ─────────────────────────────────────────────────
 * A soft colour chip behind each glyph, not a bare stroke on white — the
 * "professional depth" the flat version was missing. Still monochrome-orange
 * on hover/open, same meaning as before, just given somewhere to sit. */
.tile-icon{width:34px;height:34px;flex:none;color:var(--muted);border-radius:9px;
  background:var(--sand);display:flex;align-items:center;justify-content:center;
  transition:background .15s,color .15s}
.tile-icon svg{width:18px;height:18px;display:block}
details.tile[open] .tile-icon,.tile:hover .tile-icon{color:var(--orange);background:var(--orange-soft)}

/* ── Appointment rows ─────────────────────────────────────────────────────
 * One row per visit inside the appointments card, not one card each — a
 * customer with three visits this week should see one list, not a wall. */
.appt{border-top:1px solid var(--rule);padding:16px 0;display:flex;flex-direction:column;gap:6px}
.appt:first-child{border-top:none;padding-top:0}
.appt-head{display:flex;align-items:center;justify-content:space-between;gap:10px;flex-wrap:wrap}
.appt-head h3{font-size:17px}
.appt .when{font-size:14.5px;color:var(--text)}
.appt .who{font-size:14px;color:var(--muted)}

/* ── Equipment tiles ───────────────────────────────────────────────────────
 * Rebuilt 2026-08-01 — Ed: "wasted space on the side, you should use dynamic
 * and/or folding cards." Native <details>/<summary> per field: closed shows
 * the value as a confident stat, click anywhere on it to fold open the edit
 * control. auto-fill means a wide screen gets MORE tiles per row, not bigger
 * gaps — this is what actually uses the space a fixed 2-column layout wasted.
 */
.tiles{display:grid;gap:14px;grid-template-columns:repeat(auto-fill,minmax(210px,1fr))}

.tile{background:var(--paper);border:1px solid var(--rule);border-radius:6px;
  transition:border-color .15s,box-shadow .15s}
.tile:hover{border-color:var(--orange)}
.tile[open]{border-color:var(--orange);box-shadow:0 0 0 1px var(--orange)}
.tile summary{list-style:none;cursor:pointer;padding:16px 18px;display:flex;
  flex-direction:column;gap:6px;-webkit-tap-highlight-color:transparent}
.tile summary::-webkit-details-marker{display:none}
/* icon + label grouped on the left (gap), chevron pinned right (margin-left:
   auto) — NOT space-between on all three, which would strand the label
   drifting in the middle of the row instead of next to its icon. */
.tile-top{display:flex;align-items:center;gap:8px}
.tile-label{font-family:var(--disp);font-size:11px;font-weight:700;letter-spacing:.08em;
  text-transform:uppercase;color:var(--muted)}
.tile-chevron{color:var(--muted);font-size:14px;line-height:1;transition:transform .18s ease;
  flex:none;margin-left:auto}
.tile[open] .tile-chevron{transform:rotate(90deg);color:var(--orange)}
.tile-value{font-family:var(--disp);font-size:19px;font-weight:700;color:var(--dark);
  line-height:1.3;word-break:break-word}
.tile-value.is-blank{color:var(--muted);font-weight:400;font-style:italic;font-size:15px}
.tile-value.is-link{font-size:14px;font-weight:600;color:var(--orange-dark);
  text-decoration:underline;word-break:break-all}
.tile-pending{font-family:var(--body);font-size:13px;color:var(--orange-dark);
  background:var(--orange-soft);padding:6px 10px;border-radius:3px}
/* Same look, no <details>/<summary> — a proposal already pending has nothing
   left to fold open, so this is a plain non-interactive card. */
.tile-static{padding:16px 18px;display:flex;flex-direction:column;gap:6px}

.tile-edit{padding:0 18px 16px;display:flex;flex-direction:column;gap:8px}
.tile-edit input{min-height:44px;padding:9px 12px;font-size:15px;font-family:var(--body);
  color:var(--dark);background:var(--sand);border:2px solid var(--rule);border-radius:2px}
.tile-edit input:focus{border-color:var(--orange)}
.tile-edit .row{display:flex;gap:8px}
.tile-help{font-size:12.5px;color:var(--muted);margin:0}
.btn-sm{width:auto;min-height:44px;padding:9px 16px;font-size:14px}

/* ── Dashboard structure ──────────────────────────────────────────────────
 * Rebuilt 2026-08-01 so the account reads as sections with a clear job each,
 * not one undifferentiated scroll: a hero for "what's happening", a two-column
 * "about your property" spread, then Account and Help set apart below a rule.
 */
.hero-appt{background:var(--paper);border:1px solid var(--rule);border-left:4px solid var(--orange);
  padding:20px 22px;display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;
  gap:12px 20px}
.hero-appt.is-live{border-left-color:var(--leaf)}
.hero-appt .what{display:flex;flex-direction:column;gap:5px;min-width:220px}
.hero-appt .what h2{font-size:clamp(19px,2vw,23px)}
.hero-appt .meta{font-size:14.5px;color:var(--text)}
.hero-appt .more{font-size:13.5px;color:var(--muted);width:100%}
.hero-quiet{padding:6px 2px;font-size:15px;color:var(--muted)}

.section{display:flex;flex-direction:column;gap:16px}
.section-label{font-family:var(--disp);font-size:12px;font-weight:700;letter-spacing:.11em;
  text-transform:uppercase;color:var(--muted)}
.divider{border:none;border-top:1px solid var(--rule);margin:0}

.eyebrow{font-family:var(--disp);font-size:12px;font-weight:700;letter-spacing:.11em;
  text-transform:uppercase;color:var(--muted)}

.faq{border:1px solid var(--rule);background:var(--paper)}
.faq details{border-top:1px solid var(--rule)}
.faq details:first-child{border-top:none}
.faq summary{padding:17px 20px;cursor:pointer;font-family:var(--disp);font-weight:600;
  color:var(--dark);font-size:16px;list-style:none;display:flex;
  justify-content:space-between;gap:16px;align-items:center}
.faq summary::-webkit-details-marker{display:none}
.faq summary::after{content:'+';color:var(--orange);font-weight:700;font-size:20px;flex:none}
.faq details[open] summary::after{content:'\2212'}
.faq .a{padding:0 20px 18px;font-size:15.5px}

.cta-band{background:var(--paper);border:1px solid var(--rule);border-top:3px solid var(--orange);
  padding:clamp(26px,3vw,40px);display:flex;flex-wrap:wrap;gap:20px;
  align-items:center;justify-content:space-between}
.cta-band .t{display:flex;flex-direction:column;gap:5px}

footer{background:var(--paper);border-top:1px solid var(--rule);
  padding:34px 0 48px;margin-top:clamp(40px,5vw,68px);font-size:14.5px;color:var(--muted)}
footer .cols{display:grid;gap:20px;grid-template-columns:1fr}
@media(min-width:700px){footer .cols{grid-template-columns:repeat(3,1fr)}}
footer strong{color:var(--dark)}
footer a{color:var(--muted)}

.hide{display:none!important}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important;scroll-behavior:auto}}

/* ── Audience architecture ──────────────────────────────────────────────────
 * Four primary paths + six situational ones.
 *
 * The chooser below FILTERS, it never fetches. Every card is real HTML present
 * on first paint with a descriptive heading, so a crawler (and anyone with JS
 * off, and a screen reader) gets the full set. Selecting a path only dims the
 * others — nothing is hidden from search behind an interaction.
 */
.chooser{background:var(--paper);border:1px solid var(--rule);
  border-top:3px solid var(--orange);padding:20px 22px;
  display:flex;flex-direction:column;gap:14px}
.chooser h2{font-size:clamp(19px,2vw,23px)}
.chips{display:flex;flex-wrap:wrap;gap:9px}
.chip{font-family:var(--disp);font-size:14.5px;font-weight:600;
  padding:11px 17px;min-height:46px;display:inline-flex;align-items:center;
  background:var(--sand);color:var(--dark);border:2px solid transparent;
  border-radius:2px;cursor:pointer;transition:background .12s,border-color .12s}
.chip:hover{background:var(--orange-soft)}
.chip[aria-pressed="true"]{background:var(--orange);color:#fff;border-color:var(--orange)}
.chip-reset{background:transparent;border:2px solid var(--rule);color:var(--muted)}

/* Dimmed, not hidden: the card stays in the DOM, in the a11y tree, and in view. */
.path.is-muted{opacity:.42;filter:saturate(.45)}
.path.is-match{box-shadow:0 0 0 2px var(--orange)}

.grid-4{display:grid;gap:18px;grid-template-columns:1fr}
@media(min-width:660px){.grid-4{grid-template-columns:repeat(2,1fr)}}
@media(min-width:1060px){.grid-4{grid-template-columns:repeat(4,1fr)}}

.path{background:var(--paper);border:1px solid var(--rule);border-top:3px solid var(--orange);
  padding:22px 22px 24px;height:100%;display:flex;flex-direction:column;gap:10px;
  transition:opacity .15s,box-shadow .15s,filter .15s}
.path h3{font-size:18px;line-height:1.25}
.path .sub{font-family:var(--disp);font-size:12px;font-weight:700;letter-spacing:.09em;
  text-transform:uppercase;color:var(--orange-dark)}
.path p{font-size:15px;max-width:none;flex:1}
.path .go{margin-top:4px;display:inline-flex;align-items:center;justify-content:center;
  min-height:48px;padding:12px 16px;font-family:var(--disp);font-weight:700;font-size:15px;
  color:#fff;background:var(--orange);text-decoration:none;border-radius:2px;text-align:center}
.path .go:hover{background:var(--orange-dark)}

/* Second row: situational entry points. Lighter treatment on purpose — these
   are supporting paths, not the four primary ones. */
.situations{display:grid;gap:1px;background:var(--rule);border:1px solid var(--rule);
  grid-template-columns:1fr}
@media(min-width:640px){.situations{grid-template-columns:repeat(2,1fr)}}
@media(min-width:980px){.situations{grid-template-columns:repeat(3,1fr)}}
.sit{background:var(--paper);padding:19px 21px;display:flex;flex-direction:column;gap:7px}
.sit h3{font-size:16.5px}
.sit p{font-size:14.5px;max-width:none}
.sit a{font-family:var(--disp);font-weight:600;font-size:14.5px;text-decoration:none}
.sit a:hover{text-decoration:underline}

/* ── Family footer ──────────────────────────────────────────────────────────
 * Grouped by audience rather than dumped as one list. A homeowner looking for
 * help with a dead inverter should not have to scan past B2B permit software
 * to find Solar Rescue.
 */
.famgrid{display:grid;gap:26px;grid-template-columns:1fr;margin-top:6px}
@media(min-width:720px){.famgrid{grid-template-columns:repeat(2,1fr)}}
.famgrid h4{font-family:var(--disp);font-size:12px;font-weight:700;letter-spacing:.11em;
  text-transform:uppercase;color:var(--muted);margin:0 0 11px}
.famlist{list-style:none;margin:0;padding:0;display:grid;gap:9px;grid-template-columns:1fr}
@media(min-width:460px){.famlist{grid-template-columns:repeat(2,1fr)}}
.famlist a{display:block;color:var(--text);text-decoration:none;font-size:14.5px;
  padding:3px 0;min-height:30px}
.famlist a:hover{color:var(--orange-dark);text-decoration:underline}
.famlist a b{display:block;color:var(--dark);font-weight:600;font-size:15px;line-height:1.35}
.famlist a span{color:var(--muted);font-size:13.5px}


/* ══════════════════════════════════════════════════════════════════════════
 * PUBLIC EXPERIENCE — added 2026-08-03
 * ══════════════════════════════════════════════════════════════════════════
 * Landing page, Learn section and the SunTroller page. Everything below reuses
 * the tokens declared at the top of this file, so light mode, dark mode and
 * the data-theme override all keep working without a second palette.
 *
 * NOTE the .famgrid / .famlist / .situations / .chooser / .perks / .steps
 * rules above are now unused by any generated page. They are left in place
 * because 404.html shares this sheet and because deleting live CSS to save a
 * few hundred bytes is a bad trade.
 *
 * NOTHING here affects app.css or the signed-in portal.
 */

/* ── Button contrast fix ───────────────────────────────────────────────────
 * ⚠ White text on the brand orange #F1592A is 3.4:1, which fails AA for
 * button-sized text, and on the dark scheme's #FF6B3D it is 2.8:1 — the label
 * genuinely disappears. This is the exact bug that took three passes on the
 * app shell (2026-08-02): the fault is the BACKGROUND luminance, not the text
 * colour. #C7411A is 5.0:1 and #A83210 is 6.7:1, both already tested there.
 * Fixed values in both schemes on purpose: a deep orange reads correctly on
 * white and on near black, so the button keeps one identity.
 */
:root{--btn:#C7411A;--btn-h:#A83210}
.btn{background:var(--btn)}
.btn:hover{background:var(--btn-h)}
.btn-quiet{background:transparent;color:var(--dark)}
.btn-quiet:hover{background:var(--sand)}

/* Secondary action. Outlined rather than a second filled colour, so the page
   never has two things shouting at the same volume. */
.btn-ghost{width:auto;min-height:56px;background:transparent;color:var(--dark);
  border:2px solid var(--rule);font-weight:600}
.btn-ghost:hover{background:var(--sand);border-color:var(--muted);color:var(--dark)}
.btn-sm{width:auto;min-height:44px;padding:10px 18px;font-size:15px}

/* ── Accessibility helpers ────────────────────────────────────────────────── */
.skip{position:absolute;left:-9999px;top:0;z-index:100;background:var(--paper);
  color:var(--dark);padding:12px 18px;border:2px solid var(--orange);font-weight:600}
.skip:focus{left:8px;top:8px}
.vh{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;
  clip:rect(0 0 0 0);white-space:nowrap;border:0}
.small{font-size:14.5px}
[hidden]{display:none!important}   /* the attribute alone loses to any display rule */

/* ── Header ────────────────────────────────────────────────────────────────
 * Sticky, because the account action should stay reachable without a popup.
 * Five nav items plus Sign In and one account button; no interstitial, no
 * overlay, nothing that covers the education.
 */
.top{position:sticky;top:0;z-index:40}
.top-in{gap:12px}
.brandmark{flex:none;display:block}
/* ⚠ These MUST be written as `.top .mainnav`, not `.mainnav`. The original
 * header rule at the top of this file is `.top nav{display:flex}` — specificity
 * 0,1,1 — which silently beats a bare `.mainnav` at 0,1,0 and left the desktop
 * nav rendered on a phone underneath the menu button. Same reason for
 * `.top .top-act`. */
.top .mainnav{display:none}
.top .top-act{display:none;align-items:center;gap:14px;flex:none}
.signin-link{font-family:var(--disp);font-weight:600;font-size:15px;
  color:var(--dark);text-decoration:none;white-space:nowrap}
.signin-link:hover{color:var(--btn)}
.navtoggle{margin-left:auto;background:transparent;border:2px solid var(--rule);
  color:var(--dark);min-height:44px;min-width:48px;font-size:20px;line-height:1;
  border-radius:2px;cursor:pointer;flex:none}
.mobnav{border-top:1px solid var(--rule);background:var(--paper);padding:12px 0 18px}
.mobnav .wrap{display:flex;flex-direction:column;gap:4px}
.mobnav a{font-family:var(--disp);font-weight:600;font-size:16.5px;color:var(--dark);
  text-decoration:none;padding:12px 2px;border-bottom:1px solid var(--rule)}
.mobnav a:last-child{border-bottom:none;margin-top:10px}
.mobnav a.btn{color:#fff;padding:15px 24px}
@media(min-width:1000px){
  .top .mainnav{display:flex}
  .top .top-act{display:flex}
  .navtoggle{display:none}
  .mobnav{display:none!important}
}
/* Below 1000px the header keeps ONE restrained account action visible next to
   the menu button. That is the whole of the sticky call to action: no floating
   bar, no popup, nothing that covers the education. */
@media(max-width:999px){
  .top .top-act{display:flex;margin-left:auto}
  .top .top-act .signin-link{display:none}
  .navtoggle{margin-left:0}
}
/* Smallest phones: keep the account action, shrink around it rather than
   dropping the only conversion point on the screen. */
@media(max-width:430px){
  .top .wrap{padding:0 14px}
  .top-in{gap:8px}
  .logo{height:32px}
  .top .top-act .btn-sm{padding:10px 12px;font-size:14px}
  .navtoggle{min-width:44px;font-size:18px}
}

/* ── Hero ─────────────────────────────────────────────────────────────────── */
.hero-solo .stack{max-width:72ch}
.herobtns{display:flex;flex-wrap:wrap;gap:12px;margin-top:6px}
.herobtns .btn{width:auto;min-width:min(100%,270px)}
@media(max-width:520px){.herobtns{flex-direction:column}.herobtns .btn{width:100%}}
.trustline{border-left:3px solid var(--orange);padding:12px 0 12px 16px;
  font-size:15.5px;color:var(--text);max-width:60ch}
.finelight{font-size:13.5px;color:var(--muted);margin:0}

/* ── Product previews ─────────────────────────────────────────────────────
 * Accurate previews of the real app shell, in the app's own dark palette, with
 * DEMONSTRATION information. No customer data was read to build these and the
 * portal was not modified to produce them. Rendered as markup rather than
 * images so they stay sharp, weigh almost nothing and reflow on a phone.
 */
.shots{display:grid;gap:18px;grid-template-columns:1fr}
@media(min-width:700px){.shots{grid-template-columns:repeat(2,1fr)}}
.shot{margin:0;border:1px solid var(--rule);border-radius:10px;overflow:hidden;
  background:#0B0D0F}
.shot-chrome{display:flex;gap:6px;padding:10px 12px;background:#0F1315;
  border-bottom:1px solid #252B30}
.shot-chrome span{width:9px;height:9px;border-radius:50%;background:#252B30}
.shot-body{padding:16px;display:flex;flex-direction:column;gap:10px;
  font-size:13.5px;color:#B9C0C6;min-height:190px}
.shot figcaption{padding:12px 16px 14px;background:var(--paper);
  border-top:1px solid var(--rule);font-family:var(--disp);font-weight:600;
  font-size:14.5px;color:var(--dark)}
.shot .demo{display:block;font-family:var(--body);font-weight:400;font-size:12.5px;
  color:var(--muted)}
.s-row{display:flex;justify-content:space-between;align-items:center;gap:10px;
  flex-wrap:wrap}
.shot b{color:#F4F6F7;font-family:'Monda',system-ui,sans-serif;font-weight:600}
.s-pill{font-size:11.5px;padding:4px 10px;border-radius:20px;background:#1A1F23;
  color:#B9C0C6;white-space:nowrap}
.s-tiles{display:grid;grid-template-columns:repeat(3,1fr);gap:8px}
.s-tiles div{background:#14181B;border:1px solid #252B30;border-radius:8px;
  padding:10px;display:flex;flex-direction:column;gap:3px}
.s-tiles span{font-size:11px;color:#7D868D;text-transform:uppercase;letter-spacing:.06em}
.s-tiles b{font-size:16px;color:#FF8A61}
.s-line,.s-kv{display:flex;justify-content:space-between;gap:12px;padding:9px 0;
  border-top:1px solid #252B30}
.s-kv span,.s-line span{color:#7D868D}
.s-doc{display:flex;align-items:center;gap:9px;padding:9px 11px;background:#14181B;
  border:1px solid #252B30;border-radius:8px}
.s-ico{color:#FF8A61;flex:none}
.s-ev{display:flex;flex-direction:column;gap:2px;padding:9px 11px;background:#14181B;
  border-left:2px solid #FF6B3D;border-radius:0 8px 8px 0}
.s-ev span{color:#7D868D;font-size:12.5px}

/* ── Benefits ─────────────────────────────────────────────────────────────── */
.bengrid{display:grid;gap:1px;background:var(--rule);border:1px solid var(--rule);
  grid-template-columns:1fr}
@media(min-width:640px){.bengrid{grid-template-columns:repeat(2,1fr)}}
@media(min-width:1000px){.bengrid{grid-template-columns:repeat(3,1fr)}}
.ben{background:var(--paper);padding:22px 24px;display:flex;flex-direction:column;gap:8px}
.ben h3{font-size:17.5px}
.ben p{font-size:15px;max-width:none}
/* ⚠ The 1px gap on a --rule background is what draws the hairlines, which also
 * means an EMPTY grid cell paints as a grey block. Five cards in a three column
 * grid left exactly that hole (Ed 2026-08-03: "why the gap, it doesnt look
 * right"). There are six cards now, but this makes the last one stretch to the
 * end of the row so no future count can reopen the hole. */
.ben:last-child{grid-column:auto/-1}

/* ── The four categories ──────────────────────────────────────────────────
 * ⛔ EQUAL WEIGHT IS THE POINT. Same card, same size, same treatment, no
 * featured variant, no ordering signal, no counts. A solar pool heating owner
 * must not be able to tell they are looking at a secondary category, because
 * they are not.
 */
.catgrid{display:grid;gap:18px;grid-template-columns:1fr}
@media(min-width:620px){.catgrid{grid-template-columns:repeat(2,1fr)}}
@media(min-width:1080px){.catgrid{grid-template-columns:repeat(4,1fr)}}
.cat{background:var(--paper);border:1px solid var(--rule);border-top:3px solid var(--orange);
  padding:22px 22px 24px;display:flex;flex-direction:column;gap:10px}
/* ⭐ Real product photographs, added 2026-08-03 (Ed: "wouldn't using actual
 * pictures of products help?"). They do — a homeowner working out whether they
 * have microinverters or a string inverter, or what a pool collector header
 * looks like, needs to SEE the thing.
 *
 * The five source images have four different aspect ratios, so a fixed ratio
 * box with object-fit:cover keeps the four category cards identical in height.
 * Equal weight across the four system types is a hard requirement, and a
 * portrait battery photo stretching one card would quietly break it. */
/* ⚠ height:auto is load bearing. The <img> carries height="560" so the browser
 * can reserve space before the file arrives, and that attribute maps to the
 * height PROPERTY — which means height is not auto, which means aspect-ratio is
 * ignored entirely. The photos rendered 560px tall in a 270px wide card until
 * this line was added. Keep the attributes (they prevent layout shift) and keep
 * this override next to them. */
.cat-photo{width:calc(100% + 44px);margin:-22px -22px 4px;display:block;
  height:auto;aspect-ratio:16/10;object-fit:cover;background:var(--sand)}
.cat h3{font-size:18.5px}
.cat > p{font-size:14.8px;max-width:none;color:var(--text)}
.cat ul{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:6px;
  font-size:14.2px;flex:1}
.cat ul li{padding-left:16px;position:relative;color:var(--text)}
.cat ul li::before{content:'';position:absolute;left:0;top:.6em;width:6px;height:6px;
  border-radius:50%;background:var(--orange)}
.go{font-family:var(--disp);font-weight:600;font-size:15px;color:var(--btn);
  text-decoration:none;display:inline-flex;align-items:center;gap:6px}
.go::after{content:'\2192'}
.go:hover{text-decoration:underline}
.cat .go{margin-top:6px}

/* ── Monitoring cards ─────────────────────────────────────────────────────
 * Status text comes from the single table in content/site.js. If a card here
 * says something the integrations cannot do, fix the table, not the markup.
 */
.mongrid{display:grid;gap:14px;grid-template-columns:1fr}
@media(min-width:620px){.mongrid{grid-template-columns:repeat(2,1fr)}}
@media(min-width:1080px){.mongrid{grid-template-columns:repeat(4,1fr)}}
.moncard{background:var(--sand);border:1px solid var(--rule);padding:18px 19px;
  display:flex;flex-direction:column;gap:9px;align-items:flex-start}
.moncard h3{font-size:16.5px}
.moncard p{font-size:14px;max-width:none;color:var(--text)}
.pill-live{background:var(--leaf-soft);color:var(--leaf)}
.pill-live::before{background:var(--leaf)}
/* ⚠ CONTRAST. This pill is 13px BOLD, which is not "large text", so it needs
 * the full 4.5:1. Measured on the live page:
 *   dark  — #C7411A on #2B1810 = 3.38:1  FAIL
 *   light — #C7411A on #FEF0EA = 4.49:1  fails by a hair
 * The background is deliberately soft, so the TEXT has to move, and it has to
 * move in opposite directions per scheme: darker on the pale background,
 * lighter on the near-black one. #A83210 gives 6.0:1 on light and the dark
 * scheme's own #FF8A61 gives 7.3:1 on dark. */
.pill-soon{background:var(--orange-soft);color:#A83210}
.pill-soon::before{background:var(--orange)}
@media (prefers-color-scheme:dark){.pill-soon{color:var(--orange-dark)}}
:root[data-theme="dark"] .pill-soon{color:var(--orange-dark)}
:root[data-theme="light"] .pill-soon{color:#A83210}
.moncard .pill,.lcard .pill,h2 .pill{white-space:normal;text-align:left}
.qualifier{font-size:14px;color:var(--muted);max-width:none}

/* ── SunTroller band ──────────────────────────────────────────────────────── */
.stband{background:var(--sand);border:1px solid var(--rule);border-left:4px solid var(--orange);
  padding:clamp(24px,3.5vw,40px)}
.stband h2{display:flex;align-items:center;gap:12px;flex-wrap:wrap}
.stbtns{display:flex;flex-wrap:wrap;gap:12px;margin-top:8px}
.stbtns .btn{width:auto}
@media(max-width:520px){.stbtns{flex-direction:column}.stbtns .btn{width:100%}}

/* ── Two customer paths, side by side and equal ───────────────────────────── */
.pathpair{display:grid;gap:18px;grid-template-columns:1fr}
@media(min-width:860px){.pathpair{grid-template-columns:repeat(2,1fr)}}
.pathpair .card{display:flex;flex-direction:column}
.pathpair .btn{width:auto;margin-top:auto;align-self:flex-start}
@media(max-width:520px){.pathpair .btn{width:100%}}

/* ── Learn navigation ─────────────────────────────────────────────────────── */
.lchips{display:flex;flex-wrap:wrap;gap:9px}
.lchip{display:inline-flex;align-items:center;min-height:44px;padding:9px 16px;
  background:var(--paper);border:1px solid var(--rule);border-radius:22px;
  font-family:var(--disp);font-weight:600;font-size:14.5px;color:var(--dark);
  text-decoration:none}
.lchip:hover{border-color:var(--orange);color:var(--btn)}
.lgrid{display:grid;gap:16px;grid-template-columns:1fr}
@media(min-width:620px){.lgrid{grid-template-columns:repeat(2,1fr)}}
@media(min-width:1000px){.lgrid{grid-template-columns:repeat(3,1fr)}}
.lcard{background:var(--paper);border:1px solid var(--rule);padding:20px 21px;
  display:flex;flex-direction:column;gap:8px;text-decoration:none}
.lcard:hover{border-color:var(--orange)}
.lcard h3{font-size:17.5px;display:flex;align-items:center;gap:9px;flex-wrap:wrap}
.lcard p{font-size:14.5px;max-width:none;color:var(--text)}
.lcard-soon{border-style:dashed}

/* ── Lead photograph on a learn article ───────────────────────────────────
 * Sits under the hero, above the prose, with a caption that does real work
 * rather than repeating the alt text: the alt describes the picture for
 * somebody who cannot see it, the caption tells everybody what to look at.
 */
.leadshot{margin:0 0 clamp(20px,3vw,32px);max-width:820px}
.leadshot img{width:100%;height:auto;display:block;aspect-ratio:16/10;
  object-fit:cover;background:var(--sand);border:1px solid var(--rule)}
.leadshot figcaption{padding:11px 2px 0;font-size:14px;color:var(--muted);
  max-width:70ch}

/* ── Breadcrumbs and article prose ────────────────────────────────────────── */
.crumbs{padding:16px 0 0;font-size:14px;color:var(--muted);
  display:flex;flex-wrap:wrap;gap:7px;align-items:center}
.crumbs a{color:var(--muted)}
.crumbs a:hover{color:var(--btn)}
.prose{padding-bottom:8px}
.prose p{max-width:68ch}
.ticks,.crosses{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;
  gap:9px;max-width:70ch}
.ticks li,.crosses li{position:relative;padding-left:30px;font-size:16px}
.ticks li::before{content:'\2713';position:absolute;left:0;top:0;color:var(--leaf);
  font-weight:700}
.crosses li::before{content:'\2715';position:absolute;left:0;top:0;color:#B3261E;
  font-weight:700}
@media (prefers-color-scheme:dark){.crosses li::before{color:#F0776B}}
:root[data-theme="dark"] .crosses li::before{color:#F0776B}
.cols3{list-style:none;margin:0;padding:0;display:grid;gap:8px;grid-template-columns:1fr;
  font-size:15px}
@media(min-width:560px){.cols3{grid-template-columns:repeat(2,1fr)}}
@media(min-width:900px){.cols3{grid-template-columns:repeat(3,1fr)}}
.cols3 li{padding-left:15px;position:relative;color:var(--text)}
.cols3 li::before{content:'';position:absolute;left:0;top:.62em;width:5px;height:5px;
  border-radius:50%;background:var(--muted)}
.plain{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:9px}
.plain a{font-size:15.5px}

/* ── FAQ ──────────────────────────────────────────────────────────────────
 * The original .faq was a CONTAINER holding several <details>. These pages put
 * the class on each <details> directly, so the open state marker needs its own
 * rule — the inherited one targets a descendant and would never match.
 */
.faqgrid{display:grid;gap:10px;grid-template-columns:1fr}
@media(min-width:900px){.faqgrid{grid-template-columns:repeat(2,1fr);align-items:start}}
details.faq{border:1px solid var(--rule);background:var(--paper)}
details.faq[open] summary::after{content:'\2212'}
details.faq .a{padding:0 20px 18px;font-size:15.5px;max-width:none}

/* ── Contextual CTA band ──────────────────────────────────────────────────
 * Appears AFTER the useful part of a page, never before it, and always relates
 * to what was just read. There is no popup, no overlay and no gate anywhere in
 * this section of the site.
 */
.ctaband{background:var(--orange-soft);border-left:4px solid var(--orange);
  padding:22px 24px;display:flex;flex-direction:column;gap:16px;align-items:flex-start}
.ctaband h2{font-size:clamp(20px,2vw,25px)}
.ctaband p{font-size:15.5px;max-width:62ch;color:var(--text)}
.ctaband .btn{width:auto}
@media(min-width:860px){
  .ctaband{flex-direction:row;align-items:center;justify-content:space-between;gap:28px}
  .ctaband .btn{flex:none}
}
@media(max-width:520px){.ctaband .btn{width:100%}}
.cta-acts{display:flex;flex-wrap:wrap;gap:12px}
@media(max-width:520px){
  .cta-acts{flex-direction:column;width:100%}
  .cta-acts .btn{width:100%}
}

/* ── Footer ───────────────────────────────────────────────────────────────
 * Eleven links, not fifty. The sibling brand directory that used to live here
 * belongs on allsolarenergy.com, which is where somebody browsing a company's
 * other websites actually is.
 */
.footnav{display:flex;flex-wrap:wrap;gap:10px 22px;padding-bottom:24px;
  margin-bottom:24px;border-bottom:1px solid var(--rule)}
.footnav a{font-family:var(--disp);font-weight:600;font-size:15px;color:var(--text);
  text-decoration:none;min-height:32px;display:inline-flex;align-items:center}
.footnav a:hover{color:var(--btn);text-decoration:underline}
.footfoot{display:grid;gap:20px;grid-template-columns:1fr;font-size:14.5px}
@media(min-width:760px){.footfoot{grid-template-columns:repeat(3,1fr)}}
.powered{color:var(--muted)}
.powered a{color:var(--muted);text-decoration:underline}
.powered a:hover{color:var(--btn)}
