@kenz1117/dsh-ui-usage-billing 0.9.1 → 0.9.2

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 var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-2);width:36px;height:36px;color:var(--dsw-alias-label-secondary);cursor:pointer;border-radius:8px;flex:none;justify-content:center;align-items:center;padding:0;transition:border-color .16s,color .16s;display:flex}.VWh0dG_railButton:hover,.VWh0dG_railButton:focus-visible{border-color:var(--dsw-static-blue-500);color:var(--dsw-static-blue-500);outline:none}.VWh0dG_railButton svg{stroke-width:2px;width:18px;height:18px}.VWh0dG_trigger{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-2);width:100%;min-width:0;color:var(--dsw-alias-label-primary);cursor:pointer;text-align:left;border-radius:12px;align-items:center;gap:10px;padding:9px 12px;transition:border-color .16s,background-color .16s;display:flex;position:relative;overflow:hidden}.VWh0dG_trigger:hover,.VWh0dG_trigger:focus-visible{border-color:var(--dsw-static-blue-500);outline:none}.VWh0dG_triggerIcon{background:linear-gradient(135deg, var(--dsw-static-blue-500), var(--dsw-static-blue-400));width:30px;height:30px;color:var(--dsw-static-neutral-bluish-00);box-shadow:0 2px 8px -2px color-mix(in srgb, var(--dsw-static-blue-500) 55%, transparent);border-radius:10px;flex:none;justify-content:center;align-items:center;display:inline-flex}.VWh0dG_triggerIcon svg{stroke-width:2px;width:16px;height:16px}.VWh0dG_triggerBody{flex-direction:column;flex:1;gap:1px;min-width:0;display:flex}.VWh0dG_triggerRow{align-items:baseline;gap:5px;min-width:0;display:inline-flex}.VWh0dG_triggerAmount{color:var(--dsw-alias-label-primary);letter-spacing:-.02em;font-variant-numeric:tabular-nums;white-space:nowrap;font-size:16px;font-weight:700;line-height:20px}.VWh0dG_triggerSub{color:var(--dsw-alias-label-tertiary);white-space:nowrap;text-overflow:ellipsis;font-size:10px;line-height:14px;overflow:hidden}.VWh0dG_triggerMeta{color:var(--dsw-alias-label-tertiary);white-space:nowrap;letter-spacing:.02em;text-transform:uppercase;font-size:9.5px;font-weight:600;line-height:12px}.VWh0dG_triggerSpark{flex:none;align-items:flex-end;gap:2px;height:20px;display:flex}.VWh0dG_triggerSparkBar,.VWh0dG_triggerSparkHot{background:var(--dsw-static-blue-500);opacity:.6;border-radius:1px 1px 0 0;width:3px}.VWh0dG_triggerSparkHot{opacity:1}.VWh0dG_triggerWrap{flex:auto;width:100%;min-width:0;display:block;position:relative}.VWh0dG_triggerPop{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-2);box-shadow:var(--dsw-shadow-lv2);opacity:0;pointer-events:none;z-index:10;border-radius:10px;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)}.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:var(--dsw-static-blue-500);border-radius:2px;flex:1;transition:height .2s}.VWh0dG_dashboardModal{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);width:min(760px,100vw - 48px);max-height:min(760px,88vh);box-shadow:var(--dsw-shadow-lv3);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:var(--dsw-static-blue-500);color:var(--dsw-static-neutral-bluish-00);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 var(--dsw-alias-border-l1);background:linear-gradient(180deg, var(--dsw-alias-bg-layer-2), var(--dsw-alias-bg-layer-1));box-shadow:inset 0 1px 0 color-mix(in srgb, var(--dsw-static-neutral-bluish-00) 30%, transparent);border-radius:16px;flex-direction:column;gap:18px;padding:22px 24px;display:flex;position:relative;overflow:hidden}.VWh0dG_heroTop{justify-content:space-between;align-items:center;gap:24px;display:flex}.VWh0dG_heroMain{flex-direction:column;gap:2px;min-width:0;display:flex}.VWh0dG_heroLabel{color:var(--dsw-alias-label-tertiary);text-transform:uppercase;letter-spacing:.08em;white-space:nowrap;font-size:11px;line-height:16px}.VWh0dG_heroReadout{align-items:baseline;gap:4px;display:flex}.VWh0dG_heroCurrency{letter-spacing:-.01em;color:var(--dsw-alias-label-secondary);font-variant-numeric:tabular-nums;font-size:20px;font-weight:600;line-height:30px}.VWh0dG_heroValue{letter-spacing:-.03em;font-variant-numeric:tabular-nums;white-space:nowrap;color:var(--dsw-alias-label-primary);font-size:56px;font-weight:700;line-height:64px}.VWh0dG_heroMeta{color:var(--dsw-alias-label-caption);white-space:nowrap;margin-top:4px;font-size:12px;line-height:17px}.VWh0dG_heroGauge{flex:none;width:96px;height:96px;position:relative}.VWh0dG_heroGaugeSvg{width:100%;height:100%;display:block;transform:rotate(-90deg)}.VWh0dG_heroGaugeTrack{fill:none;stroke:var(--dsw-alias-bg-module-platform);stroke-width:9px}.VWh0dG_heroGaugeArc{fill:none;stroke:var(--dsw-static-blue-500);stroke-width:9px;stroke-linecap:round;transition:stroke-dasharray .26s}.VWh0dG_heroGaugeArcOver{stroke:var(--dsw-static-red-500)}.VWh0dG_heroGaugeCenter{flex-direction:column;justify-content:center;align-items:center;gap:1px;display:flex;position:absolute;inset:0}.VWh0dG_heroGaugePct{letter-spacing:-.02em;font-variant-numeric:tabular-nums;color:var(--dsw-alias-label-primary);font-size:18px;font-weight:700;line-height:22px}.VWh0dG_heroGaugePctOver{color:var(--dsw-static-red-500)}.VWh0dG_heroGaugeLabel{color:var(--dsw-alias-label-tertiary);font-size:10px;line-height:14px}.VWh0dG_heroSide{border-top:1px solid var(--dsw-alias-border-l1);align-items:stretch;padding-top:14px;display:flex}.VWh0dG_heroSideItem{flex-direction:column;flex:1;gap:3px;min-width:0;padding-left:16px;display:flex}.VWh0dG_heroSideItem:first-child{padding-left:0}.VWh0dG_heroSideLabel{color:var(--dsw-alias-label-tertiary);white-space:nowrap;font-size:11px;line-height:15px}.VWh0dG_heroSideValue{color:var(--dsw-alias-label-primary);font-variant-numeric:tabular-nums;letter-spacing:-.01em;white-space:nowrap;align-items:baseline;gap:6px;font-size:18px;font-weight:600;line-height:24px;display:inline-flex}.VWh0dG_heroSideSpacer{flex:1;display:block}.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;display:flex;position:relative;overflow:hidden}.VWh0dG_kpiTile:hover{border-color:var(--dsw-alias-border-l2)}.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;letter-spacing:-.01em;font-size:22px;font-weight:600;line-height:28px}.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;transition:border-color .16s;display:flex}.VWh0dG_panelHead{justify-content:space-between;align-items:baseline;gap:10px;display:flex}.VWh0dG_panelTitle{letter-spacing:-.005em;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:var(--dsw-alias-border-l2);color:var(--dsw-alias-label-primary);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:var(--dsw-static-blue-500)}.VWh0dG_shareSegOff{background:color-mix(in srgb, var(--dsw-static-blue-500) 25%, var(--dsw-alias-bg-module-platform))}.VWh0dG_shareSegUser{background:var(--dsw-static-blue-500)}.VWh0dG_shareSegAssistant{background:var(--dsw-static-green-500)}.VWh0dG_shareSegTool{background:var(--dsw-static-amber-500)}.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_bucketCost{align-items:baseline;gap:3px;display:inline-flex}.VWh0dG_bucketOfficial{color:var(--dsw-static-blue-500);font-weight:600}.VWh0dG_bucketSep{color:var(--dsw-alias-label-dimmed)}.VWh0dG_bucketThird{color:var(--dsw-alias-label-secondary)}.VWh0dG_bucketSummary{grid-template-columns:repeat(2,minmax(0,1fr));gap:10px;display:grid}.VWh0dG_bucketStat{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-2);border-radius:12px;flex-direction:column;gap:4px;padding:12px 14px;display:flex}.VWh0dG_bucketStatLabel{color:var(--dsw-alias-label-tertiary);text-transform:uppercase;letter-spacing:.05em;font-size:11px;line-height:15px}.VWh0dG_bucketStatValue{color:var(--dsw-alias-label-primary);font-variant-numeric:tabular-nums;letter-spacing:-.01em;font-size:20px;font-weight:700;line-height:26px}.VWh0dG_bucketStatSub{color:var(--dsw-alias-label-caption);font-variant-numeric:tabular-nums;font-size:11px;line-height:16px}.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-alias-border-l1);background:var(--dsw-alias-label-primary)}.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:.7}.VWh0dG_chartBar:hover{opacity:1}.VWh0dG_chartStack{stroke:var(--dsw-alias-bg-layer-1);stroke-width:.75px}.VWh0dG_chartStack:hover{opacity:.9}.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:2px}.VWh0dG_chartTooltip{pointer-events:none;z-index:2;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);box-shadow:none;white-space:nowrap;border-radius:8px;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);text-transform:uppercase;letter-spacing:.05em;background:0 0;font-size:11px;font-weight:600}.VWh0dG_modelTable tbody tr,.VWh0dG_pricingTable tbody tr{transition:background-color .12s}.VWh0dG_modelTable tbody tr:hover,.VWh0dG_pricingTable tbody tr:hover{background:0 0}.VWh0dG_numCol{text-align:right;font-variant-numeric:tabular-nums}.VWh0dG_costCol{color:var(--dsw-alias-label-primary);font-weight:600}.VWh0dG_na{color:var(--dsw-alias-label-dimmed)}.VWh0dG_modelCell{align-items:center;gap:8px;display:inline-flex}.VWh0dG_modelDot{border-radius:50%;flex:none;width:9px;height:9px}.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-alias-label-primary)}.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:var(--dsw-alias-bg-layer-2)}.VWh0dG_rateBadgeBuiltin{color:var(--dsw-alias-label-tertiary);background:var(--dsw-alias-bg-layer-2)}.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_bandTag>span:first-child{color:var(--dsw-alias-label-primary);font-weight:500}.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)}.VWh0dG_healthBad{background:var(--dsw-static-red-500)}.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:var(--dsw-alias-bg-layer-2)}.VWh0dG_healthBadgeBad{color:var(--dsw-static-red-500);background:var(--dsw-alias-bg-layer-2)}.VWh0dG_planTag{color:var(--dsw-static-green-500);background:var(--dsw-alias-bg-layer-2);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:var(--dsw-alias-bg-layer-2);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:var(--dsw-alias-bg-layer-2);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_liveTierPeak{color:var(--dsw-static-blue-500);font-weight:600}.VWh0dG_liveTierOff{color:var(--dsw-static-green-500);font-weight:600}.VWh0dG_liveQuotaWarn{color:var(--dsw-static-amber-500);font-weight:600}.VWh0dG_liveQuotaCrit{color:var(--dsw-static-red-500);font-weight:600}.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-l1);background:var(--dsw-alias-bg-layer-2);border-radius:6px;align-items:center;gap:2px;margin-right:8px;padding:2px;display:inline-flex}.VWh0dG_currencyButton{color:var(--dsw-alias-label-secondary);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-bg-layer-1);color:var(--dsw-alias-label-primary)}.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-l1);background:var(--dsw-alias-bg-layer-2);border-radius:10px;padding:12px 14px}.VWh0dG_subscriptionHead{flex-wrap:wrap;align-items:baseline;gap:6px;margin-bottom:8px;display:flex}.VWh0dG_subscriptionName{font-size:13px;font-weight:700}.VWh0dG_subscriptionPlan{color:var(--dsw-alias-label-secondary);font-size:11px}.VWh0dG_subscriptionPlan[data-kind=code],.VWh0dG_subscriptionPlan[data-kind=token]{color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-3);border-radius:999px;padding:1px 8px;font-weight:500}.VWh0dG_subscriptionStatus{color:var(--dsw-alias-label-secondary);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-label-secondary);flex:0 0 44px}.VWh0dG_subscriptionTrack{background:var(--dsw-alias-bg-layer-3);border-radius:3px;flex:1;height:5px;overflow:hidden}.VWh0dG_subscriptionFill{background:var(--dsw-static-blue-500);border-radius:3px;height:100%;transition:width .2s;display:block}.VWh0dG_subscriptionFillWarn{background:var(--dsw-static-amber-500)}.VWh0dG_subscriptionFillOver{background:var(--dsw-static-red-500)}.VWh0dG_subscriptionPct{text-align:right;font-variant-numeric:tabular-nums;flex:none;min-width:52px}.VWh0dG_subscriptionExhausted{color:var(--dsw-static-red-500);min-width:52px;font-weight:600}.VWh0dG_subscriptionReset{color:var(--dsw-alias-label-secondary);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:var(--dsw-alias-bg-layer-2);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:var(--dsw-static-neutral-bluish-00);background:var(--dsw-static-red-500);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-label-secondary);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-static-blue-500);border-radius:2px 2px 0 0;width:100%;min-height:2px;position:relative}.VWh0dG_roundsBarFlagged{background:var(--dsw-static-red-500);border-radius:2px 2px 0 0;width:100%;min-height:2px;position:relative}.VWh0dG_roundsFlagMark{background:var(--dsw-static-red-500);border-radius:50%;width:7px;height:7px;position:absolute;top:-3px;right:-3px}.VWh0dG_roundsAxis{color:var(--dsw-alias-label-secondary);justify-content:space-between;margin-top:6px;font-size:10px;display:flex}.VWh0dG_roundsEmpty{color:var(--dsw-alias-label-secondary);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);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)}.VWh0dG_heatmapFooter{color:var(--dsw-alias-label-secondary);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{gap:14px}.VWh0dG_heroTop{flex-direction:column;align-items:flex-start;gap:12px}.VWh0dG_heroGauge{width:72px;height:72px}.VWh0dG_heroSide{gap:12px}.VWh0dG_heroSideSpacer{display:none}}";
27
+ const css = ".VWh0dG_railButton{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-2);width:36px;height:36px;color:var(--dsw-alias-label-secondary);cursor:pointer;border-radius:8px;flex:none;justify-content:center;align-items:center;padding:0;transition:border-color .16s,color .16s;display:flex}.VWh0dG_railButton:hover,.VWh0dG_railButton:focus-visible{border-color:var(--dsw-static-blue-500);color:var(--dsw-static-blue-500);outline:none}.VWh0dG_railButton svg{stroke-width:2px;width:18px;height:18px}.VWh0dG_trigger{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-2);width:100%;min-width:0;color:var(--dsw-alias-label-primary);cursor:pointer;text-align:left;border-radius:12px;align-items:center;gap:10px;padding:9px 12px;transition:border-color .16s,background-color .16s;display:flex;position:relative;overflow:hidden}.VWh0dG_trigger:hover,.VWh0dG_trigger:focus-visible{border-color:var(--dsw-static-blue-500);outline:none}.VWh0dG_triggerIcon{background:linear-gradient(135deg, var(--dsw-static-blue-500), var(--dsw-static-blue-400));width:30px;height:30px;color:var(--dsw-static-neutral-bluish-00);box-shadow:0 2px 8px -2px color-mix(in srgb, var(--dsw-static-blue-500) 55%, transparent);border-radius:10px;flex:none;justify-content:center;align-items:center;display:inline-flex}.VWh0dG_triggerIcon svg{stroke-width:2px;width:16px;height:16px}.VWh0dG_triggerBody{flex-direction:column;flex:1;gap:1px;min-width:0;display:flex}.VWh0dG_triggerRow{align-items:baseline;gap:5px;min-width:0;display:inline-flex}.VWh0dG_triggerAmount{color:var(--dsw-alias-label-primary);letter-spacing:-.02em;font-variant-numeric:tabular-nums;white-space:nowrap;font-size:16px;font-weight:700;line-height:20px}.VWh0dG_triggerSub{color:var(--dsw-alias-label-tertiary);white-space:nowrap;text-overflow:ellipsis;font-size:10px;line-height:14px;overflow:hidden}.VWh0dG_triggerMeta{color:var(--dsw-alias-label-tertiary);white-space:nowrap;letter-spacing:.02em;text-transform:uppercase;font-size:9.5px;font-weight:600;line-height:12px}.VWh0dG_triggerSpark{flex:none;align-items:flex-end;gap:2px;height:20px;display:flex}.VWh0dG_triggerSparkBar,.VWh0dG_triggerSparkHot{background:var(--dsw-static-blue-500);opacity:.6;border-radius:1px 1px 0 0;width:3px}.VWh0dG_triggerSparkHot{opacity:1}.VWh0dG_triggerWrap{flex:auto;width:100%;min-width:0;display:block;position:relative}.VWh0dG_triggerPop{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-2);box-shadow:var(--dsw-shadow-lv2);opacity:0;pointer-events:none;z-index:10;border-radius:10px;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)}.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:var(--dsw-static-blue-500);border-radius:2px;flex:1;transition:height .2s}.VWh0dG_dashboardModal{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);width:min(760px,100vw - 48px);max-height:min(760px,88vh);box-shadow:var(--dsw-shadow-lv3);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:var(--dsw-static-blue-500);color:var(--dsw-static-neutral-bluish-00);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 var(--dsw-alias-border-l1);background:linear-gradient(180deg, var(--dsw-alias-bg-layer-2), var(--dsw-alias-bg-layer-1));box-shadow:inset 0 1px 0 color-mix(in srgb, var(--dsw-static-neutral-bluish-00) 30%, transparent);border-radius:16px;flex-direction:column;gap:18px;padding:22px 24px;display:flex;position:relative;overflow:hidden}.VWh0dG_heroTop{justify-content:space-between;align-items:center;gap:24px;display:flex}.VWh0dG_heroMain{flex-direction:column;gap:2px;min-width:0;display:flex}.VWh0dG_heroLabel{color:var(--dsw-alias-label-tertiary);text-transform:uppercase;letter-spacing:.08em;white-space:nowrap;font-size:11px;line-height:16px}.VWh0dG_heroReadout{align-items:baseline;gap:4px;display:flex}.VWh0dG_heroCurrency{letter-spacing:-.01em;color:var(--dsw-alias-label-secondary);font-variant-numeric:tabular-nums;font-size:20px;font-weight:600;line-height:30px}.VWh0dG_heroValue{letter-spacing:-.03em;font-variant-numeric:tabular-nums;white-space:nowrap;color:var(--dsw-alias-label-primary);font-size:56px;font-weight:700;line-height:64px}.VWh0dG_heroMeta{color:var(--dsw-alias-label-caption);white-space:nowrap;margin-top:4px;font-size:12px;line-height:17px}.VWh0dG_heroGauge{flex:none;width:96px;height:96px;position:relative}.VWh0dG_heroGaugeSvg{width:100%;height:100%;display:block;transform:rotate(-90deg)}.VWh0dG_heroGaugeTrack{fill:none;stroke:var(--dsw-alias-bg-module-platform);stroke-width:9px}.VWh0dG_heroGaugeArc{fill:none;stroke:var(--dsw-static-blue-500);stroke-width:9px;stroke-linecap:round;transition:stroke-dasharray .26s}.VWh0dG_heroGaugeArcOver{stroke:var(--dsw-static-red-500)}.VWh0dG_heroGaugeCenter{flex-direction:column;justify-content:center;align-items:center;gap:1px;display:flex;position:absolute;inset:0}.VWh0dG_heroGaugePct{letter-spacing:-.02em;font-variant-numeric:tabular-nums;color:var(--dsw-alias-label-primary);font-size:18px;font-weight:700;line-height:22px}.VWh0dG_heroGaugePctOver{color:var(--dsw-static-red-500)}.VWh0dG_heroGaugeLabel{color:var(--dsw-alias-label-tertiary);font-size:10px;line-height:14px}.VWh0dG_heroSide{border-top:1px solid var(--dsw-alias-border-l1);align-items:stretch;padding-top:14px;display:flex}.VWh0dG_heroSideItem{flex-direction:column;flex:1;gap:3px;min-width:0;padding-left:16px;display:flex}.VWh0dG_heroSideItem:first-child{padding-left:0}.VWh0dG_heroSideLabel{color:var(--dsw-alias-label-tertiary);white-space:nowrap;font-size:11px;line-height:15px}.VWh0dG_heroSideValue{color:var(--dsw-alias-label-primary);font-variant-numeric:tabular-nums;letter-spacing:-.01em;white-space:nowrap;align-items:baseline;gap:6px;font-size:18px;font-weight:600;line-height:24px;display:inline-flex}.VWh0dG_heroSideSpacer{flex:1;display:block}.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;display:flex;position:relative;overflow:hidden}.VWh0dG_kpiTile:hover{border-color:var(--dsw-alias-border-l2)}.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;letter-spacing:-.01em;font-size:22px;font-weight:600;line-height:28px}.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;transition:border-color .16s;display:flex}.VWh0dG_panelHead{justify-content:space-between;align-items:baseline;gap:10px;display:flex}.VWh0dG_panelTitle{letter-spacing:-.005em;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_pricingTip{color:var(--dsw-alias-label-caption);margin:0 0 2px;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:var(--dsw-alias-border-l2);color:var(--dsw-alias-label-primary);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:var(--dsw-static-blue-500)}.VWh0dG_shareSegOff{background:color-mix(in srgb, var(--dsw-static-blue-500) 25%, var(--dsw-alias-bg-module-platform))}.VWh0dG_shareSegUser{background:var(--dsw-static-blue-500)}.VWh0dG_shareSegAssistant{background:var(--dsw-static-green-500)}.VWh0dG_shareSegTool{background:var(--dsw-static-amber-500)}.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_bucketCost{align-items:baseline;gap:3px;display:inline-flex}.VWh0dG_bucketOfficial{color:var(--dsw-static-blue-500);font-weight:600}.VWh0dG_bucketSep{color:var(--dsw-alias-label-dimmed)}.VWh0dG_bucketThird{color:var(--dsw-alias-label-secondary)}.VWh0dG_bucketSummary{grid-template-columns:repeat(2,minmax(0,1fr));gap:10px;display:grid}.VWh0dG_bucketStat{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-2);border-radius:12px;flex-direction:column;gap:4px;padding:12px 14px;display:flex}.VWh0dG_bucketStatLabel{color:var(--dsw-alias-label-tertiary);text-transform:uppercase;letter-spacing:.05em;font-size:11px;line-height:15px}.VWh0dG_bucketStatValue{color:var(--dsw-alias-label-primary);font-variant-numeric:tabular-nums;letter-spacing:-.01em;font-size:20px;font-weight:700;line-height:26px}.VWh0dG_bucketStatSub{color:var(--dsw-alias-label-caption);font-variant-numeric:tabular-nums;font-size:11px;line-height:16px}.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-alias-border-l1);background:var(--dsw-alias-label-primary)}.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:.7}.VWh0dG_chartBar:hover{opacity:1}.VWh0dG_chartStack{stroke:var(--dsw-alias-bg-layer-1);stroke-width:.75px}.VWh0dG_chartStack:hover{opacity:.9}.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:2px}.VWh0dG_chartTooltip{pointer-events:none;z-index:2;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);box-shadow:none;white-space:nowrap;border-radius:8px;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);text-transform:uppercase;letter-spacing:.05em;background:0 0;font-size:11px;font-weight:600}.VWh0dG_modelTable tbody tr,.VWh0dG_pricingTable tbody tr{transition:background-color .12s}.VWh0dG_modelTable tbody tr:hover,.VWh0dG_pricingTable tbody tr:hover{background:0 0}.VWh0dG_numCol{text-align:right;font-variant-numeric:tabular-nums}.VWh0dG_costCol{color:var(--dsw-alias-label-primary);font-weight:600}.VWh0dG_na{color:var(--dsw-alias-label-dimmed)}.VWh0dG_modelCell{align-items:center;gap:8px;display:inline-flex}.VWh0dG_modelDot{border-radius:50%;flex:none;width:9px;height:9px}.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-alias-label-primary)}.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:var(--dsw-alias-bg-layer-2)}.VWh0dG_rateBadgeBuiltin{color:var(--dsw-alias-label-tertiary);background:var(--dsw-alias-bg-layer-2)}.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_bandTag>span:first-child{color:var(--dsw-alias-label-primary);font-weight:500}.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)}.VWh0dG_healthBad{background:var(--dsw-static-red-500)}.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:var(--dsw-alias-bg-layer-2)}.VWh0dG_healthBadgeBad{color:var(--dsw-static-red-500);background:var(--dsw-alias-bg-layer-2)}.VWh0dG_planTag{color:var(--dsw-static-green-500);background:var(--dsw-alias-bg-layer-2);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:var(--dsw-alias-bg-layer-2);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:var(--dsw-alias-bg-layer-2);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_liveTierPeak{color:var(--dsw-static-blue-500);font-weight:600}.VWh0dG_liveTierOff{color:var(--dsw-static-green-500);font-weight:600}.VWh0dG_liveQuotaWarn{color:var(--dsw-static-amber-500);font-weight:600}.VWh0dG_liveQuotaCrit{color:var(--dsw-static-red-500);font-weight:600}.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-l1);background:var(--dsw-alias-bg-layer-2);border-radius:6px;align-items:center;gap:2px;margin-right:8px;padding:2px;display:inline-flex}.VWh0dG_currencyButton{color:var(--dsw-alias-label-secondary);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-bg-layer-1);color:var(--dsw-alias-label-primary)}.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-l1);background:var(--dsw-alias-bg-layer-2);border-radius:10px;padding:12px 14px}.VWh0dG_subscriptionHead{flex-wrap:wrap;align-items:baseline;gap:6px;margin-bottom:8px;display:flex}.VWh0dG_subscriptionName{font-size:13px;font-weight:700}.VWh0dG_subscriptionPlan{color:var(--dsw-alias-label-secondary);font-size:11px}.VWh0dG_subscriptionPlan[data-kind=code],.VWh0dG_subscriptionPlan[data-kind=token]{color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-3);border-radius:999px;padding:1px 8px;font-weight:500}.VWh0dG_subscriptionStatus{color:var(--dsw-alias-label-secondary);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-label-secondary);flex:0 0 44px}.VWh0dG_subscriptionTrack{background:var(--dsw-alias-bg-layer-3);border-radius:3px;flex:1;height:5px;overflow:hidden}.VWh0dG_subscriptionFill{background:var(--dsw-static-blue-500);border-radius:3px;height:100%;transition:width .2s;display:block}.VWh0dG_subscriptionFillWarn{background:var(--dsw-static-amber-500)}.VWh0dG_subscriptionFillOver{background:var(--dsw-static-red-500)}.VWh0dG_subscriptionPct{text-align:right;font-variant-numeric:tabular-nums;flex:none;min-width:52px}.VWh0dG_subscriptionExhausted{color:var(--dsw-static-red-500);min-width:52px;font-weight:600}.VWh0dG_subscriptionReset{color:var(--dsw-alias-label-secondary);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:var(--dsw-alias-bg-layer-2);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:var(--dsw-static-neutral-bluish-00);background:var(--dsw-static-red-500);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:124px;padding:16px 2px 0;display:flex;overflow-x:auto}.VWh0dG_roundsBarCol{border-radius:5px 5px 0 0;flex-direction:column;flex:1 0 28px;justify-content:flex-end;align-items:stretch;height:100%;display:flex;position:relative}.VWh0dG_roundsBarColPeak{background:color-mix(in srgb, var(--dsw-static-amber-500) 16%, transparent)}.VWh0dG_roundsBarColOff{background:var(--dsw-alias-bg-module-platform)}.VWh0dG_roundsBarLabel{text-align:center;color:var(--dsw-alias-label-secondary);white-space:nowrap;text-overflow:ellipsis;max-width:100%;font-size:9px;line-height:1.2;position:absolute;bottom:0;left:0;right:0;overflow:hidden;transform:translateY(-100%)}.VWh0dG_roundsBarWrap{flex:1;align-items:flex-end;min-height:0;display:flex}.VWh0dG_roundsBar{background:var(--dsw-static-blue-500);border-radius:2px 2px 0 0;width:100%;min-height:2px;position:relative}.VWh0dG_roundsBarFlagged{background:var(--dsw-static-red-500);border-radius:2px 2px 0 0;width:100%;min-height:2px;position:relative}.VWh0dG_roundsFlagMark{background:var(--dsw-static-red-500);border-radius:50%;width:7px;height:7px;position:absolute;top:-3px;right:-3px}.VWh0dG_roundsAxis{color:var(--dsw-alias-label-secondary);justify-content:space-between;margin-top:6px;font-size:10px;display:flex}.VWh0dG_roundsEmpty{color:var(--dsw-alias-label-secondary);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);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)}.VWh0dG_heatmapFooter{color:var(--dsw-alias-label-secondary);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{gap:14px}.VWh0dG_heroTop{flex-direction:column;align-items:flex-start;gap:12px}.VWh0dG_heroGauge{width:72px;height:72px}.VWh0dG_heroSide{gap:12px}.VWh0dG_heroSideSpacer{display:none}}.VWh0dG_peakAlert{z-index:2000;border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);border-radius:12px;align-items:center;gap:12px;min-width:300px;max-width:460px;padding:10px 12px;animation:.2s VWh0dG_peakAlertIn;display:flex;position:fixed;box-shadow:0 4px 16px #00000014}.VWh0dG_peakAlertCorner{bottom:18px;right:18px}.VWh0dG_peakAlertCenter{top:20%;left:50%;transform:translate(-50%)}.VWh0dG_peakAlertTag{letter-spacing:.01em;color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-3);white-space:nowrap;border-radius:999px;flex:none;align-items:center;gap:6px;padding:3px 9px;font-size:11px;font-weight:650;display:inline-flex}.VWh0dG_peakAlertTag:before{content:\"\";background:currentColor;border-radius:50%;width:6px;height:6px}.VWh0dG_peakAlertPeak .VWh0dG_peakAlertTag{color:var(--dsw-static-amber-500)}.VWh0dG_peakAlertOff .VWh0dG_peakAlertTag{color:var(--dsw-static-blue-500)}.VWh0dG_peakAlertCountdown{font-variant-numeric:tabular-nums;color:var(--dsw-alias-label-primary);flex:none;font-size:18px;font-weight:700;line-height:1}.VWh0dG_peakAlertText{min-width:0;color:var(--dsw-alias-label-secondary);flex:1;font-size:12px;line-height:18px}.VWh0dG_peakAlertClose{width:20px;height:20px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:0;border-radius:6px;flex:none;justify-content:center;align-items:center;font-size:15px;line-height:1;transition:background-color .14s,color .14s;display:inline-flex}.VWh0dG_peakAlertClose:hover{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-2)}@keyframes VWh0dG_peakAlertIn{0%{opacity:0}to{opacity:1}}.VWh0dG_peakAlertPanel{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);border-radius:16px;flex-direction:column;gap:10px;padding:14px 16px;display:flex}.VWh0dG_peakAlertPanelHead{justify-content:space-between;align-items:center;gap:10px;display:flex}.VWh0dG_peakAlertPanelLabel{color:var(--dsw-alias-label-primary);font-size:13px;font-weight:600}.VWh0dG_peakAlertPanelBody{flex-wrap:wrap;align-items:center;gap:12px 16px;display:flex}.VWh0dG_peakAlertField{color:var(--dsw-alias-label-secondary);align-items:center;gap:8px;font-size:12px;display:inline-flex}.VWh0dG_peakAlertNum{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-2);width:56px;color:var(--dsw-alias-label-primary);font-variant-numeric:tabular-nums;border-radius:6px;padding:4px 6px}.VWh0dG_peakAlertSelect{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-primary);border-radius:6px;padding:4px 6px;font-size:12px}.VWh0dG_peakAlertCheck{color:var(--dsw-alias-label-secondary);align-items:center;gap:6px;font-size:12px;display:inline-flex}.VWh0dG_peakAlertPreview{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-primary);cursor:pointer;border-radius:6px;padding:5px 10px;font-size:12px}.VWh0dG_peakAlertPreview:hover{background:var(--dsw-alias-bg-layer-3)}.VWh0dG_settingsHead{flex-direction:column;gap:4px;margin-bottom:2px;display:flex}.VWh0dG_settingsTitle{letter-spacing:-.005em;color:var(--dsw-alias-label-primary);margin:0;font-size:15px;font-weight:650;line-height:22px}.VWh0dG_settingsHint{color:var(--dsw-alias-label-caption);margin:0;font-size:11px;line-height:16px}.VWh0dG_budgetHint,.VWh0dG_peakAlertHint{color:var(--dsw-alias-label-caption);margin:6px 0 0;font-size:11px;line-height:16px}";
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,223 +34,250 @@ window.__ModuleLoader__.load({
34
34
  document.head.appendChild(tag);
35
35
  }
36
36
  var UsageBilling_module_css_default = {
37
- "dashboardTitle": "VWh0dG_dashboardTitle",
38
- "triggerSparkHot": "VWh0dG_triggerSparkHot",
39
- "shareTrack": "VWh0dG_shareTrack",
40
- "budgetInputWrap": "VWh0dG_budgetInputWrap",
41
- "chartLegendBar": "VWh0dG_chartLegendBar",
42
- "numCol": "VWh0dG_numCol",
43
- "balanceCell": "VWh0dG_balanceCell",
44
- "triggerMeta": "VWh0dG_triggerMeta",
45
- "triggerWrap": "VWh0dG_triggerWrap",
46
- "triggerPopRow": "VWh0dG_triggerPopRow",
47
- "heroGaugePct": "VWh0dG_heroGaugePct",
48
- "shareSegAssistant": "VWh0dG_shareSegAssistant",
49
- "shareLegend": "VWh0dG_shareLegend",
50
- "healthDot": "VWh0dG_healthDot",
51
- "subscriptionReset": "VWh0dG_subscriptionReset",
52
- "healthBad": "VWh0dG_healthBad",
53
- "roundsBarLabel": "VWh0dG_roundsBarLabel",
54
- "chartLegendLine": "VWh0dG_chartLegendLine",
55
- "balanceDaysLow": "VWh0dG_balanceDaysLow",
56
- "kpiDetail": "VWh0dG_kpiDetail",
57
- "roundsBarCol": "VWh0dG_roundsBarCol",
58
- "heroSideItem": "VWh0dG_heroSideItem",
59
- "triggerSpark": "VWh0dG_triggerSpark",
37
+ "peakAlertPanelLabel": "VWh0dG_peakAlertPanelLabel",
38
+ "shareDot": "VWh0dG_shareDot",
60
39
  "shareSegUser": "VWh0dG_shareSegUser",
61
- "exportBar": "VWh0dG_exportBar",
62
- "healthIdle": "VWh0dG_healthIdle",
40
+ "kpiGreen": "VWh0dG_kpiGreen",
41
+ "healthOk": "VWh0dG_healthOk",
42
+ "heroReadout": "VWh0dG_heroReadout",
43
+ "shareItem": "VWh0dG_shareItem",
44
+ "dashboardHead": "VWh0dG_dashboardHead",
45
+ "dashboardTitle": "VWh0dG_dashboardTitle",
63
46
  "estimatedTag": "VWh0dG_estimatedTag",
64
- "subscriptionGrid": "VWh0dG_subscriptionGrid",
65
- "subscriptionWindowLabel": "VWh0dG_subscriptionWindowLabel",
66
- "chartTooltipSwatch": "VWh0dG_chartTooltipSwatch",
67
- "chartTooltipRow": "VWh0dG_chartTooltipRow",
47
+ "providerGroup": "VWh0dG_providerGroup",
48
+ "peakAlertPanel": "VWh0dG_peakAlertPanel",
49
+ "budgetFill": "VWh0dG_budgetFill",
50
+ "bandTagOff": "VWh0dG_bandTagOff",
68
51
  "heatmapGrid": "VWh0dG_heatmapGrid",
69
- "heroMeta": "VWh0dG_heroMeta",
70
- "bucketStatValue": "VWh0dG_bucketStatValue",
71
- "budgetUnit": "VWh0dG_budgetUnit",
72
- "chartLegend": "VWh0dG_chartLegend",
73
- "providerGroupBadge": "VWh0dG_providerGroupBadge",
74
- "modelCell": "VWh0dG_modelCell",
75
- "dashboardIn": "VWh0dG_dashboardIn",
76
- "railButton": "VWh0dG_railButton",
77
- "shareItem": "VWh0dG_shareItem",
78
- "pricingChevron": "VWh0dG_pricingChevron",
79
- "bucketStatSub": "VWh0dG_bucketStatSub",
80
- "budgetTrack": "VWh0dG_budgetTrack",
81
- "liveCostBar": "VWh0dG_liveCostBar",
82
- "exportLabel": "VWh0dG_exportLabel",
52
+ "deltaUp": "VWh0dG_deltaUp",
53
+ "budgetFillWarn": "VWh0dG_budgetFillWarn",
83
54
  "providerGroupList": "VWh0dG_providerGroupList",
84
- "providerGroupBalance": "VWh0dG_providerGroupBalance",
85
- "na": "VWh0dG_na",
86
- "tabPanelIn": "VWh0dG_tabPanelIn",
87
- "triggerAmount": "VWh0dG_triggerAmount",
88
- "pricingChevronOpen": "VWh0dG_pricingChevronOpen",
89
- "dashboard": "VWh0dG_dashboard",
90
- "kpiGrid": "VWh0dG_kpiGrid",
91
- "heroGaugeLabel": "VWh0dG_heroGaugeLabel",
92
- "shareValue": "VWh0dG_shareValue",
93
- "kpiValue": "VWh0dG_kpiValue",
94
- "bucketCost": "VWh0dG_bucketCost",
95
- "triggerRow": "VWh0dG_triggerRow",
96
- "chartTooltip": "VWh0dG_chartTooltip",
97
- "modelName": "VWh0dG_modelName",
98
- "panelHead": "VWh0dG_panelHead",
99
- "chartWrap": "VWh0dG_chartWrap",
100
- "liveQuotaCrit": "VWh0dG_liveQuotaCrit",
55
+ "budgetLabel": "VWh0dG_budgetLabel",
56
+ "heroGaugePctOver": "VWh0dG_heroGaugePctOver",
101
57
  "roundsBar": "VWh0dG_roundsBar",
102
- "roundsBarFlagged": "VWh0dG_roundsBarFlagged",
103
- "heroSideLabel": "VWh0dG_heroSideLabel",
104
- "pricingTable": "VWh0dG_pricingTable",
105
- "dashboardRight": "VWh0dG_dashboardRight",
106
- "roundsFlagMark": "VWh0dG_roundsFlagMark",
107
- "roundsBarWrap": "VWh0dG_roundsBarWrap",
108
- "chartBar": "VWh0dG_chartBar",
109
- "providerGroupMeta": "VWh0dG_providerGroupMeta",
110
- "heroMain": "VWh0dG_heroMain",
111
- "rateBadgeBuiltin": "VWh0dG_rateBadgeBuiltin",
112
- "panel": "VWh0dG_panel",
113
- "budgetValue": "VWh0dG_budgetValue",
114
- "roundsEmpty": "VWh0dG_roundsEmpty",
115
- "heatmapCell": "VWh0dG_heatmapCell",
116
- "heroGaugeArc": "VWh0dG_heroGaugeArc",
117
- "kpiGreen": "VWh0dG_kpiGreen",
118
- "exportButton": "VWh0dG_exportButton",
119
- "healthOk": "VWh0dG_healthOk",
120
- "healthBadge": "VWh0dG_healthBadge",
121
- "liveCostItem": "VWh0dG_liveCostItem",
122
- "subscriptionExhausted": "VWh0dG_subscriptionExhausted",
123
- "heatmapCellEmpty": "VWh0dG_heatmapCellEmpty",
124
- "heatmapHover": "VWh0dG_heatmapHover",
125
- "kpiTile": "VWh0dG_kpiTile",
126
- "chartAxisLabel": "VWh0dG_chartAxisLabel",
127
- "providerGroupHead": "VWh0dG_providerGroupHead",
58
+ "peakAlertPanelHead": "VWh0dG_peakAlertPanelHead",
59
+ "modelProvider": "VWh0dG_modelProvider",
60
+ "peakAlertField": "VWh0dG_peakAlertField",
61
+ "currencyButton": "VWh0dG_currencyButton",
62
+ "heroGauge": "VWh0dG_heroGauge",
63
+ "shareSegTool": "VWh0dG_shareSegTool",
64
+ "roundsBarLabel": "VWh0dG_roundsBarLabel",
65
+ "triggerMeta": "VWh0dG_triggerMeta",
66
+ "tabButton": "VWh0dG_tabButton",
128
67
  "switch": "VWh0dG_switch",
129
- "switchKnob": "VWh0dG_switchKnob",
130
- "pricingToggle": "VWh0dG_pricingToggle",
131
- "heroLabel": "VWh0dG_heroLabel",
132
- "heroGaugeSvg": "VWh0dG_heroGaugeSvg",
133
- "heroReadout": "VWh0dG_heroReadout",
134
- "budgetFillOver": "VWh0dG_budgetFillOver",
135
- "rangeButton": "VWh0dG_rangeButton",
136
- "bucketOfficial": "VWh0dG_bucketOfficial",
137
- "budgetOverPulse": "VWh0dG_budgetOverPulse",
68
+ "heroGaugeArc": "VWh0dG_heroGaugeArc",
138
69
  "bucketStatLabel": "VWh0dG_bucketStatLabel",
139
- "subscriptionHead": "VWh0dG_subscriptionHead",
140
- "headTitleRow": "VWh0dG_headTitleRow",
141
- "triggerSparkBar": "VWh0dG_triggerSparkBar",
142
- "subscriptionFill": "VWh0dG_subscriptionFill",
143
- "triggerPopBars": "VWh0dG_triggerPopBars",
144
- "panelHint": "VWh0dG_panelHint",
145
- "deltaUp": "VWh0dG_deltaUp",
146
- "bandTag": "VWh0dG_bandTag",
147
- "shareDot": "VWh0dG_shareDot",
148
- "budgetControls": "VWh0dG_budgetControls",
70
+ "chartTooltipDate": "VWh0dG_chartTooltipDate",
149
71
  "bucketStat": "VWh0dG_bucketStat",
150
- "triggerPopLabel": "VWh0dG_triggerPopLabel",
151
- "delta": "VWh0dG_delta",
152
- "rangeButtonActive": "VWh0dG_rangeButtonActive",
153
- "triggerBody": "VWh0dG_triggerBody",
154
- "liveTierOff": "VWh0dG_liveTierOff",
155
- "bucketSep": "VWh0dG_bucketSep",
156
- "heroValue": "VWh0dG_heroValue",
157
- "tabButton": "VWh0dG_tabButton",
72
+ "budgetInput": "VWh0dG_budgetInput",
73
+ "roundsBarColPeak": "VWh0dG_roundsBarColPeak",
74
+ "subscriptionPct": "VWh0dG_subscriptionPct",
158
75
  "planTag": "VWh0dG_planTag",
159
- "healthBadgeBad": "VWh0dG_healthBadgeBad",
160
- "currencyButtonActive": "VWh0dG_currencyButtonActive",
161
- "tabPanel": "VWh0dG_tabPanel",
162
- "triggerPopValue": "VWh0dG_triggerPopValue",
163
- "closeButton": "VWh0dG_closeButton",
164
- "subscriptionTrack": "VWh0dG_subscriptionTrack",
76
+ "exportBar": "VWh0dG_exportBar",
77
+ "liveCostItem": "VWh0dG_liveCostItem",
78
+ "tabNav": "VWh0dG_tabNav",
165
79
  "dashboardModal": "VWh0dG_dashboardModal",
166
- "heroGaugeArcOver": "VWh0dG_heroGaugeArcOver",
167
- "heroGaugePctOver": "VWh0dG_heroGaugePctOver",
80
+ "heroMain": "VWh0dG_heroMain",
81
+ "providerGroupBalance": "VWh0dG_providerGroupBalance",
82
+ "roundsBarCol": "VWh0dG_roundsBarCol",
83
+ "kpiDetail": "VWh0dG_kpiDetail",
84
+ "chartLegendLine": "VWh0dG_chartLegendLine",
85
+ "shareValue": "VWh0dG_shareValue",
86
+ "peakAlertHint": "VWh0dG_peakAlertHint",
87
+ "subscriptionWindowLabel": "VWh0dG_subscriptionWindowLabel",
88
+ "heatmapLegend": "VWh0dG_heatmapLegend",
89
+ "chartTooltipRow": "VWh0dG_chartTooltipRow",
168
90
  "switchOn": "VWh0dG_switchOn",
91
+ "emptyRow": "VWh0dG_emptyRow",
92
+ "heatmapCell": "VWh0dG_heatmapCell",
93
+ "roundsFlagBadge": "VWh0dG_roundsFlagBadge",
94
+ "balanceDaysLow": "VWh0dG_balanceDaysLow",
95
+ "providerGroupTitle": "VWh0dG_providerGroupTitle",
96
+ "triggerSparkBar": "VWh0dG_triggerSparkBar",
97
+ "peakAlertSelect": "VWh0dG_peakAlertSelect",
98
+ "shareSegPeak": "VWh0dG_shareSegPeak",
99
+ "exportLabel": "VWh0dG_exportLabel",
100
+ "heroMeta": "VWh0dG_heroMeta",
101
+ "budgetOverPulse": "VWh0dG_budgetOverPulse",
169
102
  "chartGrid": "VWh0dG_chartGrid",
170
- "triggerIcon": "VWh0dG_triggerIcon",
171
- "modelTable": "VWh0dG_modelTable",
172
- "flatTag": "VWh0dG_flatTag",
173
103
  "rounds": "VWh0dG_rounds",
174
- "budget": "VWh0dG_budget",
175
- "roundsBars": "VWh0dG_roundsBars",
104
+ "pricingToggleText": "VWh0dG_pricingToggleText",
105
+ "liveCostSep": "VWh0dG_liveCostSep",
106
+ "modelTable": "VWh0dG_modelTable",
107
+ "heroSideItem": "VWh0dG_heroSideItem",
108
+ "subscriptionWindow": "VWh0dG_subscriptionWindow",
109
+ "panel": "VWh0dG_panel",
110
+ "heatmapFooter": "VWh0dG_heatmapFooter",
111
+ "rateBadgeLive": "VWh0dG_rateBadgeLive",
112
+ "balanceDays": "VWh0dG_balanceDays",
113
+ "chartAxisLabel": "VWh0dG_chartAxisLabel",
114
+ "settingsTitle": "VWh0dG_settingsTitle",
115
+ "closeButton": "VWh0dG_closeButton",
116
+ "dashboardBody": "VWh0dG_dashboardBody",
117
+ "panelHead": "VWh0dG_panelHead",
118
+ "peakAlertIn": "VWh0dG_peakAlertIn",
176
119
  "heatmap": "VWh0dG_heatmap",
177
- "heroTop": "VWh0dG_heroTop",
178
- "triggerPop": "VWh0dG_triggerPop",
179
- "bucketSummary": "VWh0dG_bucketSummary",
180
- "shareSegPeak": "VWh0dG_shareSegPeak",
120
+ "bandTag": "VWh0dG_bandTag",
121
+ "shareLegend": "VWh0dG_shareLegend",
122
+ "subscriptionCard": "VWh0dG_subscriptionCard",
123
+ "chartStack": "VWh0dG_chartStack",
124
+ "peakAlertText": "VWh0dG_peakAlertText",
125
+ "rangeButton": "VWh0dG_rangeButton",
126
+ "delta": "VWh0dG_delta",
127
+ "heroSideSpacer": "VWh0dG_heroSideSpacer",
181
128
  "chartEmpty": "VWh0dG_chartEmpty",
182
- "chartCrosshair": "VWh0dG_chartCrosshair",
183
129
  "healthBadgeOk": "VWh0dG_healthBadgeOk",
184
- "currencyButton": "VWh0dG_currencyButton",
185
- "bandTagOff": "VWh0dG_bandTagOff",
186
- "subscriptionStatus": "VWh0dG_subscriptionStatus",
187
- "heatmapFooter": "VWh0dG_heatmapFooter",
188
- "chartTooltipDate": "VWh0dG_chartTooltipDate",
189
- "deltaDown": "VWh0dG_deltaDown",
190
- "tableScroll": "VWh0dG_tableScroll",
191
- "costCol": "VWh0dG_costCol",
192
- "modelTableScroll": "VWh0dG_modelTableScroll",
193
- "budgetInput": "VWh0dG_budgetInput",
194
- "subscriptionName": "VWh0dG_subscriptionName",
195
- "budgetFill": "VWh0dG_budgetFill",
196
- "providerGroupTitle": "VWh0dG_providerGroupTitle",
197
- "providerGroupName": "VWh0dG_providerGroupName",
198
- "heroSideSpacer": "VWh0dG_heroSideSpacer",
199
- "liveQuotaWarn": "VWh0dG_liveQuotaWarn",
200
- "roundsAxis": "VWh0dG_roundsAxis",
130
+ "liveTierPeak": "VWh0dG_liveTierPeak",
131
+ "tabPanel": "VWh0dG_tabPanel",
132
+ "bucketSep": "VWh0dG_bucketSep",
201
133
  "modelDot": "VWh0dG_modelDot",
134
+ "triggerSpark": "VWh0dG_triggerSpark",
135
+ "heroSideLabel": "VWh0dG_heroSideLabel",
136
+ "pricingChevron": "VWh0dG_pricingChevron",
137
+ "railButton": "VWh0dG_railButton",
138
+ "bandPriceOff": "VWh0dG_bandPriceOff",
139
+ "triggerSub": "VWh0dG_triggerSub",
140
+ "heroGaugeTrack": "VWh0dG_heroGaugeTrack",
141
+ "bucketOfficial": "VWh0dG_bucketOfficial",
142
+ "healthBadgeBad": "VWh0dG_healthBadgeBad",
143
+ "triggerWrap": "VWh0dG_triggerWrap",
144
+ "dashboardSubtitle": "VWh0dG_dashboardSubtitle",
145
+ "kpiValue": "VWh0dG_kpiValue",
146
+ "dashboardRight": "VWh0dG_dashboardRight",
147
+ "peakAlertOff": "VWh0dG_peakAlertOff",
148
+ "liveQuotaWarn": "VWh0dG_liveQuotaWarn",
149
+ "uncataloguedTag": "VWh0dG_uncataloguedTag",
202
150
  "trigger": "VWh0dG_trigger",
203
- "budgetFillWarn": "VWh0dG_budgetFillWarn",
204
- "bandPrice": "VWh0dG_bandPrice",
205
- "currencyToggle": "VWh0dG_currencyToggle",
206
- "roundsFlagBadge": "VWh0dG_roundsFlagBadge",
207
- "panelTitle": "VWh0dG_panelTitle",
208
151
  "subscriptionFillOver": "VWh0dG_subscriptionFillOver",
209
- "providerGroup": "VWh0dG_providerGroup",
210
- "rateBadgeLive": "VWh0dG_rateBadgeLive",
211
- "heroGaugeCenter": "VWh0dG_heroGaugeCenter",
152
+ "subscriptionTrack": "VWh0dG_subscriptionTrack",
153
+ "costCol": "VWh0dG_costCol",
154
+ "budgetHint": "VWh0dG_budgetHint",
155
+ "providerGroupHead": "VWh0dG_providerGroupHead",
156
+ "rangeToggle": "VWh0dG_rangeToggle",
157
+ "chartTooltipSwatch": "VWh0dG_chartTooltipSwatch",
158
+ "roundsEmpty": "VWh0dG_roundsEmpty",
159
+ "shareSegAssistant": "VWh0dG_shareSegAssistant",
160
+ "chartLegendBar": "VWh0dG_chartLegendBar",
212
161
  "trendPanel": "VWh0dG_trendPanel",
213
- "dashboardSubtitle": "VWh0dG_dashboardSubtitle",
214
- "modelProvider": "VWh0dG_modelProvider",
215
- "rateBadge": "VWh0dG_rateBadge",
216
- "pricingToggleText": "VWh0dG_pricingToggleText",
162
+ "modelCell": "VWh0dG_modelCell",
163
+ "pricingToggle": "VWh0dG_pricingToggle",
164
+ "healthBadge": "VWh0dG_healthBadge",
165
+ "budgetValue": "VWh0dG_budgetValue",
217
166
  "providerGroupBalanceLabel": "VWh0dG_providerGroupBalanceLabel",
218
- "liveTierPeak": "VWh0dG_liveTierPeak",
219
- "triggerPopBar": "VWh0dG_triggerPopBar",
220
- "emptyRow": "VWh0dG_emptyRow",
221
- "bandPriceOff": "VWh0dG_bandPriceOff",
222
- "heroGauge": "VWh0dG_heroGauge",
223
- "hero": "VWh0dG_hero",
224
- "chartSvg": "VWh0dG_chartSvg",
225
- "subscriptionPct": "VWh0dG_subscriptionPct",
226
- "heatmapLegend": "VWh0dG_heatmapLegend",
227
- "dashboardBody": "VWh0dG_dashboardBody",
228
- "tabNav": "VWh0dG_tabNav",
167
+ "peakAlertCorner": "VWh0dG_peakAlertCorner",
168
+ "modelName": "VWh0dG_modelName",
169
+ "na": "VWh0dG_na",
170
+ "heroValue": "VWh0dG_heroValue",
171
+ "budgetUnit": "VWh0dG_budgetUnit",
172
+ "dashboardIn": "VWh0dG_dashboardIn",
229
173
  "kpiLabel": "VWh0dG_kpiLabel",
230
- "liveCostSep": "VWh0dG_liveCostSep",
231
- "triggerSub": "VWh0dG_triggerSub",
232
- "dashboardHead": "VWh0dG_dashboardHead",
233
- "heroSide": "VWh0dG_heroSide",
174
+ "switchKnob": "VWh0dG_switchKnob",
175
+ "peakAlertCenter": "VWh0dG_peakAlertCenter",
176
+ "panelTitle": "VWh0dG_panelTitle",
177
+ "chartSvg": "VWh0dG_chartSvg",
178
+ "rateBadge": "VWh0dG_rateBadge",
179
+ "roundsAxis": "VWh0dG_roundsAxis",
180
+ "bucketSummary": "VWh0dG_bucketSummary",
181
+ "tableScroll": "VWh0dG_tableScroll",
182
+ "heroGaugeLabel": "VWh0dG_heroGaugeLabel",
183
+ "triggerPop": "VWh0dG_triggerPop",
184
+ "liveCostBar": "VWh0dG_liveCostBar",
185
+ "subscriptionFill": "VWh0dG_subscriptionFill",
186
+ "subscriptionFillWarn": "VWh0dG_subscriptionFillWarn",
187
+ "peakAlertPreview": "VWh0dG_peakAlertPreview",
188
+ "heroCurrency": "VWh0dG_heroCurrency",
189
+ "triggerPopBar": "VWh0dG_triggerPopBar",
190
+ "deltaDown": "VWh0dG_deltaDown",
191
+ "rangeButtonActive": "VWh0dG_rangeButtonActive",
192
+ "healthIdle": "VWh0dG_healthIdle",
193
+ "kpiGrid": "VWh0dG_kpiGrid",
194
+ "healthBad": "VWh0dG_healthBad",
195
+ "peakAlertClose": "VWh0dG_peakAlertClose",
196
+ "triggerPopBars": "VWh0dG_triggerPopBars",
197
+ "roundsBars": "VWh0dG_roundsBars",
198
+ "peakAlertCheck": "VWh0dG_peakAlertCheck",
234
199
  "shareSeg": "VWh0dG_shareSeg",
235
- "chartDot": "VWh0dG_chartDot",
236
- "subscriptionCard": "VWh0dG_subscriptionCard",
237
- "subscriptionPlan": "VWh0dG_subscriptionPlan",
238
- "heroSideValue": "VWh0dG_heroSideValue",
239
- "shareSegTool": "VWh0dG_shareSegTool",
240
- "subscriptionWindow": "VWh0dG_subscriptionWindow",
241
- "uncataloguedTag": "VWh0dG_uncataloguedTag",
200
+ "tabPanelIn": "VWh0dG_tabPanelIn",
201
+ "chartWrap": "VWh0dG_chartWrap",
202
+ "heatmapCellEmpty": "VWh0dG_heatmapCellEmpty",
203
+ "subscriptionHead": "VWh0dG_subscriptionHead",
204
+ "bucketStatValue": "VWh0dG_bucketStatValue",
205
+ "chartLegend": "VWh0dG_chartLegend",
206
+ "dashboard": "VWh0dG_dashboard",
207
+ "currencyToggle": "VWh0dG_currencyToggle",
208
+ "providerGroupName": "VWh0dG_providerGroupName",
209
+ "exportButton": "VWh0dG_exportButton",
210
+ "liveQuotaCrit": "VWh0dG_liveQuotaCrit",
211
+ "peakAlertCountdown": "VWh0dG_peakAlertCountdown",
212
+ "shareSegOff": "VWh0dG_shareSegOff",
213
+ "bandPrice": "VWh0dG_bandPrice",
242
214
  "bucketThird": "VWh0dG_bucketThird",
215
+ "currencyButtonActive": "VWh0dG_currencyButtonActive",
216
+ "subscriptionStatus": "VWh0dG_subscriptionStatus",
217
+ "subscriptionPlan": "VWh0dG_subscriptionPlan",
218
+ "peakAlertPeak": "VWh0dG_peakAlertPeak",
219
+ "headTitleRow": "VWh0dG_headTitleRow",
220
+ "rateBadgeBuiltin": "VWh0dG_rateBadgeBuiltin",
221
+ "healthDot": "VWh0dG_healthDot",
222
+ "peakAlert": "VWh0dG_peakAlert",
223
+ "heroTop": "VWh0dG_heroTop",
224
+ "shareTrack": "VWh0dG_shareTrack",
225
+ "triggerBody": "VWh0dG_triggerBody",
226
+ "triggerAmount": "VWh0dG_triggerAmount",
227
+ "heroLabel": "VWh0dG_heroLabel",
228
+ "subscriptionReset": "VWh0dG_subscriptionReset",
229
+ "roundsBarFlagged": "VWh0dG_roundsBarFlagged",
230
+ "heroGaugeSvg": "VWh0dG_heroGaugeSvg",
231
+ "chartLine": "VWh0dG_chartLine",
232
+ "flatTag": "VWh0dG_flatTag",
233
+ "budgetControls": "VWh0dG_budgetControls",
234
+ "subscriptionName": "VWh0dG_subscriptionName",
235
+ "heatmapHover": "VWh0dG_heatmapHover",
236
+ "heroGaugeArcOver": "VWh0dG_heroGaugeArcOver",
237
+ "bucketCost": "VWh0dG_bucketCost",
238
+ "liveTierOff": "VWh0dG_liveTierOff",
239
+ "heroSideValue": "VWh0dG_heroSideValue",
240
+ "roundsBarWrap": "VWh0dG_roundsBarWrap",
243
241
  "tabButtonActive": "VWh0dG_tabButtonActive",
244
- "heroCurrency": "VWh0dG_heroCurrency",
245
- "shareSegOff": "VWh0dG_shareSegOff",
246
- "rangeToggle": "VWh0dG_rangeToggle",
247
- "heroGaugeTrack": "VWh0dG_heroGaugeTrack",
242
+ "triggerPopValue": "VWh0dG_triggerPopValue",
243
+ "chartDot": "VWh0dG_chartDot",
244
+ "bucketStatSub": "VWh0dG_bucketStatSub",
245
+ "budgetInputWrap": "VWh0dG_budgetInputWrap",
246
+ "chartCrosshair": "VWh0dG_chartCrosshair",
247
+ "triggerPopRow": "VWh0dG_triggerPopRow",
248
+ "triggerPopLabel": "VWh0dG_triggerPopLabel",
249
+ "subscriptionExhausted": "VWh0dG_subscriptionExhausted",
250
+ "peakAlertTag": "VWh0dG_peakAlertTag",
251
+ "heroGaugePct": "VWh0dG_heroGaugePct",
252
+ "balanceCell": "VWh0dG_balanceCell",
253
+ "triggerSparkHot": "VWh0dG_triggerSparkHot",
254
+ "budgetTrack": "VWh0dG_budgetTrack",
255
+ "modelTableScroll": "VWh0dG_modelTableScroll",
256
+ "providerGroupBadge": "VWh0dG_providerGroupBadge",
257
+ "heroGaugeCenter": "VWh0dG_heroGaugeCenter",
258
+ "pricingTable": "VWh0dG_pricingTable",
259
+ "numCol": "VWh0dG_numCol",
260
+ "settingsHead": "VWh0dG_settingsHead",
261
+ "peakAlertNum": "VWh0dG_peakAlertNum",
262
+ "roundsFlagMark": "VWh0dG_roundsFlagMark",
263
+ "chartBar": "VWh0dG_chartBar",
264
+ "peakAlertPanelBody": "VWh0dG_peakAlertPanelBody",
265
+ "providerGroupMeta": "VWh0dG_providerGroupMeta",
266
+ "budgetFillOver": "VWh0dG_budgetFillOver",
267
+ "subscriptionGrid": "VWh0dG_subscriptionGrid",
268
+ "pricingChevronOpen": "VWh0dG_pricingChevronOpen",
269
+ "triggerIcon": "VWh0dG_triggerIcon",
270
+ "triggerRow": "VWh0dG_triggerRow",
271
+ "roundsBarColOff": "VWh0dG_roundsBarColOff",
272
+ "pricingTip": "VWh0dG_pricingTip",
273
+ "budget": "VWh0dG_budget",
274
+ "heroSide": "VWh0dG_heroSide",
275
+ "panelHint": "VWh0dG_panelHint",
248
276
  "budgetHead": "VWh0dG_budgetHead",
249
- "chartStack": "VWh0dG_chartStack",
250
- "subscriptionFillWarn": "VWh0dG_subscriptionFillWarn",
251
- "chartLine": "VWh0dG_chartLine",
252
- "budgetLabel": "VWh0dG_budgetLabel",
253
- "balanceDays": "VWh0dG_balanceDays"
277
+ "settingsHint": "VWh0dG_settingsHint",
278
+ "chartTooltip": "VWh0dG_chartTooltip",
279
+ "hero": "VWh0dG_hero",
280
+ "kpiTile": "VWh0dG_kpiTile"
254
281
  };
255
282
  //#endregion
256
283
  //#region src/client/plan-knowledge.ts
@@ -367,7 +394,8 @@ window.__ModuleLoader__.load({
367
394
  /** Default share of traffic assumed to fall in the peak band (0..1). */
368
395
  const DEFAULT_PEAK_SHARE = .5;
369
396
  /**
370
- * 高峰时段判定(北京时间,UTC+8,无夏令时):09:00–12:00、14:00–18:00。
397
+ * 工作日高峰时段判定(北京时间,UTC+8,无夏令时):09:00–12:00、14:00–18:00。
398
+ * 周末(周六/周日)北京全天为低谷,不调用本函数判定峰/平。
371
399
  * @param beijingHour - 北京时间的小时数(0–23)。
372
400
  */
373
401
  function isPeakHour(beijingHour) {
@@ -376,12 +404,26 @@ window.__ModuleLoader__.load({
376
404
  /**
377
405
  * 由时刻(epoch 毫秒)推断计费时段;时刻未知/非法时按高峰计(保守:未知
378
406
  * 时刻不低估成本,与社区 dsh-usage-chart 的 tierAt 语义一致)。
407
+ * 周末(北京时间周六/周日)全天不区分峰谷,统一按低谷价。
379
408
  * @param timeMs - Unix epoch 毫秒;null/undefined/NaN 视为未知。
380
409
  */
381
410
  function tierAt(timeMs) {
382
411
  if (timeMs === null || timeMs === void 0 || !Number.isFinite(timeMs)) return "peak";
412
+ if (isBeijingWeekend(timeMs)) return "offPeak";
383
413
  return isPeakHour((new Date(timeMs).getUTCHours() + 8) % 24) ? "peak" : "offPeak";
384
414
  }
415
+ /** 时刻是否落在北京时间周末(周六/周日)。 */
416
+ function isBeijingWeekend(timeMs) {
417
+ const day = new Date(timeMs + 8 * 36e5).getUTCDay();
418
+ return day === 0 || day === 6;
419
+ }
420
+ /** 距下一个工作日(周一)北京时间 09:00 峰时的毫秒数:周末全天低谷的下一档。 */
421
+ function nextWeekdayPeakInMs(nowMs) {
422
+ const bj = new Date(nowMs + 8 * 36e5);
423
+ const day = bj.getUTCDay();
424
+ const elapsed = bj.getUTCHours() * 36e5 + bj.getUTCMinutes() * 6e4 + bj.getUTCSeconds() * 1e3 + bj.getUTCMilliseconds();
425
+ return (day === 0 ? 1 : 2) * 864e5 - elapsed + 9 * 36e5;
426
+ }
385
427
  /** 峰谷切换边界(北京时间的当日分钟数):09:00 / 12:00 / 14:00 / 18:00。 */
386
428
  const TIER_BOUNDARY_MINUTES = [
387
429
  540,
@@ -399,6 +441,10 @@ window.__ModuleLoader__.load({
399
441
  * @returns 当前档位与到下一个切换边界的毫秒数。
400
442
  */
401
443
  function tierCountdown(nowMs) {
444
+ if (isBeijingWeekend(nowMs)) return {
445
+ tier: "offPeak",
446
+ nextSwitchInMs: nextWeekdayPeakInMs(nowMs)
447
+ };
402
448
  const dayMs = beijingMillisOfDay(nowMs);
403
449
  for (const boundary of TIER_BOUNDARY_MINUTES) {
404
450
  const boundaryMs = boundary * 6e4;
@@ -963,9 +1009,55 @@ window.__ModuleLoader__.load({
963
1009
  "k3": "kimi-k3",
964
1010
  "kimi-k3": "kimi-k3"
965
1011
  };
1012
+ /**
1013
+ * 模型 id 归一化:小写、去括号附注(如 `gpt5.6 luna(go)` 只看主体)、再去所有
1014
+ * 非字母数字分隔符(空格 / 横杠 / 点 / 下划线)。用于日志里的模型 id 与计费
1015
+ * 目录键做宽松匹配,提升「大小写/分隔符差异导致未收录」的识别率。
1016
+ * @param id - 原始模型 id(日志或目录键)。
1017
+ * @returns 归一化键(字母数字小写串)。
1018
+ */
1019
+ function canonModelId(id) {
1020
+ return String(id).toLowerCase().replace(/\([^)]*\)/g, "").replace(/[^a-z0-9]+/g, "");
1021
+ }
1022
+ /**
1023
+ * 目录常量键的归一化索引:归一化键 → 真实计费键。只索引静态来源(内置目录、
1024
+ * 别名表、dsh-spend 兜底键);models.dev 补充条目是运行时注入,单独实时匹配。
1025
+ */
1026
+ const CATALOG_CANON_INDEX = (() => {
1027
+ const map = /* @__PURE__ */ new Map();
1028
+ const add = (candidate, target) => {
1029
+ const canon = canonModelId(candidate);
1030
+ if (canon !== "" && !map.has(canon)) map.set(canon, target);
1031
+ };
1032
+ for (const entry of MODEL_CATALOG) add(entry.key, entry.key);
1033
+ for (const [alias, key] of Object.entries(MODEL_KEY_ALIASES)) add(alias, key);
1034
+ for (const rate of FALLBACK_RATES) add(rate.key, rate.key);
1035
+ return map;
1036
+ })();
1037
+ /**
1038
+ * 解析真实日志模型 id → 计费目录键。先精确别名映射(既有行为);未命中时做
1039
+ * 归一化匹配(忽略大小写/分隔符/括号附注),命中内置目录 / 别名目标 / 兜底键 /
1040
+ * models.dev 补充键即返回其真实键;完全未知时保持原样(回退 other,不计费)。
1041
+ * 供聚合层折叠与客户端渲染共用,两侧一致。
1042
+ * @param id - 真实模型 id(日志里出现的形式)。
1043
+ * @returns 计费目录键。
1044
+ */
1045
+ function resolveCatalogKey(id) {
1046
+ const exact = MODEL_KEY_ALIASES[id] ?? id;
1047
+ if (exact === id) {
1048
+ const canon = canonModelId(id);
1049
+ if (canon !== "") {
1050
+ const hit = CATALOG_CANON_INDEX.get(canon);
1051
+ if (hit !== void 0) return hit;
1052
+ const extraHit = (liveExtraModels ?? []).find((item) => canonModelId(item.key) === canon);
1053
+ if (extraHit !== void 0) return extraHit.key;
1054
+ }
1055
+ }
1056
+ return exact;
1057
+ }
966
1058
  /** 取一个计费键的实时单价(实时覆盖 > dsh-spend 官方价兜底)。 */
967
1059
  function livePriceOf(key) {
968
- const resolved = MODEL_KEY_ALIASES[key] ?? key;
1060
+ const resolved = resolveCatalogKey(key);
969
1061
  const live = livePrices?.[resolved];
970
1062
  if (live !== void 0) return live;
971
1063
  const fallback = FALLBACK_RATES.find((rate) => rate.key.toLowerCase() === resolved.toLowerCase());
@@ -978,7 +1070,7 @@ window.__ModuleLoader__.load({
978
1070
  }
979
1071
  /** Lookup a model by its stats key; falls back to the generic `other` entry. */
980
1072
  function modelOf(key) {
981
- const resolved = MODEL_KEY_ALIASES[key] ?? key;
1073
+ const resolved = resolveCatalogKey(key);
982
1074
  const found = MODEL_CATALOG.find((entry) => entry.key === resolved);
983
1075
  const extra = liveExtraModels?.find((item) => item.key === resolved);
984
1076
  const base = found ?? (extra !== void 0 ? extraEntryOf(extra) : (() => {
@@ -1024,7 +1116,7 @@ window.__ModuleLoader__.load({
1024
1116
  for (const model of liveCatalogModels ?? []) {
1025
1117
  const rawKey = model.id.toLowerCase();
1026
1118
  if ((() => {
1027
- const aliasKey = MODEL_KEY_ALIASES[model.id] ?? model.id;
1119
+ const aliasKey = resolveCatalogKey(model.id);
1028
1120
  return MODEL_CATALOG.find((item) => item.key === aliasKey);
1029
1121
  })() !== void 0) continue;
1030
1122
  if (known.has(rawKey)) continue;
@@ -1045,7 +1137,7 @@ window.__ModuleLoader__.load({
1045
1137
  }
1046
1138
  };
1047
1139
  else entry = {
1048
- key: MODEL_KEY_ALIASES[model.id] ?? model.id,
1140
+ key: resolveCatalogKey(model.id),
1049
1141
  name: model.name ?? model.id,
1050
1142
  provider: model.provider,
1051
1143
  colorVar: "dsw-static-neutral-400",
@@ -1467,10 +1559,12 @@ window.__ModuleLoader__.load({
1467
1559
  children: visible.map((round) => {
1468
1560
  const flagged = flagKey.has(`${round.sessionId}:${round.turn}`);
1469
1561
  const height = Math.max(1, round.cost / maxCost * 100);
1562
+ const peak = tierAt(round.startedAt) === "peak";
1470
1563
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1471
- className: UsageBilling_module_css_default.roundsBarCol,
1564
+ className: clsx(UsageBilling_module_css_default.roundsBarCol, peak ? UsageBilling_module_css_default.roundsBarColPeak : UsageBilling_module_css_default.roundsBarColOff),
1472
1565
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1473
1566
  className: UsageBilling_module_css_default.roundsBarLabel,
1567
+ style: { bottom: `${height}%` },
1474
1568
  children: money(round.cost)
1475
1569
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1476
1570
  className: UsageBilling_module_css_default.roundsBarWrap,
@@ -1843,6 +1937,7 @@ window.__ModuleLoader__.load({
1843
1937
  "billing.todayRate": "今日汇率",
1844
1938
  "billing.rateLive": "实时",
1845
1939
  "billing.rateBuiltin": "内置",
1940
+ "billing.pricingTip": "DeepSeek 模型自北京时间 2026-08-23(周日)00:00 起:工作日高峰 9-12 / 14-18(×2),周末(周六 / 周日)全天低谷价;双价单元格按峰 / 谷展示,费用按调用时刻计。",
1846
1941
  "billing.balance": "余额",
1847
1942
  "billing.balanceUnconfigured": "未配置",
1848
1943
  "billing.balanceUnauthorized": "密钥无效",
@@ -1885,6 +1980,13 @@ window.__ModuleLoader__.load({
1885
1980
  "billing.tabProviders": "明细",
1886
1981
  "billing.tabDetails": "统计",
1887
1982
  "billing.tabPricing": "费率",
1983
+ "billing.tabSettings": "设置",
1984
+ "billing.settingsHead": "偏好设置",
1985
+ "billing.settingsHint": "管理与计费相关的偏好",
1986
+ "billing.budgetHint": "设置月度上限,用于本月预计与超支分段提醒",
1987
+ "billing.peakAlertHint": "在切档前弹窗提醒,可选同步系统通知",
1988
+ "billing.peakAlertDescPeak": "高峰价生效,不急的调用可稍候",
1989
+ "billing.peakAlertDescOff": "价格减半省钱窗口已开启",
1888
1990
  "billing.export": "导出",
1889
1991
  "billing.exportCsvDay": "按日 CSV",
1890
1992
  "billing.exportCsvSession": "按会话 CSV",
@@ -1903,6 +2005,17 @@ window.__ModuleLoader__.load({
1903
2005
  "billing.tierToOff": "后转平价",
1904
2006
  "billing.tierAlertEnterPeak": "{minutes} 分钟后进入峰时(DeepSeek 高峰价 ×2),不急的调用可稍等",
1905
2007
  "billing.tierAlertEnterOff": "{minutes} 分钟后进入平价(价格减半)",
2008
+ "billing.peakAlertTitlePeak": "即将进入高峰价",
2009
+ "billing.peakAlertTitleOff": "即将进入平价",
2010
+ "billing.peakAlert": "峰谷切换提醒",
2011
+ "billing.peakAlertLeadMin": "提前量(分钟)",
2012
+ "billing.peakAlertPosCorner": "右下角",
2013
+ "billing.peakAlertPosCenter": "屏幕居中",
2014
+ "billing.peakAlertModePeak": "仅进入峰时",
2015
+ "billing.peakAlertModeOff": "仅进入平价",
2016
+ "billing.peakAlertModeBoth": "峰与谷都提醒",
2017
+ "billing.peakAlertWebNotify": "同时发系统通知",
2018
+ "billing.peakAlertPreview": "预览提醒",
1906
2019
  "billing.planTypeCode": "订阅制",
1907
2020
  "billing.planTypeToken": "按量",
1908
2021
  "billing.subscriptionFeePerMonth": "{amount}/月",
@@ -1965,6 +2078,7 @@ window.__ModuleLoader__.load({
1965
2078
  "billing.todayRate": "Today rate",
1966
2079
  "billing.rateLive": "Live",
1967
2080
  "billing.rateBuiltin": "Built-in",
2081
+ "billing.pricingTip": "DeepSeek models: from 2026-08-23 (Sun) 00:00 Beijing, weekdays peak 9-12 / 14-18 (×2), weekends (Sat/Sun) all-day off-peak; cells show peak/off-peak price, billed at call time.",
1968
2082
  "billing.balance": "Balance",
1969
2083
  "billing.balanceUnconfigured": "Not set",
1970
2084
  "billing.balanceUnauthorized": "Bad key",
@@ -2007,6 +2121,13 @@ window.__ModuleLoader__.load({
2007
2121
  "billing.tabProviders": "Details",
2008
2122
  "billing.tabDetails": "Stats",
2009
2123
  "billing.tabPricing": "Rates",
2124
+ "billing.tabSettings": "Settings",
2125
+ "billing.settingsHead": "Preferences",
2126
+ "billing.settingsHint": "Manage billing-related preferences",
2127
+ "billing.budgetHint": "Set a monthly cap for projections and tier alerts",
2128
+ "billing.peakAlertHint": "Alert before a tier switch, optionally via system notification",
2129
+ "billing.peakAlertDescPeak": "Peak pricing active — non-urgent calls can wait",
2130
+ "billing.peakAlertDescOff": "Off-peak savings window is on",
2010
2131
  "billing.export": "Export",
2011
2132
  "billing.exportCsvDay": "Daily CSV",
2012
2133
  "billing.exportCsvSession": "Sessions CSV",
@@ -2025,6 +2146,17 @@ window.__ModuleLoader__.load({
2025
2146
  "billing.tierToOff": "until off-peak",
2026
2147
  "billing.tierAlertEnterPeak": "Peak pricing (2x) starts in {minutes} min — non-urgent calls can wait",
2027
2148
  "billing.tierAlertEnterOff": "Off-peak pricing (50% off) starts in {minutes} min",
2149
+ "billing.peakAlertTitlePeak": "Peak pricing incoming",
2150
+ "billing.peakAlertTitleOff": "Off-peak incoming",
2151
+ "billing.peakAlert": "Peak/off-peak alert",
2152
+ "billing.peakAlertLeadMin": "Lead time (min)",
2153
+ "billing.peakAlertPosCorner": "Bottom-right",
2154
+ "billing.peakAlertPosCenter": "Center",
2155
+ "billing.peakAlertModePeak": "Entering peak only",
2156
+ "billing.peakAlertModeOff": "Entering off-peak only",
2157
+ "billing.peakAlertModeBoth": "Both",
2158
+ "billing.peakAlertWebNotify": "Also send system notification",
2159
+ "billing.peakAlertPreview": "Preview alert",
2028
2160
  "billing.planTypeCode": "Subscription",
2029
2161
  "billing.planTypeToken": "Usage",
2030
2162
  "billing.subscriptionFeePerMonth": "{amount}/mo",
@@ -2073,6 +2205,115 @@ window.__ModuleLoader__.load({
2073
2205
  return name;
2074
2206
  }
2075
2207
  //#endregion
2208
+ //#region src/client/peak-alert.ts
2209
+ /**
2210
+ * 峰谷切换提醒(增强版)纯逻辑:偏好持久化 + 切档前命中判定。
2211
+ *
2212
+ * 参照 dsh-cost-meter 的 peak/off-peak 提醒:在距下次「进入峰时 / 进入平价」
2213
+ * 不足提前量时,弹可视化色条浮层 + 可选的系统通知。偏好经 localStorage 持久化
2214
+ * (默认关闭,用户到面板设置开启);「同一切换点只提醒一次」由 budget store 的
2215
+ * `lastTierSwitchAt` 承担(与原系统通知共用一份去重,避免一条切换提醒弹两次)。
2216
+ */
2217
+ /** 配置持久化 key。 */
2218
+ const PEAK_ALERT_KEY = "dsh-billing-peak-alert-v1";
2219
+ /** 默认配置:关、2 分钟提前、右下角、开系统通知、峰与谷都提醒。 */
2220
+ const DEFAULT_PEAK_ALERT_CONFIG = {
2221
+ enabled: false,
2222
+ leadMin: 2,
2223
+ position: "bottom-right",
2224
+ webNotify: true,
2225
+ mode: "both"
2226
+ };
2227
+ /** 读取本地偏好(缺失/损坏回退默认,字段宽松校验)。 */
2228
+ function loadPeakAlertConfig() {
2229
+ try {
2230
+ const raw = localStorage.getItem(PEAK_ALERT_KEY);
2231
+ if (raw === null) return { ...DEFAULT_PEAK_ALERT_CONFIG };
2232
+ const parsed = JSON.parse(raw);
2233
+ const mode = parsed.mode === "peak" || parsed.mode === "offPeak" ? parsed.mode : DEFAULT_PEAK_ALERT_CONFIG.mode;
2234
+ const position = parsed.position === "center" ? "center" : "bottom-right";
2235
+ return {
2236
+ enabled: parsed.enabled === true,
2237
+ leadMin: typeof parsed.leadMin === "number" && Number.isFinite(parsed.leadMin) ? Math.min(30, Math.max(1, Math.round(parsed.leadMin))) : DEFAULT_PEAK_ALERT_CONFIG.leadMin,
2238
+ position,
2239
+ webNotify: parsed.webNotify !== false,
2240
+ mode
2241
+ };
2242
+ } catch {
2243
+ return { ...DEFAULT_PEAK_ALERT_CONFIG };
2244
+ }
2245
+ }
2246
+ /** 保存偏好;存储失败静默(降级为关闭,不影响其它能力)。 */
2247
+ function savePeakAlertConfig(config) {
2248
+ try {
2249
+ localStorage.setItem(PEAK_ALERT_KEY, JSON.stringify(config));
2250
+ } catch {}
2251
+ }
2252
+ /**
2253
+ * 计算是否需要提醒:已启用、距切换不足提前量、按模式过滤、且该切换点未提醒过。
2254
+ * 导出供测试:纯函数。
2255
+ * @param nowMs - 当前时刻(epoch 毫秒)。
2256
+ * @param config - 峰谷提醒偏好。
2257
+ * @param lastAlertedAt - 上次提醒过的切换点时刻(budget store 的 lastTierSwitchAt);同点跳过。
2258
+ * @returns 命中(含即将进入的档位与切换时刻),否则 null。
2259
+ */
2260
+ function computePeakAlert(nowMs, config, lastAlertedAt) {
2261
+ if (!config.enabled) return null;
2262
+ const upcoming = upcomingTierSwitch(nowMs, config.leadMin * 6e4);
2263
+ if (upcoming === null) return null;
2264
+ if (config.mode === "peak" && upcoming.entering !== "peak") return null;
2265
+ if (config.mode === "offPeak" && upcoming.entering !== "offPeak") return null;
2266
+ if (upcoming.atMs === lastAlertedAt) return null;
2267
+ return upcoming;
2268
+ }
2269
+ //#endregion
2270
+ //#region src/client/PeakAlertBanner.tsx
2271
+ /**
2272
+ * 峰谷切换提醒浮层:切档前状态条(右下角或居中)。用 `position: fixed` 即可在
2273
+ * 任意宿主容器内覆盖整个视口,因此不需要 portal。布局为「档位徽标 + 大号等宽
2274
+ * 倒计时 + 一句说明 + 关闭」,克制冷调、无重力阴影。渲染是受控的:父组件把命中
2275
+ * (hit)与偏好传入,显示剩余分钟并在切换后消失。
2276
+ */
2277
+ /** 渲染一个切档前提醒状态条。 */
2278
+ function PeakAlertBanner({ hit, config, t, onDismiss }) {
2279
+ const [nowMs, setNowMs] = (0, react.useState)(() => Date.now());
2280
+ (0, react.useEffect)(() => {
2281
+ const timer = setInterval(() => setNowMs(Date.now()), 1e3);
2282
+ return () => clearInterval(timer);
2283
+ }, []);
2284
+ if (nowMs >= hit.atMs) return null;
2285
+ const minutes = Math.max(1, Math.round((hit.atMs - nowMs) / 6e4));
2286
+ const entering = hit.entering;
2287
+ const tag = entering === "peak" ? t("billing.tierPeak") : t("billing.tierOff");
2288
+ const desc = entering === "peak" ? t("billing.peakAlertDescPeak") : t("billing.peakAlertDescOff");
2289
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2290
+ className: clsx(UsageBilling_module_css_default.peakAlert, entering === "peak" ? UsageBilling_module_css_default.peakAlertPeak : UsageBilling_module_css_default.peakAlertOff, config.position === "center" ? UsageBilling_module_css_default.peakAlertCenter : UsageBilling_module_css_default.peakAlertCorner),
2291
+ "data-testid": "billing-peak-alert",
2292
+ role: "alert",
2293
+ children: [
2294
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2295
+ className: UsageBilling_module_css_default.peakAlertTag,
2296
+ children: tag
2297
+ }),
2298
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
2299
+ className: UsageBilling_module_css_default.peakAlertCountdown,
2300
+ children: [minutes, "m"]
2301
+ }),
2302
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2303
+ className: UsageBilling_module_css_default.peakAlertText,
2304
+ children: desc
2305
+ }),
2306
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2307
+ type: "button",
2308
+ className: UsageBilling_module_css_default.peakAlertClose,
2309
+ onClick: onDismiss,
2310
+ "aria-label": t("billing.close"),
2311
+ children: "×"
2312
+ })
2313
+ ]
2314
+ });
2315
+ }
2316
+ //#endregion
2076
2317
  //#region src/client/UsageBilling.tsx
2077
2318
  /**
2078
2319
  * UsageBilling: sidebar footer trigger + full billing dashboard modal.
@@ -2088,9 +2329,9 @@ window.__ModuleLoader__.load({
2088
2329
  /** 会话明细面板最多展示的行数(完整长尾在服务端另有一层封顶)。 */
2089
2330
  const SESSION_DISPLAY_LIMIT = 20;
2090
2331
  /**
2091
- * Tab 定义(顺序即渲染顺序):概览=主数字/预算/KPI/热力图,趋势=趋势图/每轮费用,
2092
- * 明细=厂商计费与订阅,统计=工作区/会话明细,费率=模型单价表。导出供测试断言
2093
- * tab 与文案 key 对齐、decor 锚点落在正确分区。
2332
+ * Tab 定义(顺序即渲染顺序):概览=主数字/KPI/热力图,趋势=趋势图/每轮费用,
2333
+ * 明细=厂商计费与订阅,统计=工作区/会话明细,费率=模型单价表,设置=预算与峰谷提醒。
2334
+ * 导出供测试断言 tab 与文案 key 对齐、decor 锚点落在正确分区。
2094
2335
  */
2095
2336
  const DASHBOARD_TABS = [
2096
2337
  {
@@ -2112,6 +2353,10 @@ window.__ModuleLoader__.load({
2112
2353
  {
2113
2354
  id: "pricing",
2114
2355
  labelKey: "billing.tabPricing"
2356
+ },
2357
+ {
2358
+ id: "settings",
2359
+ labelKey: "billing.tabSettings"
2115
2360
  }
2116
2361
  ];
2117
2362
  /** 项目名取 cwd 的末级目录;无 cwd 时由调用方回退为 em dash。 */
@@ -2609,7 +2854,7 @@ window.__ModuleLoader__.load({
2609
2854
  }),
2610
2855
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2611
2856
  className: UsageBilling_module_css_default.triggerPopBars,
2612
- children: sparkHeights.map((h, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2857
+ children: sparkHeights.map((_h, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2613
2858
  className: UsageBilling_module_css_default.triggerPopBar,
2614
2859
  style: { height: `${sparkMax > 0 ? 4 + days[index].cost / sparkMax * 18 : 4}px` }
2615
2860
  }, days[index]?.date ?? String(index)))
@@ -2622,7 +2867,7 @@ window.__ModuleLoader__.load({
2622
2867
  * The centered billing dashboard modal.
2623
2868
  * @param props - stats, locale function, close handler, model health, balances, renderSlot.
2624
2869
  */
2625
- function BillingDashboard({ stats, t, onClose, health, balances, quotas, currency, onCurrency, turns, renderSlot, budgetEnabled, budgetAmount, onToggleBudget, onBudgetAmount }) {
2870
+ function BillingDashboard({ stats, t, onClose, health, balances, quotas, currency, onCurrency, turns, renderSlot, budgetEnabled, budgetAmount, onToggleBudget, onBudgetAmount, peakConfig, onPeakConfig, onPreviewPeak }) {
2626
2871
  const { total, byModel, byDay } = stats;
2627
2872
  const [tab, setTab] = (0, react.useState)("overview");
2628
2873
  const [trendDays, setTrendDays] = (0, react.useState)(7);
@@ -2785,7 +3030,6 @@ window.__ModuleLoader__.load({
2785
3030
  let thirdCalls = 0;
2786
3031
  for (const row of modelRows) {
2787
3032
  const official = row.officialCost;
2788
- row.actual;
2789
3033
  if (official > 0) officialCost += official;
2790
3034
  officialCalls += row.officialCalls;
2791
3035
  thirdCalls += Math.max(0, row.calls - row.officialCalls);
@@ -3068,78 +3312,6 @@ window.__ModuleLoader__.load({
3068
3312
  })
3069
3313
  ]
3070
3314
  }),
3071
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
3072
- className: UsageBilling_module_css_default.budget,
3073
- "data-testid": "billing-budget",
3074
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
3075
- className: UsageBilling_module_css_default.budgetHead,
3076
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
3077
- className: UsageBilling_module_css_default.budgetLabel,
3078
- children: t("billing.budget")
3079
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
3080
- className: UsageBilling_module_css_default.budgetControls,
3081
- children: [
3082
- budgetEnabled && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
3083
- className: UsageBilling_module_css_default.budgetInputWrap,
3084
- "data-testid": "billing-budget-input-wrap",
3085
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
3086
- className: UsageBilling_module_css_default.budgetUnit,
3087
- "aria-hidden": "true",
3088
- children: "¥"
3089
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
3090
- className: UsageBilling_module_css_default.budgetInput,
3091
- "data-testid": "billing-budget-input",
3092
- type: "number",
3093
- min: 0,
3094
- step: 1,
3095
- value: budgetAmount === 0 ? "" : budgetAmount,
3096
- placeholder: stats.budget !== void 0 ? String(stats.budget) : "0",
3097
- "aria-label": `${t("billing.budget")}(${currency === "usd" ? "USD" : "CNY"})`,
3098
- title: `${t("billing.budget")}(${currency === "usd" ? "USD" : "CNY"})`,
3099
- onChange: (e) => {
3100
- onBudgetAmount(e.target.valueAsNumber);
3101
- }
3102
- })]
3103
- }),
3104
- budgetEnabled && budgetAmount > 0 && (() => {
3105
- const pct = monthCost / budgetAmount * 100;
3106
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
3107
- className: UsageBilling_module_css_default.budgetValue,
3108
- "data-testid": "billing-budget-value",
3109
- children: [
3110
- money(monthCost),
3111
- " / ",
3112
- money(budgetAmount),
3113
- " · ",
3114
- pct.toFixed(1),
3115
- "%"
3116
- ]
3117
- });
3118
- })(),
3119
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
3120
- type: "button",
3121
- role: "switch",
3122
- "aria-checked": budgetEnabled,
3123
- "aria-label": t("billing.budget"),
3124
- "data-testid": "billing-budget-toggle",
3125
- className: clsx(UsageBilling_module_css_default.switch, budgetEnabled && UsageBilling_module_css_default.switchOn),
3126
- onClick: onToggleBudget,
3127
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: UsageBilling_module_css_default.switchKnob })
3128
- })
3129
- ]
3130
- })]
3131
- }), budgetEnabled && budgetAmount > 0 && (() => {
3132
- const pct = monthCost / budgetAmount * 100;
3133
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3134
- className: UsageBilling_module_css_default.budgetTrack,
3135
- "data-testid": "billing-budget-track",
3136
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3137
- className: clsx(UsageBilling_module_css_default.budgetFill, pct >= 100 && UsageBilling_module_css_default.budgetFillOver, pct >= 80 && pct < 100 && UsageBilling_module_css_default.budgetFillWarn),
3138
- style: { width: `${Math.min(pct, 100)}%` }
3139
- })
3140
- });
3141
- })()]
3142
- }),
3143
3315
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
3144
3316
  className: UsageBilling_module_css_default.kpiGrid,
3145
3317
  "data-testid": "billing-kpi-grid",
@@ -3252,6 +3424,223 @@ window.__ModuleLoader__.load({
3252
3424
  })
3253
3425
  ]
3254
3426
  }),
3427
+ tab === "settings" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
3428
+ className: UsageBilling_module_css_default.tabPanel,
3429
+ "data-testid": "billing-tab-panel-settings",
3430
+ children: [
3431
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
3432
+ className: UsageBilling_module_css_default.settingsHead,
3433
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
3434
+ className: UsageBilling_module_css_default.settingsTitle,
3435
+ children: t("billing.settingsHead")
3436
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
3437
+ className: UsageBilling_module_css_default.settingsHint,
3438
+ children: t("billing.settingsHint")
3439
+ })]
3440
+ }),
3441
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
3442
+ className: UsageBilling_module_css_default.budget,
3443
+ "data-testid": "billing-budget",
3444
+ children: [
3445
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
3446
+ className: UsageBilling_module_css_default.budgetHead,
3447
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
3448
+ className: UsageBilling_module_css_default.budgetLabel,
3449
+ children: t("billing.budget")
3450
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
3451
+ className: UsageBilling_module_css_default.budgetControls,
3452
+ children: [
3453
+ budgetEnabled && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
3454
+ className: UsageBilling_module_css_default.budgetInputWrap,
3455
+ "data-testid": "billing-budget-input-wrap",
3456
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
3457
+ className: UsageBilling_module_css_default.budgetUnit,
3458
+ "aria-hidden": "true",
3459
+ children: "¥"
3460
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
3461
+ className: UsageBilling_module_css_default.budgetInput,
3462
+ "data-testid": "billing-budget-input",
3463
+ type: "number",
3464
+ min: 0,
3465
+ step: 1,
3466
+ value: budgetAmount === 0 ? "" : budgetAmount,
3467
+ placeholder: stats.budget !== void 0 ? String(stats.budget) : "0",
3468
+ "aria-label": `${t("billing.budget")}(${currency === "usd" ? "USD" : "CNY"})`,
3469
+ title: `${t("billing.budget")}(${currency === "usd" ? "USD" : "CNY"})`,
3470
+ onChange: (e) => {
3471
+ onBudgetAmount(e.target.valueAsNumber);
3472
+ }
3473
+ })]
3474
+ }),
3475
+ budgetEnabled && budgetAmount > 0 && (() => {
3476
+ const pct = monthCost / budgetAmount * 100;
3477
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
3478
+ className: UsageBilling_module_css_default.budgetValue,
3479
+ "data-testid": "billing-budget-value",
3480
+ children: [
3481
+ money(monthCost),
3482
+ " / ",
3483
+ money(budgetAmount),
3484
+ " · ",
3485
+ pct.toFixed(1),
3486
+ "%"
3487
+ ]
3488
+ });
3489
+ })(),
3490
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
3491
+ type: "button",
3492
+ role: "switch",
3493
+ "aria-checked": budgetEnabled,
3494
+ "aria-label": t("billing.budget"),
3495
+ "data-testid": "billing-budget-toggle",
3496
+ className: clsx(UsageBilling_module_css_default.switch, budgetEnabled && UsageBilling_module_css_default.switchOn),
3497
+ onClick: onToggleBudget,
3498
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: UsageBilling_module_css_default.switchKnob })
3499
+ })
3500
+ ]
3501
+ })]
3502
+ }),
3503
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
3504
+ className: UsageBilling_module_css_default.budgetHint,
3505
+ children: t("billing.budgetHint")
3506
+ }),
3507
+ budgetEnabled && budgetAmount > 0 && (() => {
3508
+ const pct = monthCost / budgetAmount * 100;
3509
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3510
+ className: UsageBilling_module_css_default.budgetTrack,
3511
+ "data-testid": "billing-budget-track",
3512
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3513
+ className: clsx(UsageBilling_module_css_default.budgetFill, pct >= 100 && UsageBilling_module_css_default.budgetFillOver, pct >= 80 && pct < 100 && UsageBilling_module_css_default.budgetFillWarn),
3514
+ style: { width: `${Math.min(pct, 100)}%` }
3515
+ })
3516
+ });
3517
+ })()
3518
+ ]
3519
+ }),
3520
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
3521
+ className: UsageBilling_module_css_default.peakAlertPanel,
3522
+ "data-testid": "billing-peak-alert-settings",
3523
+ children: [
3524
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
3525
+ className: UsageBilling_module_css_default.peakAlertPanelHead,
3526
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
3527
+ className: UsageBilling_module_css_default.peakAlertPanelLabel,
3528
+ children: t("billing.peakAlert")
3529
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
3530
+ type: "button",
3531
+ role: "switch",
3532
+ "aria-checked": peakConfig.enabled,
3533
+ "aria-label": t("billing.peakAlert"),
3534
+ "data-testid": "billing-peak-alert-toggle",
3535
+ className: clsx(UsageBilling_module_css_default.switch, peakConfig.enabled && UsageBilling_module_css_default.switchOn),
3536
+ onClick: () => {
3537
+ onPeakConfig({
3538
+ ...peakConfig,
3539
+ enabled: !peakConfig.enabled
3540
+ });
3541
+ },
3542
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: UsageBilling_module_css_default.switchKnob })
3543
+ })]
3544
+ }),
3545
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
3546
+ className: UsageBilling_module_css_default.peakAlertHint,
3547
+ children: t("billing.peakAlertHint")
3548
+ }),
3549
+ peakConfig.enabled && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
3550
+ className: UsageBilling_module_css_default.peakAlertPanelBody,
3551
+ children: [
3552
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
3553
+ className: UsageBilling_module_css_default.peakAlertField,
3554
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("billing.peakAlertLeadMin") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
3555
+ type: "number",
3556
+ min: 1,
3557
+ max: 30,
3558
+ step: 1,
3559
+ value: peakConfig.leadMin,
3560
+ className: UsageBilling_module_css_default.peakAlertNum,
3561
+ "aria-label": t("billing.peakAlertLeadMin"),
3562
+ onChange: (e) => {
3563
+ const v = Number(e.target.valueAsNumber);
3564
+ onPeakConfig({
3565
+ ...peakConfig,
3566
+ leadMin: Number.isFinite(v) ? Math.min(30, Math.max(1, Math.round(v))) : peakConfig.leadMin
3567
+ });
3568
+ }
3569
+ })]
3570
+ }),
3571
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
3572
+ className: UsageBilling_module_css_default.peakAlertField,
3573
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("billing.peakAlertPosCorner") }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
3574
+ value: peakConfig.position,
3575
+ className: UsageBilling_module_css_default.peakAlertSelect,
3576
+ onChange: (e) => {
3577
+ onPeakConfig({
3578
+ ...peakConfig,
3579
+ position: e.target.value === "center" ? "center" : "bottom-right"
3580
+ });
3581
+ },
3582
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
3583
+ value: "bottom-right",
3584
+ children: t("billing.peakAlertPosCorner")
3585
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
3586
+ value: "center",
3587
+ children: t("billing.peakAlertPosCenter")
3588
+ })]
3589
+ })]
3590
+ }),
3591
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
3592
+ className: UsageBilling_module_css_default.peakAlertField,
3593
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("billing.peakAlert") }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
3594
+ value: peakConfig.mode,
3595
+ className: UsageBilling_module_css_default.peakAlertSelect,
3596
+ onChange: (e) => {
3597
+ const m = e.target.value;
3598
+ onPeakConfig({
3599
+ ...peakConfig,
3600
+ mode: m === "peak" || m === "offPeak" ? m : "both"
3601
+ });
3602
+ },
3603
+ children: [
3604
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
3605
+ value: "both",
3606
+ children: t("billing.peakAlertModeBoth")
3607
+ }),
3608
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
3609
+ value: "peak",
3610
+ children: t("billing.peakAlertModePeak")
3611
+ }),
3612
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
3613
+ value: "offPeak",
3614
+ children: t("billing.peakAlertModeOff")
3615
+ })
3616
+ ]
3617
+ })]
3618
+ }),
3619
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
3620
+ className: UsageBilling_module_css_default.peakAlertCheck,
3621
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
3622
+ type: "checkbox",
3623
+ checked: peakConfig.webNotify,
3624
+ onChange: (e) => {
3625
+ onPeakConfig({
3626
+ ...peakConfig,
3627
+ webNotify: e.target.checked
3628
+ });
3629
+ }
3630
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("billing.peakAlertWebNotify") })]
3631
+ }),
3632
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
3633
+ type: "button",
3634
+ className: UsageBilling_module_css_default.peakAlertPreview,
3635
+ onClick: onPreviewPeak,
3636
+ children: t("billing.peakAlertPreview")
3637
+ })
3638
+ ]
3639
+ })
3640
+ ]
3641
+ })
3642
+ ]
3643
+ }),
3255
3644
  tab === "trends" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
