@mohasinac/appkit 4.53.1 → 4.54.0-next.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/.build-stamp.json +5 -5
- package/dist/_internal/client/theme/ThemeProvider.js +15 -1
- package/dist/_internal/server/features/auth/capabilities.js +7 -5
- package/dist/_internal/server/features/categories/price-guidance-resolve.d.ts +66 -0
- package/dist/_internal/server/features/categories/price-guidance-resolve.js +138 -0
- package/dist/_internal/server/features/checkout/supplier-identity.js +28 -6
- package/dist/_internal/server/features/price-index/market.d.ts +57 -0
- package/dist/_internal/server/features/price-index/market.js +120 -0
- package/dist/_internal/server/features/products/list-public.d.ts +12 -0
- package/dist/_internal/server/features/products/list-public.js +10 -1
- package/dist/_internal/server/features/products/listing-tab-counts.d.ts +25 -1
- package/dist/_internal/server/features/products/listing-tab-counts.js +184 -10
- package/dist/_internal/server/features/search/index-build/sources.js +43 -2
- package/dist/_internal/server/features/stores/tabs.d.ts +7 -2
- package/dist/_internal/server/features/stores/tabs.js +5 -3
- package/dist/_internal/server/jobs/core/jobRunners.js +0 -10
- package/dist/_internal/server/jobs/core/onOrderCreate.js +10 -104
- package/dist/_internal/shared/actions/action-registry.d.ts +1 -1
- package/dist/_internal/shared/actions/action-registry.js +128 -0
- package/dist/_internal/shared/features/categories/bundle-copy.d.ts +1 -1
- package/dist/_internal/shared/features/site-settings/supplier-of-record.d.ts +56 -0
- package/dist/_internal/shared/features/site-settings/supplier-of-record.js +57 -0
- package/dist/_internal/shared/listing-types/tiers.d.ts +94 -0
- package/dist/_internal/shared/listing-types/tiers.js +150 -0
- package/dist/_internal/shared/search/match.js +28 -2
- package/dist/cli/index.js +0 -2
- package/dist/client.d.ts +21 -2
- package/dist/client.js +23 -4
- package/dist/constants/api-endpoints.d.ts +28 -0
- package/dist/constants/api-endpoints.js +14 -0
- package/dist/features/account/components/UserOrdersView.js +26 -7
- package/dist/features/addresses/utils/postal-autofill.d.ts +39 -0
- package/dist/features/addresses/utils/postal-autofill.js +54 -0
- package/dist/features/admin/components/AdminStoreEditorView.js +73 -34
- package/dist/features/admin/components/OwnerQuickActions.d.ts +29 -0
- package/dist/features/admin/components/OwnerQuickActions.js +142 -0
- package/dist/features/admin/schemas/admin-editor-forms.d.ts +1 -1
- package/dist/features/admin/schemas/admin-editor-forms.js +4 -1
- package/dist/features/auctions/components/AuctionDetailPageView.js +8 -7
- package/dist/features/auctions/components/MarketplaceAuctionCard.d.ts +11 -1
- package/dist/features/auctions/components/MarketplaceAuctionCard.js +9 -2
- package/dist/features/auth/permissions/constants.d.ts +29 -2
- package/dist/features/auth/permissions/constants.js +68 -1
- package/dist/features/blog/components/BlogFeaturedCard.d.ts +11 -1
- package/dist/features/blog/components/BlogFeaturedCard.js +9 -2
- package/dist/features/cart/components/CartDrawer.js +3 -2
- package/dist/features/cart/components/CartGroupLineRow.js +2 -1
- package/dist/features/cart/hooks/useAddToCart.js +10 -5
- package/dist/features/cart/utils/pending-ops.d.ts +11 -1
- package/dist/features/cart/utils/pending-ops.js +14 -2
- package/dist/features/categories/api/[id]/price-guidance/route.js +1 -24
- package/dist/features/categories/components/BrandDetailPageView.js +15 -6
- package/dist/features/categories/components/BrandDetailTabs.d.ts +7 -1
- package/dist/features/categories/components/BrandDetailTabs.js +18 -3
- package/dist/features/categories/components/BundleCollage.js +3 -2
- package/dist/features/categories/components/BundleItemsPicker.js +3 -4
- package/dist/features/categories/components/CategoryDetailPageView.js +19 -8
- package/dist/features/categories/components/CategoryDetailTabs.d.ts +7 -1
- package/dist/features/categories/components/CategoryDetailTabs.js +29 -7
- package/dist/features/categories/components/CategoryGrid.d.ts +11 -1
- package/dist/features/categories/components/CategoryGrid.js +9 -2
- package/dist/features/checkout/actions/checkout-value-otp-actions.d.ts +10 -5
- package/dist/features/checkout/actions/checkout-value-otp-actions.js +2 -88
- package/dist/features/classified/components/ClassifiedDetailPageView.js +10 -1
- package/dist/features/digital-codes/components/DigitalCodeDetailPageView.js +10 -1
- package/dist/features/events/components/EventCard.d.ts +11 -1
- package/dist/features/events/components/EventCard.js +9 -2
- package/dist/features/layout/AppLayoutShell.js +2 -1
- package/dist/features/layout/BottomActions.d.ts +1 -0
- package/dist/features/layout/BottomActions.js +330 -0
- package/dist/features/layout/BottomChrome.d.ts +45 -0
- package/dist/features/layout/BottomChrome.js +5 -17
- package/dist/features/layout/SideActionDock.js +36 -13
- package/dist/features/layout/index.d.ts +2 -7
- package/dist/features/layout/index.js +7 -7
- package/dist/features/layout/useIsDesktop.d.ts +36 -0
- package/dist/features/layout/useIsDesktop.js +48 -0
- package/dist/features/live/components/LiveItemDetailPageView.js +10 -1
- package/dist/features/media/messages/en.json +67 -67
- package/dist/features/orders/components/YourPurchaseStrip.d.ts +24 -0
- package/dist/features/orders/components/YourPurchaseStrip.js +77 -0
- package/dist/features/orders/components/index.d.ts +2 -1
- package/dist/features/orders/components/index.js +1 -1
- package/dist/features/orders/utils/order-announcement-message.d.ts +18 -0
- package/dist/features/orders/utils/order-announcement-message.js +16 -0
- package/dist/features/orders/utils/payment-proof-message.d.ts +20 -0
- package/dist/features/orders/utils/payment-proof-message.js +17 -0
- package/dist/features/parts/schemas/firestore.d.ts +227 -0
- package/dist/features/parts/schemas/firestore.js +6 -6
- package/dist/features/pre-orders/components/MarketplacePreorderCard.d.ts +11 -1
- package/dist/features/pre-orders/components/MarketplacePreorderCard.js +10 -3
- package/dist/features/pre-orders/components/PreOrderDetailPageView.js +8 -7
- package/dist/features/price-index/components/PriceIndexToolView.d.ts +21 -0
- package/dist/features/price-index/components/PriceIndexToolView.js +230 -27
- package/dist/features/price-index/lookup-target.d.ts +48 -0
- package/dist/features/price-index/lookup-target.js +107 -0
- package/dist/features/products/api/[id]/route.js +8 -1
- package/dist/features/products/api/route.js +16 -4
- package/dist/features/products/components/AvailabilityScopeHint.d.ts +22 -0
- package/dist/features/products/components/AvailabilityScopeHint.js +27 -0
- package/dist/features/products/components/CompareOverlay.d.ts +2 -1
- package/dist/features/products/components/CompareOverlay.js +2 -1
- package/dist/features/products/components/GroupSettingsPanel.js +2 -1
- package/dist/features/products/components/InteractiveProductCard.d.ts +7 -1
- package/dist/features/products/components/InteractiveProductCard.js +16 -4
- package/dist/features/products/components/MarketplaceBundleCard.d.ts +11 -1
- package/dist/features/products/components/MarketplaceBundleCard.js +9 -2
- package/dist/features/products/components/MarketplacePrizeDrawCard.d.ts +11 -1
- package/dist/features/products/components/MarketplacePrizeDrawCard.js +9 -2
- package/dist/features/products/components/ProductDetailPageView.js +34 -4
- package/dist/features/products/components/ProductGrid.d.ts +14 -1
- package/dist/features/products/components/ProductGrid.js +22 -5
- package/dist/features/products/components/ProductsIndexListing.js +2 -2
- package/dist/features/products/components/SublistingCarouselSection.js +2 -1
- package/dist/features/products/repository/products.repository.d.ts +1 -0
- package/dist/features/products/repository/products.repository.js +5 -1
- package/dist/features/products/utils/group-member-image.d.ts +9 -2
- package/dist/features/products/utils/group-member-image.js +2 -1
- package/dist/features/reviews/api/[id]/route.js +83 -23
- package/dist/features/reviews/components/PurchaseReviewAffordance.d.ts +6 -0
- package/dist/features/reviews/components/PurchaseReviewAffordance.js +42 -0
- package/dist/features/reviews/components/ReviewFormDrawer.d.ts +34 -0
- package/dist/features/reviews/components/ReviewFormDrawer.js +127 -0
- package/dist/features/reviews/components/index.d.ts +4 -0
- package/dist/features/reviews/components/index.js +2 -0
- package/dist/features/seller/actions/seller-actions.d.ts +1 -1
- package/dist/features/seller/actions/seller-actions.js +49 -3
- package/dist/features/seller/components/SellerPayoutSettingsView.js +30 -2
- package/dist/features/seller/components/SellerProductShell.d.ts +17 -1
- package/dist/features/seller/components/SellerProductsView.js +3 -2
- package/dist/features/seller/hooks/useStoreListingEntitlements.d.ts +8 -0
- package/dist/features/seller/hooks/useStoreListingEntitlements.js +70 -0
- package/dist/features/stores/components/InteractiveStoreCard.d.ts +11 -1
- package/dist/features/stores/components/InteractiveStoreCard.js +9 -2
- package/dist/features/stores/components/StoreAuctionsListing.js +2 -1
- package/dist/features/stores/components/index.d.ts +0 -2
- package/dist/features/stores/components/index.js +0 -1
- package/dist/features/stores/schemas/index.d.ts +1 -1
- package/dist/features/stores/schemas/index.js +10 -1
- package/dist/features/tester/seed-data/authored/content-discovery__authenticity-checker.js +114 -2
- package/dist/features/tester/seed-data/tester-checklist-seed-data.js +415 -0
- package/dist/index.d.ts +8 -27
- package/dist/index.js +14 -35
- package/dist/next/routing/route-map.d.ts +2 -0
- package/dist/next/routing/route-map.js +9 -0
- package/dist/providers/shipping-shiprocket/index.d.ts +98 -0
- package/dist/providers/shipping-shiprocket/index.js +353 -0
- package/dist/schemas/registry.d.ts +2 -2
- package/dist/security/csp.d.ts +16 -1
- package/dist/security/csp.js +5 -3
- package/dist/seed/_helpers/category-forest.js +27 -0
- package/dist/seed/_helpers/category-parts-glossary-map.js +1816 -86
- package/dist/seed/_helpers/category-parts.d.ts +1 -1
- package/dist/seed/_helpers/category-parts.js +13412 -3020
- package/dist/seed/categories-seed-data.js +48 -6
- package/dist/seed/homepage-sections-seed-data.js +41 -28
- package/dist/seed/model-composition-seed-data.js +6 -8
- package/dist/seed/part-glossary/chunk0.d.ts +9 -0
- package/dist/seed/part-glossary/chunk0.js +35044 -0
- package/dist/seed/part-glossary/chunk1.d.ts +9 -0
- package/dist/seed/part-glossary/chunk1.js +39955 -0
- package/dist/seed/part-glossary/chunk2.d.ts +9 -0
- package/dist/seed/part-glossary/chunk2.js +50335 -0
- package/dist/seed/part-glossary/chunk3.d.ts +9 -0
- package/dist/seed/part-glossary/chunk3.js +52386 -0
- package/dist/seed/part-glossary/chunk4.d.ts +9 -0
- package/dist/seed/part-glossary/chunk4.js +50549 -0
- package/dist/seed/part-glossary-seed-data.d.ts +1 -1
- package/dist/seed/part-glossary-seed-data.js +23 -47483
- package/dist/seed/products-beyblade-x-seed-data.js +36 -1
- package/dist/server.d.ts +6 -8
- package/dist/server.js +16 -20
- package/dist/styles.css +516 -358
- package/dist/tailwind-utilities.css +1 -1
- package/dist/tokens/themes/index.d.ts +3 -1
- package/dist/tokens/themes/index.js +11 -1
- package/dist/tokens/themes/technical-dark.d.ts +30 -0
- package/dist/tokens/themes/technical-dark.js +103 -0
- package/dist/tokens/themes/technical-light.d.ts +22 -0
- package/dist/tokens/themes/technical-light.js +89 -0
- package/dist/tokens/tokens.css +155 -0
- package/dist/ui/components/GatedPrice.js +30 -3
- package/dist/ui/components/GatedPrice.style.css +22 -19
- package/dist/ui/components/QuickCreateModal.style.css +78 -78
- package/dist/ui/forms/FormShell.style.css +260 -260
- package/package.json +1 -1
- package/scripts/seed-cli.mjs +133 -27
- package/dist/_internal/server/jobs/core/whatsappCatalogImport.d.ts +0 -27
- package/dist/_internal/server/jobs/core/whatsappCatalogImport.js +0 -172
- package/dist/_internal/server/jobs/core/whatsappNotify.d.ts +0 -35
- package/dist/_internal/server/jobs/core/whatsappNotify.js +0 -140
- package/dist/features/admin/components/AdminWhatsAppGuideView.d.ts +0 -2
- package/dist/features/admin/components/AdminWhatsAppGuideView.js +0 -35
- package/dist/features/orders/components/MarketplaceOrderCard.d.ts +0 -36
- package/dist/features/orders/components/MarketplaceOrderCard.js +0 -57
- package/dist/features/stores/components/StoreWhatsAppGuideView.d.ts +0 -3
- package/dist/features/stores/components/StoreWhatsAppGuideView.js +0 -12
- package/dist/features/whatsapp-bot/api/send-status/route.d.ts +0 -12
- package/dist/features/whatsapp-bot/api/send-status/route.js +0 -38
- package/dist/features/whatsapp-bot/api/webhook/route.d.ts +0 -12
- package/dist/features/whatsapp-bot/api/webhook/route.js +0 -43
- package/dist/features/whatsapp-bot/components/SellerWhatsAppSettingsView.d.ts +0 -6
- package/dist/features/whatsapp-bot/components/SellerWhatsAppSettingsView.js +0 -270
- package/dist/features/whatsapp-bot/components/WhatsAppChatButton.d.ts +0 -9
- package/dist/features/whatsapp-bot/components/WhatsAppChatButton.js +0 -7
- package/dist/features/whatsapp-bot/components/index.d.ts +0 -3
- package/dist/features/whatsapp-bot/components/index.js +0 -2
- package/dist/features/whatsapp-bot/helpers/payment-proof-message.d.ts +0 -14
- package/dist/features/whatsapp-bot/helpers/payment-proof-message.js +0 -17
- package/dist/features/whatsapp-bot/helpers/whatsapp.d.ts +0 -52
- package/dist/features/whatsapp-bot/helpers/whatsapp.js +0 -283
- package/dist/features/whatsapp-bot/index.d.ts +0 -3
- package/dist/features/whatsapp-bot/index.js +0 -3
- package/dist/features/whatsapp-bot/manifest.d.ts +0 -2
- package/dist/features/whatsapp-bot/manifest.js +0 -13
- package/dist/features/whatsapp-bot/messages/en.json +0 -7
- package/dist/features/whatsapp-bot/server.d.ts +0 -7
- package/dist/features/whatsapp-bot/server.js +0 -7
- package/dist/features/whatsapp-bot/types/index.d.ts +0 -126
- package/dist/features/whatsapp-bot/types/index.js +0 -1
|
@@ -2,8 +2,10 @@ import { DEFAULT_DARK_THEME } from "./default-dark";
|
|
|
2
2
|
import { DEFAULT_LIGHT_THEME } from "./default-light";
|
|
3
3
|
import { COBALT_NIGHT_THEME } from "./cobalt-night";
|
|
4
4
|
import { SUNSET_THEME } from "./sunset";
|
|
5
|
+
import { TECHNICAL_DARK_THEME } from "./technical-dark";
|
|
6
|
+
import { TECHNICAL_LIGHT_THEME } from "./technical-light";
|
|
5
7
|
import type { ThemeMode, ThemeRecord } from "./types";
|
|
6
|
-
export { DEFAULT_LIGHT_THEME, DEFAULT_DARK_THEME, COBALT_NIGHT_THEME, SUNSET_THEME };
|
|
8
|
+
export { DEFAULT_LIGHT_THEME, DEFAULT_DARK_THEME, COBALT_NIGHT_THEME, SUNSET_THEME, TECHNICAL_DARK_THEME, TECHNICAL_LIGHT_THEME, };
|
|
7
9
|
export { REQUIRED_GRADIENT_KEYS, REQUIRED_THEME_TOKENS } from "./required";
|
|
8
10
|
export type { RequiredThemeToken } from "./required";
|
|
9
11
|
export type { GradientKey, ThemeMode, ThemeRecord } from "./types";
|
|
@@ -2,7 +2,9 @@ import { DEFAULT_DARK_THEME } from "./default-dark.js";
|
|
|
2
2
|
import { DEFAULT_LIGHT_THEME } from "./default-light.js";
|
|
3
3
|
import { COBALT_NIGHT_THEME } from "./cobalt-night.js";
|
|
4
4
|
import { SUNSET_THEME } from "./sunset.js";
|
|
5
|
-
|
|
5
|
+
import { TECHNICAL_DARK_THEME } from "./technical-dark.js";
|
|
6
|
+
import { TECHNICAL_LIGHT_THEME } from "./technical-light.js";
|
|
7
|
+
export { DEFAULT_LIGHT_THEME, DEFAULT_DARK_THEME, COBALT_NIGHT_THEME, SUNSET_THEME, TECHNICAL_DARK_THEME, TECHNICAL_LIGHT_THEME, };
|
|
6
8
|
export { REQUIRED_GRADIENT_KEYS, REQUIRED_THEME_TOKENS } from "./required.js";
|
|
7
9
|
/** Built-in themes that ship with appkit; admin cannot delete these. */
|
|
8
10
|
export const BUILT_IN_THEMES = [
|
|
@@ -17,6 +19,14 @@ export const BUILT_IN_THEMES = [
|
|
|
17
19
|
export const THEME_TEMPLATES = [
|
|
18
20
|
COBALT_NIGHT_THEME,
|
|
19
21
|
SUNSET_THEME,
|
|
22
|
+
/*
|
|
23
|
+
* Technical Dark / Light — a developer-tool identity: graphite surfaces,
|
|
24
|
+
* hairline borders, a mono-forward type stack and syntax-palette accents
|
|
25
|
+
* reused semantically (difficulty badges, submission verdicts, status chips).
|
|
26
|
+
* Shipped as a matched PAIR so switching mode does not change identity.
|
|
27
|
+
*/
|
|
28
|
+
TECHNICAL_DARK_THEME,
|
|
29
|
+
TECHNICAL_LIGHT_THEME,
|
|
20
30
|
];
|
|
21
31
|
/**
|
|
22
32
|
* Find the default built-in theme for a given mode.
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { ThemeRecord } from "./types";
|
|
2
|
+
/**
|
|
3
|
+
* Theme template — Technical Dark.
|
|
4
|
+
*
|
|
5
|
+
* A developer-tool identity rather than a marketing one: a near-black graphite
|
|
6
|
+
* base, ONE elevation step, hairline borders, and accents drawn from a syntax
|
|
7
|
+
* palette (keyword violet, string green, number amber, error red) reused
|
|
8
|
+
* semantically for difficulty badges, submission verdicts and status chips.
|
|
9
|
+
*
|
|
10
|
+
* Deliberately different from `default-dark` (crimson + cyan on navy): there is
|
|
11
|
+
* no brand gradient wash, surfaces sit close together in luminance, and the
|
|
12
|
+
* type stack is mono-forward — `display`/`sans` are monospace for headings,
|
|
13
|
+
* labels, IDs and tables, while `editorial` carries a real reading face so
|
|
14
|
+
* 2,000-word lessons stay comfortable. That three-slot split is why no separate
|
|
15
|
+
* "prose font" token was needed.
|
|
16
|
+
*
|
|
17
|
+
* Not a built-in (`builtIn: false`) — seeded as a selectable template that an
|
|
18
|
+
* admin can assign as the default dark theme or clone from `ThemeManagerView`.
|
|
19
|
+
* Only overrides the tokens the matching CSS block overrides; everything else
|
|
20
|
+
* (spacing, font sizes, unredefined gradients) falls back to
|
|
21
|
+
* `DEFAULT_DARK_THEME`, the same way the CSS block cascades from `:root`.
|
|
22
|
+
*
|
|
23
|
+
* Contrast against `appkit-color-bg` (#0b0d10), measured not estimated:
|
|
24
|
+
* text 15.82:1, muted 7.72:1, faint 4.68:1, primary 6.53:1, and every status
|
|
25
|
+
* colour ≥ 4.5:1 (lowest: error 7.01:1). Nothing here is AA-large-only.
|
|
26
|
+
*
|
|
27
|
+
* Mirrors the `[data-theme="technical-dark"]` block in
|
|
28
|
+
* `appkit/src/tokens/tokens.css`; the two must stay byte-identical.
|
|
29
|
+
*/
|
|
30
|
+
export declare const TECHNICAL_DARK_THEME: ThemeRecord;
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { DEFAULT_DARK_THEME } from "./default-dark.js";
|
|
2
|
+
/**
|
|
3
|
+
* Theme template — Technical Dark.
|
|
4
|
+
*
|
|
5
|
+
* A developer-tool identity rather than a marketing one: a near-black graphite
|
|
6
|
+
* base, ONE elevation step, hairline borders, and accents drawn from a syntax
|
|
7
|
+
* palette (keyword violet, string green, number amber, error red) reused
|
|
8
|
+
* semantically for difficulty badges, submission verdicts and status chips.
|
|
9
|
+
*
|
|
10
|
+
* Deliberately different from `default-dark` (crimson + cyan on navy): there is
|
|
11
|
+
* no brand gradient wash, surfaces sit close together in luminance, and the
|
|
12
|
+
* type stack is mono-forward — `display`/`sans` are monospace for headings,
|
|
13
|
+
* labels, IDs and tables, while `editorial` carries a real reading face so
|
|
14
|
+
* 2,000-word lessons stay comfortable. That three-slot split is why no separate
|
|
15
|
+
* "prose font" token was needed.
|
|
16
|
+
*
|
|
17
|
+
* Not a built-in (`builtIn: false`) — seeded as a selectable template that an
|
|
18
|
+
* admin can assign as the default dark theme or clone from `ThemeManagerView`.
|
|
19
|
+
* Only overrides the tokens the matching CSS block overrides; everything else
|
|
20
|
+
* (spacing, font sizes, unredefined gradients) falls back to
|
|
21
|
+
* `DEFAULT_DARK_THEME`, the same way the CSS block cascades from `:root`.
|
|
22
|
+
*
|
|
23
|
+
* Contrast against `appkit-color-bg` (#0b0d10), measured not estimated:
|
|
24
|
+
* text 15.82:1, muted 7.72:1, faint 4.68:1, primary 6.53:1, and every status
|
|
25
|
+
* colour ≥ 4.5:1 (lowest: error 7.01:1). Nothing here is AA-large-only.
|
|
26
|
+
*
|
|
27
|
+
* Mirrors the `[data-theme="technical-dark"]` block in
|
|
28
|
+
* `appkit/src/tokens/tokens.css`; the two must stay byte-identical.
|
|
29
|
+
*/
|
|
30
|
+
export const TECHNICAL_DARK_THEME = {
|
|
31
|
+
id: "technical-dark",
|
|
32
|
+
name: "Technical Dark",
|
|
33
|
+
mode: "dark",
|
|
34
|
+
builtIn: false,
|
|
35
|
+
tokens: {
|
|
36
|
+
// Brand — keyword violet. Chosen because it reads as "syntax", not
|
|
37
|
+
// "product", and sits far from every status hue below.
|
|
38
|
+
"appkit-color-primary": "#7c8cff",
|
|
39
|
+
"appkit-color-primary-50": "#eef0ff",
|
|
40
|
+
"appkit-color-primary-100": "#e0e4ff",
|
|
41
|
+
"appkit-color-primary-200": "#c7cdff",
|
|
42
|
+
"appkit-color-primary-300": "#a5aeff",
|
|
43
|
+
"appkit-color-primary-400": "#8e99ff",
|
|
44
|
+
"appkit-color-primary-500": "#7c8cff",
|
|
45
|
+
"appkit-color-primary-600": "#5a68e8",
|
|
46
|
+
"appkit-color-primary-700": "#4650c4",
|
|
47
|
+
"appkit-color-primary-800": "#373f9c",
|
|
48
|
+
"appkit-color-primary-900": "#2b317a",
|
|
49
|
+
"appkit-color-primary-950": "#171a45",
|
|
50
|
+
// Secondary — string green.
|
|
51
|
+
"appkit-color-secondary": "#56d39a",
|
|
52
|
+
"appkit-color-secondary-50": "#ecfdf5",
|
|
53
|
+
"appkit-color-secondary-100": "#d1fae5",
|
|
54
|
+
"appkit-color-secondary-200": "#a7f3d0",
|
|
55
|
+
"appkit-color-secondary-300": "#7ee7b8",
|
|
56
|
+
"appkit-color-secondary-400": "#56d39a",
|
|
57
|
+
"appkit-color-secondary-500": "#34b87d",
|
|
58
|
+
"appkit-color-secondary-600": "#1f9664",
|
|
59
|
+
"appkit-color-secondary-700": "#187752",
|
|
60
|
+
"appkit-color-secondary-800": "#155e42",
|
|
61
|
+
"appkit-color-secondary-900": "#124b36",
|
|
62
|
+
"appkit-color-secondary-950": "#062a1d",
|
|
63
|
+
// Surfaces — one elevation step, hairline borders. Editor chrome.
|
|
64
|
+
"appkit-color-bg": "#0b0d10",
|
|
65
|
+
"appkit-color-surface": "#13161b",
|
|
66
|
+
"appkit-color-surface-elevated": "rgba(19, 22, 27, 0.92)",
|
|
67
|
+
"appkit-color-surface-input": "rgba(27, 31, 38, 0.7)",
|
|
68
|
+
"appkit-color-surface-hover": "rgba(148, 163, 184, 0.1)",
|
|
69
|
+
"appkit-color-surface-raised": "rgba(27, 31, 38, 0.8)",
|
|
70
|
+
"appkit-color-primary-surface": "rgba(124, 140, 255, 0.16)",
|
|
71
|
+
"appkit-color-border": "#242a33",
|
|
72
|
+
"appkit-color-border-subtle": "rgba(36, 42, 51, 0.6)",
|
|
73
|
+
"appkit-color-text": "#e4e8ee",
|
|
74
|
+
"appkit-color-text-muted": "#9aa4b2",
|
|
75
|
+
// 4.68:1 — clears AA at body size, so faint metadata is still readable
|
|
76
|
+
// rather than merely decorative.
|
|
77
|
+
"appkit-color-text-faint": "#747d8c",
|
|
78
|
+
// Dark ink on the violet fill: 6.53:1, where white measures only 2.98:1
|
|
79
|
+
// and would fail. This is why primary is not simply paired with white.
|
|
80
|
+
"appkit-color-text-on-primary": "#0b0d10",
|
|
81
|
+
"appkit-color-success": "#4ade80",
|
|
82
|
+
"appkit-color-success-surface": "rgba(22, 101, 68, 0.22)",
|
|
83
|
+
"appkit-color-warning": "#f2b544",
|
|
84
|
+
"appkit-color-warning-surface": "rgba(120, 78, 10, 0.22)",
|
|
85
|
+
"appkit-color-error": "#ff6b6b",
|
|
86
|
+
"appkit-color-error-surface": "rgba(140, 30, 30, 0.22)",
|
|
87
|
+
"appkit-color-info": "#58b4ff",
|
|
88
|
+
"appkit-color-info-surface": "rgba(12, 74, 110, 0.22)",
|
|
89
|
+
// Amber, deliberately NOT any status or brand hue: a focus ring that
|
|
90
|
+
// doubles as an error colour is unreadable on an invalid field.
|
|
91
|
+
"appkit-color-focus-ring": "#ffb86b",
|
|
92
|
+
// Flatter than the default theme's glow — editor chrome, not neon.
|
|
93
|
+
"appkit-shadow-glow": "0 0 0 1px rgba(124,140,255,0.14), 0 4px 16px -6px rgba(124,140,255,0.2)",
|
|
94
|
+
"appkit-shadow-glow-pink": "0 0 0 1px rgba(86,211,154,0.14), 0 4px 18px -6px rgba(86,211,154,0.22)",
|
|
95
|
+
// Mono-forward: headings, labels, IDs, nav and tables are monospace;
|
|
96
|
+
// `editorial` is the reading face for lessons and blog prose.
|
|
97
|
+
"appkit-font-display": "var(--font-mono), \"JetBrains Mono\", \"IBM Plex Mono\", ui-monospace, \"SFMono-Regular\", Consolas, monospace",
|
|
98
|
+
"appkit-font-sans": "var(--font-mono), \"JetBrains Mono\", \"IBM Plex Mono\", ui-monospace, \"SFMono-Regular\", Consolas, monospace",
|
|
99
|
+
"appkit-font-editorial": "var(--font-body), ui-sans-serif, system-ui, -apple-system, \"Segoe UI\", Roboto, sans-serif",
|
|
100
|
+
"appkit-font-mono": "var(--font-mono), \"JetBrains Mono\", \"IBM Plex Mono\", ui-monospace, \"SFMono-Regular\", Consolas, monospace",
|
|
101
|
+
},
|
|
102
|
+
gradients: { ...DEFAULT_DARK_THEME.gradients },
|
|
103
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { ThemeRecord } from "./types";
|
|
2
|
+
/**
|
|
3
|
+
* Theme template — Technical Light.
|
|
4
|
+
*
|
|
5
|
+
* A true counterpart to `technical-dark`, not an afterthought: same geometry,
|
|
6
|
+
* same mono-forward type stack, same syntax-derived accent *roles* — but every
|
|
7
|
+
* accent is re-darkened for a paper-white ground rather than reused from the
|
|
8
|
+
* dark preset. Reusing them would have been the easy mistake: #7c8cff on
|
|
9
|
+
* #fbfbfa measures 2.88:1, which fails AA outright, so primary drops to
|
|
10
|
+
* #4b5bd6 (5.38:1) and each status hue is darkened to match.
|
|
11
|
+
*
|
|
12
|
+
* Not a built-in (`builtIn: false`). Only overrides the tokens the matching CSS
|
|
13
|
+
* block overrides; everything else falls back to `DEFAULT_LIGHT_THEME`.
|
|
14
|
+
*
|
|
15
|
+
* Contrast against `appkit-color-bg` (#fbfbfa), measured not estimated:
|
|
16
|
+
* text 17.15:1, muted 5.84:1, faint 4.67:1, primary 5.38:1, white-on-primary
|
|
17
|
+
* 5.58:1, and every status colour ≥ 4.5:1 (lowest: success 4.80:1).
|
|
18
|
+
*
|
|
19
|
+
* Mirrors the `[data-theme="technical-light"]` block in
|
|
20
|
+
* `appkit/src/tokens/tokens.css`; the two must stay byte-identical.
|
|
21
|
+
*/
|
|
22
|
+
export declare const TECHNICAL_LIGHT_THEME: ThemeRecord;
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { DEFAULT_LIGHT_THEME } from "./default-light.js";
|
|
2
|
+
/**
|
|
3
|
+
* Theme template — Technical Light.
|
|
4
|
+
*
|
|
5
|
+
* A true counterpart to `technical-dark`, not an afterthought: same geometry,
|
|
6
|
+
* same mono-forward type stack, same syntax-derived accent *roles* — but every
|
|
7
|
+
* accent is re-darkened for a paper-white ground rather than reused from the
|
|
8
|
+
* dark preset. Reusing them would have been the easy mistake: #7c8cff on
|
|
9
|
+
* #fbfbfa measures 2.88:1, which fails AA outright, so primary drops to
|
|
10
|
+
* #4b5bd6 (5.38:1) and each status hue is darkened to match.
|
|
11
|
+
*
|
|
12
|
+
* Not a built-in (`builtIn: false`). Only overrides the tokens the matching CSS
|
|
13
|
+
* block overrides; everything else falls back to `DEFAULT_LIGHT_THEME`.
|
|
14
|
+
*
|
|
15
|
+
* Contrast against `appkit-color-bg` (#fbfbfa), measured not estimated:
|
|
16
|
+
* text 17.15:1, muted 5.84:1, faint 4.67:1, primary 5.38:1, white-on-primary
|
|
17
|
+
* 5.58:1, and every status colour ≥ 4.5:1 (lowest: success 4.80:1).
|
|
18
|
+
*
|
|
19
|
+
* Mirrors the `[data-theme="technical-light"]` block in
|
|
20
|
+
* `appkit/src/tokens/tokens.css`; the two must stay byte-identical.
|
|
21
|
+
*/
|
|
22
|
+
export const TECHNICAL_LIGHT_THEME = {
|
|
23
|
+
id: "technical-light",
|
|
24
|
+
name: "Technical Light",
|
|
25
|
+
mode: "light",
|
|
26
|
+
builtIn: false,
|
|
27
|
+
tokens: {
|
|
28
|
+
// Same violet ROLE as the dark preset, re-darkened for white.
|
|
29
|
+
"appkit-color-primary": "#4b5bd6",
|
|
30
|
+
"appkit-color-primary-50": "#eef0ff",
|
|
31
|
+
"appkit-color-primary-100": "#e0e4ff",
|
|
32
|
+
"appkit-color-primary-200": "#c7cdff",
|
|
33
|
+
"appkit-color-primary-300": "#a5aeff",
|
|
34
|
+
"appkit-color-primary-400": "#7c8cff",
|
|
35
|
+
"appkit-color-primary-500": "#5a68e8",
|
|
36
|
+
"appkit-color-primary-600": "#4b5bd6",
|
|
37
|
+
"appkit-color-primary-700": "#3b45ad",
|
|
38
|
+
"appkit-color-primary-800": "#2f3789",
|
|
39
|
+
"appkit-color-primary-900": "#262c6d",
|
|
40
|
+
"appkit-color-primary-950": "#151840",
|
|
41
|
+
"appkit-color-secondary": "#0f8f5f",
|
|
42
|
+
"appkit-color-secondary-50": "#ecfdf5",
|
|
43
|
+
"appkit-color-secondary-100": "#d1fae5",
|
|
44
|
+
"appkit-color-secondary-200": "#a7f3d0",
|
|
45
|
+
"appkit-color-secondary-300": "#6ee7b7",
|
|
46
|
+
"appkit-color-secondary-400": "#34b87d",
|
|
47
|
+
"appkit-color-secondary-500": "#0f8f5f",
|
|
48
|
+
"appkit-color-secondary-600": "#0c744d",
|
|
49
|
+
"appkit-color-secondary-700": "#0a5c3d",
|
|
50
|
+
"appkit-color-secondary-800": "#084830",
|
|
51
|
+
"appkit-color-secondary-900": "#063a27",
|
|
52
|
+
"appkit-color-secondary-950": "#032016",
|
|
53
|
+
// Paper white, not pure #fff — pure white against a mono type stack
|
|
54
|
+
// glares at the sizes this UI uses.
|
|
55
|
+
"appkit-color-bg": "#fbfbfa",
|
|
56
|
+
"appkit-color-surface": "#ffffff",
|
|
57
|
+
"appkit-color-surface-elevated": "rgba(255, 255, 255, 0.96)",
|
|
58
|
+
"appkit-color-surface-input": "rgba(244, 244, 242, 0.8)",
|
|
59
|
+
"appkit-color-surface-hover": "rgba(22, 24, 29, 0.05)",
|
|
60
|
+
"appkit-color-surface-raised": "rgba(244, 244, 242, 0.9)",
|
|
61
|
+
"appkit-color-primary-surface": "rgba(75, 91, 214, 0.1)",
|
|
62
|
+
"appkit-color-border": "#e2e2df",
|
|
63
|
+
"appkit-color-border-subtle": "rgba(226, 226, 223, 0.7)",
|
|
64
|
+
"appkit-color-text": "#16181d",
|
|
65
|
+
"appkit-color-text-muted": "#5c6370",
|
|
66
|
+
// #767d89 measured 4.00:1 here — AA for large text only. Darkened so even
|
|
67
|
+
// faint metadata clears AA at body size.
|
|
68
|
+
"appkit-color-text-faint": "#6b7280",
|
|
69
|
+
"appkit-color-text-on-primary": "#ffffff",
|
|
70
|
+
"appkit-color-success": "#13804f",
|
|
71
|
+
"appkit-color-success-surface": "rgba(19, 128, 79, 0.1)",
|
|
72
|
+
"appkit-color-warning": "#9a6400",
|
|
73
|
+
"appkit-color-warning-surface": "rgba(154, 100, 0, 0.1)",
|
|
74
|
+
"appkit-color-error": "#c62828",
|
|
75
|
+
"appkit-color-error-surface": "rgba(198, 40, 40, 0.1)",
|
|
76
|
+
"appkit-color-info": "#0a69b5",
|
|
77
|
+
"appkit-color-info-surface": "rgba(10, 105, 181, 0.1)",
|
|
78
|
+
// Darkened amber. The dark preset's #ffb86b measures 1.65:1 here —
|
|
79
|
+
// effectively an invisible focus ring, which is a keyboard trap.
|
|
80
|
+
"appkit-color-focus-ring": "#b45a00",
|
|
81
|
+
"appkit-shadow-glow": "0 0 0 1px rgba(75,91,214,0.14), 0 4px 16px -6px rgba(75,91,214,0.18)",
|
|
82
|
+
"appkit-shadow-glow-pink": "0 0 0 1px rgba(15,143,95,0.14), 0 4px 18px -6px rgba(15,143,95,0.2)",
|
|
83
|
+
"appkit-font-display": "var(--font-mono), \"JetBrains Mono\", \"IBM Plex Mono\", ui-monospace, \"SFMono-Regular\", Consolas, monospace",
|
|
84
|
+
"appkit-font-sans": "var(--font-mono), \"JetBrains Mono\", \"IBM Plex Mono\", ui-monospace, \"SFMono-Regular\", Consolas, monospace",
|
|
85
|
+
"appkit-font-editorial": "var(--font-body), ui-sans-serif, system-ui, -apple-system, \"Segoe UI\", Roboto, sans-serif",
|
|
86
|
+
"appkit-font-mono": "var(--font-mono), \"JetBrains Mono\", \"IBM Plex Mono\", ui-monospace, \"SFMono-Regular\", Consolas, monospace",
|
|
87
|
+
},
|
|
88
|
+
gradients: { ...DEFAULT_LIGHT_THEME.gradients },
|
|
89
|
+
};
|
package/dist/tokens/tokens.css
CHANGED
|
@@ -628,6 +628,161 @@
|
|
|
628
628
|
--appkit-shadow-glow-pink: 0 0 0 1px rgba(244,63,94,0.18), 0 4px 20px -4px rgba(244,63,94,0.30);
|
|
629
629
|
}
|
|
630
630
|
|
|
631
|
+
/* --- Theme — Technical Dark ([data-theme="technical-dark"]) --------------- */
|
|
632
|
+
/* Developer-tool identity: graphite surfaces, hairline borders, a mono-forward
|
|
633
|
+
type stack, and accents from a syntax palette (keyword violet, string green,
|
|
634
|
+
number amber, error red) reused semantically for difficulty badges,
|
|
635
|
+
submission verdicts and status chips.
|
|
636
|
+
|
|
637
|
+
Mirrors src/tokens/themes/technical-dark.ts — values must stay identical or
|
|
638
|
+
the first paint disagrees with the hydrated theme.
|
|
639
|
+
|
|
640
|
+
Contrast on --appkit-color-bg (#0b0d10), measured: text 15.82:1,
|
|
641
|
+
muted 7.72:1, faint 4.68:1, primary 6.53:1, lowest status 7.01:1. */
|
|
642
|
+
[data-theme="technical-dark"] {
|
|
643
|
+
--appkit-color-primary: #7c8cff;
|
|
644
|
+
--appkit-color-primary-50: #eef0ff;
|
|
645
|
+
--appkit-color-primary-100: #e0e4ff;
|
|
646
|
+
--appkit-color-primary-200: #c7cdff;
|
|
647
|
+
--appkit-color-primary-300: #a5aeff;
|
|
648
|
+
--appkit-color-primary-400: #8e99ff;
|
|
649
|
+
--appkit-color-primary-500: #7c8cff;
|
|
650
|
+
--appkit-color-primary-600: #5a68e8;
|
|
651
|
+
--appkit-color-primary-700: #4650c4;
|
|
652
|
+
--appkit-color-primary-800: #373f9c;
|
|
653
|
+
--appkit-color-primary-900: #2b317a;
|
|
654
|
+
--appkit-color-primary-950: #171a45;
|
|
655
|
+
|
|
656
|
+
--appkit-color-secondary: #56d39a;
|
|
657
|
+
--appkit-color-secondary-50: #ecfdf5;
|
|
658
|
+
--appkit-color-secondary-100: #d1fae5;
|
|
659
|
+
--appkit-color-secondary-200: #a7f3d0;
|
|
660
|
+
--appkit-color-secondary-300: #7ee7b8;
|
|
661
|
+
--appkit-color-secondary-400: #56d39a;
|
|
662
|
+
--appkit-color-secondary-500: #34b87d;
|
|
663
|
+
--appkit-color-secondary-600: #1f9664;
|
|
664
|
+
--appkit-color-secondary-700: #187752;
|
|
665
|
+
--appkit-color-secondary-800: #155e42;
|
|
666
|
+
--appkit-color-secondary-900: #124b36;
|
|
667
|
+
--appkit-color-secondary-950: #062a1d;
|
|
668
|
+
|
|
669
|
+
--appkit-color-bg: #0b0d10;
|
|
670
|
+
--appkit-color-surface: #13161b;
|
|
671
|
+
--appkit-color-surface-elevated: rgba(19, 22, 27, 0.92);
|
|
672
|
+
--appkit-color-surface-input: rgba(27, 31, 38, 0.7);
|
|
673
|
+
|
|
674
|
+
--appkit-color-surface-hover: rgba(148, 163, 184, 0.1);
|
|
675
|
+
--appkit-color-surface-raised: rgba(27, 31, 38, 0.8);
|
|
676
|
+
--appkit-color-primary-surface: rgba(124, 140, 255, 0.16);
|
|
677
|
+
|
|
678
|
+
--appkit-color-border: #242a33;
|
|
679
|
+
--appkit-color-border-subtle: rgba(36, 42, 51, 0.6);
|
|
680
|
+
|
|
681
|
+
--appkit-color-text: #e4e8ee;
|
|
682
|
+
--appkit-color-text-muted: #9aa4b2;
|
|
683
|
+
--appkit-color-text-faint: #747d8c;
|
|
684
|
+
/* Dark ink on the violet fill: 6.53:1, where white measures 2.98:1 and
|
|
685
|
+
fails. Declared here AND in the TS record or first paint disagrees. */
|
|
686
|
+
--appkit-color-text-on-primary: #0b0d10;
|
|
687
|
+
|
|
688
|
+
--appkit-color-success: #4ade80;
|
|
689
|
+
--appkit-color-success-surface: rgba(22, 101, 68, 0.22);
|
|
690
|
+
--appkit-color-warning: #f2b544;
|
|
691
|
+
--appkit-color-warning-surface: rgba(120, 78, 10, 0.22);
|
|
692
|
+
--appkit-color-error: #ff6b6b;
|
|
693
|
+
--appkit-color-error-surface: rgba(140, 30, 30, 0.22);
|
|
694
|
+
--appkit-color-info: #58b4ff;
|
|
695
|
+
--appkit-color-info-surface: rgba(12, 74, 110, 0.22);
|
|
696
|
+
|
|
697
|
+
/* Amber, deliberately not a status or brand hue — a focus ring that doubles
|
|
698
|
+
as an error colour is unreadable on an invalid field. */
|
|
699
|
+
--appkit-color-focus-ring: #ffb86b;
|
|
700
|
+
--appkit-shadow-glow: 0 0 0 1px rgba(124,140,255,0.14), 0 4px 16px -6px rgba(124,140,255,0.2);
|
|
701
|
+
--appkit-shadow-glow-pink: 0 0 0 1px rgba(86,211,154,0.14), 0 4px 18px -6px rgba(86,211,154,0.22);
|
|
702
|
+
|
|
703
|
+
/* Mono-forward: display/sans are monospace for headings, labels, IDs and
|
|
704
|
+
tables; editorial carries the reading face for long lesson prose. */
|
|
705
|
+
--appkit-font-display: var(--font-mono), "JetBrains Mono", "IBM Plex Mono", ui-monospace, "SFMono-Regular", Consolas, monospace;
|
|
706
|
+
--appkit-font-sans: var(--font-mono), "JetBrains Mono", "IBM Plex Mono", ui-monospace, "SFMono-Regular", Consolas, monospace;
|
|
707
|
+
--appkit-font-editorial: var(--font-body), ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
|
|
708
|
+
--appkit-font-mono: var(--font-mono), "JetBrains Mono", "IBM Plex Mono", ui-monospace, "SFMono-Regular", Consolas, monospace;
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
/* --- Theme — Technical Light ([data-theme="technical-light"]) ------------- */
|
|
712
|
+
/* The matched light counterpart. Every accent is RE-DARKENED rather than
|
|
713
|
+
reused: the dark preset's #7c8cff measures 2.88:1 on this ground and fails
|
|
714
|
+
AA, and its #ffb86b focus ring measures 1.65:1 — an invisible focus ring is
|
|
715
|
+
a keyboard trap.
|
|
716
|
+
|
|
717
|
+
Mirrors src/tokens/themes/technical-light.ts.
|
|
718
|
+
|
|
719
|
+
Contrast on --appkit-color-bg (#fbfbfa), measured: text 17.15:1,
|
|
720
|
+
muted 5.84:1, faint 4.67:1, primary 5.38:1, lowest status 4.80:1. */
|
|
721
|
+
[data-theme="technical-light"] {
|
|
722
|
+
--appkit-color-primary: #4b5bd6;
|
|
723
|
+
--appkit-color-primary-50: #eef0ff;
|
|
724
|
+
--appkit-color-primary-100: #e0e4ff;
|
|
725
|
+
--appkit-color-primary-200: #c7cdff;
|
|
726
|
+
--appkit-color-primary-300: #a5aeff;
|
|
727
|
+
--appkit-color-primary-400: #7c8cff;
|
|
728
|
+
--appkit-color-primary-500: #5a68e8;
|
|
729
|
+
--appkit-color-primary-600: #4b5bd6;
|
|
730
|
+
--appkit-color-primary-700: #3b45ad;
|
|
731
|
+
--appkit-color-primary-800: #2f3789;
|
|
732
|
+
--appkit-color-primary-900: #262c6d;
|
|
733
|
+
--appkit-color-primary-950: #151840;
|
|
734
|
+
|
|
735
|
+
--appkit-color-secondary: #0f8f5f;
|
|
736
|
+
--appkit-color-secondary-50: #ecfdf5;
|
|
737
|
+
--appkit-color-secondary-100: #d1fae5;
|
|
738
|
+
--appkit-color-secondary-200: #a7f3d0;
|
|
739
|
+
--appkit-color-secondary-300: #6ee7b7;
|
|
740
|
+
--appkit-color-secondary-400: #34b87d;
|
|
741
|
+
--appkit-color-secondary-500: #0f8f5f;
|
|
742
|
+
--appkit-color-secondary-600: #0c744d;
|
|
743
|
+
--appkit-color-secondary-700: #0a5c3d;
|
|
744
|
+
--appkit-color-secondary-800: #084830;
|
|
745
|
+
--appkit-color-secondary-900: #063a27;
|
|
746
|
+
--appkit-color-secondary-950: #032016;
|
|
747
|
+
|
|
748
|
+
--appkit-color-bg: #fbfbfa;
|
|
749
|
+
--appkit-color-surface: #ffffff;
|
|
750
|
+
--appkit-color-surface-elevated: rgba(255, 255, 255, 0.96);
|
|
751
|
+
--appkit-color-surface-input: rgba(244, 244, 242, 0.8);
|
|
752
|
+
|
|
753
|
+
--appkit-color-surface-hover: rgba(22, 24, 29, 0.05);
|
|
754
|
+
--appkit-color-surface-raised: rgba(244, 244, 242, 0.9);
|
|
755
|
+
--appkit-color-primary-surface: rgba(75, 91, 214, 0.1);
|
|
756
|
+
|
|
757
|
+
--appkit-color-border: #e2e2df;
|
|
758
|
+
--appkit-color-border-subtle: rgba(226, 226, 223, 0.7);
|
|
759
|
+
|
|
760
|
+
--appkit-color-text: #16181d;
|
|
761
|
+
--appkit-color-text-muted: #5c6370;
|
|
762
|
+
/* #767d89 measured 4.00:1 — AA for large text only. Darkened to clear AA
|
|
763
|
+
at body size. */
|
|
764
|
+
--appkit-color-text-faint: #6b7280;
|
|
765
|
+
--appkit-color-text-on-primary: #ffffff;
|
|
766
|
+
|
|
767
|
+
--appkit-color-success: #13804f;
|
|
768
|
+
--appkit-color-success-surface: rgba(19, 128, 79, 0.1);
|
|
769
|
+
--appkit-color-warning: #9a6400;
|
|
770
|
+
--appkit-color-warning-surface: rgba(154, 100, 0, 0.1);
|
|
771
|
+
--appkit-color-error: #c62828;
|
|
772
|
+
--appkit-color-error-surface: rgba(198, 40, 40, 0.1);
|
|
773
|
+
--appkit-color-info: #0a69b5;
|
|
774
|
+
--appkit-color-info-surface: rgba(10, 105, 181, 0.1);
|
|
775
|
+
|
|
776
|
+
--appkit-color-focus-ring: #b45a00;
|
|
777
|
+
--appkit-shadow-glow: 0 0 0 1px rgba(75,91,214,0.14), 0 4px 16px -6px rgba(75,91,214,0.18);
|
|
778
|
+
--appkit-shadow-glow-pink: 0 0 0 1px rgba(15,143,95,0.14), 0 4px 18px -6px rgba(15,143,95,0.2);
|
|
779
|
+
|
|
780
|
+
--appkit-font-display: var(--font-mono), "JetBrains Mono", "IBM Plex Mono", ui-monospace, "SFMono-Regular", Consolas, monospace;
|
|
781
|
+
--appkit-font-sans: var(--font-mono), "JetBrains Mono", "IBM Plex Mono", ui-monospace, "SFMono-Regular", Consolas, monospace;
|
|
782
|
+
--appkit-font-editorial: var(--font-body), ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
|
|
783
|
+
--appkit-font-mono: var(--font-mono), "JetBrains Mono", "IBM Plex Mono", ui-monospace, "SFMono-Regular", Consolas, monospace;
|
|
784
|
+
}
|
|
785
|
+
|
|
631
786
|
/* --- Typography ----------------------------------------------------------- */
|
|
632
787
|
:root {
|
|
633
788
|
--appkit-font-sans: var(--font-body), ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import {
|
|
2
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import React from "react";
|
|
3
4
|
import { Span } from "./Typography.js";
|
|
4
5
|
import { Row } from "./Layout.js";
|
|
5
|
-
import {
|
|
6
|
+
import { Icon } from "./Icon.js";
|
|
7
|
+
import { IconButton, ICON_BUTTON_ICON_SIZE } from "./IconButton.js";
|
|
8
|
+
import { LoginRequiredModal } from "./LoginRequiredModal.js";
|
|
6
9
|
import { getDefaultCurrency } from "../../core/baseline-resolver.js";
|
|
7
10
|
import { formatCurrency, formatPercentage } from "../../utils/number.formatter.js";
|
|
8
11
|
import { useCanSeePrices } from "../../react/hooks/useCanSeePrices.js";
|
|
@@ -24,6 +27,30 @@ import { useCanSeePrices } from "../../react/hooks/useCanSeePrices.js";
|
|
|
24
27
|
// audit-dead-css-ok: selector target for the paywall JSON-LD, never styled
|
|
25
28
|
export const GATED_PRICE_CLASS = "appkit-gated-price";
|
|
26
29
|
const DEFAULT_LABEL = "Sign in to see price";
|
|
30
|
+
/**
|
|
31
|
+
* The signed-out state: a closed eye you can press, not a line of refusal copy.
|
|
32
|
+
*
|
|
33
|
+
* 🛑 WHY AN ICON AND NOT THE SENTENCE. The prompt used to be a full
|
|
34
|
+
* "🔒 Sign in to see price" link in `--appkit-color-primary`, repeated once per
|
|
35
|
+
* card. On a 24-card grid that is 24 lines of brand-coloured refusal, each
|
|
36
|
+
* wider than the price it stands in for — so the grid's loudest element became
|
|
37
|
+
* the thing the visitor cannot have, and the rows it sat in changed width with
|
|
38
|
+
* the copy. An eye occupies roughly a price's worth of space, reads as "there
|
|
39
|
+
* is something here", and says it once per card without shouting.
|
|
40
|
+
*
|
|
41
|
+
* 🛑 THE ASK IS ON THE CLICK, NOT ON THE PAGE. Pressing it opens the shared
|
|
42
|
+
* sign-in modal rather than navigating away: a visitor who taps a price on a
|
|
43
|
+
* listing page wants the price, not to lose their place in the catalogue. The
|
|
44
|
+
* modal is rendered only while open, so a grid of 24 gated prices mounts 24
|
|
45
|
+
* buttons and zero modals.
|
|
46
|
+
*
|
|
47
|
+
* The accessible name is still the full sentence — the icon is the visual
|
|
48
|
+
* economy, not an information loss.
|
|
49
|
+
*/
|
|
50
|
+
function GatedPriceReveal({ label }) {
|
|
51
|
+
const [asking, setAsking] = React.useState(false);
|
|
52
|
+
return (_jsxs(_Fragment, { children: [_jsx(IconButton, { size: "sm", variant: "outline", rounded: "lg", "aria-label": label, title: label, onClick: () => setAsking(true), icon: _jsx(Icon, { name: "hide", size: ICON_BUTTON_ICON_SIZE.sm }) }), asking && (_jsx(LoginRequiredModal, { isOpen: true, onClose: () => setAsking(false), message: `${label}. Sign in or create an account to see prices across the site.` }))] }));
|
|
53
|
+
}
|
|
27
54
|
/**
|
|
28
55
|
* Renders its children only when the viewer may see prices; renders NOTHING
|
|
29
56
|
* otherwise — no prompt, no placeholder.
|
|
@@ -65,7 +92,7 @@ export function GatedPrice({ amount, currency = getDefaultCurrency(), originalAm
|
|
|
65
92
|
return (_jsx(Span, { className: `${rootClass} appkit-gated-price__pending`, "aria-hidden": "true" }));
|
|
66
93
|
}
|
|
67
94
|
if (!canSeePrices) {
|
|
68
|
-
return (_jsx(
|
|
95
|
+
return (_jsx(Span, { className: `${rootClass} appkit-gated-price__prompt`, children: _jsx(GatedPriceReveal, { label: label }) }));
|
|
69
96
|
}
|
|
70
97
|
if (children !== undefined) {
|
|
71
98
|
return _jsx(Span, { className: rootClass, children: children });
|
|
@@ -11,30 +11,33 @@
|
|
|
11
11
|
min-width: 5rem;
|
|
12
12
|
height: 1.25rem;
|
|
13
13
|
border-radius: 0.25rem;
|
|
14
|
-
|
|
14
|
+
/* 🛑 `--appkit-color-surface-muted` is NOT a token — 15 uses, 0 definitions,
|
|
15
|
+
and `audit-undefined-css-vars` ratchets it down. An undefined custom
|
|
16
|
+
property with no fallback makes the whole declaration invalid, so this
|
|
17
|
+
placeholder had no background at all and the grid still reflowed on
|
|
18
|
+
resolve, which is the one job it has. */
|
|
19
|
+
background: var(--appkit-color-surface-input);
|
|
15
20
|
}
|
|
16
21
|
|
|
17
22
|
.appkit-gated-price__prompt {
|
|
18
23
|
display: inline-flex;
|
|
19
24
|
align-items: center;
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
25
|
+
/*
|
|
26
|
+
* The eye is a 2rem IconButton while `__pending` above is a 1.25rem price
|
|
27
|
+
* line, so a GUEST's row grows by 0.75rem once the session resolves. That is
|
|
28
|
+
* deliberate and is the lesser of the two: the alternative is making
|
|
29
|
+
* `__pending` 2rem, which shifts the row for SIGNED-IN users — the ones who
|
|
30
|
+
* end up looking at real content. The guest shift happens once per load and
|
|
31
|
+
* applies to every card identically, so the grid moves as one rather than
|
|
32
|
+
* going ragged.
|
|
33
|
+
*/
|
|
23
34
|
line-height: 1.25rem;
|
|
24
|
-
color: var(--appkit-color-primary);
|
|
25
|
-
text-decoration: none;
|
|
26
|
-
cursor: pointer;
|
|
27
35
|
}
|
|
28
36
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
.appkit-gated-price__prompt::before {
|
|
37
|
-
content: "\1F512";
|
|
38
|
-
font-size: 0.75rem;
|
|
39
|
-
line-height: 1;
|
|
40
|
-
}
|
|
37
|
+
/*
|
|
38
|
+
* 🛑 The eye itself has NO rules here, on purpose. It is an `<IconButton
|
|
39
|
+
* size="sm" variant="outline">`, so its box, ink, hover and focus ring all
|
|
40
|
+
* come from the design system — a second, private set of button styles for
|
|
41
|
+
* one control is exactly how a UI ends up with two kinds of icon button that
|
|
42
|
+
* drift apart. This wrapper only has to keep the row's height stable.
|
|
43
|
+
*/
|