@saasicat/ui-vue 0.19.0 → 0.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (145) hide show
  1. package/dist/{catalog-JXdKdIqG.d.cts → catalog-DJcfm5N2.d.cts} +21 -7
  2. package/dist/{catalog-JXdKdIqG.d.ts → catalog-DJcfm5N2.d.ts} +21 -7
  3. package/dist/{chunk-DPTIOQXX.js → chunk-F7NRM6KI.js} +56 -28
  4. package/dist/{chunk-RVG6LQHL.js → chunk-LY52T4N4.js} +21 -2
  5. package/dist/{chunk-ORX3ZG47.js → chunk-XMMFN2WJ.js} +74 -3
  6. package/dist/client/index.cjs +134 -29
  7. package/dist/client/index.d.cts +53 -3
  8. package/dist/client/index.d.ts +53 -3
  9. package/dist/client/index.js +14 -2
  10. package/dist/index.cjs +321 -162
  11. package/dist/index.d.cts +30 -8
  12. package/dist/index.d.ts +30 -8
  13. package/dist/index.js +176 -133
  14. package/dist/quasar/index.cjs +78 -29
  15. package/dist/quasar/index.d.cts +2 -2
  16. package/dist/quasar/index.d.ts +2 -2
  17. package/dist/quasar/index.js +6 -2
  18. package/dist/testing-e2e/admin-pages-suite.d.cts +37 -0
  19. package/dist/testing-e2e/admin-pages-suite.d.ts +37 -0
  20. package/dist/{use-super-admin-i18n-BlqcD0N7.d.ts → use-super-admin-i18n-CHNdsSlm.d.ts} +34 -7
  21. package/dist/{use-super-admin-i18n-1nCOkvgi.d.cts → use-super-admin-i18n-CgTuNi8h.d.cts} +34 -7
  22. package/package.json +18 -8
  23. package/src/client/i18n/messages/bundles.ts +0 -2
  24. package/src/client/i18n/messages/common.ts +24 -0
  25. package/src/client/i18n/messages/discovery.ts +2 -2
  26. package/src/client/i18n/messages/marketing.ts +2 -4
  27. package/src/client/i18n/messages/plan-detail.ts +0 -4
  28. package/src/client/i18n/messages/plans.ts +20 -8
  29. package/src/client/i18n/messages/tenants.ts +0 -2
  30. package/src/client/index.ts +1 -0
  31. package/src/client/manifest-loader.ts +1 -1
  32. package/src/client/resolve-plans.ts +144 -0
  33. package/src/components/BundleVersionPublishDialog.vue +6 -6
  34. package/src/components/KvBlock.vue +4 -4
  35. package/src/components/MarketingPromotionsTab.vue +34 -48
  36. package/src/components/MfaPromptDialog.vue +8 -2
  37. package/src/components/TenantActionConfirmDialog.vue +4 -4
  38. package/src/components/VersionDiffPreview.vue +7 -7
  39. package/src/components/admin-page/AdminBody.vue +40 -0
  40. package/src/components/admin-page/AdminFilters.vue +12 -0
  41. package/src/components/admin-page/AdminHero.vue +49 -0
  42. package/src/components/admin-page/AdminKpi.vue +84 -0
  43. package/src/components/admin-page/AdminPage.vue +16 -0
  44. package/src/components/admin-page/AdminPaginator.vue +195 -0
  45. package/src/components/admin-page/AdminRefreshBtn.vue +39 -0
  46. package/src/components/admin-page/AdminSection.vue +53 -0
  47. package/src/components/admin-page/AdminStatistics.vue +40 -0
  48. package/src/components/admin-page/AdminTable.vue +175 -0
  49. package/src/components/bundle-editor/BundleCreatePanel.vue +23 -23
  50. package/src/components/bundle-editor/BundleFeaturesEditor.vue +7 -7
  51. package/src/components/bundle-editor/BundlePlanCompatPicker.vue +9 -9
  52. package/src/components/bundle-editor/BundleQuotasEditor.vue +11 -11
  53. package/src/components/bundle-editor/BundleStatusBanner.vue +6 -6
  54. package/src/components/bundle-editor/BundleVersionInlineEditor.vue +18 -18
  55. package/src/components/bundle-editor/BundleVersionStrip.vue +12 -12
  56. package/src/components/dialogs/PilotCreateDialog.vue +12 -12
  57. package/src/components/dialogs/PilotEditDialog.vue +7 -7
  58. package/src/components/dialogs/PromoCodeCreateDialog.vue +8 -8
  59. package/src/components/dialogs/PromoCodeDialogFields.vue +33 -19
  60. package/src/components/dialogs/PromoCodeEditDialog.vue +10 -10
  61. package/src/components/plan/PlanGrid.vue +1 -1
  62. package/src/components/plan-create-dialog/PlanCreateDialog.vue +34 -46
  63. package/src/components/plan-detail/PlanAuditLog.vue +7 -8
  64. package/src/components/plan-detail/PlanDetail.vue +95 -292
  65. package/src/components/plan-detail/PlanDetailKpis.vue +22 -27
  66. package/src/components/plan-detail/PlanTitleEdit.vue +133 -0
  67. package/src/components/plan-detail/PlanVersionDiffPanel.vue +5 -8
  68. package/src/components/plan-detail/PlanVersionsPanel.vue +9 -11
  69. package/src/components/plan-list/PlanList.vue +206 -457
  70. package/src/components/plan-matrix/PlanMatrix.vue +66 -183
  71. package/src/components/plan-review/PlanReview.vue +191 -275
  72. package/src/components/plan-version-editor/PlanCatalogPreview.vue +7 -5
  73. package/src/components/plan-version-editor/PlanVersionEditor.vue +200 -295
  74. package/src/components/plan-version-editor/PlanVersionEditorHeader.vue +23 -55
  75. package/src/index.ts +1 -0
  76. package/src/pages-standard/AdminLayout.vue +38 -12
  77. package/src/pages-standard/AdminManifestErrorPage.vue +79 -9
  78. package/src/pages-standard/AuditPage.vue +65 -109
  79. package/src/pages-standard/BundlesPage.vue +146 -179
  80. package/src/pages-standard/DashboardPage.vue +59 -154
  81. package/src/pages-standard/DiscoveryPage.vue +172 -227
  82. package/src/pages-standard/EmailHistoryPage.vue +118 -159
  83. package/src/pages-standard/MarketingCatalogPage.vue +399 -440
  84. package/src/pages-standard/PilotsPage.vue +69 -117
  85. package/src/pages-standard/PlansPage.vue +240 -112
  86. package/src/pages-standard/PlatformEmailPage.vue +56 -91
  87. package/src/pages-standard/PromoCodeDetailPage.vue +49 -74
  88. package/src/pages-standard/PromoCodesPage.vue +95 -128
  89. package/src/pages-standard/SubscriptionsPage.vue +19 -52
  90. package/src/pages-standard/SuperAdminLoginPage.vue +12 -12
  91. package/src/pages-standard/SuperAdminSetupWizard.vue +22 -18
  92. package/src/pages-standard/TenantDetailPage.vue +100 -191
  93. package/src/pages-standard/TenantsPage.vue +190 -295
  94. package/src/pages-standard/UsersPage.vue +89 -157
  95. package/src/pages-standard/bundles-page/BundleAccordionList.vue +20 -17
  96. package/src/pages-standard/bundles-page/BundlesKpis.vue +13 -22
  97. package/src/pages-standard/bundles-page/BundlesToolbar.vue +63 -0
  98. package/src/pages-standard/discovery-page/CatalogEntryTransPanel.vue +10 -10
  99. package/src/pages-standard/discovery-page/DiscoveryCapList.vue +5 -5
  100. package/src/pages-standard/discovery-page/DiscoveryFeatureCard.vue +16 -16
  101. package/src/pages-standard/discovery-page/DiscoveryKpis.vue +31 -27
  102. package/src/pages-standard/discovery-page/DiscoveryQuotaCard.vue +7 -7
  103. package/src/pages-standard/marketing-catalog/MarketingCatalogAdmin.vue +111 -73
  104. package/src/pages-standard/marketing-catalog/MarketingCatalogHeader.vue +43 -62
  105. package/src/pages-standard/marketing-catalog/MarketingCatalogPreview.vue +53 -35
  106. package/src/pages-standard/marketing-catalog/MarketingCatalogToolbar.vue +7 -7
  107. package/src/pages-standard/plan-versions/PlanDiffCard.vue +6 -6
  108. package/src/pages-standard/plan-versions/PlanVersionsDiff.vue +6 -6
  109. package/src/pages-standard/plan-versions/PlanVersionsTimeline.vue +16 -16
  110. package/src/pages-standard/plans-page/PlanBundleOverview.vue +14 -29
  111. package/src/pages-standard/plans-page/PlanPublishDialog.vue +1 -1
  112. package/src/pages-standard/plans-page/PlansPageToast.vue +6 -6
  113. package/src/pages-standard/sa-theme.css +552 -86
  114. package/src/pages-standard/tenant-detail/TenantMasterData.vue +28 -0
  115. package/src/pages-standard/tenant-detail/TenantUsage.vue +31 -0
  116. package/src/pages-standard/tenant-detail/TenantUsers.vue +15 -0
  117. package/src/pages-standard/tenant-detail/types.ts +38 -0
  118. package/src/pages-standard/tenants/StatusPill.vue +2 -2
  119. package/src/pages-tenant/MySubscriptionBundlesPage.vue +25 -25
  120. package/src/pages-tenant/OnboardingConfigurator.vue +1 -5
  121. package/src/pages-tenant/PackageSnapshotPanel.vue +1 -1
  122. package/src/pages-tenant/TenantPlanSection.vue +12 -20
  123. package/src/quasar/create-super-admin-app.ts +4 -0
  124. package/src/vue/entitlement-provider.ts +0 -1
  125. package/src/vue/feature-router-guard.ts +0 -1
  126. package/src/vue/super-admin-context.ts +106 -1
  127. package/src/vue/use-api-list.ts +2 -1
  128. package/src/vue/use-mfa-prompt.ts +72 -0
  129. package/src/vue/use-pagination.ts +63 -0
  130. package/src/vue/use-plans.ts +1 -2
  131. package/src/vue/use-sign-out.ts +90 -0
  132. package/src/vue/use-tenant-billing.ts +1 -1
  133. package/src/vue/use-tenant-manifest.ts +0 -1
  134. package/src/components/KpiCard.vue +0 -53
  135. package/src/components/plan-cockpit/PlanCockpit.vue +0 -1012
  136. package/src/components/plan-cockpit/PlanCockpitAuditLog.vue +0 -72
  137. package/src/components/plan-cockpit/PlanCockpitDiffPanel.vue +0 -100
  138. package/src/components/plan-cockpit/PlanCockpitHeader.vue +0 -101
  139. package/src/components/plan-cockpit/PlanCockpitImpactPanel.vue +0 -112
  140. package/src/components/plan-cockpit/PlanCockpitKpis.vue +0 -68
  141. package/src/components/plan-cockpit/PlanCockpitVersions.vue +0 -251
  142. package/src/components/plan-cockpit/types.ts +0 -72
  143. package/src/components/plan-detail/PlanDetailHeader.vue +0 -194
  144. package/src/pages-standard/bundles-page/BundlesHeader.vue +0 -68
  145. package/src/pages-standard/discovery-page/DiscoveryHeader.vue +0 -34