3256
3645
  className: UsageBilling_module_css_default.tabPanel,
3257
3646
  "data-testid": "billing-tab-panel-trends",
@@ -3905,119 +4294,126 @@ window.__ModuleLoader__.load({
3905
4294
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
3906
4295
  className: UsageBilling_module_css_default.panel,
3907
4296
  "data-testid": "billing-panel-pricing",
3908
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
3909
- className: UsageBilling_module_css_default.panelHead,
3910
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
3911
- className: UsageBilling_module_css_default.panelTitle,
3912
- children: t("billing.pricing")
3913
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
3914
- className: UsageBilling_module_css_default.panelHint,
3915
- children: [
3916
- t("billing.todayRate"),
3917
- " 1 USD = ",
3918
- formatMoney(rateInfo.rate),
3919
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
3920
- className: clsx(UsageBilling_module_css_default.rateBadge, rateInfo.live ? UsageBilling_module_css_default.rateBadgeLive : UsageBilling_module_css_default.rateBadgeBuiltin),
3921
- children: rateInfo.live ? t("billing.rateLive") : t("billing.rateBuiltin")
3922
- })
3923
- ]
3924
- })]
3925
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3926
- className: UsageBilling_module_css_default.tableScroll,
3927
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("table", {
3928
- className: UsageBilling_module_css_default.pricingTable,
3929
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("thead", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("tr", { children: [
3930
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", { children: "Model" }),
3931
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", {
3932
- className: UsageBilling_module_css_default.numCol,
3933
- children: t("billing.input")
3934
- }),
3935
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", {
3936
- className: UsageBilling_module_css_default.numCol,
3937
- children: t("billing.cacheHit")
3938
- }),
3939
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", {
3940
- className: UsageBilling_module_css_default.numCol,
3941
- children: t("billing.output")
3942
- }),
3943
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", { children: t("billing.band") })
3944
- ] }) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("tbody", { children: catalogEntries().map((entry) => {
3945
- const hasPrice = entry.price.input > 0 || entry.price.output > 0;
3946
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("tr", { children: [
3947
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
3948
- className: UsageBilling_module_css_default.modelCell,
3949
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
3950
- className: UsageBilling_module_css_default.modelDot,
3951
- style: { background: resolveToken(entry.colorVar) }
3952
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
3953
- className: UsageBilling_module_css_default.modelName,
3954
- children: [entry.name, entry.uncatalogued && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
3955
- className: UsageBilling_module_css_default.uncataloguedTag,
3956
- "data-testid": "billing-price-uncatalogued",
3957
- children: t("billing.uncatalogued")
3958
- })]
3959
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
3960
- className: UsageBilling_module_css_default.modelProvider,
3961
- children: providerName(entry.provider)
3962
- })] })]
3963
- }) }),
3964
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", {
4297
+ children: [
4298
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4299
+ className: UsageBilling_module_css_default.panelHead,
4300
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
4301
+ className: UsageBilling_module_css_default.panelTitle,
4302
+ children: t("billing.pricing")
4303
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
4304
+ className: UsageBilling_module_css_default.panelHint,
4305
+ children: [
4306
+ t("billing.todayRate"),
4307
+ " 1 USD = ",
4308
+ formatMoney(rateInfo.rate),
4309
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4310
+ className: clsx(UsageBilling_module_css_default.rateBadge, rateInfo.live ? UsageBilling_module_css_default.rateBadgeLive : UsageBilling_module_css_default.rateBadgeBuiltin),
4311
+ children: rateInfo.live ? t("billing.rateLive") : t("billing.rateBuiltin")
4312
+ })
4313
+ ]
4314
+ })]
4315
+ }),
4316
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
4317
+ className: UsageBilling_module_css_default.pricingTip,
4318
+ children: t("billing.pricingTip")
4319
+ }),
4320
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
4321
+ className: UsageBilling_module_css_default.tableScroll,
4322
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("table", {
4323
+ className: UsageBilling_module_css_default.pricingTable,
4324
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("thead", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("tr", { children: [
4325
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", { children: "Model" }),
4326
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", {
3965
4327
  className: UsageBilling_module_css_default.numCol,
3966
- children: hasPrice ? entry.price.offPeak !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
3967
- className: UsageBilling_module_css_default.bandPrice,
3968
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: unitMoney(entry.price.input, entry.price.currency) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
3969
- className: UsageBilling_module_css_default.bandPriceOff,
3970
- children: unitMoney(entry.price.offPeak.input, entry.price.currency)
3971
- })]
3972
- }) : unitMoney(entry.price.input, entry.price.currency) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
3973
- className: UsageBilling_module_css_default.na,
3974
- children: "—"
3975
- })
4328
+ children: t("billing.input")
3976
4329
  }),
