@kenz1117/dsh-ui-usage-billing 0.5.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/client.js CHANGED
@@ -24,7 +24,7 @@ window.__ModuleLoader__.load({
24
24
  }
25
25
  //#endregion
26
26
  //#region \0dsh-css:/Users/ken/deepseek-harness/packages/client/ui-usage-billing/src/client/UsageBilling.module.css.mjs
27
- const css = ".VWh0dG_railButton{border:1px solid color-mix(in srgb, var(--dsw-static-blue-500) 28%, var(--dsw-alias-border-l2));background:linear-gradient(135deg, color-mix(in srgb, var(--dsw-static-blue-500) 14%, var(--dsw-alias-bg-layer-1)), var(--dsw-alias-bg-layer-1));width:36px;height:36px;color:var(--dsw-static-blue-500);cursor:pointer;border-radius:10px;justify-content:center;align-items:center;padding:0;transition:border-color .16s,box-shadow .16s,transform .16s,color .16s;display:flex}.VWh0dG_railButton:hover,.VWh0dG_railButton:focus-visible{border-color:color-mix(in srgb, var(--dsw-static-blue-500) 48%, var(--dsw-alias-border-l2));box-shadow:0 4px 14px -6px color-mix(in srgb, var(--dsw-static-blue-500) 55%, transparent);color:var(--dsw-static-blue-400);outline:none;transform:translateY(-1px)}.VWh0dG_railButton svg{stroke-width:2px;width:18px;height:18px}.VWh0dG_trigger{border:1px solid color-mix(in srgb, var(--dsw-static-blue-500) 20%, var(--dsw-alias-border-l1));background:radial-gradient(130% 180% at 0% 0%, color-mix(in srgb, var(--dsw-static-blue-500) 12%, transparent), transparent 55%), radial-gradient(150% 200% at 100% 110%, color-mix(in srgb, var(--dsw-static-blue-400) 9%, transparent), transparent 60%), var(--dsw-alias-bg-layer-1);width:100%;color:var(--dsw-alias-label-primary);cursor:pointer;text-align:left;border-radius:12px;align-items:center;gap:12px;padding:10px 14px;transition:border-color .16s,box-shadow .16s,transform .16s;display:flex;position:relative;overflow:hidden}@supports (backdrop-filter:blur(1px)){.VWh0dG_trigger{background:radial-gradient(130% 180% at 0% 0%, color-mix(in srgb, var(--dsw-static-blue-500) 14%, transparent), transparent 55%), radial-gradient(150% 200% at 100% 110%, color-mix(in srgb, var(--dsw-static-blue-400) 10%, transparent), transparent 60%), color-mix(in srgb, var(--dsw-alias-bg-layer-1) 72%, transparent);backdrop-filter:blur(12px)}}.VWh0dG_trigger:hover,.VWh0dG_trigger:focus-visible{border-color:color-mix(in srgb, var(--dsw-static-blue-500) 42%, var(--dsw-alias-border-l1));box-shadow:0 8px 24px -10px color-mix(in srgb, var(--dsw-static-blue-500) 45%, transparent);outline:none;transform:translateY(-1px)}.VWh0dG_triggerIcon{background:linear-gradient(135deg, var(--dsw-static-blue-500), var(--dsw-static-blue-400));width:28px;height:28px;color:var(--dsw-static-neutral-bluish-00);box-shadow:0 2px 8px -2px color-mix(in srgb, var(--dsw-static-blue-500) 60%, transparent);border-radius:8px;flex:none;justify-content:center;align-items:center;display:inline-flex}.VWh0dG_triggerIcon svg{stroke-width:1.8px;width:15px;height:15px}.VWh0dG_triggerToday,.VWh0dG_triggerMonth{align-items:baseline;gap:4px;min-width:0;display:flex}.VWh0dG_triggerDivider{background:var(--dsw-alias-border-l1);align-self:stretch;width:1px}.VWh0dG_triggerAmount{color:var(--dsw-alias-label-primary);letter-spacing:-.01em;font-variant-numeric:tabular-nums;white-space:nowrap;font-size:18px;font-weight:600;line-height:22px}.VWh0dG_triggerAmountSub{color:var(--dsw-alias-label-secondary);font-variant-numeric:tabular-nums;white-space:nowrap;font-size:13px;font-weight:600;line-height:18px}.VWh0dG_triggerMeta{color:var(--dsw-alias-label-tertiary);white-space:nowrap;font-size:10.5px;line-height:14px}.VWh0dG_dashboardModal{background:linear-gradient(var(--dsw-alias-bg-layer-2), var(--dsw-alias-bg-layer-2)) padding-box, linear-gradient(135deg, color-mix(in srgb, var(--dsw-static-blue-500) 55%, transparent), color-mix(in srgb, var(--dsw-static-blue-400) 22%, transparent) 45%, color-mix(in srgb, var(--dsw-static-blue-500) 38%, transparent)) border-box;width:min(760px,100vw - 48px);max-height:min(760px,88vh);box-shadow:var(--dsw-shadow-lv3), 0 24px 80px -24px color-mix(in srgb, var(--dsw-static-blue-500) 35%, transparent);border:1px solid #0000;animation:.18s ease-out VWh0dG_dashboardIn}@keyframes VWh0dG_dashboardIn{0%{opacity:0;transform:translateY(8px)scale(.98)}to{opacity:1;transform:none}}div[role=presentation]:has(>.dsh-billing-modal)>div[aria-hidden=true]:first-child{backdrop-filter:blur(8px)saturate(1.25)}.VWh0dG_dashboard{flex-direction:column;width:100%;max-height:min(760px,88vh);display:flex}.VWh0dG_dashboardHead{border-bottom:1px solid var(--dsw-alias-border-l1);justify-content:space-between;align-items:flex-start;gap:12px;padding:20px 24px 14px;display:flex}.VWh0dG_dashboardTitle{color:var(--dsw-alias-label-primary);margin:0;font-size:17px;font-weight:600;line-height:24px}.VWh0dG_dashboardSubtitle{color:var(--dsw-alias-label-caption);margin:3px 0 0;font-size:12px;line-height:17px}.VWh0dG_closeButton{width:30px;height:30px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;border-radius:8px;flex:none;justify-content:center;align-items:center;transition:background-color .14s;display:inline-flex}.VWh0dG_closeButton:hover{background:var(--dsw-alias-interactive-bg-hover)}.VWh0dG_closeButton svg{stroke-width:2px;width:16px;height:16px}.VWh0dG_dashboardBody{flex-direction:column;gap:14px;padding:16px 24px 24px;display:flex;overflow-y:auto}.VWh0dG_tabNav{border-bottom:1px solid var(--dsw-alias-border-l1);align-items:center;gap:4px;padding:10px 24px;display:flex}.VWh0dG_tabButton{color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:none;border-radius:999px;padding:5px 14px;font-size:12.5px;font-weight:500;line-height:18px;transition:background-color .16s,color .16s,box-shadow .16s}.VWh0dG_tabButton:hover,.VWh0dG_tabButton:focus-visible{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-interactive-bg-hover);outline:none}.VWh0dG_tabButtonActive,.VWh0dG_tabButtonActive:hover,.VWh0dG_tabButtonActive:focus-visible{background:linear-gradient(135deg, var(--dsw-static-blue-500), color-mix(in srgb, var(--dsw-static-blue-500) 72%, var(--dsw-static-blue-400)));color:var(--dsw-static-neutral-bluish-00);box-shadow:0 2px 10px -3px color-mix(in srgb, var(--dsw-static-blue-500) 55%, transparent);font-weight:600}.VWh0dG_tabPanel{flex-direction:column;gap:14px;animation:.14s ease-out VWh0dG_tabPanelIn;display:flex}@keyframes VWh0dG_tabPanelIn{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:none}}.VWh0dG_hero{border:1px solid color-mix(in srgb, var(--dsw-static-blue-500) 16%, var(--dsw-alias-border-l1));background:radial-gradient(90% 150% at 6% 0%, color-mix(in srgb, var(--dsw-static-blue-500) 10%, transparent), transparent 60%), radial-gradient(70% 130% at 96% 100%, color-mix(in srgb, var(--dsw-static-blue-400) 8%, transparent), transparent 55%), var(--dsw-alias-bg-layer-1);border-radius:16px;justify-content:space-between;align-items:center;gap:24px;padding:20px 24px;display:flex;position:relative;overflow:hidden}.VWh0dG_heroMain{flex-direction:column;gap:4px;min-width:0;display:flex}.VWh0dG_heroLabel{color:var(--dsw-alias-label-tertiary);white-space:nowrap;font-size:12px;line-height:17px}.VWh0dG_heroValue{letter-spacing:-.02em;font-variant-numeric:tabular-nums;white-space:nowrap;background:linear-gradient(120deg, var(--dsw-alias-label-primary) 25%, color-mix(in srgb, var(--dsw-static-blue-500) 85%, var(--dsw-alias-label-primary)));color:#0000;-webkit-text-fill-color:transparent;-webkit-background-clip:text;background-clip:text;font-size:44px;font-weight:600;line-height:52px}.VWh0dG_heroMeta{color:var(--dsw-alias-label-caption);white-space:nowrap;font-size:12px;line-height:17px}.VWh0dG_heroSide{border-left:1px solid var(--dsw-alias-border-l1);flex-direction:column;flex:none;gap:10px;padding-left:24px;display:flex}.VWh0dG_heroSideItem{align-items:baseline;gap:8px;display:flex}.VWh0dG_heroSideLabel{color:var(--dsw-alias-label-tertiary);white-space:nowrap;font-size:12px;line-height:17px}.VWh0dG_heroSideValue{color:var(--dsw-alias-label-primary);font-variant-numeric:tabular-nums;white-space:nowrap;font-size:16px;font-weight:600;line-height:22px}.VWh0dG_delta{align-items:center;gap:2px;margin-left:4px;font-size:11px;font-weight:600;line-height:17px;display:inline-flex}.VWh0dG_deltaUp{color:var(--dsw-static-green-500)}.VWh0dG_deltaDown{color:var(--dsw-static-red-500)}.VWh0dG_kpiGrid{grid-template-columns:repeat(4,minmax(0,1fr));gap:12px;display:grid}.VWh0dG_kpiTile{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);border-radius:14px;flex-direction:column;gap:3px;padding:14px 15px;transition:border-color .16s,background-color .16s,transform .16s,box-shadow .16s;display:flex;position:relative;overflow:hidden}.VWh0dG_kpiTile:before{content:\"\";background:linear-gradient(90deg, color-mix(in srgb, var(--dsw-static-blue-500) 70%, transparent), transparent);opacity:.7;height:2px;position:absolute;inset:0 0 auto}.VWh0dG_kpiTile:has(.VWh0dG_kpiGreen):before{background:linear-gradient(90deg, color-mix(in srgb, var(--dsw-static-green-500) 70%, transparent), transparent)}.VWh0dG_kpiTile:hover{border-color:var(--dsw-alias-border-l2);background:var(--dsw-alias-interactive-bg-hover);box-shadow:0 6px 16px -8px color-mix(in srgb, var(--dsw-alias-label-primary) 35%, transparent);transform:translateY(-1px)}.VWh0dG_kpiLabel{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:15px}.VWh0dG_kpiValue{color:var(--dsw-alias-label-primary);font-variant-numeric:tabular-nums;font-size:21px;font-weight:600;line-height:27px}.VWh0dG_kpiGreen{color:var(--dsw-static-green-500)}.VWh0dG_kpiDetail{color:var(--dsw-alias-label-caption);white-space:nowrap;text-overflow:ellipsis;font-size:11px;line-height:15px;overflow:hidden}.VWh0dG_panel{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);border-radius:16px;flex-direction:column;gap:10px;padding:16px 18px;display:flex}.VWh0dG_panelHead{justify-content:space-between;align-items:baseline;gap:10px;display:flex}.VWh0dG_panelTitle{color:var(--dsw-alias-label-primary);margin:0;font-size:14px;font-weight:600;line-height:20px}.VWh0dG_panelHint{color:var(--dsw-alias-label-caption);white-space:nowrap;font-size:11px;line-height:16px}.VWh0dG_rangeToggle{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);border-radius:8px;gap:2px;padding:2px;display:inline-flex}.VWh0dG_rangeButton{color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:none;border-radius:6px;padding:2px 8px;font-size:11px;line-height:16px;transition:background-color .14s,color .14s}.VWh0dG_rangeButtonActive{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary);font-weight:600}.VWh0dG_budget{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);border-radius:14px;flex-direction:column;gap:8px;padding:12px 16px;display:flex}.VWh0dG_budgetHead{justify-content:space-between;align-items:baseline;gap:10px;display:flex}.VWh0dG_budgetLabel{color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:17px}.VWh0dG_budgetValue{color:var(--dsw-alias-label-secondary);font-variant-numeric:tabular-nums;white-space:nowrap;font-size:12px;line-height:17px}.VWh0dG_budgetControls{align-items:center;gap:8px;min-width:0;display:inline-flex}.VWh0dG_budgetInputWrap{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);border-radius:6px;align-items:center;gap:2px;padding:2px 6px;display:inline-flex}.VWh0dG_budgetInputWrap:focus-within{border-color:var(--dsw-alias-border-l3)}.VWh0dG_budgetUnit{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:16px}.VWh0dG_budgetInput{width:64px;color:var(--dsw-alias-label-primary);font-variant-numeric:tabular-nums;text-align:right;background:0 0;border:none;padding:0;font-size:12px;line-height:16px}.VWh0dG_budgetInput:focus-visible{outline:none}.VWh0dG_switch{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-module-platform);cursor:pointer;border-radius:999px;flex:none;width:30px;height:17px;padding:0;transition:background-color .16s,border-color .16s;position:relative}.VWh0dG_switchOn{border-color:var(--dsw-static-blue-500);background:var(--dsw-static-blue-500)}.VWh0dG_switchKnob{background:var(--dsw-static-neutral-bluish-00);border-radius:50%;width:11px;height:11px;transition:transform .16s;position:absolute;top:2px;left:2px}.VWh0dG_switchOn .VWh0dG_switchKnob{transform:translate(13px)}.VWh0dG_budgetTrack{background:var(--dsw-alias-bg-module-platform);border-radius:999px;height:6px;overflow:hidden}.VWh0dG_budgetFill{background:var(--dsw-static-blue-500);border-radius:999px;height:100%;transition:width .2s}.VWh0dG_budgetFillOver{background:var(--dsw-static-red-500);animation:1.6s ease-in-out infinite VWh0dG_budgetOverPulse}@keyframes VWh0dG_budgetOverPulse{50%{opacity:.55}}.VWh0dG_chartWrap{width:100%;position:relative}.VWh0dG_chartSvg{width:100%;height:auto;display:block}.VWh0dG_chartEmpty{height:140px;color:var(--dsw-alias-label-caption);justify-content:center;align-items:center;font-size:13px;display:flex}.VWh0dG_emptyRow{text-align:center;color:var(--dsw-alias-label-caption);padding:28px 0;font-size:13px}.VWh0dG_chartGrid{stroke:var(--dsw-alias-border-l1);stroke-width:1px}.VWh0dG_chartAxisLabel{fill:var(--dsw-alias-label-tertiary);font-size:10px}.VWh0dG_chartBar{fill:var(--dsw-static-blue-500);opacity:.35}.VWh0dG_chartBar:hover{opacity:.6}.VWh0dG_chartStack{stroke:var(--dsw-alias-bg-layer-1);stroke-width:.75px}.VWh0dG_chartStack:hover{opacity:.85}.VWh0dG_chartLine{stroke:var(--dsw-static-blue-500);stroke-width:2px;stroke-linecap:round;stroke-linejoin:round}.VWh0dG_chartCrosshair{stroke:var(--dsw-alias-label-dimmed);stroke-width:1px;stroke-dasharray:3 3}.VWh0dG_chartDot{fill:var(--dsw-static-neutral-bluish-00);stroke:var(--dsw-static-blue-500);stroke-width:2.5px}.VWh0dG_chartTooltip{pointer-events:none;z-index:2;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);box-shadow:var(--dsw-shadow-lv2);white-space:nowrap;border-radius:10px;padding:8px 10px;position:absolute;transform:translate(-50%,calc(-100% - 10px))}.VWh0dG_chartTooltipDate{color:var(--dsw-alias-label-primary);margin-bottom:3px;font-size:11px;font-weight:600}.VWh0dG_chartTooltipRow{color:var(--dsw-alias-label-secondary);align-items:center;gap:5px;font-size:11px;line-height:17px;display:flex}.VWh0dG_chartTooltipRow strong{color:var(--dsw-alias-label-primary);font-variant-numeric:tabular-nums;font-weight:600}.VWh0dG_chartLegendLine{background:var(--dsw-static-blue-500);border-radius:2px;width:10px;height:3px;display:inline-block}.VWh0dG_chartLegendBar{background:var(--dsw-static-blue-500);opacity:.5;border-radius:2px;width:7px;height:7px;display:inline-block}.VWh0dG_chartTooltipSwatch{border-radius:3px;flex:none;width:8px;height:8px;display:inline-block}.VWh0dG_chartLegend{color:var(--dsw-alias-label-tertiary);justify-content:flex-end;gap:14px;margin-top:2px;font-size:11px;display:flex}.VWh0dG_chartLegend span{align-items:center;gap:5px;display:inline-flex}.VWh0dG_tableScroll{border:1px solid var(--dsw-alias-border-l1);--dsh-scrollbar-thumb:var(--dsw-alias-scrollbar-bg-l2);--dsh-scrollbar-thumb-hover:var(--dsw-alias-scrollbar-hover-l2);border-radius:12px;overflow:auto}.VWh0dG_modelTable,.VWh0dG_pricingTable{border-collapse:collapse;width:100%;font-size:12.5px}.VWh0dG_modelTable th,.VWh0dG_modelTable td,.VWh0dG_pricingTable th,.VWh0dG_pricingTable td{border-bottom:1px solid var(--dsw-alias-border-l1);text-align:left;white-space:nowrap;padding:9px 12px}.VWh0dG_modelTable tbody tr:last-child td,.VWh0dG_pricingTable tbody tr:last-child td{border-bottom:0}.VWh0dG_modelTable thead th,.VWh0dG_pricingTable thead th{color:var(--dsw-alias-label-tertiary);background:var(--dsw-alias-bg-module-platform);font-size:11px;font-weight:500}.VWh0dG_modelTable tbody tr,.VWh0dG_pricingTable tbody tr{transition:background-color .12s}.VWh0dG_modelTable tbody tr:hover,.VWh0dG_pricingTable tbody tr:hover{background:var(--dsw-alias-interactive-bg-hover)}.VWh0dG_numCol{text-align:right;font-variant-numeric:tabular-nums}.VWh0dG_costCol{color:var(--dsw-static-blue-500);font-weight:600}.VWh0dG_na{color:var(--dsw-alias-label-dimmed)}.VWh0dG_modelCell{align-items:center;gap:8px;display:inline-flex}.VWh0dG_modelDot{width:9px;height:9px;box-shadow:0 0 0 3px color-mix(in srgb, var(--dsw-alias-bg-layer-1) 60%, transparent);border-radius:50%;flex:none}.VWh0dG_modelName{color:var(--dsw-alias-label-primary);font-weight:500;line-height:16px;display:block}.VWh0dG_modelProvider{color:var(--dsw-alias-label-caption);font-size:10.5px;line-height:14px;display:block}.VWh0dG_pricingToggle{cursor:pointer;text-align:left;background:0 0;border:none;justify-content:space-between;align-items:center;gap:10px;width:100%;padding:0;display:flex}.VWh0dG_pricingToggle:hover .VWh0dG_panelTitle,.VWh0dG_pricingToggle:focus-visible .VWh0dG_panelTitle{color:var(--dsw-static-blue-500)}.VWh0dG_rateBadge{vertical-align:1px;white-space:nowrap;border-radius:999px;align-items:center;margin-left:6px;padding:1px 6px;font-size:10px;font-weight:500;line-height:14px;display:inline-flex}.VWh0dG_rateBadgeLive{color:var(--dsw-static-green-500);background:color-mix(in srgb, var(--dsw-static-green-500) 10%, transparent)}.VWh0dG_rateBadgeBuiltin{color:var(--dsw-alias-label-tertiary);background:var(--dsw-alias-bg-module-platform)}.VWh0dG_pricingToggleText{align-items:baseline;gap:10px;min-width:0;display:flex}.VWh0dG_pricingChevron{width:16px;height:16px;color:var(--dsw-alias-label-tertiary);flex:none;transition:transform .16s}.VWh0dG_pricingChevronOpen{transform:rotate(180deg)}.VWh0dG_bandPrice{align-items:baseline;gap:6px;display:inline-flex}.VWh0dG_bandPriceOff{color:var(--dsw-alias-label-caption)}.VWh0dG_bandPriceOff:before{content:\"/\";color:var(--dsw-alias-label-dimmed);margin-right:4px}.VWh0dG_bandTag{color:var(--dsw-alias-label-secondary);flex-direction:column;gap:1px;font-size:10.5px;line-height:14px;display:inline-flex}.VWh0dG_bandTagOff{color:var(--dsw-static-green-500);font-weight:600}.VWh0dG_flatTag{color:var(--dsw-alias-label-caption);font-size:10.5px;line-height:14px}.VWh0dG_healthDot{border-radius:50%;flex:none;width:8px;height:8px;display:inline-block}.VWh0dG_healthOk{background:var(--dsw-static-green-500);box-shadow:0 0 0 3px color-mix(in srgb, var(--dsw-static-green-500) 18%, transparent)}.VWh0dG_healthBad{background:var(--dsw-static-red-500);box-shadow:0 0 0 3px color-mix(in srgb, var(--dsw-static-red-500) 18%, transparent)}.VWh0dG_healthIdle{background:var(--dsw-static-neutral-bluish-400)}.VWh0dG_dashboardRight{align-items:center;gap:8px;min-width:0;display:flex}.VWh0dG_healthBadge{white-space:nowrap;border-radius:999px;align-items:center;gap:6px;padding:3px 9px;font-size:11px;line-height:16px;display:inline-flex}.VWh0dG_healthBadgeOk{color:var(--dsw-static-green-500);background:color-mix(in srgb, var(--dsw-static-green-500) 10%, transparent)}.VWh0dG_healthBadgeBad{color:var(--dsw-static-red-500);background:color-mix(in srgb, var(--dsw-static-red-500) 10%, transparent)}.VWh0dG_planTag{color:var(--dsw-static-green-500);background:color-mix(in srgb, var(--dsw-static-green-500) 12%, transparent);border-radius:999px;align-items:center;padding:1px 8px;font-size:11px;font-weight:500;line-height:17px;display:inline-flex}.VWh0dG_uncataloguedTag{vertical-align:1px;color:var(--dsw-static-amber-500);background:color-mix(in srgb, var(--dsw-static-amber-500) 12%, transparent);border-radius:999px;margin-left:6px;padding:0 6px;font-size:10px;font-weight:600;line-height:16px;display:inline-block}.VWh0dG_estimatedTag{vertical-align:1px;color:var(--dsw-static-blue-500);background:color-mix(in srgb, var(--dsw-static-blue-500) 12%, transparent);border-radius:999px;margin-left:6px;padding:0 6px;font-size:10px;font-weight:600;line-height:16px;display:inline-block}.VWh0dG_liveCostBar{color:var(--dsw-static-neutral-400);font-variant-numeric:tabular-nums;align-items:center;gap:6px;font-size:11px;line-height:16px;display:inline-flex}.VWh0dG_liveCostItem{white-space:nowrap}.VWh0dG_liveCostSep{color:var(--dsw-static-neutral-300)}.VWh0dG_balanceCell{flex-direction:column;align-items:flex-end;gap:2px;display:inline-flex}.VWh0dG_balanceDays{color:var(--dsw-alias-label-caption);white-space:nowrap;font-size:10.5px;line-height:14px}.VWh0dG_balanceDaysLow{color:var(--dsw-static-red-500);font-weight:600}body[data-zine-mode] .VWh0dG_trigger,body[data-zine-mode] .VWh0dG_railButton{display:none}body[data-zine-mode] .VWh0dG_dashboardHead{background:#000;border-bottom:2px solid #e8ff00}body[data-zine-mode] .VWh0dG_headTitleRow{align-items:center;gap:8px;margin-top:4px;display:flex}body[data-zine-mode] .VWh0dG_dashboardTitle{color:#e8ff00;letter-spacing:.04em;text-transform:uppercase;text-shadow:0 0 8px #e8ff0066;font-weight:900}body[data-zine-mode] .VWh0dG_dashboardSubtitle{color:#c9d98a;letter-spacing:.08em;text-transform:uppercase;font-size:10px}body[data-zine-mode] .VWh0dG_closeButton{color:#0a0a05;background:#ff2d95;border:1.5px solid #ff2d95;border-radius:0;box-shadow:0 0 10px #ff2d9573}body[data-zine-mode] .VWh0dG_hero{background:#000;border:2.5px solid #e8ff00;border-radius:0;position:relative;box-shadow:0 0 0 1px #0009,0 0 24px #e8ff002e}body[data-zine-mode] .VWh0dG_heroLabel{color:#c9d98a;letter-spacing:.12em;text-transform:uppercase;font-size:10px;font-weight:900}body[data-zine-mode] .VWh0dG_heroValue{color:#e8ff00;letter-spacing:-.02em;text-shadow:0 0 12px #e8ff0073;-webkit-text-fill-color:#e8ff00;background:0 0;font-size:38px;font-weight:900}body[data-zine-mode] .VWh0dG_heroMeta{color:#c9d98a;letter-spacing:.06em;text-transform:uppercase;font-size:10.5px}body[data-zine-mode] .VWh0dG_heroSideLabel{color:#c9d98a;letter-spacing:.1em;text-transform:uppercase;font-size:10px;font-weight:900}body[data-zine-mode] .VWh0dG_heroSideValue{color:#e8ff00;text-shadow:0 0 6px #e8ff0059}body[data-zine-mode] .VWh0dG_delta{font-weight:900}body[data-zine-mode] .VWh0dG_deltaUp{color:#ff2d95}body[data-zine-mode] .VWh0dG_deltaDown{color:#c9d98a}body[data-zine-mode] .VWh0dG_tabNav{background:#000;border-bottom:2px solid #e8ff00}body[data-zine-mode] .VWh0dG_tabButton{color:#c9d98a;letter-spacing:.08em;text-transform:uppercase;border-radius:0;font-size:10.5px;font-weight:900}body[data-zine-mode] .VWh0dG_tabButton:hover,body[data-zine-mode] .VWh0dG_tabButton:focus-visible{color:#e8ff00;background:#e8ff001f}body[data-zine-mode] .VWh0dG_tabButtonActive,body[data-zine-mode] .VWh0dG_tabButtonActive:hover,body[data-zine-mode] .VWh0dG_tabButtonActive:focus-visible{color:#0a0a05;background:#e8ff00;box-shadow:0 0 10px #e8ff0073}body[data-zine-mode] .VWh0dG_panel{background:#000;border:2px solid #e8ff00;border-radius:0}body[data-zine-mode] .VWh0dG_trendPanel{position:relative}body[data-zine-mode] .VWh0dG_panelTitle{color:#e8ff00;letter-spacing:.06em;text-transform:uppercase;text-shadow:0 0 6px #e8ff0066;font-weight:900}body[data-zine-mode] .VWh0dG_panelHint{color:#c9d98a;letter-spacing:.08em;text-transform:uppercase;font-size:10px;font-weight:900}body[data-zine-mode] .VWh0dG_modelTableScroll{background:#000;border:1.5px solid #e8ff0080;border-radius:0}.VWh0dG_currencyToggle{border:1px solid var(--dsw-alias-border-muted,#3a4250);background:var(--dsw-alias-bg-layer-2,#232a33);border-radius:6px;align-items:center;gap:2px;margin-right:8px;padding:2px;display:inline-flex}.VWh0dG_currencyButton{color:var(--dsw-alias-text-secondary,#9aa5b1);cursor:pointer;background:0 0;border:0;border-radius:4px;padding:4px 7px;font-size:11px;font-weight:700;line-height:1}.VWh0dG_currencyButtonActive{background:var(--dsw-alias-accent-muted,#2f6fed);color:#fff}.VWh0dG_subscriptionGrid{grid-template-columns:repeat(auto-fill,minmax(240px,1fr));gap:10px;margin-top:10px;display:grid}.VWh0dG_subscriptionCard{border:1px solid var(--dsw-alias-border-muted,#3a4250);background:var(--dsw-alias-bg-layer-2,#232a33);border-radius:8px;padding:10px 12px}.VWh0dG_subscriptionHead{align-items:baseline;gap:8px;margin-bottom:6px;display:flex}.VWh0dG_subscriptionName{font-size:13px;font-weight:700}.VWh0dG_subscriptionPlan{color:var(--dsw-alias-text-secondary,#9aa5b1);font-size:11px}.VWh0dG_subscriptionStatus{color:var(--dsw-alias-warning,#e0a63c);margin-bottom:6px;font-size:11px}.VWh0dG_subscriptionWindow{align-items:center;gap:8px;margin-top:6px;font-size:11px;display:flex}.VWh0dG_subscriptionWindowLabel{color:var(--dsw-alias-text-secondary,#9aa5b1);flex:0 0 44px}.VWh0dG_subscriptionTrack{background:var(--dsw-alias-bg-layer-3,#1a2028);border-radius:3px;flex:1;height:5px;overflow:hidden}.VWh0dG_subscriptionFill{background:var(--dsw-alias-accent,#3b82f6);border-radius:3px;height:100%;display:block}.VWh0dG_subscriptionPct{text-align:right;font-variant-numeric:tabular-nums;flex:none;min-width:52px}.VWh0dG_subscriptionReset{color:var(--dsw-alias-text-secondary,#9aa5b1);flex:none}.VWh0dG_providerGroupList{flex-direction:column;gap:10px;display:flex}.VWh0dG_providerGroup{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);border-radius:12px;padding:12px 14px}.VWh0dG_providerGroupHead{justify-content:space-between;align-items:baseline;gap:12px;display:flex}.VWh0dG_providerGroupTitle{align-items:center;gap:7px;min-width:0;display:inline-flex}.VWh0dG_providerGroupName{color:var(--dsw-alias-label-primary);font-size:13px;font-weight:600;line-height:18px}.VWh0dG_providerGroupMeta{flex:none;align-items:center;gap:10px;display:inline-flex}.VWh0dG_providerGroupBadge{color:var(--dsw-static-green-500);background:color-mix(in srgb, var(--dsw-static-green-500) 12%, transparent);border-radius:999px;align-items:center;padding:1px 8px;font-size:11px;font-weight:500;line-height:17px;display:inline-flex}.VWh0dG_providerGroupBalance{color:var(--dsw-alias-label-secondary);font-variant-numeric:tabular-nums;white-space:nowrap;align-items:baseline;gap:6px;font-size:12px;line-height:17px;display:inline-flex}.VWh0dG_providerGroupBalanceLabel{color:var(--dsw-alias-label-caption);font-size:11px;line-height:17px}.VWh0dG_roundsFlagBadge{color:#fff;background:#ef4444;border-radius:999px;margin-left:8px;padding:1px 7px;font-size:10px;font-weight:800}.VWh0dG_rounds{margin-top:10px}.VWh0dG_roundsBars{align-items:flex-end;gap:3px;height:110px;padding:4px 2px 0;display:flex;overflow-x:auto}.VWh0dG_roundsBarCol{flex-direction:column;flex:1 0 28px;justify-content:flex-end;align-items:stretch;height:100%;display:flex}.VWh0dG_roundsBarLabel{text-align:center;color:var(--dsw-alias-text-secondary,#9aa5b1);white-space:nowrap;text-overflow:ellipsis;max-width:100%;margin-bottom:2px;font-size:8px;line-height:1;overflow:hidden}.VWh0dG_roundsBarWrap{flex:1;align-items:flex-end;min-height:0;display:flex}.VWh0dG_roundsBar{background:var(--dsw-alias-accent,#3b82f6);border-radius:2px 2px 0 0;width:100%;min-height:2px;position:relative}.VWh0dG_roundsBarFlagged{outline-offset:1px;background:#ef4444;border-radius:2px 2px 0 0;outline:1.5px solid #ef4444;width:100%;min-height:2px;position:relative}.VWh0dG_roundsFlagMark{background:#ef4444;border-radius:50%;width:7px;height:7px;position:absolute;top:-3px;right:-3px;box-shadow:0 0 4px #ef4444}.VWh0dG_roundsAxis{color:var(--dsw-alias-text-secondary,#9aa5b1);justify-content:space-between;margin-top:6px;font-size:10px;display:flex}.VWh0dG_roundsEmpty{color:var(--dsw-alias-text-secondary,#9aa5b1);margin-top:10px;font-size:12px}.VWh0dG_heatmap{margin-top:10px}.VWh0dG_heatmapGrid{grid-template-columns:repeat(7,minmax(0,1fr));gap:8px;display:grid}.VWh0dG_heatmapCellEmpty{background:var(--dsw-alias-bg-layer-1);height:30px;color:var(--dsw-alias-label-dimmed,#6b7480);font-variant-numeric:tabular-nums;border-radius:8px;justify-content:center;align-items:center;font-size:11px;display:flex}.VWh0dG_heatmapCell{font-variant-numeric:tabular-nums;cursor:pointer;border:0;border-radius:8px;justify-content:center;align-items:center;height:30px;padding:0;font-size:11px;display:flex}.VWh0dG_heatmapCell[data-level=\"0\"],.VWh0dG_heatmapCell[data-level=\"1\"],.VWh0dG_heatmapCell[data-level=\"2\"]{color:var(--dsw-alias-label-primary)}.VWh0dG_heatmapCell[data-level=\"3\"],.VWh0dG_heatmapCell[data-level=\"4\"]{color:var(--dsw-static-neutral-bluish-00,#fff)}.VWh0dG_heatmapFooter{color:var(--dsw-alias-text-secondary,#9aa5b1);align-items:center;gap:8px;margin-top:10px;font-size:10px;display:flex}.VWh0dG_heatmapLegend{gap:3px;display:inline-flex}.VWh0dG_heatmapLegend i{border-radius:4px;width:14px;height:14px;display:block}.VWh0dG_heatmapHover{font-variant-numeric:tabular-nums;margin-left:auto}@media (width<=640px){.VWh0dG_kpiGrid{grid-template-columns:repeat(2,minmax(0,1fr))}.VWh0dG_hero{flex-direction:column;align-items:flex-start;gap:14px}.VWh0dG_heroSide{border-left:none;border-top:1px solid var(--dsw-alias-border-l1);flex-direction:row;align-self:stretch;gap:20px;padding-top:14px;padding-left:0}}";
27
+ const css = ".VWh0dG_railButton{border:1px solid color-mix(in srgb, var(--dsw-static-blue-500) 28%, var(--dsw-alias-border-l2));background:linear-gradient(135deg, color-mix(in srgb, var(--dsw-static-blue-500) 14%, var(--dsw-alias-bg-layer-1)), var(--dsw-alias-bg-layer-1));width:36px;height:36px;color:var(--dsw-static-blue-500);cursor:pointer;border-radius:10px;justify-content:center;align-items:center;padding:0;transition:border-color .16s,box-shadow .16s,transform .16s,color .16s;display:flex}.VWh0dG_railButton:hover,.VWh0dG_railButton:focus-visible{border-color:color-mix(in srgb, var(--dsw-static-blue-500) 48%, var(--dsw-alias-border-l2));box-shadow:0 4px 14px -6px color-mix(in srgb, var(--dsw-static-blue-500) 55%, transparent);color:var(--dsw-static-blue-400);outline:none;transform:translateY(-1px)}.VWh0dG_railButton svg{stroke-width:2px;width:18px;height:18px}.VWh0dG_trigger{border:1px solid color-mix(in srgb, var(--dsw-static-blue-500) 20%, var(--dsw-alias-border-l1));background:radial-gradient(130% 180% at 0% 0%, color-mix(in srgb, var(--dsw-static-blue-500) 12%, transparent), transparent 55%), radial-gradient(150% 200% at 100% 110%, color-mix(in srgb, var(--dsw-static-blue-400) 9%, transparent), transparent 60%), var(--dsw-alias-bg-layer-1);width:100%;color:var(--dsw-alias-label-primary);cursor:pointer;text-align:left;border-radius:12px;align-items:center;gap:12px;padding:10px 14px;transition:border-color .16s,box-shadow .16s,transform .16s;display:flex;position:relative;overflow:hidden}@supports (backdrop-filter:blur(1px)){.VWh0dG_trigger{background:radial-gradient(130% 180% at 0% 0%, color-mix(in srgb, var(--dsw-static-blue-500) 14%, transparent), transparent 55%), radial-gradient(150% 200% at 100% 110%, color-mix(in srgb, var(--dsw-static-blue-400) 10%, transparent), transparent 60%), color-mix(in srgb, var(--dsw-alias-bg-layer-1) 72%, transparent);backdrop-filter:blur(12px)}}.VWh0dG_trigger:hover,.VWh0dG_trigger:focus-visible{border-color:color-mix(in srgb, var(--dsw-static-blue-500) 42%, var(--dsw-alias-border-l1));box-shadow:0 8px 24px -10px color-mix(in srgb, var(--dsw-static-blue-500) 45%, transparent);outline:none;transform:translateY(-1px)}.VWh0dG_triggerIcon{background:linear-gradient(135deg, var(--dsw-static-blue-500), var(--dsw-static-blue-400));width:28px;height:28px;color:var(--dsw-static-neutral-bluish-00);box-shadow:0 2px 8px -2px color-mix(in srgb, var(--dsw-static-blue-500) 60%, transparent);border-radius:8px;flex:none;justify-content:center;align-items:center;display:inline-flex}.VWh0dG_triggerIcon svg{stroke-width:1.8px;width:15px;height:15px}.VWh0dG_triggerToday,.VWh0dG_triggerMonth{align-items:baseline;gap:4px;min-width:0;display:flex}.VWh0dG_triggerDivider{background:var(--dsw-alias-border-l1);align-self:stretch;width:1px}.VWh0dG_triggerAmount{color:var(--dsw-alias-label-primary);letter-spacing:-.01em;font-variant-numeric:tabular-nums;white-space:nowrap;font-size:18px;font-weight:600;line-height:22px}.VWh0dG_triggerAmountSub{color:var(--dsw-alias-label-secondary);font-variant-numeric:tabular-nums;white-space:nowrap;font-size:13px;font-weight:600;line-height:18px}.VWh0dG_triggerMeta{color:var(--dsw-alias-label-tertiary);white-space:nowrap;font-size:10.5px;line-height:14px}.VWh0dG_triggerWrap{width:100%;display:block;position:relative}.VWh0dG_triggerPop{border:1px solid color-mix(in srgb, var(--dsw-static-blue-500) 22%, var(--dsw-alias-border-l1));background:radial-gradient(130% 180% at 0% 0%, color-mix(in srgb, var(--dsw-static-blue-500) 12%, transparent), transparent 55%), var(--dsw-alias-bg-layer-2);box-shadow:0 12px 32px -12px color-mix(in srgb, var(--dsw-alias-label-primary) 30%, transparent);opacity:0;pointer-events:none;z-index:10;border-radius:12px;flex-direction:column;gap:6px;padding:12px 14px;transition:opacity .16s,transform .16s;display:flex;position:absolute;bottom:calc(100% + 8px);left:0;right:0;transform:translateY(4px)}@supports (backdrop-filter:blur(1px)){.VWh0dG_triggerPop{background:radial-gradient(130% 180% at 0% 0%, color-mix(in srgb, var(--dsw-static-blue-500) 14%, transparent), transparent 55%), color-mix(in srgb, var(--dsw-alias-bg-layer-2) 82%, transparent);backdrop-filter:blur(14px)}}.VWh0dG_triggerWrap:hover .VWh0dG_triggerPop,.VWh0dG_triggerWrap:focus-within .VWh0dG_triggerPop{opacity:1;transform:translateY(0)}.VWh0dG_triggerPopRow{justify-content:space-between;align-items:baseline;gap:12px;display:flex}.VWh0dG_triggerPopLabel{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:16px}.VWh0dG_triggerPopValue{color:var(--dsw-alias-label-primary);font-variant-numeric:tabular-nums;font-size:13px;font-weight:600;line-height:18px}.VWh0dG_triggerPopBars{border-top:1px solid var(--dsw-alias-border-l1);align-items:flex-end;gap:4px;height:22px;margin-top:4px;padding-top:8px;display:flex}.VWh0dG_triggerPopBar{background:linear-gradient(180deg, var(--dsw-static-blue-400), var(--dsw-static-blue-500));border-radius:2px;flex:1;transition:height .2s}.VWh0dG_dashboardModal{background:linear-gradient(var(--dsw-alias-bg-layer-2), var(--dsw-alias-bg-layer-2)) padding-box, linear-gradient(135deg, color-mix(in srgb, var(--dsw-static-blue-500) 55%, transparent), color-mix(in srgb, var(--dsw-static-blue-400) 22%, transparent) 45%, color-mix(in srgb, var(--dsw-static-blue-500) 38%, transparent)) border-box;width:min(760px,100vw - 48px);max-height:min(760px,88vh);box-shadow:var(--dsw-shadow-lv3), 0 24px 80px -24px color-mix(in srgb, var(--dsw-static-blue-500) 35%, transparent);border:1px solid #0000;animation:.18s ease-out VWh0dG_dashboardIn}@keyframes VWh0dG_dashboardIn{0%{opacity:0;transform:translateY(8px)scale(.98)}to{opacity:1;transform:none}}div[role=presentation]:has(>.dsh-billing-modal)>div[aria-hidden=true]:first-child{backdrop-filter:blur(8px)saturate(1.25)}.VWh0dG_dashboard{flex-direction:column;width:100%;max-height:min(760px,88vh);display:flex}.VWh0dG_dashboardHead{border-bottom:1px solid var(--dsw-alias-border-l1);justify-content:space-between;align-items:flex-start;gap:12px;padding:20px 24px 14px;display:flex}.VWh0dG_dashboardTitle{color:var(--dsw-alias-label-primary);margin:0;font-size:17px;font-weight:600;line-height:24px}.VWh0dG_dashboardSubtitle{color:var(--dsw-alias-label-caption);margin:3px 0 0;font-size:12px;line-height:17px}.VWh0dG_closeButton{width:30px;height:30px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;border-radius:8px;flex:none;justify-content:center;align-items:center;transition:background-color .14s;display:inline-flex}.VWh0dG_closeButton:hover{background:var(--dsw-alias-interactive-bg-hover)}.VWh0dG_closeButton svg{stroke-width:2px;width:16px;height:16px}.VWh0dG_dashboardBody{flex-direction:column;gap:14px;padding:16px 24px 24px;display:flex;overflow-y:auto}.VWh0dG_tabNav{border-bottom:1px solid var(--dsw-alias-border-l1);align-items:center;gap:4px;padding:10px 24px;display:flex}.VWh0dG_tabButton{color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:none;border-radius:999px;padding:5px 14px;font-size:12.5px;font-weight:500;line-height:18px;transition:background-color .16s,color .16s,box-shadow .16s}.VWh0dG_tabButton:hover,.VWh0dG_tabButton:focus-visible{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-interactive-bg-hover);outline:none}.VWh0dG_tabButtonActive,.VWh0dG_tabButtonActive:hover,.VWh0dG_tabButtonActive:focus-visible{background:linear-gradient(135deg, var(--dsw-static-blue-500), color-mix(in srgb, var(--dsw-static-blue-500) 72%, var(--dsw-static-blue-400)));color:var(--dsw-static-neutral-bluish-00);box-shadow:0 2px 10px -3px color-mix(in srgb, var(--dsw-static-blue-500) 55%, transparent);font-weight:600}.VWh0dG_tabPanel{flex-direction:column;gap:14px;animation:.14s ease-out VWh0dG_tabPanelIn;display:flex}@keyframes VWh0dG_tabPanelIn{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:none}}.VWh0dG_hero{border:1px solid color-mix(in srgb, var(--dsw-static-blue-500) 16%, var(--dsw-alias-border-l1));background:radial-gradient(90% 150% at 6% 0%, color-mix(in srgb, var(--dsw-static-blue-500) 10%, transparent), transparent 60%), radial-gradient(70% 130% at 96% 100%, color-mix(in srgb, var(--dsw-static-blue-400) 8%, transparent), transparent 55%), var(--dsw-alias-bg-layer-1);border-radius:16px;justify-content:space-between;align-items:center;gap:24px;padding:20px 24px;display:flex;position:relative;overflow:hidden}.VWh0dG_heroMain{flex-direction:column;gap:4px;min-width:0;display:flex}.VWh0dG_heroLabel{color:var(--dsw-alias-label-tertiary);white-space:nowrap;font-size:12px;line-height:17px}.VWh0dG_heroValue{letter-spacing:-.02em;font-variant-numeric:tabular-nums;white-space:nowrap;background:linear-gradient(120deg, var(--dsw-alias-label-primary) 25%, color-mix(in srgb, var(--dsw-static-blue-500) 85%, var(--dsw-alias-label-primary)));color:#0000;-webkit-text-fill-color:transparent;-webkit-background-clip:text;background-clip:text;font-size:44px;font-weight:600;line-height:52px}.VWh0dG_heroMeta{color:var(--dsw-alias-label-caption);white-space:nowrap;font-size:12px;line-height:17px}.VWh0dG_heroSide{border-left:1px solid var(--dsw-alias-border-l1);flex-direction:column;flex:none;gap:10px;padding-left:24px;display:flex}.VWh0dG_heroSideItem{align-items:baseline;gap:8px;display:flex}.VWh0dG_heroSideLabel{color:var(--dsw-alias-label-tertiary);white-space:nowrap;font-size:12px;line-height:17px}.VWh0dG_heroSideValue{color:var(--dsw-alias-label-primary);font-variant-numeric:tabular-nums;white-space:nowrap;font-size:16px;font-weight:600;line-height:22px}.VWh0dG_delta{align-items:center;gap:2px;margin-left:4px;font-size:11px;font-weight:600;line-height:17px;display:inline-flex}.VWh0dG_deltaUp{color:var(--dsw-static-green-500)}.VWh0dG_deltaDown{color:var(--dsw-static-red-500)}.VWh0dG_kpiGrid{grid-template-columns:repeat(4,minmax(0,1fr));gap:12px;display:grid}.VWh0dG_kpiTile{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);border-radius:14px;flex-direction:column;gap:3px;padding:14px 15px;transition:border-color .16s,background-color .16s,transform .16s,box-shadow .16s;display:flex;position:relative;overflow:hidden}.VWh0dG_kpiTile:before{content:\"\";background:linear-gradient(90deg, color-mix(in srgb, var(--dsw-static-blue-500) 70%, transparent), transparent);opacity:.7;height:2px;position:absolute;inset:0 0 auto}.VWh0dG_kpiTile:has(.VWh0dG_kpiGreen):before{background:linear-gradient(90deg, color-mix(in srgb, var(--dsw-static-green-500) 70%, transparent), transparent)}.VWh0dG_kpiTile:hover{border-color:var(--dsw-alias-border-l2);background:var(--dsw-alias-interactive-bg-hover);box-shadow:0 6px 16px -8px color-mix(in srgb, var(--dsw-alias-label-primary) 35%, transparent);transform:translateY(-1px)}.VWh0dG_kpiLabel{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:15px}.VWh0dG_kpiValue{color:var(--dsw-alias-label-primary);font-variant-numeric:tabular-nums;font-size:21px;font-weight:600;line-height:27px}.VWh0dG_kpiGreen{color:var(--dsw-static-green-500)}.VWh0dG_kpiDetail{color:var(--dsw-alias-label-caption);white-space:nowrap;text-overflow:ellipsis;font-size:11px;line-height:15px;overflow:hidden}.VWh0dG_panel{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);border-radius:16px;flex-direction:column;gap:10px;padding:16px 18px;display:flex}.VWh0dG_panelHead{justify-content:space-between;align-items:baseline;gap:10px;display:flex}.VWh0dG_panelTitle{color:var(--dsw-alias-label-primary);margin:0;font-size:14px;font-weight:600;line-height:20px}.VWh0dG_panelHint{color:var(--dsw-alias-label-caption);white-space:nowrap;font-size:11px;line-height:16px}.VWh0dG_rangeToggle{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);border-radius:8px;gap:2px;padding:2px;display:inline-flex}.VWh0dG_rangeButton{color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:none;border-radius:6px;padding:2px 8px;font-size:11px;line-height:16px;transition:background-color .14s,color .14s}.VWh0dG_rangeButtonActive{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary);font-weight:600}.VWh0dG_exportBar{justify-content:flex-end;align-items:center;gap:8px;display:flex}.VWh0dG_exportLabel{color:var(--dsw-alias-label-caption);font-size:11px;line-height:16px}.VWh0dG_exportButton{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-secondary);cursor:pointer;border-radius:999px;padding:4px 12px;font-size:11.5px;line-height:16px;transition:border-color .16s,color .16s,background-color .16s}.VWh0dG_exportButton:hover,.VWh0dG_exportButton:focus-visible{border-color:color-mix(in srgb, var(--dsw-static-blue-500) 40%, var(--dsw-alias-border-l1));color:var(--dsw-static-blue-500);outline:none}.VWh0dG_shareTrack{background:var(--dsw-alias-bg-module-platform);border-radius:999px;height:10px;display:flex;overflow:hidden}.VWh0dG_shareSeg{height:100%;transition:width .2s}.VWh0dG_shareSegPeak{background:linear-gradient(90deg, var(--dsw-static-blue-500), var(--dsw-static-blue-400))}.VWh0dG_shareSegOff{background:color-mix(in srgb, var(--dsw-static-blue-500) 30%, var(--dsw-alias-bg-module-platform))}.VWh0dG_shareSegUser{background:linear-gradient(90deg, var(--dsw-static-blue-500), var(--dsw-static-blue-400))}.VWh0dG_shareSegAssistant{background:linear-gradient(90deg, var(--dsw-static-green-500), color-mix(in srgb, var(--dsw-static-green-500) 70%, var(--dsw-static-blue-400)))}.VWh0dG_shareSegTool{background:color-mix(in srgb, var(--dsw-static-amber-500) 80%, var(--dsw-alias-bg-module-platform))}.VWh0dG_shareLegend{align-items:center;gap:16px;display:flex}.VWh0dG_shareItem{color:var(--dsw-alias-label-secondary);align-items:baseline;gap:6px;font-size:12px;line-height:17px;display:inline-flex}.VWh0dG_shareDot{border-radius:50%;flex:none;align-self:center;width:8px;height:8px}.VWh0dG_shareValue{color:var(--dsw-alias-label-primary);font-variant-numeric:tabular-nums;font-weight:600}.VWh0dG_budget{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);border-radius:14px;flex-direction:column;gap:8px;padding:12px 16px;display:flex}.VWh0dG_budgetHead{justify-content:space-between;align-items:baseline;gap:10px;display:flex}.VWh0dG_budgetLabel{color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:17px}.VWh0dG_budgetValue{color:var(--dsw-alias-label-secondary);font-variant-numeric:tabular-nums;white-space:nowrap;font-size:12px;line-height:17px}.VWh0dG_budgetControls{align-items:center;gap:8px;min-width:0;display:inline-flex}.VWh0dG_budgetInputWrap{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);border-radius:6px;align-items:center;gap:2px;padding:2px 6px;display:inline-flex}.VWh0dG_budgetInputWrap:focus-within{border-color:var(--dsw-alias-border-l3)}.VWh0dG_budgetUnit{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:16px}.VWh0dG_budgetInput{width:64px;color:var(--dsw-alias-label-primary);font-variant-numeric:tabular-nums;text-align:right;background:0 0;border:none;padding:0;font-size:12px;line-height:16px}.VWh0dG_budgetInput:focus-visible{outline:none}.VWh0dG_switch{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-module-platform);cursor:pointer;border-radius:999px;flex:none;width:30px;height:17px;padding:0;transition:background-color .16s,border-color .16s;position:relative}.VWh0dG_switchOn{border-color:var(--dsw-static-blue-500);background:var(--dsw-static-blue-500)}.VWh0dG_switchKnob{background:var(--dsw-static-neutral-bluish-00);border-radius:50%;width:11px;height:11px;transition:transform .16s;position:absolute;top:2px;left:2px}.VWh0dG_switchOn .VWh0dG_switchKnob{transform:translate(13px)}.VWh0dG_budgetTrack{background:var(--dsw-alias-bg-module-platform);border-radius:999px;height:6px;overflow:hidden}.VWh0dG_budgetFill{background:var(--dsw-static-blue-500);border-radius:999px;height:100%;transition:width .2s}.VWh0dG_budgetFillWarn{background:var(--dsw-static-amber-500)}.VWh0dG_budgetFillOver{background:var(--dsw-static-red-500);animation:1.6s ease-in-out infinite VWh0dG_budgetOverPulse}@keyframes VWh0dG_budgetOverPulse{50%{opacity:.55}}.VWh0dG_chartWrap{width:100%;position:relative}.VWh0dG_chartSvg{width:100%;height:auto;display:block}.VWh0dG_chartEmpty{height:140px;color:var(--dsw-alias-label-caption);justify-content:center;align-items:center;font-size:13px;display:flex}.VWh0dG_emptyRow{text-align:center;color:var(--dsw-alias-label-caption);padding:28px 0;font-size:13px}.VWh0dG_chartGrid{stroke:var(--dsw-alias-border-l1);stroke-width:1px}.VWh0dG_chartAxisLabel{fill:var(--dsw-alias-label-tertiary);font-size:10px}.VWh0dG_chartBar{fill:var(--dsw-static-blue-500);opacity:.35}.VWh0dG_chartBar:hover{opacity:.6}.VWh0dG_chartStack{stroke:var(--dsw-alias-bg-layer-1);stroke-width:.75px}.VWh0dG_chartStack:hover{opacity:.85}.VWh0dG_chartLine{stroke:var(--dsw-static-blue-500);stroke-width:2px;stroke-linecap:round;stroke-linejoin:round}.VWh0dG_chartCrosshair{stroke:var(--dsw-alias-label-dimmed);stroke-width:1px;stroke-dasharray:3 3}.VWh0dG_chartDot{fill:var(--dsw-static-neutral-bluish-00);stroke:var(--dsw-static-blue-500);stroke-width:2.5px}.VWh0dG_chartTooltip{pointer-events:none;z-index:2;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);box-shadow:var(--dsw-shadow-lv2);white-space:nowrap;border-radius:10px;padding:8px 10px;position:absolute;transform:translate(-50%,calc(-100% - 10px))}.VWh0dG_chartTooltipDate{color:var(--dsw-alias-label-primary);margin-bottom:3px;font-size:11px;font-weight:600}.VWh0dG_chartTooltipRow{color:var(--dsw-alias-label-secondary);align-items:center;gap:5px;font-size:11px;line-height:17px;display:flex}.VWh0dG_chartTooltipRow strong{color:var(--dsw-alias-label-primary);font-variant-numeric:tabular-nums;font-weight:600}.VWh0dG_chartLegendLine{background:var(--dsw-static-blue-500);border-radius:2px;width:10px;height:3px;display:inline-block}.VWh0dG_chartLegendBar{background:var(--dsw-static-blue-500);opacity:.5;border-radius:2px;width:7px;height:7px;display:inline-block}.VWh0dG_chartTooltipSwatch{border-radius:3px;flex:none;width:8px;height:8px;display:inline-block}.VWh0dG_chartLegend{color:var(--dsw-alias-label-tertiary);justify-content:flex-end;gap:14px;margin-top:2px;font-size:11px;display:flex}.VWh0dG_chartLegend span{align-items:center;gap:5px;display:inline-flex}.VWh0dG_tableScroll{border:1px solid var(--dsw-alias-border-l1);--dsh-scrollbar-thumb:var(--dsw-alias-scrollbar-bg-l2);--dsh-scrollbar-thumb-hover:var(--dsw-alias-scrollbar-hover-l2);border-radius:12px;overflow:auto}.VWh0dG_modelTable,.VWh0dG_pricingTable{border-collapse:collapse;width:100%;font-size:12.5px}.VWh0dG_modelTable th,.VWh0dG_modelTable td,.VWh0dG_pricingTable th,.VWh0dG_pricingTable td{border-bottom:1px solid var(--dsw-alias-border-l1);text-align:left;white-space:nowrap;padding:9px 12px}.VWh0dG_modelTable tbody tr:last-child td,.VWh0dG_pricingTable tbody tr:last-child td{border-bottom:0}.VWh0dG_modelTable thead th,.VWh0dG_pricingTable thead th{color:var(--dsw-alias-label-tertiary);background:var(--dsw-alias-bg-module-platform);font-size:11px;font-weight:500}.VWh0dG_modelTable tbody tr,.VWh0dG_pricingTable tbody tr{transition:background-color .12s}.VWh0dG_modelTable tbody tr:hover,.VWh0dG_pricingTable tbody tr:hover{background:var(--dsw-alias-interactive-bg-hover)}.VWh0dG_numCol{text-align:right;font-variant-numeric:tabular-nums}.VWh0dG_costCol{color:var(--dsw-static-blue-500);font-weight:600}.VWh0dG_na{color:var(--dsw-alias-label-dimmed)}.VWh0dG_modelCell{align-items:center;gap:8px;display:inline-flex}.VWh0dG_modelDot{width:9px;height:9px;box-shadow:0 0 0 3px color-mix(in srgb, var(--dsw-alias-bg-layer-1) 60%, transparent);border-radius:50%;flex:none}.VWh0dG_modelName{color:var(--dsw-alias-label-primary);font-weight:500;line-height:16px;display:block}.VWh0dG_modelProvider{color:var(--dsw-alias-label-caption);font-size:10.5px;line-height:14px;display:block}.VWh0dG_pricingToggle{cursor:pointer;text-align:left;background:0 0;border:none;justify-content:space-between;align-items:center;gap:10px;width:100%;padding:0;display:flex}.VWh0dG_pricingToggle:hover .VWh0dG_panelTitle,.VWh0dG_pricingToggle:focus-visible .VWh0dG_panelTitle{color:var(--dsw-static-blue-500)}.VWh0dG_rateBadge{vertical-align:1px;white-space:nowrap;border-radius:999px;align-items:center;margin-left:6px;padding:1px 6px;font-size:10px;font-weight:500;line-height:14px;display:inline-flex}.VWh0dG_rateBadgeLive{color:var(--dsw-static-green-500);background:color-mix(in srgb, var(--dsw-static-green-500) 10%, transparent)}.VWh0dG_rateBadgeBuiltin{color:var(--dsw-alias-label-tertiary);background:var(--dsw-alias-bg-module-platform)}.VWh0dG_pricingToggleText{align-items:baseline;gap:10px;min-width:0;display:flex}.VWh0dG_pricingChevron{width:16px;height:16px;color:var(--dsw-alias-label-tertiary);flex:none;transition:transform .16s}.VWh0dG_pricingChevronOpen{transform:rotate(180deg)}.VWh0dG_bandPrice{align-items:baseline;gap:6px;display:inline-flex}.VWh0dG_bandPriceOff{color:var(--dsw-alias-label-caption)}.VWh0dG_bandPriceOff:before{content:\"/\";color:var(--dsw-alias-label-dimmed);margin-right:4px}.VWh0dG_bandTag{color:var(--dsw-alias-label-secondary);flex-direction:column;gap:1px;font-size:10.5px;line-height:14px;display:inline-flex}.VWh0dG_bandTagOff{color:var(--dsw-static-green-500);font-weight:600}.VWh0dG_flatTag{color:var(--dsw-alias-label-caption);font-size:10.5px;line-height:14px}.VWh0dG_healthDot{border-radius:50%;flex:none;width:8px;height:8px;display:inline-block}.VWh0dG_healthOk{background:var(--dsw-static-green-500);box-shadow:0 0 0 3px color-mix(in srgb, var(--dsw-static-green-500) 18%, transparent)}.VWh0dG_healthBad{background:var(--dsw-static-red-500);box-shadow:0 0 0 3px color-mix(in srgb, var(--dsw-static-red-500) 18%, transparent)}.VWh0dG_healthIdle{background:var(--dsw-static-neutral-bluish-400)}.VWh0dG_dashboardRight{align-items:center;gap:8px;min-width:0;display:flex}.VWh0dG_healthBadge{white-space:nowrap;border-radius:999px;align-items:center;gap:6px;padding:3px 9px;font-size:11px;line-height:16px;display:inline-flex}.VWh0dG_healthBadgeOk{color:var(--dsw-static-green-500);background:color-mix(in srgb, var(--dsw-static-green-500) 10%, transparent)}.VWh0dG_healthBadgeBad{color:var(--dsw-static-red-500);background:color-mix(in srgb, var(--dsw-static-red-500) 10%, transparent)}.VWh0dG_planTag{color:var(--dsw-static-green-500);background:color-mix(in srgb, var(--dsw-static-green-500) 12%, transparent);border-radius:999px;align-items:center;padding:1px 8px;font-size:11px;font-weight:500;line-height:17px;display:inline-flex}.VWh0dG_uncataloguedTag{vertical-align:1px;color:var(--dsw-static-amber-500);background:color-mix(in srgb, var(--dsw-static-amber-500) 12%, transparent);border-radius:999px;margin-left:6px;padding:0 6px;font-size:10px;font-weight:600;line-height:16px;display:inline-block}.VWh0dG_estimatedTag{vertical-align:1px;color:var(--dsw-static-blue-500);background:color-mix(in srgb, var(--dsw-static-blue-500) 12%, transparent);border-radius:999px;margin-left:6px;padding:0 6px;font-size:10px;font-weight:600;line-height:16px;display:inline-block}.VWh0dG_liveCostBar{color:var(--dsw-static-neutral-400);font-variant-numeric:tabular-nums;align-items:center;gap:6px;font-size:11px;line-height:16px;display:inline-flex}.VWh0dG_liveCostItem{white-space:nowrap}.VWh0dG_liveCostSep{color:var(--dsw-static-neutral-300)}.VWh0dG_balanceCell{flex-direction:column;align-items:flex-end;gap:2px;display:inline-flex}.VWh0dG_balanceDays{color:var(--dsw-alias-label-caption);white-space:nowrap;font-size:10.5px;line-height:14px}.VWh0dG_balanceDaysLow{color:var(--dsw-static-red-500);font-weight:600}body[data-zine-mode] .VWh0dG_trigger,body[data-zine-mode] .VWh0dG_triggerPop,body[data-zine-mode] .VWh0dG_railButton{display:none}body[data-zine-mode] .VWh0dG_dashboardHead{background:#000;border-bottom:2px solid #e8ff00}body[data-zine-mode] .VWh0dG_headTitleRow{align-items:center;gap:8px;margin-top:4px;display:flex}body[data-zine-mode] .VWh0dG_dashboardTitle{color:#e8ff00;letter-spacing:.04em;text-transform:uppercase;text-shadow:0 0 8px #e8ff0066;font-weight:900}body[data-zine-mode] .VWh0dG_dashboardSubtitle{color:#c9d98a;letter-spacing:.08em;text-transform:uppercase;font-size:10px}body[data-zine-mode] .VWh0dG_closeButton{color:#0a0a05;background:#ff2d95;border:1.5px solid #ff2d95;border-radius:0;box-shadow:0 0 10px #ff2d9573}body[data-zine-mode] .VWh0dG_hero{background:#000;border:2.5px solid #e8ff00;border-radius:0;position:relative;box-shadow:0 0 0 1px #0009,0 0 24px #e8ff002e}body[data-zine-mode] .VWh0dG_heroLabel{color:#c9d98a;letter-spacing:.12em;text-transform:uppercase;font-size:10px;font-weight:900}body[data-zine-mode] .VWh0dG_heroValue{color:#e8ff00;letter-spacing:-.02em;text-shadow:0 0 12px #e8ff0073;-webkit-text-fill-color:#e8ff00;background:0 0;font-size:38px;font-weight:900}body[data-zine-mode] .VWh0dG_heroMeta{color:#c9d98a;letter-spacing:.06em;text-transform:uppercase;font-size:10.5px}body[data-zine-mode] .VWh0dG_heroSideLabel{color:#c9d98a;letter-spacing:.1em;text-transform:uppercase;font-size:10px;font-weight:900}body[data-zine-mode] .VWh0dG_heroSideValue{color:#e8ff00;text-shadow:0 0 6px #e8ff0059}body[data-zine-mode] .VWh0dG_delta{font-weight:900}body[data-zine-mode] .VWh0dG_deltaUp{color:#ff2d95}body[data-zine-mode] .VWh0dG_deltaDown{color:#c9d98a}body[data-zine-mode] .VWh0dG_tabNav{background:#000;border-bottom:2px solid #e8ff00}body[data-zine-mode] .VWh0dG_tabButton{color:#c9d98a;letter-spacing:.08em;text-transform:uppercase;border-radius:0;font-size:10.5px;font-weight:900}body[data-zine-mode] .VWh0dG_tabButton:hover,body[data-zine-mode] .VWh0dG_tabButton:focus-visible{color:#e8ff00;background:#e8ff001f}body[data-zine-mode] .VWh0dG_tabButtonActive,body[data-zine-mode] .VWh0dG_tabButtonActive:hover,body[data-zine-mode] .VWh0dG_tabButtonActive:focus-visible{color:#0a0a05;background:#e8ff00;box-shadow:0 0 10px #e8ff0073}body[data-zine-mode] .VWh0dG_panel{background:#000;border:2px solid #e8ff00;border-radius:0}body[data-zine-mode] .VWh0dG_trendPanel{position:relative}body[data-zine-mode] .VWh0dG_panelTitle{color:#e8ff00;letter-spacing:.06em;text-transform:uppercase;text-shadow:0 0 6px #e8ff0066;font-weight:900}body[data-zine-mode] .VWh0dG_panelHint{color:#c9d98a;letter-spacing:.08em;text-transform:uppercase;font-size:10px;font-weight:900}body[data-zine-mode] .VWh0dG_modelTableScroll{background:#000;border:1.5px solid #e8ff0080;border-radius:0}.VWh0dG_currencyToggle{border:1px solid var(--dsw-alias-border-muted,#3a4250);background:var(--dsw-alias-bg-layer-2,#232a33);border-radius:6px;align-items:center;gap:2px;margin-right:8px;padding:2px;display:inline-flex}.VWh0dG_currencyButton{color:var(--dsw-alias-text-secondary,#9aa5b1);cursor:pointer;background:0 0;border:0;border-radius:4px;padding:4px 7px;font-size:11px;font-weight:700;line-height:1}.VWh0dG_currencyButtonActive{background:var(--dsw-alias-accent-muted,#2f6fed);color:#fff}.VWh0dG_subscriptionGrid{grid-template-columns:repeat(auto-fill,minmax(240px,1fr));gap:10px;margin-top:10px;display:grid}.VWh0dG_subscriptionCard{border:1px solid var(--dsw-alias-border-muted,#3a4250);background:var(--dsw-alias-bg-layer-2,#232a33);border-radius:8px;padding:10px 12px}.VWh0dG_subscriptionHead{align-items:baseline;gap:8px;margin-bottom:6px;display:flex}.VWh0dG_subscriptionName{font-size:13px;font-weight:700}.VWh0dG_subscriptionPlan{color:var(--dsw-alias-text-secondary,#9aa5b1);font-size:11px}.VWh0dG_subscriptionStatus{color:var(--dsw-alias-warning,#e0a63c);margin-bottom:6px;font-size:11px}.VWh0dG_subscriptionWindow{align-items:center;gap:8px;margin-top:6px;font-size:11px;display:flex}.VWh0dG_subscriptionWindowLabel{color:var(--dsw-alias-text-secondary,#9aa5b1);flex:0 0 44px}.VWh0dG_subscriptionTrack{background:var(--dsw-alias-bg-layer-3,#1a2028);border-radius:3px;flex:1;height:5px;overflow:hidden}.VWh0dG_subscriptionFill{background:var(--dsw-alias-accent,#3b82f6);border-radius:3px;height:100%;display:block}.VWh0dG_subscriptionPct{text-align:right;font-variant-numeric:tabular-nums;flex:none;min-width:52px}.VWh0dG_subscriptionReset{color:var(--dsw-alias-text-secondary,#9aa5b1);flex:none}.VWh0dG_providerGroupList{flex-direction:column;gap:10px;display:flex}.VWh0dG_providerGroup{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);border-radius:12px;padding:12px 14px}.VWh0dG_providerGroupHead{justify-content:space-between;align-items:baseline;gap:12px;display:flex}.VWh0dG_providerGroupTitle{align-items:center;gap:7px;min-width:0;display:inline-flex}.VWh0dG_providerGroupName{color:var(--dsw-alias-label-primary);font-size:13px;font-weight:600;line-height:18px}.VWh0dG_providerGroupMeta{flex:none;align-items:center;gap:10px;display:inline-flex}.VWh0dG_providerGroupBadge{color:var(--dsw-static-green-500);background:color-mix(in srgb, var(--dsw-static-green-500) 12%, transparent);border-radius:999px;align-items:center;padding:1px 8px;font-size:11px;font-weight:500;line-height:17px;display:inline-flex}.VWh0dG_providerGroupBalance{color:var(--dsw-alias-label-secondary);font-variant-numeric:tabular-nums;white-space:nowrap;align-items:baseline;gap:6px;font-size:12px;line-height:17px;display:inline-flex}.VWh0dG_providerGroupBalanceLabel{color:var(--dsw-alias-label-caption);font-size:11px;line-height:17px}.VWh0dG_roundsFlagBadge{color:#fff;background:#ef4444;border-radius:999px;margin-left:8px;padding:1px 7px;font-size:10px;font-weight:800}.VWh0dG_rounds{margin-top:10px}.VWh0dG_roundsBars{align-items:flex-end;gap:3px;height:110px;padding:4px 2px 0;display:flex;overflow-x:auto}.VWh0dG_roundsBarCol{flex-direction:column;flex:1 0 28px;justify-content:flex-end;align-items:stretch;height:100%;display:flex}.VWh0dG_roundsBarLabel{text-align:center;color:var(--dsw-alias-text-secondary,#9aa5b1);white-space:nowrap;text-overflow:ellipsis;max-width:100%;margin-bottom:2px;font-size:8px;line-height:1;overflow:hidden}.VWh0dG_roundsBarWrap{flex:1;align-items:flex-end;min-height:0;display:flex}.VWh0dG_roundsBar{background:var(--dsw-alias-accent,#3b82f6);border-radius:2px 2px 0 0;width:100%;min-height:2px;position:relative}.VWh0dG_roundsBarFlagged{outline-offset:1px;background:#ef4444;border-radius:2px 2px 0 0;outline:1.5px solid #ef4444;width:100%;min-height:2px;position:relative}.VWh0dG_roundsFlagMark{background:#ef4444;border-radius:50%;width:7px;height:7px;position:absolute;top:-3px;right:-3px;box-shadow:0 0 4px #ef4444}.VWh0dG_roundsAxis{color:var(--dsw-alias-text-secondary,#9aa5b1);justify-content:space-between;margin-top:6px;font-size:10px;display:flex}.VWh0dG_roundsEmpty{color:var(--dsw-alias-text-secondary,#9aa5b1);margin-top:10px;font-size:12px}.VWh0dG_heatmap{margin-top:10px}.VWh0dG_heatmapGrid{grid-template-columns:repeat(7,minmax(0,1fr));gap:8px;display:grid}.VWh0dG_heatmapCellEmpty{background:var(--dsw-alias-bg-layer-1);height:30px;color:var(--dsw-alias-label-dimmed,#6b7480);font-variant-numeric:tabular-nums;border-radius:8px;justify-content:center;align-items:center;font-size:11px;display:flex}.VWh0dG_heatmapCell{font-variant-numeric:tabular-nums;cursor:pointer;border:0;border-radius:8px;justify-content:center;align-items:center;height:30px;padding:0;font-size:11px;display:flex}.VWh0dG_heatmapCell[data-level=\"0\"],.VWh0dG_heatmapCell[data-level=\"1\"],.VWh0dG_heatmapCell[data-level=\"2\"]{color:var(--dsw-alias-label-primary)}.VWh0dG_heatmapCell[data-level=\"3\"],.VWh0dG_heatmapCell[data-level=\"4\"]{color:var(--dsw-static-neutral-bluish-00,#fff)}.VWh0dG_heatmapFooter{color:var(--dsw-alias-text-secondary,#9aa5b1);align-items:center;gap:8px;margin-top:10px;font-size:10px;display:flex}.VWh0dG_heatmapLegend{gap:3px;display:inline-flex}.VWh0dG_heatmapLegend i{border-radius:4px;width:14px;height:14px;display:block}.VWh0dG_heatmapHover{font-variant-numeric:tabular-nums;margin-left:auto}@media (width<=640px){.VWh0dG_kpiGrid{grid-template-columns:repeat(2,minmax(0,1fr))}.VWh0dG_hero{flex-direction:column;align-items:flex-start;gap:14px}.VWh0dG_heroSide{border-left:none;border-top:1px solid var(--dsw-alias-border-l1);flex-direction:row;align-self:stretch;gap:20px;padding-top:14px;padding-left:0}}";
28
28
  const tagId = "@kenz1117/dsh-ui-usage-billing/UsageBilling.module.css";
29
29
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
30
30
  const tag = document.createElement("style");
@@ -34,170 +34,192 @@ window.__ModuleLoader__.load({
34
34
  document.head.appendChild(tag);
35
35
  }
36
36
  var UsageBilling_module_css_default = {
37
- "panelHead": "VWh0dG_panelHead",
38
- "bandPrice": "VWh0dG_bandPrice",
37
+ "subscriptionGrid": "VWh0dG_subscriptionGrid",
38
+ "roundsBarLabel": "VWh0dG_roundsBarLabel",
39
+ "heatmapLegend": "VWh0dG_heatmapLegend",
40
+ "trendPanel": "VWh0dG_trendPanel",
41
+ "chartGrid": "VWh0dG_chartGrid",
42
+ "chartLegend": "VWh0dG_chartLegend",
43
+ "triggerIcon": "VWh0dG_triggerIcon",
44
+ "chartSvg": "VWh0dG_chartSvg",
45
+ "budgetUnit": "VWh0dG_budgetUnit",
46
+ "shareDot": "VWh0dG_shareDot",
47
+ "healthBad": "VWh0dG_healthBad",
48
+ "pricingToggleText": "VWh0dG_pricingToggleText",
49
+ "rangeButton": "VWh0dG_rangeButton",
50
+ "planTag": "VWh0dG_planTag",
51
+ "chartWrap": "VWh0dG_chartWrap",
52
+ "heatmapCell": "VWh0dG_heatmapCell",
53
+ "budgetControls": "VWh0dG_budgetControls",
54
+ "kpiLabel": "VWh0dG_kpiLabel",
55
+ "triggerAmountSub": "VWh0dG_triggerAmountSub",
56
+ "budgetLabel": "VWh0dG_budgetLabel",
57
+ "rangeButtonActive": "VWh0dG_rangeButtonActive",
58
+ "numCol": "VWh0dG_numCol",
59
+ "panel": "VWh0dG_panel",
60
+ "chartAxisLabel": "VWh0dG_chartAxisLabel",
61
+ "budgetInputWrap": "VWh0dG_budgetInputWrap",
62
+ "shareSeg": "VWh0dG_shareSeg",
63
+ "chartTooltipDate": "VWh0dG_chartTooltipDate",
64
+ "subscriptionHead": "VWh0dG_subscriptionHead",
65
+ "emptyRow": "VWh0dG_emptyRow",
66
+ "uncataloguedTag": "VWh0dG_uncataloguedTag",
67
+ "shareSegPeak": "VWh0dG_shareSegPeak",
68
+ "subscriptionFill": "VWh0dG_subscriptionFill",
39
69
  "chartDot": "VWh0dG_chartDot",
40
- "healthBadgeOk": "VWh0dG_healthBadgeOk",
41
- "headTitleRow": "VWh0dG_headTitleRow",
70
+ "panelHint": "VWh0dG_panelHint",
71
+ "tableScroll": "VWh0dG_tableScroll",
42
72
  "estimatedTag": "VWh0dG_estimatedTag",
43
- "tabButtonActive": "VWh0dG_tabButtonActive",
44
- "flatTag": "VWh0dG_flatTag",
45
- "roundsBarFlagged": "VWh0dG_roundsBarFlagged",
46
- "rangeToggle": "VWh0dG_rangeToggle",
47
- "liveCostSep": "VWh0dG_liveCostSep",
48
- "heatmapCellEmpty": "VWh0dG_heatmapCellEmpty",
73
+ "budget": "VWh0dG_budget",
74
+ "chartStack": "VWh0dG_chartStack",
75
+ "tabNav": "VWh0dG_tabNav",
76
+ "budgetOverPulse": "VWh0dG_budgetOverPulse",
77
+ "healthBadgeBad": "VWh0dG_healthBadgeBad",
78
+ "providerGroupBadge": "VWh0dG_providerGroupBadge",
79
+ "rateBadgeBuiltin": "VWh0dG_rateBadgeBuiltin",
80
+ "exportLabel": "VWh0dG_exportLabel",
81
+ "exportBar": "VWh0dG_exportBar",
82
+ "heroSide": "VWh0dG_heroSide",
83
+ "triggerPopValue": "VWh0dG_triggerPopValue",
84
+ "healthOk": "VWh0dG_healthOk",
85
+ "subscriptionCard": "VWh0dG_subscriptionCard",
86
+ "chartLine": "VWh0dG_chartLine",
87
+ "providerGroupName": "VWh0dG_providerGroupName",
88
+ "bandPrice": "VWh0dG_bandPrice",
89
+ "dashboardModal": "VWh0dG_dashboardModal",
90
+ "pricingToggle": "VWh0dG_pricingToggle",
91
+ "shareSegOff": "VWh0dG_shareSegOff",
49
92
  "triggerAmount": "VWh0dG_triggerAmount",
50
- "kpiDetail": "VWh0dG_kpiDetail",
51
- "chartSvg": "VWh0dG_chartSvg",
52
- "subscriptionReset": "VWh0dG_subscriptionReset",
53
- "rateBadge": "VWh0dG_rateBadge",
54
- "roundsBarCol": "VWh0dG_roundsBarCol",
55
- "chartLegendLine": "VWh0dG_chartLegendLine",
56
- "healthBadge": "VWh0dG_healthBadge",
57
- "heroMeta": "VWh0dG_heroMeta",
58
- "tabPanelIn": "VWh0dG_tabPanelIn",
59
- "chartEmpty": "VWh0dG_chartEmpty",
93
+ "dashboardHead": "VWh0dG_dashboardHead",
94
+ "heatmapCellEmpty": "VWh0dG_heatmapCellEmpty",
60
95
  "subscriptionPct": "VWh0dG_subscriptionPct",
61
- "budgetOverPulse": "VWh0dG_budgetOverPulse",
62
- "subscriptionHead": "VWh0dG_subscriptionHead",
63
- "dashboardBody": "VWh0dG_dashboardBody",
64
- "chartTooltipRow": "VWh0dG_chartTooltipRow",
65
- "liveCostBar": "VWh0dG_liveCostBar",
66
- "budgetUnit": "VWh0dG_budgetUnit",
96
+ "triggerPopBar": "VWh0dG_triggerPopBar",
97
+ "chartCrosshair": "VWh0dG_chartCrosshair",
98
+ "heroMeta": "VWh0dG_heroMeta",
99
+ "shareSegUser": "VWh0dG_shareSegUser",
100
+ "switchOn": "VWh0dG_switchOn",
101
+ "budgetValue": "VWh0dG_budgetValue",
102
+ "liveCostItem": "VWh0dG_liveCostItem",
103
+ "heroMain": "VWh0dG_heroMain",
67
104
  "currencyButton": "VWh0dG_currencyButton",
68
- "budget": "VWh0dG_budget",
69
- "switchKnob": "VWh0dG_switchKnob",
70
- "panelTitle": "VWh0dG_panelTitle",
71
- "healthOk": "VWh0dG_healthOk",
72
- "currencyToggle": "VWh0dG_currencyToggle",
73
- "heroValue": "VWh0dG_heroValue",
74
- "triggerMeta": "VWh0dG_triggerMeta",
75
- "heroSide": "VWh0dG_heroSide",
76
- "providerGroupList": "VWh0dG_providerGroupList",
77
- "rateBadgeBuiltin": "VWh0dG_rateBadgeBuiltin",
78
- "chartAxisLabel": "VWh0dG_chartAxisLabel",
79
- "dashboard": "VWh0dG_dashboard",
80
- "pricingChevronOpen": "VWh0dG_pricingChevronOpen",
81
- "roundsEmpty": "VWh0dG_roundsEmpty",
82
- "bandTag": "VWh0dG_bandTag",
83
- "chartGrid": "VWh0dG_chartGrid",
84
- "roundsBars": "VWh0dG_roundsBars",
105
+ "chartBar": "VWh0dG_chartBar",
85
106
  "modelTable": "VWh0dG_modelTable",
86
- "heroSideItem": "VWh0dG_heroSideItem",
87
- "kpiLabel": "VWh0dG_kpiLabel",
88
- "kpiGreen": "VWh0dG_kpiGreen",
89
- "budgetFill": "VWh0dG_budgetFill",
90
- "kpiTile": "VWh0dG_kpiTile",
91
- "trigger": "VWh0dG_trigger",
107
+ "budgetFillOver": "VWh0dG_budgetFillOver",
108
+ "modelTableScroll": "VWh0dG_modelTableScroll",
109
+ "providerGroup": "VWh0dG_providerGroup",
110
+ "bandTag": "VWh0dG_bandTag",
111
+ "dashboardTitle": "VWh0dG_dashboardTitle",
92
112
  "bandPriceOff": "VWh0dG_bandPriceOff",
93
- "liveCostItem": "VWh0dG_liveCostItem",
113
+ "healthIdle": "VWh0dG_healthIdle",
114
+ "balanceCell": "VWh0dG_balanceCell",
94
115
  "subscriptionTrack": "VWh0dG_subscriptionTrack",
95
- "na": "VWh0dG_na",
116
+ "roundsBar": "VWh0dG_roundsBar",
117
+ "panelTitle": "VWh0dG_panelTitle",
118
+ "kpiTile": "VWh0dG_kpiTile",
119
+ "rateBadge": "VWh0dG_rateBadge",
96
120
  "delta": "VWh0dG_delta",
97
- "heroSideLabel": "VWh0dG_heroSideLabel",
98
- "pricingToggleText": "VWh0dG_pricingToggleText",
99
- "rangeButtonActive": "VWh0dG_rangeButtonActive",
100
- "budgetFillOver": "VWh0dG_budgetFillOver",
101
- "chartStack": "VWh0dG_chartStack",
102
- "closeButton": "VWh0dG_closeButton",
103
- "budgetLabel": "VWh0dG_budgetLabel",
104
- "heroLabel": "VWh0dG_heroLabel",
105
- "numCol": "VWh0dG_numCol",
106
- "rangeButton": "VWh0dG_rangeButton",
107
- "balanceCell": "VWh0dG_balanceCell",
108
- "balanceDaysLow": "VWh0dG_balanceDaysLow",
121
+ "chartEmpty": "VWh0dG_chartEmpty",
122
+ "flatTag": "VWh0dG_flatTag",
123
+ "liveCostBar": "VWh0dG_liveCostBar",
109
124
  "currencyButtonActive": "VWh0dG_currencyButtonActive",
110
- "deltaDown": "VWh0dG_deltaDown",
111
- "heroSideValue": "VWh0dG_heroSideValue",
112
- "switchOn": "VWh0dG_switchOn",
113
- "emptyRow": "VWh0dG_emptyRow",
114
- "modelTableScroll": "VWh0dG_modelTableScroll",
115
- "heroMain": "VWh0dG_heroMain",
116
- "budgetTrack": "VWh0dG_budgetTrack",
117
- "chartBar": "VWh0dG_chartBar",
118
- "budgetValue": "VWh0dG_budgetValue",
119
- "chartLegend": "VWh0dG_chartLegend",
120
- "rounds": "VWh0dG_rounds",
121
- "modelDot": "VWh0dG_modelDot",
122
- "switch": "VWh0dG_switch",
123
- "panel": "VWh0dG_panel",
124
- "roundsBarLabel": "VWh0dG_roundsBarLabel",
125
- "pricingTable": "VWh0dG_pricingTable",
126
- "dashboardHead": "VWh0dG_dashboardHead",
125
+ "pricingChevron": "VWh0dG_pricingChevron",
126
+ "shareSegAssistant": "VWh0dG_shareSegAssistant",
127
+ "providerGroupTitle": "VWh0dG_providerGroupTitle",
128
+ "dashboardIn": "VWh0dG_dashboardIn",
129
+ "heatmap": "VWh0dG_heatmap",
127
130
  "healthDot": "VWh0dG_healthDot",
128
- "triggerMonth": "VWh0dG_triggerMonth",
129
131
  "providerGroupHead": "VWh0dG_providerGroupHead",
130
- "modelProvider": "VWh0dG_modelProvider",
131
- "triggerAmountSub": "VWh0dG_triggerAmountSub",
132
- "triggerToday": "VWh0dG_triggerToday",
133
- "deltaUp": "VWh0dG_deltaUp",
134
- "heatmapGrid": "VWh0dG_heatmapGrid",
135
- "chartWrap": "VWh0dG_chartWrap",
136
- "subscriptionFill": "VWh0dG_subscriptionFill",
137
- "subscriptionStatus": "VWh0dG_subscriptionStatus",
138
- "subscriptionWindowLabel": "VWh0dG_subscriptionWindowLabel",
139
- "roundsFlagMark": "VWh0dG_roundsFlagMark",
140
- "heatmapCell": "VWh0dG_heatmapCell",
141
- "providerGroupTitle": "VWh0dG_providerGroupTitle",
142
- "tabPanel": "VWh0dG_tabPanel",
143
- "dashboardRight": "VWh0dG_dashboardRight",
144
- "triggerIcon": "VWh0dG_triggerIcon",
145
- "subscriptionCard": "VWh0dG_subscriptionCard",
146
- "providerGroup": "VWh0dG_providerGroup",
147
- "tabNav": "VWh0dG_tabNav",
148
- "subscriptionName": "VWh0dG_subscriptionName",
149
- "budgetInputWrap": "VWh0dG_budgetInputWrap",
150
132
  "subscriptionPlan": "VWh0dG_subscriptionPlan",
133
+ "providerGroupList": "VWh0dG_providerGroupList",
134
+ "triggerMonth": "VWh0dG_triggerMonth",
135
+ "dashboard": "VWh0dG_dashboard",
136
+ "hero": "VWh0dG_hero",
137
+ "chartTooltipSwatch": "VWh0dG_chartTooltipSwatch",
138
+ "subscriptionName": "VWh0dG_subscriptionName",
139
+ "tabPanelIn": "VWh0dG_tabPanelIn",
140
+ "heroSideValue": "VWh0dG_heroSideValue",
141
+ "healthBadgeOk": "VWh0dG_healthBadgeOk",
142
+ "triggerPop": "VWh0dG_triggerPop",
143
+ "shareItem": "VWh0dG_shareItem",
144
+ "subscriptionReset": "VWh0dG_subscriptionReset",
145
+ "chartLegendLine": "VWh0dG_chartLegendLine",
146
+ "budgetFill": "VWh0dG_budgetFill",
147
+ "providerGroupMeta": "VWh0dG_providerGroupMeta",
148
+ "providerGroupBalance": "VWh0dG_providerGroupBalance",
149
+ "providerGroupBalanceLabel": "VWh0dG_providerGroupBalanceLabel",
150
+ "dashboardRight": "VWh0dG_dashboardRight",
151
+ "subscriptionStatus": "VWh0dG_subscriptionStatus",
152
+ "closeButton": "VWh0dG_closeButton",
153
+ "modelName": "VWh0dG_modelName",
154
+ "triggerPopBars": "VWh0dG_triggerPopBars",
155
+ "dashboardBody": "VWh0dG_dashboardBody",
151
156
  "triggerDivider": "VWh0dG_triggerDivider",
152
- "heatmap": "VWh0dG_heatmap",
153
- "subscriptionGrid": "VWh0dG_subscriptionGrid",
154
- "providerGroupName": "VWh0dG_providerGroupName",
155
- "dashboardIn": "VWh0dG_dashboardIn",
156
- "panelHint": "VWh0dG_panelHint",
157
- "chartLine": "VWh0dG_chartLine",
157
+ "triggerMeta": "VWh0dG_triggerMeta",
158
+ "deltaUp": "VWh0dG_deltaUp",
158
159
  "budgetInput": "VWh0dG_budgetInput",
159
- "budgetControls": "VWh0dG_budgetControls",
160
- "chartTooltip": "VWh0dG_chartTooltip",
161
- "tableScroll": "VWh0dG_tableScroll",
162
- "dashboardModal": "VWh0dG_dashboardModal",
163
- "healthBad": "VWh0dG_healthBad",
164
- "trendPanel": "VWh0dG_trendPanel",
165
- "heatmapFooter": "VWh0dG_heatmapFooter",
160
+ "chartTooltipRow": "VWh0dG_chartTooltipRow",
161
+ "roundsFlagBadge": "VWh0dG_roundsFlagBadge",
162
+ "modelProvider": "VWh0dG_modelProvider",
163
+ "budgetFillWarn": "VWh0dG_budgetFillWarn",
164
+ "rateBadgeLive": "VWh0dG_rateBadgeLive",
165
+ "liveCostSep": "VWh0dG_liveCostSep",
166
+ "subscriptionWindowLabel": "VWh0dG_subscriptionWindowLabel",
167
+ "roundsBarCol": "VWh0dG_roundsBarCol",
166
168
  "heatmapHover": "VWh0dG_heatmapHover",
167
- "tabButton": "VWh0dG_tabButton",
168
- "chartTooltipSwatch": "VWh0dG_chartTooltipSwatch",
169
- "healthIdle": "VWh0dG_healthIdle",
170
- "budgetHead": "VWh0dG_budgetHead",
171
- "balanceDays": "VWh0dG_balanceDays",
172
169
  "subscriptionWindow": "VWh0dG_subscriptionWindow",
173
- "roundsBar": "VWh0dG_roundsBar",
174
- "kpiValue": "VWh0dG_kpiValue",
175
- "pricingChevron": "VWh0dG_pricingChevron",
170
+ "heroSideLabel": "VWh0dG_heroSideLabel",
171
+ "switchKnob": "VWh0dG_switchKnob",
172
+ "shareTrack": "VWh0dG_shareTrack",
173
+ "shareLegend": "VWh0dG_shareLegend",
174
+ "kpiDetail": "VWh0dG_kpiDetail",
175
+ "kpiGreen": "VWh0dG_kpiGreen",
176
+ "dashboardSubtitle": "VWh0dG_dashboardSubtitle",
177
+ "shareSegTool": "VWh0dG_shareSegTool",
178
+ "modelDot": "VWh0dG_modelDot",
179
+ "rounds": "VWh0dG_rounds",
180
+ "roundsBarFlagged": "VWh0dG_roundsBarFlagged",
181
+ "roundsEmpty": "VWh0dG_roundsEmpty",
182
+ "roundsBars": "VWh0dG_roundsBars",
183
+ "trigger": "VWh0dG_trigger",
184
+ "balanceDaysLow": "VWh0dG_balanceDaysLow",
185
+ "chartTooltip": "VWh0dG_chartTooltip",
186
+ "balanceDays": "VWh0dG_balanceDays",
187
+ "headTitleRow": "VWh0dG_headTitleRow",
188
+ "heroLabel": "VWh0dG_heroLabel",
189
+ "healthBadge": "VWh0dG_healthBadge",
190
+ "deltaDown": "VWh0dG_deltaDown",
191
+ "roundsFlagMark": "VWh0dG_roundsFlagMark",
176
192
  "roundsAxis": "VWh0dG_roundsAxis",
177
- "providerGroupBadge": "VWh0dG_providerGroupBadge",
178
- "dashboardTitle": "VWh0dG_dashboardTitle",
179
- "costCol": "VWh0dG_costCol",
180
- "modelName": "VWh0dG_modelName",
181
- "kpiGrid": "VWh0dG_kpiGrid",
182
- "pricingToggle": "VWh0dG_pricingToggle",
183
- "heatmapLegend": "VWh0dG_heatmapLegend",
184
- "planTag": "VWh0dG_planTag",
185
- "roundsFlagBadge": "VWh0dG_roundsFlagBadge",
186
- "healthBadgeBad": "VWh0dG_healthBadgeBad",
187
- "rateBadgeLive": "VWh0dG_rateBadgeLive",
188
- "providerGroupMeta": "VWh0dG_providerGroupMeta",
189
- "modelCell": "VWh0dG_modelCell",
190
193
  "bandTagOff": "VWh0dG_bandTagOff",
191
- "providerGroupBalanceLabel": "VWh0dG_providerGroupBalanceLabel",
194
+ "kpiValue": "VWh0dG_kpiValue",
195
+ "tabButtonActive": "VWh0dG_tabButtonActive",
196
+ "triggerToday": "VWh0dG_triggerToday",
197
+ "costCol": "VWh0dG_costCol",
198
+ "triggerPopRow": "VWh0dG_triggerPopRow",
199
+ "triggerWrap": "VWh0dG_triggerWrap",
192
200
  "roundsBarWrap": "VWh0dG_roundsBarWrap",
193
- "hero": "VWh0dG_hero",
194
- "dashboardSubtitle": "VWh0dG_dashboardSubtitle",
195
- "uncataloguedTag": "VWh0dG_uncataloguedTag",
196
- "chartCrosshair": "VWh0dG_chartCrosshair",
201
+ "budgetHead": "VWh0dG_budgetHead",
202
+ "triggerPopLabel": "VWh0dG_triggerPopLabel",
203
+ "railButton": "VWh0dG_railButton",
204
+ "na": "VWh0dG_na",
205
+ "budgetTrack": "VWh0dG_budgetTrack",
206
+ "heatmapFooter": "VWh0dG_heatmapFooter",
207
+ "pricingTable": "VWh0dG_pricingTable",
208
+ "exportButton": "VWh0dG_exportButton",
209
+ "heroValue": "VWh0dG_heroValue",
210
+ "switch": "VWh0dG_switch",
211
+ "heroSideItem": "VWh0dG_heroSideItem",
212
+ "heatmapGrid": "VWh0dG_heatmapGrid",
213
+ "shareValue": "VWh0dG_shareValue",
197
214
  "chartLegendBar": "VWh0dG_chartLegendBar",
198
- "chartTooltipDate": "VWh0dG_chartTooltipDate",
199
- "providerGroupBalance": "VWh0dG_providerGroupBalance",
200
- "railButton": "VWh0dG_railButton"
215
+ "pricingChevronOpen": "VWh0dG_pricingChevronOpen",
216
+ "currencyToggle": "VWh0dG_currencyToggle",
217
+ "rangeToggle": "VWh0dG_rangeToggle",
218
+ "tabPanel": "VWh0dG_tabPanel",
219
+ "panelHead": "VWh0dG_panelHead",
220
+ "kpiGrid": "VWh0dG_kpiGrid",
221
+ "tabButton": "VWh0dG_tabButton",
222
+ "modelCell": "VWh0dG_modelCell"
201
223
  };
202
224
  //#endregion
203
225
  //#region src/client/pricing.ts
@@ -238,6 +260,22 @@ window.__ModuleLoader__.load({
238
260
  /** Default share of traffic assumed to fall in the peak band (0..1). */
239
261
  const DEFAULT_PEAK_SHARE = .5;
240
262
  /**
263
+ * 高峰时段判定(北京时间,UTC+8,无夏令时):09:00–12:00、14:00–18:00。
264
+ * @param beijingHour - 北京时间的小时数(0–23)。
265
+ */
266
+ function isPeakHour(beijingHour) {
267
+ return beijingHour >= 9 && beijingHour < 12 || beijingHour >= 14 && beijingHour < 18;
268
+ }
269
+ /**
270
+ * 由时刻(epoch 毫秒)推断计费时段;时刻未知/非法时按高峰计(保守:未知
271
+ * 时刻不低估成本,与社区 dsh-usage-chart 的 tierAt 语义一致)。
272
+ * @param timeMs - Unix epoch 毫秒;null/undefined/NaN 视为未知。
273
+ */
274
+ function tierAt(timeMs) {
275
+ if (timeMs === null || timeMs === void 0 || !Number.isFinite(timeMs)) return "peak";
276
+ return isPeakHour((new Date(timeMs).getUTCHours() + 8) % 24) ? "peak" : "offPeak";
277
+ }
278
+ /**
241
279
  * Built-in catalog of current mainstream models as of 2026-08-16, priced from
242
280
  * each provider's official price page. Domestic providers are OpenAI-API
243
281
  * compatible and publish RMB prices directly; overseas providers publish USD
@@ -1429,6 +1467,64 @@ window.__ModuleLoader__.load({
1429
1467
  return flags;
1430
1468
  }
1431
1469
  //#endregion
1470
+ //#region src/client/export.ts
1471
+ /** CSV 单元格转义:含逗号 / 引号 / 换行的值加双引号并内层引号双写。 */
1472
+ function csvCell(value) {
1473
+ return /[",\n]/.test(value) ? `"${value.replace(/"/g, "\"\"")}"` : value;
1474
+ }
1475
+ /** 金额保留两位小数字符串(导出对账用,不做千分位)。 */
1476
+ function money(value) {
1477
+ return value.toFixed(2);
1478
+ }
1479
+ /** 按日 CSV:日期,调用,输入,输出,缓存命中,缓存未命中,费用(元)。 */
1480
+ function dayRowsCsv(byDay) {
1481
+ return ["date,calls,input,output,cache_hit,cache_miss,cost_cny", ...Object.keys(byDay).sort().map((date) => {
1482
+ const day = byDay[date];
1483
+ if (day === void 0) return "";
1484
+ return [
1485
+ date,
1486
+ day.calls,
1487
+ day.input,
1488
+ day.output,
1489
+ day.cacheHit,
1490
+ day.cacheMiss,
1491
+ money(day.cost)
1492
+ ].join(",");
1493
+ })].join("\n");
1494
+ }
1495
+ /** 项目名取 cwd 末级目录(与统计 Tab 的会话明细同口径)。 */
1496
+ function projectOf(cwd) {
1497
+ if (cwd === void 0) return "";
1498
+ return cwd.split(/[\\/]/).filter(Boolean).pop() ?? cwd;
1499
+ }
1500
+ /** 按会话 CSV:会话 id,标题,项目,调用,费用(元),最后活跃(ISO)。 */
1501
+ function sessionRowsCsv(rows) {
1502
+ return ["session_id,title,project,calls,cost_cny,last_active", ...rows.map((row) => [
1503
+ csvCell(row.id),
1504
+ csvCell(row.title ?? ""),
1505
+ csvCell(projectOf(row.cwd)),
1506
+ row.calls,
1507
+ money(row.cost),
1508
+ row.lastActive > 0 ? new Date(row.lastActive).toISOString() : ""
1509
+ ].join(","))].join("\n");
1510
+ }
1511
+ /** 导出文件名:带日期范围(usage-2026-08-01_2026-08-22.csv);无日期时只带前缀。 */
1512
+ function exportFileName(prefix, ext, dates) {
1513
+ const sorted = [...dates].sort();
1514
+ const first = sorted[0];
1515
+ const last = sorted.at(-1);
1516
+ return `${prefix}${first !== void 0 && last !== void 0 ? `-${first}_${last}` : ""}.${ext}`;
1517
+ }
1518
+ /** 触发浏览器下载(唯一 DOM 副作用;调用方在 click 手势里使用)。 */
1519
+ function downloadText(filename, text, mime) {
1520
+ const url = URL.createObjectURL(new Blob([text], { type: mime }));
1521
+ const anchor = document.createElement("a");
1522
+ anchor.href = url;
1523
+ anchor.download = filename;
1524
+ anchor.click();
1525
+ URL.revokeObjectURL(url);
1526
+ }
1527
+ //#endregion
1432
1528
  //#region src/client/UsageBilling.tsx
1433
1529
  /**
1434
1530
  * UsageBilling: sidebar footer trigger + full billing dashboard modal.
@@ -1475,6 +1571,12 @@ window.__ModuleLoader__.load({
1475
1571
  if (cwd === void 0) return void 0;
1476
1572
  return cwd.split(/[\\/]/).filter(Boolean).pop() ?? cwd;
1477
1573
  }
1574
+ /** 预算提醒档位(百分比):跨档时桌面通知,每档每天最多一次。 */
1575
+ const BUDGET_ALERT_TIERS = [
1576
+ 50,
1577
+ 80,
1578
+ 100
1579
+ ];
1478
1580
  /** Idle health state before the probe settles. */
1479
1581
  const IDLE_HEALTH = {
1480
1582
  checked: false,
@@ -1645,6 +1747,41 @@ window.__ModuleLoader__.load({
1645
1747
  if (avg <= 0) return 0;
1646
1748
  return avg * monthLen;
1647
1749
  }
1750
+ /**
1751
+ * 峰谷时段费用分摊:按每轮的起始时刻(北京时间高峰 9-12 / 14-18)把费用
1752
+ * 归入高峰 / 空闲两档。导出供测试:纯函数。
1753
+ * @param turns - 每轮费用行(需带 startedAt 与 cost)。
1754
+ * @returns 两档费用合计(人民币元)。
1755
+ */
1756
+ function peakOffpeakCost(turns) {
1757
+ let peak = 0;
1758
+ let offPeak = 0;
1759
+ for (const turn of turns) if (tierAt(turn.startedAt) === "peak") peak += turn.cost;
1760
+ else offPeak += turn.cost;
1761
+ return {
1762
+ peak,
1763
+ offPeak
1764
+ };
1765
+ }
1766
+ /**
1767
+ * 近 7 天费用序列(含今天,缺日补 0):触发卡 hover 速览的迷你柱数据源。
1768
+ * 导出供测试:纯函数(日期取本地时区)。
1769
+ * @param byDay - 按日费用表。
1770
+ * @returns 7 个 `{ date, cost }`,最旧在前。
1771
+ */
1772
+ function lastSevenDays(byDay) {
1773
+ const out = [];
1774
+ for (let offset = 6; offset >= 0; offset -= 1) {
1775
+ const day = /* @__PURE__ */ new Date();
1776
+ day.setDate(day.getDate() - offset);
1777
+ const stamp = localDayStamp(day.getTime());
1778
+ out.push({
1779
+ date: stamp,
1780
+ cost: byDay[stamp]?.cost ?? 0
1781
+ });
1782
+ }
1783
+ return out;
1784
+ }
1648
1785
  /** Resolve one provider's dot state: green when live, red when failed, gray when unknown. */
1649
1786
  function providerDot(health, provider) {
1650
1787
  if (!health.checked) return UsageBilling_module_css_default.healthIdle;
@@ -1746,7 +1883,8 @@ window.__ModuleLoader__.load({
1746
1883
  ...typeof candidate.lowBalanceThreshold === "number" ? { lowBalanceThreshold: candidate.lowBalanceThreshold } : {},
1747
1884
  ...Array.isArray(candidate.bySession) ? { bySession: candidate.bySession } : {},
1748
1885
  ...Array.isArray(candidate.byTurn) ? { byTurn: candidate.byTurn } : {},
1749
- ...Array.isArray(candidate.byWorkspace) ? { byWorkspace: candidate.byWorkspace } : {}
1886
+ ...Array.isArray(candidate.byWorkspace) ? { byWorkspace: candidate.byWorkspace } : {},
1887
+ ...candidate.byRole !== null && typeof candidate.byRole === "object" ? { byRole: candidate.byRole } : {}
1750
1888
  };
1751
1889
  } catch {
1752
1890
  return null;
@@ -1817,7 +1955,7 @@ window.__ModuleLoader__.load({
1817
1955
  * @param props - framework props plus `wide` column state.
1818
1956
  */
1819
1957
  function UsageBillingTrigger(props) {
1820
- const { wide, t, onOpen, monthCost, todayCost } = props;
1958
+ const { wide, t, onOpen, monthCost, todayCost, weekCost, days } = props;
1821
1959
  const cardIcon = /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
1822
1960
  viewBox: "0 0 24 24",
1823
1961
  fill: "none",
@@ -1849,42 +1987,91 @@ window.__ModuleLoader__.load({
1849
1987
  title: `${t("billing.title")} · ${formatMoney(monthCost)}`,
1850
1988
  children: cardIcon
1851
1989
  });
1852
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
1853
- type: "button",
1854
- className: UsageBilling_module_css_default.trigger,
1855
- "data-testid": "billing-trigger",
1856
- onClick: onOpen,
1857
- title: `${t("billing.title")} · 本月 ${formatMoney(monthCost)}`,
1858
- children: [
1859
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1860
- className: UsageBilling_module_css_default.triggerIcon,
1861
- "data-testid": "billing-trigger-icon",
1862
- children: cardIcon
1863
- }),
1864
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1865
- className: UsageBilling_module_css_default.triggerToday,
1866
- "data-testid": "billing-trigger-today",
1867
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1868
- className: UsageBilling_module_css_default.triggerMeta,
1869
- children: "今日"
1870
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1871
- className: UsageBilling_module_css_default.triggerAmount,
1872
- children: formatMoney(todayCost)
1873
- })]
1874
- }),
1875
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: UsageBilling_module_css_default.triggerDivider }),
1876
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1877
- className: UsageBilling_module_css_default.triggerMonth,
1878
- "data-testid": "billing-trigger-month",
1879
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1880
- className: UsageBilling_module_css_default.triggerMeta,
1881
- children: "当月"
1882
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1883
- className: UsageBilling_module_css_default.triggerAmountSub,
1884
- children: formatMoney(monthCost)
1885
- })]
1886
- })
1887
- ]
1990
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1991
+ className: UsageBilling_module_css_default.triggerWrap,
1992
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
1993
+ type: "button",
1994
+ className: UsageBilling_module_css_default.trigger,
1995
+ "data-testid": "billing-trigger",
1996
+ onClick: onOpen,
1997
+ title: `${t("billing.title")} · 本月 ${formatMoney(monthCost)}`,
1998
+ children: [
1999
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2000
+ className: UsageBilling_module_css_default.triggerIcon,
2001
+ "data-testid": "billing-trigger-icon",
2002
+ children: cardIcon
2003
+ }),
2004
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
2005
+ className: UsageBilling_module_css_default.triggerToday,
2006
+ "data-testid": "billing-trigger-today",
2007
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2008
+ className: UsageBilling_module_css_default.triggerMeta,
2009
+ children: "今日"
2010
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2011
+ className: UsageBilling_module_css_default.triggerAmount,
2012
+ children: formatMoney(todayCost)
2013
+ })]
2014
+ }),
2015
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: UsageBilling_module_css_default.triggerDivider }),
2016
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
2017
+ className: UsageBilling_module_css_default.triggerMonth,
2018
+ "data-testid": "billing-trigger-month",
2019
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2020
+ className: UsageBilling_module_css_default.triggerMeta,
2021
+ children: "当月"
2022
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2023
+ className: UsageBilling_module_css_default.triggerAmountSub,
2024
+ children: formatMoney(monthCost)
2025
+ })]
2026
+ })
2027
+ ]
2028
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
2029
+ className: UsageBilling_module_css_default.triggerPop,
2030
+ "data-testid": "billing-trigger-pop",
2031
+ "aria-hidden": "true",
2032
+ children: [
2033
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
2034
+ className: UsageBilling_module_css_default.triggerPopRow,
2035
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2036
+ className: UsageBilling_module_css_default.triggerPopLabel,
2037
+ children: t("billing.todayCost")
2038
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2039
+ className: UsageBilling_module_css_default.triggerPopValue,
2040
+ children: formatMoney(todayCost)
2041
+ })]
2042
+ }),
2043
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
2044
+ className: UsageBilling_module_css_default.triggerPopRow,
2045
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2046
+ className: UsageBilling_module_css_default.triggerPopLabel,
2047
+ children: t("billing.weekCost")
2048
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2049
+ className: UsageBilling_module_css_default.triggerPopValue,
2050
+ children: formatMoney(weekCost)
2051
+ })]
2052
+ }),
2053
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
2054
+ className: UsageBilling_module_css_default.triggerPopRow,
2055
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2056
+ className: UsageBilling_module_css_default.triggerPopLabel,
2057
+ children: t("billing.monthCost")
2058
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2059
+ className: UsageBilling_module_css_default.triggerPopValue,
2060
+ children: formatMoney(monthCost)
2061
+ })]
2062
+ }),
2063
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2064
+ className: UsageBilling_module_css_default.triggerPopBars,
2065
+ children: (() => {
2066
+ const max = Math.max(...days.map((d) => d.cost), 0);
2067
+ return days.map((d) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2068
+ className: UsageBilling_module_css_default.triggerPopBar,
2069
+ style: { height: `${max > 0 ? 4 + d.cost / max * 18 : 4}px` }
2070
+ }, d.date));
2071
+ })()
2072
+ })
2073
+ ]
2074
+ })]
1888
2075
  });