@@ -1,25 +1,14 @@
1
1
  <template>
2
- <div class="pd">
3
- <PlanDetailHeader
4
- :plan="plan"
5
- :draft-version="draftVersion"
6
- :tenant-total="tenantTotal"
7
- :published-count="publishedCount"
8
- @back="$emit('back')"
9
- @delete-plan="$emit('deletePlan')"
10
- @clone-plan="$emit('clonePlan')"
11
- @create-draft="$emit('createDraft')"
12
- @publish="$emit('publish', $event)"
13
- @update-plan="$emit('updatePlan', $event)"
14
- />
15
-
16
- <PlanDetailKpis
17
- :live-version="liveVersion"
18
- :draft-version="draftVersion"
19
- :tenant-total="tenantTotal"
20
- :version-count="versions.length"
21
- :published-count="publishedCount"
22
- />
2
+ <div>
3
+ <AdminSection class="q-mb-md">
4
+ <PlanDetailKpis
5
+ :live-version="liveVersion"
6
+ :draft-version="draftVersion"
7
+ :tenant-total="tenantTotal"
8
+ :version-count="versions.length"
9
+ :published-count="publishedCount"
10
+ />
11
+ </AdminSection>
23
12
 
24
13
  <div class="pd-body">
25
14
  <PlanVersionsPanel
