@hraness/design-kit 0.31.1
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/ARTICLE_COPY.md +208 -0
- package/HERO_FIELDS.md +55 -0
- package/ICONS.md +56 -0
- package/LANTERN_MATERIAL.md +60 -0
- package/LICENSE +21 -0
- package/MARKETING_COPY.md +49 -0
- package/MARKETING_PRESET.md +108 -0
- package/PALETTES.md +90 -0
- package/PAPER_THEME.md +128 -0
- package/README.md +745 -0
- package/STATUS_PAGES.md +67 -0
- package/STYLE.md +245 -0
- package/WRITING.md +72 -0
- package/dist/browser/index.js +2345 -0
- package/dist/chunk-44djxk16.js +6872 -0
- package/dist/chunk-5gtx3pza.js +9 -0
- package/dist/chunk-77391vmq.js +454 -0
- package/dist/chunk-7b1586eb.js +1209 -0
- package/dist/chunk-8834fh4n.js +6 -0
- package/dist/chunk-9t8xyqte.js +870 -0
- package/dist/chunk-cejpzyfh.js +446 -0
- package/dist/chunk-eh71jz57.js +429 -0
- package/dist/chunk-evb02bc1.js +516 -0
- package/dist/chunk-h4k7yv6x.js +368 -0
- package/dist/chunk-he8eznb1.js +760 -0
- package/dist/chunk-mr1vdcjq.js +404 -0
- package/dist/chunk-wzvdn8ey.js +116 -0
- package/dist/fonts/nebula-sans/social-fonts.generated.js +53 -0
- package/dist/icons.js +48 -0
- package/dist/index.js +237 -0
- package/dist/launch.js +41 -0
- package/dist/mockups/client.js +422 -0
- package/dist/mockups/index.js +1850 -0
- package/dist/portfolio.js +1549 -0
- package/dist/provider-marks.js +19 -0
- package/dist/react/charts.js +11 -0
- package/dist/react/hero-backdrop.js +8 -0
- package/dist/react/index.js +7252 -0
- package/dist/react/platform-install.js +10 -0
- package/dist/react/server.js +137 -0
- package/dist/stylex-manifest.json +1 -0
- package/dist/stylex.css +5392 -0
- package/dist/syntax-highlighting.js +15 -0
- package/dist/testing.js +250 -0
- package/package.json +377 -0
- package/portfolio-inventory.json +31 -0
- package/scripts/check-lantern-material-snapshot.d.mts +26 -0
- package/scripts/check-lantern-material-snapshot.mjs +126 -0
- package/scripts/check-marketing-snapshot.d.mts +12 -0
- package/scripts/check-marketing-snapshot.mjs +58 -0
- package/scripts/lantern-material-snapshot.ts +101 -0
- package/scripts/marketing-textures.ts +48 -0
- package/scripts/paper-theme-snapshot.ts +97 -0
- package/scripts/product-marketing-snapshot.ts +149 -0
- package/src/appearance-menu.css +266 -0
- package/src/appearance.ts +32 -0
- package/src/article-html.ts +269 -0
- package/src/article.ts +686 -0
- package/src/browser/appearance-menu.ts +604 -0
- package/src/browser/artifact-share.ts +164 -0
- package/src/browser/design-palette.ts +197 -0
- package/src/browser/foil.ts +124 -0
- package/src/browser/hero-light.ts +11 -0
- package/src/browser/index.ts +29 -0
- package/src/browser/status-field.ts +432 -0
- package/src/browser/status-page.ts +100 -0
- package/src/browser/sticky-offset.ts +82 -0
- package/src/browser/theme-color-sync.ts +213 -0
- package/src/charts.css +7 -0
- package/src/compiler-components.css +34 -0
- package/src/compiler-foundation.css +18 -0
- package/src/compiler-palettes.css +7 -0
- package/src/compiler-tokens.css +342 -0
- package/src/components.css +3 -0
- package/src/design-gallery.css +431 -0
- package/src/effects.css +14 -0
- package/src/fonts/geist-mono/GeistMono[wght].woff2 +0 -0
- package/src/fonts/geist-mono/OFL.txt +93 -0
- package/src/fonts/geist-mono/PROVENANCE.md +12 -0
- package/src/fonts/instrument-serif/OFL.txt +93 -0
- package/src/fonts/instrument-serif/UPSTREAM.md +14 -0
- package/src/fonts/instrument-serif/instrument-serif-latin-400.woff2 +0 -0
- package/src/fonts/nebula-sans/LICENSE.txt +96 -0
- package/src/fonts/nebula-sans/NebulaSans-Black.woff2 +0 -0
- package/src/fonts/nebula-sans/NebulaSans-BlackItalic.woff2 +0 -0
- package/src/fonts/nebula-sans/NebulaSans-Bold.otf +0 -0
- package/src/fonts/nebula-sans/NebulaSans-Bold.woff2 +0 -0
- package/src/fonts/nebula-sans/NebulaSans-BoldItalic.woff2 +0 -0
- package/src/fonts/nebula-sans/NebulaSans-Book.otf +0 -0
- package/src/fonts/nebula-sans/NebulaSans-Book.woff2 +0 -0
- package/src/fonts/nebula-sans/NebulaSans-BookItalic.woff2 +0 -0
- package/src/fonts/nebula-sans/NebulaSans-Light.woff2 +0 -0
- package/src/fonts/nebula-sans/NebulaSans-LightItalic.woff2 +0 -0
- package/src/fonts/nebula-sans/NebulaSans-Medium.woff2 +0 -0
- package/src/fonts/nebula-sans/NebulaSans-MediumItalic.woff2 +0 -0
- package/src/fonts/nebula-sans/NebulaSans-Semibold.woff2 +0 -0
- package/src/fonts/nebula-sans/NebulaSans-SemiboldItalic.woff2 +0 -0
- package/src/fonts/nebula-sans/PROVENANCE.md +14 -0
- package/src/fonts/nebula-sans/social-fonts.generated.ts +3873 -0
- package/src/fonts.css +106 -0
- package/src/icons/act60/act60.svg +5 -0
- package/src/icons/act60/application.svg +9 -0
- package/src/icons/act60/chapter-compare.svg +3 -0
- package/src/icons/act60/decree-residence.svg +6 -0
- package/src/icons/act60/estimate.svg +7 -0
- package/src/icons/act60/export-services.svg +4 -0
- package/src/icons/act60/investor.svg +13 -0
- package/src/icons/act60/presence.svg +7 -0
- package/src/icons/aicharts/aicharts.svg +6 -0
- package/src/icons/aicharts/cost-compare.svg +4 -0
- package/src/icons/aicharts/task-audio.svg +7 -0
- package/src/icons/aicharts/task-coding.svg +6 -0
- package/src/icons/aicharts/task-images.svg +3 -0
- package/src/icons/aicharts/task-reasoning.svg +9 -0
- package/src/icons/aicharts/task-research.svg +5 -0
- package/src/icons/aicharts/task-video.svg +4 -0
- package/src/icons/manifest.json +1371 -0
- package/src/icons/platonik/conversation.svg +3 -0
- package/src/icons/platonik/creature.svg +7 -0
- package/src/icons/platonik/economy.svg +4 -0
- package/src/icons/platonik/keep-light.svg +6 -0
- package/src/icons/platonik/platonik.svg +7 -0
- package/src/icons/platonik/spark-route.svg +15 -0
- package/src/icons/receipts/act60-retry.receipt.json +888 -0
- package/src/icons/receipts/act60.receipt.json +1366 -0
- package/src/icons/receipts/aicharts.receipt.json +1546 -0
- package/src/icons/receipts/platonik.receipt.json +1011 -0
- package/src/icons/receipts/roughday.receipt.json +770 -0
- package/src/icons/receipts/shared.receipt.json +1296 -0
- package/src/icons/receipts/slopcamera.receipt.json +1495 -0
- package/src/icons/receipts/soundfish-retry.receipt.json +460 -0
- package/src/icons/receipts/soundfish.receipt.json +1709 -0
- package/src/icons/receipts/sponge.receipt.json +1743 -0
- package/src/icons/receipts/stripe-history-retry.receipt.json +145 -0
- package/src/icons/receipts/stripe-history.receipt.json +1202 -0
- package/src/icons/receipts/wordcell.receipt.json +1924 -0
- package/src/icons/roughday/finance.svg +7 -0
- package/src/icons/roughday/roughday.svg +6 -0
- package/src/icons/roughday/technology.svg +4 -0
- package/src/icons/roughday/world.svg +4 -0
- package/src/icons/sets/act60.json +63 -0
- package/src/icons/sets/aicharts.json +63 -0
- package/src/icons/sets/platonik.json +39 -0
- package/src/icons/sets/roughday.json +25 -0
- package/src/icons/sets/shared.json +12 -0
- package/src/icons/sets/slopcamera.json +47 -0
- package/src/icons/sets/soundfish.json +43 -0
- package/src/icons/sets/sponge.json +51 -0
- package/src/icons/sets/stripe-history.json +39 -0
- package/src/icons/sets/wordcell.json +51 -0
- package/src/icons/shared/agent-skill.svg +4 -0
- package/src/icons/shared/cli.svg +5 -0
- package/src/icons/shared/privacy.svg +3 -0
- package/src/icons/shared/research.svg +7 -0
- package/src/icons/shared/sdk.svg +3 -0
- package/src/icons/slopcamera/diagram.svg +3 -0
- package/src/icons/slopcamera/direct-scene.svg +5 -0
- package/src/icons/slopcamera/edit-video.svg +17 -0
- package/src/icons/slopcamera/mcp.svg +3 -0
- package/src/icons/slopcamera/native-world.svg +3 -0
- package/src/icons/slopcamera/slopcamera.svg +11 -0
- package/src/icons/soundfish/agent-ui.svg +7 -0
- package/src/icons/soundfish/collaborate.svg +5 -0
- package/src/icons/soundfish/compose.svg +3 -0
- package/src/icons/soundfish/hear.svg +6 -0
- package/src/icons/soundfish/human-ui.svg +6 -0
- package/src/icons/soundfish/share.svg +3 -0
- package/src/icons/soundfish/soundfish.svg +6 -0
- package/src/icons/sponge/api.svg +3 -0
- package/src/icons/sponge/documents.svg +3 -0
- package/src/icons/sponge/library.svg +3 -0
- package/src/icons/sponge/one-question.svg +5 -0
- package/src/icons/sponge/people-direct.svg +5 -0
- package/src/icons/sponge/read.svg +3 -0
- package/src/icons/sponge/save.svg +4 -0
- package/src/icons/sponge/sponge.svg +7 -0
- package/src/icons/stripe-history/company-history.svg +3 -0
- package/src/icons/stripe-history/evidence.svg +4 -0
- package/src/icons/stripe-history/independence.svg +7 -0
- package/src/icons/stripe-history/publications.svg +11 -0
- package/src/icons/stripe-history/sources.svg +6 -0
- package/src/icons/stripe-history/stripe-history.svg +3 -0
- package/src/icons/wordcell/backlinks.svg +6 -0
- package/src/icons/wordcell/capture.svg +6 -0
- package/src/icons/wordcell/git-provenance.svg +4 -0
- package/src/icons/wordcell/kb.svg +4 -0
- package/src/icons/wordcell/markdown.svg +4 -0
- package/src/icons/wordcell/scopes.svg +3 -0
- package/src/icons/wordcell/search.svg +7 -0
- package/src/icons.generated.ts +734 -0
- package/src/icons.ts +51 -0
- package/src/index.ts +275 -0
- package/src/lantern-material.css +213 -0
- package/src/launch.ts +624 -0
- package/src/marketing-assets/UPSTREAM.md +18 -0
- package/src/marketing-assets/cells.svg +1 -0
- package/src/marketing-assets/grain.svg +1 -0
- package/src/marketing-forced-colors.css +12 -0
- package/src/mockups/client.tsx +415 -0
- package/src/mockups/core.tsx +318 -0
- package/src/mockups/frames.tsx +368 -0
- package/src/mockups/index.ts +14 -0
- package/src/mockups/surfaces.tsx +681 -0
- package/src/mockups.css +2607 -0
- package/src/palette-appearance.ts +45 -0
- package/src/palette-bridge.css +124 -0
- package/src/palette-color.ts +41 -0
- package/src/palette-system.css +721 -0
- package/src/palette-themes.ts +23 -0
- package/src/palette-tokens.stylex.ts +519 -0
- package/src/palettes.css +3 -0
- package/src/palettes.ts +161 -0
- package/src/paper-theme.css +244 -0
- package/src/plain-publication.css +1241 -0
- package/src/plain-site.css +397 -0
- package/src/platforms.ts +151 -0
- package/src/portfolio.generated.json +1595 -0
- package/src/portfolio.generated.ts +1596 -0
- package/src/portfolio.ts +226 -0
- package/src/product-marketing-foundation.css +433 -0
- package/src/product-marketing-preset.css +261 -0
- package/src/product-marketing.css +2186 -0
- package/src/provider-marks.generated.ts +112 -0
- package/src/provider-marks.ts +143 -0
- package/src/react/animated-rail-stage.stylex.ts +15 -0
- package/src/react/animated-rail-stage.tsx +51 -0
- package/src/react/app-shell.stylex.ts +104 -0
- package/src/react/app-shell.tsx +121 -0
- package/src/react/article.tsx +602 -0
- package/src/react/aurora-dots-background.tsx +34 -0
- package/src/react/charts.stylex.ts +563 -0
- package/src/react/charts.tsx +610 -0
- package/src/react/chat.stylex.ts +34 -0
- package/src/react/chat.tsx +155 -0
- package/src/react/design-gallery.tsx +943 -0
- package/src/react/design-palette.stylex.ts +124 -0
- package/src/react/design-palette.tsx +196 -0
- package/src/react/design-theme-context.tsx +41 -0
- package/src/react/effects.stylex.ts +325 -0
- package/src/react/fader.stylex.ts +71 -0
- package/src/react/fader.tsx +151 -0
- package/src/react/foil-card-math.ts +100 -0
- package/src/react/foil-card-surface.stylex.ts +326 -0
- package/src/react/foil-card-surface.tsx +742 -0
- package/src/react/foil-mark.tsx +35 -0
- package/src/react/foil.stylex.ts +163 -0
- package/src/react/haptics.ts +228 -0
- package/src/react/hero-backdrop.tsx +22 -0
- package/src/react/index.ts +38 -0
- package/src/react/keyboard-shortcuts.ts +228 -0
- package/src/react/lantern-material-gallery.tsx +166 -0
- package/src/react/lantern-material.stylex.ts +39 -0
- package/src/react/launch-beats.tsx +73 -0
- package/src/react/navigation-rail.stylex.ts +130 -0
- package/src/react/navigation-rail.tsx +228 -0
- package/src/react/particle-halo.tsx +115 -0
- package/src/react/phaser-dots.tsx +501 -0
- package/src/react/platform-icons.tsx +94 -0
- package/src/react/platform-install.stylex.ts +385 -0
- package/src/react/platform-install.tsx +389 -0
- package/src/react/playback-transport.stylex.ts +14 -0
- package/src/react/playback-transport.tsx +112 -0
- package/src/react/procedural-backdrop.tsx +192 -0
- package/src/react/procedural-recipe.ts +323 -0
- package/src/react/product-marketing.stylex.ts +4469 -0
- package/src/react/product-marketing.tsx +1611 -0
- package/src/react/production-data-preview-notice.stylex.ts +40 -0
- package/src/react/production-data-preview-notice.tsx +34 -0
- package/src/react/provider-mark.stylex.ts +132 -0
- package/src/react/provider-mark.tsx +120 -0
- package/src/react/relative-time.tsx +117 -0
- package/src/react/route-state.stylex.ts +39 -0
- package/src/react/route-state.tsx +350 -0
- package/src/react/server.ts +11 -0
- package/src/react/social-kit-panel.tsx +103 -0
- package/src/react/sticky-offset.tsx +33 -0
- package/src/react/surfaces.stylex.ts +179 -0
- package/src/react/surfaces.tsx +330 -0
- package/src/react/syntax-code.tsx +33 -0
- package/src/react/theme-color-sync.ts +1 -0
- package/src/react/theme-resolution.ts +11 -0
- package/src/react/theme.stylex.ts +276 -0
- package/src/react/theme.tsx +402 -0
- package/src/reading.css +72 -0
- package/src/relative-time.ts +185 -0
- package/src/reset.css +2 -0
- package/src/site-shell.css +16 -0
- package/src/status-page-html.ts +63 -0
- package/src/status-page.css +276 -0
- package/src/status-page.ts +323 -0
- package/src/styles.css +21 -0
- package/src/syntax-code-lexers.ts +303 -0
- package/src/syntax-highlighting.css +78 -0
- package/src/syntax-highlighting.ts +477 -0
- package/src/syntax-tokens.ts +33 -0
- package/src/testing.ts +307 -0
- package/src/tokens.css +3 -0
- package/src/typography.css +86 -0
- package/vendor/evilcharts/LICENSE +21 -0
- package/vendor/evilcharts/UPSTREAM.md +14 -0
- package/vendor/platform-marks/LICENSE +30 -0
- package/vendor/platform-marks/UPSTREAM.md +15 -0
- package/vendor/platform-marks/apple.svg +1 -0
- package/vendor/platform-marks/linux.svg +1 -0
- package/vendor/provider-marks/CRUSH-LICENSE.md +134 -0
- package/vendor/provider-marks/LICENSE +21 -0
- package/vendor/provider-marks/UPSTREAM.md +27 -0
- package/vendor/provider-marks/aider.svg +3 -0
- package/vendor/provider-marks/crush-heartbit.svg +8 -0
- package/vendor/provider-marks/lobehub/alibabacloud-color.svg +1 -0
- package/vendor/provider-marks/lobehub/alibabacloud.svg +1 -0
- package/vendor/provider-marks/lobehub/amp-color.svg +1 -0
- package/vendor/provider-marks/lobehub/amp.svg +1 -0
- package/vendor/provider-marks/lobehub/anthropic.svg +1 -0
- package/vendor/provider-marks/lobehub/claude-color.svg +1 -0
- package/vendor/provider-marks/lobehub/claude.svg +1 -0
- package/vendor/provider-marks/lobehub/claudecode-color.svg +1 -0
- package/vendor/provider-marks/lobehub/claudecode.svg +1 -0
- package/vendor/provider-marks/lobehub/codex-color.svg +1 -0
- package/vendor/provider-marks/lobehub/codex.svg +1 -0
- package/vendor/provider-marks/lobehub/cursor.svg +1 -0
- package/vendor/provider-marks/lobehub/deepseek-color.svg +1 -0
- package/vendor/provider-marks/lobehub/deepseek.svg +1 -0
- package/vendor/provider-marks/lobehub/devin-color.svg +1 -0
- package/vendor/provider-marks/lobehub/devin.svg +1 -0
- package/vendor/provider-marks/lobehub/gemini-color.svg +1 -0
- package/vendor/provider-marks/lobehub/gemini.svg +1 -0
- package/vendor/provider-marks/lobehub/geminicli-color.svg +1 -0
- package/vendor/provider-marks/lobehub/geminicli.svg +1 -0
- package/vendor/provider-marks/lobehub/goose.svg +1 -0
- package/vendor/provider-marks/lobehub/meta-color.svg +1 -0
- package/vendor/provider-marks/lobehub/meta.svg +1 -0
- package/vendor/provider-marks/lobehub/mistral-color.svg +1 -0
- package/vendor/provider-marks/lobehub/mistral.svg +1 -0
- package/vendor/provider-marks/lobehub/moonshot.svg +1 -0
- package/vendor/provider-marks/lobehub/nvidia-color.svg +1 -0
- package/vendor/provider-marks/lobehub/nvidia.svg +1 -0
- package/vendor/provider-marks/lobehub/openai.svg +1 -0
- package/vendor/provider-marks/lobehub/opencode.svg +1 -0
- package/vendor/provider-marks/lobehub/perplexity-color.svg +1 -0
- package/vendor/provider-marks/lobehub/perplexity.svg +1 -0
- package/vendor/provider-marks/lobehub/qwen-color.svg +1 -0
- package/vendor/provider-marks/lobehub/qwen.svg +1 -0
- package/vendor/provider-marks/lobehub/xai.svg +1 -0
- package/vendor/provider-marks/lobehub/zai.svg +1 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { CSSProperties, ReactNode } from "react";
|
|
2
|
+
import { foilMarkClassName } from "./foil.stylex.js";
|
|
3
|
+
|
|
4
|
+
export interface FoilMarkProps {
|
|
5
|
+
/** Transparent, same-origin or data-URL artwork; its alpha defines the mark. */
|
|
6
|
+
readonly src: string;
|
|
7
|
+
readonly className?: string;
|
|
8
|
+
/** Decorative by default; name the enclosing link instead when possible. */
|
|
9
|
+
readonly label?: string;
|
|
10
|
+
readonly size?: number;
|
|
11
|
+
/** Optional original inline vector for a currentColor forced-color fallback. */
|
|
12
|
+
readonly fallback?: ReactNode;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/** Static metallic paint over the exact source silhouette, with an intact fallback. */
|
|
16
|
+
export function FoilMark({ src, className, label, size = 24, fallback }: FoilMarkProps) {
|
|
17
|
+
if (!Number.isFinite(size) || size <= 0) throw new RangeError("FoilMark size must be positive and finite.");
|
|
18
|
+
return (
|
|
19
|
+
<span
|
|
20
|
+
aria-hidden={label === undefined ? true : undefined}
|
|
21
|
+
aria-label={label}
|
|
22
|
+
className={foilMarkClassName("root", className)}
|
|
23
|
+
data-foil=""
|
|
24
|
+
role={label === undefined ? undefined : "img"}
|
|
25
|
+
style={{ "--hraness-foil-size": `${size}px` } as CSSProperties}
|
|
26
|
+
>
|
|
27
|
+
{fallback ?? <img alt="" className={foilMarkClassName("image")} decoding="async" height={size} src={src} width={size} />}
|
|
28
|
+
<span
|
|
29
|
+
aria-hidden="true"
|
|
30
|
+
className={foilMarkClassName("paint")}
|
|
31
|
+
style={{ "--hraness-foil-mask": `url(${JSON.stringify(src)})` } as CSSProperties}
|
|
32
|
+
/>
|
|
33
|
+
</span>
|
|
34
|
+
);
|
|
35
|
+
}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import * as stylex from "@stylexjs/stylex";
|
|
2
|
+
|
|
3
|
+
// Shared metallic-chrome contract projected from the authored material in
|
|
4
|
+
// ../foil-material.ts, mirrored by the handwritten product-marketing.css
|
|
5
|
+
// grammar and by @hraness/site-footer's holographic recipe. attachFoil() from
|
|
6
|
+
// @hraness/design-kit/browser eases the two bounded pointer inputs
|
|
7
|
+
// --hraness-foil-x and --hraness-foil-y on the outermost [data-foil] lockup;
|
|
8
|
+
// shapes never rotate, only the light moves. --hraness-foil-glow stays
|
|
9
|
+
// CSS-owned on hover-capable pointers. Each recipe resolves the public
|
|
10
|
+
// --hraness-foil-* spectrum into private scheme-conditioned stops so product
|
|
11
|
+
// overrides inherit while the darker dark palette keeps the pointer sheen
|
|
12
|
+
// visible on standalone surfaces. Bordered surfaces paint a flat fill under
|
|
13
|
+
// the theme-aware monochrome --hraness-foil-edge instead of the spectrum.
|
|
14
|
+
const foilStops = {
|
|
15
|
+
"--_hraness-foil-1": {
|
|
16
|
+
"default": "var(--hraness-foil-1, oklch(0.89 0.065 337))",
|
|
17
|
+
"@media (prefers-color-scheme: dark)": "var(--hraness-foil-1, oklch(0.56 0.16 340))",
|
|
18
|
+
},
|
|
19
|
+
"--_hraness-foil-2": {
|
|
20
|
+
"default": "var(--hraness-foil-2, oklch(0.875 0.05 277))",
|
|
21
|
+
"@media (prefers-color-scheme: dark)": "var(--hraness-foil-2, oklch(0.52 0.15 285))",
|
|
22
|
+
},
|
|
23
|
+
"--_hraness-foil-3": {
|
|
24
|
+
"default": "var(--hraness-foil-3, oklch(0.92 0.05 170))",
|
|
25
|
+
"@media (prefers-color-scheme: dark)": "var(--hraness-foil-3, oklch(0.66 0.14 175))",
|
|
26
|
+
},
|
|
27
|
+
"--_hraness-foil-4": {
|
|
28
|
+
"default": "var(--hraness-foil-4, oklch(0.95 0.045 96))",
|
|
29
|
+
"@media (prefers-color-scheme: dark)": "var(--hraness-foil-4, oklch(0.72 0.13 100))",
|
|
30
|
+
},
|
|
31
|
+
"--_hraness-foil-5": {
|
|
32
|
+
"default": "var(--hraness-foil-5, oklch(0.9 0.05 55))",
|
|
33
|
+
"@media (prefers-color-scheme: dark)": "var(--hraness-foil-5, oklch(0.55 0.15 45))",
|
|
34
|
+
},
|
|
35
|
+
"--_hraness-foil-6": {
|
|
36
|
+
"default": "var(--hraness-foil-6, oklch(0.875 0.06 305))",
|
|
37
|
+
"@media (prefers-color-scheme: dark)": "var(--hraness-foil-6, oklch(0.62 0.16 305))",
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
// Bordered surfaces resolve the edge through a private scheme-conditioned stop
|
|
42
|
+
// so a product's public --hraness-foil-edge override wins ahead of either scheme
|
|
43
|
+
// default, exactly like the --_hraness-foil-* spectrum stops.
|
|
44
|
+
const foilEdgeStops = {
|
|
45
|
+
"--_hraness-foil-edge": {
|
|
46
|
+
"default": "var(--hraness-foil-edge, light-dark(black, white))",
|
|
47
|
+
"@media (prefers-color-scheme: dark)": "var(--hraness-foil-edge, white)",
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
/** Theme-aware monochrome emphasis edge for bordered foil surfaces. */
|
|
52
|
+
export const foilEdge = "var(--_hraness-foil-edge, light-dark(black, white))";
|
|
53
|
+
|
|
54
|
+
export const foilTextImage = "var(--hraness-foil-image, radial-gradient(ellipse 24% 85% at var(--hraness-foil-x, 50%) var(--hraness-foil-y, 50%), color-mix(in oklch, var(--hraness-foil-text-base, var(--foreground, CanvasText)) 80%, var(--background, Canvas)) 0%, transparent 68%), radial-gradient(ellipse 65% 160% at calc(100% - var(--hraness-foil-x, 50%)) calc(100% - var(--hraness-foil-y, 50%)), color-mix(in oklch, var(--hraness-foil-text-base, var(--foreground, CanvasText)) 98%, var(--background, Canvas)) 0%, transparent 72%), linear-gradient(115deg, color-mix(in srgb, var(--_hraness-foil-1) var(--hraness-foil-reflection, 14%), transparent), color-mix(in srgb, var(--_hraness-foil-2) var(--hraness-foil-reflection, 14%), transparent), color-mix(in srgb, var(--_hraness-foil-3) var(--hraness-foil-reflection, 14%), transparent), color-mix(in srgb, var(--_hraness-foil-4) var(--hraness-foil-reflection, 14%), transparent), color-mix(in srgb, var(--_hraness-foil-5) var(--hraness-foil-reflection, 14%), transparent), color-mix(in srgb, var(--_hraness-foil-6) var(--hraness-foil-reflection, 14%), transparent)), linear-gradient(115deg, color-mix(in oklch, var(--hraness-foil-text-base, var(--foreground, CanvasText)) 90%, var(--background, Canvas)) 0%, color-mix(in oklch, var(--hraness-foil-text-base, var(--foreground, CanvasText)) 100%, var(--background, Canvas)) 24%, color-mix(in oklch, var(--hraness-foil-text-base, var(--foreground, CanvasText)) 86%, var(--background, Canvas)) 39%, color-mix(in oklch, var(--hraness-foil-text-base, var(--foreground, CanvasText)) 100%, var(--background, Canvas)) 56%, color-mix(in oklch, var(--hraness-foil-text-base, var(--foreground, CanvasText)) 84%, var(--background, Canvas)) 82%, color-mix(in oklch, var(--hraness-foil-text-base, var(--foreground, CanvasText)) 100%, var(--background, Canvas)) 100%))";
|
|
55
|
+
|
|
56
|
+
export const foilHalo = "0 1px 4px color-mix(in srgb, var(--foreground, CanvasText) 12%, transparent)";
|
|
57
|
+
|
|
58
|
+
export const foilTextHalo = "none";
|
|
59
|
+
|
|
60
|
+
export const foilStyles = stylex.create({
|
|
61
|
+
surface: {
|
|
62
|
+
...foilEdgeStops,
|
|
63
|
+
"--hraness-foil-glow": {
|
|
64
|
+
"default": "0",
|
|
65
|
+
"@media (hover: hover)": { ":hover:not(:disabled)": "1" },
|
|
66
|
+
},
|
|
67
|
+
"border-top-width": "2px",
|
|
68
|
+
"border-right-width": "2px",
|
|
69
|
+
"border-bottom-width": "2px",
|
|
70
|
+
"border-left-width": "2px",
|
|
71
|
+
"border-top-style": "solid",
|
|
72
|
+
"border-right-style": "solid",
|
|
73
|
+
"border-bottom-style": "solid",
|
|
74
|
+
"border-left-style": "solid",
|
|
75
|
+
"border-top-color": { "default": foilEdge, "@media (forced-colors: active)": "ButtonText" },
|
|
76
|
+
"border-right-color": { "default": foilEdge, "@media (forced-colors: active)": "ButtonText" },
|
|
77
|
+
"border-bottom-color": { "default": foilEdge, "@media (forced-colors: active)": "ButtonText" },
|
|
78
|
+
"border-left-color": { "default": foilEdge, "@media (forced-colors: active)": "ButtonText" },
|
|
79
|
+
"background-color": {
|
|
80
|
+
"default": "var(--hraness-foil-surface, var(--surface, var(--background, Canvas)))",
|
|
81
|
+
"@media (forced-colors: active)": "Canvas",
|
|
82
|
+
},
|
|
83
|
+
"box-shadow": { "default": foilHalo, "@media (forced-colors: active)": "none" },
|
|
84
|
+
"color": { "default": null, "@media (forced-colors: active)": "CanvasText" },
|
|
85
|
+
},
|
|
86
|
+
text: {
|
|
87
|
+
...foilStops,
|
|
88
|
+
"--hraness-foil-glow": {
|
|
89
|
+
"default": "0",
|
|
90
|
+
"@media (hover: hover)": { ":hover": "1" },
|
|
91
|
+
},
|
|
92
|
+
"background-image": {
|
|
93
|
+
"default": foilTextImage,
|
|
94
|
+
"@media (forced-colors: active)": "none",
|
|
95
|
+
},
|
|
96
|
+
"-webkit-background-clip": "text",
|
|
97
|
+
"background-clip": "text",
|
|
98
|
+
"color": { "default": "transparent", "@media (forced-colors: active)": "CanvasText" },
|
|
99
|
+
"-webkit-text-fill-color": { "default": "transparent", "@media (forced-colors: active)": "CanvasText" },
|
|
100
|
+
"filter": "none",
|
|
101
|
+
},
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
const foilHooks = {
|
|
105
|
+
surface: "hraness-foil",
|
|
106
|
+
text: "hraness-foil-text",
|
|
107
|
+
} as const;
|
|
108
|
+
|
|
109
|
+
export type FoilKind = keyof typeof foilHooks;
|
|
110
|
+
|
|
111
|
+
/** Stable hook plus compiled atoms; caller classes stay last and win conflicts. */
|
|
112
|
+
export function foilClassName(kind: FoilKind, caller?: string): string {
|
|
113
|
+
const hook = foilHooks[kind];
|
|
114
|
+
return [hook, stylex.props(foilStyles[kind]).className, caller]
|
|
115
|
+
.filter((value) => value !== undefined && value.length > 0).join(" ");
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
const markStyles = stylex.create({
|
|
120
|
+
root: {
|
|
121
|
+
"display": "inline-flex",
|
|
122
|
+
"position": "relative",
|
|
123
|
+
"flex-shrink": "0",
|
|
124
|
+
"color": "var(--foreground, CanvasText)",
|
|
125
|
+
"line-height": "0",
|
|
126
|
+
"vertical-align": "middle",
|
|
127
|
+
"inline-size": "var(--hraness-foil-size, 1.5rem)",
|
|
128
|
+
"block-size": "var(--hraness-foil-size, 1.5rem)",
|
|
129
|
+
},
|
|
130
|
+
image: {
|
|
131
|
+
"display": "block",
|
|
132
|
+
"inline-size": "100%",
|
|
133
|
+
"block-size": "100%",
|
|
134
|
+
"object-fit": "contain",
|
|
135
|
+
},
|
|
136
|
+
paint: {
|
|
137
|
+
...foilStops,
|
|
138
|
+
// A generic display:none atom can be repeated by a later package layer and
|
|
139
|
+
// override our supported-mask state. Keep the conditional state mark-owned.
|
|
140
|
+
"display": "var(--_hraness-foil-mark-display)",
|
|
141
|
+
"--_hraness-foil-mark-display": {
|
|
142
|
+
"default": "none",
|
|
143
|
+
"@supports (mask-image: linear-gradient(black, black))": {
|
|
144
|
+
"default": "block",
|
|
145
|
+
"@media (forced-colors: active)": "none",
|
|
146
|
+
},
|
|
147
|
+
},
|
|
148
|
+
"position": "absolute",
|
|
149
|
+
"inset": "0",
|
|
150
|
+
"pointer-events": "none",
|
|
151
|
+
"background-image": foilTextImage,
|
|
152
|
+
"mask-image": "var(--hraness-foil-mask, linear-gradient(transparent, transparent))",
|
|
153
|
+
"mask-mode": "alpha",
|
|
154
|
+
"mask-repeat": "no-repeat",
|
|
155
|
+
"mask-position": "center",
|
|
156
|
+
"mask-size": "contain",
|
|
157
|
+
},
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
export function foilMarkClassName(part: keyof typeof markStyles, caller?: string): string {
|
|
161
|
+
const hook = part === "root" ? "hraness-foil-mark" : `hraness-foil-mark__${part}`;
|
|
162
|
+
return [hook, stylex.props(markStyles[part]).className, caller].filter(Boolean).join(" ");
|
|
163
|
+
}
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useCallback, useEffect } from "react";
|
|
4
|
+
import type { WebHaptics } from "web-haptics";
|
|
5
|
+
|
|
6
|
+
export type HapticFeedback = "error" | "press" | "selection" | "success" | "warning";
|
|
7
|
+
export type HapticFeedbackInput = "error" | "medium" | "selection" | "success" | "warning";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Browser-only proof seam emitted after Web Haptics accepts and completes a
|
|
11
|
+
* semantic trigger. Product behavior must never depend on this event.
|
|
12
|
+
*/
|
|
13
|
+
export const HAPTIC_FEEDBACK_EVENT_NAME = "hraness-design:haptic-feedback";
|
|
14
|
+
|
|
15
|
+
export interface HapticFeedbackEventDetail {
|
|
16
|
+
readonly feedback: HapticFeedback;
|
|
17
|
+
readonly input: HapticFeedbackInput;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface HapticBrowserEnvironment {
|
|
21
|
+
readonly document?: unknown;
|
|
22
|
+
readonly navigator?: unknown;
|
|
23
|
+
readonly window?: unknown;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
type HapticEngine = Pick<WebHaptics, "cancel" | "destroy" | "trigger">;
|
|
27
|
+
type HapticEngineConstructor = new (
|
|
28
|
+
options?: Readonly<{ debug?: boolean; showSwitch?: boolean }>,
|
|
29
|
+
) => HapticEngine;
|
|
30
|
+
|
|
31
|
+
export interface HapticModule {
|
|
32
|
+
readonly WebHaptics: HapticEngineConstructor;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface HapticFeedbackController {
|
|
36
|
+
readonly cancel: () => boolean;
|
|
37
|
+
readonly dispose: () => void;
|
|
38
|
+
readonly prepare: () => Promise<boolean>;
|
|
39
|
+
readonly trigger: (feedback?: HapticFeedback) => Promise<boolean>;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** The adapter is deliberately inert during SSR and other DOM-less runtimes. */
|
|
43
|
+
export function isHapticBrowserEnvironment(
|
|
44
|
+
environment: HapticBrowserEnvironment = globalThis,
|
|
45
|
+
): boolean {
|
|
46
|
+
return typeof environment.window === "object"
|
|
47
|
+
&& typeof environment.document === "object"
|
|
48
|
+
&& typeof environment.navigator === "object";
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/** Maps product-neutral intent to WebHaptics' short semantic presets. */
|
|
52
|
+
export function hapticInputForFeedback(feedback: HapticFeedback): HapticFeedbackInput {
|
|
53
|
+
switch (feedback) {
|
|
54
|
+
case "error":
|
|
55
|
+
return "error";
|
|
56
|
+
case "press":
|
|
57
|
+
return "medium";
|
|
58
|
+
case "selection":
|
|
59
|
+
return "selection";
|
|
60
|
+
case "success":
|
|
61
|
+
return "success";
|
|
62
|
+
case "warning":
|
|
63
|
+
return "warning";
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function hasCustomEventConstructor(
|
|
68
|
+
candidate: unknown,
|
|
69
|
+
): candidate is Readonly<{ CustomEvent: typeof CustomEvent }> {
|
|
70
|
+
return typeof candidate === "object"
|
|
71
|
+
&& candidate !== null
|
|
72
|
+
&& "CustomEvent" in candidate
|
|
73
|
+
&& typeof candidate.CustomEvent === "function";
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function hasEventDispatcher(
|
|
77
|
+
candidate: unknown,
|
|
78
|
+
): candidate is Readonly<{ dispatchEvent: (event: Event) => boolean }> {
|
|
79
|
+
return typeof candidate === "object"
|
|
80
|
+
&& candidate !== null
|
|
81
|
+
&& "dispatchEvent" in candidate
|
|
82
|
+
&& typeof candidate.dispatchEvent === "function";
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function dispatchHapticFeedbackEvent(
|
|
86
|
+
environment: HapticBrowserEnvironment,
|
|
87
|
+
detail: HapticFeedbackEventDetail,
|
|
88
|
+
): void {
|
|
89
|
+
if (!hasCustomEventConstructor(environment.window)
|
|
90
|
+
|| !hasEventDispatcher(environment.document)) return;
|
|
91
|
+
try {
|
|
92
|
+
environment.document.dispatchEvent(
|
|
93
|
+
new environment.window.CustomEvent<HapticFeedbackEventDetail>(
|
|
94
|
+
HAPTIC_FEEDBACK_EVENT_NAME,
|
|
95
|
+
{ detail },
|
|
96
|
+
),
|
|
97
|
+
);
|
|
98
|
+
} catch {
|
|
99
|
+
// The verification signal is observational and must not affect feedback.
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function cancelAndDestroy(candidate: HapticEngine): void {
|
|
104
|
+
try {
|
|
105
|
+
candidate.cancel();
|
|
106
|
+
} catch {
|
|
107
|
+
// Continue into destroy even if a browser backend rejects cancellation.
|
|
108
|
+
}
|
|
109
|
+
try {
|
|
110
|
+
candidate.destroy();
|
|
111
|
+
} catch {
|
|
112
|
+
// Optional feedback must never make application teardown fail.
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Isolated lifecycle controller. Passing the environment and loader keeps the
|
|
118
|
+
* browser path deterministic in tests without installing or mutating globals.
|
|
119
|
+
*/
|
|
120
|
+
export function createHapticFeedbackController(
|
|
121
|
+
environment: HapticBrowserEnvironment,
|
|
122
|
+
loadModule: () => Promise<HapticModule>,
|
|
123
|
+
): HapticFeedbackController {
|
|
124
|
+
let engine: HapticEngine | null = null;
|
|
125
|
+
let enginePromise: Promise<HapticEngine | null> | null = null;
|
|
126
|
+
let engineGeneration = 0;
|
|
127
|
+
|
|
128
|
+
const loadEngine = async (): Promise<HapticEngine | null> => {
|
|
129
|
+
if (!isHapticBrowserEnvironment(environment)) return null;
|
|
130
|
+
if (engine !== null) return engine;
|
|
131
|
+
if (enginePromise !== null) return enginePromise;
|
|
132
|
+
|
|
133
|
+
const generation = engineGeneration;
|
|
134
|
+
const pendingEngine = loadModule()
|
|
135
|
+
.then(({ WebHaptics }) => {
|
|
136
|
+
if (!isHapticBrowserEnvironment(environment)) return null;
|
|
137
|
+
const candidate = new WebHaptics({ debug: false, showSwitch: false });
|
|
138
|
+
if (generation !== engineGeneration) {
|
|
139
|
+
cancelAndDestroy(candidate);
|
|
140
|
+
return null;
|
|
141
|
+
}
|
|
142
|
+
engine = candidate;
|
|
143
|
+
return candidate;
|
|
144
|
+
})
|
|
145
|
+
.catch(() => null);
|
|
146
|
+
enginePromise = pendingEngine;
|
|
147
|
+
void pendingEngine.finally(() => {
|
|
148
|
+
if (enginePromise === pendingEngine) enginePromise = null;
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
return pendingEngine;
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
return {
|
|
155
|
+
cancel() {
|
|
156
|
+
if (engine === null) return false;
|
|
157
|
+
try {
|
|
158
|
+
engine.cancel();
|
|
159
|
+
return true;
|
|
160
|
+
} catch {
|
|
161
|
+
return false;
|
|
162
|
+
}
|
|
163
|
+
},
|
|
164
|
+
dispose() {
|
|
165
|
+
engineGeneration += 1;
|
|
166
|
+
const activeEngine = engine;
|
|
167
|
+
engine = null;
|
|
168
|
+
enginePromise = null;
|
|
169
|
+
if (activeEngine !== null) cancelAndDestroy(activeEngine);
|
|
170
|
+
},
|
|
171
|
+
async prepare() {
|
|
172
|
+
return await loadEngine() !== null;
|
|
173
|
+
},
|
|
174
|
+
async trigger(feedback: HapticFeedback = "press") {
|
|
175
|
+
try {
|
|
176
|
+
const activeEngine = await loadEngine();
|
|
177
|
+
if (activeEngine === null) return false;
|
|
178
|
+
const input = hapticInputForFeedback(feedback);
|
|
179
|
+
await activeEngine.trigger(input);
|
|
180
|
+
dispatchHapticFeedbackEvent(environment, { feedback, input });
|
|
181
|
+
return true;
|
|
182
|
+
} catch {
|
|
183
|
+
return false;
|
|
184
|
+
}
|
|
185
|
+
},
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
const browserHaptics = createHapticFeedbackController(globalThis, async () => {
|
|
190
|
+
const { WebHaptics } = await import("web-haptics");
|
|
191
|
+
return { WebHaptics };
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
/** Warms the browser-only engine so a later user gesture can trigger synchronously. */
|
|
195
|
+
export async function prepareHapticFeedback(): Promise<boolean> {
|
|
196
|
+
return await browserHaptics.prepare();
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/** Triggers semantic feedback and degrades to a no-op when unavailable or blocked. */
|
|
200
|
+
export async function triggerHapticFeedback(
|
|
201
|
+
feedback: HapticFeedback = "press",
|
|
202
|
+
): Promise<boolean> {
|
|
203
|
+
return await browserHaptics.trigger(feedback);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
export function cancelHapticFeedback(): boolean {
|
|
207
|
+
return browserHaptics.cancel();
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
export function disposeHapticFeedback(): void {
|
|
211
|
+
browserHaptics.dispose();
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/** Opt-in React adapter. Disabled callers do not preload the package. */
|
|
215
|
+
export function useHapticFeedback(enabled = true): (
|
|
216
|
+
feedback?: HapticFeedback,
|
|
217
|
+
) => Promise<boolean> {
|
|
218
|
+
useEffect(() => {
|
|
219
|
+
if (enabled) void prepareHapticFeedback();
|
|
220
|
+
}, [enabled]);
|
|
221
|
+
|
|
222
|
+
return useCallback(
|
|
223
|
+
async (feedback: HapticFeedback = "press") => enabled
|
|
224
|
+
? await triggerHapticFeedback(feedback)
|
|
225
|
+
: false,
|
|
226
|
+
[enabled],
|
|
227
|
+
);
|
|
228
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import type { ReactNode } from "react";
|
|
4
|
+
|
|
5
|
+
/** @deprecated Hero backdrops are retired; `HeroBackdrop` renders nothing. */
|
|
6
|
+
export interface HeroBackdropProps {
|
|
7
|
+
/** @deprecated Ignored. */
|
|
8
|
+
readonly seed: string;
|
|
9
|
+
/** @deprecated Ignored. Decorative artwork no longer renders; put real product proof in the hero `frame`. */
|
|
10
|
+
readonly children?: ReactNode;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* @deprecated Retired with the Quiet marketing direction. The component stays
|
|
15
|
+
* exported so existing callers compile, but it renders nothing: no light
|
|
16
|
+
* field, drift, blur, or product artwork. Remove it when convenient and show
|
|
17
|
+
* real product proof in `ProductHero`'s `frame` instead.
|
|
18
|
+
*/
|
|
19
|
+
export function HeroBackdrop(props: HeroBackdropProps): null {
|
|
20
|
+
void props;
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
export * from "./animated-rail-stage.js";
|
|
2
|
+
export * from "./app-shell.js";
|
|
3
|
+
export * from "./article.js";
|
|
4
|
+
export * from "./aurora-dots-background.js";
|
|
5
|
+
export * from "./charts.js";
|
|
6
|
+
export * from "./chat.js";
|
|
7
|
+
export * from "./design-theme-context.js";
|
|
8
|
+
export * from "./design-palette.js";
|
|
9
|
+
export * from "./design-gallery.js";
|
|
10
|
+
export * from "./fader.js";
|
|
11
|
+
export * from "./foil-card-math.js";
|
|
12
|
+
export * from "./foil-card-surface.js";
|
|
13
|
+
export * from "./foil.stylex.js";
|
|
14
|
+
export * from "./haptics.js";
|
|
15
|
+
export * from "./hero-backdrop.js";
|
|
16
|
+
export * from "./keyboard-shortcuts.js";
|
|
17
|
+
export * from "./lantern-material.stylex.js";
|
|
18
|
+
export * from "./lantern-material-gallery.js";
|
|
19
|
+
export * from "./navigation-rail.js";
|
|
20
|
+
export * from "./particle-halo.js";
|
|
21
|
+
export * from "./phaser-dots.js";
|
|
22
|
+
export * from "./playback-transport.js";
|
|
23
|
+
export * from "./procedural-backdrop.js";
|
|
24
|
+
export * from "./procedural-recipe.js";
|
|
25
|
+
export * from "./relative-time.js";
|
|
26
|
+
export * from "./production-data-preview-notice.js";
|
|
27
|
+
export * from "./product-marketing.js";
|
|
28
|
+
export * from "./route-state.js";
|
|
29
|
+
export * from "./sticky-offset.js";
|
|
30
|
+
export * from "./surfaces.js";
|
|
31
|
+
export * from "./syntax-code.js";
|
|
32
|
+
export * from "./theme.js";
|
|
33
|
+
export * from "./foil-mark.js";
|
|
34
|
+
export * from "./provider-mark.js";
|
|
35
|
+
export * from "./launch-beats.js";
|
|
36
|
+
export * from "./social-kit-panel.js";
|
|
37
|
+
export * from "./platform-icons.js";
|
|
38
|
+
export * from "./platform-install.js";
|