@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,943 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
Badge,
|
|
5
|
+
Button,
|
|
6
|
+
Card,
|
|
7
|
+
CardContent,
|
|
8
|
+
CardDescription,
|
|
9
|
+
CardHeader,
|
|
10
|
+
CardTitle,
|
|
11
|
+
Icon,
|
|
12
|
+
LinkButton,
|
|
13
|
+
SegmentedControl,
|
|
14
|
+
Slider,
|
|
15
|
+
Tag,
|
|
16
|
+
ViewportFrame,
|
|
17
|
+
WrappingRow,
|
|
18
|
+
} from "@hraness/ui";
|
|
19
|
+
import { Chart01Icon, CodeIcon, DashboardSquare01Icon } from "@hugeicons/core-free-icons";
|
|
20
|
+
import { useState } from "react";
|
|
21
|
+
|
|
22
|
+
import { AnimatedRailStage } from "./animated-rail-stage.js";
|
|
23
|
+
import { AppShell } from "./app-shell.js";
|
|
24
|
+
import {
|
|
25
|
+
ArticleCallout,
|
|
26
|
+
ArticleIndex,
|
|
27
|
+
ArticleSources,
|
|
28
|
+
MarketingArticle,
|
|
29
|
+
} from "./article.js";
|
|
30
|
+
import { AuroraDotsBackground } from "./aurora-dots-background.js";
|
|
31
|
+
import { BarListChart, RangePlotChart } from "./charts.js";
|
|
32
|
+
import { ChatComposer, ChatMessage } from "./chat.js";
|
|
33
|
+
import { Fader } from "./fader.js";
|
|
34
|
+
import { FoilCardDeck, FoilCardSurface } from "./foil-card-surface.js";
|
|
35
|
+
import { FoilMark } from "./foil-mark.js";
|
|
36
|
+
import { foilClassName } from "./foil.stylex.js";
|
|
37
|
+
import { LanternMaterialGallery } from "./lantern-material-gallery.js";
|
|
38
|
+
import { NavigationRail, RailItem, RailSection } from "./navigation-rail.js";
|
|
39
|
+
import { PlaybackTransport, type PlaybackTransportStatus } from "./playback-transport.js";
|
|
40
|
+
import { ProceduralBackdrop } from "./procedural-backdrop.js";
|
|
41
|
+
import { StatusPage } from "./route-state.js";
|
|
42
|
+
import { ProductionDataPreviewNotice } from "./production-data-preview-notice.js";
|
|
43
|
+
import { ProviderMark } from "./provider-mark.js";
|
|
44
|
+
import { PlatformBadges } from "./platform-icons.js";
|
|
45
|
+
import { PlatformInstall } from "./platform-install.js";
|
|
46
|
+
import { RelativeTime } from "./relative-time.js";
|
|
47
|
+
import {
|
|
48
|
+
MarketingCallToAction,
|
|
49
|
+
MarketingCardRow,
|
|
50
|
+
MarketingCodeBlock,
|
|
51
|
+
MarketingDataTable,
|
|
52
|
+
MarketingFlow,
|
|
53
|
+
MarketingField,
|
|
54
|
+
MarketingInstallPanel,
|
|
55
|
+
MarketingInterfaceGrid,
|
|
56
|
+
MarketingMain,
|
|
57
|
+
MarketingMaker,
|
|
58
|
+
MarketingPage,
|
|
59
|
+
MarketingPillars,
|
|
60
|
+
MarketingPricing,
|
|
61
|
+
MarketingPrimitives,
|
|
62
|
+
MarketingProofFrame,
|
|
63
|
+
MarketingQuestionList,
|
|
64
|
+
MarketingRelated,
|
|
65
|
+
MarketingQuoteGrid,
|
|
66
|
+
MarketingSection,
|
|
67
|
+
MarketingSectionLabel,
|
|
68
|
+
MarketingSiteFooter,
|
|
69
|
+
MarketingSiteHeader,
|
|
70
|
+
MarketingStatStrip,
|
|
71
|
+
MarketingTrustBoundary,
|
|
72
|
+
ProductHero,
|
|
73
|
+
} from "./product-marketing.js";
|
|
74
|
+
import {
|
|
75
|
+
BottomBar,
|
|
76
|
+
DitherSurface,
|
|
77
|
+
DockedFooter,
|
|
78
|
+
PageCanvas,
|
|
79
|
+
TopBar,
|
|
80
|
+
} from "./surfaces.js";
|
|
81
|
+
import { SyntaxCode } from "./syntax-code.js";
|
|
82
|
+
import { type ConcreteDesignTheme, type DesignTheme } from "./theme.js";
|
|
83
|
+
|
|
84
|
+
export const designGallerySections = [
|
|
85
|
+
{ id: "foundation", label: "Foundation" },
|
|
86
|
+
{ id: "paper-theme", label: "Paper theme" },
|
|
87
|
+
{ id: "lantern", label: "Lantern" },
|
|
88
|
+
{ id: "marketing", label: "Marketing" },
|
|
89
|
+
{ id: "articles", label: "Articles" },
|
|
90
|
+
{ id: "status-pages", label: "Status pages" },
|
|
91
|
+
{ id: "shells", label: "Shells" },
|
|
92
|
+
{ id: "data", label: "Data" },
|
|
93
|
+
{ id: "effects", label: "Effects" },
|
|
94
|
+
{ id: "syntax", label: "Syntax" },
|
|
95
|
+
] as const;
|
|
96
|
+
|
|
97
|
+
/** Representative semantic control kinds every gallery consumer must exercise. */
|
|
98
|
+
export const designGalleryTouchKinds = [
|
|
99
|
+
"button",
|
|
100
|
+
"link",
|
|
101
|
+
"radio",
|
|
102
|
+
"range",
|
|
103
|
+
] as const;
|
|
104
|
+
|
|
105
|
+
export const designGalleryRecipeCoverage = [
|
|
106
|
+
"@hraness/ui primitives",
|
|
107
|
+
"animated rail stage",
|
|
108
|
+
"application shells",
|
|
109
|
+
"article layer",
|
|
110
|
+
"charts",
|
|
111
|
+
"chat message and composer",
|
|
112
|
+
"dither surface",
|
|
113
|
+
"fader",
|
|
114
|
+
"foil card surface",
|
|
115
|
+
"layout surfaces",
|
|
116
|
+
"Lantern material",
|
|
117
|
+
"playback transport",
|
|
118
|
+
"plain site and publication grammar",
|
|
119
|
+
"product-marketing grammar",
|
|
120
|
+
"Nebula Sans typography",
|
|
121
|
+
"procedural effects",
|
|
122
|
+
"platform install commands",
|
|
123
|
+
"production preview notice",
|
|
124
|
+
"relative time",
|
|
125
|
+
"status pages",
|
|
126
|
+
"syntax highlighting",
|
|
127
|
+
] as const;
|
|
128
|
+
|
|
129
|
+
/** A fixed reference keeps the gallery's relative times deterministic. */
|
|
130
|
+
export const designGalleryRelativeTimeNow = Date.UTC(2026, 8, 26, 12, 0, 0);
|
|
131
|
+
const relativeTimeExamples = [
|
|
132
|
+
{ id: "seconds", value: designGalleryRelativeTimeNow - 12_000 },
|
|
133
|
+
{ id: "minutes", value: designGalleryRelativeTimeNow - 5 * 60_000 },
|
|
134
|
+
{ id: "hours", value: designGalleryRelativeTimeNow + 23 * 3_600_000 },
|
|
135
|
+
{ id: "months", value: designGalleryRelativeTimeNow - 62 * 86_400_000 },
|
|
136
|
+
] as const;
|
|
137
|
+
|
|
138
|
+
/** Resolves the gallery's System choice through the live OS preference. */
|
|
139
|
+
export function resolveGalleryTheme(
|
|
140
|
+
theme: DesignTheme,
|
|
141
|
+
prefersDark: boolean,
|
|
142
|
+
): ConcreteDesignTheme {
|
|
143
|
+
return theme === "system" ? (prefersDark ? "dark" : "light") : theme;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
const barData = [
|
|
147
|
+
{ id: "alpha", label: "Alpha", value: 72, detail: "72 requests" },
|
|
148
|
+
{ id: "beta", label: "Beta", value: 48, detail: "48 requests" },
|
|
149
|
+
{ id: "gamma", label: "Gamma", value: 31, detail: "31 requests" },
|
|
150
|
+
] as const;
|
|
151
|
+
|
|
152
|
+
const rangeData = [
|
|
153
|
+
{ id: "north", label: "North", minimum: 24, median: 51, maximum: 78 },
|
|
154
|
+
{ id: "south", label: "South", minimum: 38, median: 64, maximum: 82 },
|
|
155
|
+
] as const;
|
|
156
|
+
|
|
157
|
+
const foilDeckExamples = [
|
|
158
|
+
{ label: "Corner frame", ornament: "corners", preset: "prism" },
|
|
159
|
+
{ label: "Rail frame", ornament: "rails", preset: "etched" },
|
|
160
|
+
{ label: "Circuit frame", ornament: "circuit", preset: "fast" },
|
|
161
|
+
{ label: "Radial frame", ornament: "radial", preset: "aurora" },
|
|
162
|
+
{ label: "Facet frame", ornament: "facets", preset: "max" },
|
|
163
|
+
] as const;
|
|
164
|
+
|
|
165
|
+
/** Product-neutral executable reference for the public composition layer. */
|
|
166
|
+
export function DesignSystemGallery({
|
|
167
|
+
isNestedInMain = false,
|
|
168
|
+
}: Readonly<{ isNestedInMain?: boolean }>) {
|
|
169
|
+
const [density, setDensity] = useState<"compact" | "default">("default");
|
|
170
|
+
const [chatDraft, setChatDraft] = useState("Review the presentation contract");
|
|
171
|
+
const [chatSubmission, setChatSubmission] = useState("");
|
|
172
|
+
const [faderValue, setFaderValue] = useState(64);
|
|
173
|
+
const [playbackStatus, setPlaybackStatus] = useState<PlaybackTransportStatus>("idle");
|
|
174
|
+
const Root = isNestedInMain ? "div" : "main";
|
|
175
|
+
|
|
176
|
+
return (
|
|
177
|
+
<Root
|
|
178
|
+
className="design-gallery"
|
|
179
|
+
data-design-gallery="public"
|
|
180
|
+
data-design-gallery-nested={isNestedInMain ? "true" : "false"}
|
|
181
|
+
>
|
|
182
|
+
<header className="design-gallery__intro">
|
|
183
|
+
<Badge tone="info">@hraness/design-kit</Badge>
|
|
184
|
+
<h1>Presentation and composition reference</h1>
|
|
185
|
+
<p>
|
|
186
|
+
Portable controls come from @hraness/ui. This package adds application
|
|
187
|
+
shells, charts, effects, syntax, and haptics.
|
|
188
|
+
</p>
|
|
189
|
+
<p>
|
|
190
|
+
System follows your device on the first visit. Choosing Light, Dark,
|
|
191
|
+
or System saves that preference.
|
|
192
|
+
</p>
|
|
193
|
+
<WrappingRow>
|
|
194
|
+
<SegmentedControl
|
|
195
|
+
aria-label="Gallery density"
|
|
196
|
+
items={[
|
|
197
|
+
{ id: "compact", label: "Compact" },
|
|
198
|
+
{ id: "default", label: "Default" },
|
|
199
|
+
]}
|
|
200
|
+
onChange={setDensity}
|
|
201
|
+
size="compact"
|
|
202
|
+
value={density}
|
|
203
|
+
/>
|
|
204
|
+
</WrappingRow>
|
|
205
|
+
</header>
|
|
206
|
+
|
|
207
|
+
<section className="design-gallery__section" id="foundation">
|
|
208
|
+
<h2>Foundation boundary</h2>
|
|
209
|
+
<ProductionDataPreviewNotice surfaceOrigin="https://preview.example.test" />
|
|
210
|
+
<div className="design-gallery__grid">
|
|
211
|
+
<Card>
|
|
212
|
+
<CardHeader>
|
|
213
|
+
<CardTitle>Portable control</CardTitle>
|
|
214
|
+
<CardDescription>Rendered directly by @hraness/ui.</CardDescription>
|
|
215
|
+
</CardHeader>
|
|
216
|
+
<CardContent>
|
|
217
|
+
<WrappingRow>
|
|
218
|
+
<Button variant="primary">Primary action</Button>
|
|
219
|
+
<LinkButton href="#shells">Open shells</LinkButton>
|
|
220
|
+
<Tag variant="outline">public core</Tag>
|
|
221
|
+
</WrappingRow>
|
|
222
|
+
</CardContent>
|
|
223
|
+
</Card>
|
|
224
|
+
<Card>
|
|
225
|
+
<CardHeader>
|
|
226
|
+
<CardTitle>Typography roles</CardTitle>
|
|
227
|
+
<CardDescription>Nebula Sans for proportional text; mono stays explicit.</CardDescription>
|
|
228
|
+
</CardHeader>
|
|
229
|
+
<CardContent>
|
|
230
|
+
<div className="design-gallery__type-specimen">
|
|
231
|
+
<p data-gallery-font="proportional">Nebula Sans sets both headings and body text.</p>
|
|
232
|
+
<code data-gallery-font="mono">const role = "mono";</code>
|
|
233
|
+
</div>
|
|
234
|
+
</CardContent>
|
|
235
|
+
</Card>
|
|
236
|
+
<Card>
|
|
237
|
+
<CardHeader>
|
|
238
|
+
<CardTitle>Provider marks</CardTitle>
|
|
239
|
+
<CardDescription>Vendored agent and vendor artwork on accent-tinted tiles.</CardDescription>
|
|
240
|
+
</CardHeader>
|
|
241
|
+
<CardContent>
|
|
242
|
+
<WrappingRow>
|
|
243
|
+
<ProviderMark mark="claudecode" label="Claude Code" size={40} />
|
|
244
|
+
<ProviderMark mark="codex" label="Codex" size={40} />
|
|
245
|
+
<ProviderMark mark="opencode" label="opencode" size={40} />
|
|
246
|
+
<ProviderMark mark="crush" label="Crush" size={40} />
|
|
247
|
+
<ProviderMark mark="aider" label="Aider" size={40} />
|
|
248
|
+
<ProviderMark mark="goose" label="Goose" size={40} />
|
|
249
|
+
<ProviderMark mark="gemini" label="Gemini" size={40} />
|
|
250
|
+
<ProviderMark mark="nvidia" label="NVIDIA" size={40} />
|
|
251
|
+
</WrappingRow>
|
|
252
|
+
</CardContent>
|
|
253
|
+
</Card>
|
|
254
|
+
</div>
|
|
255
|
+
<div
|
|
256
|
+
aria-label="Plain site link presentation"
|
|
257
|
+
className="design-gallery__plain-theme plain-site plain-publication"
|
|
258
|
+
>
|
|
259
|
+
<header className="plain-header">
|
|
260
|
+
<div className="plain-header__inner" data-layout="responsive-wrap">
|
|
261
|
+
<a className="plain-wordmark" href="#foundation">project-name.example</a>
|
|
262
|
+
<nav aria-label="Plain site example" className="plain-nav">
|
|
263
|
+
<a href="#foundation">Articles</a>
|
|
264
|
+
<a href="#shells">About</a>
|
|
265
|
+
</nav>
|
|
266
|
+
</div>
|
|
267
|
+
</header>
|
|
268
|
+
<div className="plain-page">
|
|
269
|
+
<p className="design-gallery__plain-link-example">
|
|
270
|
+
Ordinary <a href="#foundation">blue links</a> stay quiet until interaction.
|
|
271
|
+
</p>
|
|
272
|
+
</div>
|
|
273
|
+
</div>
|
|
274
|
+
</section>
|
|
275
|
+
|
|
276
|
+
<section className="design-gallery__section" id="paper-theme">
|
|
277
|
+
<h2>Paper theme</h2>
|
|
278
|
+
<p>Import paper-theme.css to share warm neutral colors and compact typography without replacing layouts or saved appearance choices.</p>
|
|
279
|
+
<div className="design-gallery__paper" data-hraness-theme="paper" data-theme="light">
|
|
280
|
+
<MarketingSiteHeader brand="Light paper" brandHref="#paper-theme" links={[{ href: "#foundation", label: "Foundation" }]} sticky={false} />
|
|
281
|
+
<TopBar surface="glass" title="Glass application header" data-gallery-glass-top-bar="" />
|
|
282
|
+
<h3>Light paper</h3><p>Headers blur scrolling content and become opaque when reduced transparency is preferred.</p>
|
|
283
|
+
<p><a className="design-gallery__paper-link" href="#foundation">Read about the foundation</a></p>
|
|
284
|
+
<Button variant="primary">Create note</Button>
|
|
285
|
+
</div>
|
|
286
|
+
<div className="design-gallery__paper" data-hraness-theme="paper" data-theme="dark">
|
|
287
|
+
<MarketingSiteHeader brand="Dark paper" brandHref="#paper-theme" links={[{ href: "#foundation", label: "Foundation" }]} sticky={false} />
|
|
288
|
+
<TopBar surface="glass" title="Glass application header" data-gallery-glass-top-bar="" />
|
|
289
|
+
<h3>Dark paper</h3><p>The same header treatment follows an explicit dark preference.</p>
|
|
290
|
+
<p><a className="design-gallery__paper-link" href="#foundation">Read about the foundation</a></p>
|
|
291
|
+
<Button variant="primary">Open notes</Button>
|
|
292
|
+
</div>
|
|
293
|
+
</section>
|
|
294
|
+
|
|
295
|
+
<LanternMaterialGallery />
|
|
296
|
+
|
|
297
|
+
<section className="design-gallery__section" id="marketing">
|
|
298
|
+
<h2>Product-marketing grammar</h2>
|
|
299
|
+
<MarketingPage className="design-gallery__marketing">
|
|
300
|
+
<MarketingSiteHeader
|
|
301
|
+
action={{ href: "#gallery-install", label: "Install Relay" }}
|
|
302
|
+
brand="Relay"
|
|
303
|
+
sticky={false}
|
|
304
|
+
links={[
|
|
305
|
+
{ current: true, href: "#marketing", label: "How it works" },
|
|
306
|
+
{ href: "#gallery-install", label: "Install" },
|
|
307
|
+
{ href: "#shells", label: "Docs" },
|
|
308
|
+
]}
|
|
309
|
+
/>
|
|
310
|
+
<MarketingMain>
|
|
311
|
+
<ProductHero
|
|
312
|
+
actions={[
|
|
313
|
+
{ href: "#gallery-install", label: "Install Relay" },
|
|
314
|
+
{ href: "#shells", label: "See the workspace" },
|
|
315
|
+
]}
|
|
316
|
+
boundary="Free for local use on macOS and Linux · version 1.2.3"
|
|
317
|
+
className="design-gallery__marketing-hero"
|
|
318
|
+
example="Ask your agent to run the nightly job and show you the log."
|
|
319
|
+
eyebrow="A reference developer tool"
|
|
320
|
+
facts={[
|
|
321
|
+
{ detail: "Any Git checkout.", label: "Input", value: "Repository" },
|
|
322
|
+
{ detail: "Plain JSON you can read.", label: "Output", value: "Run log" },
|
|
323
|
+
{ detail: "Terminal or TypeScript.", label: "Interfaces", value: "CLI + SDK" },
|
|
324
|
+
]}
|
|
325
|
+
factsColumns={3}
|
|
326
|
+
frame={(
|
|
327
|
+
<MarketingProofFrame
|
|
328
|
+
caption="The log written by the example job."
|
|
329
|
+
credit="Captured 5 September 2026"
|
|
330
|
+
title="relay run job-01"
|
|
331
|
+
>
|
|
332
|
+
<MarketingCodeBlock className="design-gallery__marketing-command" code={'{"status":"complete","job":"job-01","durationMs":412}'} language="json" />
|
|
333
|
+
</MarketingProofFrame>
|
|
334
|
+
)}
|
|
335
|
+
heading="Run a job from your terminal, your code, or your agent"
|
|
336
|
+
headingId="design-gallery-marketing-title"
|
|
337
|
+
headingLevel={3}
|
|
338
|
+
name="Relay"
|
|
339
|
+
notice={<p data-gallery-marketing-slot="notice">This example release runs locally.</p>}
|
|
340
|
+
summary="Relay runs the same job wherever you start it and writes a log you can read afterward: inputs, outputs, and how long it took."
|
|
341
|
+
/>
|
|
342
|
+
<MarketingPillars
|
|
343
|
+
ariaLabel="Relay in three points"
|
|
344
|
+
columns={3}
|
|
345
|
+
pillars={[
|
|
346
|
+
{ label: "No hosted service", summary: "Jobs run on your machine and never wait on a server." },
|
|
347
|
+
{ label: "A log for every run", summary: "Open it to see what went in, what came out, and when." },
|
|
348
|
+
{ label: "Your files stay put", summary: "Source files and credentials never leave your machine." },
|
|
349
|
+
]}
|
|
350
|
+
/>
|
|
351
|
+
<MarketingInstallPanel
|
|
352
|
+
eyebrow="Local release"
|
|
353
|
+
heading="Install Relay and run your first job."
|
|
354
|
+
headingId="design-gallery-install-title"
|
|
355
|
+
headingLevel={3}
|
|
356
|
+
id="gallery-install"
|
|
357
|
+
note={<p data-gallery-marketing-slot="note">Requires Bun 1.3.14.</p>}
|
|
358
|
+
>
|
|
359
|
+
<PlatformInstall
|
|
360
|
+
id="design-gallery-platform-install"
|
|
361
|
+
platforms={[
|
|
362
|
+
{
|
|
363
|
+
alternatives: [{ command: "brew install relay", label: "Homebrew" }],
|
|
364
|
+
command: "curl -fsSL https://relay.example/install.sh | sh",
|
|
365
|
+
id: "macos",
|
|
366
|
+
note: "Apple silicon and Intel, macOS 13 or later.",
|
|
367
|
+
shell: "Terminal",
|
|
368
|
+
},
|
|
369
|
+
{
|
|
370
|
+
alternatives: [{ command: "bun add --global relay@1.2.3", label: "Bun" }],
|
|
371
|
+
command: "curl -fsSL https://relay.example/install.sh | sh",
|
|
372
|
+
id: "linux",
|
|
373
|
+
note: "x86_64 and ARM64, glibc 2.34 or later.",
|
|
374
|
+
shell: "Terminal",
|
|
375
|
+
},
|
|
376
|
+
{
|
|
377
|
+
command: "curl -fsSL https://relay.example/install.sh | sh",
|
|
378
|
+
id: "windows",
|
|
379
|
+
shell: "WSL2 terminal",
|
|
380
|
+
unavailable: true,
|
|
381
|
+
unavailableNote: <p>No native Windows build yet. Relay runs in WSL2.</p>,
|
|
382
|
+
},
|
|
383
|
+
]}
|
|
384
|
+
/>
|
|
385
|
+
<PlatformBadges platforms={["macos", "linux", { id: "windows", note: "via WSL2" }]} />
|
|
386
|
+
<MarketingFlow
|
|
387
|
+
ariaLabel="First Relay job"
|
|
388
|
+
steps={[
|
|
389
|
+
{ code: "relay init", detail: "Create a workspace.", label: "Initialize" },
|
|
390
|
+
{ code: "relay run job-01", detail: "Run a job by name.", label: "Run" },
|
|
391
|
+
{ code: "relay inspect job-01", detail: "Read its log.", label: "Inspect" },
|
|
392
|
+
]}
|
|
393
|
+
/>
|
|
394
|
+
</MarketingInstallPanel>
|
|
395
|
+
<MarketingPrimitives
|
|
396
|
+
heading="Three objects cover most work."
|
|
397
|
+
headingId="design-gallery-primitives-title"
|
|
398
|
+
headingLevel={3}
|
|
399
|
+
items={[
|
|
400
|
+
{ label: "Jobs", summary: "A named task with declared inputs and outputs." },
|
|
401
|
+
{ label: "Logs", summary: "The record of one run, readable by people and agents." },
|
|
402
|
+
{ label: "Schedules", summary: "Run a job on a schedule without a separate daemon." },
|
|
403
|
+
]}
|
|
404
|
+
label="Primitives"
|
|
405
|
+
summary="People and agents use the same three objects, so a job you start by hand is one an agent can rerun."
|
|
406
|
+
/>
|
|
407
|
+
<MarketingSection heading="A job keeps its name everywhere." headingId="gallery-marketing-section" headingLevel={3} label="Workflow" layout="split-reverse" summary="Start it from the CLI and check on it from code; both see the same job.">
|
|
408
|
+
<MarketingSectionLabel size="body">Reference</MarketingSectionLabel>
|
|
409
|
+
<p>Consumer-owned content can include <a href="#gallery-install">links</a> and <code>inline code</code>.</p>
|
|
410
|
+
</MarketingSection>
|
|
411
|
+
<MarketingInterfaceGrid heading="Choose your interface." headingId="gallery-marketing-interfaces" headingLevel={3} label="Interfaces" interfaces={[
|
|
412
|
+
{ label: "CLI", summary: "Run a named job.", example: <MarketingCodeBlock code="relay run job-01" /> },
|
|
413
|
+
{ label: "SDK", summary: "Use typed application code." },
|
|
414
|
+
]} />
|
|
415
|
+
<MarketingCardRow ariaLabel="Release radar" cards={[
|
|
416
|
+
{ art: <svg aria-hidden="true" viewBox="0 0 24 24" width="24" height="24"><circle cx="12" cy="12" r="8" /></svg>, href: "#marketing", title: "Grok 4.7", meta: "First observed 21 September 2026." },
|
|
417
|
+
{ art: <svg aria-hidden="true" viewBox="0 0 24 24" width="24" height="24"><rect x="4" y="4" width="16" height="16" rx="4" /></svg>, href: "#gallery-install", title: "GLM 5.3 Flash", meta: "First observed 26 August 2026. Early DeepSWE coverage on OpenRouter." },
|
|
418
|
+
]} />
|
|
419
|
+
<MarketingTrustBoundary heading="What leaves your machine." headingId="gallery-marketing-trust" headingLevel={3} label="Boundary" items={[
|
|
420
|
+
{ label: "Stays local", detail: "Source files and credentials." },
|
|
421
|
+
{ label: "Shared", detail: "Only the logs you choose to sync." },
|
|
422
|
+
]} />
|
|
423
|
+
<MarketingStatStrip
|
|
424
|
+
ariaLabel="Relay usage"
|
|
425
|
+
columns={3}
|
|
426
|
+
source="Counted from the public example repository on 5 September 2026."
|
|
427
|
+
stats={[
|
|
428
|
+
{ label: "Example jobs", value: "12" },
|
|
429
|
+
{ label: "Interfaces", detail: "CLI, SDK, Agent Skill", value: "3" },
|
|
430
|
+
{ label: "Accounts required", value: "0" },
|
|
431
|
+
]}
|
|
432
|
+
/>
|
|
433
|
+
<MarketingDataTable
|
|
434
|
+
caption="Cold-run timing across interfaces"
|
|
435
|
+
columns={[
|
|
436
|
+
{ label: "Interface" },
|
|
437
|
+
{ label: "Median", numeric: true },
|
|
438
|
+
{ label: "Worst observed", numeric: true },
|
|
439
|
+
{ label: "Within target?" },
|
|
440
|
+
]}
|
|
441
|
+
meta="12 example jobs · 5 September 2026"
|
|
442
|
+
note="One repository on one machine; a smoke check, not a guarantee."
|
|
443
|
+
rows={[
|
|
444
|
+
["CLI", "41 ms", "58 ms", { content: "yes", tone: "positive" }],
|
|
445
|
+
["SDK", "43 ms", "61 ms", { content: "yes", tone: "positive" }],
|
|
446
|
+
["Agent Skill", "77 ms", "120 ms", { content: "no", tone: "negative" }],
|
|
447
|
+
]}
|
|
448
|
+
/>
|
|
449
|
+
<MarketingQuoteGrid
|
|
450
|
+
heading="From the people building with it."
|
|
451
|
+
headingId="design-gallery-quotes-title"
|
|
452
|
+
headingLevel={3}
|
|
453
|
+
label="Quotes"
|
|
454
|
+
quotes={[
|
|
455
|
+
{ name: "A. Example", quote: "A placeholder quote for the gallery only. Product sites render real, attributed quotes or none.", role: "@example" },
|
|
456
|
+
]}
|
|
457
|
+
/>
|
|
458
|
+
<MarketingPricing
|
|
459
|
+
heading="Free for local use."
|
|
460
|
+
headingId="design-gallery-pricing-title"
|
|
461
|
+
headingLevel={3}
|
|
462
|
+
label="Pricing"
|
|
463
|
+
plans={[
|
|
464
|
+
{
|
|
465
|
+
action: { href: "#gallery-install", label: "Install Relay" },
|
|
466
|
+
emphasis: "primary",
|
|
467
|
+
features: ["Every feature", "Unlimited local jobs", "All future updates"],
|
|
468
|
+
name: "Local",
|
|
469
|
+
period: "forever",
|
|
470
|
+
price: "$0",
|
|
471
|
+
summary: "Full-featured, with no trial or expiration.",
|
|
472
|
+
},
|
|
473
|
+
{
|
|
474
|
+
action: { href: "#shells", label: "Read about sync" },
|
|
475
|
+
features: ["Everything in Local", "Encrypted sync", "Priority email support"],
|
|
476
|
+
name: "Sync",
|
|
477
|
+
note: "Cancel any time.",
|
|
478
|
+
period: "per year",
|
|
479
|
+
price: "$49",
|
|
480
|
+
summary: "Keep logs in step across your machines.",
|
|
481
|
+
},
|
|
482
|
+
]}
|
|
483
|
+
/>
|
|
484
|
+
<MarketingQuestionList
|
|
485
|
+
heading="Questions before installing."
|
|
486
|
+
headingId="design-gallery-questions-title"
|
|
487
|
+
headingLevel={3}
|
|
488
|
+
label="Questions"
|
|
489
|
+
questions={[
|
|
490
|
+
{ answer: <p>No. The local workflow works without one.</p>, question: "Does it require an account?" },
|
|
491
|
+
{ answer: <p>Nothing leaves your machine unless you turn on sync.</p>, question: "Does it phone home?" },
|
|
492
|
+
]}
|
|
493
|
+
/>
|
|
494
|
+
<MarketingRelated
|
|
495
|
+
groups={[
|
|
496
|
+
{
|
|
497
|
+
heading: "Sibling tools",
|
|
498
|
+
headingId: "design-gallery-related-tools",
|
|
499
|
+
items: [
|
|
500
|
+
{
|
|
501
|
+
href: "#gallery-install",
|
|
502
|
+
name: "Ledger",
|
|
503
|
+
role: "Long-term storage for run logs",
|
|
504
|
+
},
|
|
505
|
+
{
|
|
506
|
+
href: "#marketing",
|
|
507
|
+
name: "Index",
|
|
508
|
+
role: "A local search index",
|
|
509
|
+
},
|
|
510
|
+
],
|
|
511
|
+
},
|
|
512
|
+
{
|
|
513
|
+
heading: "Shared infrastructure",
|
|
514
|
+
headingId: "design-gallery-related-infra",
|
|
515
|
+
items: [
|
|
516
|
+
{
|
|
517
|
+
href: "#marketing",
|
|
518
|
+
name: "Relay",
|
|
519
|
+
role: "The shared job runner",
|
|
520
|
+
},
|
|
521
|
+
],
|
|
522
|
+
summary: "The runner the other tools depend on.",
|
|
523
|
+
},
|
|
524
|
+
]}
|
|
525
|
+
heading="Related tools."
|
|
526
|
+
headingId="design-gallery-related-title"
|
|
527
|
+
headingLevel={3}
|
|
528
|
+
label="Related"
|
|
529
|
+
summary="Each is a separate release. Its card says how it works with Relay."
|
|
530
|
+
/>
|
|
531
|
+
<MarketingMaker
|
|
532
|
+
heading="Who builds Relay"
|
|
533
|
+
headingId="design-gallery-maker-title"
|
|
534
|
+
headingLevel={3}
|
|
535
|
+
label="Built by"
|
|
536
|
+
linkClassName="design-gallery__maker-link"
|
|
537
|
+
links={[{ href: "#marketing", label: "Personal site" }]}
|
|
538
|
+
>
|
|
539
|
+
<p>A short, plain-words bio: who made it, what they did before, where they are, and why this product exists.</p>
|
|
540
|
+
</MarketingMaker>
|
|
541
|
+
<MarketingCallToAction
|
|
542
|
+
actions={[{ href: "#gallery-install", label: "Install Relay" }]}
|
|
543
|
+
footnote="Free for local use on macOS and Linux."
|
|
544
|
+
heading="Start with one job."
|
|
545
|
+
headingId="design-gallery-cta-title"
|
|
546
|
+
headingLevel={3}
|
|
547
|
+
/>
|
|
548
|
+
<div className="design-gallery__foil-note">
|
|
549
|
+
<p>
|
|
550
|
+
Metallic wordmarks and exact-shape marks share a restrained rainbow reflection. Wordmarks use{" "}
|
|
551
|
+
<code>.hraness-foil-text</code>, primary calls to action use <code>.hraness-foil</code>,
|
|
552
|
+
and <code>attachFoil</code> eases the pointer inputs on <code>data-foil</code> targets.
|
|
553
|
+
</p>
|
|
554
|
+
<p className="design-gallery__foil-row">
|
|
555
|
+
<a className={foilClassName("text", "design-gallery__foil-wordmark")} data-foil="" href="#marketing"><FoilMark src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='currentColor' d='M3 3h8v8H3zM13 3h8v8h-8zM3 13h8v8H3zM13 13h8v8h-8z'/%3E%3C/svg%3E" /> Relay</a>
|
|
556
|
+
<a className={foilClassName("surface", "design-gallery__foil-action")} data-foil="" href="#gallery-install">Install Relay</a>
|
|
557
|
+
</p>
|
|
558
|
+
</div>
|
|
559
|
+
</MarketingMain>
|
|
560
|
+
</MarketingPage>
|
|
561
|
+
<MarketingPage preset="editorial" className="design-gallery__marketing-preset">
|
|
562
|
+
<MarketingSiteHeader
|
|
563
|
+
action={{ href: "#gallery-install", label: "Install" }}
|
|
564
|
+
brand="Relay"
|
|
565
|
+
brandHref="#marketing"
|
|
566
|
+
links={[
|
|
567
|
+
{ href: "#gallery-editorial-title", label: "How it works" },
|
|
568
|
+
{ href: "#gallery-install", label: "Install" },
|
|
569
|
+
{ href: "#gallery-quiet-limits", label: "Limits" },
|
|
570
|
+
{ href: "#shells", label: "Docs" },
|
|
571
|
+
{ href: "#articles", label: "Changelog" },
|
|
572
|
+
]}
|
|
573
|
+
sticky={false}
|
|
574
|
+
/>
|
|
575
|
+
<MarketingField>
|
|
576
|
+
<ProductHero
|
|
577
|
+
actions={[
|
|
578
|
+
{ href: "#gallery-install", label: "Install Relay" },
|
|
579
|
+
{ emphasis: "secondary", href: "#gallery-minimal-title", label: "See the compact preset" },
|
|
580
|
+
]}
|
|
581
|
+
align="start"
|
|
582
|
+
boundary="MIT license · macOS and Linux · free for local use"
|
|
583
|
+
eyebrow="Job runner"
|
|
584
|
+
frame={(
|
|
585
|
+
<MarketingProofFrame title="relay run job-01">
|
|
586
|
+
<MarketingCodeBlock className="design-gallery__marketing-command" code={"$ relay run job-01\n{\"status\":\"complete\",\"job\":\"job-01\",\"durationMs\":412}"} />
|
|
587
|
+
</MarketingProofFrame>
|
|
588
|
+
)}
|
|
589
|
+
heading="Run a job from your terminal, your code, or your agent"
|
|
590
|
+
headingId="gallery-editorial-title"
|
|
591
|
+
headingLevel={3}
|
|
592
|
+
name=""
|
|
593
|
+
summary="The editorial preset sets one large sans heading on the flat palette background, a short summary, one next step, and one real proof."
|
|
594
|
+
/>
|
|
595
|
+
</MarketingField>
|
|
596
|
+
<MarketingSection heading="Keep every limit next to what it limits." headingId="gallery-quiet-limits" headingLevel={3} label="Limits" summary="Sections sit between hairline rules, each with one short paragraph and one concrete element.">
|
|
597
|
+
<ol className="design-gallery__quiet-steps">
|
|
598
|
+
<li>Local jobs only; sync is a separate plan.</li>
|
|
599
|
+
<li>Logs older than 30 days are pruned unless pinned.</li>
|
|
600
|
+
</ol>
|
|
601
|
+
</MarketingSection>
|
|
602
|
+
</MarketingPage>
|
|
603
|
+
<MarketingPage preset="minimal" className="design-gallery__marketing-preset">
|
|
604
|
+
<MarketingSiteHeader brand="Relay" brandHref="#marketing" links={[]} sticky={false} />
|
|
605
|
+
<ProductHero name="Relay" heading="A quieter public page." headingId="gallery-minimal-title" headingLevel={3}
|
|
606
|
+
summary="The same shared system, with compact sans headings and a plain surface." />
|
|
607
|
+
<MarketingSiteFooter
|
|
608
|
+
brand={<svg aria-hidden="true" viewBox="0 0 24 24"><path d="M4 4h16v16H4z" fill="currentColor" /></svg>}
|
|
609
|
+
brandHref="#marketing"
|
|
610
|
+
brandLabel="Relay home"
|
|
611
|
+
links={[{ href: "#marketing", label: "Marketing" }]}
|
|
612
|
+
name="Relay"
|
|
613
|
+
/>
|
|
614
|
+
</MarketingPage>
|
|
615
|
+
</section>
|
|
616
|
+
|
|
617
|
+
<section className="design-gallery__section" id="articles">
|
|
618
|
+
<h2>Article layer</h2>
|
|
619
|
+
<MarketingArticle
|
|
620
|
+
after={(
|
|
621
|
+
<ArticleSources
|
|
622
|
+
headingId="gallery-article-sources"
|
|
623
|
+
sources={[
|
|
624
|
+
{ checkedOn: "2026-09-20", href: "#articles", publisher: "Relay", title: "Relay 2.4 release notes" },
|
|
625
|
+
]}
|
|
626
|
+
/>
|
|
627
|
+
)}
|
|
628
|
+
author={{ kind: "organization", name: "Hraness" }}
|
|
629
|
+
dek="Relay replays a failed webhook from the stored request body, so the retry sends the same bytes the provider signed."
|
|
630
|
+
eyebrow="Technique"
|
|
631
|
+
heading="Replaying webhooks without breaking signatures"
|
|
632
|
+
headingId="gallery-article-title"
|
|
633
|
+
provenance={{
|
|
634
|
+
drafting: "ai-from-source",
|
|
635
|
+
review: { reviewer: "an independent AI editorial review", reviewerType: "ai" },
|
|
636
|
+
}}
|
|
637
|
+
published="2026-09-10"
|
|
638
|
+
toc={[
|
|
639
|
+
{ href: "#gallery-article-problem", label: "The problem" },
|
|
640
|
+
{ href: "#gallery-article-approach", label: "The approach" },
|
|
641
|
+
]}
|
|
642
|
+
updated="2026-09-20"
|
|
643
|
+
>
|
|
644
|
+
<h2 id="gallery-article-problem">The problem</h2>
|
|
645
|
+
<p>
|
|
646
|
+
A provider signs the exact request body. Parsing the JSON and serializing it again changes
|
|
647
|
+
whitespace and key order, and the signature check then fails on every retry.
|
|
648
|
+
</p>
|
|
649
|
+
<ArticleCallout label="Limit" tone="limit">
|
|
650
|
+
This applies to providers that sign the raw body. Header-only schemes need no stored copy.
|
|
651
|
+
</ArticleCallout>
|
|
652
|
+
<h2 id="gallery-article-approach">The approach</h2>
|
|
653
|
+
<p>Store the body as bytes next to the parsed event, and send those bytes on replay.</p>
|
|
654
|
+
<pre><code>{"await replay(event.id, { body: stored.raw });"}</code></pre>
|
|
655
|
+
<figure>
|
|
656
|
+
<table>
|
|
657
|
+
<thead>
|
|
658
|
+
<tr><th scope="col">Step</th><th scope="col">Stored</th><th scope="col">Sent on replay</th></tr>
|
|
659
|
+
</thead>
|
|
660
|
+
<tbody>
|
|
661
|
+
<tr><td>Receive</td><td>Raw body and headers</td><td>Nothing</td></tr>
|
|
662
|
+
<tr><td>Retry</td><td>Attempt count</td><td>The stored raw body</td></tr>
|
|
663
|
+
</tbody>
|
|
664
|
+
</table>
|
|
665
|
+
<figcaption>What Relay keeps for each delivery, and what a replay sends.</figcaption>
|
|
666
|
+
</figure>
|
|
667
|
+
</MarketingArticle>
|
|
668
|
+
<ArticleIndex
|
|
669
|
+
heading="Recent writing"
|
|
670
|
+
headingId="gallery-article-index"
|
|
671
|
+
headingLevel={3}
|
|
672
|
+
items={[
|
|
673
|
+
{
|
|
674
|
+
dek: "Relay replays a failed webhook from the stored request body.",
|
|
675
|
+
eyebrow: "Technique",
|
|
676
|
+
href: "#gallery-article-title",
|
|
677
|
+
published: "2026-09-10",
|
|
678
|
+
title: "Replaying webhooks without breaking signatures",
|
|
679
|
+
updated: "2026-09-20",
|
|
680
|
+
},
|
|
681
|
+
{
|
|
682
|
+
dek: "Relay 2.4 adds per-endpoint retry limits.",
|
|
683
|
+
eyebrow: "Release",
|
|
684
|
+
href: "#articles",
|
|
685
|
+
published: "2026-09-02",
|
|
686
|
+
title: "Relay 2.4 adds per-endpoint retry limits",
|
|
687
|
+
},
|
|
688
|
+
]}
|
|
689
|
+
/>
|
|
690
|
+
<div className="hraness-prose">
|
|
691
|
+
<h3>Shared reading scale</h3>
|
|
692
|
+
<p>
|
|
693
|
+
The `.hraness-prose` grammar carries the shared `--hraness-type-*` scale to docs
|
|
694
|
+
and guide surfaces that do not run the publication shell. Headings step up on
|
|
695
|
+
wide windows and a serif face opts in with `data-hraness-reading-face="serif"`.
|
|
696
|
+
</p>
|
|
697
|
+
<h4>Section spacing</h4>
|
|
698
|
+
<p>
|
|
699
|
+
Sections separate on the shared space token; subsections tighten to the
|
|
700
|
+
subsection space and small heads keep the text face.
|
|
701
|
+
</p>
|
|
702
|
+
</div>
|
|
703
|
+
</section>
|
|
704
|
+
|
|
705
|
+
<section className="design-gallery__section" id="status-pages">
|
|
706
|
+
<h2>Status pages</h2>
|
|
707
|
+
<p>
|
|
708
|
+
One page for missing addresses and recoverable errors. It leads with the
|
|
709
|
+
product's main action, offers the closest known page for a mistyped
|
|
710
|
+
link, and lists at most three places to start. Move the pointer over the
|
|
711
|
+
glyph, or click it.
|
|
712
|
+
</p>
|
|
713
|
+
<ViewportFrame className="design-gallery__status-preview">
|
|
714
|
+
<StatusPage
|
|
715
|
+
agentIndexHref="/llms.txt"
|
|
716
|
+
canvasAs="div"
|
|
717
|
+
next={[
|
|
718
|
+
{ description: "What the product does, in one minute.", href: "#status-pages", label: "How it works" },
|
|
719
|
+
{ description: "Set it up on your own machine.", href: "#status-pages", label: "Docs" },
|
|
720
|
+
]}
|
|
721
|
+
primaryAction={{ href: "#status-pages", label: "Start a project" }}
|
|
722
|
+
routes={[{ href: "/docs/getting-started", label: "Getting started" }]}
|
|
723
|
+
siteName="Example"
|
|
724
|
+
titleAs="h3"
|
|
725
|
+
/>
|
|
726
|
+
</ViewportFrame>
|
|
727
|
+
</section>
|
|
728
|
+
|
|
729
|
+
<section className="design-gallery__section" id="shells">
|
|
730
|
+
<h2>Site shell</h2>
|
|
731
|
+
<p>The main content fills available height so the footer follows short and long pages.</p>
|
|
732
|
+
<pre><code>{'<body class="hraness-site-shell">\n <header>Project</header>\n <main>Payment complete</main>\n <footer>By Hraness</footer>\n</body>'}</code></pre>
|
|
733
|
+
|
|
734
|
+
<h2>Application shells</h2>
|
|
735
|
+
<ViewportFrame className="design-gallery__shell-preview">
|
|
736
|
+
<AppShell
|
|
737
|
+
bottomBar={(
|
|
738
|
+
<BottomBar
|
|
739
|
+
actions={<span>Synced</span>}
|
|
740
|
+
data-gallery-layout-bottom-bar=""
|
|
741
|
+
leading={<span>Ready</span>}
|
|
742
|
+
>
|
|
743
|
+
Reference footer
|
|
744
|
+
</BottomBar>
|
|
745
|
+
)}
|
|
746
|
+
navigationKey="gallery"
|
|
747
|
+
rail={(
|
|
748
|
+
<NavigationRail>
|
|
749
|
+
<RailSection title="Workspace">
|
|
750
|
+
<RailItem href="#foundation" icon={<Icon icon={DashboardSquare01Icon} />} isActive label="Overview" />
|
|
751
|
+
<RailItem href="#data" icon={<Icon icon={Chart01Icon} />} label="Data" />
|
|
752
|
+
<RailItem href="#syntax" icon={<Icon icon={CodeIcon} />} label="Syntax" />
|
|
753
|
+
</RailSection>
|
|
754
|
+
</NavigationRail>
|
|
755
|
+
)}
|
|
756
|
+
topBar={(
|
|
757
|
+
<TopBar
|
|
758
|
+
data-gallery-layout-top-bar=""
|
|
759
|
+
title="Reference workspace"
|
|
760
|
+
/>
|
|
761
|
+
)}
|
|
762
|
+
>
|
|
763
|
+
<PageCanvas as="div" data-gallery-layout-page-canvas="">
|
|
764
|
+
<AnimatedRailStage
|
|
765
|
+
className="design-gallery__animated-rail-stage"
|
|
766
|
+
stageKey={density}
|
|
767
|
+
>
|
|
768
|
+
<DitherSurface
|
|
769
|
+
as="section"
|
|
770
|
+
data-gallery-dither=""
|
|
771
|
+
density={density === "compact" ? "fine" : "medium"}
|
|
772
|
+
tone="card"
|
|
773
|
+
>
|
|
774
|
+
<h3>{density === "compact" ? "Compact" : "Default"} composition</h3>
|
|
775
|
+
<p>The route body changes while persistent navigation remains in place.</p>
|
|
776
|
+
</DitherSurface>
|
|
777
|
+
</AnimatedRailStage>
|
|
778
|
+
</PageCanvas>
|
|
779
|
+
</AppShell>
|
|
780
|
+
</ViewportFrame>
|
|
781
|
+
<div
|
|
782
|
+
className="design-gallery__docked-footer-preview"
|
|
783
|
+
data-gallery-layout-docked-frame=""
|
|
784
|
+
>
|
|
785
|
+
<p>Docked commands remain inside their positioning owner.</p>
|
|
786
|
+
<DockedFooter
|
|
787
|
+
data-gallery-layout-docked-footer=""
|
|
788
|
+
density="compact"
|
|
789
|
+
position="absolute"
|
|
790
|
+
>
|
|
791
|
+
Reference commands
|
|
792
|
+
</DockedFooter>
|
|
793
|
+
</div>
|
|
794
|
+
</section>
|
|
795
|
+
|
|
796
|
+
<section className="design-gallery__section" id="data">
|
|
797
|
+
<h2>Data and instrument compositions</h2>
|
|
798
|
+
<div className="design-gallery__grid">
|
|
799
|
+
<BarListChart aria-label="Example request volume" data={barData} />
|
|
800
|
+
<RangePlotChart aria-label="Example regional ranges" data={rangeData} />
|
|
801
|
+
<div className="design-gallery__instrument">
|
|
802
|
+
<Fader
|
|
803
|
+
aria-label="Example level"
|
|
804
|
+
className="design-gallery__vertical-fader"
|
|
805
|
+
data-gallery-fader="vertical"
|
|
806
|
+
density="default"
|
|
807
|
+
label="Level"
|
|
808
|
+
labelAccessory={<span data-gallery-fader-accessory="">dB</span>}
|
|
809
|
+
maxValue={100}
|
|
810
|
+
minValue={0}
|
|
811
|
+
onChange={setFaderValue}
|
|
812
|
+
showLabel
|
|
813
|
+
showOutput
|
|
814
|
+
value={faderValue}
|
|
815
|
+
/>
|
|
816
|
+
<Fader
|
|
817
|
+
aria-label="Example horizontal level"
|
|
818
|
+
className="design-gallery__horizontal-fader"
|
|
819
|
+
data-gallery-fader="horizontal"
|
|
820
|
+
density="compact"
|
|
821
|
+
label="Horizontal level"
|
|
822
|
+
maxValue={100}
|
|
823
|
+
minValue={0}
|
|
824
|
+
onChange={setFaderValue}
|
|
825
|
+
orientation="horizontal"
|
|
826
|
+
showLabel
|
|
827
|
+
showOutput
|
|
828
|
+
value={faderValue}
|
|
829
|
+
/>
|
|
830
|
+
<Slider label="Balance" maxValue={100} minValue={0} value={50} />
|
|
831
|
+
<PlaybackTransport
|
|
832
|
+
aria-label="Preview transport"
|
|
833
|
+
buttonAriaKeyShortcuts="Space"
|
|
834
|
+
buttonId="design-gallery-playback-command"
|
|
835
|
+
className="design-gallery__playback-transport"
|
|
836
|
+
onPlay={() => setPlaybackStatus("playing")}
|
|
837
|
+
onStop={() => setPlaybackStatus("idle")}
|
|
838
|
+
status={playbackStatus}
|
|
839
|
+
/>
|
|
840
|
+
</div>
|
|
841
|
+
</div>
|
|
842
|
+
<div
|
|
843
|
+
className="design-gallery__chat"
|
|
844
|
+
data-gallery-chat=""
|
|
845
|
+
data-gallery-chat-submission={chatSubmission}
|
|
846
|
+
>
|
|
847
|
+
<ChatMessage
|
|
848
|
+
actions={<Button variant="quiet">Copy response</Button>}
|
|
849
|
+
avatar={<span aria-hidden="true" className="design-gallery__chat-avatar">AI</span>}
|
|
850
|
+
className="design-gallery__chat-message"
|
|
851
|
+
meta={(
|
|
852
|
+
<RelativeTime
|
|
853
|
+
locale="en-US"
|
|
854
|
+
now={designGalleryRelativeTimeNow}
|
|
855
|
+
refreshInterval="off"
|
|
856
|
+
value={designGalleryRelativeTimeNow}
|
|
857
|
+
/>
|
|
858
|
+
)}
|
|
859
|
+
name="Assistant"
|
|
860
|
+
role="assistant"
|
|
861
|
+
>
|
|
862
|
+
<p>A complete message keeps its ordinary article and slot semantics.</p>
|
|
863
|
+
</ChatMessage>
|
|
864
|
+
<ChatMessage role="user">
|
|
865
|
+
<p>Responsive composition belongs to the extracted package recipe.</p>
|
|
866
|
+
</ChatMessage>
|
|
867
|
+
<ChatComposer
|
|
868
|
+
action="/gallery-chat-submit"
|
|
869
|
+
aria-label="Gallery message composer"
|
|
870
|
+
className="design-gallery__chat-composer"
|
|
871
|
+
onSubmit={() => {
|
|
872
|
+
setChatSubmission(chatDraft);
|
|
873
|
+
setChatDraft("");
|
|
874
|
+
}}
|
|
875
|
+
onValueChange={setChatDraft}
|
|
876
|
+
placeholder="Write a message"
|
|
877
|
+
sendLabel="Send message"
|
|
878
|
+
value={chatDraft}
|
|
879
|
+
/>
|
|
880
|
+
</div>
|
|
881
|
+
<ul aria-label="Relative time examples" className="design-gallery__relative-times" data-gallery-relative-time="">
|
|
882
|
+
{relativeTimeExamples.map(({ id, value }) => (
|
|
883
|
+
<li key={id}>
|
|
884
|
+
<RelativeTime
|
|
885
|
+
data-gallery-relative-time-example={id}
|
|
886
|
+
locale="en-US"
|
|
887
|
+
now={designGalleryRelativeTimeNow}
|
|
888
|
+
refreshInterval="off"
|
|
889
|
+
value={value}
|
|
890
|
+
/>
|
|
891
|
+
</li>
|
|
892
|
+
))}
|
|
893
|
+
</ul>
|
|
894
|
+
</section>
|
|
895
|
+
|
|
896
|
+
<section className="design-gallery__section" id="effects">
|
|
897
|
+
<h2>Decorative effects</h2>
|
|
898
|
+
<FoilCardDeck
|
|
899
|
+
aria-label="Delegated foil ornament examples"
|
|
900
|
+
className="design-gallery__foil-deck"
|
|
901
|
+
>
|
|
902
|
+
{foilDeckExamples.map((example) => (
|
|
903
|
+
<FoilCardSurface
|
|
904
|
+
className="design-gallery__foil-example"
|
|
905
|
+
intensity="standard"
|
|
906
|
+
key={example.ornament}
|
|
907
|
+
ornament={example.ornament}
|
|
908
|
+
preset={example.preset}
|
|
909
|
+
renderMode="interactive"
|
|
910
|
+
seed={`public-gallery-foil-${example.ornament}`}
|
|
911
|
+
>
|
|
912
|
+
<article className="design-gallery__foil-card">
|
|
913
|
+
<Tag variant="outline">{example.label}</Tag>
|
|
914
|
+
<div>
|
|
915
|
+
<h3>Semantic card content</h3>
|
|
916
|
+
<p>One deck controller decorates ordinary articles.</p>
|
|
917
|
+
</div>
|
|
918
|
+
</article>
|
|
919
|
+
</FoilCardSurface>
|
|
920
|
+
))}
|
|
921
|
+
</FoilCardDeck>
|
|
922
|
+
<div className="design-gallery__effect">
|
|
923
|
+
<AuroraDotsBackground />
|
|
924
|
+
<ProceduralBackdrop seed="public-gallery" variant="composite" />
|
|
925
|
+
<div className="design-gallery__effect-copy">
|
|
926
|
+
<h3>Semantic content stays ordinary DOM</h3>
|
|
927
|
+
<p>Decorative paint is pointer-transparent and removable in forced colors. Marketing actions use system button colors so their labels stay readable.</p>
|
|
928
|
+
</div>
|
|
929
|
+
</div>
|
|
930
|
+
</section>
|
|
931
|
+
|
|
932
|
+
<section className="design-gallery__section" id="syntax">
|
|
933
|
+
<h2>Server syntax</h2>
|
|
934
|
+
<pre className="design-gallery__syntax">
|
|
935
|
+
<SyntaxCode
|
|
936
|
+
code={'import { AppShell } from "@hraness/design-kit/react";\n\nexport const shell = <AppShell rail={null}>Content</AppShell>;'}
|
|
937
|
+
styles="classes"
|
|
938
|
+
/>
|
|
939
|
+
</pre>
|
|
940
|
+
</section>
|
|
941
|
+
</Root>
|
|
942
|
+
);
|
|
943
|
+
}
|