@@ -81,7 +70,7 @@ import { isVersionEditable, type PlanRow, type PlanVersionRow } from '@saasicat/
81
70
  import { formatCurrency } from '../../client/i18n/currency.js';
82
71
  import { useSaMessages, useSuperAdminI18n } from '../../vue/use-super-admin-i18n.js';
83
72
  import PlanAuditLog from './PlanAuditLog.vue';
84
- import PlanDetailHeader from './PlanDetailHeader.vue';
73
+ import AdminSection from '../admin-page/AdminSection.vue';
85
74
  import PlanDetailKpis from './PlanDetailKpis.vue';
86
75
  import PlanTerminateDialog from './PlanTerminateDialog.vue';
87
76
  import PlanVersionDiffPanel from './PlanVersionDiffPanel.vue';
@@ -131,13 +120,9 @@ const props = withDefaults(
131
120
  );
132
121
 
133
122
  const emit = defineEmits<{
134
- (e: 'back'): void;
135
123
  (e: 'createDraft'): void;
136
124
  (e: 'editDraft', version: PlanVersionRow): void;
137
125
  (e: 'publish', version: PlanVersionRow): void;
138
- (e: 'clonePlan'): void;
139
- (e: 'deletePlan'): void;
140
- (e: 'updatePlan', patch: { label: string }): void;
141
126
  (e: 'terminate', versionId: string, endsAt: string): void;
142
127
  }>();
143
128
 