3977
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", {
4330
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", {
3978
4331
  className: UsageBilling_module_css_default.numCol,
3979
- children: hasPrice ? entry.price.offPeak !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
3980
- className: UsageBilling_module_css_default.bandPrice,
3981
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: unitMoney(entry.price.cacheHit, entry.price.currency) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
3982
- className: UsageBilling_module_css_default.bandPriceOff,
3983
- children: unitMoney(entry.price.offPeak.cacheHit, entry.price.currency)
3984
- })]
3985
- }) : unitMoney(entry.price.cacheHit, entry.price.currency) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
3986
- className: UsageBilling_module_css_default.na,
3987
- children: "—"
3988
- })
4332
+ children: t("billing.cacheHit")
3989
4333
  }),
3990
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", {
4334
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", {
3991
4335
  className: UsageBilling_module_css_default.numCol,
3992
- children: hasPrice ? entry.price.offPeak !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
3993
- className: UsageBilling_module_css_default.bandPrice,
3994
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: unitMoney(entry.price.output, entry.price.currency) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
3995
- className: UsageBilling_module_css_default.bandPriceOff,
3996
- children: unitMoney(entry.price.offPeak.output, entry.price.currency)
3997
- })]
3998
- }) : unitMoney(entry.price.output, entry.price.currency) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
3999
- className: UsageBilling_module_css_default.na,
4000
- children: "—"
4001
- })
4336
+ children: t("billing.output")
4002
4337
  }),
