/* Greentech Pulse portal styles.
   Every selector is scoped under .pulse so the CRM panel's own styles are
   never touched. Two complete palettes: light on .pulse, dark on
   .dark .pulse — Filament stamps `dark` on <html>, and the standalone portal
   layout sets it permanently. Markup lives in resources/views/pulse/. */











/* ================= TOKENS =================
   Three palettes, all complete — no colour is defined in only one of them.
   .pulse                     light, sitting on Filament's light page
   .dark .pulse               dark, tuned to Filament's own dark surfaces
   .dark .pulse.is-standalone the original deep-green portal, used full-screen
   Non-colour tokens live in the .pulse layout rule below and serve all three. */
.pulse {
  color-scheme: light;
  /* One surface everywhere: the panel's own card colour. Nested blocks
     (turbine tiles, site cards, work orders) sit on the same colour and are
     separated by hairlines, not by a darker well. */
  --bg:#F6F7F8; --bg2:#FFFFFF;
  --panel:#FFFFFF; --panel2:#FFFFFF; --inset:#FFFFFF;
  --ink:#111827; --ink2:#4B5563; --ink3:#79838F;
  --hairline:rgba(17,24,39,.12); --hairline2:rgba(17,24,39,.19);
  --gold:#8A6A28; --gold-dim:rgba(138,106,40,.12);
  --cyan:#1A7CAD; --cyan-soft:rgba(26,124,173,.10);
  --good:#0F7A59; --good-soft:rgba(15,122,89,.12);
  --warn:#8F6408; --warn-soft:rgba(143,100,8,.13);
  --crit:#B23127; --crit-soft:rgba(178,49,39,.12);
  --ext:#5F51BE;  --ext-soft:rgba(95,81,190,.13);
  --tint-faint:rgba(17,24,39,.035); --tint-soft:rgba(17,24,39,.05);
  --tint:rgba(17,24,39,.07); --tint-strong:rgba(17,24,39,.13);
  --leader:rgba(17,24,39,.34);
  --chart-muted:#808C99; --chart-ref:#5E6B78; --chart-tick:#3B4653;
  --nac-outer:#46515C; --nac-inner:#6B7681; --nac-detail:#929BA5;
  --overlay:rgba(255,255,255,.97); --chrome-bg:rgba(255,255,255,.86);
  --shadow:rgba(17,24,39,.16);
}

/* --------------------------------------------------------------------------
   OLD EMBEDDED GREY PALETTE — the pre-Pulse-theme values.
   TO REVERT: comment out the active `.dark .pulse` block below and uncomment
   this one. Served straight from public/, so a browser refresh is enough —
   no build step.

.dark .pulse {
  color-scheme: dark;
  --bg:#2A2F36; --bg2:#373D45;
  --panel:#373D45; --panel2:#373D45; --inset:#373D45;
  --ink:#E9EDF1; --ink2:#A8B2BD; --ink3:#7A8593;
  --hairline:rgba(255,255,255,.11); --hairline2:rgba(255,255,255,.18);
  --gold:#D9BC7C; --gold-dim:rgba(217,188,124,.16);
  --cyan:#4FB0E0; --cyan-soft:rgba(79,176,224,.14);
  --good:#35C296; --good-soft:rgba(53,194,150,.15);
  --warn:#E0A227; --warn-soft:rgba(224,162,39,.16);
  --crit:#EE5A4E; --crit-soft:rgba(238,90,78,.16);
  --ext:#9B8FE8;  --ext-soft:rgba(155,143,232,.16);
  --tint-faint:rgba(255,255,255,.04); --tint-soft:rgba(255,255,255,.06);
  --tint:rgba(255,255,255,.08); --tint-strong:rgba(255,255,255,.13);
  --leader:rgba(255,255,255,.38);
  --chart-muted:#7F8B97; --chart-ref:#9BA6B1; --chart-tick:#CBD3DA;
  --nac-outer:#C3CBD3; --nac-inner:#96A1AB; --nac-detail:#727E89;
  --overlay:rgba(38,43,50,.97); --chrome-bg:rgba(42,47,54,.85);
  --shadow:rgba(0,0,0,.5);
}
   -------------------------------------------------------------------------- 

/* Embedded dark. This used to sample Filament's own grey chrome (page #2A2F36,
   cards #373D45) so portal cards would read as panel cards. The panel's dark
   theme is now the portal palette itself — see the DARK THEME block in
   resources/css/filament/crm/theme.css — so the two agree here instead, and an
   embedded Pulse page is indistinguishable from the full-screen portal. */
.dark .pulse {
  color-scheme: dark;
  --bg:#0A0F0C; --bg2:#0D1310;
  --panel:#111A14; --panel2:#152018; --inset:#0C1410;
  --ink:#EAF2EC; --ink2:#9DB2A3; --ink3:#647A6C;
  --hairline:rgba(190,215,196,.085); --hairline2:rgba(190,215,196,.16);
  --gold:#D2B372; --gold-dim:rgba(210,179,114,.14);
  --cyan:#2E9FD6; --cyan-soft:rgba(46,159,214,.10);
  --good:#26B487; --good-soft:rgba(38,180,135,.12);
  --warn:#CE8F14; --warn-soft:rgba(206,143,20,.13);
  --crit:#DC4438; --crit-soft:rgba(220,68,56,.13);
  --ext:#8B7DE0;  --ext-soft:rgba(139,125,224,.13);
  --tint-faint:rgba(190,215,196,.03); --tint-soft:rgba(190,215,196,.05);
  --tint:rgba(190,215,196,.07); --tint-strong:rgba(190,215,196,.12);
  --leader:rgba(190,215,196,.35);
  --chart-muted:#7F8B97; --chart-ref:#9BA6B1; --chart-tick:#CBD3DA;
  --nac-outer:#C3CBD3; --nac-inner:#96A1AB; --nac-detail:#727E89;
  --overlay:rgba(12,18,14,.97); --chrome-bg:rgba(10,15,12,.85);
  --shadow:rgba(0,0,0,.6);
}

/* Full-screen portal at /customer-portal keeps the palette it was designed
   in — there is no panel chrome there to match. */
.dark .pulse.is-standalone {
  --bg:#0A0F0C; --bg2:#0D1310;
  --panel:#111A14; --panel2:#152018; --inset:#0C1410;
  --ink:#EAF2EC; --ink2:#9DB2A3; --ink3:#647A6C;
  --hairline:rgba(190,215,196,.085); --hairline2:rgba(190,215,196,.16);
  --gold:#D2B372; --gold-dim:rgba(210,179,114,.14);
  --cyan:#2E9FD6; --cyan-soft:rgba(46,159,214,.10);
  --good:#26B487; --good-soft:rgba(38,180,135,.12);
  --warn:#CE8F14; --warn-soft:rgba(206,143,20,.13);
  --crit:#DC4438; --crit-soft:rgba(220,68,56,.13);
  --ext:#8B7DE0;  --ext-soft:rgba(139,125,224,.13);
  --tint-faint:rgba(190,215,196,.03); --tint-soft:rgba(190,215,196,.05);
  --tint:rgba(190,215,196,.07); --tint-strong:rgba(190,215,196,.12);
  --leader:rgba(190,215,196,.35);
  --chart-muted:#5A7263; --chart-ref:#8CA294; --chart-tick:#C7D4CA;
  --nac-outer:#B9CCBE; --nac-inner:#7E948A; --nac-detail:#5E7168;
  --overlay:rgba(12,20,16,.95); --chrome-bg:rgba(10,15,12,.82);
  --shadow:rgba(0,0,0,.7);
}

.pulse, .pulse {margin:0;padding:0;background:var(--bg)}
.pulse {
  --r:12px;
  --sans:"Saira",-apple-system,"Segoe UI",sans-serif;
  --disp:"Saira Semi Condensed","Saira",-apple-system,sans-serif;
  --mono:"IBM Plex Mono",ui-monospace,SFMono-Regular,Menlo,monospace;
  min-height:100vh;background:
  radial-gradient(1100px 500px at 85% -10%, rgba(46,159,214,.05), transparent 60%),
  radial-gradient(900px 600px at -10% 110%, rgba(38,180,135,.04), transparent 55%),
  var(--bg);
  color:var(--ink); font-family:var(--sans); font-size:14px; line-height:1.45;
  -webkit-font-smoothing:antialiased;}
