@tokenoftrust/storefront-runner 1.3.2 → 1.3.4-rc.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.
Files changed (79) hide show
  1. package/apps/storefront/astro.config.mjs +59 -0
  2. package/apps/storefront/env.d.ts +24 -8
  3. package/apps/storefront/package.json +1 -1
  4. package/apps/storefront/src/components/admin/{AdminFoxyCartSettingsPanel.astro → AdminCheckoutSettingsPanel.astro} +50 -51
  5. package/apps/storefront/src/components/admin/AdminSettingsTab.astro +2 -2
  6. package/apps/storefront/src/components/admin/AdminSubscriptionsTab.astro +613 -0
  7. package/apps/storefront/src/components/admin/orders/OrdersWorkspace.astro +3 -3
  8. package/apps/storefront/src/components/chrome/SiteHeader.astro +3 -4
  9. package/apps/storefront/src/components/commerce/{FoxySidecartStyles.astro → CartDrawerStyles.astro} +13 -14
  10. package/apps/storefront/src/components/commerce/CheckoutLoader.astro +21 -0
  11. package/apps/storefront/src/components/islands/VariantSelector.tsx +101 -20
  12. package/apps/storefront/src/config/adminTargetTenant.ts +2 -2
  13. package/apps/storefront/src/config/devTenantSeed.ts +65 -16
  14. package/apps/storefront/src/config/resolver.ts +48 -1
  15. package/apps/storefront/src/layouts/Layout.astro +14 -12
  16. package/apps/storefront/src/lib/admin/README.md +2 -2
  17. package/apps/storefront/src/lib/admin/checkoutStyleInput.ts +5 -5
  18. package/apps/storefront/src/lib/admin/orderClient.ts +20 -20
  19. package/apps/storefront/src/lib/admin/services/mock/{foxyCartSettings.ts → checkoutSettings.ts} +21 -22
  20. package/apps/storefront/src/lib/admin/services/mock/index.ts +3 -2
  21. package/apps/storefront/src/lib/admin/services/mock/settings.ts +1 -1
  22. package/apps/storefront/src/lib/admin/services/mock/subscriptions.ts +398 -0
  23. package/apps/storefront/src/lib/admin/services/orders.ts +21 -21
  24. package/apps/storefront/src/lib/admin/viewmodels/subscriptions.ts +106 -0
  25. package/apps/storefront/src/lib/auth/loginGate.ts +14 -3
  26. package/apps/storefront/src/lib/{foxyCommerce.ts → checkoutCommerce.ts} +20 -18
  27. package/apps/storefront/src/lib/commerce/{foxyCartSettings.ts → checkoutSettings.ts} +65 -66
  28. package/apps/storefront/src/lib/dev/activityIngestToken.ts +9 -0
  29. package/apps/storefront/src/lib/dev/activityStore.ts +12 -0
  30. package/apps/storefront/src/lib/dev/cliSignInCode.ts +23 -4
  31. package/apps/storefront/src/lib/dev/runtimeStore.ts +193 -22
  32. package/apps/storefront/src/lib/edgeCache.ts +7 -6
  33. package/apps/storefront/src/lib/health.ts +53 -0
  34. package/apps/storefront/src/lib/privacy/emailHint.ts +33 -0
  35. package/apps/storefront/src/lib/rawMarketingHtml.ts +1 -0
  36. package/apps/storefront/src/lib/sections.ts +19 -23
  37. package/apps/storefront/src/lib/securityHeaders.ts +1 -1
  38. package/apps/storefront/src/lib/storyblok/content-model.ts +3 -2
  39. package/apps/storefront/src/middleware/index.ts +29 -12
  40. package/apps/storefront/src/pages/[...slug].astro +5 -6
  41. package/apps/storefront/src/pages/admin.astro +10 -3
  42. package/apps/storefront/src/pages/api/admin/orders/[id].ts +4 -4
  43. package/apps/storefront/src/pages/api/admin/orders.ts +5 -5
  44. package/apps/storefront/src/pages/api/auth/magic-exchange.ts +14 -7
  45. package/apps/storefront/src/pages/api/checkout-style.css.ts +5 -5
  46. package/apps/storefront/src/pages/auth/login.astro +4 -1
  47. package/apps/storefront/src/pages/auth/magic.astro +263 -43
  48. package/apps/storefront/src/pages/capabilities.astro +1 -1
  49. package/apps/storefront/src/pages/cockpit.astro +2365 -0
  50. package/apps/storefront/src/pages/dashboard/[appDomain]/team.astro +19 -0
  51. package/apps/storefront/src/pages/index.astro +23 -29
  52. package/apps/storefront/src/pages/products/[handle].astro +50 -20
  53. package/package.json +6 -2
  54. package/packages/public-runtime/src/capabilities.ts +97 -9
  55. package/packages/public-runtime/src/{foxy-orders.ts → checkout-orders.ts} +28 -27
  56. package/packages/public-runtime/src/checkout-style-publish.ts +25 -25
  57. package/packages/public-runtime/src/checkout-style.ts +13 -13
  58. package/packages/public-runtime/src/{foxy.ts → checkout.ts} +111 -34
  59. package/packages/public-runtime/src/csp.ts +11 -11
  60. package/packages/public-runtime/src/customization-scripts.ts +28 -0
  61. package/packages/public-runtime/src/extension-contract.ts +73 -0
  62. package/packages/public-runtime/src/index.ts +4 -2
  63. package/packages/public-runtime/src/product.ts +57 -0
  64. package/packages/public-runtime/src/raw-html-policy.ts +35 -0
  65. package/packages/public-runtime/src/tenant.ts +14 -11
  66. package/pnpm-workspace.yaml +1 -0
  67. package/scripts/dev/checkout-watch.mjs +9 -0
  68. package/scripts/dev/file-browser.mjs +5 -1
  69. package/scripts/dev/transient-files.mjs +34 -0
  70. package/scripts/tot-dev.mjs +16 -3
  71. package/apps/storefront/src/components/commerce/FoxyLoader.astro +0 -23
  72. package/apps/storefront/src/pages/api/dev/activity.ts +0 -124
  73. package/apps/storefront/src/pages/api/dev/cli-signin-code.ts +0 -73
  74. package/apps/storefront/src/pages/api/dev/diff.ts +0 -68
  75. package/apps/storefront/src/pages/api/dev/file.ts +0 -57
  76. package/apps/storefront/src/pages/api/dev/locate.ts +0 -125
  77. package/apps/storefront/src/pages/api/dev/publish.ts +0 -128
  78. package/apps/storefront/src/pages/api/dev/tree.ts +0 -70
  79. package/apps/storefront/src/pages/api/dev/write.ts +0 -116