4003
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", { children: entry.price.offPeak !== void 0 && entry.peakHours !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
4004
- className: UsageBilling_module_css_default.bandTag,
4005
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [
4006
- t("billing.peak"),
4007
- " ",
4008
- entry.peakHours
4009
- ] }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
4010
- className: UsageBilling_module_css_default.bandTagOff,
4011
- children: [t("billing.offPeak"), " 50%"]
4012
- })]
4013
- }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4014
- className: UsageBilling_module_css_default.flatTag,
4015
- children: t("billing.flat")
4016
- }) })
4017
- ] }, entry.key);
4018
- }) })]
4338
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", { children: t("billing.band") })
4339
+ ] }) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("tbody", { children: catalogEntries().map((entry) => {
4340
+ const hasPrice = entry.price.input > 0 || entry.price.output > 0;
4341
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("tr", { children: [
4342
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
4343
+ className: UsageBilling_module_css_default.modelCell,
4344
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4345
+ className: UsageBilling_module_css_default.modelDot,
4346
+ style: { background: resolveToken(entry.colorVar) }
4347
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
4348
+ className: UsageBilling_module_css_default.modelName,
4349
+ children: [entry.name, entry.uncatalogued && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4350
+ className: UsageBilling_module_css_default.uncataloguedTag,
4351
+ "data-testid": "billing-price-uncatalogued",
4352
+ children: t("billing.uncatalogued")
4353
+ })]
4354
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4355
+ className: UsageBilling_module_css_default.modelProvider,
4356
+ children: providerName(entry.provider)
4357
+ })] })]
4358
+ }) }),
4359
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", {
4360
+ className: UsageBilling_module_css_default.numCol,
4361
+ children: hasPrice ? entry.price.offPeak !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
4362
+ className: UsageBilling_module_css_default.bandPrice,
4363
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: unitMoney(entry.price.input, entry.price.currency) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4364
+ className: UsageBilling_module_css_default.bandPriceOff,
4365
+ children: unitMoney(entry.price.offPeak.input, entry.price.currency)
4366
+ })]
4367
+ }) : unitMoney(entry.price.input, entry.price.currency) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4368
+ className: UsageBilling_module_css_default.na,
4369
+ children: "—"
4370
+ })
4371
+ }),
4372
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", {
4373
+ className: UsageBilling_module_css_default.numCol,
4374
+ children: hasPrice ? entry.price.offPeak !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
4375
+ className: UsageBilling_module_css_default.bandPrice,
4376
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: unitMoney(entry.price.cacheHit, entry.price.currency) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4377
+ className: UsageBilling_module_css_default.bandPriceOff,
4378
+ children: unitMoney(entry.price.offPeak.cacheHit, entry.price.currency)
4379
+ })]
4380
+ }) : unitMoney(entry.price.cacheHit, entry.price.currency) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4381
+ className: UsageBilling_module_css_default.na,
4382
+ children: "—"
4383
+ })
4384
+ }),
4385
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", {
4386
+ className: UsageBilling_module_css_default.numCol,
4387
+ children: hasPrice ? entry.price.offPeak !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
4388
+ className: UsageBilling_module_css_default.bandPrice,
4389
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: unitMoney(entry.price.output, entry.price.currency) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4390
+ className: UsageBilling_module_css_default.bandPriceOff,
4391
+ children: unitMoney(entry.price.offPeak.output, entry.price.currency)
4392
+ })]
4393
+ }) : unitMoney(entry.price.output, entry.price.currency) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4394
+ className: UsageBilling_module_css_default.na,
4395
+ children: "—"
4396
+ })
4397
+ }),
4398
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", { children: entry.price.offPeak !== void 0 && entry.peakHours !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
4399
+ className: UsageBilling_module_css_default.bandTag,
4400
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [
4401
+ t("billing.peak"),
4402
+ " ",
4403
+ entry.peakHours
4404
+ ] }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
4405
+ className: UsageBilling_module_css_default.bandTagOff,
4406
+ children: [t("billing.offPeak"), " 50%"]
4407
+ })]
4408
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4409
+ className: UsageBilling_module_css_default.flatTag,
4410
+ children: t("billing.flat")
4411
+ }) })
4412
+ ] }, entry.key);
4413
+ }) })]
4414
+ })
4019
4415
  })
