/* Graphite / aurum. Presentation only; no external assets or animation loop. */
:root {
    --depth-edge: rgba(187, 212, 241, .22);
    --depth-gold: #ffdb83;
    --depth-cyan: #89d9ff;
    --depth-face: linear-gradient(145deg, #303c4e 0%, #1a2433 42%, #101722 100%);
    --icon-receipt: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 3l3 2 3-2 3 2 3-2v18l-3-2-3 2-3-2-3 2zM9 9h6M9 13h6'/%3E%3C/svg%3E");
    --icon-wallet: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.7' stroke-linejoin='round'%3E%3Cpath d='M4 7V5l14-2v4M4 7h16v14H4a2 2 0 0 1-2-2V9a2 2 0 0 1 2-2zM20 11h-6v6h6'/%3E%3Ccircle cx='17' cy='14' r='.8'/%3E%3C/svg%3E");
    --icon-coins: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.7'%3E%3Cellipse cx='9' cy='6' rx='6' ry='3'/%3E%3Cpath d='M3 6v5c0 4 12 4 12 0V6M3 11v5c0 3 7 4 10 2M15 10c8-1 8 6 2 6-2 0-4-1-4-3M13 13v5c0 4 9 4 9 0v-5'/%3E%3C/svg%3E");
    --icon-bolt: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'%3E%3Cpath d='M13 1L4 14h7l-1 9 10-14h-7z'/%3E%3C/svg%3E");
}

/* The edge, dark lower lip and soft cast shadow give each shell real depth. */
#pageCameras .cam-sidebar-card,
#pageLive .bar-card,
#pageCameras .solar-widget,
#solarPageContent .dm-solar {
    border: 1px solid var(--depth-edge);
    border-radius: 18px;
    background: radial-gradient(ellipse at 2% 0%, rgba(160,197,236,.14), transparent 58%),
                linear-gradient(150deg, #232d3b, #131c28 62%, #101722);
    background-blend-mode: normal;
    box-shadow: inset 0 1px 0 rgba(255,255,255,.15), inset 0 -2px 0 #070c13,
                0 3px 0 #080e17, 0 5px 0 rgba(116,146,183,.14),
                0 13px 22px rgba(0,0,0,.42);
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
}
#pageCameras .cam-sidebar-card::before,
#pageLive .bar-card::before,
#pageCameras .solar-widget::before,
#solarPageContent .dm-solar::before { display: none; }
#pageCameras .cam-right { padding: 5px 8px 15px; }
/* Let the sidebar lay out each card directly. A shrinking wrapper could become
   shorter than its two minimum-height cards and place solar over Shooters. */
#pageCameras #camSidebarBars { display: contents; }
#pageCameras .cam-sidebar-card { padding: 9px; margin-bottom: 13px; }
#camSidebarBars .cam-sidebar-card { min-height: 210px; }

/* Gold ingot, inset lettering and an embossed coin emblem. */
#camCombinedTotal, #combinedTotal {
    position: relative;
    overflow: hidden;
    border: 1px solid #ffe5a6;
    border-bottom-color: #916221;
    border-radius: 13px;
    padding: 12px 12px 12px 42px;
    color: #352109;
    background: radial-gradient(ellipse at 25% 0, #fff1bf, transparent 60%),
                linear-gradient(112deg, #b57c27, #f6d57b 26%, #e5b34f 60%, #b7822f);
    box-shadow: inset 0 1px 0 #fff3c7, inset 0 -2px 0 #98651b,
                0 3px 0 #644313, 0 5px 0 #080d14, 0 9px 18px #0006;
    font-size: 14px;
    font-weight: 850;
    letter-spacing: .6px;
    text-align: center;
    text-shadow: 0 1px 0 #fff0b2;
    white-space: normal;
}
#camCombinedTotal::before, #combinedTotal::before {
    content: ""; position: absolute; left: 13px; top: 50%; width: 22px; height: 22px;
    transform: translateY(-50%); background: #654315;
    mask: var(--icon-coins) center / contain no-repeat;
    -webkit-mask: var(--icon-coins) center / contain no-repeat;
}
#pageCameras #camCombinedTotal { margin-bottom: 16px; }

/* Two-level nameplate keeps long venue names away from the sales value. */
.cam-sidebar-hero.rhino, .cam-sidebar-hero.shooters,
.bar-hero.rhino, .bar-hero.shooters {
    display: grid;
    grid-template-columns: 28px minmax(0, 1fr) auto;
    grid-template-rows: auto auto;
    column-gap: 8px; row-gap: 2px;
    padding: 8px 9px; margin-bottom: 8px;
    border: 1px solid #8198b440; border-radius: 11px;
    color: #eaf3ff; background: linear-gradient(135deg, #354b64, #1c2b40 65%);
    box-shadow: inset 0 1px 0 #ffffff25, inset 0 -1px 0 #0008, 0 3px 6px #0005;
    text-shadow: 0 1px 2px #0008;
    letter-spacing: .5px;
    white-space: normal;
}
.cam-sidebar-hero.shooters, .bar-hero.shooters {
    background: linear-gradient(135deg, #713947, #371e2c 70%);
    border-color: #d391a040;
}
#pageLive .bar-hero { width: 100%; }
.cam-sidebar-hero::before, .bar-hero::before {
    content: ""; grid-column: 1; grid-row: 1 / 3; width: 27px; height: 30px;
    background: var(--depth-cyan);
    mask: var(--icon-wallet) center / 24px no-repeat;
    -webkit-mask: var(--icon-wallet) center / 24px no-repeat;
    filter: drop-shadow(0 2px 1px #0008);
}
.cam-sidebar-hero.shooters::before, .bar-hero.shooters::before { background: #ffa4b5; }
.cam-sidebar-hero > span:first-child, .bar-hero > span:first-child {
    grid-column: 2; grid-row: 1; text-align: left; font-size: 11px; overflow-wrap: anywhere;
}
.cam-sidebar-hero .tl, .bar-hero .tl {
    grid-column: 2; grid-row: 2; text-align: left; font-size: 7px; letter-spacing: 1.5px;
    color: #c1cddd; opacity: 1;
}
.cam-sidebar-hero .amt, .bar-hero .amt {
    grid-column: 3; grid-row: 1 / 3; align-self: center;
    font-size: 15px; font-weight: 800; color: var(--depth-gold); letter-spacing: -.4px;
    text-shadow: 0 2px 2px #0009; font-variant-numeric: tabular-nums;
}
.cam-sidebar-section { gap: 7px; margin-top: 0; }
.cam-sidebar-col, #pageLive .column { min-width: 0; }
.cam-sidebar-col-header, #pageLive .col-header {
    display: flex; justify-content: center; align-items: center; gap: 4px;
    min-height: 25px; padding: 4px 3px; border-radius: 7px;
    font-size: 8px; letter-spacing: .5px;
}
.cam-sidebar-col-header.tabs, #pageLive .col-header.tabs,
.cam-sidebar-col-header.expenses, #pageLive .col-header.expenses,
.cam-sidebar-col-header.payouts, #pageLive .col-header.payouts {
    border: 1px solid color-mix(in srgb, currentColor 24%, transparent);
    background: linear-gradient(180deg, #ffffff0d, #00000012), #18212e;
    box-shadow: inset 0 1px 0 #ffffff12, 0 2px 3px #0006;
    text-shadow: 0 1px 1px #000;
}
.cam-sidebar-col-header.tabs, #pageLive .col-header.tabs { color: #ffa091; }
.cam-sidebar-col-header.expenses, #pageLive .col-header.expenses { color: #87d5ff; }
.cam-sidebar-col-header.payouts, #pageLive .col-header.payouts { color: #d5afff; }
.cam-sidebar-col-header::before, #pageLive .col-header::before {
    content: ""; display: inline-block; flex: 0 0 13px; height: 13px; background: currentColor;
    mask: var(--section-icon) center / contain no-repeat;
    -webkit-mask: var(--section-icon) center / contain no-repeat;
}
.tabs { --section-icon: var(--icon-receipt); }
.expenses { --section-icon: var(--icon-wallet); }
.payouts { --section-icon: var(--icon-coins); }
.cam-sidebar-labels, .cam-sidebar-payout-labels { background: transparent; font-size: 7px; padding: 3px 1px; }
.cam-sidebar-list {
    background: linear-gradient(180deg, #070e1880, #10192440); border-radius: 5px;
    box-shadow: inset 0 1px 3px #0004; min-height: 42px;
}
.cam-sidebar-row, .cam-sidebar-payout-row { padding: 3px 2px; border-bottom: 1px solid #ffffff06; }
.cam-sidebar-row > span:first-child { min-width: 0; overflow-wrap: anywhere; }
.cam-sidebar-row > span:last-child { flex-shrink: 0; }
.cam-sidebar-total { padding-top: 5px; font-size: 10px; text-shadow: 0 1px 1px #000; }
.cam-sidebar-float {
    border-top: 1px solid #ffffff0c; margin-top: 5px; padding-top: 5px;
    color: #ddbc84; font-size: 8px; letter-spacing: .05px;
}

/* Inverters are raised instrument pods; the figures sit in recessed displays. */
#pageCameras .solar-widget { margin-top: 2px; padding: 10px 10px 6px; }
.solar-widget-title { color: #ffda88; letter-spacing: 1.8px; margin-bottom: 8px; font-size: 10px; text-shadow: 0 2px 3px #000; }
.dm-todcanvas { filter: drop-shadow(0 2px 3px #0008); }
.dm-gauges { gap: 12px; }
.dm-inv {
    position: relative; min-width: 126px; padding: 8px 9px 9px;
    border: 1px solid #8aa3c02e; border-radius: 13px;
    background: radial-gradient(ellipse at 20% 0, #ffffff0c, transparent 65%), var(--depth-face);
    box-shadow: inset 0 1px 0 #ffffff1f, inset 0 -2px 0 #080f19,
                0 3px 0 #070d16, 0 7px 10px #0006;
}
.dm-inv::after {
    content: ""; position: absolute; top: 10px; right: 9px; width: 4px; height: 4px;
    border: 1px solid #080e18; border-radius: 50%; background: #687789;
    box-shadow: inset 0 1px 0 #ccd8e8, 0 1px 1px #000;
}
.dm-name { color: #d4deec; font-size: 9px; letter-spacing: 2px; margin: 0 0 4px; }
.dm-gwrap { gap: 1px; }
.dm-trend.flat { color: #93a6bd; }
.dm-stats {
    max-width: none; padding: 4px 1px; margin-top: 4px; border: 1px solid #080e17;
    border-radius: 7px; background: #0b121d;
    box-shadow: inset 0 2px 4px #0009, 0 1px 0 #ffffff0f;
}
.dm-stat { padding: 2px 5px; font-size: 11px; }
.dm-stat .lbl { color: #a4b5cc; font-size: 8px; }
.dm-stat .lbl::before {
    content: ""; display: inline-block; width: 9px; height: 10px; margin-right: 4px;
    vertical-align: -1px; background: currentColor;
    mask: var(--icon-bolt) center / contain no-repeat;
    -webkit-mask: var(--icon-bolt) center / contain no-repeat;
}
.dm-netrow { margin-top: 7px; gap: 5px; }
.dm-net.up, .dm-net.dn, .dm-yield {
    border: 1px solid #ffffff20;
    box-shadow: inset 0 1px 0 #ffffff30, inset 0 -1px 0 #0008, 0 2px 3px #0007;
    padding: 3px 7px; font-size: 9px; text-shadow: 0 1px 2px #000;
}
.dm-net.up { background: linear-gradient(#326c57, #183c2e); color: #b6ffd5; }
.dm-net.dn { background: linear-gradient(#874a42, #492720); color: #ffd0c5; }
.dm-yield { background: linear-gradient(#886c2d, #453618); color: #ffe49b; }
.dm-sep { margin: 12px 8px 5px; }
.dm-wx-item {
    padding: 5px 7px; border: 1px solid #91a6c026; border-radius: 8px;
    background: linear-gradient(145deg, #2d3b50, #141e2c);
    box-shadow: inset 0 1px 0 #ffffff12, 0 2px 0 #080e16, 0 4px 6px #0004;
}
.dm-wx-item svg { filter: drop-shadow(0 1px 2px #0007); }
.dm-status { color: #91a1b7; padding-top: 5px; }

/* Matching sculpted icon keys across the existing navigation. */
.nav-btn .nav-icon {
    display: flex; align-items: center; justify-content: center;
    width: 35px; height: 32px; border-radius: 10px;
    border: 1px solid #b5cbe421; background: linear-gradient(145deg, #354156, #151e2d);
    box-shadow: inset 0 1px 0 #ffffff21, 0 3px 0 #080f19, 0 5px 7px #0005;
    font-size: 19px; text-shadow: 0 2px 3px #0008;
}
.nav-btn.active .nav-icon {
    border-color: #f1c46f80; background: linear-gradient(145deg, #705b33, #312819);
    box-shadow: inset 0 1px 0 #ffe7ac55, 0 3px 0 #120f09, 0 0 15px #efb33d24;
}
:is(.nav-btn, .refresh-btn, .notif-btn, .cam-ibtn, .hc-chip):focus-visible {
    outline: 2px solid #ffdb83; outline-offset: 3px;
}
@media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {
    .dm-inv { transition: transform 180ms ease, box-shadow 180ms ease; }
    .dm-inv:hover { transform: translateY(-3px); box-shadow: inset 0 1px 0 #ffffff30, 0 4px 0 #070d16, 0 12px 16px #0007; }
    .nav-btn:hover .nav-icon { transform: translateY(-2px); }
}
@media (max-width: 420px) {
    #combinedTotal { max-width: 145px; font-size: 10px; padding: 7px 7px 7px 27px; letter-spacing: 0; }
    #combinedTotal::before { left: 7px; width: 16px; height: 16px; }
    #pageLive .col-labels, #pageLive .payout-labels { font-size: 6px; gap: 2px; letter-spacing: 0; }
    .bar-hero.rhino, .bar-hero.shooters { grid-template-columns: 20px minmax(0, 1fr) auto; gap: 3px 5px; padding: 7px 6px; }
    .bar-hero::before { width: 20px; }
    .bar-hero > span:first-child { font-size: 10px; }
    .bar-hero .amt { font-size: 13px; }
    #pageLive .col-header { font-size: 7px; letter-spacing: 0; }
}
@media (prefers-reduced-motion: reduce) {
    .solar-widget, .dm-inv, .nav-btn .nav-icon { transition: none !important; transform: none !important; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   PHONE — MACHINE PAYOUTS COLUMN FIT (2026-09-05)
   Polly, on a 360-412px phone: "the machine payouts does not look right,
   everywhere else it is fine."  Measured cause, not a guess:

   Every .payout-row is its OWN grid, sized `1fr 1fr minmax(5.8em,auto) 2.9em`.
   `1fr` is minmax(AUTO,1fr), so the Mach/Client tracks refuse to shrink below
   their text. In a 106px column the fixed part (52.2px Amt + 26.1px Type +
   3 gaps) left ~20px for two names needing 35-45px, so each row overflowed by
   7-35px and .col-list — overflow-y:auto, which forces overflow-x:auto —
   clipped the right edge: "R 300.00 CAS". Per-row grids made it ragged, short
   names (Awie) surviving while longer ones (Sammy, Wayne) lost their type.

   Fix is geometry only, phones only:
   - The payouts column carries FOUR fields against the other two columns' two,
     so it gets the width to match. Tabs/expenses were measured with 27-44px of
     slack and wrap long names exactly as they already did.
   - Mach sizes to its content (1.1em floor keeps 1- and 2-digit machine numbers
     lined up between rows), Client takes the rest and can shrink,
     Amt/Type are pinned in px so the 6px label strip lines up with the 9px rows.
   - Amt is minmax(): money grows before it ever truncates — verified against the
     largest payout on record (R 7,000) in bold-red tier.
   Measured after: zero overflow at 320/360/375/412px; desktop geometry byte-identical. */
@media (max-width: 620px) {
    /* 4 fields vs 2 — the payouts column needs the width more than its neighbours */
    #pageLive .columns > .column:nth-child(3) { flex: 1.35; }
    #pageLive .payout-row, #pageLive .payout-labels {
        grid-template-columns: minmax(1.1em, auto) minmax(0, 1fr) minmax(34px, auto) 25px;
        gap: 2px; }
}
/* A long client name must never shove Amt/Type off the row again — it ellipsizes
   instead. No-op wherever the row already fits, so desktop and the camera rail are
   untouched apart from the same overflow case (measured: cameras row heights and
   card heights unchanged). */
.payout-row > span, .payout-labels > span,
.cam-sidebar-payout-row > span, .cam-sidebar-payout-labels > span {
    min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* ...but ellipsis is a safety net, not a layout. On the camera rail the payout grid was
   handing 26px to a ONE-CHARACTER machine number (`1fr 1fr` splits the leftover evenly, so
   Mach got exactly as much as Client) and 52px to an amount that needs 32 now the cents are
   gone — leaving Client 26px and truncating "Sammy" in a card with room to spare. Polly saw
   it immediately: "there is more than enough space for the payout names, why did you cut it
   off." So the space goes where the content is: Mach sizes to its digits, Amt/Type get what
   they measure (R 7,000 in bold = 31.5px, CASH = 22.5px) in px so the 7px label strip lines
   up with the 9px rows, and the client name takes everything left over.
   Measured at 1920: client track 26px -> 59px, five truncated names -> none, and the card's
   own column widths (143/103/143), card heights and rail fit are byte-identical either way. */
#pageCameras .cam-sidebar-payout-row, #pageCameras .cam-sidebar-payout-labels {
    grid-template-columns: minmax(1.1em, auto) minmax(0, 1fr) minmax(36px, auto) 25px; }
/* Same guarantee for the tab/expense rows: the money keeps its own line and its own
   width, the description wraps around it as it always has. Without this a 13-character
   customer ("Jacques Maand") squeezed the amount until "R 1,240" broke across two lines. */
#pageLive .col-row > span:last-child { flex: 0 0 auto; white-space: nowrap; }

/* ═══════════════════════════════════════════════════════════════════════════
   FIT-TO-SCREEN COMPACT PASS (2026-09-05)
   The graphite/aurum rules above unknowingly reverted the 2026-07-15 compact
   pass in index.html, so the camera sidebar (COMBINED + 2 bar cards + solar)
   no longer fit one screen below ~1000px of viewport height and scrolled.
   This block restores the tighter geometry ONLY — every gradient, border,
   shadow, mask and colour from the design above is untouched, so the look is
   identical, just denser.
   Two rules for anything added here:
     1. Never set background / box-shadow / border / color — geometry only.
     2. Scope to #pageCameras. Only the camera sidebar is fit-to-screen; the
        Live and Solar pages scroll by design and Polly signed those off as-is.
   Delete this block to get the roomier (overflowing) sizing back.
   ═══════════════════════════════════════════════════════════════════════════ */

/* Rail: the 15px bottom lip was dead space under the last card. */
#pageCameras .cam-right { padding: 4px 8px 7px; }

/* Gold plaque: same ingot, less air around the lettering. */
#pageCameras #camCombinedTotal { padding: 7px 12px 7px 38px; margin-bottom: 8px; }
#pageCameras #camCombinedTotal::before { left: 11px; width: 19px; height: 19px; }

/* Bar cards. min-height governs the card, so it has to come down with the
   padding or the shells just keep their old height. 178px still clears the
   hero + column headers + a 38px list + totals + float strip; when the screen
   is tall the flex row hands the surplus back to the lists. */
#pageCameras .cam-sidebar-card { padding: 7px; margin-bottom: 7px; }
#pageCameras #camSidebarBars .cam-sidebar-card { min-height: 178px; }

/* Nameplate: the 30px wallet icon set the floor here, so it scales too. */
#pageCameras .cam-sidebar-hero.rhino,
#pageCameras .cam-sidebar-hero.shooters { padding: 5px 9px; margin-bottom: 5px; }
#pageCameras .cam-sidebar-hero::before {
    width: 24px; height: 26px;
    mask: var(--icon-wallet) center / 21px no-repeat;
    -webkit-mask: var(--icon-wallet) center / 21px no-repeat;
}

/* Column chrome inside the cards. */
#pageCameras .cam-sidebar-col-header { min-height: 21px; padding: 2px 3px; }
#pageCameras .cam-sidebar-labels,
#pageCameras .cam-sidebar-payout-labels { padding: 2px 1px; }
#pageCameras .cam-sidebar-list { min-height: 38px; }
#pageCameras .cam-sidebar-total { padding-top: 3px; }
#pageCameras .cam-sidebar-float { margin-top: 4px; padding-top: 3px; }

/* Solar: instrument pods keep their bezel, dial and recessed displays at full
   size — only the gaps between them close up. The 70px dial is untouched, and
   #pageSolar's copy of these .dm-* rules is deliberately not in scope. */
#pageCameras .solar-widget { margin-top: 2px; margin-bottom: 4px; padding: 6px 8px 4px; }
#pageCameras .solar-widget .solar-widget-title { margin-bottom: 5px; }
#pageCameras .solar-widget .dm-inv { padding: 5px 9px 6px; }
#pageCameras .solar-widget .dm-inv::after { top: 7px; }
#pageCameras .solar-widget .dm-name { margin: 0 0 2px; }
#pageCameras .solar-widget .dm-stats { padding: 3px 1px; margin-top: 3px; }
#pageCameras .solar-widget .dm-netrow { margin-top: 5px; }
#pageCameras .solar-widget .dm-sep { margin: 6px 8px 4px; }
#pageCameras .solar-widget .dm-wx-item { padding: 4px 7px; }
#pageCameras .solar-widget .dm-status { padding-top: 3px; }

/* Safety net for genuinely short windows (laptops, half-height browsers).
   zoom scales the whole rail uniformly, so proportions and effects survive —
   same trick the ultrawide tiers use, mirrored downwards. Blur is dropped
   while zoomed for the same reason the >=2600px guard drops it. Capped at
   2599px so an ultrawide screen keeps its own zoom-up tier instead. */
@media (min-width: 900px) and (max-width: 2599px) and (max-height: 860px) {
    #pageCameras .cam-right { zoom: .93; }
    #pageCameras .cam-right .cam-sidebar-card,
    #pageCameras .cam-right .solar-widget { backdrop-filter: none; -webkit-backdrop-filter: none; }
}
@media (min-width: 900px) and (max-width: 2599px) and (max-height: 800px) {
    #pageCameras .cam-right { zoom: .86; }
}
@media (min-width: 900px) and (max-width: 2599px) and (max-height: 740px) {
    #pageCameras .cam-right { zoom: .79; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   TAB/EXPENSE/PAYOUT ROW DENSITY (2026-09-05)
   Polly: "that font is too big, it is going to fill up the screen very fast
   when rhino get active." He is right, and half of it was a regression: the
   2026-07-15 compact pass set .cam-sidebar-row padding to 1px, the graphite
   pass above put it back to 3px, and the FIT-TO-SCREEN block never caught it
   because it only walked the card chrome, not the rows inside the wells.

   Measured before: row 21.0px (tabs/expenses) and 19.0px (payouts) against a
   list well that is only 63px tall at a 900px viewport - three visible tabs.
   After: a uniform 16.5px row, so the wells hold ~27% more before scrolling.

   The row box is now identical in all three columns (12.5px line box + 1.5px
   padding + the 1px separator), so the zebra stripes line up across the card
   instead of drifting 2px per row the way they did before.

   Same two rules as the block above: geometry/type only - no background,
   box-shadow, border-colour or colour - and everything scoped to #pageCameras
   so #pageLive and #pageSolar keep the sizing Polly signed off.
   Delete this block to get the roomier rows back.
   ═══════════════════════════════════════════════════════════════════════════ */
#pageCameras .cam-sidebar-row,
#pageCameras .cam-sidebar-payout-row { padding: 1.5px 2px; line-height: 12.5px; }
#pageCameras .cam-sidebar-row { font-size: 9.5px; }
#pageCameras .cam-sidebar-payout-row { font-size: 9px; }

/* ═══════════════════════════════════════════════════════════════════════════
   SOLAR STRIP (2026-09-05) — solar moved out of the rail, under the camera wall
   Polly's call. Measured before the move: the solar block was 272px of a 758px
   sidebar (36% of it), which held the tab lists to ~3.8 visible rows at a 900px
   viewport. Laid out on its side under the grid it needs roughly a third of that
   height, and the rail hands every freed pixel to the two bar cards.

   The pods keep their bezel, dial and recessed readouts exactly as signed off —
   only the axis changes: each .dm-inv turns from a column into a row (label,
   dial, readout, then the net/yield pills stacked), the groove runs vertically
   instead of across, and the weather chips sit at the far end with the sync
   state. Same light source, same vocabulary, new orientation.

   Rules, as everywhere else on this page: scope to #pageCameras so #pageSolar
   keeps its own copy of the .dm-* rules, and never restyle what already works.
   Below 900px the phone layout stacks the whole page, so the strip stays in its
   original vertical form and none of this applies.
   ═══════════════════════════════════════════════════════════════════════════ */

/* The grid keeps taking the slack; the strip is intrinsic and never squeezed.
   margin-bottom is zeroed because the strip inherits the sidebar island rule that
   spaces the rail's cards apart, and here it is the last thing in the column. */
#pageCameras .cam-left { gap: 8px; }
#pageCameras .solar-strip { flex: none; margin-bottom: 0; }

/* It is a readout, not a control — drop the lift and the pointer it inherited
   from the sidebar widget, which was never wired to a click either. */
#pageCameras .solar-strip { cursor: default; }
#pageCameras .solar-strip:hover { transform: none; }

@media (min-width: 900px) {
    #pageCameras .solar-strip {
        display: flex; align-items: center; gap: 16px;
        margin: 0; padding: 7px 16px;
    }
    /* The nameplate anchors the left end and carries the one groove in the strip.
       It sits on the title rather than between the instruments because the title
       can never wrap — a groove inside .dm-solar dangles at the end of line one
       the moment the weather drops to a second row. */
    #pageCameras .solar-strip .solar-widget-title {
        flex: none; margin: 0; text-align: left; white-space: nowrap;
        display: flex; align-items: center; gap: 14px;
    }
    #pageCameras .solar-strip .solar-widget-title::after {
        content: ""; width: 2px; height: 46px; border-radius: 1px;
        background: linear-gradient(180deg, transparent, rgba(0,0,0,.65), transparent);
        box-shadow: 1px 0 0 rgba(255,255,255,.06);
    }
    #pageCameras .solar-strip .dm-sep { display: none; }
    #pageCameras .solar-strip #solarWidgetContent { flex: 1; min-width: 0; }
    /* wrap, so a narrow left column drops the weather to a second line instead
       of overflowing the strip. */
    #pageCameras .solar-strip .dm-solar {
        display: flex; align-items: center; justify-content: center; flex-wrap: wrap;
        gap: 10px 16px; padding: 0; margin: 0; max-width: none;
    }
    /* On a 5120px screen the strip is a ~4200px band, and centring the whole group
       left a huge void at both ends. Auto margins on the pods take the free space
       instead, so the strip reads as a panel with three anchors — nameplate hard
       left, instruments centred, weather and sync hard right. When the band is
       narrow there is no free space, the margins collapse to nothing, and the
       justify-content below still centres whatever wraps onto a second line. */
    #pageCameras .solar-strip .dm-gauges {
        flex: none; gap: 12px; margin-left: auto; margin-right: auto;
    }
    /* One inverter (Michael) gets the same horizontal pod as two — the old vertical
       ultrawide composition now only applies inside .cam-right, where it belongs. */
    #pageCameras .solar-strip .dm-single .dm-gauges { display: flex; }

    /* Each inverter pod on its side: NAME | dial | PV/LOAD | net + yield. */
    #pageCameras .solar-strip .dm-inv {
        flex-direction: row; align-items: center; gap: 11px;
        min-width: 0; padding: 6px 12px;
    }
    #pageCameras .solar-strip .dm-name { margin: 0; flex: none; }
    #pageCameras .solar-strip .dm-stats {
        width: auto; max-width: none; min-width: 92px; margin: 0;
    }
    #pageCameras .solar-strip .dm-netrow {
        flex-direction: column; align-items: stretch; gap: 4px; margin: 0;
    }

    /* Weather + sync keep their natural width and ride along at the end of the
       instrument group. When the left column is too narrow for one line they wrap
       together and stay centred, instead of being flung to the right edge and
       leaving a hole under the pods. */
    #pageCameras .solar-strip .dm-wxrow {
        flex: 0 1 auto; justify-content: center; gap: 7px; padding: 0;
    }
    #pageCameras .solar-strip .dm-status {
        flex: none; margin: 0; text-align: left; white-space: nowrap;
    }
}

/* ── The SOLAR chip in the camera tick bar ──────────────────────────────────
   Same chassis as the camera chips so it reads as one control strip, but gold
   rather than green and carrying the bolt instead of the status dot: it is not
   a camera, and colour is what carries hierarchy in this design. Lit "on" it is
   the same ingot as the COMBINED plaque - dark lettering on aurum.
   It is DRAWN only for a role that already has solar; see applySolarVisibility. */
#pageCameras .home-cam-toggles .hc-chip-solar { margin-left: 10px; }
#pageCameras .home-cam-toggles .hc-chip-solar::before {
    width: 9px; height: 11px; border-radius: 0; background: #7d8697; box-shadow: none;
    mask: var(--icon-bolt) center / contain no-repeat;
    -webkit-mask: var(--icon-bolt) center / contain no-repeat;
}
#pageCameras .home-cam-toggles .hc-chip-solar:hover::before { background: #cdd4de; }
#pageCameras .home-cam-toggles .hc-chip-solar.on {
    border-color: #4a3308; color: #332004;
    background:
        linear-gradient(180deg, rgba(255,255,255,.30), rgba(255,255,255,0) 55%),
        linear-gradient(180deg, #ffe6a8 0%, #e5b34f 55%, #b7822f 100%);
    box-shadow: inset 0 1px 0 #fff3c7, 0 2px 6px rgba(181,124,39,.38);
    text-shadow: 0 1px 0 rgba(255,242,190,.6);
}
#pageCameras .home-cam-toggles .hc-chip-solar.on::before,
#pageCameras .home-cam-toggles .hc-chip-solar.on:hover::before {
    background: #3a2705; box-shadow: none;
}

/* ── Strip scale on ultrawide screens ──────────────────────────────────────
   The rail is deliberately zoomed on wide screens (1.35 / 1.7 / 2.0 in
   index.html) because 1x is physically small on a 5120px panel. Solar used to
   live inside that zoom and was counter-zoomed back down so it would not eat
   the tab lists' height. Out here in .cam-left it inherits no zoom at all, so
   it rendered at 1x next to a 2x sidebar and read as undersized — part of why
   the band looked empty. These tiers put it back in proportion, gentler than
   the rail's because the strip is height-constrained, not width-constrained:
   at 5120 the strip goes 100px -> 160px and the grid still lands on 5+4.
   Safe with zoom because the strip's backdrop-filter is already none. */
@media (min-width: 2600px) { #pageCameras .solar-strip { zoom: 1.25; } }
@media (min-width: 3800px) { #pageCameras .solar-strip { zoom: 1.45; } }
@media (min-width: 4800px) { #pageCameras .solar-strip { zoom: 1.6; } }

/* ═══════════════════════════════════════════════════════════════════════════
   QUIET WHEN NORMAL (2026-09-05) — status by exception, and columns that
   hand their width to whichever one actually has data.
   Two ideas, both about spending attention where it is earned:

   1. A camera that is working should not shout. Twelve green LIVE pills, each
      with a glowing pulsing dot, were the loudest repeated thing on the wall —
      and the pulse was on the GOOD state while an offline camera sat still and
      dark. That is backwards. LIVE is now a muted slate pill with one small
      steady green pip; WARM/FB keep the amber pulse because they are transient
      and worth watching; OFFLINE gets the glow and the pulse, because a dead
      feed is the only thing on this page that needs you.

   2. On a quiet morning a bar card is mostly frame: three headers, three label
      strips, three empty wells, three totals around one line of data. An empty
      column now fades back and gives ~28% of its width to its neighbours, so
      the column carrying the night's tabs is the widest thing in the card. The well
      itself stays empty — see the note above .cam-sidebar-col.is-empty.

   Scoped to #pageCameras as always; #pageLive and #pageSolar are untouched.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── 1. Status pills ─────────────────────────────────────────────────────── */
#pageCameras .cam-status { color: #9aa7ba; }
#pageCameras .cam-status::before {
    background: #2fbf6b; animation: none;
    box-shadow: 0 0 4px rgba(47,191,107,.55);
}
/* Transient states stay amber and keep the pulse — they resolve on their own. */
#pageCameras .cam-status.warm,
#pageCameras .cam-status.fb { color: #f0a52e; }
#pageCameras .cam-status.warm::before,
#pageCameras .cam-status.fb::before {
    background: currentColor; animation: livePulse 1.8s ease-in-out infinite;
    box-shadow: 0 0 6px currentColor;
}
/* A dead feed is the one thing here that should reach across the room. */
#pageCameras .cam-status.offline {
    color: #ff6b5c;
    border-color: rgba(255,107,92,.55);
    box-shadow: inset 0 1px 0 rgba(255,255,255,.12), 0 1px 3px rgba(0,0,0,.4),
                0 0 12px rgba(255,79,64,.42);
}
#pageCameras .cam-status.offline::before {
    background: currentColor;
    animation: livePulse 1.35s ease-in-out infinite;
    box-shadow: 0 0 7px currentColor;
}

/* ── 2. Columns breathe ──────────────────────────────────────────────────── */
#pageCameras .cam-sidebar-col { flex: 1 1 0; transition: flex-grow .26s ease; }
#pageCameras .cam-sidebar-col.is-empty { flex-grow: .72; }
#pageCameras .cam-sidebar-col.is-empty .cam-sidebar-col-header,
#pageCameras .cam-sidebar-col.is-empty .cam-sidebar-labels,
#pageCameras .cam-sidebar-col.is-empty .cam-sidebar-payout-labels,
#pageCameras .cam-sidebar-col.is-empty .cam-sidebar-total { opacity: .5; }
/* Nothing is drawn inside an empty well. A centred dash was tried on 2026-09-05 and
   removed the same day: in a tall well it floats with nothing to anchor it and reads
   as a scratch on the glass. The fade and the width give-away say "empty" on their own. */

/* ═══════════════════════════════════════════════════════════════════════════
   TOP BAR (2026-09-05) — the camera picker and COMBINED share one row
   Polly spotted the waste: the picker is a `width: max-content` glass toolbar,
   so on the 5120 screen it ended at ~1450px and the rest of that band was empty
   while the gold plaque sat a whole row lower inside the rail.

   MEASURED, because the idea is only right on a wide screen (13 cams + SOLAR):
       5120x1440   card 559 -> 590,  well 277 -> 308,  grid 1086 -> 1063   WIN
       3440x1440   card 581 -> 609,  well 394 -> 423,  grid unchanged      PURE WIN
       1915x1003   card 374 -> 378,  grid  707 -> 672                      LOSS
   At 1920 the picker already fills its row, so there is no band to reclaim —
   making room for the plaque just pushes the chips onto a second row and the
   camera grid pays 35px for the rail's 4px. Hence the 2200px gate below: the
   picker (~1454px) plus the plaque (450px) plus the gap needs ~1930px before it
   fits on one line, and 2200 leaves headroom for a few more cameras.

   The plaque exists in BOTH places in the DOM and renderCamSidebar fills both;
   this rule decides which one is on screen. Its width is derived from the rail's
   own box so the two edges line up with the bar cards, not with the rail's outer
   edge, and it carries the rail's zoom tiers so that stays true when zoomed.
   ═══════════════════════════════════════════════════════════════════════════ */
#pageCameras .cam-topbar { display: flex; align-items: center; gap: 8px; }
#pageCameras .cam-topbar .home-cam-toggles {
    align-self: center; flex: 0 1 auto; min-width: 0; margin-bottom: 0;
}
/* Narrow screens: the picker owns the row, the plaque stays at the top of the rail. */
#pageCameras #camCombinedTop { display: none; }

/* Gate lowered 2200 -> 1800 on 2026-09-05 once the chips shrank. The gate was never
   about screen size, it was about whether the picker and the plaque fit on one line:
   at 1920 the old picker was 1454px wide and adding a 442px plaque pushed the chips
   onto a second row, which cost the camera grid 35px to gain the rail 4px. The smaller
   chips take the picker to 1234px, leaving ~220px of slack at 1920 — room for about
   three more cameras before it wraps, and wrapping now costs 32px instead of 46px, so
   even the degraded case stays ahead. Re-measure at 1920 before lowering it further. */
@media (min-width: 1800px) {
    #pageCameras #camCombinedTop { display: block; }
    #pageCameras .cam-right > #camCombinedTotal { display: none; }
    #pageCameras .cam-topbar {
        --rail-w: 450px;      /* .cam-right width */
        --rail-padx: 8px;     /* .cam-right side padding */
        --rail-gutter: 11px;  /* scrollbar-gutter: stable reserves this on the right */
    }
    /* rail width minus both paddings and the gutter == the bar cards' width (423px),
       and the same right offset (19px), so the plaque sits exactly over the column. */
    #pageCameras .cam-topbar #camCombinedTop {
        flex: 0 0 calc(var(--rail-w) - var(--rail-padx) * 2 - var(--rail-gutter));
        margin: 0 calc(var(--rail-padx) + var(--rail-gutter)) 0 auto;
    }
}
/* Same zoom tiers as the rail (1.35 / 1.7 / 2.0 in index.html), so the plaque keeps
   the cards' width and the picker keeps the room it actually needs. */
@media (min-width: 2600px) { #pageCameras .cam-topbar #camCombinedTop { zoom: 1.35; } }
@media (min-width: 3800px) { #pageCameras .cam-topbar #camCombinedTop { zoom: 1.7; } }
@media (min-width: 4800px) { #pageCameras .cam-topbar #camCombinedTop { zoom: 2; } }
@media (max-width: 899px) { #pageCameras .cam-topbar { display: block; } }

/* ── Picker chips, smaller (2026-09-05) ───────────────────────────────────
   Polly's call over moving the CAMERAS pill: shrink the selector instead of
   restructuring the header. Thirteen cameras plus SOLAR made the picker both
   the tallest band on the page after the header and the loudest thing on it.
   Type stays at 9.5px, which is well clear of the 7-8px legibility floor the
   rest of this design lives at, and every chip keeps its plaque, its dot and
   its colour — only the padding and the type size come down.
   Scoped to #pageCameras: #pageHome's own toggle tray is untouched. */
#pageCameras .home-cam-toggles { padding: 4px 7px; gap: 5px; }
#pageCameras .home-cam-toggles .hc-chip {
    font-size: 9.5px; padding: 4px 11px; gap: 5px; letter-spacing: .4px;
}
#pageCameras .home-cam-toggles .hc-chip::before { width: 5px; height: 5px; }
#pageCameras .home-cam-toggles .hc-chip-solar { margin-left: 8px; }
#pageCameras .home-cam-toggles .hc-chip-solar::before { width: 8px; height: 10px; }

/* ── Rail edges line up with the camera wall (2026-09-05) ──────────────────
   Polly's eye caught a 2px step at the top and a 14px one at the bottom.

   TOP: the grid carries 2px of vertical padding and has to keep it — a hovered
   tile lifts by -2px and the grid clips its own overflow, so without that pad
   the top row's lift gets shaved. The rail therefore has to match those 2px
   *after* its zoom, hence the divide: at zoom 2 a 2px pad would render 4px.
   BOTTOM: the rail's 7px bottom padding plus the last card's 7px margin left
   the last card floating 14px above the rail's floor, which is exactly where
   the solar strip ends. Both go to zero, and the cards (flex: 1 1 auto) take
   the reclaimed 14px into their wells.
   If .cam-right's zoom tiers ever change, --rail-zoom has to change with them. */
#pageCameras .cam-right {
    --rail-zoom: 1;
    padding-top: calc(2px / var(--rail-zoom));
    padding-bottom: 0;
}
@media (min-width: 2600px) { #pageCameras .cam-right { --rail-zoom: 1.35; } }
@media (min-width: 3800px) { #pageCameras .cam-right { --rail-zoom: 1.7; } }
@media (min-width: 4800px) { #pageCameras .cam-right { --rail-zoom: 2; } }
@media (min-width: 900px) and (max-width: 2599px) and (max-height: 860px) { #pageCameras .cam-right { --rail-zoom: .93; } }
@media (min-width: 900px) and (max-width: 2599px) and (max-height: 800px) { #pageCameras .cam-right { --rail-zoom: .86; } }
@media (min-width: 900px) and (max-width: 2599px) and (max-height: 740px) { #pageCameras .cam-right { --rail-zoom: .79; } }
#pageCameras #camSidebarBars .cam-sidebar-card:last-child { margin-bottom: 0; }

/* ═══════════════════════════════════════════════════════════════════════════
   SOLAR POWER-FLOW (2026-10-03) — Polly: "up the ante ... improve the visuals
   ... on dashapi solar. like alot."

   Each inverter pod stops being a dial next to two numbers and becomes a live
   schematic of where the power is going: PV and grid on the left, the battery
   dial as the hub, the house on the right. Flow dots run along recessed wires at
   a speed that follows the watts; a glint runs round the battery arc towards the
   tip while it fills and back from it while it drains; the pod's rivet is now a
   status lamp. Beside the net pill sits the runtime to the 30% alert line.
   The weather chips became one sky instrument with the day's sun path, and the
   sync countdown moved into the nameplate as a ring.

   Vocabulary unchanged: one light source top-left, raised = object, recessed =
   data well, colour carries the hierarchy (PV green, load orange, grid blue,
   charging green / draining red, yield gold), status by exception — anything at
   rest goes slate and only what is moving lights up.

   LOAD-BEARING: the strip's height. Measured before this pass at 1920x1080 the
   strip was 1442x100 with 84px pods, and the camera grid was fitted and signed
   off around that. Everything here lays out inside the same 70px dial height, so
   the strip stays 100px and fitCamGrid sees no change. Re-measure if the dial
   size or the pod padding ever changes.

   Vertical forms (#pageSolar, and the strip below 900px) keep their layout: the
   new nodes fall back to the familiar PV / GRID / LOAD rows in the recessed box;
   wires and node discs are hidden there.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Shared: every orientation ──────────────────────────────────────────── */
.dm-wires, .dm-ico, .sw-sync { display: none; }
.dm-stat .val.grid { color: #7cc4ff; }
.dm-node.n-grid:not(.on) .val { color: #8796aa; }
.dm-node.n-grid.off .val { color: #5f6c7e; letter-spacing: .6px; }

/* Battery at rest: a slate pill that says so. Green used to mean "+0W charging". */
.dm-net.idle {
    color: #b9c6d6; border: 1px solid #ffffff1a; letter-spacing: 1px; font-size: 8.5px;
    background: linear-gradient(#3a4659, #1d2533);
    box-shadow: inset 0 1px 0 #ffffff26, inset 0 -1px 0 #0008, 0 2px 3px #0007;
    text-shadow: 0 1px 2px #000;
}

/* Runtime: the bold figure is the answer, the tag says what it answers. */
/* Nothing yielded yet (every dawn): the chip keeps its place but stops shouting gold. */
.dm-yield.zero { filter: saturate(.35) brightness(.78); }

.dm-eta { font-size: 8px; font-weight: 600; color: #8796aa; letter-spacing: .3px; white-space: nowrap; }
.dm-eta:empty { display: none; }
.dm-eta b { font-size: 10px; font-weight: 800; color: #dbe4ef; letter-spacing: 0; text-shadow: 0 1px 2px #000; }
.dm-eta.dn b { color: #ffc2b6; }
.dm-eta.up b { color: #b5f3cd; }

/* The rivet becomes a status lamp. At rest it stays the plain screw head. */
.dm-inv.is-charging::after {
    border-color: #06301a; background: radial-gradient(circle at 35% 30%, #e6fff0, #52e08e 55%, #1f9a55);
    box-shadow: 0 0 6px 1px #3fd27f, 0 1px 1px #000;
}
.dm-inv.is-draining::after {
    border-color: #3a0c07; background: radial-gradient(circle at 35% 30%, #ffe3dc, #ff6d58 55%, #c23624);
    box-shadow: 0 0 6px 1px #ff5a45, 0 1px 1px #000;
}
.dm-inv.is-stale::after, .dm-inv.no-data::after {
    border-color: #3d2604; background: radial-gradient(circle at 35% 30%, #fff1d6, #f0a43a 60%, #a8670f);
    box-shadow: 0 0 5px #f0a43a99, 0 1px 1px #000;
}

/* Battery dial: glint along the filled arc + the low-battery pulse ring. */
.dm-gwrap { position: relative; }
.dm-glint, .dm-lowring { position: absolute; left: 0; top: 0; pointer-events: none; }
.dm-glint { overflow: visible; mix-blend-mode: screen; }
.dm-glint path {
    fill: none; stroke-linecap: round;
    stroke-dasharray: 11px calc(var(--len) * 3px);
    animation: dm-glint var(--dur) cubic-bezier(.45, 0, .55, 1) infinite;
}
.dm-glint .halo { stroke: #fff; stroke-opacity: .2; stroke-width: 9; }
.dm-glint .core { stroke: #fff; stroke-opacity: .8; stroke-width: 2.4; }
.dm-glint.rev path { animation-direction: reverse; }
@keyframes dm-glint {
    from { stroke-dashoffset: 11px; }
    72%, to { stroke-dashoffset: calc(var(--len) * -1px); }
}
.dm-lowring { border-radius: 50%; animation: dm-lowpulse 2.2s ease-out infinite; }
@keyframes dm-lowpulse {
    0% { box-shadow: 0 0 0 0 rgba(255, 92, 70, .6); }
    75%, 100% { box-shadow: 0 0 0 10px rgba(255, 92, 70, 0); }
}

/* Sky instrument: a recessed well holding the sun path and the weather. */
.dm-sky {
    display: inline-flex; align-items: center; gap: 10px; padding: 4px 12px 4px 8px;
    border: 1px solid #080e17; border-radius: 10px; background: #0b121d;
    box-shadow: inset 0 2px 5px #000a, 0 1px 0 #ffffff0f;
}
.dm-sunarc { width: 100px; height: 44px; flex: none; overflow: visible; }
.dm-sunarc path { fill: none; }
.dm-sunarc .dome { fill: #ffbf5a; fill-opacity: .045; }
.dm-sunarc.night .dome { fill: #7f9be0; fill-opacity: .035; }
.dm-sunarc .track { stroke: #ffffff40; stroke-width: 1.2; stroke-dasharray: 1.4 2.4; }
.dm-sunarc .under { stroke: #ffffff12; stroke-width: 1; stroke-dasharray: 1 3; }
.dm-sunarc .lit { stroke: #ffc561; stroke-width: 1.8; stroke-linecap: round; }
.dm-sunarc .horizon { stroke: #000; stroke-opacity: .7; stroke-width: 2; }
.dm-sunarc .sun { fill: #fff4d2; }
.dm-sunarc .sun-glow { fill: #ffbe4d; opacity: .2; }
.dm-sunarc .sun-glow2 { fill: #ffd27a; opacity: .45; }
.dm-sunarc.night .sun { fill: #b9c7e2; }
.dm-sunarc.night .sun-glow2 { fill: #8ea6d8; opacity: .16; }
.dm-sunarc.night .sun-glow { display: none; }
.dm-sunarc .t { font: 600 7px "Segoe UI", system-ui, sans-serif; fill: #8392a8; text-anchor: middle; letter-spacing: .2px; }
.dm-sunarc .t.nx { fill: #c3cedd; }
.dm-sunarc .arr { fill: #ffc561; }
.dm-sunarc.night .arr { fill: #9fb3dc; }
.dm-wxnow { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.dm-wx-main { display: flex; align-items: baseline; gap: 5px; white-space: nowrap; }
.dm-wx-main .emo { font-size: 13px; align-self: center; filter: drop-shadow(0 1px 2px #000a); }
.dm-wx-main b { font-size: 17px; font-weight: 800; color: #eef3fa; line-height: 1; text-shadow: 0 2px 3px #000; }
.dm-wx-main .cond { font-size: 9.5px; font-weight: 700; letter-spacing: .5px; text-shadow: 0 1px 2px #000; }
.dm-wx-sub { display: flex; gap: 9px; font-size: 9px; font-weight: 700; white-space: nowrap; text-shadow: 0 1px 2px #000; }
.dm-wx-sub span { display: inline-flex; align-items: center; gap: 3px; }
.dm-wx-sub svg { width: 9px; height: 9px; flex: none; }

/* ── The strip: pods on their side become the power-flow schematic ────────── */
@media (min-width: 900px) {
    /* Nameplate: the title keeps its line; the countdown ring sits under it. */
    /* grid, not wrapping flex: a wrapping flex box sizes to all its items on ONE line,
       which left a 54px hole between the title and the groove. */
    #pageCameras .solar-strip .sw-title-txt {
        display: grid; grid-template-columns: max-content max-content; align-items: baseline;
        column-gap: 6px; row-gap: 7px;
    }
    #pageCameras .solar-strip .sw-sync {
        display: flex; grid-column: 1 / -1; align-items: center; gap: 5px;
        font-size: 8.5px; font-weight: 600; letter-spacing: .5px; color: #8d9bb0; text-shadow: none;
    }
    #pageCameras .solar-strip .sw-sync svg { width: 11px; height: 11px; transform: rotate(-90deg); flex: none; }
    #pageCameras .solar-strip .sw-sync circle { fill: none; stroke-width: 2.2; }
    #pageCameras .solar-strip .sw-sync .r0 { stroke: #ffffff17; }
    #pageCameras .solar-strip .sw-sync .r1 {
        stroke: #ffda88; stroke-linecap: round;
        stroke-dasharray: calc(var(--sync-p, 0) * 1px) 200px;
    }
    #pageCameras .solar-strip .dm-status { display: none; }

    /*   name   │ wire │      │ wire │ yield  yield
         PV  (o)━━━━━━━  dial ━━━━━━(o) LOAD
         GRID(o)━━╯    │      │      │ [net]  eta
       Three equal 23.3px rows inside the 70px dial height; the wire SVG spans the three
       middle columns behind the dial, so its geometry is fixed, never measured. */
    #pageCameras .solar-strip .dm-inv {
        display: grid; gap: 0; align-items: center;
        grid-template-columns: auto 30px 70px 30px auto auto;
        grid-template-rows: repeat(3, 1fr);
        grid-template-areas:
            "name w dial w2 yield yield"
            "pv   w dial w2 load  load"
            "grid w dial w2 net   eta";
        padding: 6px 19px 6px 12px;   /* the right 19px is the status lamp's own lane */
    }
    #pageCameras .solar-strip .dm-stats,
    #pageCameras .solar-strip .dm-netrow { display: contents; }
    #pageCameras .solar-strip .dm-name { grid-area: name; justify-self: start; align-self: start; margin: 1px 0 0; }
    #pageCameras .solar-strip .dm-gwrap { grid-area: dial; z-index: 1; width: 70px; height: 70px; }
    #pageCameras .solar-strip .dm-wires {
        display: block; grid-column: 2 / 5; grid-row: 1 / 4; width: 130px; height: 70px; overflow: visible;
    }

    /* Wires: a recessed channel with a light lip under it, like the strip's groove. */
    #pageCameras .solar-strip .dm-wire path { fill: none; stroke-linecap: round; }
    #pageCameras .solar-strip .dm-wire .groove { stroke: #03070d; stroke-width: 5; }
    #pageCameras .solar-strip .dm-wire .seam { stroke: #ffffff12; stroke-width: 1; transform: translateY(2.6px); }
    #pageCameras .solar-strip .dm-wire .glow { stroke: var(--wc); stroke-width: 3.4; opacity: calc(var(--amp) * .38); }
    #pageCameras .solar-strip .dm-wire .dots {
        stroke: var(--wc); stroke-width: 3; stroke-dasharray: .1 8.9; opacity: var(--amp);
        animation: dm-flow var(--dur) linear infinite;
    }
    #pageCameras .solar-strip .dm-wire.rev .dots { animation-direction: reverse; }
    #pageCameras .solar-strip .w-pv   { --wc: #9ff0a8; }
    #pageCameras .solar-strip .w-load { --wc: #ffad5c; }
    #pageCameras .solar-strip .w-grid { --wc: #86cbff; }
    /* No grid at all (AUX is off-grid by design): the channel is there but nothing is
       connected to it, so it fades rather than reading as a live line. */
    #pageCameras .solar-strip .dm-inv:has(.n-grid.off) .w-grid { opacity: .45; }

    /* Nodes: a raised disc is the wire's terminal, the readout stacks beside it. */
    #pageCameras .solar-strip .dm-node {
        display: grid; align-items: center; column-gap: 6px; row-gap: 1px; padding: 0;
        font-size: inherit;
    }
    #pageCameras .solar-strip .n-pv   { grid-area: pv; }
    #pageCameras .solar-strip .n-grid { grid-area: grid; }
    #pageCameras .solar-strip .n-pv, #pageCameras .solar-strip .n-grid {
        justify-self: end; text-align: right; margin-right: -1px;
        grid-template-areas: "lbl ico" "val ico";
    }
    #pageCameras .solar-strip .n-load {
        grid-area: load; justify-self: start; text-align: left; margin-left: -1px;
        grid-template-areas: "ico lbl" "ico val";
    }
    #pageCameras .solar-strip .dm-node .lbl {
        grid-area: lbl; font-size: 7px; letter-spacing: 1.1px; line-height: 8px; color: #8a9ab0;
    }
    #pageCameras .solar-strip .dm-node .lbl::before { display: none; }
    #pageCameras .solar-strip .dm-node .val { grid-area: val; font-size: 11.5px; line-height: 13px; }
    #pageCameras .solar-strip .dm-node:not(.on) .val { color: #7d8b9e; }
    #pageCameras .solar-strip .dm-node.n-grid.off .val { color: #5f6c7e; font-size: 9px; }
    #pageCameras .solar-strip .dm-ico {
        grid-area: ico; display: grid; place-items: center; width: 20px; height: 20px;
        border-radius: 50%; border: 1px solid #8aa3c033; color: #66758a;
        background: radial-gradient(circle at 32% 24%, #ffffff1e, transparent 62%), linear-gradient(160deg, #2a3750, #0d1420);
        box-shadow: inset 0 1px 0 #ffffff26, inset 0 -1px 0 #050a12, 0 2px 0 #050a12, 0 3px 6px #0008;
        transition: color .4s, box-shadow .4s;
    }
    #pageCameras .solar-strip .dm-ico svg { width: 11px; height: 11px; }
    #pageCameras .solar-strip .n-pv   { --nc: #9ff0a8; }
    #pageCameras .solar-strip .n-grid { --nc: #86cbff; }
    #pageCameras .solar-strip .n-load { --nc: #ffad5c; }
    #pageCameras .solar-strip .dm-node.on .dm-ico {
        color: var(--nc); border-color: color-mix(in srgb, var(--nc) 45%, transparent);
        box-shadow: inset 0 1px 0 #ffffff26, inset 0 -1px 0 #050a12, 0 2px 0 #050a12, 0 3px 6px #0008,
                    0 0 9px color-mix(in srgb, var(--nc) 45%, transparent);
    }

    /* Right column: yield up top, battery pill + runtime on the bottom row. */
    #pageCameras .solar-strip .dm-yield { grid-area: yield; justify-self: start; align-self: start; padding: 1px 7px; font-size: 8.5px; }
    #pageCameras .solar-strip .dm-net { grid-area: net; justify-self: start; margin: 0; }
    #pageCameras .solar-strip .dm-eta { grid-area: eta; justify-self: start; margin-left: 6px; }

    /* Trend / stale appear only as an exception, hanging in the gap at the foot of the arc. */
    #pageCameras .solar-strip .dm-trend {
        position: absolute; left: 50%; bottom: -4px; transform: translateX(-50%); z-index: 2;
        margin: 0; min-width: 0; padding: 0 5px; font-size: 8.5px; line-height: 12px; white-space: nowrap;
        border: 1px solid #ffffff14; border-radius: 6px; background: #0a111ce6;
    }
    #pageCameras .solar-strip .dm-trend.flat { display: none; }

    #pageCameras .solar-strip .dm-wxrow { gap: 0; }

    /* Narrow windows (below ~1600px the instruments and the sky no longer share a line).
       Measured: at 1280-1600 the strip already wrapped before this pass (134px), and
       the two-line sky well would have made that 164px, 30px off the camera grid. So
       when the content box is narrow the sky folds to ONE line: where it then fits beside
       the pods the strip stays at 100px, and where it still wraps it costs what the old
       chip row did. A container query, because the trigger is this box's width. */
    #pageCameras .solar-strip #solarWidgetContent { container: solarstrip / inline-size; }
}
@container solarstrip (max-width: 1040px) {
    #pageCameras .solar-strip .dm-sky { gap: 9px; padding: 2px 11px 2px 7px; }
    #pageCameras .solar-strip .dm-sunarc { width: 41px; height: 18px; }
    #pageCameras .solar-strip .dm-sunarc .t { display: none; }
    #pageCameras .solar-strip .dm-wxnow { flex-direction: row; align-items: center; gap: 10px; }
    #pageCameras .solar-strip .dm-wx-main b { font-size: 13px; }
}
@keyframes dm-flow { to { stroke-dashoffset: -9; } }

/* No prefers-reduced-motion guard here, on purpose. Polly's own desktop (huis-polly)
   has Windows "Animation effects" switched off, so Chrome reports reduce there — and on
   this strip the motion IS the reading: which way the power is going and how hard.
   It follows the WeatherFX sky on the same strip, which has always animated regardless.
   The camera wall's status-pill guard in index.html is untouched. To honour the OS
   setting instead, wrap the three animation rules above in (prefers-reduced-motion:
   no-preference). Decided 2026-10-03; ask Polly before changing it. */

/* ═══════════════════════════════════════════════════════════════════════════
   SOLAR PAGE DASHBOARD (2026-10-03) — Polly: "do the solar page full dashboard too"

   Replaces the 380px widget card the page used to show. Scoped to #pageSolar .sd, so
   the Cameras strip and everything else are untouched. Same vocabulary as the rest of
   the app: one light source top-left, raised = object (cards, nodes, the ingot),
   recessed = a well that holds data (readouts, tiles, the chart surface), colour
   carries the hierarchy, and gold is spent once: today's solar, in the ingot.
   Chart marks use the dataviz-validated dark steps (see SD_C in index.html); text is
   always ink, never the series colour - a key mark beside it carries identity.
   No backdrop-filter anywhere here: #pageSolar zooms 1.5-2.4x on the ultrawides.
   ═══════════════════════════════════════════════════════════════════════════ */
#pageSolar .sd {
    --sd-ink: #e6edf6; --sd-ink2: #aab8ca; --sd-mute: #7f8ea3;
    --k-pv: #199e70; --k-load: #d95926; --k-grid: #3987e5; --k-soc: #cfd9e6; --k-bat: #9085e9; --k-eco: #6fae5c;
    width: 100%; max-width: 1640px; margin: 0 auto 18px; display: flex; flex-direction: column; gap: 16px;
    color: var(--sd-ink);
}
#pageSolar .sd-card {
    position: relative; border: 1px solid var(--depth-edge); border-radius: 18px;
    background: radial-gradient(ellipse at 2% 0%, rgba(160,197,236,.14), transparent 58%),
                linear-gradient(150deg, #232d3b, #131c28 62%, #101722);
    box-shadow: inset 0 1px 0 rgba(255,255,255,.15), inset 0 -2px 0 #070c13,
                0 3px 0 #080e17, 0 5px 0 rgba(116,146,183,.14), 0 13px 22px rgba(0,0,0,.42);
}
#pageSolar .sd-well {
    border: 1px solid #080e17; border-radius: 10px; background: #0b121d;
    box-shadow: inset 0 2px 5px #000a, 0 1px 0 #ffffff0f;
}
#pageSolar .sd h3, #pageSolar .sd h4 {
    margin: 0; font-size: 10px; font-weight: 800; letter-spacing: 2.4px; text-transform: uppercase; color: #ffda88;
    text-shadow: 0 2px 3px #000;
}
#pageSolar .sd-sec-head { display: flex; align-items: baseline; gap: 12px; margin-bottom: 12px; }
#pageSolar .sd-sec-head .sub { font-size: 10px; color: var(--sd-mute); letter-spacing: .4px; }

/* Shared keys: a dot / short line / swatch in the series colour beside ink text. */
#pageSolar .sd .k-pv, #pageSolar .sd .s-pv { --kc: var(--k-pv); }
#pageSolar .sd .k-load, #pageSolar .sd .s-load { --kc: var(--k-load); }
#pageSolar .sd .k-grid, #pageSolar .sd .s-grid { --kc: var(--k-grid); }
#pageSolar .sd .k-soc, #pageSolar .sd .s-soc { --kc: var(--k-soc); }
#pageSolar .sd .k-bat, #pageSolar .sd .s-bat { --kc: var(--k-bat); }
#pageSolar .sd .k-eco { --kc: var(--k-eco); }
#pageSolar .sd .k-self { --kc: #ffda88; }
#pageSolar .sd i.k-dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; background: var(--kc); flex: none; }
#pageSolar .sd i.k-line { display: inline-block; width: 14px; height: 2px; border-radius: 1px; background: var(--kc); flex: none; }
#pageSolar .sd i.k-area { display: inline-block; width: 14px; height: 9px; border-radius: 2px; flex: none;
    background: linear-gradient(var(--kc), var(--kc)) top / 100% 2px no-repeat, color-mix(in srgb, var(--kc) 22%, transparent); }
#pageSolar .sd i.k-rect { display: inline-block; width: 11px; height: 11px; border-radius: 3px; background: var(--kc); flex: none; }
#pageSolar .sd i.k-ref { display: inline-block; width: 14px; height: 0; border-top: 1px solid #ff9c8a99; flex: none; }
#pageSolar .sd .s-bat.sd-seg, #pageSolar .sd i.k-rect.s-bat { background: var(--k-bat); }
#pageSolar .sd-legend { display: flex; flex-wrap: wrap; gap: 6px 16px; font-size: 10px; color: var(--sd-ink2); }
#pageSolar .sd-legend > span { display: inline-flex; align-items: center; gap: 6px; }

/* ── Sky banner ── */
#pageSolar .sd-sky {
    overflow: hidden; display: grid; grid-template-columns: auto auto 1fr auto; align-items: center;
    gap: 22px 30px; padding: 18px 26px; min-height: 132px;
}
#pageSolar .sd-sky > :not(canvas) { position: relative; z-index: 1; }
#pageSolar .sd-sky .dm-wxcanvas { border-radius: inherit; }
#pageSolar .sd-sky .dm-sunarc { width: 210px; height: 92px; }
#pageSolar .sd-wx-main { display: flex; align-items: baseline; gap: 8px; white-space: nowrap; }
#pageSolar .sd-wx-main .emo { font-size: 24px; align-self: center; filter: drop-shadow(0 2px 3px #000a); }
#pageSolar .sd-wx-main b { font-size: 42px; font-weight: 800; color: #f2f6fb; line-height: 1; text-shadow: 0 3px 6px #000; }
#pageSolar .sd-wx-main .cond { font-size: 14px; font-weight: 800; letter-spacing: .6px; text-shadow: 0 1px 3px #000; }
#pageSolar .sd-wx-sub { display: flex; gap: 14px; margin-top: 8px; font-size: 11.5px; font-weight: 700; white-space: nowrap; text-shadow: 0 1px 2px #000; }
#pageSolar .sd-wx-sub span { display: inline-flex; align-items: center; gap: 4px; }
#pageSolar .sd-wx-sub svg { width: 11px; height: 11px; }
#pageSolar .sd-wx-day { margin-top: 6px; font-size: 10.5px; color: var(--sd-ink2); letter-spacing: .3px; text-shadow: 0 1px 2px #000; }
#pageSolar .sd-sky-now { display: flex; flex-wrap: wrap; justify-content: center; gap: 10px; }
#pageSolar .sd-stat {
    min-width: 118px; padding: 9px 14px 10px; border: 1px solid #080e17; border-radius: 11px;
    background: #0b121de6; box-shadow: inset 0 2px 5px #000a, 0 1px 0 #ffffff0f;
}
#pageSolar .sd-stat-l, #pageSolar .sd-tile-l {
    display: flex; align-items: center; gap: 6px; font-size: 8.5px; font-weight: 700; letter-spacing: 1.2px;
    text-transform: uppercase; color: var(--sd-ink2);
}
#pageSolar .sd-stat-l i, #pageSolar .sd-tile-l i { width: 8px; height: 8px; border-radius: 50%; background: var(--kc); flex: none; }
#pageSolar .sd-stat b { display: block; margin-top: 5px; font-size: 20px; font-weight: 800; color: var(--sd-ink); text-shadow: 0 2px 3px #000; }
#pageSolar .sd-stat.k-bat.up b { color: #b5f3cd; }
#pageSolar .sd-stat.k-bat.dn b { color: #ffc2b6; }
/* The one hero: today's solar, on the same ingot as COMBINED. */
#pageSolar .sd-ingot {
    position: relative; overflow: hidden; min-width: 190px; padding: 12px 22px 13px 56px;
    border: 1px solid #ffe5a6; border-bottom-color: #916221; border-radius: 14px; color: #352109;
    background: radial-gradient(ellipse at 25% 0, #fff1bf, transparent 60%),
                linear-gradient(112deg, #b57c27, #f6d57b 26%, #e5b34f 60%, #b7822f);
    box-shadow: inset 0 1px 0 #fff3c7, inset 0 -2px 0 #98651b, 0 3px 0 #644313, 0 5px 0 #080d14, 0 9px 18px #0006;
    text-shadow: 0 1px 0 #fff0b2;
}
#pageSolar .sd-ingot::before {
    content: ""; position: absolute; left: 16px; top: 50%; width: 28px; height: 28px; transform: translateY(-50%);
    background: #654315; -webkit-mask: var(--icon-bolt) center / contain no-repeat; mask: var(--icon-bolt) center / contain no-repeat;
}
#pageSolar .sd-ingot .l { display: block; font-size: 9px; font-weight: 850; letter-spacing: 1.8px; text-transform: uppercase; opacity: .8; }
#pageSolar .sd-ingot b { display: block; font-size: 28px; font-weight: 850; line-height: 1.1; letter-spacing: .3px; }

/* ── Inverter columns ── */
#pageSolar .sd-cols, #pageSolar .sd-charts { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; }
#pageSolar .sd-cols.single, #pageSolar .sd-charts.single { grid-template-columns: minmax(0, 900px); justify-content: center; }
#pageSolar .sd-inv { display: flex; flex-direction: column; gap: 14px; padding: 15px 18px 18px; }
#pageSolar .sd-inv-head, #pageSolar .sd-chart-head { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; }
#pageSolar .sd-inv-name { font-size: 13px; font-weight: 800; letter-spacing: 3px; color: #e3eaf4; text-shadow: 0 2px 3px #000; }
#pageSolar .sd-inv-meta { font-size: 10px; color: var(--sd-mute); letter-spacing: .4px; }
#pageSolar .sd-state {
    margin-left: auto; display: inline-flex; align-items: center; gap: 7px; padding: 3px 11px 3px 9px;
    font-size: 9.5px; font-weight: 800; letter-spacing: 1px; text-transform: uppercase; color: #b9c6d6;
    border: 1px solid #ffffff14; border-radius: 999px; background: #0b121d;
    box-shadow: inset 0 1px 3px #0009, 0 1px 0 #ffffff0d;
}
#pageSolar .sd-state i { width: 7px; height: 7px; border-radius: 50%; border: 1px solid #080e18; background: #687789; box-shadow: inset 0 1px 0 #ccd8e8; }
#pageSolar .st-up .sd-state { color: #b5f3cd; }
#pageSolar .st-up .sd-state i { background: radial-gradient(circle at 35% 30%, #e6fff0, #52e08e 55%, #1f9a55); box-shadow: 0 0 7px 1px #3fd27f; border-color: #06301a; }
#pageSolar .st-dn .sd-state { color: #ffc2b6; }
#pageSolar .st-dn .sd-state i { background: radial-gradient(circle at 35% 30%, #ffe3dc, #ff6d58 55%, #c23624); box-shadow: 0 0 7px 1px #ff5a45; border-color: #3a0c07; }
#pageSolar .st-stale .sd-state, #pageSolar .st-nd .sd-state { color: #f6c779; }
#pageSolar .st-stale .sd-state i, #pageSolar .st-nd .sd-state i { background: radial-gradient(circle at 35% 30%, #fff1d6, #f0a43a 60%, #a8670f); box-shadow: 0 0 6px #f0a43a99; border-color: #3d2604; }

/* The schematic: PV and grid in, the battery dial as the hub, the home out. Three equal
   rows, so the wire ends (1/6, 5/6 of the height) always meet the node centres; the wires
   run under the dial to its centre, so a different dial size never leaves a gap. */
#pageSolar .sd-flow {
    --dial: 150px; --w: 64px; position: relative; display: grid; align-items: center;
    grid-template-columns: minmax(0, 1fr) var(--w) var(--dial) var(--w) minmax(0, 1fr);
    grid-template-rows: repeat(3, 1fr); height: calc(var(--dial) + 34px);
    grid-template-areas: "pv w hub w2 load" ". w hub w2 ." "grid w hub w2 bat";
}
#pageSolar .sd-wires { grid-column: 2 / 5; grid-row: 1 / 4; width: 100%; height: 100%; overflow: visible; }
#pageSolar .sd-wires path { fill: none; stroke-linecap: round; vector-effect: non-scaling-stroke; }
#pageSolar .sd-wires .groove { stroke: #03070d; stroke-width: 7; }
#pageSolar .sd-wires .seam { stroke: #ffffff14; stroke-width: 1; transform: translateY(3.5px); }
#pageSolar .sd-wires .glow { stroke: var(--wc); stroke-width: 4.5; opacity: calc(var(--amp) * .36); }
#pageSolar .sd-wires .dots {
    stroke: var(--wc); stroke-width: 4; stroke-dasharray: .1 11.9; opacity: var(--amp);
    animation: sd-flow var(--dur) linear infinite;
}
#pageSolar .sd-wires .rev .dots { animation-direction: reverse; }
#pageSolar .sd-wires .w-pv { --wc: #9ff0a8; }
#pageSolar .sd-wires .w-load { --wc: #ffad5c; }
#pageSolar .sd-wires .w-grid { --wc: #86cbff; }
#pageSolar .sd-inv:has(.n-grid.off) .w-grid { opacity: .4; }
@keyframes sd-flow { to { stroke-dashoffset: -12; } }
#pageSolar .sd-hub { grid-area: hub; place-self: center; z-index: 1; width: var(--dial); height: var(--dial);
    border-radius: 50%; box-shadow: 0 6px 16px #000a, 0 0 0 1px #00000080; }
#pageSolar .sd-hub canvas { display: block; }

#pageSolar .sd-node { display: flex; align-items: center; gap: 10px; min-width: 0; z-index: 1; }
#pageSolar .n-pv { grid-area: pv; } #pageSolar .n-grid { grid-area: grid; } #pageSolar .n-load { grid-area: load; }
#pageSolar .n-pv, #pageSolar .n-grid { justify-self: end; flex-direction: row-reverse; text-align: right; margin-right: -2px; }
#pageSolar .n-load { justify-self: start; margin-left: -2px; }
#pageSolar .n-pv { --nc: #9ff0a8; } #pageSolar .n-grid { --nc: #86cbff; } #pageSolar .n-load { --nc: #ffad5c; }
#pageSolar .sd-disc {
    display: grid; place-items: center; flex: none; width: 36px; height: 36px; border-radius: 50%;
    border: 1px solid #8aa3c033; color: #66758a;
    background: radial-gradient(circle at 32% 24%, #ffffff1e, transparent 62%), linear-gradient(160deg, #2a3750, #0d1420);
    box-shadow: inset 0 1px 0 #ffffff26, inset 0 -1px 0 #050a12, 0 3px 0 #050a12, 0 5px 9px #0008;
}
#pageSolar .sd-disc svg { width: 18px; height: 18px; }
#pageSolar .sd-node.on .sd-disc {
    color: var(--nc); border-color: color-mix(in srgb, var(--nc) 45%, transparent);
    box-shadow: inset 0 1px 0 #ffffff26, inset 0 -1px 0 #050a12, 0 3px 0 #050a12, 0 5px 9px #0008,
                0 0 14px color-mix(in srgb, var(--nc) 40%, transparent);
}
#pageSolar .sd-node-t { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
#pageSolar .sd-node .lbl, #pageSolar .sd-bat .lbl { font-size: 8.5px; font-weight: 800; letter-spacing: 1.4px; text-transform: uppercase; color: var(--sd-mute); }
#pageSolar .sd-node .val { font-size: 21px; font-weight: 800; line-height: 1.05; color: #8796aa; white-space: nowrap; text-shadow: 0 2px 3px #000; }
#pageSolar .sd-node.on .val { color: var(--nc); }
#pageSolar .sd-node .sub, #pageSolar .sd-bat .sub { display: flex; flex-wrap: wrap; gap: 2px 10px; font-size: 9.5px; color: var(--sd-mute); }
#pageSolar .n-pv .sub, #pageSolar .n-grid .sub { justify-content: flex-end; }
#pageSolar .sd-bat { grid-area: bat; justify-self: start; display: flex; flex-direction: column; gap: 4px; min-width: 0; z-index: 1; }
#pageSolar .sd-bat-row { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }
#pageSolar .sd-bat .dm-net { font-size: 12px; padding: 4px 11px; }
#pageSolar .sd-bat .dm-net svg { width: 11px; height: 11px; }
#pageSolar .sd-bat .dm-eta { font-size: 9.5px; }
#pageSolar .sd-bat .dm-eta b { font-size: 13px; }

/* Readouts + today's tiles: data, so recessed. */
#pageSolar .sd-health {
    margin: 0; display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 9px 18px; padding: 11px 15px;
    border: 1px solid #080e17; border-radius: 11px; background: #0b121d; box-shadow: inset 0 2px 5px #000a, 0 1px 0 #ffffff0f;
}
#pageSolar .sd-health dt { font-size: 8px; font-weight: 800; letter-spacing: 1.3px; text-transform: uppercase; color: var(--sd-mute); }
#pageSolar .sd-health dd { margin: 3px 0 0; font-size: 11.5px; font-weight: 700; color: #d5deea; font-variant-numeric: tabular-nums; }
#pageSolar .sd-today h4 { margin-bottom: 9px; }
#pageSolar .sd-tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(84px, 1fr)); gap: 8px; }
#pageSolar .sd-tile {
    display: flex; flex-direction: column; justify-content: space-between;   /* values share a baseline when a label wraps */
    padding: 8px 11px 9px; border: 1px solid #080e17; border-radius: 10px; background: #0b121d;
    box-shadow: inset 0 2px 5px #000a, 0 1px 0 #ffffff0f;
}
#pageSolar .sd-tile b { display: block; margin-top: 5px; font-size: 15px; font-weight: 800; color: var(--sd-ink); white-space: nowrap; }
#pageSolar .sd-offline { padding: 26px; text-align: center; color: #ffb4a6; font-size: 12px; grid-column: 1 / -1; }

/* ── Lifetime ── */
#pageSolar .sd-life { padding: 16px 20px 18px; }
#pageSolar .sd-life-grid { display: grid; grid-template-columns: minmax(200px, auto) 1fr; gap: 16px 22px; align-items: center; }
#pageSolar .sd-life-hero .l { display: block; font-size: 9px; font-weight: 800; letter-spacing: 1.4px; text-transform: uppercase; color: var(--sd-ink2); }
#pageSolar .sd-life-hero b { display: block; margin: 4px 0 3px; font-size: 32px; font-weight: 850; color: var(--sd-ink); text-shadow: 0 2px 4px #000; }
#pageSolar .sd-life-hero .s { font-size: 10px; color: var(--sd-mute); }
#pageSolar .sd-split { margin-top: 16px; display: flex; flex-direction: column; gap: 8px; }
#pageSolar .sd-split-head { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 20px; font-size: 10px; font-weight: 800; letter-spacing: 1.2px; text-transform: uppercase; color: var(--sd-ink2); }
#pageSolar .sd-split-head .sd-legend { font-weight: 600; letter-spacing: .2px; text-transform: none; }
#pageSolar .sd-split-row { display: grid; grid-template-columns: 52px 1fr; align-items: center; gap: 10px; }
#pageSolar .sd-split-name { font-size: 10px; font-weight: 800; letter-spacing: 2px; color: var(--sd-ink2); }
#pageSolar .sd-split-bar { display: flex; gap: 2px; height: 22px; padding: 3px; border: 1px solid #080e17; border-radius: 9px; background: #0b121d; box-shadow: inset 0 2px 4px #0009; }
#pageSolar .sd-seg { display: grid; place-items: center; min-width: 0; font-size: 10px; font-weight: 800; color: #fff; text-shadow: 0 1px 2px #0008; }
#pageSolar .sd-seg:first-child { border-radius: 6px 0 0 6px; } #pageSolar .sd-seg:last-child { border-radius: 0 6px 6px 0; }
#pageSolar .sd-seg:only-child { border-radius: 6px; }
#pageSolar .sd-seg.s-bat { background: var(--k-bat); } #pageSolar .sd-seg.s-load { background: var(--k-load); } #pageSolar .sd-seg.s-grid { background: var(--k-grid); }

/* ── Day row: one control row, scoping the charts below it ── */
#pageSolar .sd-dayrow { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
#pageSolar .sd-day-btn {
    min-width: 34px; padding: 6px 14px; border: 1px solid #8aa3c033; border-radius: 999px; cursor: pointer;
    font: 800 10px/1 "Segoe UI", system-ui, sans-serif; letter-spacing: 1.2px; text-transform: uppercase; color: #c3cedd;
    background: radial-gradient(circle at 30% 0, #ffffff1a, transparent 60%), linear-gradient(160deg, #2a3750, #121a28);
    box-shadow: inset 0 1px 0 #ffffff24, inset 0 -1px 0 #050a12, 0 2px 0 #050a12, 0 4px 8px #0007;
}
#pageSolar .sd-day-btn.sd-step { font-size: 15px; padding: 3px 11px 5px; letter-spacing: 0; }
#pageSolar .sd-day-btn:hover:not(:disabled) { color: #fff; }
#pageSolar .sd-day-btn:disabled { opacity: .35; cursor: default; }
#pageSolar .sd-day-btn.on {
    border-color: #4a3308; color: #332004; text-shadow: 0 1px 0 rgba(255,242,190,.6);
    background: linear-gradient(180deg, rgba(255,255,255,.30), rgba(255,255,255,0) 55%), linear-gradient(180deg, #ffe6a8 0%, #e5b34f 55%, #b7822f 100%);
    box-shadow: inset 0 1px 0 #fff3c7, 0 2px 6px rgba(181,124,39,.38);
}
#pageSolar .sd-day-label { margin-left: 6px; font-size: 12px; font-weight: 700; color: var(--sd-ink2); letter-spacing: .3px; }

/* ── Charts ── */
#pageSolar .sd-charts { transition: opacity .2s; }
#pageSolar .sd-charts.is-loading { opacity: .5; }
#pageSolar .sd-chart { display: flex; flex-direction: column; gap: 10px; padding: 15px 18px 14px; }
#pageSolar .sd-chart-sum { display: flex; flex-wrap: wrap; gap: 4px 14px; margin-left: auto; font-size: 10.5px; color: var(--sd-ink2); }
#pageSolar .sd-sum { display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; }
#pageSolar .sd-sum b { color: var(--sd-ink); font-weight: 800; }
#pageSolar .sd-sum.muted { color: var(--sd-mute); font-style: italic; }
#pageSolar .sd-plot {
    position: relative; outline: none; padding: 4px 0 2px; border: 1px solid #080e17; border-radius: 11px;
    background: #0b121d; box-shadow: inset 0 2px 5px #000a, 0 1px 0 #ffffff0f; touch-action: pan-y;
}
#pageSolar .sd-plot:focus-visible { box-shadow: inset 0 2px 5px #000a, 0 0 0 2px #ffda8888; }
#pageSolar .sd-svg { display: block; width: 100%; height: auto; overflow: visible; }
#pageSolar .sd-gl { stroke: #ffffff10; stroke-width: 1; shape-rendering: crispEdges; }
#pageSolar .sd-gl.zero { stroke: #ffffff2a; }
#pageSolar .sd-night { fill: #000; opacity: .22; }
#pageSolar .sd-tick { font: 600 9.5px "Segoe UI", system-ui, sans-serif; fill: #7f8ea3; font-variant-numeric: tabular-nums; }
#pageSolar .sd-tick.now { fill: #ffda88; font-weight: 800; }
#pageSolar .sd-now { stroke: #ffda8899; stroke-width: 1; shape-rendering: crispEdges; }
#pageSolar .sd-ref { stroke: #ff9c8a77; stroke-width: 1; shape-rendering: crispEdges; }
#pageSolar .sd-line { fill: none; stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
#pageSolar .sd-area { opacity: .12; }
#pageSolar .sd-area.soc { opacity: .07; }
#pageSolar .sd-mark, #pageSolar .sd-hd { stroke: #0b121d; stroke-width: 2; }
#pageSolar .sd-dl { font: 700 10px "Segoe UI", system-ui, sans-serif; fill: #c3cedd; paint-order: stroke; stroke: #0b121d; stroke-width: 3px; }
#pageSolar .sd-xh { stroke: #ffffff59; stroke-width: 1; shape-rendering: crispEdges; }
#pageSolar .sd-tip {
    position: absolute; top: 10px; z-index: 3; min-width: 146px; padding: 8px 11px 9px; pointer-events: none;
    border: 1px solid #ffffff1c; border-radius: 9px; background: #060b13f2; box-shadow: 0 8px 20px #000a;
    font-size: 11px; color: var(--sd-ink2);
}
#pageSolar .sd-tip-h { margin-bottom: 5px; font-weight: 800; letter-spacing: .8px; color: #ffda88; }
#pageSolar .sd-tip-r { display: flex; align-items: center; gap: 7px; line-height: 17px; white-space: nowrap; }
#pageSolar .sd-tip-r b { min-width: 58px; color: var(--sd-ink); font-weight: 800; font-variant-numeric: tabular-nums; }
#pageSolar .sd-empty { margin: 0; padding: 40px 12px; text-align: center; font-size: 12px; color: var(--sd-mute); }
#pageSolar .sd-table summary { cursor: pointer; font-size: 10px; font-weight: 700; letter-spacing: .6px; color: var(--sd-mute); }
#pageSolar .sd-table summary:hover { color: var(--sd-ink2); }
#pageSolar .sd-table-body { max-height: 260px; overflow: auto; margin-top: 8px; }
#pageSolar .sd-table table { width: 100%; border-collapse: collapse; font-size: 11px; font-variant-numeric: tabular-nums; }
#pageSolar .sd-table th { position: sticky; top: 0; background: #101826; text-align: right; padding: 5px 8px; font-size: 9px; letter-spacing: .8px; text-transform: uppercase; color: var(--sd-mute); }
#pageSolar .sd-table td { text-align: right; padding: 3px 8px; color: #d5deea; border-top: 1px solid #ffffff0a; }
#pageSolar .sd-table th:first-child, #pageSolar .sd-table td:first-child { text-align: left; }
#pageSolar .sd > .dm-status { text-align: center; }

/* ── Narrower screens ── */
@media (max-width: 1180px) {
    #pageSolar .sd-cols, #pageSolar .sd-charts { grid-template-columns: minmax(0, 1fr); }
    #pageSolar .sd-sky { grid-template-columns: auto 1fr auto; }
    #pageSolar .sd-sky-now { grid-column: 1 / -1; order: 4; justify-content: stretch; }
    #pageSolar .sd-sky-now .sd-stat { flex: 1 1 120px; }
}
@media (max-width: 760px) {
    #pageSolar .sd { gap: 12px; }
    #pageSolar .sd-sky { grid-template-columns: 1fr; justify-items: center; text-align: center; padding: 14px 14px 16px; gap: 14px; }
    #pageSolar .sd-sky .sd-wx-main, #pageSolar .sd-sky .sd-wx-sub { justify-content: center; }
    #pageSolar .sd-ingot { justify-self: stretch; text-align: left; }
    #pageSolar .sd-inv, #pageSolar .sd-chart, #pageSolar .sd-life { padding: 13px 12px 14px; }
    #pageSolar .sd-state { margin-left: 0; }
    #pageSolar .sd-flow { --w: 26px; }
    #pageSolar .sd-disc { display: none; }
    #pageSolar .sd-node .val { font-size: 16px; }
    #pageSolar .sd-node .sub, #pageSolar .sd-bat .sub { display: none; }   /* the readout panel below carries them */
    #pageSolar .sd-bat .dm-net { font-size: 10.5px; padding: 3px 8px; }
    #pageSolar .sd-life-grid { grid-template-columns: 1fr; }
    #pageSolar .sd-chart-sum { margin-left: 0; }
}