@@ -1,6 +1,59 @@
1
1
  // @ts-check
2
+ import { readFileSync } from "node:fs";
3
+ import { execFileSync } from "node:child_process";
4
+ import { fileURLToPath } from "node:url";
2
5
  import { defineConfig } from "astro/config";
3
6
  import cloudflare from "@astrojs/cloudflare";
7
+
8
+ // The npm install spec the cockpit hands out for `npm i -g @tokenoftrust/cli`, derived
9
+ // at BUILD time from the CLI version THIS build was cut alongside
10
+ // (packages/cli/package.json). We PIN THE EXACT VERSION rather than a floating dist-tag:
11
+ // this build KNOWS which CLI it expects, so the developer's terminal shouldn't get a vote.
12
+ // A channel (@next/@latest) can silently drift behind (or ahead of) the source — e.g. a
13
+ // stable release moves @latest ahead of a never-republished @next — and the copy-paste then
14
+ // hands out a build that doesn't match this cockpit. Pinning makes the paste reproducible.
15
+ // INVARIANT this introduces: the version in packages/cli/package.json MUST be published to
16
+ // npm before/as this storefront ships, else the pasted `npm i -g @tokenoftrust/cli@<v>` 404s.
17
+ // The CLI publish workflow (.github/workflows/publish-cli.yml) is the publisher; there is no
18
+ // deploy-time guard yet that asserts the embedded version exists on npm — a worthwhile add.
19
+ // NEVER THROWS (like gitSha below): the published RUNNER tree prunes packages/cli, and a
20
+ // bare read here crashed `astro dev` for every standalone invited-dev boot. The runner's
21
+ // local page falls back to the floating spec — only the HOSTED cockpit needs the pin.
22
+ const cliVersion = (() => {
23
+ try {
24
+ return JSON.parse(
25
+ readFileSync(fileURLToPath(new URL("../../packages/cli/package.json", import.meta.url)), "utf8"),
26
+ ).version;
27
+ } catch {
28
+ return null; // standalone runner tree — packages/cli isn't shipped
29
+ }
30
+ })();
31
+ const cliInstallSpec = cliVersion ? `@tokenoftrust/cli@${cliVersion}` : "@tokenoftrust/cli";
32
+
33
+ // The commit THIS build was cut from, baked in at BUILD time so /health can report
34
+ // exactly which code is live (see src/lib/health.ts + src/middleware). Prefer a CI-
35
+ // provided SHA (Workers Builds / GitHub Actions / CF Pages) so the value is right even
36
+ // when the build runs from a shallow/detached checkout; fall back to `git rev-parse`
37
+ // for local deploys. deploy.sh's source guard pins HEAD to origin/<deploySourceBranch>,
38
+ // so on a clean deploy this SHA equals the pushed umbrella tip. Never throws — a build
39
+ // with no git context reports "unknown" rather than failing.
40
+ const gitSha = (() => {
41
+ const fromEnv =
42
+ process.env.GIT_SHA ||
43
+ process.env.WORKERS_CI_COMMIT_SHA ||
44
+ process.env.CF_PAGES_COMMIT_SHA ||
45
+ process.env.GITHUB_SHA;
46
+ if (fromEnv) return fromEnv.trim();
47
+ try {
48
+ return execFileSync("git", ["rev-parse", "HEAD"], {
49
+ cwd: fileURLToPath(new URL(".", import.meta.url)),
50
+ encoding: "utf8",
51
+ }).trim();
52
+ } catch {
53
+ return "unknown";
54
+ }
55
+ })();
56
+
4
57
  import preact from "@astrojs/preact";