.pulse * {box-sizing:border-box}
.pulse h1, .pulse h2, .pulse h3, .pulse h4 {margin:0;font-family:var(--disp);font-weight:600;text-wrap:balance}
.pulse p {margin:0}
.pulse button {font-family:inherit;color:inherit;background:none;border:none;cursor:pointer;padding:0}
.pulse a {color:inherit}
.pulse svg {display:block}
.pulse .mono {font-family:var(--mono)}
.pulse .tnum {font-variant-numeric:tabular-nums}
/* ================= LOGIN ================= */
.pulse #login {position:relative;min-height:100vh;display:flex;flex-direction:column;overflow:hidden}
.pulse .lg-top {display:flex;justify-content:space-between;align-items:center;padding:26px 40px;position:relative;z-index:3}
.pulse .brand {display:flex;align-items:center;gap:11px}
.pulse .brand .bmark {width:34px;height:34px;border-radius:9px;background:linear-gradient(145deg,#152A1E,#0D1A12);border:1px solid var(--hairline2);display:grid;place-items:center}
.pulse .brand .bname {font-family:var(--disp);font-weight:600;font-size:16px;letter-spacing:.02em}
.pulse .brand .bsub {font-size:10px;color:var(--gold);letter-spacing:.22em;text-transform:uppercase;font-family:var(--mono)}
.pulse .lg-main {position:relative;z-index:3;flex:1;display:grid;grid-template-columns:minmax(360px,560px) 1fr;gap:40px;align-items:center;padding:10px 40px 40px;max-width:1280px;width:100%;margin:0 auto}
.pulse .lg-eyebrow {display:inline-flex;align-items:center;gap:8px;font-family:var(--mono);font-size:10.5px;letter-spacing:.2em;text-transform:uppercase;color:var(--gold);margin-bottom:18px}
.pulse .lg-eyebrow::before {content:"";width:22px;height:1px;background:var(--gold)}
.pulse .lg-h1 {font-size:clamp(34px,4.6vw,54px);line-height:1.04;letter-spacing:-.015em;font-weight:650}
.pulse .lg-h1 em {font-style:normal;color:var(--gold)}
.pulse .lg-sub {color:var(--ink2);font-size:15.5px;max-width:46ch;margin-top:18px}
.pulse .lg-card {margin-top:30px;background:var(--panel);border:1px solid var(--hairline2);border-radius:16px;padding:22px;max-width:400px;box-shadow:0 24px 60px -30px var(--shadow)}
.pulse .lg-card label {display:block;font-family:var(--mono);font-size:10px;letter-spacing:.16em;text-transform:uppercase;color:var(--ink3);margin-bottom:8px}
.pulse .lg-field {display:flex;gap:10px}
.pulse .lg-field input {flex:1;background:var(--inset);border:1px solid var(--hairline2);border-radius:10px;padding:12px 14px;color:var(--ink);font-family:var(--mono);font-size:13px;letter-spacing:.28em}
.pulse .lg-field input:focus {outline:2px solid var(--cyan);outline-offset:1px}
.pulse .btn {display:inline-flex;align-items:center;justify-content:center;gap:8px;background:var(--gold);color:#191405;border-radius:10px;padding:12px 20px;font-weight:600;font-size:14px;font-family:var(--disp);letter-spacing:.02em}
.pulse .btn:hover {filter:brightness(1.07)}
.pulse .btn:focus-visible, .pulse .navbtn:focus-visible, .pulse button:focus-visible {outline:2px solid var(--cyan);outline-offset:2px}
.pulse .lg-meta {margin-top:14px;font-size:12px;color:var(--ink3)}
.pulse .lg-meta b {color:var(--ink2);font-weight:500}
.pulse .lg-stats {position:relative;z-index:3;display:flex;gap:0;border-top:1px solid var(--hairline);background:var(--chrome-bg);backdrop-filter:blur(6px)}
.pulse .lg-stats .ls {flex:1;padding:16px 40px;border-right:1px solid var(--hairline)}
.pulse .lg-stats .ls:last-child {border-right:none}
.pulse .ls .lsv {font-family:var(--disp);font-size:22px;font-weight:650}
.pulse .ls .lsl {font-size:11px;color:var(--ink3);letter-spacing:.06em;text-transform:uppercase;font-family:var(--mono)}
/* hillside scene */
.pulse .scene {position:absolute;inset:0;z-index:1;pointer-events:none}
.pulse .scene svg {width:100%;height:100%;}
.pulse .ridge {fill:#0C1410}
.pulse .ridge2 {fill:#0A100D}
.pulse .twr {stroke:#2C3E33;stroke-width:2.4;fill:none}
.pulse .hub {fill:#33473B}
.pulse .bl {fill:#2C3E33}
.pulse .rot {animation:spin 2.6s linear infinite;transform-box:fill-box;transform-origin:center}
.pulse .rot.s2 {animation-duration:3.4s}
.pulse .rot.s3 {animation-duration:2.1s}
.pulse .windline {stroke:rgba(46,159,214,.16);stroke-width:1.4;fill:none;stroke-dasharray:2 7;animation:drift 9s linear infinite}
.pulse .windline.w2 {animation-duration:13s;animation-delay:-4s}
@keyframes spin {to{transform:rotate(360deg)}}
@keyframes drift {to{stroke-dashoffset:-140}}
/* ================= APP SHELL ================= */
.pulse #app {display:none;min-height:100vh}
.pulse #app.on {display:grid;grid-template-columns:228px 1fr}
.pulse .side {border-right:1px solid var(--hairline);background:var(--bg2);display:flex;flex-direction:column;position:sticky;top:0;height:100vh;min-width:0}
.pulse .side .brand {padding:18px 18px 14px}
.pulse .nav {display:flex;flex-direction:column;gap:2px;padding:10px 10px;flex:1;overflow:auto}
.pulse .navlbl {font-family:var(--mono);font-size:9.5px;letter-spacing:.2em;color:var(--ink3);text-transform:uppercase;padding:12px 10px 6px}
.pulse .navbtn {display:flex;align-items:center;gap:11px;padding:9.5px 12px;border-radius:9px;color:var(--ink2);font-size:13.5px;font-weight:500;text-align:left;border:1px solid transparent}
.pulse .navbtn svg {flex:none;opacity:.8}
.pulse .navbtn:hover {background:var(--tint-soft);color:var(--ink)}
.pulse .navbtn.on {background:var(--gold-dim);color:var(--gold);border-color:rgba(210,179,114,.22)}
.pulse .navbtn.on svg {opacity:1}
.pulse .navbtn .sub {margin-left:auto;font-family:var(--mono);font-size:9.5px;color:var(--ink3)}
.pulse .side .roc {margin:10px;border:1px solid var(--hairline2);border-radius:12px;padding:12px;background:linear-gradient(160deg,rgba(38,180,135,.07),transparent 70%)}
.pulse .roc .rt {display:flex;align-items:center;gap:7px;font-size:11px;font-family:var(--mono);letter-spacing:.08em;color:var(--good)}
.pulse .roc .rt .dot {width:7px;height:7px;border-radius:50%;background:var(--good);box-shadow:0 0 8px var(--good);animation:pulse 2.2s ease-in-out infinite}
.pulse .roc p {font-size:11.5px;color:var(--ink2);margin-top:7px}
.pulse .roc .tel {font-family:var(--mono);font-size:12px;color:var(--ink);margin-top:6px}
@keyframes pulse {50%{opacity:.45}}
.pulse .main {min-width:0;display:flex;flex-direction:column}
.pulse .topbar {position:sticky;top:0;z-index:40;display:flex;align-items:center;gap:14px;padding:12px 26px;border-bottom:1px solid var(--hairline);background:var(--chrome-bg);backdrop-filter:blur(10px)}
.pulse .tb-title {font-family:var(--disp);font-weight:600;font-size:15px}
.pulse .tb-cust {font-size:11px;color:var(--ink3)}
.pulse .chip {display:inline-flex;align-items:center;gap:6px;border:1px solid var(--hairline2);border-radius:999px;padding:4px 10px;font-family:var(--mono);font-size:9.5px;letter-spacing:.09em;text-transform:uppercase;color:var(--ink2);white-space:nowrap}
.pulse .chip .dot {width:6px;height:6px;border-radius:50%}
/* Chips used as navigation: the current scope is marked, the rest are links. */
.pulse a.chip {text-decoration:none;transition:border-color .15s,color .15s}
.pulse a.chip:hover {color:var(--ink);border-color:var(--hairline2)}
.pulse .chip.on {color:var(--gold);border-color:var(--gold);background:var(--gold-dim)}

.pulse .chip.live {color:var(--good);border-color:rgba(38,180,135,.35)}
.pulse .chip.live .dot {background:var(--good);box-shadow:0 0 7px var(--good);animation:pulse 2.2s infinite}
.pulse .chip.season {color:var(--cyan);border-color:rgba(46,159,214,.3)}
.pulse .chip.concept {color:var(--gold);border-color:rgba(210,179,114,.3)}
.pulse .chip.warnc {color:var(--warn);border-color:rgba(206,143,20,.35)}
.pulse .chip.critc {color:var(--crit);border-color:rgba(220,68,56,.35)}
.pulse .chip.extc {color:var(--ext);border-color:rgba(139,125,224,.35)}
.pulse .tb-spacer {flex:1}
.pulse .tb-clock {font-family:var(--mono);font-size:12px;color:var(--ink2)}
.pulse .bell {position:relative;width:34px;height:34px;border-radius:9px;border:1px solid var(--hairline2);display:grid;place-items:center;color:var(--ink2)}
.pulse .bell .bn {position:absolute;top:-5px;right:-5px;background:var(--crit);color:#fff;border-radius:999px;font-size:9.5px;font-family:var(--mono);padding:1px 5px}
.pulse .avatar {display:flex;align-items:center;gap:9px}
.pulse .avatar .av {width:34px;height:34px;border-radius:9px;background:linear-gradient(140deg,#23392C,#152018);border:1px solid var(--hairline2);display:grid;place-items:center;font-family:var(--disp);font-size:12.5px;color:var(--gold)}
.pulse .avatar .an {font-size:12.5px;line-height:1.2}
.pulse .avatar .ar {font-size:10px;color:var(--ink3)}
.pulse .content {padding:24px 26px 60px;display:none}
.pulse .content.on {display:block}
.pulse .ph {display:flex;align-items:baseline;gap:14px;flex-wrap:wrap;margin-bottom:4px}
.pulse .ph h2 {font-size:21px;letter-spacing:-.01em}
.pulse .ph .pd {color:var(--ink3);font-size:12.5px}
.pulse .toolrow {display:flex;gap:8px;align-items:center;flex-wrap:wrap;margin:12px 0 18px}
.pulse .toolrow .grow {flex:1}
.pulse .ghostbtn {display:inline-flex;align-items:center;gap:7px;border:1px solid var(--hairline2);border-radius:9px;padding:7px 12px;font-size:12px;color:var(--ink2)}
.pulse .ghostbtn:hover {color:var(--ink);background:var(--tint-soft)}
/* ================= CARDS & GRID ================= */
.pulse .card {background:var(--panel);border:1px solid var(--hairline);border-radius:var(--r);padding:16px 18px;position:relative}
.pulse .card.pad0 {padding:0;overflow:hidden}
.pulse .chd {display:flex;align-items:flex-start;justify-content:space-between;gap:10px;margin-bottom:12px}
.pulse .eyebrow {display:block;font-family:var(--mono);font-size:9px;letter-spacing:.22em;text-transform:uppercase;color:var(--gold);margin-bottom:4px}
.pulse .chd h3 {font-size:14.5px;color:var(--ink)}
.pulse .chd .hint {font-size:11px;color:var(--ink3);margin-top:2px}
.pulse .src {font-family:var(--mono);font-size:9.5px;color:var(--ink3);letter-spacing:.05em;margin-top:10px}
.pulse .ov-hero {display:grid;grid-template-columns:minmax(280px,1.3fr) repeat(4,minmax(0,1fr));gap:12px;margin-bottom:12px}
.pulse .ov-hero>* {min-width:0}
.pulse .hero {background:linear-gradient(150deg,rgba(46,159,214,.09),transparent 55%),var(--panel);border:1px solid var(--hairline2);border-radius:var(--r);padding:18px 20px;display:flex;flex-direction:column;justify-content:space-between;min-height:150px}
.pulse .hero .hv {font-family:var(--disp);font-size:54px;font-weight:650;letter-spacing:-.02em;line-height:1}
.pulse .hero .hv small {font-size:20px;color:var(--ink2);font-weight:500;margin-left:6px}
.pulse .hero .hl {display:flex;align-items:center;gap:8px}
.pulse .hero .cappct {font-size:12px;color:var(--ink2)}
.pulse .kpi {display:flex;flex-direction:column;gap:6px;justify-content:space-between}
.pulse .kpi .kl {font-size:12.5px;font-weight:600;color:var(--ink2)}
/* The qualifier after the label — "- 17:30", "- Jul 2026". A class rather than
   the inline styles it replaces, so the four cards cannot drift apart.
   600 is the heaviest IBM Plex Mono weight embedded in this file, so weight is
   already maxed; the qualifier reads bolder because it moved off --ink3 (the
   dimmest ink) onto --ink2. Asking for 700 would only get a synthesised
   fallback, which looks smeared rather than bold. */
.pulse .kpi .kl .klt {font-family:var(--mono);font-size:11.5px;font-weight:600;color:var(--ink2)}
.pulse .kpi .kv {font-family:var(--disp);font-size:26px;font-weight:650;letter-spacing:-.01em}
.pulse .kpi .kv small {font-size:13px;color:var(--ink2);font-weight:500}
.pulse .kpi .kd {display:flex;align-items:center;gap:8px;font-size:11.5px;color:var(--ink3);flex-wrap:wrap}
.pulse .delta {font-family:var(--mono);font-size:10.5px;padding:2px 7px;border-radius:6px;white-space:nowrap}
.pulse .delta.up {color:var(--good);background:var(--good-soft)}
.pulse .delta.dn {color:var(--crit);background:var(--crit-soft)}
.pulse .delta.flat {color:var(--ink2);background:var(--tint)}
.pulse .spark {width:92px;height:26px;flex:none}
.pulse .sline {stroke:var(--chart-muted);stroke-width:1.6;fill:none;opacity:.75}
.pulse .sdot {fill:var(--cyan);stroke:var(--panel);stroke-width:2}
.pulse .kpirow.cols-3 {grid-template-columns:repeat(3,minmax(0,1fr))}
.pulse .kpirow.cols-5 {grid-template-columns:repeat(5,minmax(0,1fr))}
.pulse .sitedetails-grid {display:grid;grid-template-columns:1fr 1fr;margin-top:4px}
.pulse .sitedetails-grid .m {padding:8px 14px 8px 0;font-family:var(--mono);font-size:9px;letter-spacing:.1em;text-transform:uppercase;color:var(--ink3)}
.pulse .sitedetails-grid .m:nth-child(even) {padding-left:14px;padding-right:0;border-left:1px solid var(--hairline)}
.pulse .sitedetails-grid .m:nth-child(n+3) {border-top:1px solid var(--hairline);padding-top:8px}
.pulse .sitedetails-grid .m b {display:block;margin-top:3px;font-family:var(--mono);font-size:13px;font-weight:500;letter-spacing:0;color:var(--ink)}
.pulse .card.sitedetails {overflow:hidden}
/* Turbine turning inside the card. Bled off the bottom-right corner and clipped
   by the card's overflow, so it reads as part of the card rather than an icon
   dropped on top of it. Sits under the text (z-index 0 against the content's 1)
   and never takes a click. currentColor follows the theme, so dark needs a
   different opacity rather than a second asset.

   3.6s is chosen to be clearly in motion, yet slower than the live status
   rotors (2-2.4s) so a customer cannot read this decoration as "generating". */
.pulse .cardart {position:absolute;z-index:0;right:-14px;bottom:-20px;width:128px;height:128px;color:var(--gold);opacity:.2;pointer-events:none;overflow:visible}
.pulse .cardart .rot {animation-duration:3.6s}
.dark .pulse .cardart {opacity:.26}
/* Keeps the label and the meta grid above the artwork. */
.pulse .card.sitedetails > .kl, .pulse .card.sitedetails > .sitedetails-grid {position:relative;z-index:1}
/* Full-width bands stacked between the grids. */
.pulse .ov-band {margin-bottom:12px}

/* Row 1: four equal KPI cards. */
.pulse .kpirow {display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:12px;margin-bottom:12px}

/* Two columns: the fleet and the chart on the wide side, the summaries and the
   activity feed on the narrow one. The side column is wide enough that feed
   entries wrap over two lines rather than four. */
.pulse .ov-split {display:grid;grid-template-columns:minmax(0,1fr) minmax(380px,0.5fr);gap:12px;margin-bottom:12px}
.pulse .ov-split>* {min-width:0}
.pulse .stack {display:flex;flex-direction:column;gap:12px;min-width:0}
.pulse .stack>.card {margin-bottom:0}

/* Both columns stretch to the taller one, and the activity feed takes up the
   slack in the narrow column so the two columns end level. */
.pulse .ov-split>.stack:last-child>.card:last-child:has(.feed) {flex:1 1 auto;display:flex;flex-direction:column}
.pulse .ov-split>.stack:last-child>.card:last-child .feed {flex:1 1 auto;overflow-y:auto}

/* The summary column travels with the scroll.

   The maintenance feed lives beside Production Year now, so nothing in this
   column absorbs slack — and on a large fleet the status board makes the left
   column several screens tall, leaving the summaries in a short block above a
   long void. Stretching a card to fill it is no answer: none of these have
   content to grow into, and an oversized card reads worse than the gap.

   So the column keeps its natural height and sticks below the topbar, putting
   the figures beside whatever part of the board is on screen. The space is
   still there; nothing is ever parked next to it.

   Excludes .chartsplit, where the opposite is wanted — that feed stretches to
   match the chart beside it. The max-height guards short viewports, where a
   sticky block taller than the screen pins its own bottom out of reach. */
.pulse .ov-split:not(.chartsplit)>.stack:last-child {
  position:sticky;
  top:var(--stick,64px);
  align-self:start;
  max-height:calc(100vh - var(--stick,64px) - 14px);
  overflow-y:auto;
}
.pulse.is-standalone {--stick:62px}
.pulse.is-embedded {--stick:78px}

/* Below the split's own breakpoint there is one column and nothing to stick
   beside, so it goes back to flowing with the page. */
@media (max-width:1100px) {
  .pulse .ov-split:not(.chartsplit)>.stack:last-child {
    position:static;max-height:none;overflow:visible;
  }
}

/* Period summary sits in a 336px column now, so its figures stack again. */
.pulse .periodgrid {display:grid;grid-template-columns:1fr;gap:0}


@media (max-width:1180px){
  /* The cols-* classes are listed explicitly: they carry higher specificity
     than a bare .kpirow, so without them a 3- or 5-up row never collapsed. */
  .pulse .kpirow, .pulse .kpirow.cols-3, .pulse .kpirow.cols-5 {grid-template-columns:repeat(2,minmax(0,1fr))}
  .pulse .ov-split {grid-template-columns:1fr}
}
@media (max-width:640px){
  .pulse .kpirow, .pulse .kpirow.cols-3, .pulse .kpirow.cols-5 {grid-template-columns:1fr}
}

.pulse .ov-grid {display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr) 336px;gap:12px;grid-auto-rows:min-content}
.pulse .ov-grid>* {min-width:0}
.pulse .span2 {grid-column:span 2}
.pulse .rail {grid-row:span 4;display:flex;flex-direction:column;gap:12px}
/* charts */
.pulse .ch {width:100%;height:auto}
.pulse .smch {width:100%;height:52px}
.pulse .grid {stroke:var(--hairline);stroke-width:1}
.pulse .axlbl {fill:var(--ink3);font-family:var(--mono);font-size:10px}
.pulse .axlbl.unit {fill:var(--ink3)}
.pulse .axlbl.cap {fill:var(--ink2)}
.pulse .axlbl.guar {fill:var(--gold)}
.pulse .axlbl.alarm {fill:var(--crit)}
.pulse .axlbl.warn {fill:var(--warn)}
.pulse .axlbl.hotlbl {fill:var(--ink2)}
.pulse .area {fill:rgba(46,159,214,.10)}
.pulse .line {stroke:var(--cyan);stroke-width:2;fill:none;stroke-linejoin:round;stroke-linecap:round}
.pulse .enddot {fill:var(--cyan);stroke:var(--panel);stroke-width:2}
.pulse .endpulse {fill:none;stroke:var(--cyan);stroke-width:1.5;opacity:0;animation:ping 2.6s ease-out infinite}
@keyframes ping {0%{opacity:.7;transform:scale(1)}70%{opacity:0;transform:scale(2.6)}100%{opacity:0}}
.pulse .endpulse {transform-box:fill-box;transform-origin:center}
.pulse .capline {stroke:var(--hairline2);stroke-width:1}
.pulse .hb {fill:transparent}
.pulse .hb:hover {fill:var(--tint-soft)}
.pulse .xhair {stroke:var(--hairline2);stroke-width:1;visibility:hidden}
.pulse .refline {stroke:var(--chart-ref);stroke-width:2;fill:none}
.pulse .pdot {fill:var(--cyan);stroke:var(--panel);stroke-width:2;opacity:.9}
.pulse .opdot {fill:var(--gold);stroke:var(--panel);stroke-width:2}
.pulse .mklbl {fill:var(--ink2);font-family:var(--mono);font-size:10.5px}
.pulse .warnband {fill:rgba(206,143,20,.07)}
.pulse .alarmline {stroke:var(--crit);stroke-width:1;stroke-dasharray:5 4}
.pulse .guarline {stroke:var(--gold);stroke-width:1.2;stroke-dasharray:5 4;opacity:.85}
.pulse .ldot {fill:var(--cyan);stroke:var(--panel);stroke-width:2}
.pulse .ldot.below {fill:var(--warn)}
.pulse .evdiamond {fill:var(--warn);stroke:var(--panel);stroke-width:1.5}
.pulse .petal {fill:rgba(46,159,214,.25);stroke:rgba(46,159,214,.55);stroke-width:1}
.pulse .petal.hot {fill:rgba(46,159,214,.78)}
.pulse .ring {fill:none;stroke:var(--hairline);stroke-width:1}
.pulse .rose {width:100%;max-width:250px;height:auto;margin:0 auto}
.pulse .roseval {fill:var(--ink);font-family:var(--disp);font-size:19px;font-weight:600}
.pulse .roseunit {fill:var(--ink3);font-family:var(--mono);font-size:9px}
.pulse .col {fill:var(--cyan)}
.pulse .col.mtd {fill:rgba(46,159,214,.42)}
.pulse .p50tick {stroke:var(--chart-tick);stroke-width:2.5}
.pulse .collbl {fill:var(--ink2);font-family:var(--mono);font-size:10.5px}
.pulse .legend {display:flex;gap:16px;flex-wrap:wrap;font-size:11px;color:var(--ink2);margin-top:10px}
.pulse .legend .li {display:inline-flex;align-items:center;gap:7px}
.pulse .sw {width:14px;height:3px;border-radius:2px;background:var(--cyan)}
.pulse .sw.dot {width:8px;height:8px;border-radius:50%}
.pulse .sw.refl {background:var(--chart-ref)}
.pulse .sw.tick {background:var(--chart-tick);height:2.5px}
.pulse .sw.goldd {background:var(--gold);height:2px}
.pulse .dtable {margin-top:10px;border-top:1px solid var(--hairline)}
.pulse .dtable summary {cursor:pointer;font-family:var(--mono);font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:var(--ink3);padding:8px 0;list-style:none}
.pulse .dtable summary:hover {color:var(--ink2)}
.pulse .dtable table {width:100%;border-collapse:collapse;font-family:var(--mono);font-size:11px;color:var(--ink2)}
.pulse .dtable td, .pulse .dtable th {padding:4px 8px;border-top:1px solid var(--hairline);text-align:right}
.pulse .dtable td:first-child, .pulse .dtable th:first-child {text-align:left;color:var(--ink3)}
/* meter ring */
.pulse .ringwrap {display:flex;align-items:center;gap:16px}
.pulse .ringsvg {width:104px;height:104px;flex:none}
.pulse .rtrack {stroke:rgba(38,180,135,.16);stroke-width:9;fill:none}
.pulse .rfill {stroke:var(--good);stroke-width:9;fill:none;stroke-linecap:round;transform:rotate(-90deg);transform-origin:center}
.pulse .rguar {stroke:var(--gold);stroke-width:3}
.pulse .rv {fill:var(--ink);font-family:var(--disp);font-size:21px;font-weight:650}
.pulse .rl {fill:var(--ink3);font-family:var(--mono);font-size:8px;letter-spacing:.08em}
.pulse .ringmeta {display:flex;flex-direction:column;gap:7px;font-size:12px;color:var(--ink2)}
.pulse .ringmeta .row {display:flex;gap:8px;align-items:center}
.pulse .ringmeta .k {font-family:var(--mono);font-size:10px;color:var(--ink3);width:86px;letter-spacing:.04em}
.pulse .ringmeta .v {font-family:var(--mono);font-size:12px;color:var(--ink)}
/* turbine board */
.pulse .board {display:grid;grid-template-columns:repeat(auto-fill,minmax(112px,1fr));gap:8px}
.pulse .wtg {border:1px solid var(--hairline);border-radius:11px;padding:9px 10px;background:var(--inset);display:flex;flex-direction:column;gap:6px;transition:border-color .15s}
.pulse a.wtg {text-decoration:none;color:inherit}
.pulse .wtg:hover {border-color:var(--hairline2)}
.pulse .wtg .wid {display:flex;justify-content:space-between;align-items:center;font-family:var(--mono);font-size:10.5px;color:var(--ink2)}
.pulse .wtg .sdot2 {width:7px;height:7px;border-radius:50%}
.pulse .wtg .wkw {font-family:var(--disp);font-size:17px;font-weight:650}
.pulse .wtg .wkw small {font-size:10.5px;color:var(--ink3);font-weight:500}
.pulse .wtg .wst {display:flex;align-items:center;gap:6px;font-size:9.5px;font-family:var(--mono);letter-spacing:.05em;text-transform:uppercase}
.pulse .wtg.gen .sdot2 {background:var(--good);box-shadow:0 0 6px var(--good)}
.pulse .wtg.gen .wst {color:var(--good)}
.pulse .wtg.warn .sdot2 {background:var(--warn);box-shadow:0 0 6px var(--warn)}
.pulse .wtg.warn .wst {color:var(--warn)}
.pulse .wtg.fault .sdot2 {background:var(--crit);box-shadow:0 0 6px var(--crit)}
.pulse .wtg.fault .wst {color:var(--crit)}
.pulse .wtg.svc .sdot2 {background:var(--cyan)}
.pulse .wtg.svc .wst {color:var(--cyan)}
.pulse .wtg.ext .sdot2 {background:var(--ext)}
.pulse .wtg.ext .wst {color:var(--ext)}
.pulse .rotoricon {width:15px;height:15px;flex:none;overflow:visible}
.pulse .rotoricon use {transform-box:fill-box;transform-origin:center}
.pulse .wtg.gen .rotoricon use {animation:spin 2s linear infinite}
.pulse .wtg.warn .rotoricon use {animation:spin 2.4s linear infinite}
/* No live reading: grey dot, still rotor, muted label. */
.pulse .wtg:not(.gen):not(.warn):not(.fault):not(.svc):not(.ext) .sdot2 {background:var(--ink3)}
.pulse .wtg:not(.gen):not(.warn):not(.fault):not(.svc):not(.ext) .wst {color:var(--ink3)}
.pulse .boardlegend {display:flex;gap:14px;flex-wrap:wrap;margin-top:12px;font-family:var(--mono);font-size:10px;letter-spacing:.06em;text-transform:uppercase;color:var(--ink2)}
.pulse .boardlegend .li {display:flex;align-items:center;gap:6px}
.pulse .boardlegend .dot {width:7px;height:7px;border-radius:50%}
/* feed */
.pulse .feed {display:flex;flex-direction:column}
.pulse .fi {display:flex;gap:12px;padding:10px 0;border-top:1px solid var(--hairline)}
.pulse .fi:first-child {border-top:none}
.pulse .fi .ft {font-family:var(--mono);font-size:10.5px;color:var(--ink3);width:52px;flex:none;padding-top:2px}
.pulse .fi .fb {font-size:12.5px;color:var(--ink2)}
.pulse .fi .fb b {color:var(--ink);font-weight:600}

/* Scheduled-activity feed. The bare .fi row above is still what the demo
   work-order feed renders, so the maintenance card's own layout is scoped to
   .feed.sched: an accent rail, the site as the row's headline, the job under
   it, and the date pinned right. Colours are all tokens, so dark follows. */
.pulse .feed.sched .fi {gap:0;padding:11px 0;align-items:stretch}
.pulse .feed.sched .frail {width:3px;flex:none;margin-right:11px;border-radius:3px;background:var(--cyan);opacity:.5}
.pulse .feed.sched .fi.is-planned .frail {background:var(--warn)}
.pulse .feed.sched .fb {flex:1 1 auto;min-width:0}
/* The site is the row's identity — bold ink against the muted job line. */
.pulse .feed.sched .fsite {display:block;font-weight:700;font-size:12.5px;color:var(--ink);letter-spacing:.005em}
.pulse .feed.sched .ftitle {display:block;margin-top:1px;font-size:12.5px;line-height:1.35;color:var(--ink3)}
.pulse .feed.sched .ftitle b {color:var(--ink2);font-weight:600}
.pulse .feed.sched .fmeta {display:flex;flex-wrap:wrap;align-items:center;gap:6px;margin-top:5px;
  font-family:var(--mono);font-size:10.5px;color:var(--ink3)}
.pulse .feed.sched .fmeta .sep {opacity:.45}
.pulse .feed.sched .fdur {color:var(--ink2);font-weight:600}
/* Grouped rows only: how many separate stops were folded into this job. */
.pulse .feed.sched .fstops {padding:1px 6px;border-radius:4px;background:var(--tint-soft);color:var(--ink2)}
.pulse .feed.sched .ft {width:auto;flex:none;margin-left:12px;text-align:right;padding-top:1px;line-height:1.3;white-space:nowrap}
.pulse .feed.sched .ft .fy {opacity:.65}
/* Base pill. Was scoped to .fi (the activity feed), which meant the machines
   table got the colour rules below but none of the shape — no padding, no
   radius. Unscoped now so any .tag looks like a pill; the feed still matches
   and is unchanged. */
.pulse .tag {display:inline-block;font-family:var(--mono);font-size:9px;letter-spacing:.08em;text-transform:uppercase;padding:1.5px 7px;border-radius:5px;margin-right:7px}
/* Machine status in the table: sentence case rather than shouty, a size up,
   and roomier so it reads as a state badge instead of a category chip. */
.pulse .tag.status {font-size:10.5px;letter-spacing:.02em;text-transform:none;padding:3.5px 11px;margin-right:0;
  /* Every pill the same size regardless of its word, so the column reads as one
     block instead of a ragged edge. Sized for the longest state, "Maintenance";
     shorter ones centre inside it rather than shrinking. */
  min-width:104px;text-align:center;box-sizing:border-box}
.pulse .tag.ok {color:var(--good);background:var(--good-soft)}
.pulse .tag.warn {color:var(--warn);background:var(--warn-soft)}
.pulse .tag.crit {color:var(--crit);background:var(--crit-soft)}
.pulse .tag.ext {color:var(--ext);background:var(--ext-soft)}
.pulse .tag.info {color:var(--cyan);background:var(--cyan-soft)}
/* rail */
.pulse .rail .rsec {border-top:1px solid var(--hairline);padding-top:10px;margin-top:2px}
.pulse .kvrow {display:flex;justify-content:space-between;align-items:baseline;padding:5px 0;font-size:12.5px;color:var(--ink2)}
.pulse .kvrow .v {font-family:var(--mono);font-size:12.5px;color:var(--ink)}
.pulse .kvrow .v.good {color:var(--good)}
.pulse .kvrow .v.warn {color:var(--warn)}
.pulse .kvrow .v.gold {color:var(--gold)}

/* Contract dial. The ring is a dashed circle rather than an arc path so the
   value is one number to change; the gold tick is a separate line so it stays
   crisp at any percentage and never inherits the ring's cap rounding. */
.pulse .contractrow {display:flex;align-items:center;gap:22px;flex-wrap:wrap;margin-top:8px}
.pulse .madial {width:118px;height:118px;flex:0 0 auto}
.pulse .madial .dtrack {fill:none;stroke:var(--hairline);stroke-width:9}
.pulse .madial .dval {fill:none;stroke:var(--good);stroke-width:9;stroke-linecap:round}
.pulse .madial .dval.below {stroke:var(--warn)}
.pulse .madial .dtick {stroke:var(--gold);stroke-width:2.5;stroke-linecap:round}
.pulse .madial .dnum {fill:var(--ink);font-family:var(--disp);font-size:21px;font-weight:650;text-anchor:middle}
.pulse .madial .dlbl {fill:var(--ink3);font-family:var(--mono);font-size:7.5px;letter-spacing:.16em;text-anchor:middle}
.pulse .contractkv {flex:1 1 140px;min-width:130px}
.pulse .sitecard {display:flex;flex-direction:column;gap:8px;border:1px solid var(--hairline);border-radius:11px;padding:11px 12px;background:var(--inset)}
.pulse .sitecard .sc1 {display:flex;justify-content:space-between;align-items:baseline}
.pulse .sitecard .sn {font-family:var(--disp);font-weight:600;font-size:13.5px}
.pulse .sitecard .sm {font-size:10.5px;color:var(--ink3)}
.pulse .sitecard .scv {font-family:var(--mono);font-size:11px;color:var(--ink2)}
.pulse .esg {display:flex;gap:14px}
.pulse .esg .e {flex:1}
.pulse .esg .ev {font-family:var(--disp);font-size:19px;font-weight:650}
.pulse .esg .el {font-size:10.5px;color:var(--ink3)}
/* tables */
.pulse .twrap {overflow-x:auto}
.pulse table.data {width:100%;border-collapse:collapse;font-size:12.5px;min-width:640px}
.pulse table.data th {font-family:var(--mono);font-size:9.5px;letter-spacing:.12em;text-transform:uppercase;color:var(--ink3);text-align:left;padding:8px 10px;border-bottom:1px solid var(--hairline2);white-space:nowrap}
.pulse table.data td {padding:8.5px 10px;border-bottom:1px solid var(--hairline);color:var(--ink2);white-space:nowrap}
.pulse table.data td.num, .pulse table.data th.num {text-align:right;font-family:var(--mono);font-variant-numeric:tabular-nums}
.pulse table.data tr:hover td {background:var(--tint-faint)}
.pulse table.data td:first-child {color:var(--ink);font-family:var(--mono)}
/* Period summary: two period rows, one column per measure. No min-width and
   wrapping headers so it also sits inside the narrow summaries column. */
.pulse table.data.periodtable {min-width:0}
.pulse table.data.periodtable th {white-space:normal}
.pulse table.data.periodtable td:first-child {white-space:normal}
.pulse .mbar {display:inline-flex;align-items:center;gap:8px}
.pulse .mbar .track {width:64px;height:5px;border-radius:3px;background:rgba(38,180,135,.15);position:relative;overflow:hidden}
.pulse .mbar .fill {position:absolute;inset:0 auto 0 0;border-radius:3px;background:var(--good)}
.pulse .mbar.w .track {background:rgba(206,143,20,.16)}
.pulse .mbar.w .fill {background:var(--warn)}
.pulse .stchip {display:inline-flex;align-items:center;gap:6px;font-family:var(--mono);font-size:9.5px;letter-spacing:.07em;text-transform:uppercase;padding:2.5px 8px;border-radius:6px}
.pulse .stchip .dot {width:6px;height:6px;border-radius:50%}
.pulse .stchip.gen {color:var(--good);background:var(--good-soft)}
.pulse .stchip.gen .dot {background:var(--good)}
.pulse .stchip.warn {color:var(--warn);background:var(--warn-soft)}
.pulse .stchip.warn .dot {background:var(--warn)}
.pulse .stchip.fault {color:var(--crit);background:var(--crit-soft)}
.pulse .stchip.fault .dot {background:var(--crit)}
.pulse .stchip.svc {color:var(--cyan);background:var(--cyan-soft)}
.pulse .stchip.svc .dot {background:var(--cyan)}
.pulse .stchip.ext {color:var(--ext);background:var(--ext-soft)}
.pulse .stchip.ext .dot {background:var(--ext)}
.pulse .stchip.info {color:var(--ink2);background:var(--tint)}
.pulse .stchip.info .dot {background:var(--ink3)}
/* site screen */
.pulse .sitegrid {display:grid;grid-template-columns:1.35fr 1fr;gap:12px}
.pulse .sitehead {display:grid;grid-template-columns:1fr auto;gap:18px;background:linear-gradient(160deg,rgba(46,159,214,.06),transparent 60%),var(--panel);border:1px solid var(--hairline2);border-radius:var(--r);padding:18px 20px;margin-bottom:12px}
.pulse .sitehead h2 {font-size:22px}
.pulse .sh-meta {display:flex;flex-wrap:wrap;margin-top:14px;padding-top:14px;border-top:1px solid var(--hairline)}
.pulse .sh-meta .m {flex:1 1 150px;padding-right:22px;font-family:var(--mono);font-size:10px;letter-spacing:.12em;text-transform:uppercase;color:var(--ink3)}
.pulse .sh-meta .m:not(:first-child) {padding-left:22px;border-left:1px solid var(--hairline)}
.pulse .sh-meta .m b {display:block;margin-top:7px;font-family:var(--mono);font-size:15px;letter-spacing:0;text-transform:none;font-weight:500;color:var(--ink)}
.pulse .sh-kpis {display:flex;gap:22px;align-items:center}
.pulse .sh-kpis .k {text-align:right}
.pulse .sh-kpis .kv {font-family:var(--disp);font-size:27px;font-weight:650}
.pulse .sh-kpis .kl {font-size:10.5px;color:var(--ink3);font-family:var(--mono);letter-spacing:.06em;text-transform:uppercase}
.pulse .metlist {display:flex;flex-direction:column}
.pulse .metlist .mrow {display:flex;justify-content:space-between;align-items:center;padding:8px 0;border-top:1px solid var(--hairline);font-size:12.5px;color:var(--ink2)}
.pulse .metlist .mrow:first-child {border-top:none}
.pulse .metlist .mv {font-family:var(--mono);color:var(--ink);font-size:12.5px}
.pulse .sitemap {position:relative}
.pulse .sitemap svg {width:100%;height:auto}
.pulse .smdot {stroke:var(--panel);stroke-width:1.6}
.pulse .smdot.gen {fill:var(--good)}
.pulse .smdot.fault {fill:var(--crit)}
.pulse .smdot.ext {fill:var(--ext)}
.pulse .smdot.warn {fill:var(--warn)}
.pulse .smdot.svc {fill:var(--cyan)}
.pulse .smlbl {fill:var(--ink3);font-family:var(--mono);font-size:8.5px}
.pulse .contour {fill:none;stroke:var(--tint);stroke-width:1.2}
.pulse .roadln {stroke:var(--tint-strong);stroke-width:1;stroke-dasharray:3 4;fill:none}
.pulse .banner {display:flex;gap:12px;align-items:flex-start;border:1px solid rgba(139,125,224,.3);background:var(--ext-soft);border-radius:11px;padding:11px 13px;font-size:12.5px;color:var(--ink2);margin-top:12px}
.pulse .banner b {color:var(--ink)}
.pulse .banner .bico {color:var(--ext);flex:none;padding-top:1px}
/* turbine screen */
.pulse .tgrid {display:grid;grid-template-columns:1.4fr 1fr;gap:12px}
.pulse .scadastrip {display:grid;grid-template-columns:repeat(auto-fit,minmax(118px,1fr));gap:1px;background:var(--hairline);border:1px solid var(--hairline);border-radius:var(--r);overflow:hidden;margin-bottom:12px}
.pulse .sc {background:var(--panel);padding:13px 14px}
.pulse .sc .scl {font-family:var(--mono);font-size:9px;letter-spacing:.14em;text-transform:uppercase;color:var(--ink3)}
.pulse .sc .scv {font-family:var(--disp);font-size:23px;font-weight:650;margin-top:4px}
.pulse .sc .scv small {font-size:12px;color:var(--ink2);font-weight:500}
.pulse .sc .scs {font-size:10.5px;margin-top:3px;color:var(--ink3);font-family:var(--mono)}
.pulse .sc.hot {background:linear-gradient(160deg,rgba(38,180,135,.1),var(--panel) 70%)}
.pulse .nacwrap {position:relative;aspect-ratio:640/302;margin-top:4px}
.pulse .nacwrap svg {position:absolute;inset:0;width:100%;height:100%}
.pulse .nac-o {stroke:var(--nac-outer);stroke-width:1.6;fill:var(--tint-faint)}
.pulse .nac-i {stroke:var(--nac-inner);stroke-width:1.3;fill:var(--tint-faint)}
.pulse .nac-x {stroke:var(--nac-detail);stroke-width:1.1}
.pulse .nac-fill {fill:rgba(46,159,214,.06)}
.pulse .pin {fill:var(--good);stroke:var(--panel);stroke-width:2}
.pulse .pin.warn {fill:var(--warn)}
.pulse .pinring {fill:none;stroke:var(--warn);stroke-width:1.4;transform-box:fill-box;transform-origin:center;animation:ping 2.4s ease-out infinite}
.pulse .leader {stroke:var(--leader);stroke-width:1;fill:none}
.pulse .callout {position:absolute;max-width:212px;background:var(--overlay);border:1px solid var(--hairline2);border-radius:9px;padding:8px 10px;font-size:11px;color:var(--ink2);backdrop-filter:blur(4px)}
.pulse .callout b {display:block;color:var(--ink);font-size:11.5px;margin-bottom:2px}
.pulse .callout .cv {display:block;font-family:var(--mono);font-size:10.5px;margin-top:3px}
.pulse .callout.warn {border-color:rgba(206,143,20,.4)}
.pulse .callout.warn b {color:var(--warn)}
.pulse .dimline {stroke:var(--ink3);stroke-width:.8}
.pulse .dimlbl {fill:var(--ink3);font-family:var(--mono);font-size:8.5px}
.pulse .thermos {display:flex;gap:14px;justify-content:space-between}
.pulse .th {display:flex;flex-direction:column;align-items:center;gap:8px;flex:1}
.pulse .th .track {width:14px;height:96px;border-radius:8px;background:rgba(46,159,214,.12);position:relative;overflow:hidden}
.pulse .th .fill {position:absolute;left:0;right:0;bottom:0;border-radius:8px;background:var(--cyan)}
.pulse .th.warm .track {background:rgba(206,143,20,.14)}
.pulse .th.warm .fill {background:var(--warn)}
.pulse .th .alarmtick {position:absolute;left:-3px;right:-3px;height:1px;background:rgba(220,68,56,.6)}
.pulse .th .tv {font-family:var(--mono);font-size:11.5px;color:var(--ink)}
.pulse .th .tl {font-size:9.5px;color:var(--ink3);text-align:center;line-height:1.25;font-family:var(--mono);letter-spacing:.02em}
.pulse .hlist .hrow {display:flex;align-items:center;gap:10px;padding:8px 0;border-top:1px solid var(--hairline);font-size:12.5px;color:var(--ink2)}
.pulse .hlist .hrow:first-child {border-top:none}
.pulse .hlist .hname {flex:1}
.pulse .hlist .hv {font-family:var(--mono);font-size:11px;color:var(--ink3)}
.pulse .timeline {position:relative;padding-left:20px}
.pulse .timeline::before {content:"";position:absolute;left:5px;top:6px;bottom:6px;width:1px;background:var(--hairline2)}
.pulse .tl-i {position:relative;padding:9px 0}
.pulse .tl-i::before {content:"";position:absolute;left:-19px;top:14px;width:9px;height:9px;border-radius:50%;background:var(--panel);border:2px solid var(--good)}
.pulse .tl-i.warn::before {border-color:var(--warn)}
.pulse .tl-i.info::before {border-color:var(--cyan)}
.pulse .tl-i .tld {font-family:var(--mono);font-size:10px;color:var(--ink3)}
.pulse .tl-i .tlt {font-size:12.5px;color:var(--ink);margin-top:2px}
.pulse .tl-i .tls {font-size:11.5px;color:var(--ink2);margin-top:2px}
.pulse .factgrid {display:grid;grid-template-columns:1fr 1fr;gap:0 18px}
/* service screen */
.pulse .svcgrid {display:grid;grid-template-columns:1.45fr 1fr;gap:12px}
.pulse .slatiles {display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:12px;margin-bottom:12px}
.pulse .wo {border:1px solid var(--hairline);border-radius:12px;padding:13px 14px;background:var(--inset);margin-bottom:10px}
.pulse .wo:last-child {margin-bottom:0}
.pulse .wo .wo1 {display:flex;justify-content:space-between;gap:10px;align-items:center;flex-wrap:wrap}
.pulse .wo .woid {font-family:var(--mono);font-size:11px;color:var(--ink3)}
.pulse .wo .wot {font-size:13.5px;font-weight:600;color:var(--ink);margin-top:3px}
.pulse .wo .wos {font-size:11.5px;color:var(--ink2);margin-top:4px}
.pulse .wo .prog {margin-top:10px;display:flex;align-items:center;gap:10px}
.pulse .wo .ptrack {flex:1;height:5px;border-radius:3px;background:rgba(38,180,135,.14);overflow:hidden;position:relative}
.pulse .wo .pfill {position:absolute;inset:0 auto 0 0;background:var(--good);border-radius:3px}
.pulse .wo .pv {font-family:var(--mono);font-size:10.5px;color:var(--ink2)}
.pulse .cal {display:grid;grid-template-columns:repeat(7,1fr);gap:5px}
.pulse .cal .cd {border:1px solid var(--hairline);border-radius:8px;padding:6px 7px;min-height:52px;font-family:var(--mono);font-size:10px;color:var(--ink3);position:relative}
.pulse .cal .cd.today {border-color:rgba(210,179,114,.5);background:var(--gold-dim)}
.pulse .cal .cd.past {opacity:.55}
.pulse .cal .cdd {display:flex;gap:3px;flex-wrap:wrap;margin-top:5px}
.pulse .cal .m {width:7px;height:7px;border-radius:50%}
.pulse .cal .m.svc, .pulse .callegend .m.svc {background:var(--cyan)}
.pulse .cal .m.brk, .pulse .callegend .m.brk {background:var(--crit)}
.pulse .cal .m.insp, .pulse .callegend .m.insp {background:var(--warn)}
.pulse .cal .m.lep, .pulse .callegend .m.lep {background:var(--good)}
.pulse .callegend {display:flex;gap:13px;flex-wrap:wrap;margin-top:11px;font-family:var(--mono);font-size:9.5px;letter-spacing:.06em;text-transform:uppercase;color:var(--ink2)}
.pulse .callegend .li {display:flex;gap:6px;align-items:center}
.pulse .callegend .m {width:7px;height:7px;border-radius:50%}
/* analytics */
.pulse .angrid {display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:12px;align-items:start}
.pulse .sitegrid>*, .pulse .tgrid>*, .pulse .svcgrid>*, .pulse .angrid>*, .pulse .notesgrid>*, .pulse .sitegrid .card, .pulse .tgrid .card, .pulse .svcgrid .card {min-width:0}
.pulse .pareto .prow {display:grid;grid-template-columns:150px 1fr 92px;gap:12px;align-items:center;padding:7px 0}
.pulse .pareto .pl {font-size:12px;color:var(--ink2)}
.pulse .pareto .ptrack {height:14px;border-radius:4px;position:relative}
.pulse .pareto .pfill {position:absolute;left:0;top:0;bottom:0;border-radius:0 4px 4px 0;background:var(--cyan)}
.pulse .pareto .pv {font-family:var(--mono);font-size:11px;color:var(--ink2);text-align:right}
.pulse .seg {display:flex;gap:3px;margin-top:12px}
.pulse .seg .s {flex:1;height:26px;border-radius:5px;background:rgba(46,159,214,.1);position:relative;overflow:hidden}
.pulse .seg .s .f {position:absolute;inset:0;background:var(--cyan);border-radius:5px}
.pulse .seg .s.part .f {width:55%}
.pulse .seg .s span {position:absolute;bottom:-19px;left:50%;transform:translateX(-50%);font-family:var(--mono);font-size:8.5px;color:var(--ink3)}
.pulse .reportrow {display:flex;justify-content:space-between;align-items:center;gap:10px;padding:10px 0;border-top:1px solid var(--hairline)}
.pulse .reportrow:first-child {border-top:none}
.pulse .reportrow .rn {font-size:13px;color:var(--ink)}
.pulse .reportrow .rm {font-family:var(--mono);font-size:10.5px;color:var(--ink3);margin-top:2px}
/* design notes */
.pulse .notesgrid {display:grid;grid-template-columns:repeat(auto-fit,minmax(310px,1fr));gap:12px}
.pulse .plist {counter-reset:p;display:flex;flex-direction:column}
.pulse .plist .pi {display:flex;gap:13px;padding:10px 0;border-top:1px solid var(--hairline);font-size:12.5px;color:var(--ink2)}
.pulse .plist .pi:first-child {border-top:none}
.pulse .plist .pi::before {counter-increment:p;content:counter(p,decimal-leading-zero);font-family:var(--mono);font-size:11px;color:var(--gold);padding-top:1px}
.pulse .plist .pi b {color:var(--ink)}
.pulse .palrow {display:flex;gap:8px;flex-wrap:wrap;margin-top:6px}
.pulse .palrow .p {display:flex;flex-direction:column;gap:5px;align-items:center;font-family:var(--mono);font-size:9px;color:var(--ink3)}
.pulse .palrow .sw2 {width:44px;height:26px;border-radius:7px;border:1px solid var(--hairline2)}
/* tooltip */
.pulse #tip {position:fixed;z-index:200;pointer-events:none;background:var(--overlay);border:1px solid var(--hairline2);border-radius:8px;padding:7px 10px;font-family:var(--mono);font-size:11px;color:var(--ink);opacity:0;transition:opacity .12s;max-width:230px}
.pulse #tip .t1 {color:var(--ink3);font-size:9.5px;letter-spacing:.08em;text-transform:uppercase}
.pulse #tip .t2 {font-size:12.5px;margin-top:2px}
.pulse #tip .t3 {color:var(--ink2);font-size:10px;margin-top:2px}
/* footer */
.pulse .foot {margin-top:26px;padding-top:14px;border-top:1px solid var(--hairline);display:flex;justify-content:space-between;gap:14px;flex-wrap:wrap;font-size:11px;color:var(--ink3)}
.pulse .foot .mono {font-size:10px}
/* responsive */
@media (max-width:1180px) {
.pulse .ov-hero {grid-template-columns:1fr 1fr}
.pulse .hero {grid-column:span 2}
.pulse .ov-grid {grid-template-columns:1fr 1fr}
.pulse .rail {grid-row:auto;grid-column:span 2}
.pulse .sitegrid, .pulse .tgrid, .pulse .svcgrid, .pulse .angrid {grid-template-columns:1fr}
}
@media (max-width:900px) {
.pulse #app.on {grid-template-columns:1fr}
.pulse .side {position:static;height:auto;border-right:none;border-bottom:1px solid var(--hairline)}
.pulse .nav {flex-direction:row;overflow-x:auto;padding:6px 10px}
.pulse .navlbl, .pulse .side .roc {display:none}
.pulse .navbtn {white-space:nowrap}
.pulse .lg-main {grid-template-columns:1fr;padding-top:30px}
.pulse .lg-stats {flex-wrap:wrap}
.pulse .lg-stats .ls {flex:1 1 40%;padding:13px 22px}
}
@media (max-width:640px) {
.pulse .chip {white-space:normal}
.pulse .content {padding:16px 14px 40px}
.pulse .topbar {padding:10px 14px;flex-wrap:wrap}
.pulse .tb-clock, .pulse .avatar .meta {display:none}
.pulse .ov-hero {grid-template-columns:1fr 1fr}
.pulse .hero .hv {font-size:44px}
.pulse .ov-grid {grid-template-columns:1fr}
.pulse .rail {grid-column:auto}
.pulse .span2 {grid-column:auto}
.pulse .sh-kpis {flex-wrap:wrap;gap:14px}
.pulse .sitehead {grid-template-columns:1fr}
.pulse .board {grid-template-columns:repeat(auto-fill,minmax(96px,1fr))}
.pulse .thermos {flex-wrap:wrap;gap:10px}
.pulse .callout {position:static;max-width:none;margin-top:8px}
.pulse .nacwrap {aspect-ratio:auto}
.pulse .nacwrap svg {position:static}
}
@media (prefers-reduced-motion:reduce) {
.pulse .rot, .pulse .rotoricon use, .pulse .endpulse, .pulse .pinring, .pulse .chip.live .dot, .pulse .roc .rt .dot, .pulse .windline {animation:none !important}
}
.pulse .is-hidden {display:none!important}
.pulse .crm-return {color:var(--ink2);text-decoration:none}
.pulse .crm-return:hover {color:var(--gold);border-color:rgba(210,179,114,.35)}
.pulse [wire\:loading].pulse-loading {display:inline-flex;align-items:center;gap:7px}

/* ------------------------------------------------------------------
   Embedded mode — the portal rendered inside a Filament panel page.
   Filament owns the sidebar, topbar and page scroll, so the standalone
   shell rules are neutralised here.
   ------------------------------------------------------------------ */
.pulse.is-embedded { min-height:0; background:transparent; }
.pulse.is-embedded .main { display:block; }
.pulse.is-embedded .content { padding:0 0 8px; }
.pulse.is-embedded .toolrow { margin-top:0; }
@media (max-width:900px){
  .pulse.is-embedded .content { padding:0 0 8px; }
}

/* Status split inside the Fleet KPI card. Sits on the .kd row, which is
   already a wrapping flex line, so this only needs to keep each dot glued to
   its own count and stop a long split from breaking mid-label. */
.pulse .fleetstates {display:flex;flex-wrap:wrap;gap:3px 10px;width:100%}
.pulse .fleetstates .fs {display:inline-flex;align-items:center;gap:5px;white-space:nowrap;color:var(--ink2)}
.pulse .fleetstates .dot {width:6px;height:6px;border-radius:50%;flex:none}

/* Turbine status card (drill-down screen). Sits under the generation chart to
   square the two columns, so it is sized to read at a glance rather than to
   pack in rows. */
.pulse .tstate {display:flex;align-items:center;gap:12px;padding:4px 0 14px}
.pulse .tsdot {width:17px;height:17px;border-radius:50%;flex:none;box-shadow:0 0 0 4px var(--tint-soft)}
.pulse .tstext {display:flex;flex-direction:column;gap:2px;min-width:0}
.pulse .tstext b {font-family:var(--disp);font-size:23px;font-weight:650;line-height:1.1}
.pulse .tstext span {font-size:11.5px;color:var(--ink3)}
.pulse .tsmeta {margin:0;display:grid;gap:0;border-top:1px solid var(--hairline)}
.pulse .tsmeta > div {display:flex;justify-content:space-between;align-items:baseline;gap:14px;padding:8px 0;border-bottom:1px solid var(--hairline)}
.pulse .tsmeta > div:last-child {border-bottom:0}
.pulse .tsmeta dt {font-size:11.5px;color:var(--ink3)}
.pulse .tsmeta dd {margin:0;font-size:12.5px;font-weight:600;color:var(--ink);text-align:right;min-width:0}

/* Deficit reading on the contract card. Sits beside .v.good, which already
   carries the surplus case. */
.pulse .kvrow .v.crit {color:var(--crit)}

/* ------------------------------------------------------------------
   ApexCharts on the Pulse screens (Production Year, MAP, GAP).

   The panel theme hides Apex legends and toolbars outright — see
   .apexcharts-legend-text in resources/css/filament/crm/theme.css, which
   the widget dashboards rely on. These re-enable them for Pulse cards
   only: scoped under .pulse, so specificity beats the global rule
   without touching any other chart in the app.
   ------------------------------------------------------------------ */
/* The series is laid out as a flex row with its own gap, and the text's
   padding zeroed. ApexCharts sizes that padding from the marker it thinks it
   drew; with the theme's display:none in play that measurement is wrong and
   the marker lands on top of the first character. */
.pulse .apexcharts-legend-series {display:inline-flex !important;align-items:center;gap:7px}
.pulse .apexcharts-legend-text {display:inline-block !important;color:var(--ink2) !important;font-family:inherit !important;font-size:11.5px !important;padding-left:0 !important}
/* Pinned rather than left where Apex computed it: it positions the toolbar
   from the width it measured at render, so a card that resized afterwards got
   its export button parked over the plot or past the card edge. */
.pulse .apexcharts-toolbar {display:flex !important;position:absolute !important;top:6px !important;right:10px !important;left:auto !important;opacity:.55;z-index:3}
.pulse .apexcharts-toolbar:hover {opacity:1}
/* Belt and braces for the same measurement problem: never let the drawing
   paint wider than the card holding it. */
.pulse .apexcharts-canvas {max-width:100% !important}
/* The export menu was only ever hidden by its parent toolbar being display:none.
   Unhiding the toolbar exposed it, so it now states its own closed position. */
.pulse .apexcharts-menu {opacity:0;visibility:hidden;pointer-events:none;background:var(--inset) !important;border:1px solid var(--hairline2) !important;border-radius:8px !important;padding:4px !important}
.pulse .apexcharts-menu.apexcharts-menu-open {opacity:1;visibility:visible;pointer-events:auto}
.pulse .apexcharts-menu-item {color:var(--ink2) !important;font-family:inherit !important;font-size:11.5px !important;border-radius:5px}
.pulse .apexcharts-menu-item:hover {background:var(--hairline) !important;color:var(--ink) !important}
/* The library writes its tooltip into a light default; the portal is dark. */
.pulse .apexcharts-tooltip {background:var(--inset) !important;border:1px solid var(--hairline2) !important;color:var(--ink) !important;box-shadow:0 8px 26px rgba(0,0,0,.4) !important}
.pulse .apexcharts-tooltip-title {background:var(--inset) !important;border-bottom:1px solid var(--hairline) !important;color:var(--ink2) !important;font-family:inherit !important}
.pulse .apexcharts-xaxistooltip {display:none !important}

/* Full-width chart band under the two-column split. Production Year spans the
   row; the two availability charts halve it. Keeping them out of .ov-split is
   what lets the right-hand summary column stop at the generation chart instead
   of being stretched down to match three more cards. */
.pulse .chartband > .card {margin-bottom:12px}
.pulse .chartrow {display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;margin-bottom:12px}
.pulse .chartrow > * {min-width:0}
@media (max-width:1100px) {
  .pulse .chartrow {grid-template-columns:1fr}
}