@@ -155,7 +140,6 @@ function statusOf(v: PlanVersionRow): PlanVersionStatus {
155
140
  * Editability decision per version — identical to the backend rule
156
141
  * (`isVersionEditable`). The UI uses the result both for the visibility
157
142
  * of the edit button and for the badge on published-but-future versions
158
- * (SPEC_V2 §11.1 M6 Pack 2c).
159
143
  */
160
144
  function editabilityOf(v: PlanVersionRow): PlanVersionEditability {
161
145
  return isVersionEditable(v);
@@ -401,7 +385,9 @@ async function executeTerminate(): Promise<void> {
401
385
  const code = e?.body?.code;
402
386
  if (code === 'PLAN_TERMINATE_DATE_NOT_FUTURE') {
403
387
  terminateError.value = msg.value.terminateDialog.errorDateNotFuture;
404
- } else if (code === 'PLAN_VERSION_NOT_LIVE') {
388
+ } else if (code === 'PLAN_VERSION_NOT_PUBLISHED' || code === 'PLAN_VERSION_SUPERSEDED') {
389
+ // Split out of the former PLAN_VERSION_NOT_LIVE; both mean the
390
+ // version cannot be terminated, so they share one message.
405
391
  terminateError.value = msg.value.terminateDialog.errorVersionNotLive;
406
392
  } else if (code === 'PLAN_TERMINATE_NOT_IMPLEMENTED') {
407
393
  terminateError.value = msg.value.terminateDialog.errorNotImplemented;
@@ -418,38 +404,8 @@ async function executeTerminate(): Promise<void> {
418
404
  </script>
419
405
 
420
406
  <style>
421
- .pd {
422
- --primary: #2563eb;
423
- --border: #e5e7eb;
424
- --border-strong: #d1d5db;
425
- --text: #0f172a;
426
- --text-2: #475569;
427
- --bg: #f6f7f9;
428
- --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
429
- --font-mono: 'JetBrains Mono', ui-monospace, 'SF Mono', Menlo, monospace;
430
-
431
- padding: 22px 26px;
432
- background: var(--bg);
433
- font-family: var(--font-sans);
434
- color: var(--text);
435
- min-height: 100%;
436
- box-sizing: border-box;
437
- }
438
- .pd * {
439
- box-sizing: border-box;
440
- }
441
- /* Consumer apps load Quasar, which styles h1–h6 globally with very large
442
- line-heights. Neutralize that here so headings (and the tier chip
443
- sitting next to them) are aligned correctly. */
444
- .pd h1,
445
- .pd h2,
446
- .pd h3,
447
- .pd h4 {
448
- line-height: 1.2;
449
- margin: 0;
450
- }
451
407
  .pd-code {
452
- font: 500 11px var(--font-mono);
408
+ font: 500 11px var(--sa-font-mono);
453
409
  }
454
410
 
455
411
  /* buttons + chips (1:1 styles.css) */
@@ -459,40 +415,31 @@ async function executeTerminate(): Promise<void> {
459
415
  gap: 7px;
460
416
  padding: 8px 14px;
461
417
  border-radius: 7px;
462
- font: 500 13px var(--font-sans);
418
+ font: 500 13px var(--sa-font-body);
463
419
  cursor: pointer;
464
- border: 1px solid var(--border-strong);
420
+ border: 1px solid var(--sa-border-strong);
465
421
  background: #fff;
466
- color: var(--text);
422
+ color: var(--sa-heading);
467
423
  transition:
468
424
  background 0.12s,
469
425
  border-color 0.12s;
470
426
  }
471
427
  .btn:hover {
472
- background: #f8fafc;
428
+ background: var(--sa-bg-surface-2);
473
429
  }
474
430
  .btn.primary {
475
- background: var(--primary);
476
- border-color: var(--primary);
431
+ background: var(--sa-primary);
432
+ border-color: var(--sa-primary);
477
433
  color: #fff;
478
434
  }
479
435
  .btn.primary:hover {
480
- background: #1d4ed8;
436
+ background: var(--sa-primary-strong);
481
437
  }
482
438
  .btn.btn--sm {
483
439
  padding: 5px 9px;
484
440
  font-size: 12px;
485
441
  gap: 5px;
486
442
  }
487
- .btn.danger {
488
- border-color: #fecaca;
489
- color: #b91c1c;
490
- background: #fff;
491
- }
492
- .btn.danger:hover {
493
- background: #fef2f2;
494
- border-color: #fca5a5;
495
- }
496
443
  .chip {
497
444
  display: inline-flex;
498
445
  align-items: center;
@@ -501,23 +448,23 @@ async function executeTerminate(): Promise<void> {
501
448
  border-radius: 999px;
502
449
  font-size: 11px;
503
450
  font-weight: 600;
504
- background: #f8fafc;
505
- color: var(--text-2);
506
- border: 1px solid var(--border);
451
+ background: var(--sa-bg-surface-2);
452
+ color: var(--sa-muted-dark);
453
+ border: 1px solid var(--sa-border);
507
454
  }
508
455
  .chip.live {
509
- background: #ecfdf5;
456
+ background: var(--sa-positive-bg);
510
457
  color: #047857;
511
458
  border-color: #a7f3d0;
512
459
  }
513
460
  .chip.draft {
514
- background: #fffbeb;
461
+ background: var(--sa-warning-bg);
515
462
  color: #b45309;
516
463
  border-color: #fde68a;
517
464
  }
518
465
  .chip.supersed {
519
- background: #f1f5f9;
520
- color: #475569;
466
+ background: var(--sa-border-soft);
467
+ color: var(--sa-muted-dark);
521
468
  border-color: #cbd5e1;
522
469
  }
523
470
  .chip.dot::before {
@@ -529,148 +476,8 @@ async function executeTerminate(): Promise<void> {
529
476
  }
530
477
 
531
478
  /* header */
532
- .pd-header {
533
- display: flex;
534
- align-items: flex-start;
535
- gap: 18px;
536
- margin-bottom: 18px;
537
- }
538
- .pd-header-left {
539
- display: flex;
540
- align-items: flex-start;
541
- gap: 14px;
542
- min-width: 0;
543
- flex: 1;
544
- }
545
- .pd-header-titles {
546
- min-width: 0;
547
- }
548
- .pd-back-arrow {
549
- display: inline-flex;
550
- transform: rotate(180deg);
551
- }
552
- .pd-tier-chip {
553
- font: 700 10.5px var(--font-mono);
554
- letter-spacing: 0.08em;
555
- background: #f1f5f9;
556
- color: #475569;
557
- border: 1px solid #e2e8f0;
558
- padding: 4px 10px;
559
- border-radius: 6px;
560
- margin-top: 8px;
561
- }
562
- .pd-title {
563
- font-size: 28px;
564
- font-weight: 700;
565
- letter-spacing: -0.025em;
566
- margin: 0;
567
- color: var(--text);
568
- }
569
- .pd-desc {
570
- margin-top: 4px;
571
- font-size: 13px;
572
- color: var(--text-2);
573
- }
574
- .pd-actions {
575
- display: flex;
576
- gap: 8px;
577
- align-items: center;
578
- }
579
- .pd-title-wrap {
580
- display: flex;
581
- align-items: center;
582
- gap: 8px;
583
- }
584
- .pd-title-edit-btn {
585
- display: inline-flex;
586
- align-items: center;
587
- justify-content: center;
588
- width: 28px;
589
- height: 28px;
590
- border-radius: 6px;
591
- background: transparent;
592
- border: 1px solid transparent;
593
- color: #94a3b8;
594
- cursor: pointer;
595
- transition:
596
- background 0.12s,
597
- color 0.12s,
598
- border-color 0.12s;
599
- }
600
- .pd-title-edit-btn:hover {
601
- background: #f1f5f9;
602
- color: var(--primary);
603
- border-color: #e2e8f0;
604
- }
605
- .pd-title-input {
606
- font: inherit;
607
- font-size: 28px;
608
- font-weight: 700;
609
- letter-spacing: -0.025em;
610
- color: var(--text);
611
- border: 0;
612
- background: #fffbeb;
613
- outline: 2px solid #fcd34d;
614
- padding: 2px 8px;
615
- border-radius: 6px;
616
- min-width: 220px;
617
- }
618
- .pd-title-hint {
619
- font-size: 11px;
620
- color: #92400e;
621
- font-weight: 500;
622
- background: #fffbeb;
623
- border: 1px solid #fde68a;
624
- padding: 2px 8px;
625
- border-radius: 999px;
626
- margin-left: 4px;
627
- }
628
479
 
629
480
  /* KPI cards */
630
- .pd-kpis {
631
- display: grid;
632
- grid-template-columns: repeat(4, 1fr);
633
- gap: 12px;
634
- margin-bottom: 16px;
635
- }
636
- .pd-kpi {
637
- background: #fff;
638
- border: 1px solid var(--border);
639
- border-radius: 10px;
640
- padding: 14px 16px 12px;
641
- min-height: 102px;
642
- display: flex;
643
- flex-direction: column;
644
- gap: 6px;
645
- }
646
- .pd-kpi-label {
647
- font-size: 10.5px;
648
- font-weight: 700;
649
- text-transform: uppercase;
650
- letter-spacing: 0.1em;
651
- color: #64748b;
652
- }
653
- .pd-kpi-big {
654
- font: 700 26px/1 var(--font-sans);
655
- letter-spacing: -0.025em;
656
- color: var(--text);
657
- display: flex;
658
- align-items: center;
659
- gap: 10px;
660
- }
661
- .pd-kpi-sub {
662
- font-size: 11.5px;
663
- color: #64748b;
664
- margin-top: auto;
665
- }
666
- .pd-kpi.draft {
667
- background: linear-gradient(180deg, #fffbeb 0%, #fffef7 100%);
668
- border-color: #fde68a;
669
- }
670
- .pd-kpi.draft .pd-kpi-label,
671
- .pd-kpi.draft .pd-kpi-sub {
672
- color: #92400e;
673
- }
674
481
 
675
482
  /* body */
676
483
  .pd-body {
@@ -679,10 +486,9 @@ async function executeTerminate(): Promise<void> {
679
486
  gap: 16px;
680
487
  align-items: start;
681
488
  }
489
+ /* Surface, border and radius come from `.sa-section` — the panel IS one.
490
+ * Only `overflow` stays, so content is clipped at the rounded edge. */
682
491
  .pd-panel {
683
- background: #fff;
684
- border: 1px solid var(--border);
685
- border-radius: 10px;
686
492
  overflow: hidden;
687
493
  }
688
494
  .pd-panel-head {
@@ -690,18 +496,18 @@ async function executeTerminate(): Promise<void> {
690
496
  align-items: flex-start;
691
497
  gap: 12px;
692
498
  padding: 14px 16px 12px;
693
- border-bottom: 1px solid #f1f5f9;
499
+ border-bottom: 1px solid var(--sa-border-soft);
694
500
  }
695
501
  .pd-panel-title {
696
502
  font-size: 15px;
697
503
  font-weight: 700;
698
504
  margin: 0;
699
505
  letter-spacing: -0.01em;
700
- color: var(--text);
506
+ color: var(--sa-heading);
701
507
  }
702
508
  .pd-panel-sub {
703
509
  font-size: 11.5px;
704
- color: #64748b;
510
+ color: var(--sa-muted);
705
511
  margin-top: 3px;
706
512
  }
707
513
  .pd-panel-head-right {
@@ -720,7 +526,7 @@ async function executeTerminate(): Promise<void> {
720
526
  align-items: center;
721
527
  gap: 6px;
722
528
  font-size: 11px;
723
- color: #94a3b8;
529
+ color: var(--sa-muted-light);
724
530
  margin-bottom: 8px;
725
531
  font-weight: 500;
726
532
  }
@@ -734,14 +540,14 @@ async function executeTerminate(): Promise<void> {
734
540
  height: 24px;
735
541
  border-radius: 6px;
736
542
  overflow: hidden;
737
- background: #f1f5f9;
738
- border: 1px solid #e2e8f0;
543
+ background: var(--sa-border-soft);
544
+ border: 1px solid var(--sa-border);
739
545
  }
740
546
  .pd-timeline-seg {
741
547
  display: flex;
742
548
  align-items: center;
743
549
  justify-content: center;
744
- font: 600 11px var(--font-sans);
550
+ font: 600 11px var(--sa-font-body);
745
551
  color: rgba(15, 23, 42, 0.65);
746
552
  border-right: 1px solid rgba(0, 0, 0, 0.06);
747
553
  white-space: nowrap;
@@ -764,8 +570,8 @@ async function executeTerminate(): Promise<void> {
764
570
  transform: translateY(0);
765
571
  }
766
572
  .pd-timeline-seg.superseded {
767
- background: #e2e8f0;
768
- color: #475569;
573
+ background: var(--sa-border);
574
+ color: var(--sa-muted-dark);
769
575
  }
770
576
  .pd-timeline-seg.live {
771
577
  background: #10b981;
@@ -780,13 +586,13 @@ async function executeTerminate(): Promise<void> {
780
586
  .pd-timeline-seg.is-selected {
781
587
  position: relative;
782
588
  z-index: 1;
783
- outline: 2px solid var(--primary);
589
+ outline: 2px solid var(--sa-primary);
784
590
  outline-offset: -2px;
785
591
  box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.18);
786
592
  font-weight: 700;
787
593
  }
788
594
  .pd-timeline-seg.is-selected.superseded {
789
- color: #0f172a;
595
+ color: var(--sa-heading);
790
596
  }
791
597
  .pd-timeline-seg.is-selected.live {
792
598
  outline-color: #047857;
@@ -800,8 +606,8 @@ async function executeTerminate(): Promise<void> {
800
606
  display: flex;
801
607
  justify-content: space-between;
802
608
  margin-top: 6px;
803
- font: 500 10.5px var(--font-mono);
804
- color: #94a3b8;
609
+ font: 500 10.5px var(--sa-font-mono);
610
+ color: var(--sa-muted-light);
805
611
  }
806
612
 
807
613
  /* versions table */
@@ -817,7 +623,7 @@ async function executeTerminate(): Promise<void> {
817
623
  64px minmax(0, 1.4fr) minmax(0, 1.1fr) minmax(0, 0.8fr) minmax(0, 1fr)
818
624
  minmax(96px, auto);
819
625
  align-items: stretch;
820
- border-top: 1px solid #f1f5f9;
626
+ border-top: 1px solid var(--sa-border-soft);
821
627
  margin-top: 12px;
822
628
  }
823
629
  .pd-versions-head {
@@ -829,9 +635,9 @@ async function executeTerminate(): Promise<void> {
829
635
  font-size: 10px;
830
636
  text-transform: uppercase;
831
637
  letter-spacing: 0.1em;
832
- color: #64748b;
638
+ color: var(--sa-muted);
833
639
  font-weight: 700;
834
- border-bottom: 1px solid var(--border);
640
+ border-bottom: 1px solid var(--sa-border);
835
641
  }
836
642
  .pd-vrow {
837
643
  display: contents;
@@ -839,11 +645,11 @@ async function executeTerminate(): Promise<void> {
839
645
  }
840
646
  .pd-vrow > div {
841
647
  padding: 13px 12px;
842
- border-bottom: 1px solid #f1f5f9;
648
+ border-bottom: 1px solid var(--sa-border-soft);
843
649
  display: flex;
844
650
  align-items: center;
845
651
  font-size: 12.5px;
846
- color: var(--text);
652
+ color: var(--sa-heading);
847
653
  }
848
654
  .pd-vrow:hover > div {
849
655
  background: #fafbfd;
@@ -855,7 +661,7 @@ async function executeTerminate(): Promise<void> {
855
661
  background: #fff8e7;
856
662
  }
857
663
  .pd-vrow.is-selected > div {
858
- background: #eff6ff !important;
664
+ background: var(--sa-primary-50) !important;
859
665
  box-shadow: inset 0 -1px 0 0 #bfdbfe;
860
666
  }
861
667
  .pd-vrow.is-selected.is-draft > div {
@@ -864,7 +670,7 @@ async function executeTerminate(): Promise<void> {
864
670
  }
865
671
  .pd-vrow.is-selected > div:first-child {
866
672
  box-shadow:
867
- inset 3px 0 0 0 var(--primary),
673
+ inset 3px 0 0 0 var(--sa-primary),
868
674
  inset 0 -1px 0 0 #bfdbfe;
869
675
  }
870
676
  .pd-vrow.is-draft > div:first-child {
@@ -882,7 +688,7 @@ async function executeTerminate(): Promise<void> {
882
688
  align-items: flex-start;
883
689
  }
884
690
  .pd-v-num {
885
- font: 700 14px var(--font-sans);
691
+ font: 700 14px var(--sa-font-body);
886
692
  }
887
693
  .pd-validity {
888
694
  display: flex;
@@ -896,32 +702,32 @@ async function executeTerminate(): Promise<void> {
896
702
  }
897
703
  .pd-validity-sub {
898
704
  font-size: 10.5px;
899
- color: #94a3b8;
705
+ color: var(--sa-muted-light);
900
706
  }
901
707
  .pd-validity-date {
902
- font: 500 12.5px var(--font-mono);
708
+ font: 500 12.5px var(--sa-font-mono);
903
709
  }
904
710
  .pd-arrow-inf {
905
- font: 600 13px var(--font-mono);
906
- color: #94a3b8;
711
+ font: 600 13px var(--sa-font-mono);
712
+ color: var(--sa-muted-light);
907
713
  }
908
714
  .pd-pricing-m {
909
- font: 600 13px var(--font-sans);
715
+ font: 600 13px var(--sa-font-body);
910
716
  }
911
717
  .pd-pricing-y {
912
- font: 500 10.5px var(--font-sans);
913
- color: #94a3b8;
718
+ font: 500 10.5px var(--sa-font-body);
719
+ color: var(--sa-muted-light);
914
720
  margin-top: 2px;
915
721
  }
916
722
  .pd-impact-num {
917
- font: 700 14px var(--font-sans);
723
+ font: 700 14px var(--sa-font-body);
918
724
  }
919
725
  .pd-impact-sub {
920
726
  font-size: 10.5px;
921
- color: #94a3b8;
727
+ color: var(--sa-muted-light);
922
728
  }
923
729
  .pd-change-note {
924
- color: #94a3b8;
730
+ color: var(--sa-muted-light);
925
731
  font-style: italic;
926
732
  overflow: hidden;
927
733
  text-overflow: ellipsis;
@@ -938,8 +744,8 @@ async function executeTerminate(): Promise<void> {
938
744
  align-items: center;
939
745
  padding: 3px 8px;
940
746
  border-radius: 999px;
941
- font: 600 10.5px var(--font-mono);
942
- background: #fffbeb;
747
+ font: 600 10.5px var(--sa-font-mono);
748
+ background: var(--sa-warning-bg);
943
749
  color: #b45309;
944
750
  border: 1px solid #fde68a;
945
751
  white-space: nowrap;
@@ -951,12 +757,12 @@ async function executeTerminate(): Promise<void> {
951
757
  gap: 6px;
952
758
  }
953
759
  .pd-diff-chip {
954
- font: 700 11px var(--font-mono);
760
+ font: 700 11px var(--sa-font-mono);
955
761
  padding: 3px 8px;
956
762
  border-radius: 6px;
957
763
  }
958
764
  .pd-diff-chip.add {
959
- background: #ecfdf5;
765
+ background: var(--sa-positive-bg);
960
766
  color: #047857;
961
767
  border: 1px solid #a7f3d0;
962
768
  }
@@ -966,9 +772,9 @@ async function executeTerminate(): Promise<void> {
966
772
  border: 1px solid #fecaca;
967
773
  }
968
774
  .pd-diff-chip.mod {
969
- background: #f1f5f9;
970
- color: #475569;
971
- border: 1px solid #e2e8f0;
775
+ background: var(--sa-border-soft);
776
+ color: var(--sa-muted-dark);
777
+ border: 1px solid var(--sa-border);
972
778
  }
973
779
  .pd-diff-list {
974
780
  padding: 12px;
@@ -981,13 +787,13 @@ async function executeTerminate(): Promise<void> {
981
787
  align-items: center;
982
788
  gap: 10px;
983
789
  background: #fff;
984
- border: 1px solid var(--border);
790
+ border: 1px solid var(--sa-border);
985
791
  border-radius: 8px;
986
792
  padding: 11px 12px 11px 0;
987
793
  overflow: hidden;
988
794
  }
989
795
  .pd-diff-row.add {
990
- background: linear-gradient(90deg, #ecfdf5 0%, #fff 60%);
796
+ background: linear-gradient(90deg, var(--sa-positive-bg) 0%, #fff 60%);
991
797
  border-color: #a7f3d0;
992
798
  }
993
799
  .pd-diff-row.rm {
@@ -995,8 +801,8 @@ async function executeTerminate(): Promise<void> {
995
801
  border-color: #fecaca;
996
802
  }
997
803
  .pd-diff-row.mod {
998
- background: linear-gradient(90deg, #f8fafc 0%, #fff 60%);
999
- border-color: #e2e8f0;
804
+ background: linear-gradient(90deg, var(--sa-bg-surface-2) 0%, #fff 60%);
805
+ border-color: var(--sa-border);
1000
806
  }
1001
807
  .pd-diff-icon {
1002
808
  width: 32px;
@@ -1005,7 +811,7 @@ async function executeTerminate(): Promise<void> {
1005
811
  place-items: center;
1006
812
  flex: 0 0 32px;
1007
813
  color: #fff;
1008
- font: 700 16px var(--font-sans);
814
+ font: 700 16px var(--sa-font-body);
1009
815
  }
1010
816
  .pd-diff-row.add .pd-diff-icon {
1011
817
  background: #10b981;
@@ -1014,7 +820,7 @@ async function executeTerminate(): Promise<void> {
1014
820
  background: #ef4444;
1015
821
  }
1016
822
  .pd-diff-row.mod .pd-diff-icon {
1017
- background: #64748b;
823
+ background: var(--sa-muted);
1018
824
  }
1019
825
  .pd-diff-body {
1020
826
  flex: 1;
@@ -1025,29 +831,29 @@ async function executeTerminate(): Promise<void> {
1025
831
  flex-wrap: wrap;
1026
832
  }
1027
833
  .pd-diff-kind {
1028
- font: 700 10px var(--font-mono);
834
+ font: 700 10px var(--sa-font-mono);
1029
835
  text-transform: uppercase;
1030
836
  letter-spacing: 0.1em;
1031
- color: #64748b;
837
+ color: var(--sa-muted);
1032
838
  }
1033
839
  .pd-diff-label {
1034
840
  font-size: 13.5px;
1035
841
  font-weight: 600;
1036
- color: var(--text);
842
+ color: var(--sa-heading);
1037
843
  }
1038
844
  .pd-diff-key {
1039
- font: 500 11px var(--font-mono);
1040
- color: #94a3b8;
845
+ font: 500 11px var(--sa-font-mono);
846
+ color: var(--sa-muted-light);
1041
847
  }
1042
848
  .pd-diff-vals {
1043
849
  display: flex;
1044
850
  align-items: center;
1045
851
  gap: 6px;
1046
- font: 500 12px var(--font-mono);
852
+ font: 500 12px var(--sa-font-mono);
1047
853
  }
1048
854
  .pd-diff-strike {
1049
855
  text-decoration: line-through;
1050
- color: #94a3b8;
856
+ color: var(--sa-muted-light);
1051
857
  }
1052
858
  .pd-diff-arrow {
1053
859
  color: #cbd5e1;
@@ -1076,12 +882,12 @@ async function executeTerminate(): Promise<void> {
1076
882
  }
1077
883
  .pd-diff-tag.mod {
1078
884
  background: #fff;
1079
- color: #475569;
885
+ color: var(--sa-muted-dark);
1080
886
  border-color: #cbd5e1;
1081
887
  }
1082
888
  .pd-diff-row.plain {
1083
889
  background: #fff;
1084
- border-color: #e2e8f0;
890
+ border-color: var(--sa-border);
1085
891
  padding: 11px 12px 11px 0;
1086
892
  }
1087
893
  .pd-diff-section {
@@ -1093,7 +899,7 @@ async function executeTerminate(): Promise<void> {
1093
899
  font-size: 10.5px;
1094
900
  text-transform: uppercase;
1095
901
  letter-spacing: 0.1em;
1096
- color: #94a3b8;
902
+ color: var(--sa-muted-light);
1097
903
  font-weight: 700;
1098
904
  }
1099
905
  .pd-diff-section:first-child {
@@ -1102,17 +908,17 @@ async function executeTerminate(): Promise<void> {
1102
908
  .pd-diff-section hr {
1103
909
  flex: 1;
1104
910
  border: 0;
1105
- border-top: 1px dashed #e2e8f0;
911
+ border-top: 1px dashed var(--sa-border);
1106
912
  }
1107
913
  .pd-diff-empty {
1108
914
  padding: 28px 18px;
1109
915
  text-align: center;
1110
- color: #94a3b8;
916
+ color: var(--sa-muted-light);
1111
917
  font-size: 13px;
1112
918
  }
1113
919
  .pd-diff-empty b {
1114
920
  display: block;
1115
- color: #475569;
921
+ color: var(--sa-muted-dark);
1116
922
  font-size: 14px;
1117
923
  margin-bottom: 4px;
1118
924
  }
@@ -1129,7 +935,7 @@ async function executeTerminate(): Promise<void> {
1129
935
  align-items: center;
1130
936
  gap: 14px;
1131
937
  padding: 9px 0;
1132
- border-top: 1px solid #f1f5f9;
938
+ border-top: 1px solid var(--sa-border-soft);
1133
939
  }
1134
940
  .pd-audit-row:first-child {
1135
941
  border-top: 0;
@@ -1147,7 +953,7 @@ async function executeTerminate(): Promise<void> {
1147
953
  background: #10b981;
1148
954
  }
1149
955
  .pd-audit-change {
1150
- background: #2563eb;
956
+ background: var(--sa-primary);
1151
957
  }
1152
958
  .pd-audit-publish {
1153
959
  background: #8b5cf6;
@@ -1157,28 +963,28 @@ async function executeTerminate(): Promise<void> {
1157
963
  }
1158
964
  .pd-audit-when {
1159
965
  font-size: 11.5px;
1160
- color: #64748b;
966
+ color: var(--sa-muted);
1161
967
  min-width: 130px;
1162
968
  }
1163
969
  .pd-audit-avatar {
1164
970
  width: 24px;
1165
971
  height: 24px;
1166
972
  border-radius: 50%;
1167
- background: var(--text);
973
+ background: var(--sa-heading);
1168
974
  color: #fff;
1169
975
  display: grid;
1170
976
  place-items: center;
1171
- font: 700 11px var(--font-sans);
977
+ font: 700 11px var(--sa-font-body);
1172
978
  flex: 0 0 auto;
1173
979
  }
1174
980
  .pd-audit-who {
1175
981
  font-size: 12px;
1176
- color: var(--text-2);
982
+ color: var(--sa-muted-dark);
1177
983
  min-width: 64px;
1178
984
  }
1179
985
  .pd-audit-what {
1180
986
  font-size: 13px;
1181
- color: var(--text);
987
+ color: var(--sa-heading);
1182
988
  flex: 1;
1183
989
  }
1184
990
 
@@ -1186,8 +992,5 @@ async function executeTerminate(): Promise<void> {
1186
992
  .pd-body {
1187
993
  grid-template-columns: 1fr;
1188
994
  }
1189
- .pd-kpis {
1190
- grid-template-columns: repeat(2, 1fr);
1191
- }
1192
995
  }
1193
996
  </style>