5
58
  import tailwindcss from "@tailwindcss/vite";
6
59
  import { tenantHotReload } from "./dev-plugins/tenant-hot-reload.mjs";
@@ -22,6 +75,12 @@ export default defineConfig({
22
75
  }),
23
76
  integrations: [preact({ compat: true })],
24
77
  vite: {
78
+ // Build-time constants: the CLI install spec the cockpit hands out (next vs latest),
79
+ // and this build's commit SHA reported by /health.
80
+ define: {
81
+ __CLI_INSTALL_SPEC__: JSON.stringify(cliInstallSpec),
82
+ __GIT_SHA__: JSON.stringify(gitSha),
83
+ },
25
84
  plugins: [tailwindcss(), tenantHotReload()],
26
85
  optimizeDeps: {
27
86
  // Vite's SSR optimizer can try to prebundle the Cloudflare adapter's
@@ -5,7 +5,7 @@ import type {
5
5
  TenantConfig,
6
6
  CustomizationEnv,
7
7
  TenantFeatures,
8
- ResolvedFoxyCommerce,
8
+ ResolvedManagedCheckout,
9
9
  CapabilityConfig,
10
10
  } from "@tot/public-runtime";
11
11
  import type { ToTClient } from "@/lib/tot/ToTClient";
@@ -52,10 +52,12 @@ interface CloudflareEnv {
52
52
  /** HMAC secret for signing/verifying customization preview tokens (D4). */
53
53
  CUSTOMIZATION_PREVIEW_SECRET?: string;
54
54
  /**
55
- * FoxyCart (Track A). `FOXY_STORE_SUBDOMAIN` overrides the tenant's default
55
+ * Managed checkout (Track A). `FOXY_STORE_SUBDOMAIN` overrides the tenant's default
56
56
  * demo store subdomain (swap the demo store with zero code change).
57
57
  * `FOXY_CART_SECRET` is the store's cart-validation secret for signed mode —
58
58
  * absent in the unsigned demo (validation OFF), present on preview/live.
59
+ * These binding names intentionally stay provider-specific for existing
60
+ * internal developer secrets and provider-side setup.
59
61
  */
60
62
  FOXY_STORE_SUBDOMAIN?: string;
61
63
  /** Branded custom checkout domain override (e.g. checkout.preview.tokenoftrust.com). */
@@ -63,9 +65,8 @@ interface CloudflareEnv {
63
65
  FOXY_CART_SECRET?: string;
64
66
  /**
65
67
  * Order READ API bearer (U2) — the tenant's ToT `partnerApi.apiKey`, sent as
66
- * `Authorization: Bearer` to tot-foxycart `GET /commerce/orders`. Server-side
67
- * only (never shipped to the browser). Absent the Orders route reports
68
- * `not_provisioned` (503).
68
+ * `Authorization: Bearer` to the checkout order API. Server-side only (never
69
+ * shipped to the browser). Absent -> the Orders route reports `not_provisioned`.
69
70
  */
70
71
  FOXY_ORDER_API_KEY?: string;
71
72
  }
@@ -75,6 +76,21 @@ declare global {
75
76
  type KVNamespace = KVNamespaceLike;
76
77
  type R2Bucket = R2BucketLike;
77
78
 
79
+ /**
80
+ * Build-time constant (astro.config.mjs Vite `define`): the npm install spec the
81
+ * cockpit hands out — the EXACT version this build was cut alongside, pinned as
82
+ * `@tokenoftrust/cli@<version>` (never a floating @latest/@next dist-tag), so the
83
+ * pasted command installs precisely the CLI this cockpit expects.
84
+ */
85
+ const __CLI_INSTALL_SPEC__: string;
86
+
87
+ /**
88
+ * Build-time constant (astro.config.mjs Vite `define`): the commit SHA this build
89
+ * was cut from, surfaced by GET /health so a probe reveals exactly which code is
90
+ * live. "unknown" when the build had no git context.
91
+ */
92
+ const __GIT_SHA__: string;
93
+
78
94
  namespace App {
79
95
  interface Locals {
80
96
  /** Tenant resolved from the request Host by src/middleware. */
@@ -116,11 +132,11 @@ declare global {
116
132
  */
117
133
  cspNonce: string;
118
134
  /**
119
- * Resolved FoxyCart cart/checkout facts for this request (loader src, cart
120
- * URL, mode). Present only for commerce tenants with a FoxyCart store;
135
+ * Resolved cart/checkout facts for this request (loader src, cart URL,
136
+ * mode). Present only for commerce tenants with a checkout store;
121
137
  * undefined for marketing tenants or when no store is configured.
122
138
  */
123
- commerce?: ResolvedFoxyCommerce;
139
+ commerce?: ResolvedManagedCheckout;
124
140
  /**
125
141
  * Effective, per-environment capability switches (cart/checkout, age
126
142
  * verification, excise tax) for this request. Resolved from the tenant's
@@ -21,7 +21,7 @@
21
21
  "@astrojs/preact": "^6.0.0",
22
22
  "@storyblok/astro": "^10.0.0",
23
23
  "@tailwindcss/vite": "^4.3.1",
24
- "@tot/public-runtime": "workspace:*",
24
+ "@tot/public-runtime": "*",
25
25
  "astro": "^7.0.3",
26
26
  "fuse.js": "^7.4.2",
27
27
  "jose": "^6.2.3",
@@ -1,58 +1,58 @@
1
1
  ---
2
2
  /**
3
- * <AdminFoxyCartSettingsPanel> — the "Cart & Checkout appearance (FoxyCart)"
4
- * settings section. Mirrors the tot-foxycart settings surface (brand colors,
5
- * per-template-type URLs, store/feature config); each visual field is
3
+ * <AdminCheckoutSettingsPanel> — the "Cart & Checkout appearance" settings
4
+ * section. Mirrors the managed checkout settings surface (brand colors,
5
+ * per-template URLs, store/feature config); each visual field is
6
6
  * prepopulated from the tenant's theme (the style-guide) and can be overridden
7
7
  * or reset back to that theme default.
8
8
  *
9
9
  * Presentational at the current admin altitude: the resolve/override/reset MODEL
10
- * is real (lib/commerce/foxyCartSettings), but SAVE is the tot-foxycart
11
- * `/theme/foxy` PUT/refresh + Foxy color PATCH seam — surfaced, not faked.
10
+ * is real (lib/commerce/checkoutSettings), but SAVE is the commerce-service
11
+ * theme PUT/refresh seam — surfaced, not faked.
12
12
  */
13
- import { getFoxyCartSettingsViewModel } from "@/lib/admin/services/mock";
13
+ import { getCheckoutSettingsViewModel } from "@/lib/admin/services/mock";
14
14
  import { resolveAdminTargetTenant } from "@/config/adminTargetTenant";
15
- import type { FoxyFieldGroup, FoxySettingsField } from "@/lib/commerce/foxyCartSettings";
15
+ import type { CheckoutFieldGroup, CheckoutSettingsField } from "@/lib/commerce/checkoutSettings";
16
16
 
17
17
  const { envelope } = Astro.props;
18
18
  // Resolve the TARGET tenant's config through the resolver seam (config layer),
19
19
  // then build the view model from it — lib never reaches into the static map.
20
20
  const targetTenant = await resolveAdminTargetTenant(envelope.targetTenant);
21
- const vm = getFoxyCartSettingsViewModel(envelope, targetTenant);
21
+ const vm = getCheckoutSettingsViewModel(envelope, targetTenant);
22
22
 
23
- const GROUP_META: Record<FoxyFieldGroup, { title: string; blurb: string }> = {
23
+ const GROUP_META: Record<CheckoutFieldGroup, { title: string; blurb: string }> = {
24
24
  colors: {
25
25
  title: "Brand colors",
26
- blurb: "Foxy template colors, prepopulated from this tenant's theme tokens.",
26
+ blurb: "Hosted checkout colors, prepopulated from this tenant's theme tokens.",
27
27
  },
28
28
  templates: {
29
29
  title: "Templates",
30
- blurb: "Per-surface hosted template URLs (checkout, cart, sidecart, receipt, email).",
30
+ blurb: "Per-surface hosted template URLs (checkout, cart, cart drawer, receipt, email).",
31
31
  },
32
32
  store: {
33
33
  title: "Store & features",
34
34
  blurb: "Store identity and checkout feature toggles. No theme default.",
35
35
  },
36
36
  };
37
- const GROUP_ORDER: FoxyFieldGroup[] = ["colors", "templates", "store"];
38
- const byGroup = (g: FoxyFieldGroup) => vm.fields.filter((f) => f.group === g);
37
+ const GROUP_ORDER: CheckoutFieldGroup[] = ["colors", "templates", "store"];
38
+ const byGroup = (g: CheckoutFieldGroup) => vm.fields.filter((f) => f.group === g);
39
39
 
40
- const isColor = (f: FoxySettingsField) => f.kind === "color";
40
+ const isColor = (f: CheckoutSettingsField) => f.kind === "color";
41
41
  ---
42
42
 
43
43
  <div class="panel" id="settings-cart-appearance">
44
44
  <div class="panel-head settings-panel-head">
45
45
  <h3><svg><use href="#i-gear"></use></svg>Cart &amp; Checkout Appearance</h3>
46
- <span class="chip blue">FoxyCart</span>
46
+ <span class="chip blue">Managed checkout</span>
47
47
  </div>
48
48
 
49
49
  {!vm.hasStore ? (
50
50
  <div class="panel-body">
51
- <p class="note">This tenant has no FoxyCart store configured, so there is nothing to theme here.</p>
51
+ <p class="note">This tenant has no hosted checkout store configured, so there is nothing to theme here.</p>
52
52
  </div>
53
53
  ) : (
54
54
  <div class="panel-body grid">
55
- <div class="fx-head">
55
+ <div class="checkout-head">
56
56
  <p class="note">
57
57
  Values are <b>prepopulated from the theme</b> (the style guide). Override any field, or
58
58
  reset it back to the theme default. {vm.overrideCount > 0 ? `${vm.overrideCount} field(s) currently overridden.` : "No overrides yet."}
@@ -63,24 +63,24 @@ const isColor = (f: FoxySettingsField) => f.kind === "color";
63
63
  </div>
64
64
 
65
65
  {GROUP_ORDER.map((g) => (
66
- <section class="fx-group">
67
- <div class="fx-group-head">
66
+ <section class="checkout-group">
67
+ <div class="checkout-group-head">
68
68
  <h4>{GROUP_META[g].title}</h4>
69
69
  <p>{GROUP_META[g].blurb}</p>
70
70
  </div>
71
- <div class="fx-fields">
71
+ <div class="checkout-fields">
72
72
  {byGroup(g).map((f) => (
73
- <div class="fx-field">
74
- <div class="fx-field-label">
73
+ <div class="checkout-field">
74
+ <div class="checkout-field-label">
75
75
  <label>{f.label}</label>
76
76
  <span class:list={["chip", f.source === "override" ? "amber" : "green"]}>
77
77
  {f.source === "override" ? "Overridden" : "Theme default"}
78
78
  </span>
79
79
  </div>
80
80
 
81
- <div class="fx-field-control">
81
+ <div class="checkout-field-control">
82
82
  {isColor(f) ? (
83
- <span class="fx-swatch" style={`background:${f.value}`} aria-hidden="true"></span>
83
+ <span class="checkout-swatch" style={`background:${f.value}`} aria-hidden="true"></span>
84
84
  ) : null}
85
85
 
86
86
  {f.kind === "boolean" ? (
@@ -96,98 +96,97 @@ const isColor = (f: FoxySettingsField) => f.kind === "color";
96
96
  type="text"
97
97
  value={String(f.value)}
98
98
  readonly
99
- class:list={["fx-input", { url: f.kind === "url" }]}
99
+ class:list={["checkout-input", { url: f.kind === "url" }]}
100
100
  />
101
101
  )}
102
102
 
103
103
  {f.resettable && f.source === "override" ? (
104
- <button class="btn ghost fx-reset" type="button" title={`Reset to theme default: ${f.default}`}>
104
+ <button class="btn ghost checkout-reset" type="button" title={`Reset to theme default: ${f.default}`}>
105
105
  Reset
106
106
  </button>
107
107
  ) : f.resettable ? (
108
- <span class="fx-default-hint">= theme</span>
108
+ <span class="checkout-default-hint">= theme</span>
109
109
  ) : (
110
- <span class="fx-default-hint">no theme default</span>
110
+ <span class="checkout-default-hint">no theme default</span>
111
111
  )}
112
112
  </div>
113
113
 
114
- {f.help ? <p class="fx-help">{f.help}</p> : null}
114
+ {f.help ? <p class="checkout-help">{f.help}</p> : null}
115
115
  </div>
116
116
  ))}
117
117
  </div>
118
118
  </section>
119
119
  ))}
120
120
 
121
- <p class="note fx-seam">
121
+ <p class="note checkout-seam">
122
122
  <svg><use href="#i-alert"></use></svg>
123
- Saving writes to tot-foxycart: colors via Foxy <code>template_config.colors</code>, template
124
- URLs via <code>PUT /theme/foxy</code> then <code>POST /theme/foxy/refresh</code>. That API hop
125
- is not wired in this build.
123
+ Saving updates the managed checkout theme through the commerce service. That API hop is
124
+ not wired in this build.
126
125
  </p>
127
126
  </div>
128
127
  )}
129
128
  </div>
130
129
 
131
130
  <style>
132
- .fx-head {
131
+ .checkout-head {
133
132
  display: flex;
134
133
  gap: 12px;
135
134
  align-items: center;
136
135
  justify-content: space-between;
137
136
  flex-wrap: wrap;
138
137
  }
139
- .fx-group {
138
+ .checkout-group {
140
139
  border-top: 1px solid var(--admin-line);
141
140
  padding-top: 14px;
142
141
  margin-top: 4px;
143
142
  }
144
- .fx-group-head h4 {
143
+ .checkout-group-head h4 {
145
144
  margin: 0;
146
145
  font-size: 13px;
147
146
  }
148
- .fx-group-head p {
147
+ .checkout-group-head p {
149
148
  margin: 2px 0 12px;
150
149
  color: var(--admin-muted);
151
150
  font-size: 12px;
152
151
  }
153
- .fx-fields {
152
+ .checkout-fields {
154
153
  display: grid;
155
154
  gap: 14px;
156
155
  }
157
- .fx-field {
156
+ .checkout-field {
158
157
  display: grid;
159
158
  gap: 6px;
160
159
  padding-bottom: 12px;
161
160
  border-bottom: 1px solid var(--admin-line);
162
161
  }
163
- .fx-field:last-child {
162
+ .checkout-field:last-child {
164
163
  border-bottom: 0;
165
164
  padding-bottom: 0;
166
165
  }
167
- .fx-field-label {
166
+ .checkout-field-label {
168
167
  display: flex;
169
168
  align-items: center;
170
169
  gap: 10px;
171
170
  }
172
- .fx-field-label label {
171
+ .checkout-field-label label {
173
172
  font-size: 13px;
174
173
  font-weight: 640;
175
174
  color: var(--admin-ink);
176
175
  }
177
- .fx-field-control {
176
+ .checkout-field-control {
178
177
  display: flex;
179
178
  align-items: center;
180
179
  gap: 8px;
181
180
  flex-wrap: wrap;
182
181
  }
183
- .fx-swatch {
182
+ .checkout-swatch {
184
183
  width: 26px;
185
184
  height: 26px;
186
185
  border-radius: var(--admin-radius-sm);
187
186
  border: 1px solid var(--admin-line-strong);
188
187
  flex: none;
189
188
  }
190
- .fx-input {
189
+ .checkout-input {
191
190
  min-height: 34px;
192
191
  padding: 0 10px;
193
192
  border: 1px solid var(--admin-line-strong);
@@ -196,31 +195,31 @@ const isColor = (f: FoxySettingsField) => f.kind === "color";
196
195
  color: var(--admin-ink);
197
196
  min-width: 220px;
198
197
  }
199
- .fx-input.url {
198
+ .checkout-input.url {
200
199
  min-width: 340px;
201
200
  font-family: ui-monospace, Menlo, monospace;
202
201
  font-size: 12px;
203
202
  }
204
- .fx-reset {
203
+ .checkout-reset {
205
204
  font-size: 12px;
206
205
  }
207
- .fx-default-hint {
206
+ .checkout-default-hint {
208
207
  color: var(--admin-muted);
209
208
  font-size: 11px;
210
209
  }
211
- .fx-help {
210
+ .checkout-help {
212
211
  margin: 0;
213
212
  color: var(--admin-muted);
214
213
  font-size: 12px;
215
214
  }
216
- .fx-seam {
215
+ .checkout-seam {
217
216
  display: flex;
218
217
  gap: 8px;
219
218
  align-items: flex-start;
220
219
  border-top: 1px solid var(--admin-line);
221
220
  padding-top: 12px;
222
221
  }
223
- .fx-seam code {
222
+ .checkout-seam code {
224
223
  font-family: ui-monospace, Menlo, monospace;
225
224
  font-size: 11px;
226
225
  }
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  import { getSettingsViewModel } from "@/lib/admin/services/mock";
3
- import AdminFoxyCartSettingsPanel from "@/components/admin/AdminFoxyCartSettingsPanel.astro";
3
+ import AdminCheckoutSettingsPanel from "@/components/admin/AdminCheckoutSettingsPanel.astro";
4
4
  import { withBase } from "@/lib/basePath";
5
5
 
6
6
  const { envelope } = Astro.props;
@@ -261,7 +261,7 @@ function formatChangeSummary(change: string): string {
261
261
  </div>
262
262
  </div>
263
263
 
264
- <AdminFoxyCartSettingsPanel envelope={envelope} />
264
+ <AdminCheckoutSettingsPanel envelope={envelope} />
265
265
 
266
266
  <div class="grid cols-2">
267
267
  <div class="panel">