1889
2076
  }
1890
2077
  /**
@@ -1898,6 +2085,33 @@ window.__ModuleLoader__.load({
1898
2085
  const rateInfo = getRateInfo();
1899
2086
  const money = (cny) => formatMoney(currency === "usd" ? cnyToUsd(cny) : cny, currency);
1900
2087
  const roundFlags = (0, react.useMemo)(() => flagAnomalies([...turns].reverse()), [turns]);
2088
+ const peakShare = (0, react.useMemo)(() => peakOffpeakCost(turns), [turns]);
2089
+ const roleRows = (0, react.useMemo)(() => {
2090
+ const role = stats.byRole;
2091
+ if (role === void 0) return [];
2092
+ const total = role.user + role.assistant + role.tool;
2093
+ if (total <= 0) return [];
2094
+ return [
2095
+ {
2096
+ label: t("billing.roleUser"),
2097
+ value: role.user,
2098
+ seg: UsageBilling_module_css_default.shareSegUser
2099
+ },
2100
+ {
2101
+ label: t("billing.roleAssistant"),
2102
+ value: role.assistant,
2103
+ seg: UsageBilling_module_css_default.shareSegAssistant
2104
+ },
2105
+ {
2106
+ label: t("billing.roleTool"),
2107
+ value: role.tool,
2108
+ seg: UsageBilling_module_css_default.shareSegTool
2109
+ }
2110
+ ].map((row) => ({
2111
+ ...row,
2112
+ pct: row.value / total * 100
2113
+ }));
2114
+ }, [stats.byRole, t]);
1901
2115
  const dailyBurn = dailyBurnRate(byDay, localDayStamp());
1902
2116
  const balanceFor = (provider) => balances.find((balance) => normalizeProvider(balance.provider) === normalizeProvider(provider));
1903
2117
  const renderBalance = (balance) => {
@@ -2279,7 +2493,7 @@ window.__ModuleLoader__.load({
2279
2493
  className: UsageBilling_module_css_default.budgetTrack,
2280
2494
  "data-testid": "billing-budget-track",
2281
2495
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2282
- className: clsx(UsageBilling_module_css_default.budgetFill, pct >= 100 && UsageBilling_module_css_default.budgetFillOver),
2496
+ className: clsx(UsageBilling_module_css_default.budgetFill, pct >= 100 && UsageBilling_module_css_default.budgetFillOver, pct >= 80 && pct < 100 && UsageBilling_module_css_default.budgetFillWarn),
2283
2497
  style: { width: `${Math.min(pct, 100)}%` }
2284
2498
  })
2285
2499
  });
@@ -2400,66 +2614,143 @@ window.__ModuleLoader__.load({
2400
2614
  tab === "trends" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2401
2615
  className: UsageBilling_module_css_default.tabPanel,
2402
2616
  "data-testid": "billing-tab-panel-trends",
2403
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
2404
- className: clsx(UsageBilling_module_css_default.panel, UsageBilling_module_css_default.trendPanel),
2405
- "data-testid": "billing-panel-trend",
2406
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2407
- className: UsageBilling_module_css_default.panelHead,
2408
- children: [
2409
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
2410
- className: UsageBilling_module_css_default.panelTitle,
2411
- children: t("billing.trend")
2412
- }),
2413
- renderSlot("billing.dashboard.decor", { position: "trend" }),
2414
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2415
- className: UsageBilling_module_css_default.rangeToggle,
2416
- role: "group",
2417
- "aria-label": t("billing.trend"),
2418
- children: [7, 30].map((days) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2419
- type: "button",
2420
- className: clsx(UsageBilling_module_css_default.rangeButton, trendDays === days && UsageBilling_module_css_default.rangeButtonActive),
2421
- "aria-pressed": trendDays === days,
2422
- "data-testid": `billing-trend-${days}d`,
2423
- onClick: () => {
2424
- setTrendDays(days);
2425
- },
2426
- children: days === 7 ? t("billing.trend7d") : t("billing.trend30d")
2427
- }, days))
2428
- }),
2429
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2430
- className: UsageBilling_module_css_default.panelHint,
2431
- children: latestDate
2432
- })
2433
- ]
2434
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TrendChart, {
2435
- data: trend,
2436
- models: chartModels,
2437
- currency
2438
- })]
2439
- }), turns.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
2440
- className: UsageBilling_module_css_default.panel,
2441
- "data-testid": "billing-panel-rounds",
2442
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2443
- className: UsageBilling_module_css_default.panelHead,
2444
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
2445
- className: UsageBilling_module_css_default.panelTitle,
2446
- children: t("billing.rounds")
2447
- }), roundFlags.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
2448
- className: UsageBilling_module_css_default.roundsFlagBadge,
2449
- "data-testid": "billing-rounds-flag-count",
2617
+ children: [
2618
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
2619
+ className: clsx(UsageBilling_module_css_default.panel, UsageBilling_module_css_default.trendPanel),
2620
+ "data-testid": "billing-panel-trend",
2621
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2622
+ className: UsageBilling_module_css_default.panelHead,
2450
2623
  children: [
2451
- roundFlags.length,
2452
- " ",
2453
- t("billing.anomaly")
2624
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
2625
+ className: UsageBilling_module_css_default.panelTitle,
2626
+ children: t("billing.trend")
2627
+ }),
2628
+ renderSlot("billing.dashboard.decor", { position: "trend" }),
2629
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2630
+ className: UsageBilling_module_css_default.rangeToggle,
2631
+ role: "group",
2632
+ "aria-label": t("billing.trend"),
2633
+ children: [7, 30].map((days) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2634
+ type: "button",
2635
+ className: clsx(UsageBilling_module_css_default.rangeButton, trendDays === days && UsageBilling_module_css_default.rangeButtonActive),
2636
+ "aria-pressed": trendDays === days,
2637
+ "data-testid": `billing-trend-${days}d`,
2638
+ onClick: () => {
2639
+ setTrendDays(days);
2640
+ },
2641
+ children: days === 7 ? t("billing.trend7d") : t("billing.trend30d")
2642
+ }, days))
2643
+ }),
2644
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2645
+ className: UsageBilling_module_css_default.panelHint,
2646
+ children: latestDate
2647
+ })
2454
2648
  ]
2649
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TrendChart, {
2650
+ data: trend,
2651
+ models: chartModels,
2652
+ currency
2455
2653
  })]
2456
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RoundCostChart, {
2457
- rounds: turns,
2458
- flags: roundFlags,
2459
- currency,
2460
- t
2461
- })]
2462
- })]
2654
+ }),
2655
+ turns.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
2656
+ className: UsageBilling_module_css_default.panel,
2657
+ "data-testid": "billing-panel-rounds",
2658
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2659
+ className: UsageBilling_module_css_default.panelHead,
2660
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
2661
+ className: UsageBilling_module_css_default.panelTitle,
2662
+ children: t("billing.rounds")
2663
+ }), roundFlags.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
2664
+ className: UsageBilling_module_css_default.roundsFlagBadge,
2665
+ "data-testid": "billing-rounds-flag-count",
2666
+ children: [
2667
+ roundFlags.length,
2668
+ " ",
2669
+ t("billing.anomaly")
2670
+ ]
2671
+ })]
2672
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RoundCostChart, {
2673
+ rounds: turns,
2674
+ flags: roundFlags,
2675
+ currency,
2676
+ t
2677
+ })]
2678
+ }),
2679
+ turns.length > 0 && (() => {
2680
+ const shareTotal = peakShare.peak + peakShare.offPeak;
2681
+ if (shareTotal <= 0) return null;
2682
+ const peakPct = peakShare.peak / shareTotal * 100;
2683
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
2684
+ className: UsageBilling_module_css_default.panel,
2685
+ "data-testid": "billing-panel-share",
2686
+ children: [
2687
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2688
+ className: UsageBilling_module_css_default.panelHead,
2689
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
2690
+ className: UsageBilling_module_css_default.panelTitle,
2691
+ children: t("billing.peakShare")
2692
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2693
+ className: UsageBilling_module_css_default.panelHint,
2694
+ children: t("billing.peakShareHint").replace("{count}", String(turns.length))
2695
+ })]
2696
+ }),
2697
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2698
+ className: UsageBilling_module_css_default.shareTrack,
2699
+ "data-testid": "billing-share-track",
2700
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2701
+ className: clsx(UsageBilling_module_css_default.shareSeg, UsageBilling_module_css_default.shareSegPeak),
2702
+ style: { width: `${peakPct}%` }
2703
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2704
+ className: clsx(UsageBilling_module_css_default.shareSeg, UsageBilling_module_css_default.shareSegOff),
2705
+ style: { width: `${100 - peakPct}%` }
2706
+ })]
2707
+ }),
2708
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2709
+ className: UsageBilling_module_css_default.shareLegend,
2710
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
2711
+ className: UsageBilling_module_css_default.shareItem,
2712
+ children: [
2713
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2714
+ className: UsageBilling_module_css_default.shareDot,
2715
+ style: { background: "var(--dsw-static-blue-500)" }
2716
+ }),
2717
+ t("billing.peak"),
2718
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
2719
+ className: UsageBilling_module_css_default.shareValue,
2720
+ "data-testid": "billing-share-peak",
2721
+ children: [
2722
+ money(peakShare.peak),
2723
+ " · ",
2724
+ peakPct.toFixed(1),
2725
+ "%"
2726
+ ]
2727
+ })
2728
+ ]
2729
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
2730
+ className: UsageBilling_module_css_default.shareItem,
2731
+ children: [
2732
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2733
+ className: UsageBilling_module_css_default.shareDot,
2734
+ style: { background: "color-mix(in srgb, var(--dsw-static-blue-500) 30%, var(--dsw-alias-bg-module-platform))" }
2735
+ }),
2736
+ t("billing.offPeak"),
2737
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
2738
+ className: UsageBilling_module_css_default.shareValue,
2739
+ "data-testid": "billing-share-offpeak",
2740
+ children: [
2741
+ money(peakShare.offPeak),
2742
+ " · ",
2743
+ (100 - peakPct).toFixed(1),
2744
+ "%"
2745
+ ]
2746
+ })
2747
+ ]
2748
+ })]
2749
+ })
2750
+ ]
2751
+ });
2752
+ })()
2753
+ ]
2463
2754
  }),
2464
2755
  tab === "providers" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2465
2756
  className: UsageBilling_module_css_default.tabPanel,
@@ -2661,130 +2952,215 @@ window.__ModuleLoader__.load({
2661
2952
  tab === "details" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2662
2953
  className: UsageBilling_module_css_default.tabPanel,
2663
2954
  "data-testid": "billing-tab-panel-details",
2664
- children: [stats.byWorkspace !== void 0 && stats.byWorkspace.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
2665
- className: UsageBilling_module_css_default.panel,
2666
- "data-testid": "billing-panel-workspaces",
2667
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2668
- className: UsageBilling_module_css_default.panelHead,
2669
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
2670
- className: UsageBilling_module_css_default.panelTitle,
2671
- children: t("billing.workspaces")
2672
- })
2673
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2674
- className: UsageBilling_module_css_default.tableScroll,
2675
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("table", {
2676
- className: UsageBilling_module_css_default.modelTable,
2677
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("thead", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("tr", { children: [
2678
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", { children: t("billing.project") }),
2679
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", {
2680
- className: UsageBilling_module_css_default.numCol,
2681
- children: t("billing.calls")
2682
- }),
2683
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", {
2684
- className: UsageBilling_module_css_default.numCol,
2685
- children: t("billing.inputTokens")
2686
- }),
2687
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", {
2688
- className: UsageBilling_module_css_default.numCol,
2689
- children: t("billing.outputTokens")
2690
- }),
2691
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", {
2692
- className: UsageBilling_module_css_default.numCol,
2693
- children: t("billing.actual")
2694
- }),
2695
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", {
2696
- className: UsageBilling_module_css_default.numCol,
2697
- children: t("billing.lastActive")
2698
- })
2699
- ] }) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("tbody", { children: stats.byWorkspace.map((row) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("tr", { children: [
2700
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2701
- className: UsageBilling_module_css_default.modelName,
2702
- children: row.name
2703
- }) }),
2704
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", {
2705
- className: UsageBilling_module_css_default.numCol,
2706
- children: row.calls.toLocaleString()
2707
- }),
2708
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", {
2709
- className: UsageBilling_module_css_default.numCol,
2710
- children: formatTokens(row.input)
2711
- }),
2712
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", {
2713
- className: UsageBilling_module_css_default.numCol,
2714
- children: formatTokens(row.output)
2715
- }),
2716
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", {
2717
- className: UsageBilling_module_css_default.numCol,
2718
- children: money(row.cost)
2719
- }),
2720
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", {
2721
- className: UsageBilling_module_css_default.numCol,
2722
- children: row.lastActive > 0 ? `${localDayStamp(row.lastActive)}` : "—"
2723
- })
2724
- ] }, row.name)) })]
2725
- })
2726
- })]
2727
- }), stats.bySession !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
2728
- className: UsageBilling_module_css_default.panel,
2729
- "data-testid": "billing-panel-sessions",
2730
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2731
- className: UsageBilling_module_css_default.panelHead,
2732
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
2733
- className: UsageBilling_module_css_default.panelTitle,
2734
- children: t("billing.sessions")
2735
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2736
- className: UsageBilling_module_css_default.panelHint,
2737
- children: stats.bySession.length > SESSION_DISPLAY_LIMIT ? t("billing.sessionOverflow").replace("{limit}", String(SESSION_DISPLAY_LIMIT)).replace("{total}", String(stats.bySession.length)) : `${stats.bySession.length}`
2955
+ children: [
2956
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2957
+ className: UsageBilling_module_css_default.exportBar,
2958
+ "data-testid": "billing-export-bar",
2959
+ role: "group",
2960
+ "aria-label": t("billing.export"),
2961
+ children: [
2962
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2963
+ className: UsageBilling_module_css_default.exportLabel,
2964
+ children: t("billing.export")
2965
+ }),
2966
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2967
+ type: "button",
2968
+ className: UsageBilling_module_css_default.exportButton,
2969
+ "data-testid": "billing-export-day",
2970
+ onClick: () => {
2971
+ downloadText(exportFileName("usage-daily", "csv", Object.keys(byDay)), dayRowsCsv(byDay), "text/csv");
2972
+ },
2973
+ children: t("billing.exportCsvDay")
2974
+ }),
2975
+ stats.bySession !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2976
+ type: "button",
2977
+ className: UsageBilling_module_css_default.exportButton,
2978
+ "data-testid": "billing-export-sessions",
2979
+ onClick: () => {
2980
+ downloadText(exportFileName("usage-sessions", "csv", Object.keys(byDay)), sessionRowsCsv(stats.bySession ?? []), "text/csv");
2981
+ },
2982
+ children: t("billing.exportCsvSession")
2983
+ }),
2984
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2985
+ type: "button",
2986
+ className: UsageBilling_module_css_default.exportButton,
2987
+ "data-testid": "billing-export-json",
2988
+ onClick: () => {
2989
+ downloadText(exportFileName("usage-stats", "json", Object.keys(byDay)), JSON.stringify(stats, null, 2), "application/json");
2990
+ },
2991
+ children: t("billing.exportJson")
2992
+ })
2993
+ ]
2994
+ }),
2995
+ roleRows.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
2996
+ className: UsageBilling_module_css_default.panel,
2997
+ "data-testid": "billing-panel-roles",
2998
+ children: [
2999
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
3000
+ className: UsageBilling_module_css_default.panelHead,
3001
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
3002
+ className: UsageBilling_module_css_default.panelTitle,
3003
+ children: t("billing.roleCost")
3004
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
3005
+ className: UsageBilling_module_css_default.panelHint,
3006
+ children: t("billing.roleHint")
3007
+ })]
3008
+ }),
3009
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3010
+ className: UsageBilling_module_css_default.shareTrack,
3011
+ "data-testid": "billing-role-track",
3012
+ children: roleRows.map((row) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3013
+ className: clsx(UsageBilling_module_css_default.shareSeg, row.seg),
3014
+ style: { width: `${row.pct}%` }
3015
+ }, row.label))
3016
+ }),
3017
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3018
+ className: UsageBilling_module_css_default.shareLegend,
3019
+ children: roleRows.map((row) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
3020
+ className: UsageBilling_module_css_default.shareItem,
3021
+ children: [
3022
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: clsx(UsageBilling_module_css_default.shareDot, row.seg) }),
3023
+ row.label,
3024
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
3025
+ className: UsageBilling_module_css_default.shareValue,
3026
+ children: [
3027
+ money(row.value),
3028
+ " · ",
3029
+ row.pct.toFixed(1),
3030
+ "%"
3031
+ ]
3032
+ })
3033
+ ]
3034
+ }, row.label))
3035
+ })
3036
+ ]
3037
+ }),
3038
+ stats.byWorkspace !== void 0 && stats.byWorkspace.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
3039
+ className: UsageBilling_module_css_default.panel,
3040
+ "data-testid": "billing-panel-workspaces",
3041
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3042
+ className: UsageBilling_module_css_default.panelHead,
3043
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
3044
+ className: UsageBilling_module_css_default.panelTitle,
3045
+ children: t("billing.workspaces")
3046
+ })
3047
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3048
+ className: UsageBilling_module_css_default.tableScroll,
3049
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("table", {
3050
+ className: UsageBilling_module_css_default.modelTable,
3051
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("thead", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("tr", { children: [
3052
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", { children: t("billing.project") }),
3053
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", {
3054
+ className: UsageBilling_module_css_default.numCol,
3055
+ children: t("billing.calls")
3056
+ }),
3057
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", {
3058
+ className: UsageBilling_module_css_default.numCol,
3059
+ children: t("billing.inputTokens")
3060
+ }),
3061
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", {
3062
+ className: UsageBilling_module_css_default.numCol,
3063
+ children: t("billing.outputTokens")
3064
+ }),
3065
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", {
3066
+ className: UsageBilling_module_css_default.numCol,
3067
+ children: t("billing.actual")
3068
+ }),
3069
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", {
3070
+ className: UsageBilling_module_css_default.numCol,
3071
+ children: t("billing.lastActive")
3072
+ })
3073
+ ] }) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("tbody", { children: stats.byWorkspace.map((row) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("tr", { children: [
3074
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
3075
+ className: UsageBilling_module_css_default.modelName,
3076
+ children: row.name
3077
+ }) }),
3078
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", {
3079
+ className: UsageBilling_module_css_default.numCol,
3080
+ children: row.calls.toLocaleString()
3081
+ }),
3082
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", {
3083
+ className: UsageBilling_module_css_default.numCol,
3084
+ children: formatTokens(row.input)
3085
+ }),
3086
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", {
3087
+ className: UsageBilling_module_css_default.numCol,
3088
+ children: formatTokens(row.output)
3089
+ }),
3090
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", {
3091
+ className: UsageBilling_module_css_default.numCol,
3092
+ children: money(row.cost)
3093
+ }),
3094
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", {
3095
+ className: UsageBilling_module_css_default.numCol,
3096
+ children: row.lastActive > 0 ? `${localDayStamp(row.lastActive)}` : "—"
3097
+ })
3098
+ ] }, row.name)) })]
3099
+ })
2738
3100
  })]
2739
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2740
- className: UsageBilling_module_css_default.tableScroll,
2741
- "data-testid": "billing-sessions-table",
2742
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("table", {
2743
- className: UsageBilling_module_css_default.modelTable,
2744
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("thead", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("tr", { children: [
2745
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", { children: t("billing.sessions") }),
2746
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", { children: t("billing.project") }),
2747
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", {
2748
- className: UsageBilling_module_css_default.numCol,
2749
- children: t("billing.calls")
2750
- }),
2751
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", {
2752
- className: UsageBilling_module_css_default.numCol,
2753
- children: t("billing.actual")
2754
- }),
2755
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", {
2756
- className: UsageBilling_module_css_default.numCol,
2757
- children: t("billing.lastActive")
2758
- })
2759
- ] }) }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("tbody", { children: [stats.bySession.length === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("tr", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", {
2760
- colSpan: 5,
2761
- className: UsageBilling_module_css_default.emptyRow,
2762
- children: t("billing.noData")
2763
- }) }), stats.bySession.slice(0, SESSION_DISPLAY_LIMIT).map((row) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("tr", { children: [
2764
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2765
- className: UsageBilling_module_css_default.modelName,
2766
- children: row.title ?? row.id.slice(0, 8)
2767
- }) }),
2768
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2769
- className: UsageBilling_module_css_default.modelProvider,
2770
- children: projectName(row.cwd) ?? "—"
2771
- }) }),
2772
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", {
2773
- className: UsageBilling_module_css_default.numCol,
2774
- children: row.calls.toLocaleString()
2775
- }),
2776
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", {
2777
- className: UsageBilling_module_css_default.numCol,
2778
- children: money(row.cost)
2779
- }),
2780
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", {
2781
- className: UsageBilling_module_css_default.numCol,
2782
- children: row.lastActive > 0 ? `${localDayStamp(row.lastActive)} ${formatClock(row.lastActive)}` : "—"
2783
- })
2784
- ] }, row.id))] })]
2785
- })
2786
- })]
2787
- })]
3101
+ }),
3102
+ stats.bySession !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
3103
+ className: UsageBilling_module_css_default.panel,
3104
+ "data-testid": "billing-panel-sessions",
3105
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
3106
+ className: UsageBilling_module_css_default.panelHead,
3107
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
3108
+ className: UsageBilling_module_css_default.panelTitle,
3109
+ children: t("billing.sessions")
3110
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
3111
+ className: UsageBilling_module_css_default.panelHint,
3112
+ children: stats.bySession.length > SESSION_DISPLAY_LIMIT ? t("billing.sessionOverflow").replace("{limit}", String(SESSION_DISPLAY_LIMIT)).replace("{total}", String(stats.bySession.length)) : `${stats.bySession.length}`
3113
+ })]
3114
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3115
+ className: UsageBilling_module_css_default.tableScroll,
3116
+ "data-testid": "billing-sessions-table",
3117
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("table", {
3118
+ className: UsageBilling_module_css_default.modelTable,
3119
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("thead", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("tr", { children: [
3120
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", { children: t("billing.sessions") }),
3121
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", { children: t("billing.project") }),
3122
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", {
3123
+ className: UsageBilling_module_css_default.numCol,
3124
+ children: t("billing.calls")
3125
+ }),
3126
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", {
3127
+ className: UsageBilling_module_css_default.numCol,
3128
+ children: t("billing.actual")
3129
+ }),
3130
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", {
3131
+ className: UsageBilling_module_css_default.numCol,
3132
+ children: t("billing.lastActive")
3133
+ })
3134
+ ] }) }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("tbody", { children: [stats.bySession.length === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("tr", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", {
3135
+ colSpan: 5,
3136
+ className: UsageBilling_module_css_default.emptyRow,
3137
+ children: t("billing.noData")
3138
+ }) }), stats.bySession.slice(0, SESSION_DISPLAY_LIMIT).map((row) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("tr", { children: [
3139
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
3140
+ className: UsageBilling_module_css_default.modelName,
3141
+ children: row.title ?? row.id.slice(0, 8)
3142
+ }) }),
3143
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
3144
+ className: UsageBilling_module_css_default.modelProvider,
3145
+ children: projectName(row.cwd) ?? "—"
3146
+ }) }),
3147
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", {
3148
+ className: UsageBilling_module_css_default.numCol,
3149
+ children: row.calls.toLocaleString()
3150
+ }),
3151
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", {
3152
+ className: UsageBilling_module_css_default.numCol,
3153
+ children: money(row.cost)
3154
+ }),
3155
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", {
3156
+ className: UsageBilling_module_css_default.numCol,
3157
+ children: row.lastActive > 0 ? `${localDayStamp(row.lastActive)} ${formatClock(row.lastActive)}` : "—"
3158
+ })
3159
+ ] }, row.id))] })]
3160
+ })
3161
+ })]
3162
+ })
3163
+ ]
2788
3164
  }),
2789
3165
  tab === "pricing" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2790
3166
  className: UsageBilling_module_css_default.tabPanel,
@@ -2954,9 +3330,11 @@ window.__ModuleLoader__.load({
2954
3330
  const today = localDayStamp();
2955
3331
  const monthCost = Object.entries(stats.byDay).filter(([date]) => date.startsWith(today.slice(0, 7))).reduce((sum, [, day]) => sum + day.cost, 0);
2956
3332
  const todayCost = stats.byDay[today]?.cost ?? 0;
3333
+ const weekCost = lastSevenDays(stats.byDay).reduce((sum, d) => sum + d.cost, 0);
3334
+ const last7 = (0, react.useMemo)(() => lastSevenDays(stats.byDay), [stats.byDay]);
2957
3335
  const budgetEnabled = useStore((s) => s.enabled);
2958
3336
  const budgetAmount = useStore((s) => s.amount);
2959
- const budgetAlertedDay = useStore((s) => s.lastAlertDay);
3337
+ const tierAlertDays = useStore((s) => s.tierAlertDays);
2960
3338
  const effectiveBudget = budgetAmount > 0 ? budgetAmount : stats.budget ?? 0;
2961
3339
  const toggleBudget = (0, react.useCallback)(() => {
2962
3340
  const next = !budgetEnabled;
@@ -2966,12 +3344,13 @@ window.__ModuleLoader__.load({
2966
3344
  (0, react.useEffect)(() => {
2967
3345
  if (!budgetEnabled || effectiveBudget <= 0) return;
2968
3346
  const pct = monthCost / effectiveBudget * 100;
2969
- if (pct < 100) return;
2970
3347
  const day = localDayStamp();
2971
- if (budgetAlertedDay === day) return;
2972
- actions.markAlerted(day);
3348
+ const crossed = BUDGET_ALERT_TIERS.filter((tier) => pct >= tier && tierAlertDays?.[String(tier)] !== day);
3349
+ if (crossed.length === 0) return;
3350
+ const top = crossed[crossed.length - 1] ?? 100;
3351
+ actions.markTierAlerted(crossed, day);
2973
3352
  if (typeof Notification === "undefined" || Notification.permission !== "granted") return;
2974
- const body = t("billing.budgetOverBody").replace("{cost}", formatMoney(monthCost)).replace("{budget}", formatMoney(effectiveBudget)).replace("{pct}", pct.toFixed(0));
3353
+ const body = t("billing.budgetTierBody").replace("{cost}", formatMoney(monthCost)).replace("{budget}", formatMoney(effectiveBudget)).replace("{pct}", String(top));
2975
3354
  try {
2976
3355
  new Notification(t("billing.budget"), { body });
2977
3356
  } catch {}
@@ -2979,7 +3358,7 @@ window.__ModuleLoader__.load({
2979
3358
  budgetEnabled,
2980
3359
  effectiveBudget,
2981
3360
  monthCost,
2982
- budgetAlertedDay,
3361
+ tierAlertDays,
2983
3362
  actions,
2984
3363
  t
2985
3364
  ]);
@@ -3038,7 +3417,9 @@ window.__ModuleLoader__.load({
3038
3417
  ...props,
3039
3418
  onOpen: openDashboard,
3040
3419
  monthCost,
3041
- todayCost
3420
+ todayCost,
3421
+ weekCost,
3422
+ days: last7
3042
3423
  }), open && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BillingDashboard, {
3043
3424
  stats,
3044
3425
  t,
@@ -3207,7 +3588,7 @@ window.__ModuleLoader__.load({
3207
3588
  "billing.project": "项目",
3208
3589
  "billing.lastActive": "最后活跃",
3209
3590
  "billing.sessionOverflow": "仅显示花费前 {limit} 个,共 {total} 个会话",
3210
- "billing.budgetOverBody": "本月花费 {cost} 已超过预算 {budget}({pct}%)",
3591
+ "billing.budgetTierBody": "本月花费 {cost} 已达预算 {budget} 的 {pct}%",
3211
3592
  "billing.models": "模型计费明细",
3212
3593
  "billing.providerBilling": "厂商计费与订阅",
3213
3594
  "billing.estimated": "估算",
@@ -3271,7 +3652,19 @@ window.__ModuleLoader__.load({
3271
3652
  "billing.tabTrends": "趋势",
3272
3653
  "billing.tabProviders": "明细",
3273
3654
  "billing.tabDetails": "统计",
3274
- "billing.tabPricing": "费率"
3655
+ "billing.tabPricing": "费率",
3656
+ "billing.export": "导出",
3657
+ "billing.exportCsvDay": "按日 CSV",
3658
+ "billing.exportCsvSession": "按会话 CSV",
3659
+ "billing.exportJson": "全量 JSON",
3660
+ "billing.peakShare": "峰谷时段占比",
3661
+ "billing.peakShareHint": "近 {count} 轮",
3662
+ "billing.weekCost": "本周",
3663
+ "billing.roleCost": "费用构成",
3664
+ "billing.roleUser": "用户输入",
3665
+ "billing.roleAssistant": "助手输出",
3666
+ "billing.roleTool": "工具结果",
3667
+ "billing.roleHint": "估算:输出按实测计价,输入按消息长度摊分"
3275
3668
  };
3276
3669
  const en = {
3277
3670
  "billing.title": "Usage",
@@ -3299,7 +3692,7 @@ window.__ModuleLoader__.load({
3299
3692
  "billing.project": "Project",
3300
3693
  "billing.lastActive": "Last active",
3301
3694
  "billing.sessionOverflow": "Top {limit} of {total} sessions by cost",
3302
- "billing.budgetOverBody": "This month {cost} exceeded the budget {budget} ({pct}%)",
3695
+ "billing.budgetTierBody": "This month {cost} reached {pct}% of the budget {budget}",
3303
3696
  "billing.models": "Model billing",
3304
3697
  "billing.providerBilling": "Provider billing & subscriptions",
3305
3698
  "billing.estimated": "Est.",
@@ -3363,7 +3756,19 @@ window.__ModuleLoader__.load({
3363
3756
  "billing.tabTrends": "Trends",
3364
3757
  "billing.tabProviders": "Details",
3365
3758
  "billing.tabDetails": "Stats",
3366
- "billing.tabPricing": "Rates"
3759
+ "billing.tabPricing": "Rates",
3760
+ "billing.export": "Export",
3761
+ "billing.exportCsvDay": "Daily CSV",
3762
+ "billing.exportCsvSession": "Sessions CSV",
3763
+ "billing.exportJson": "Full JSON",
3764
+ "billing.peakShare": "Peak vs off-peak",
3765
+ "billing.peakShareHint": "last {count} turns",
3766
+ "billing.weekCost": "This week",
3767
+ "billing.roleCost": "Cost breakdown",
3768
+ "billing.roleUser": "User input",
3769
+ "billing.roleAssistant": "Assistant output",
3770
+ "billing.roleTool": "Tool results",
3771
+ "billing.roleHint": "Estimated: output priced exactly, input split by message size"
3367
3772
  };
3368
3773
  //#endregion
3369
3774
  //#region src/client/billing-service.ts
@@ -3414,7 +3819,7 @@ window.__ModuleLoader__.load({
3414
3819
  init: () => ({
3415
3820
  enabled: false,
3416
3821
  amount: 0,
3417
- lastAlertDay: "",
3822
+ tierAlertDays: {},
3418
3823
  lastBalanceAlertDay: ""
3419
3824
  }),
3420
3825
  persist: "dsh.ui-usage-billing.budget",
@@ -3425,8 +3830,9 @@ window.__ModuleLoader__.load({
3425
3830
  setAmount: (d, value) => {
3426
3831
  d.amount = Number.isFinite(value) && value > 0 ? value : 0;
3427
3832
  },
3428
- markAlerted: (d, day) => {
3429
- d.lastAlertDay = day;
3833
+ markTierAlerted: (d, tiers, day) => {
3834
+ d.tierAlertDays ??= {};
3835
+ for (const tier of tiers) d.tierAlertDays[String(tier)] = day;
3430
3836
  },
3431
3837
  markBalanceAlerted: (d, day) => {
3432
3838
  d.lastBalanceAlertDay = day;