4020
- })]
4416
+ ]
4021
4417
  })
4022
4418
  }),
4023
4419
  renderSlot("billing.dashboard.decor", { position: "footer" })
@@ -4099,6 +4495,19 @@ window.__ModuleLoader__.load({
4099
4495
  const budgetAmount = useStore((s) => s.amount);
4100
4496
  const tierAlertDays = useStore((s) => s.tierAlertDays);
4101
4497
  const lastTierSwitchAt = useStore((s) => s.lastTierSwitchAt);
4498
+ const [peakConfig, setPeakConfig] = (0, react.useState)(() => loadPeakAlertConfig());
4499
+ const [peakHit, setPeakHit] = (0, react.useState)(null);
4500
+ const [peakPreview, setPeakPreview] = (0, react.useState)(null);
4501
+ const updatePeakConfig = (0, react.useCallback)((config) => {
4502
+ setPeakConfig(config);
4503
+ savePeakAlertConfig(config);
4504
+ }, []);
4505
+ const previewPeak = (0, react.useCallback)(() => {
4506
+ setPeakPreview({
4507
+ entering: tierAt(Date.now()) === "peak" ? "offPeak" : "peak",
4508
+ atMs: Date.now() + 3 * 6e4
4509
+ });
4510
+ }, []);
4102
4511
  const effectiveBudget = budgetAmount > 0 ? budgetAmount : stats.budget ?? 0;
4103
4512
  const toggleBudget = (0, react.useCallback)(() => {
4104
4513
  const next = !budgetEnabled;
@@ -4127,20 +4536,21 @@ window.__ModuleLoader__.load({
4127
4536
  t
4128
4537
  ]);
4129
4538
  (0, react.useEffect)(() => {
4130
- const leadMs = 2 * 6e4;
4131
- const now = Date.now();
4132
- const upcoming = upcomingTierSwitch(now, leadMs);
4539
+ const upcoming = computePeakAlert(Date.now(), peakConfig, lastTierSwitchAt);
4133
4540
  if (upcoming === null) return;
4134
- if (upcoming.atMs === lastTierSwitchAt) return;
4135
4541
  actions.markTierSwitchAlerted(upcoming.atMs);
4542
+ setPeakHit(upcoming);
4543
+ if (!peakConfig.webNotify) return;
4136
4544
  if (typeof Notification === "undefined" || Notification.permission !== "granted") return;
4137
- const minutes = Math.max(1, Math.round((upcoming.atMs - now) / 6e4));
4545
+ const minutes = Math.max(1, Math.round((upcoming.atMs - Date.now()) / 6e4));
4546
+ const title = upcoming.entering === "peak" ? t("billing.peakAlertTitlePeak") : t("billing.peakAlertTitleOff");
4138
4547
  const body = upcoming.entering === "peak" ? t("billing.tierAlertEnterPeak").replace("{minutes}", String(minutes)) : t("billing.tierAlertEnterOff").replace("{minutes}", String(minutes));
4139
4548
  try {
4140
- new Notification(t("billing.budget"), { body });
4549
+ new Notification(title, { body });
4141
4550
  } catch {}
4142
4551
  }, [
4143
4552
  lastTierSwitchAt,
4553
+ peakConfig,
4144
4554
  actions,
4145
4555
  t
4146
4556
  ]);
@@ -4195,30 +4605,45 @@ window.__ModuleLoader__.load({
4195
4605
  ]);
4196
4606
  (0, react.useEffect)(() => registerOpen(openDashboard), [registerOpen, openDashboard]);
4197
4607
  const turns = (0, react.useMemo)(() => stats.byTurn ?? [], [stats.byTurn]);
4198
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(UsageBillingTrigger, {
4199
- ...props,
4200
- t,
4201
- onOpen: openDashboard,
4202
- monthCost,
4203
- todayCost,
4204
- weekCost,
4205
- days: last7
4206
- }), open && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BillingDashboard, {
4207
- stats,
4208
- t,
4209
- onClose: close,
4210
- health,
4211
- balances,
4212
- quotas,
4213
- currency,
4214
- onCurrency: setCurrency,
4215
- turns,
4216
- renderSlot,
4217
- budgetEnabled,
4218
- budgetAmount: effectiveBudget,
4219
- onToggleBudget: toggleBudget,
4220
- onBudgetAmount: actions.setAmount
4221
- })] });
4608
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
4609
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(UsageBillingTrigger, {
4610
+ ...props,
4611
+ t,
4612
+ onOpen: openDashboard,
4613
+ monthCost,
4614
+ todayCost,
4615
+ weekCost,
4616
+ days: last7
4617
+ }),
4618
+ open && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BillingDashboard, {
4619
+ stats,
4620
+ t,
4621
+ onClose: close,
4622
+ health,
4623
+ balances,
4624
+ quotas,
4625
+ currency,
4626
+ onCurrency: setCurrency,
4627
+ turns,
4628
+ renderSlot,
4629
+ budgetEnabled,
4630
+ budgetAmount: effectiveBudget,
4631
+ onToggleBudget: toggleBudget,
4632
+ onBudgetAmount: actions.setAmount,
4633
+ peakConfig,
4634
+ onPeakConfig: updatePeakConfig,
4635
+ onPreviewPeak: previewPeak
4636
+ }),
4637
+ (peakHit !== null || peakPreview !== null) && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PeakAlertBanner, {
4638
+ hit: peakHit ?? peakPreview,
4639
+ config: peakConfig,
4640
+ t,
4641
+ onDismiss: () => {
4642
+ setPeakHit(null);
4643
+ setPeakPreview(null);
4644
+ }
4645
+ })
4646
+ ] });
4222
4647
  }
4223
4648
  //#endregion
4224
4649
  //#region src/client/live-cost.tsx
@@ -4577,7 +5002,7 @@ window.__ModuleLoader__.load({
4577
5002
  }
4578
5003
  if (finishedTitles.length > 0) {
4579
5004
  queuedTitle = finishedTitles.length === 1 ? finishedTitles[0] : `${finishedTitles.length} 个会话已完成`;
4580
- notify(queuedTitle);
5005
+ if (queuedTitle !== void 0) notify(queuedTitle);
4581
5006
  }
4582
5007
  });
4583
5008
  }